Browse Source

Snapshot 1c4b68d

master
commit
c5e6c56950
39 changed files with 922 additions and 0 deletions
  1. +154
    -0
      .gitignore
  2. +4
    -0
      DebugServer.py
  3. +128
    -0
      HandleWeatherFile.py
  4. +1
    -0
      Licence note
  5. +55
    -0
      README.md
  6. +145
    -0
      WebServer.py
  7. BIN
      doc/Illustration.png
  8. +3
    -0
      static/img/bkn.svg
  9. +3
    -0
      static/img/dust.svg
  10. +3
    -0
      static/img/few.svg
  11. +3
    -0
      static/img/fg.svg
  12. +3
    -0
      static/img/fzra.svg
  13. +3
    -0
      static/img/fzrara.svg
  14. +1
    -0
      static/img/help.svg
  15. +3
    -0
      static/img/hi_shwrs.svg
  16. +3
    -0
      static/img/hi_tsra.svg
  17. +3
    -0
      static/img/ip.svg
  18. +3
    -0
      static/img/mist.svg
  19. +3
    -0
      static/img/mix.svg
  20. +1
    -0
      static/img/moon.svg
  21. +3
    -0
      static/img/nsurtsra.svg
  22. +3
    -0
      static/img/ovc.svg
  23. +3
    -0
      static/img/ra.svg
  24. +3
    -0
      static/img/ra1.svg
  25. +3
    -0
      static/img/raip.svg
  26. +3
    -0
      static/img/rasn.svg
  27. +3
    -0
      static/img/rasn1.svg
  28. +3
    -0
      static/img/sct.svg
  29. +3
    -0
      static/img/shra.svg
  30. +3
    -0
      static/img/skc.svg
  31. +3
    -0
      static/img/smoke.svg
  32. +3
    -0
      static/img/sn.svg
  33. +1
    -0
      static/img/sun.svg
  34. +3
    -0
      static/img/tsra.svg
  35. +3
    -0
      static/img/wind.svg
  36. +68
    -0
      static/js/script.js
  37. +33
    -0
      templates/help.html
  38. +242
    -0
      templates/index.html
  39. +14
    -0
      templates/layout.html

+ 154
- 0
.gitignore View File

@ -0,0 +1,154 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintainted in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
WeatherReport*.json

+ 4
- 0
DebugServer.py View File

@ -0,0 +1,4 @@
from WebServer import app
if __name__ == '__main__':
app.run(host='0.0.0.0',debug=True)

+ 128
- 0
HandleWeatherFile.py View File

@ -0,0 +1,128 @@
from datetime import datetime, timedelta
import json
import os.path
import requests
import time
class HandleWeatherFile:
"""
Fetch weather data from the infoclimat.fr public API.
Save the data into JSON file for future use so as to not overload the
free API.
Provide helper function to retrieve information from the JSON file.
@param latitude Latitude of the point in space to gather weather data from.
@param longitude Latitude of the point in space to gather weather data from.
@param filename Name of the JSON file that host weather data.
"""
def __init__(self,latitude=48.85341,longitude=2.3488,filename="WeatherReport.json"):
self.latitude=latitude
self.longitude=longitude
self.filename=filename
def fetchWeatherFile(self,fileValidityInSecond=3600):
"""
Fetch the JSON weather report file from the web
Use self.filename file to store the data. If this file already
exist and it's creation date is less than "fileValidityInSecond"
then its content is used instead of an API request.
The self.filename file will be saved/overrode automatically.
@param fileValidityInSecond Maximum time in second for an old file to be valid.
"""
fetchNewFile=True
jsonData=None
if(os.path.exists(self.filename)):
f=open(self.filename)
try:
jsonData=json.load(f)
if jsonData.get("fetchTime")!=None:
if (jsonData["fetchTime"]+fileValidityInSecond)>time.time():
fetchNewFile=False
except Exception:
pass
f.close()
if fetchNewFile:
try:
request=requests.get("https://www.infoclimat.fr/public-api/gfs/json?_ll="+str(self.latitude)+","+str(self.longitude)+"&_auth=VkxeSQ5wVnRQfQQzVCJXflE5ADUNe1dwB3tRMgBlAH1UPwRlBGRUMlI8WyZTfFJkAy5XNAE6BzcEbwZ%2BXS8AYVY8XjIOZVYxUD8EYVR7V3xRfwBhDS1XcAdlUTYAZAB9VDYEaQRnVChSPlsnU2JSbwM2VygBIQc%2BBGEGYl05AGBWPF44Dm5WMlA%2BBHlUe1dlUWMAMg01V20HYFEwAGQAYVQxBGkEYlQxUj1bJ1NqUmcDNFc3ATsHNwRiBmldLwB8VkxeSQ5wVnRQfQQzVCJXflE3AD4NZg%3D%3D&_c=8f0f822a713fe1e38891d301396859ea");
if(request.status_code==200):
jsonData=request.json()
jsonData["fetchTime"]=time.time()
f=open(self.filename, "w")
f.write(json.dumps(jsonData))
f.close()
else:
jsonData=request.status_code
except Exception:
pass
return jsonData
def getFormattedDateTimeArray(self,dayCount,includeToday=False,hour=[]):
"""
Return an array composed of string representing dates and times formatted like the weather JSON file
@param dayCount Number of days of measure (counting up from today)
@param includeToday Indicate if dayCount include today or not
@param hour Hours to include, can be empty: then all possible hour will be returned.
"""
dayDateTime=[]
currentDateTime=datetime.now()
for i in range(dayCount):
if includeToday:
if i==0:
iDateTime=currentDateTime
else:
iDateTime=currentDateTime+timedelta(days=i)
else:
iDateTime=currentDateTime+timedelta(days=i+1)
if len(hour)==0:
for h in range(0,24):
dayDateTime.append(self._getFormattedDateTime(iDateTime,h))
else:
for h in hour:
dayDateTime.append(self._getFormattedDateTime(iDateTime,h))
return dayDateTime
def _getFormattedDateTime(self,dateTimeObj,hour):
"""
Return a dateTime string formatted like the weather JSON file
@param dateTimeObj dateTime object used to get year/month and day.
@param hour Hour to be used instead of the dateTimeObj value
"""
return(
str(dateTimeObj.year)
+"-"+str(dateTimeObj.month).rjust(2,"0")
+"-"+str(dateTimeObj.day).rjust(2,"0")
+" "+str(hour).rjust(2,"0")
+":00:00"
)
def getWeatherFileMeasureHours(self,integerValue=False):
"""
Return an array with all the possible measured hours within the weather report file.
Return empty array if file empty or fail to open.
@param integerValue Return only the integer value of the hour instead of "HH:MM:SS" by default.
"""
validHours=[]
measureDateTime=datetime.now()+timedelta(days=1)
measureDay=self._getFormattedDateTime(measureDateTime,0)[:-9]
if(os.path.exists(self.filename)):
f=open(self.filename)
try:
jsonData=json.load(f)
for k in jsonData.keys():
if k.__contains__(measureDay):
validHours.append(k.replace(measureDay+" ",""))
except Exception:
pass
f.close()
if(integerValue):
for i in range(0,len(validHours)):
validHours[i]=int(validHours[i].replace(":00:00",""))
return validHours

+ 1
- 0
Licence note View File

@ -0,0 +1 @@
If you find software that doesn’t have a license, that means you have no permission from the creators of the software to use, modify, or share the software. Although a code host such as GitHub may allow you to view and fork the code, this does not imply that you are permitted to use, modify, or share the software for any purpose.

+ 55
- 0
README.md View File

@ -0,0 +1,55 @@
# Weather web server
Web server that fetch and display weather data.
## Weather data provider
The weather data are provided by [infoclimat.fr](https://www.infoclimat.fr/) (not affiliated).
*Why them ?* They got weather data accessible from a registration free public API.
*Are they the best ?* Probably not, their API lack modularity and some data that may be critical depending on your application.
*Do they provide data outside France ?* No.
## Installation
For debugging/development purpose, you could simply use ```python3 DebugServer.py``` to launch the integrated flask webserver.
To deploy in production, there's multiple possibility depending on your need, see [the official flask documentation](https://flask.palletsprojects.com/en/2.1.x/deploying/) for reference.
## Usage
By default the development server is accessible via [127.0.0.1:5000](127.0.0.1:5000) and display the weather of today and the next 6 days at Paris.
You could navigate to [127.0.0.1:5000/lat;long](127.0.0.1:5000/lat;long) where "lat" and "long" are the latitude and longitude of the place you which to display.
Note:
* The freezing point and rain quantity are only displayed when it's snowing and raining respectively.
* The bold number represent the gust of wind and is only displayed when it is greater than the average speed of wind.
* Use the buttons on the top-left of the table to access night-mode and display the help.
![Illustration of the page](doc/Illustration.png)
### Optional parameters
Use the following URL parameters to change the default behavior.
* **`hour`**
Use one or multiples numerical values separated by a comma to change the default displayed hours.
Note that invalid values will result in empty cells.
Example: [127.0.0.1:5000/?hour=8,10,12,14](http://127.0.0.1:5000/?hour=8,10,12,14)
* **`day`**
Indicate the number of days to display. Invalid values will result in empty cells.
Example: [127.0.0.1:5000/?day=4](http://127.0.0.1:5000/?day=4)
* **`today`**
If set to `0` then the current day won't be displayed.
Example: [127.0.0.1:5000/?today=0](http://127.0.0.1:5000/?today=0)
* **`title`**
Change the title of the web page.
Example: [127.0.0.1:5000/?title=Weather%20at%20Paris](http://127.0.0.1:5000/?title=Weather%20at%20Paris)
* **`ui`**
If set to `0` the icons won't be displayed.
Example: [127.0.0.1:5000/?help=0](http://127.0.0.1:5000/?help=0)
* **`night`**
If set to `1` the page will be displayed using the dark theme.
Example: [127.0.0.1:5000/?night=1](http://127.0.0.1:5000/?night=1)
Obviously you can use parameters with or without the `lat;long` elements like this: [127.0.0.1:5000/48.51296;2.17402?day=2&today=0&title=Weather%20at%20the%20Eiffel%20Tower](http://127.0.0.1:5000/48.51296;2.17402?day=2&today=0&title=Weather%20at%20the%20Eiffel%20Tower) that will display the weather for the next two days at some random tower in Paris.

+ 145
- 0
WebServer.py View File

@ -0,0 +1,145 @@
from flask import Flask, render_template, request
from HandleWeatherFile import HandleWeatherFile
from datetime import datetime
app=Flask(__name__)
def getUniqueDate(dateArray):
date=[]
for i in dateArray:
iDate=i.split(" ")[0]
if iDate not in date:
date.append(iDate)
return date
def getHumanReadableFetchTime(fetchTime):
"""
Compare fetchTime with current date and time value.
Return the result as "X days Y minutes Z seconds" where days and minutes will only be displayed if relevant.
@param fetchTime datetime.datetime object representing a past point in time
"""
fetchTime=datetime.fromtimestamp(fetchTime)
tDelta=datetime.now()-fetchTime
returnValue=""
rest=tDelta.seconds
if(tDelta.days>0):
returnValue+=str(int(tDelta.days))+" days "
if(rest>3599):
returnValue+=str(int(rest/3600))+" hours "
rest=rest%3600
if(rest>59):
returnValue+=str(int(rest/60))+" minutes "
rest=rest%60
returnValue+=str((rest))+" seconds"
return returnValue
def getUserArgumentHour(requestHour):
"""
Return a sanitized array from the measurement hour(s) requested by the user.
Return empty array if no valid values.
Removes duplicates, unsure that the values are number and sort the results.
@param requestHour URL parameter relative to the hour in string format, value separated by comma.
"""
hour=[]
requestedHour=requestHour
if requestedHour is None:
return hour
requestedHour=requestedHour.split(",")
requestedHour=list(dict.fromkeys(requestedHour)) #removes duplicates
for h in requestedHour:
try:
hi=int(h)
hour.append(hi)
except Exception:
pass
hour.sort()
return hour
@app.route("/")
def indexRoute():
return renderWeatherTemplate(request.args)
@app.route("/<latitude>;<longitude>")
def specifiedCoordinateRoute(latitude,longitude):
try:
flatitude=float(latitude)
except Exception:
return "Error, verify the provided latitude. ("+str(latitude)+")"
try:
flongitude=float(longitude)
except Exception:
return "Error, verify the provided longitude. ("+str(longitude)+")"
return renderWeatherTemplate(request.args,latitude,longitude)
def renderWeatherTemplate(requestArgs,latitude=None,longitude=None):
"""
Render the weather template based on the specified paramaters.
@param request.args Parsed URL parameters.
@param latitude Optional geographic coordinate that specifies the northsouth position.
@param longitude Optional geographic coordinate that specifies the east-west position.
"""
title="Weather "
handleWeatherFile=None
if latitude is not None and longitude is not None:
title+=latitude+"/"+longitude
handleWeatherFile=HandleWeatherFile(latitude=latitude,longitude=longitude,filename="WeatherReport"+latitude+"_"+longitude+".json")
else:
handleWeatherFile=HandleWeatherFile()
title+=" Paris"
weatherFile=handleWeatherFile.fetchWeatherFile()
measureHour=getUserArgumentHour(requestArgs.get("hour",type=str))
validHours=None
if(len(measureHour)==0):
measureHour=handleWeatherFile.getWeatherFileMeasureHours(True)
validHours=measureHour
includeToday=True
if requestArgs.get("today",type=int) is not None:
if(requestArgs.get("today",type=int)==0):
includeToday=False
night=False
if requestArgs.get("night",type=int) is not None:
if(requestArgs.get("night",type=int)==1):
night=True
ui=True
if requestArgs.get("ui",type=int) is not None:
if(requestArgs.get("ui",type=int)==0):
ui=False
if ui and validHours is None:
validHours=handleWeatherFile.getWeatherFileMeasureHours(True)
dayCount=7
if requestArgs.get("day",type=int) is not None:
dayCount=requestArgs.get("day",type=int)
if requestArgs.get("title",type=str) is not None:
title=requestArgs.get("title",type=str)
dt=handleWeatherFile.getFormattedDateTimeArray(dayCount,includeToday,measureHour)
return render_template(
"index.html",
date=getUniqueDate(dt),
hour=measureHour,
datetime=dt,
weatherData=weatherFile,
fetchTime=getHumanReadableFetchTime(weatherFile["fetchTime"]),
title=title,
ui=ui,
validHours=str(validHours)[1:-1],
night=night
)
#if __name__ == '__main__':
# app.run(host='0.0.0.0',debug=True)

BIN
doc/Illustration.png View File

Before After
Width: 1885  |  Height: 721  |  Size: 178 KiB

+ 3
- 0
static/img/bkn.svg View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100">
<path d="M33.469,15v11.938h3.125v-11.938h-3.125zm-13.813,3.406l-2.656,1.656,6.312,10.126,2.657-1.657-6.313-10.125zm30.938,0.313l-4.719,8.531c-2.986,0.663-5.776,1.865-8.25,3.5-0.847-0.119-1.715-0.188-2.594-0.188-10.675,0-19.312,8.695-19.312,19.407,0,1.947,0.305,3.825,0.843,5.593-0.978,1.235-1.775,2.642-2.312,4.157l-0.688-1.063-10.062,6.344,0.3438,0.562c-2.3766,2.331-3.8438,5.561-3.8438,9.126,0,3.52,1.6295,6.439,4.0938,8.093,2.4642,1.654,5.5401,2.219,8.7182,2.219h20.469,3.125,9.125,17.844,16.375c11.15,0,20.25-9.098,20.25-20.25s-9.099-20.219-20.25-20.219c-1.607,0-3.124,0.264-4.594,0.625-2.866-10.607-12.411-18.5-23.906-18.5-0.499,0-0.977,0.034-1.469,0.063l3.563-6.469-2.75-1.531zm-44.532,11.375l-1.5313,2.75,10.407,5.781,1.5-2.75-10.376-5.781zm45.188,1.344c10.088,0,18.319,7.377,19.844,17.031l0.468,2.906,2.75-1.031c1.734-0.658,3.538-1.063,5.438-1.063,8.58,0,15.5,6.89,15.5,15.469s-6.921,15.5-15.5,15.5h-16.375-17.844-32.719c-2.576,0-4.757-0.53-6.062-1.406s-2-1.922-2-4.156c0-4.463,3.5946-8.032,8.062-8.032,0.74,0,1.486,0.128,2.313,0.375l3.063,0.938v-3.219c0-0.288,0.007-0.458,0-0.5,0.133-5.302,4.412-9.5,9.75-9.5-0.078,0,0.118,0.026,0.656,0.062l2.656,0.188-0.125-2.656c-0.029-0.651-0.063-0.871-0.063-0.719,0-11.178,9.002-20.187,20.188-20.187zm-51.25,16.062v3.125h11.906v-3.125h-11.906z"/>
</svg>

+ 3
- 0
static/img/dust.svg View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100">
<path d="M51.312,0c-5.182,0-9.974,1.68-13.874,4.5h27.687c-3.879-2.82-8.641-4.5-13.813-4.5zm-18.312,8.625c-1.135,1.375-2.102,2.891-2.906,4.5h42.312c-0.806-1.614-1.771-3.121-2.906-4.5h-36.5zm-4.5,8.625c-0.41,1.451-0.686,2.95-0.812,4.5h63.718c-2.932-1.897-6.403-3-10.156-3-2.34,0-4.568,0.47-6.625,1.25-0.15-0.948-0.368-1.843-0.625-2.75h-45.5zm-7.438,8.625c-2.04,1.037-3.774,2.58-5,4.5h82.532c-0.668-1.626-1.551-3.141-2.625-4.5h-74.907zm-6.718,8.625c-0.192,0.879-0.282,1.814-0.282,2.75,0,0.087,0.032,0.163,0.032,0.25-1.008-0.302-2.054-0.531-3.156-0.531-2.3638,0-4.5566,0.758-6.3442,2.031h95.344c0.038-0.499,0.062-0.991,0.062-1.5,0-1.025-0.092-2.02-0.25-3h-85.406zm-13.25,8.625c-0.66562,1.366-1.0531,2.889-1.0938,4.5h97.031c0.893-1.385,1.589-2.896,2.094-4.5h-98.031zm-0.25005,8.625c1.6598,3.194,5.5612,4.5,10.094,4.5h70.312c4.652,0,8.91-1.698,12.188-4.5h-92.594zm38.468,10.75c-0.759-0.008-1.556,0.309-2.25,0.938-1.335,1.169-1.566,2.837-1.562,4.343,0,0.72,0.028,1.412,0.062,2.094-0.312-0.273-0.654-0.545-1.093-0.813-0.923-0.583-1.719-0.901-2.5-0.906-1.983,0.081-2.569,1.987-2.625,4.063-2.107,1.723-2.485,8.9,1.25,7.656,2.024-0.679,2.888-3.279,2.687-5.063,0,0-0.133-2.52-2.406-2.906,0.113-1.699,0.571-2.25,1.094-2.25,0.322-0.007,0.906,0.152,1.687,0.656,1.414,0.98,1.839,1.344,2,2.25,0.022,0.858,0.123,2.878,0.125,2.969,0.215,3.013,0.671,5.308,1,8.344h-15.375l2.406,1.125,10.188,3.406,9.406-1.625,6.594,2.313,5.219-1.625,1.562-3.594h-17.75c-0.332-3.103-1.537-5.565-1.75-8.563,0.025-1.026,0.014-1.776-0.125-2.75-0.014-0.558-0.062-1.052-0.062-1.624,0-1.092-0.094-2.176-0.094-3.157,0.005-1.388,0.215-2.473,1.062-3.219,0.506-0.442,0.912-0.556,1.25-0.562,0.889-0.094,2.063,1.286,2.657,2.844-0.523,0.425-0.813,0.812-0.813,0.812-2.021,2.831,5.595,10.919,8.625,6.563,1.297-1.864-0.371-7.221-3.437-8.281-1.201-0.418-2.252-0.24-3.094,0.124-0.718-1.754-1.95-3.466-3.938-3.562zm4.282,4.281s3.683,2.507,4.718,6.969l-5.781-6.312,1.063-0.657zm-13.032,6.063l-1.031,5.781c-0.517-1.831,0-5.344,0-5.344l1.031-0.437zm-30.562,11.031v6.375l5.2188-2.781,1.5624-3.594h-6.7812zm8.6875,0l-2.0937,4.187,4.7812,6,4.594-2.75,4.781-5.937-1.469-1.5h-10.594zm50,0l-2.094,4.187,4.781,6,4.594-2.75,4.781-5.937-1.469-1.5h-10.593zm12.718,0l2.406,1.125,10.188,3.406,7.938-1.125,8.062-2.562v-0.844h-28.594zm-48.718,2.281l-4.563,5.656,12.5,6.782,7.625-1.469-5.375-7.594-10.187-3.375zm50,0l-4.563,5.656,12.5,6.782,7.625-1.469-5.375-7.594-10.187-3.375zm27.312,0l-5.281,1.406,5.281,1.532v-2.938zm-56.781,2.594l-7.688,1.031,5.031,7.313,13.344,2.906,5.813-4.75-4.375-5.75-5.344,1.438-6.781-2.188zm50,0l-7.688,1.031,5.031,7.313,9.438,2.218v-8.374l-6.781-2.188zm-87.875,0.75l-5.3438,2.562v7.938h3.9062l5.8126-4.781-4.375-5.719zm11.406,3.625l-8.1562,5.531,1.0937,1.344h18.718l-0.062-0.281-11.594-6.594zm50,0l-8.156,5.531,1.094,1.344h18.718l-0.062-0.281-11.594-6.594zm-27.062,5.469l-6.376,1.406h12.219l-5.843-1.406zm50,0l-6.376,1.406h12.219l-5.843-1.406z"/>
</svg>

+ 3
- 0
static/img/few.svg View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100">
<path d="M43.031,0v15.344h4v-15.344h-4zm-17.75,4.375l-3.406,2.1562,8.125,13,3.406-2.125-8.125-13.031zm39.781,0.4062l-7.437,13.407,3.531,1.968,7.406-13.406-3.5-1.9688zm-57.281,14.625l-1.9687,3.532,13.376,7.437,1.968-3.531-13.375-7.438zm37.281,0.594c-13.724,0-24.874,11.166-24.874,24.938,0,13.77,11.15,24.94,24.874,24.937,13.716,0,24.813-11.165,24.813-24.937s-11.099-24.938-24.813-24.938zm37.563,0.5l-13.25,7.656,2.031,3.5,13.25-7.656-2.031-3.5zm-82.625,21.281v4.031h15.312v-4.031h-15.312zm74.688,0.25v4.031h15.312v-4.031h-15.312zm-57.219,14.094l-12.969,8.156,2.0938,3.407,13-8.126-2.125-3.437zm54.437,0.875l-1.968,3.531,13.406,7.438,1.937-3.531-13.375-7.438zm-10.187,12.25l-3.469,2,7.656,13.312,3.469-2-7.656-13.312zm-33.438,0.094l-7.406,13.437,3.5,1.969,7.437-13.438-3.531-1.968zm14.5,5.312v15.344h4.031v-15.344h-4.031zm37.719,2c-5.303,0-9.565,4.213-9.875,9.438-2.591,0.249-4.6,2.193-5.063,4.718-0.152-0.016-0.276-0.062-0.437-0.062-2.817,0-5.125,2.31-5.125,5.125,0,1.408,0.671,2.588,1.656,3.25,0.986,0.662,2.198,0.875,3.469,0.875h13.094,7.125,6.562c4.46,0,8.094-3.633,8.094-8.094s-3.633-8.094-8.094-8.094c-0.677,0-1.29,0.185-1.906,0.344-1.127-4.272-4.881-7.5-9.5-7.5zm0,1.906c4.035,0,7.328,2.983,7.938,6.844l0.187,1.156,1.094-0.437c0.693-0.263,1.427-0.406,2.187-0.406,3.432,0,6.188,2.756,6.188,6.187,0,3.432-2.756,6.188-6.188,6.188h-6.562-7.125-13.094c-1.031,0-1.884-0.212-2.406-0.563-0.522-0.35-0.813-0.762-0.813-1.656,0-1.785,1.432-3.219,3.219-3.219,0.296,0,0.576,0.057,0.906,0.156l1.25,0.376v-1.282c0-0.059-0.028-0.061-0.031-0.094,0-0.054-0.005-0.05,0-0.062-0.001-0.005,0.001-0.029,0-0.031,0.05-2.124,1.77-3.813,3.906-3.813-0.031,0,0.066,0.017,0.282,0.032l1.062,0.062-0.031-1.062c-0.012-0.261-0.063-0.343-0.063-0.282,0-4.471,3.62-8.094,8.094-8.094z"/>
</svg>

+ 3
- 0
static/img/fg.svg View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100">
<path d="M51.312,21.875c-5.183,0-9.974,1.68-13.874,4.5h27.687c-3.879-2.82-8.642-4.5-13.813-4.5zm-18.312,8.625c-1.135,1.375-2.102,2.891-2.906,4.5h42.312c-0.806-1.614-1.771-3.121-2.906-4.5h-36.5zm-4.5,8.625c-0.41,1.451-0.686,2.95-0.812,4.5h63.718c-2.932-1.897-6.403-3-10.156-3-2.34,0-4.568,0.47-6.625,1.25-0.15-0.948-0.368-1.843-0.625-2.75h-45.5zm-7.438,8.625c-2.041,1.037-3.774,2.58-5,4.5h82.532c-0.668-1.626-1.551-3.141-2.625-4.5h-74.907zm-6.718,8.625c-0.192,0.879-0.282,1.814-0.282,2.75,0,0.087,0.032,0.163,0.032,0.25-1.008-0.302-2.054-0.531-3.156-0.531-2.3633,0-4.5566,0.758-6.3442,2.031h95.344c0.039-0.499,0.062-0.991,0.062-1.5,0-1.025-0.092-2.02-0.25-3h-85.406zm-13.25,8.625c-0.66557,1.366-1.0531,2.889-1.0938,4.5h97.031c0.893-1.385,1.589-2.896,2.094-4.5h-98.031zm-0.25005,8.625c1.6598,3.194,5.5614,4.5,10.094,4.5h70.312c4.652,0,8.91-1.698,12.188-4.5h-92.594z"/>
</svg>

+ 3
- 0
static/img/fzra.svg View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100">
<path d="M42.312,14.812c-10.476,0-18.937,8.499-18.937,18.969,0,0.237,0.052,0.451,0.063,0.688-0.237-0.016-0.451-0.063-0.688-0.063-5.636,0-10.219,4.583-10.219,10.219,0,0.07,0.031,0.118,0.031,0.187-0.806-0.241-1.648-0.406-2.531-0.406-4.8342,0-8.7498,3.921-8.7498,8.75,0,4.835,3.9156,6.656,8.7498,6.656h56.25c8.287,0,15-6.713,15-15s-6.713-15-15-15c-1.872,0-3.667,0.408-5.312,1.032-1.431-9.057-9.202-16.032-18.657-16.032zm48.126,20.376c-1.21,0.03-2.276,0.423-3.126,1.124-1.06,0.875-1.75,2.193-1.75,3.719v30.188c-2.122,1.594-3.365,4.018-3.374,6.656-0.009,3.496,2.126,6.419,5.124,7.656,0.971,0.401,2.015,0.651,3.126,0.657,0.999,0.006,1.965-0.177,2.843-0.5,3.171-1.156,5.381-4.23,5.438-7.657,0.043-2.685-1.199-5.179-3.375-6.812v-30.407c0-1.612-0.821-2.962-2.063-3.781-0.799-0.529-1.772-0.817-2.812-0.843h-0.031zm0,2.156c0.579,0.015,1.147,0.174,1.593,0.468,0.692,0.457,1.157,1.227,1.157,2.126v31.5c2.005,1,3.374,3.074,3.374,5.468,0,3.372-2.753,6.094-6.124,6.094-3.372,0-6.094-2.722-6.094-6.094,0-2.393,1.369-4.468,3.375-5.468v-31.407c0-0.85,0.378-1.575,0.969-2.062,0.473-0.391,1.076-0.608,1.75-0.625zm-70.376,27.437l-7.218,19.844,1.531,0.563,7.437-20.407h-1.75zm8.25,0l-7.218,19.844,1.562,0.563,7.406-20.407h-1.75zm8.282,0l-7.219,19.844,1.531,0.563,7.438-20.407h-1.75zm8.25,0l-7.219,19.844,1.531,0.563,7.438-20.407h-1.75zm8.25,0l-7.219,19.844,1.563,0.563,7.406-20.407h-1.75zm8.281,0l-7.219,19.844,1.532,0.563,7.437-20.407h-1.75zm27.437,1.844v5.531c-1.966,0.681-3.374,2.552-3.374,4.75,0,2.774,2.226,5.032,5,5.032s5.031-2.258,5.031-5.032c0-2.198-1.408-4.069-3.375-4.75v-5.531h-3.282z"/>
</svg>

+ 3
- 0
static/img/fzrara.svg View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100">
<path d="M30.219,2c-7.202,0-13.031,5.8326-13.031,13.031,0,0.163,0.024,0.306,0.031,0.469-0.163-0.011-0.306-0.031-0.469-0.031-3.875,0-7,3.125-7,7v0.156c-0.5544-0.166-1.112-0.281-1.7188-0.281-3.3236,0-6.0312,2.679-6.0312,6,0,3.323,2.7076,4.594,6.0312,4.594h38.657c5.696,0,10.312-4.615,10.312-10.313,0-5.697-4.616-10.313-10.312-10.313-1.288,0-2.525,0.259-3.657,0.688-0.983-6.2265-6.313-11-12.812-11zm63.719,1.9375l-90,90,2.125,2.124,90-90-2.124-2.125zm-2.313,12.75c-0.939,0.03-1.808,0.36-2.469,0.906-0.833,0.688-1.344,1.706-1.344,2.906v23.75c-1.668,1.254-2.648,3.145-2.656,5.219-0.007,2.748,1.643,5.058,4,6.031,0.763,0.315,1.596,0.495,2.469,0.5,0.786,0.005,1.56-0.121,2.25-0.375,2.492-0.909,4.205-3.338,4.25-6.031,0.034-2.111-0.945-4.06-2.656-5.344v-23.906c0-1.267-0.618-2.325-1.594-2.969-0.621-0.411-1.412-0.662-2.219-0.687h-0.031zm0.031,1.718c0.456,0.012,0.869,0.144,1.219,0.375,0.544,0.359,0.906,0.951,0.906,1.657v24.781c1.577,0.786,2.657,2.399,2.657,4.281,0,2.65-2.132,4.812-4.782,4.812s-4.812-2.162-4.812-4.812c0-1.882,1.079-3.495,2.656-4.281v-24.688c0-0.668,0.286-1.242,0.75-1.625,0.372-0.307,0.876-0.486,1.406-0.5zm-76.75,17.938l-4.9685,13.625,1.0625,0.406,5.125-14.031h-1.219zm5.688,0l-4.969,13.625,1.063,0.406,5.124-14.031h-1.218zm5.687,0l-4.969,13.625,1.063,0.406,5.094-14.031h-1.188zm5.657,0l-4.938,13.625,1.062,0.406,5.094-14.031h-1.218zm5.687,0l-4.969,13.625,1.063,0.406,5.125-14.031h-1.219zm5.687,0l-4.968,13.625,1.062,0.406,5.094-14.031h-1.188zm47.032,5.062v4.375c-1.546,0.535-2.656,1.991-2.656,3.719,0,2.18,1.788,3.938,3.968,3.938,2.181,0,3.938-1.758,3.938-3.938,0-1.728-1.11-3.184-2.656-3.719v-4.375h-2.594zm-19.125,8.219c-7.202,0-13.031,5.833-13.031,13.031,0,0.163,0.024,0.337,0.031,0.5-0.163-0.011-0.306-0.062-0.469-0.062-3.875,0-7,3.156-7,7.031v0.125c-0.554-0.166-1.112-0.281-1.719-0.281-3.323,0-6.031,2.679-6.031,6,0,3.323,2.708,4.593,6.031,4.593h38.657c5.696,0.002,10.312-4.614,10.312-10.312,0-5.697-4.616-10.312-10.312-10.312-1.288,0-2.525,0.258-3.657,0.687-0.983-6.227-6.313-11-12.812-11zm-15.313,34.344l-4.968,13.656,1.062,0.375,5.125-14.031h-1.219zm5.688,0l-4.969,13.656,1.063,0.375,5.124-14.031h-1.218zm5.687,0l-4.969,13.656,1.063,0.375,5.094-14.031h-1.188zm5.657,0l-4.938,13.656,1.062,0.375,5.094-14.031h-1.218zm5.687,0l-4.969,13.656,1.063,0.375,5.125-14.031h-1.219zm5.687,0l-4.968,13.656,1.062,0.375,5.094-14.031h-1.188z"/>
</svg>

+ 1
- 0
static/img/help.svg View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path><line x1="12" y1="17" x2="12.01" y2="17"></line></svg>

+ 3
- 0
static/img/hi_shwrs.svg View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100">
<path d="m73.078,1.875,0,8.5312,2.2188,0,0-8.5312-2.2188,0zm-9.875,2.4062-1.875,1.2188,4.5,7.2188,1.9062-1.1875-4.5312-7.25zm22.125,0.25-4.125,7.4375,1.9375,1.0938,4.125-7.4688-1.9375-1.0625zm-31.844,8.125-1.0625,1.9375,7.4062,4.1562,1.0938-1.9688-7.4375-4.125zm20.719,0.3125c-7.625,0-13.812,6.224-13.812,13.875,0,7.65,6.1875,13.845,13.812,13.844,7.619,0,13.781-6.1928,13.781-13.844,0-7.65-6.1622-13.875-13.781-13.875zm20.875,0.28125-7.375,4.25,1.125,1.9688,7.375-4.2812-1.125-1.9375zm-45.906,11.812,0,2.25,8.5,0,0-2.25-8.5,0zm41.5,0.15625,0,2.2188,8.5,0,0-2.2188-8.5,0zm-31.812,7.8125-7.1875,4.5312,1.1562,1.9062,7.2188-4.5312-1.1875-1.9062zm30.25,0.5-1.0625,1.9688,7.4062,4.125,1.0938-1.9688-7.4375-4.125zm-54.094,3.5625c-8.8406,0-15.952,7.0403-16.469,15.75-4.3198,0.41518-7.666,3.6658-8.4375,7.875-0.25345-0.02661-0.4506-0.125-0.71875-0.125-4.6961,0-8.5625,3.8389-8.5625,8.5312,0,2.3476,1.108,4.3341,2.75,5.4375,1.6436,1.1041,3.6939,1.4688,5.8125,1.4688h21.812,11.875,10.938c7.4348,0,13.5-6.0639,13.5-13.5s-6.0638-13.5-13.5-13.5c-1.1286,0-2.1604,0.29785-3.1875,0.5625-1.8785-7.1211-8.1131-12.5-15.812-12.5zm0,3.1875c6.7262,0,12.201,4.9699,13.219,11.406l0.3125,1.9375,1.8438-0.75c1.1552-0.43828,2.3578-0.65625,3.625-0.65625,5.7208,0,10.344,4.5931,10.344,10.312,0,5.7208-4.6229,10.312-10.344,10.312h-10.938-11.875-21.812c-1.7188,0-3.1608-0.35219-4.0312-0.9375-0.8702-0.58322-1.3438-1.2907-1.3438-2.7812,0-2.9749,2.3959-5.3438,5.375-5.3438,0.49359,0,0.94969,0.08547,1.5,0.25l2.0938,0.625v-2.125c0-0.09802-0.0576-0.10094-0.0625-0.15625,0-0.08962-0.008-0.1047,0-0.125-0.001-0.0084,0.001-0.02845,0-0.03125,0.0833-3.5413,2.9391-6.375,6.5-6.375-0.0518,0,0.14013,0.0373,0.5,0.0625l1.75,0.09375-0.0625-1.75c-0.01274-0.28261-0.06568-0.42474-0.09375-0.46875,0-0.02538-0.0087-0.03558,0-0.03125,0.01709-7.4384,6.052-13.469,13.5-13.469zm48.438,0.0625-1.9062,1.125,4.25,7.375,1.9062-1.125-4.25-7.375zm-18.562,0.0625-4.125,7.4375,1.9688,1.0938,4.125-7.4688-1.9688-1.0625zm8.0625,2.9375,0,8.5312,2.2188,0,0-8.5312-2.2188,0zm-57.344,36.938-6.3438,17.344,1.375,0.5,6.5-17.844-1.5312,0zm12.031,0-6.3125,17.344,1.3438,0.5,6.5-17.844-1.5312,0zm12.062,0-6.3125,17.344,1.3438,0.5,6.5-17.844-1.5312,0zm12.031,0-6.2812,17.344,1.3438,0.5,6.5-17.844-1.5625,0z"/>
</svg>

+ 3
- 0
static/img/hi_tsra.svg View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100">
<path d="M73.906,0v8.5312h2.219v-8.5312h-2.219zm-9.875,2.4375l-1.875,1.1875,4.5,7.219,1.906-1.1878-4.531-7.2187zm22.125,0.2187l-4.125,7.4378,1.938,1.094,4.125-7.438-1.938-1.0938zm-31.844,8.1248l-1.062,1.969,7.406,4.125,1.094-1.969-7.438-4.125zm20.719,0.344c-7.625,0-13.812,6.193-13.812,13.844s6.186,13.845,13.812,13.843c7.619,0,13.781-6.192,13.781-13.843,0-7.65-6.162-13.844-13.781-13.844zm20.875,0.25l-7.375,4.281,1.125,1.938,7.375-4.25-1.125-1.969zm-45.906,11.844v2.25h8.5v-2.25h-8.5zm41.5,0.125v2.25h8.5v-2.25h-8.5zm-31.812,7.844l-7.188,4.531,1.156,1.875,7.219-4.5-1.187-1.906zm30.25,0.468l-1.063,1.969,7.406,4.156,1.094-1.969-7.437-4.156zm-54.032,3.344c-9.166,0-16.594,7.432-16.594,16.594,0,0.207,0.054,0.386,0.063,0.594-0.207-0.014-0.387-0.032-0.594-0.032-4.931,0-8.9372,3.975-8.9372,8.906,0,0.061,0.0312,0.127,0.0312,0.188-0.7072-0.211-1.4466-0.375-2.2188-0.375-4.23,0-7.6562,3.43-7.6562,7.656,0,4.23,3.4262,5.844,7.6562,5.844h49.219c7.251-0.001,13.125-5.874,13.125-13.125,0-7.252-5.874-13.125-13.125-13.125-1.638,0-3.185,0.36-4.625,0.906-1.252-7.924-8.071-14.031-16.344-14.031zm48.375,3.469l-1.906,1.125,4.25,7.375,1.906-1.094-4.25-7.406zm-18.562,0.062l-4.125,7.469,1.968,1.094,4.126-7.469-1.969-1.094zm8.062,2.938v8.531h2.219v-8.531h-2.219zm-41.062,34.593l-8.375,14.376h5.968l-4.781,9.562,14.375-14.375h-7.187l5.969-9.563h-5.969zm-16.281,2.657l-6.313,17.343,1.344,0.5,6.5-17.843h-1.531zm7.218,0l-6.312,17.343,1.344,0.5,6.5-17.843h-1.532zm21.688,0l-6.313,17.343,1.344,0.5,6.5-17.843h-1.531zm7.218,0l-6.312,17.343,1.375,0.5,6.5-17.843h-1.563z"/>
</svg>

+ 3
- 0
static/img/ip.svg View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100">
<path d="M51.312,4.6875c-13.094,0-23.718,10.6-23.718,23.688,0,0.296,0.08,0.579,0.094,0.875-0.296-0.02-0.58-0.094-0.876-0.094-7.044,0-12.75,5.705-12.75,12.75,0,0.087,0.032,0.163,0.032,0.25-1.008-0.302-2.054-0.5-3.156-0.5-6.0435,0-10.938,4.901-10.938,10.938,0,6.043,4.8945,8.344,10.938,8.344h70.312c10.358,0,18.75-8.392,18.75-18.75,0-10.36-8.391-18.75-18.75-18.75-2.34,0-4.568,0.47-6.625,1.25-1.788-11.322-11.495-20-23.313-20zm-9.562,59.594c-0.973,0.049-1.864,0.653-2.219,1.625-0.473,1.297,0.204,2.745,1.5,3.219,1.297,0.473,2.745-0.203,3.219-1.5s-0.203-2.745-1.5-3.219c-0.324-0.118-0.676-0.141-1-0.125zm34.438,0c-0.973,0.049-1.864,0.653-2.219,1.625-0.474,1.297,0.203,2.745,1.5,3.219,1.296,0.473,2.714-0.203,3.187-1.5,0.474-1.297-0.172-2.745-1.468-3.219-0.325-0.118-0.676-0.141-1-0.125zm-52.126,1c-0.778,0.039-1.497,0.535-1.781,1.313-0.379,1.037,0.182,2.183,1.219,2.562s2.184-0.181,2.562-1.218c0.379-1.038-0.181-2.184-1.218-2.563-0.26-0.095-0.522-0.107-0.782-0.094zm34.438,0c-0.778,0.039-1.497,0.535-1.781,1.313-0.379,1.037,0.15,2.183,1.187,2.562,1.038,0.379,2.184-0.181,2.563-1.218,0.379-1.038-0.151-2.184-1.188-2.563-0.259-0.095-0.522-0.107-0.781-0.094zm-19.125,5.5c-0.973,0.049-1.864,0.684-2.219,1.657-0.473,1.296,0.204,2.713,1.5,3.187,1.297,0.473,2.714-0.203,3.188-1.5,0.473-1.297-0.172-2.714-1.469-3.187-0.324-0.119-0.676-0.173-1-0.157zm34.437,0c-0.972,0.049-1.863,0.684-2.218,1.657-0.474,1.296,0.203,2.713,1.5,3.187,1.296,0.473,2.714-0.203,3.187-1.5,0.474-1.297-0.203-2.714-1.5-3.187-0.324-0.119-0.644-0.173-0.969-0.157zm-52.124,1c-0.779,0.039-1.498,0.535-1.782,1.313-0.379,1.037,0.151,2.183,1.188,2.562s2.215-0.15,2.594-1.187c0.378-1.038-0.182-2.184-1.219-2.563-0.26-0.094-0.522-0.138-0.781-0.125zm34.437,0c-0.778,0.039-1.497,0.535-1.781,1.313-0.379,1.037,0.15,2.183,1.187,2.562,1.038,0.379,2.184-0.15,2.563-1.187,0.379-1.038-0.151-2.184-1.188-2.563-0.259-0.094-0.522-0.138-0.781-0.125zm-19.125,5.5c-0.973,0.049-1.864,0.684-2.219,1.657-0.473,1.296,0.204,2.745,1.5,3.218,1.297,0.474,2.714-0.203,3.188-1.5,0.473-1.296-0.172-2.745-1.469-3.218-0.324-0.119-0.676-0.173-1-0.157zm34.438,0c-0.973,0.049-1.864,0.684-2.219,1.657-0.474,1.296,0.172,2.745,1.469,3.218,1.296,0.474,2.745-0.203,3.218-1.5,0.474-1.296-0.203-2.745-1.5-3.218-0.324-0.119-0.644-0.173-0.968-0.157zm-52.126,1c-0.778,0.039-1.497,0.535-1.781,1.313-0.379,1.037,0.151,2.215,1.188,2.594,1.037,0.378,2.183-0.182,2.562-1.219,0.379-1.038-0.15-2.184-1.187-2.563-0.26-0.094-0.522-0.138-0.782-0.125zm34.438,0c-0.778,0.039-1.497,0.535-1.781,1.313-0.379,1.037,0.15,2.215,1.187,2.594,1.038,0.378,2.184-0.182,2.563-1.219,0.379-1.038-0.151-2.184-1.188-2.563-0.259-0.094-0.522-0.138-0.781-0.125zm-19.125,5.531c-0.973,0.049-1.864,0.653-2.219,1.626-0.473,1.296,0.204,2.745,1.5,3.218,1.297,0.474,2.714-0.203,3.188-1.5,0.473-1.296-0.204-2.714-1.5-3.187-0.324-0.119-0.645-0.173-0.969-0.157zm34.437,0c-0.972,0.049-1.863,0.653-2.218,1.626-0.474,1.296,0.172,2.745,1.468,3.218,1.297,0.474,2.746-0.203,3.219-1.5,0.474-1.296-0.203-2.714-1.5-3.187-0.324-0.119-0.644-0.173-0.969-0.157zm-52.124,1c-0.779,0.039-1.498,0.535-1.782,1.313-0.379,1.037,0.151,2.184,1.188,2.563,1.037,0.378,2.183-0.151,2.562-1.188s-0.15-2.184-1.187-2.562c-0.26-0.095-0.522-0.138-0.781-0.126zm34.437,0c-0.778,0.039-1.497,0.535-1.781,1.313-0.379,1.037,0.15,2.184,1.187,2.563,1.038,0.378,2.184-0.151,2.563-1.188s-0.151-2.184-1.188-2.562c-0.259-0.095-0.522-0.138-0.781-0.126zm-24.844,2.219c-1.38,0-2.5,1.12-2.5,2.5,0,1.381,1.12,2.5,2.5,2.5,1.381,0,2.5-1.119,2.5-2.5,0-1.38-1.119-2.5-2.5-2.5zm34.438,0c-1.381,0-2.5,1.12-2.5,2.5,0,1.381,1.119,2.5,2.5,2.5,1.38,0,2.5-1.119,2.5-2.5,0-1.38-1.12-2.5-2.5-2.5zm-52.156,1c-1.1046,0-2,0.896-2,2,0,1.105,0.8954,2,2,2s1.9995-0.895,1.9995-2c0-1.104-0.8949-2-1.9995-2zm34.438,0c-1.105,0-2,0.896-2,2,0,1.105,0.895,2,2,2s2-0.895,2-2c0-1.104-0.895-2-2-2zm-11,2.281c-0.973,0.049-1.864,0.684-2.219,1.657-0.473,1.296,0.172,2.714,1.469,3.187,1.297,0.474,2.745-0.172,3.219-1.468,0.473-1.297-0.204-2.746-1.5-3.219-0.324-0.119-0.645-0.173-0.969-0.157zm34.438,0c-0.973,0.049-1.864,0.684-2.219,1.657-0.474,1.296,0.172,2.714,1.469,3.187,1.296,0.474,2.745-0.172,3.218-1.468,0.474-1.297-0.203-2.746-1.5-3.219-0.324-0.119-0.644-0.173-0.968-0.157zm-52.126,1c-0.778,0.039-1.497,0.535-1.781,1.313-0.379,1.037,0.151,2.184,1.188,2.563,1.037,0.378,2.183-0.151,2.562-1.188s-0.15-2.184-1.187-2.562c-0.26-0.095-0.522-0.138-0.782-0.126zm34.438,0c-0.778,0.039-1.497,0.535-1.781,1.313-0.379,1.037,0.15,2.184,1.187,2.563,1.038,0.378,2.184-0.151,2.563-1.188s-0.151-2.184-1.188-2.562c-0.259-0.095-0.522-0.138-0.781-0.126z"/>
</svg>

+ 3
- 0
static/img/mist.svg View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100">
<path d="m51.312,5.9375c-5.183,0-9.975,1.68-13.875,4.5h27.688c-3.879-2.82-8.6415-4.5-13.812-4.5zm-18.312,8.6245c-1.135,1.375-2.1022,2.891-2.9062,4.5h42.312c-0.806-1.614-1.7712-3.121-2.9062-4.5h-36.5zm-4.5,8.625c-0.41,1.451-0.6865,2.95-0.8125,4.5h12.469v4.125h-19.094c-2.041,1.037-3.774,2.58-5,4.5h24.094v4.125h-25.812c-0.192,0.879-0.28125,1.814-0.28125,2.75,0,0.087,0.03125,0.163,0.03125,0.25-1.008-0.302-2.0542-0.53125-3.1562-0.53125-2.3633,0-4.5562,0.75825-6.3438,2.0312h35.562v4.125h-6.25v-3.6875h-20.406v3.6875h-12.406c-0.66682,1.366-1.0543,2.89-1.095,4.5h13.5v4.125h-12.656c1.6598,3.194,5.5611,4.5,10.094,4.5h2.5625v21.281h-13.5v10.594h100v-10.594h-12.75v-22.312c2.2843-0.7748,4.3939-1.9356,6.1875-3.4688h-6.1875v-4.125h9.7812c0.893-1.385,1.5888-2.896,2.0938-4.5h-35.406v-4.125h36.219c0.039-0.499,0.0625-0.991,0.0625-1.5,0-1.025-0.092-2.02-0.25-3h-36.031v-4.125h34.875c-0.668-1.626-1.551-3.141-2.625-4.5h-32.25v-4.125h27.688c-2.932-1.897-6.4032-3-10.156-3-2.34,0-4.568,0.47-6.625,1.25-0.15-0.948-0.368-1.843-0.625-2.75h-45.5zm14.094,6.3438,7.4375,0,0,2.2812-7.4375,0,0-2.2812zm11.25,0,7.4375,0,0,2.2812-7.4375,0,0-2.2812zm-11.25,8.125,7.4375,0,0,2.7812-7.4375,0,0-2.7812zm11.25,0,7.4375,0,0,2.7812-7.4375,0,0-2.7812zm-37.375,15.906,4.5625,0,0,2.3125-4.5625,0,0-2.3125zm9.875,0,4.5625,0,0,2.3125-4.5625,0,0-2.3125zm7.5625,0,6.25,0,0,4.125-6.25,0,0-4.125zm29.812,0,9.4062,0,0,4.125-9.4062,0,0-4.125zm-29.812,8.625,6.25,0,0,21.281-6.25,0,0-21.281zm29.812,0,9.4062,0,0,21.281-9.4062,0,0-21.281z"/>
</svg>

+ 3
- 0
static/img/mix.svg View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100">
<path d="M25.5,2l-2.25,1.4688v7.0312l-3.938-2.1875-2,1.1563v2.4692l5.844,3.312v4.625l-4.344-2.313v4.782l-4.124-2.375v-6.781l-2.25-1.313-1.876,1.25v4.531l-6.1558-3.531-2.4062,1.219v2.812l6.25,3.406-3.9062,2.188v2.562l2.1562,1.094,5.781-3.406,4.031,2.312-4,2.5,4.126,2.344,0.093,0.094-4.031,2.312-5.7812-3.406-2.3126,1.25v2.563l4.0626,2.031-6.4688,3.531v2.813l2.625,1.094,6.156-3.469v4.469l1.875,1.25,2.219-1.376v-6.656l4.031-2.344v4.907l4.25-2.719v4.625l-5.844,3.344v2.469l2,1.156,3.938-2.219v7.063l2.25,1.437,2.281-1.437v-7.063l3.938,2.219,2-1v-2.625l-5.844-3.344v-4.625l4.125,2.531v-4.625l4.344,2.438v6.687l2.031,1.157,2.094-1.157v-4.406l5.843,3.313,2.532-1.126v-2.781l-5.938-3.531,3.719-2.094v-2.406l-1.906-1.344-5.969,3.313-4.219-2.188,4.094-2.375-3.969-2.468,4.094-2.626,5.969,3.532,2-1.125v-2.5l-3.875-2.188,6.187-3.5v-2.625l-2.219-1.375-6.343,3.438v-4.657l-2.157-0.937-2.031,0.937v7.282l-4.281,2.312v-5.031l-4.125,2.5v-4.625l6.063-3.438v-2.187l-2.063-1.375-4.094,2.25v-7.0312l-2.281-1.4688zm68.438,1.9375l-90,90,2.125,2.124,90-90-2.124-2.125zm-2.313,10.75c-0.939,0.03-1.808,0.36-2.469,0.906-0.833,0.688-1.344,1.706-1.344,2.906v23.75c-1.668,1.254-2.648,3.145-2.656,5.219-0.007,2.748,1.643,5.058,4,6.031,0.763,0.315,1.596,0.495,2.469,0.5,0.786,0.005,1.56-0.121,2.25-0.375,2.492-0.909,4.205-3.338,4.25-6.031,0.034-2.111-0.945-4.06-2.656-5.344v-23.906c0-1.267-0.618-2.325-1.594-2.969-0.621-0.411-1.412-0.662-2.219-0.687h-0.031zm0.031,1.718c0.456,0.012,0.869,0.144,1.219,0.375,0.544,0.359,0.906,0.951,0.906,1.657v24.781c1.577,0.786,2.657,2.399,2.657,4.281,0,2.65-2.132,4.812-4.782,4.812s-4.812-2.162-4.812-4.812c0-1.882,1.079-3.495,2.656-4.281v-24.688c0-0.668,0.286-1.242,0.75-1.625,0.372-0.307,0.876-0.486,1.406-0.5zm-68,9.125h3.938l1.906,3.313-1.812,3.125h-3.938l-2.125-3.125,2.031-3.313zm66.688,13.875v4.375c-1.546,0.535-2.656,1.991-2.656,3.719,0,2.18,1.788,3.938,3.968,3.938,2.181,0,3.938-1.758,3.938-3.938,0-1.728-1.11-3.184-2.656-3.719v-4.375h-2.594zm-22.25,4.563c-8.046,0-14.563,6.521-14.563,14.562,0,0.182,0.024,0.35,0.031,0.531-0.181-0.012-0.349-0.062-0.531-0.062-4.328,0-7.843,3.515-7.843,7.844,0,0.053,0.031,0.103,0.031,0.156-0.62-0.186-1.26-0.312-1.938-0.312-3.713,0-6.719,3.009-6.719,6.718,0,3.713,3.006,5.125,6.719,5.125h43.188c6.364-0.002,11.531-5.166,11.531-11.531,0-6.364-5.167-11.5-11.531-11.5-1.438,0-2.799,0.271-4.063,0.75-1.098-6.956-7.051-12.281-14.312-12.281zm-17.094,38.343l-5.562,15.25,1.187,0.438,5.719-15.688h-1.344zm6.344,0l-5.563,15.25,1.188,0.438,5.719-15.688h-1.344zm6.344,0l-5.563,15.25,1.187,0.438,5.719-15.688h-1.343zm6.343,0l-5.562,15.25,1.187,0.438,5.719-15.688h-1.344zm6.344,0l-5.563,15.25,1.188,0.438,5.719-15.688h-1.344zm6.344,0l-5.563,15.25,1.188,0.438,5.718-15.688h-1.343z"/>
</svg>

+ 1
- 0
static/img/moon.svg View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>

+ 3
- 0
static/img/nsurtsra.svg View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100">
<path d="M50,0c-20.898,0-40.913,4.784-46.875,9.375,2.805,6.747,33.855,9.375,46.875,9.375s43.548-3.544,46.875-9.375c-3.864-5.116-23.854-9.375-46.875-9.375zm-46.844,12.5c-0.049,0.195-1.661,18.125,28.125,28.125,20.639,6.924,9.375,18.75,9.375,18.75s-22.412,21.25-3.156,28.125c12.062,4.292,10.92,10.118,9.375,12.5,11.7-14.721-21.6-17.334,15.656-34.375,19.116-8.754,21.485-13.846,15.594-21.875-7.717-10.55,17.12-14.778,18.75-31.25-7.369,5.788-26.346,9.033-46.875,9.375-23.121-0.378-41.557-1.987-46.844-9.375z"/>
</svg>

+ 3
- 0
static/img/ovc.svg View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100">
<path d="m81.245,40.626c-2.34,0-4.558,0.484-6.615,1.264-1.788-11.321-11.508-20.013-23.326-20.013-13.095,0-23.702,10.608-23.702,23.696,0,0.296,0.081,0.571,0.094,0.867-0.296-0.02-0.578-0.087-0.874-0.087-7.045,0-12.759,5.714-12.759,12.759,0,0.087,0.027,0.168,0.027,0.255-1.008-0.302-2.05-0.518-3.153-0.518-6.043,0-10.937,4.901-10.937,10.938,0,6.043,4.894,8.335,10.937,8.335h70.308c10.358,0,18.755-8.389,18.755-18.748s-8.396-18.748-18.755-18.748z"/>
</svg>

+ 3
- 0
static/img/ra.svg View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100">
<path d="M51.312,6.0312c-13.094,0-23.718,10.6-23.718,23.688,0,0.296,0.08,0.579,0.094,0.875-0.296-0.02-0.58-0.094-0.876-0.094-7.044,0-12.75,5.705-12.75,12.75,0,0.087,0.032,0.194,0.032,0.281-1.008-0.302-2.054-0.531-3.156-0.531-6.0435,0-10.938,4.9-10.938,10.938,0,6.042,4.8945,8.343,10.938,8.343h34.374,18.719,17.219c10.358,0,18.75-8.391,18.75-18.75s-8.391-18.75-18.75-18.75c-2.34,0-4.568,0.47-6.625,1.25-1.788-11.321-11.495-20-23.313-20zm-27.843,62.438l-9.031,24.781,1.937,0.719,9.313-25.5h-2.219zm10.343,0l-9.031,24.781,1.938,0.719,9.281-25.5h-2.188zm10.313,0l-9.031,24.781,1.937,0.719,9.281-25.5h-2.187zm10.344,0l-9.031,24.781,1.937,0.719,9.281-25.5h-2.187zm10.312,0l-9.031,24.781,1.938,0.719,9.281-25.5h-2.188zm10.313,0l-9,24.781,1.937,0.719,9.281-25.5h-2.218z"/>
</svg>

+ 3
- 0
static/img/ra1.svg View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100">
<path d="M51.312,6.0312c-13.094,0-23.718,10.6-23.718,23.688,0,0.296,0.08,0.579,0.094,0.875-0.296-0.02-0.58-0.094-0.876-0.094-7.044,0-12.75,5.705-12.75,12.75,0,0.087,0.032,0.194,0.032,0.281-1.008-0.302-2.054-0.531-3.156-0.531-6.0435,0-10.938,4.9-10.938,10.938,0,6.042,4.8945,8.343,10.938,8.343h70.312c10.358,0,18.75-8.391,18.75-18.75s-8.391-18.75-18.75-18.75c-2.34,0-4.568,0.47-6.625,1.25-1.788-11.321-11.495-20-23.313-20zm-27.843,62.438l-9.031,24.781,1.937,0.719,9.313-25.5h-2.219zm17.219,0l-9.032,24.781,1.938,0.719,9.281-25.5h-2.187zm17.218,0l-9.031,24.781,1.937,0.719,9.282-25.5h-2.188zm17.188,0l-9,24.781,1.937,0.719,9.281-25.5h-2.218z"/>
</svg>

+ 3
- 0
static/img/raip.svg
File diff suppressed because it is too large
View File


+ 3
- 0
static/img/rasn.svg View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100">
<path d="M25.5,2l-2.25,1.4688v7.0312l-3.938-2.1875-2,1.1563v2.4692l5.844,3.312v4.625l-4.344-2.313v4.782l-4.124-2.375v-6.781l-2.25-1.313-1.876,1.25v4.531l-6.1558-3.531-2.4062,1.219v2.812l6.25,3.406-3.9062,2.188v2.562l2.1562,1.094,5.781-3.406,4.031,2.312-4,2.5,4.126,2.344,0.093,0.094-4.031,2.312-5.7812-3.406-2.3126,1.25v2.563l4.0626,2.031-6.4688,3.531v2.813l2.625,1.094,6.156-3.469v4.469l1.875,1.25,2.219-1.376v-6.656l4.031-2.344v4.907l4.25-2.719v4.625l-5.844,3.344v2.469l2,1.156,3.938-2.219v7.063l2.25,1.437,2.281-1.437v-7.063l3.938,2.219,2-1v-2.625l-5.844-3.344v-4.625l4.125,2.531v-4.625l4.344,2.438v6.687l2.031,1.157,2.094-1.157v-4.406l5.843,3.313,2.532-1.126v-2.781l-5.938-3.531,3.719-2.094v-2.406l-1.906-1.344-5.969,3.313-4.219-2.188,4.094-2.375-3.969-2.468,4.094-2.626,5.969,3.532,2-1.125v-2.5l-3.875-2.188,6.187-3.5v-2.625l-2.219-1.375-6.343,3.438v-4.657l-2.157-0.937-2.031,0.937v7.282l-4.281,2.312v-5.031l-4.125,2.5v-4.625l6.063-3.438v-2.187l-2.063-1.375-4.094,2.25v-7.0312l-2.281-1.4688zm68.438,1.9375l-90,90,2.125,2.124,90-90-2.124-2.125zm-70.282,21.594h3.938l1.906,3.313-1.812,3.125h-3.938l-2.125-3.125,2.031-3.313zm44.438,16.438c-8.046,0-14.563,6.521-14.563,14.562,0,0.182,0.024,0.35,0.031,0.531-0.181-0.012-0.349-0.062-0.531-0.062-4.328,0-7.843,3.515-7.843,7.844,0,0.053,0.031,0.103,0.031,0.156-0.62-0.186-1.26-0.312-1.938-0.312-3.713,0-6.719,3.009-6.719,6.718,0,3.713,3.006,5.125,6.719,5.125h43.188c6.364-0.002,11.531-5.166,11.531-11.531,0-6.364-5.167-11.5-11.531-11.5-1.438,0-2.799,0.271-4.063,0.75-1.098-6.956-7.051-12.281-14.312-12.281zm-17.094,38.343l-5.562,15.25,1.187,0.438,5.719-15.688h-1.344zm6.344,0l-5.563,15.25,1.188,0.438,5.719-15.688h-1.344zm6.344,0l-5.563,15.25,1.187,0.438,5.719-15.688h-1.343zm6.343,0l-5.562,15.25,1.187,0.438,5.719-15.688h-1.344zm6.344,0l-5.563,15.25,1.188,0.438,5.719-15.688h-1.344zm6.344,0l-5.563,15.25,1.188,0.438,5.718-15.688h-1.343z"/>
</svg>

+ 3
- 0
static/img/rasn1.svg View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100">
<path d="M 25.5,2 23.25,3.4688 V 10.5 l -3.938,-2.1875 -2,1.1563 v 2.4692 l 5.844,3.312 v 4.625 l -4.344,-2.313 v 4.782 l -4.124,-2.375 v -6.781 l -2.25,-1.313 -1.876,1.25 v 4.531 L 4.4062,14.125 2,15.344 v 2.812 l 6.25,3.406 -3.9062,2.188 v 2.562 L 6.5,27.406 12.281,24 l 4.031,2.312 -4,2.5 4.126,2.344 0.093,0.094 -4.031,2.312 -5.7812,-3.406 -2.3126,1.25 v 2.563 L 8.4688,36 2,39.531 v 2.813 l 2.625,1.094 6.156,-3.469 v 4.469 l 1.875,1.25 2.219,-1.376 v -6.656 l 4.031,-2.344 v 4.907 l 4.25,-2.719 v 4.625 l -5.844,3.344 v 2.469 l 2,1.156 3.938,-2.219 v 7.063 l 2.25,1.437 2.281,-1.437 v -7.063 l 3.938,2.219 2,-1 V 45.469 L 27.875,42.125 V 37.5 L 32,40.031 v -4.625 l 4.344,2.438 v 6.687 l 2.031,1.157 2.094,-1.157 v -4.406 l 5.843,3.313 2.532,-1.126 V 39.531 L 42.906,36 46.625,33.906 V 31.5 l -1.906,-1.344 -5.969,3.313 -4.219,-2.188 4.094,-2.375 -3.969,-2.468 4.094,-2.626 5.969,3.532 2,-1.125 v -2.5 l -3.875,-2.188 6.187,-3.5 v -2.625 l -2.219,-1.375 -6.343,3.438 v -4.657 l -2.157,-0.937 -2.031,0.937 v 7.282 L 32,22.406 v -5.031 l -4.125,2.5 V 15.25 l 6.063,-3.438 V 9.625 L 31.875,8.25 27.781,10.5 V 3.4688 Z m 68.438,1.9375 -90,90 2.125,2.124 90,-90 -2.124,-2.125 z m -70.282,21.594 h 3.938 l 1.906,3.313 -1.812,3.125 H 23.75 l -2.125,-3.125 z m 44.438,16.438 c -8.046,0 -14.563,6.521 -14.563,14.562 0,0.182 0.024,0.35 0.031,0.531 -0.181,-0.012 -0.349,-0.062 -0.531,-0.062 -4.328,0 -7.843,3.515 -7.843,7.844 0,0.053 0.031,0.103 0.031,0.156 -0.62,-0.186 -1.26,-0.312 -1.938,-0.312 -3.713,0 -6.719,3.009 -6.719,6.718 0,3.713 3.006,5.125 6.719,5.125 H 86.469 C 92.833,76.5295 98,71.3655 98,65.0005 c 0,-6.364 -5.167,-11.5 -11.531,-11.5 -1.438,0 -2.799,0.271 -4.063,0.75 -1.098,-6.956 -7.051,-12.281 -14.312,-12.281 z M 51,80.3125 l -5.562,15.25 1.187,0.438 5.719,-15.688 z m 10.688,0 -5.563,15.25 1.187,0.438 5.719,-15.688 z m 10.343,0 -5.562,15.25 1.187,0.438 5.719,-15.688 z m 10.688,0 -5.563,15.25 1.188,0.438 5.718,-15.688 z"/>
</svg>

+ 3
- 0
static/img/sct.svg View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100">
<path d="M33.469,15v11.938h3.125v-11.938h-3.125zm-13.813,3.406l-2.656,1.656,6.312,10.126,2.657-1.657-6.313-10.125zm30.938,0.313l-5.782,10.437,2.75,1.532,5.782-10.438-2.75-1.531zm-44.532,11.375l-1.5313,2.75,10.407,5.781,1.5-2.75-10.376-5.781zm28.968,0.468c-10.675,0-19.312,8.695-19.312,19.407,0,9.054,6.173,16.619,14.531,18.75-3.104,1.593-5.25,4.819-5.25,8.531,0,2.64,1.214,4.853,3.062,6.094,1.508,1.012,3.31,1.457,5.219,1.594v0.062h1.313,1.812,22.75,13.375,12.281c8.363,0,15.188-6.823,15.188-15.188,0-8.364-6.824-15.156-15.188-15.156-1.204,0-2.335,0.198-3.437,0.469-2.148-7.959-9.313-13.875-17.937-13.875-3.692,0-7.108,1.081-10,2.938-2.449-7.888-9.748-13.626-18.407-13.626zm29.219,0.376l-10.281,5.968,1.562,2.719,10.313-5.969-1.594-2.718zm-0.812,13.874c7.565,0,13.762,5.572,14.906,12.813l0.312,2.156,2.063-0.781c1.3-0.493,2.668-0.781,4.093-0.781,6.436,0,11.626,5.159,11.626,11.593,0,6.435-5.191,11.626-11.626,11.626h-12.281-13.375-24.562c-1.933,0-3.553-0.406-4.532-1.063-0.978-0.657-1.5-1.449-1.5-3.125,0-3.347,2.681-6.031,6.032-6.031,0.554,0,1.13,0.126,1.75,0.312l2.281,0.688v-2.407-0.187c0-4.067,3.246-7.313,7.313-7.313-0.059,0,0.097,0.036,0.5,0.063l2,0.125-0.094-2c-0.022-0.488-0.063-0.646-0.063-0.531,0-8.384,6.767-15.157,15.157-15.157zm-63.438,2.688v3.125h11.906v-3.125h-11.906zm13.562,11.156l-10.062,6.344,1.625,2.656,10.094-6.344-1.657-2.656zm8.438,10.282l-5.75,10.468,2.719,1.5,5.781-10.437-2.75-1.531z"/>
</svg>

+ 3
- 0
static/img/shra.svg View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100">
<path d="M51.188,6.8125c-12.627,0-22.762,10.028-23.5,22.468-6.17,0.593-10.961,5.238-12.063,11.25-0.362-0.038-0.648-0.156-1.031-0.156-6.7074,0-12.219,5.485-12.219,12.187,0,3.353,1.5923,6.174,3.9375,7.75,2.3476,1.577,5.2555,2.094,8.2815,2.094h31.156,16.969,15.625c10.619,0,19.281-8.66,19.281-19.281s-8.66-19.281-19.281-19.281c-1.612,0-3.065,0.434-4.532,0.812-2.683-10.171-11.627-17.844-22.624-17.844zm0,4.5315c9.607,0,17.453,7.119,18.906,16.312l0.437,2.75,2.625-1.062c1.65-0.626,3.378-0.938,5.188-0.938,8.171,0,14.75,6.55,14.75,14.719,0,8.171-6.579,14.719-14.75,14.719h-15.625-16.969-31.156c-2.455,0-4.507-0.508-5.7502-1.344-1.2429-0.833-1.9376-1.809-1.9376-3.938,0-4.249,3.4328-7.656,7.6878-7.656,0.705,0,1.37,0.14,2.156,0.375l2.969,0.907v-3.063c0-0.14-0.056-0.14-0.063-0.219,0-0.128-0.012-0.127,0-0.156-0.002-0.012,0.002-0.058,0-0.062,0.119-5.058,4.196-9.094,9.282-9.094-0.074,0,0.173,0.058,0.687,0.094l2.531,0.124-0.094-2.531c-0.028-0.621-0.156-0.801-0.156-0.656,0-10.645,8.629-19.281,19.282-19.281zm-27.719,57.125l-9.031,24.781,1.937,0.719,9.313-25.5h-2.219zm17.219,0l-9.032,24.781,1.938,0.719,9.281-25.5h-2.187zm17.218,0l-9.031,24.781,1.937,0.719,9.282-25.5h-2.188zm17.188,0l-9,24.781,1.937,0.719,9.281-25.5h-2.218z"/>
</svg>

+ 3
- 0
static/img/skc.svg View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100">
<path d="M47.812,0v17.062h4.469v-17.062h-4.469zm-19.718,4.875l-3.782,2.375,9,14.438,3.782-2.344-9-14.469zm44.187,0.4375l-8.25,14.906,3.938,2.187,8.219-14.906-3.907-2.1875zm-63.625,16.25l-2.1874,3.938,14.843,8.25,2.188-3.906-14.844-8.282zm41.406,0.657c-15.25,0-27.624,12.417-27.624,27.719,0,15.3,12.374,27.721,27.624,27.718,15.24,0,27.594-12.416,27.594-27.718s-12.356-27.719-27.594-27.719zm41.75,0.531l-14.718,8.531,2.218,3.907,14.719-8.532-2.219-3.906zm-91.812,23.688v4.468h17v-4.468h-17zm83,0.25v4.5h17v-4.5h-17zm-63.594,15.687l-14.406,9.031,2.3438,3.813,14.406-9.063-2.344-3.781zm60.5,0.969l-2.187,3.906,14.875,8.281,2.187-3.937-14.875-8.25zm-11.312,13.625l-3.875,2.219,8.5,14.781,3.875-2.25-8.5-14.75zm-37.156,0.093l-8.25,14.938,3.906,2.156,8.25-14.937-3.906-2.157zm16.093,5.876v17.062h4.469v-17.062h-4.469z"/>
</svg>

+ 3
- 0
static/img/smoke.svg View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100">
<path d="M51.312,0c-5.182,0-9.974,1.68-13.874,4.5h27.687c-3.879-2.82-8.641-4.5-13.813-4.5zm-18.312,8.625c-1.135,1.375-2.102,2.891-2.906,4.5h42.312c-0.806-1.614-1.771-3.121-2.906-4.5h-36.5zm-4.5,8.625c-0.41,1.451-0.686,2.95-0.812,4.5h63.718c-2.932-1.897-6.403-3-10.156-3-2.34,0-4.568,0.47-6.625,1.25-0.15-0.948-0.368-1.843-0.625-2.75h-45.5zm-7.438,8.625c-2.04,1.037-3.774,2.58-5,4.5h82.532c-0.668-1.626-1.551-3.141-2.625-4.5h-74.907zm-6.718,8.625c-0.192,0.879-0.282,1.814-0.282,2.75,0,0.087,0.032,0.163,0.032,0.25-1.008-0.302-2.054-0.531-3.156-0.531-2.3638,0-4.5566,0.758-6.3442,2.031h95.344c0.038-0.499,0.062-0.991,0.062-1.5,0-1.025-0.092-2.02-0.25-3h-85.406zm-13.25,8.625c-0.66562,1.366-1.0531,2.889-1.0938,4.5h97.031c0.893-1.385,1.589-2.896,2.094-4.5h-98.031zm-0.25005,8.625c1.6598,3.194,5.5612,4.5,10.094,4.5h70.312c4.652,0,8.91-1.698,12.188-4.5h-92.594zm36.781,5.469c-1.524,1.269-2.656,2.59-2.656,3.969,0,0.735,0.502,1.755,1.312,2.624,0.926,1.072,1.199,2.288,1.344,2.657,0.959-0.765,1.313-1.671,1.313-2.657,0-0.735-0.801-1.727-1.313-2.624-0.66-1.214,0.153-2.866,0-3.969zm-6.625,2.625c-0.004,0.156-3.809,6.267-1.344,9.281,3.827,4.666,2.211,8.27,0,7.937-3.714-0.556-3.241-5.403-2.625-6.624-1.941-0.205-4.201,1.01-5.312,2.656-3.342,4.963,3.887,9.72,1.312,13.25-1.959,2.689-5.292-2.615-5.281-2.656-3.976,20.752,24.882,21.272,26.469,3.968,0.472-5.19,5.162-8.004,5.312-7.937-4.976-2.295-7.937,1.478-7.937,1.312,0-0.65,2.782-9.29-2.656-11.906-6.267-3.014-7.99-5.429-7.938-9.281zm-1.344,23.844c0.02,0.041,3.265,0.534,5.313,2.656,3.14,3.242,2.773,9.076-2.657,9.281-6.942,0.256-6.212-4.95-5.281-6.625,1.183-2.133,4.153-2.568,2.625-5.312z"/>
</svg>

+ 3
- 0
static/img/sn.svg View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100">
<path d="m42.732,50.287,3.955,5.841,7.365,0,3.398-5.841-3.58-6.22-7.379,0zm3.033,46.974,0-13.207-7.379,4.15-3.759-2.152,0-4.653,10.943-6.22,0-8.68-7.939,5.102,0-9.196-7.589,4.374,0,12.468-4.151,2.572-3.508-2.321,0-8.356-11.518,6.498-4.919-2.07,0-5.27,12.089-6.609-7.561-3.801,0-4.822,4.291-2.349,10.845,6.386,7.533-4.346-0.182-0.139-7.701-4.417,7.477-4.64-7.505-4.346-10.844,6.372-4.068-2.026,0-4.808,7.339-4.123-11.713-6.36,0-5.269,4.5-2.319,11.544,6.666,0-8.497,3.48-2.348,4.264,2.46-0.028,12.718,7.756,4.43-0.027-8.986,8.134,4.375,0-8.68-10.943-6.233,0-4.612,3.759-2.18,7.379,4.151,0-13.18,4.222-2.768,4.261,2.768,0,13.18,7.646-4.235,3.845,2.544,0,4.151-11.322,6.414,0,8.68,7.744-4.724,0,9.448,7.979-4.348,0-13.598,3.844-1.789,4.038,1.789,0,8.694,11.879-6.416,4.153,2.53,0,4.919-11.601,6.597,7.254,4.066,0,4.697-3.76,2.083-11.138-6.583-7.702,4.892,7.449,4.642-7.673,4.416,7.926,4.15,11.138-6.221,3.578,2.53,0,4.487-6.988,3.927,11.126,6.61,0,5.188-4.71,2.152-10.931-6.221,0,8.232-3.927,2.194-3.843-2.194,0-12.496-8.092-4.611,0,8.68-7.744-4.725,0,8.68,10.944,6.22,0,4.92-3.776,1.886-7.337-4.15,0,13.207-4.26,2.738z"/>
</svg>

+ 1
- 0
static/img/sun.svg View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="5"/><path d="M12 1v2M12 21v2M4.2 4.2l1.4 1.4M18.4 18.4l1.4 1.4M1 12h2M21 12h2M4.2 19.8l1.4-1.4M18.4 5.6l1.4-1.4"/></svg>

+ 3
- 0
static/img/tsra.svg View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100">
<path d="M51.312,3.5625c-13.094,0-23.718,10.63-23.718,23.718,0,0.296,0.08,0.548,0.094,0.844-0.296-0.02-0.58-0.063-0.876-0.063-7.044,0-12.75,5.706-12.75,12.75,0,0.088,0.032,0.164,0.032,0.25-1.008-0.302-2.054-0.5-3.156-0.5-6.0435,0-10.938,4.901-10.938,10.938,0,6.043,4.8945,8.312,10.938,8.312h70.312c10.358,0,18.75-8.39,18.75-18.75,0-10.358-8.391-18.75-18.75-18.75-2.34,0-4.568,0.502-6.625,1.282-1.788-11.321-11.495-20.032-23.313-20.032zm-4.593,58.656l-11.969,20.531h8.562l-6.843,13.688,20.531-20.532h-10.281l8.562-13.687h-8.562zm-23.25,3.781l-9.031,24.812,1.937,0.719,9.313-25.531h-2.219zm10.343,0l-9.031,24.812,1.938,0.719,9.281-25.531h-2.188zm30.969,0l-9.031,24.812,1.938,0.719,9.281-25.531h-2.188zm10.313,0l-9,24.812,1.937,0.719,9.281-25.531h-2.218z"/>
</svg>

+ 3
- 0
static/img/wind.svg View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100">
<path d="M62.781,0.0062768c-1.621,0.18889-7.737,6.4392-19.093,25.311,3.0187,0.032,5.663,1.6919,7.0938,4.1247,11.41-20.557,13.346-28.772,12.25-29.404-0.0685-0.039435-0.14194-0.043841-0.25-0.031248zm-19.187,29.467c-2.2942,0-4.1562,1.8647-4.1562,4.156s1.862,4.156,4.1562,4.156,4.1562-1.8647,4.1562-4.156-1.862-4.156-4.1562-4.156zm-7.2188,0.0625c-23.477,0.41497-31.531,2.8316-31.531,4.0935,0,1.2609,8.0532,3.6795,31.531,4.0935-0.68785-1.2069-1.0938-2.6066-1.0938-4.0935,0-1.4859,0.40594-2.8856,1.0938-4.0935zm14.406,8.2495c-1.4238,2.4358-4.0448,4.0887-7.0625,4.1247,12.105,20.107,18.216,25.878,19.312,25.248,1.0943-0.63196-0.84705-8.8283-12.25-29.373zm-50.468,2.062c-0.063218-0.0073-0.11601,0.0082-0.15625,0.03125-0.6438,0.373,0.50625,5.156,7.0312,16.999,0.9162-1.38,2.4383-2.304,4.1875-2.438-6.5661-10.832-10.114-14.483-11.062-14.592zm65.062,0c-0.06321-0.0073-0.11601,0.0082-0.15625,0.03125-0.643,0.37298,0.50625,5.1567,7.0312,16.999,0.9172-1.3799,2.4393-2.3034,4.1875-2.4373-6.566-10.833-10.113-14.484-11.061-14.593zm-25.938,3.0311,0,57.121,8.3125,0,0-43.935c-2.379-3.518-5.134-7.856-8.31-13.186zm-27.655,14.28c-1.5295,0-2.75,1.2223-2.75,2.7498s1.2205,2.7811,2.75,2.7811,2.7812-1.2536,2.7812-2.7811-1.2518-2.7498-2.7812-2.7498zm65.094,0c-1.5295,0-2.7812,1.2223-2.7812,2.7498s1.2518,2.7811,2.7812,2.7811c1.5295,0,2.7812-1.2536,2.7812-2.7811s-1.2518-2.7498-2.7812-2.7498zm-60.125,0.344c0.35844,0.73095,0.59375,1.5372,0.59375,2.4061,0,0.87594-0.2293,1.7014-0.59375,2.4373,13.471-0.28298,18.156-1.6671,18.156-2.4061,0-0.74195-4.6902-2.1544-18.156-2.4373zm65.094,0c0.35744,0.73095,0.5625,1.5372,0.5625,2.4061,0,0.87594-0.20306,1.7014-0.5625,2.4373,13.471-0.283,18.156-1.667,18.156-2.406,0-0.742-4.69-2.154-18.156-2.437zm-74.656,5.468c-6.523,11.842-7.675,16.627-7.0312,16.999,0.644,0.371,4.2152-3.01,11.219-14.562-1.7502-0.135-3.2694-1.056-4.1875-2.437zm65.062,0c-6.524,11.842-7.675,16.623-7.031,16.999,0.643,0.37,4.216-3.007,11.219-14.562-1.752-0.135-3.27-1.056-4.188-2.437zm-57.688,2.5311c-2.15,3.6138-3.9764,6.4613-5.5312,8.7182l-0.0308,25.78h5.5312l0.03125-34.498zm65.094,0c-2.1496,3.6137-4.0086,6.4613-5.5625,8.7182v25.78h5.5312l0.03125-34.498z"/>
</svg>

+ 68
- 0
static/js/script.js View File

@ -0,0 +1,68 @@
document.addEventListener("DOMContentLoaded",()=>{
let currentUrlObj=document.getElementsByClassName('currentUrl');
for (let i=0; i<currentUrlObj.length; i++){
currentUrlObj[i].innerHTML=window.location.origin;
}
let helpLinkObj=document.getElementsByClassName('helpLink');
for (let i=0; i<helpLinkObj.length; i++){
helpLinkObj[i].setAttribute("href",helpLinkObj[i].getAttribute("href").replace("[currentUrl]",window.location.origin));
}
let nightModeInputObj=document.getElementById("nightModeInput");
nightModeInputObj.addEventListener("change",(e)=>{
toggleDayNightMode(e.target.checked);
});
if(nightModeInputObj.checked){
toggleDayNightMode(nightModeInputObj.checked);
}else{
toggleDayNightIcon(nightModeInputObj.checked);
}
let helpObj=document.getElementById("help");
let helpImageObj=document.getElementById("helpImage");
if(helpImageObj){//Used because #helpImage can be hidden by user request.
document.getElementById("helpImage").addEventListener("click", ()=>{
if(window.getComputedStyle(helpObj).getPropertyValue("display")=="none"){
helpObj.style.display="block";
}else{
helpObj.style.display="none";
}
});
}
});
function toggleDayNightMode(nightMode){
document.body.classList.toggle("nightBackground");
let weatherImageArray=document.querySelectorAll(".weatherImage,#dayMode,#helpImage");
for (let i=0; i<weatherImageArray.length; i++){
weatherImageArray[i].classList.toggle("nightFilter");
}
let tableCellArray=document.querySelectorAll("td,th:not(:first-child)");
for (let i=0; i<tableCellArray.length; i++){
tableCellArray[i].classList.toggle("nightBorder");
}
let allArray=document.querySelectorAll("*");
for (let i=0; i<allArray.length; i++){
allArray[i].classList.toggle("nightColor");
}
let alternativeColumnArray=document.querySelectorAll("td:nth-child(2n+1):not(:first-child)");
for (let i=0; i<alternativeColumnArray.length; i++){
alternativeColumnArray[i].classList.toggle("nightAlternateBackground");
}
toggleDayNightIcon(nightMode);
}
function toggleDayNightIcon(nightMode){
if(nightMode){
document.getElementById("dayMode").style.display="block";
document.getElementById("nightMode").style.display="none";
}else{
document.getElementById("dayMode").style.display="none";
document.getElementById("nightMode").style.display="block";
}
}

+ 33
- 0
templates/help.html View File

@ -0,0 +1,33 @@
{% block head %}
<style>
#help{
display: none;
margin-left: auto;
margin-right: auto;
}
.argumentURL{
font-weight: bold;
}
.bold{
font-weight: bold;
}
</style>
{% endblock %}
{% block help %}
<div id="help">
<p>By default, will display the weather at Paris for the next 7 days, including today.</p>
<p>Empty cells results from the lack of data for a specific hour/date. <span class="bold">Valid hours are: {{validHours}}</span>. May be susceptible to change due to daylight saving time.</p>
<p>Use <a class="helpLink" href="[currentUrl]/latitude;longitude"><span class="currentUrl">[currentUrl]</span>/latitude;longitude</a> to obtain the weather data for a specific location.
<p>The display can be altered using one or multiple of the following arguments:
<ul>
<li><span class="argumentURL">day=X</span> Number of days (X) to display.</li>
<li><span class="argumentURL">hour=X,Y</span> Hours to display, multiple values separated by comma possible.</li>
<li><span class="argumentURL">today=0</span> Don't display today's weather.</li>
<li><span class="argumentURL">title=X</span> Change the HTML title by X.</li>
<li><span class="argumentURL">ui=0</span> Hide the UI icons.</li>
<li><span class="argumentURL">night=1</span> Display the dark theme.</li>
</ul>
</p>
<p>Example: <a class="helpLink" href="[currentUrl]/48.51296;2.17402?day=2&today=0&title=Weather%20at%20the%20Eiffel%20Tower"><span class="currentUrl">[currentUrl]</span>/48.51296;2.17402?day=2&today=0&title=Weather%20at%20the%20Eiffel%20Tower</p></a>
</div>
{% endblock %}

+ 242
- 0
templates/index.html View File

@ -0,0 +1,242 @@
{% extends 'layout.html' %}
{% block title %}{{title}}{% endblock %}
{% block head %}
{{ super() }}
<script src="{{ url_for('static', filename='js/script.js') }}"></script>
<style>
table{
border-collapse: collapse;
}
td,th:not(:first-child){
border: 1px solid black;
padding: 5px;
}
th,td:first-child,.windGust{
font-weight: bold;
}
td:nth-child(2n+1):not(:first-child){
background-color: #e0e0e0;
}
.value, .windAverage, .windGust, .windDirectionLetter{
font-size: 20px;
}
.unit,th,td:first-child{
font-size: 20px;
}
.weatherCell{
display: grid;
grid-template-columns: 2fr 1fr;
grid-template-rows: repeat(2,2fr) auto;
}
.weatherImage{
grid-column: 1;
grid-row: 1/3;
justify-self: center;
}
.weatherImage,.temperature,.humidity{
align-self: center;
}
.temperature{
grid-column: 2;
grid-row: 1;
}
.humidity{
grid-column: 2;
grid-row: 2;
}
.wind,.rain,.freezingLevel{
grid-column: 1/3;
justify-self: center;
}
.wind{
margin-top: 5px;
}
.negative{
color: blue;
}
#helpImage,#dayMode,#nightMode{
cursor: pointer;
}
.unselectable{
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
}
.nightBorder{
border-color: #FF0000!important;
}
.nightColor{
color: #FF0000;
}
.nightFilter{
filter: invert(16%) sepia(100%) saturate(5458%) hue-rotate(358deg) brightness(111%) contrast(124%);
}
.nightBackground{
background-color: #000000;
}
.nightAlternateBackground{
background-color: #5a5a5a!important;
}
#nightModeInput{
display: none;
}
#commandCell{
display: grid;
grid-auto-flow: column;
align-items: center;
justify-items: center;
}
</style>
{% endblock %}
{% block body %}
{{ super() }}
{% if ui %}
{% include 'help.html' %}
{% block help %}{% endblock %}
{% endif %}
<table>
<thead>
<tr>
<th>
{% if ui %}
<div id="commandCell">
<img id="helpImage" class="unselectable" src="{{ url_for('static', filename='img/help.svg') }}" />
<label for="nightModeInput">
<img id="dayMode" class="unselectable" src="{{ url_for('static', filename='img/sun.svg') }}" />
<img id="nightMode" class="unselectable" src="{{ url_for('static', filename='img/moon.svg') }}" />
</label>
<input type="checkbox" name="nightModeInput" id="nightModeInput" {% if night %}checked=checked{% endif %}>
</div>
{% endif %}
</th>
{% for d in date %}
<th>{{d}}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for h in hour %}
<tr>
<td>{% if h < 10 %}{% set h="0"+h|string() %}{% endif %}{{h}}H00</td>
{% for dt in datetime %}
{% if h|string() in dt.split(" ")[1].split(":")[0] %}
<td>
{% if dt in weatherData %}
<div class="weatherCell">
{% set img="skc.svg" %}
{% if weatherData[dt]["risque_neige"]=="oui" %}
{% if weatherData[dt]["pluie"]>0 %}
{% if weatherData[dt]["pluie"] > 30 %}
{% set img="rasn.svg" %}
{% else %}
{% set img="rasn1.svg" %}
{% endif %}
{% else %}
{% set img="sn.svg" %}
{% endif %}
{% elif weatherData[dt]["pluie"]>0 %}
{% set img="hi_shwrs.svg" %}
{% if weatherData[dt]["nebulosite"]["totale"]>=25 and weatherData[dt]["nebulosite"]["totale"] < 50 %}
{% set img="shra.svg" %}
{% endif %}
{% if weatherData[dt]["nebulosite"]["totale"]>=50 %}
{% if weatherData[dt]["pluie"] > 30 %}
{% set img="ra.svg" %}
{% else %}
{% set img="ra1.svg" %}
{% endif %}
{% endif %}
{% else %}
{% if weatherData[dt]["nebulosite"]["totale"]>=10 and weatherData[dt]["nebulosite"]["totale"] < 25 %}
{% set img="few.svg" %}
{% endif %}
{% if weatherData[dt]["nebulosite"]["totale"]>=25 and weatherData[dt]["nebulosite"]["totale"] < 50 %}
{% set img="sct.svg" %}
{% endif %}
{% if weatherData[dt]["nebulosite"]["totale"]>=50 and weatherData[dt]["nebulosite"]["totale"] < 75 %}
{% set img="bkn.svg" %}
{% endif %}
{% if weatherData[dt]["nebulosite"]["totale"]>=75 %}
{% set img="ovc.svg" %}
{% endif %}
{% endif %}
<img class="weatherImage unselectable" src="{{ url_for('static', filename='img/'+img) }}" />
<div class="temperature">
{% if weatherData[dt]["temperature"]["2m"]-273.15<=0 %}
<span class="value negative">{{(weatherData[dt]["temperature"]["2m"]-273.15)|round(1)}}</span>
{% else %}
<span class="value">{{(weatherData[dt]["temperature"]["2m"]-273.15)|round(1)}}</span>
{% endif %}
<span class="unit">°C</span>
</div>
<div class="humidity">
<span class="value">{{weatherData[dt]["humidite"]["2m"]}}</span>
<span class="unit">%</span>
</div>
<div class="wind">
<span class="windAverage">{{weatherData[dt]["vent_moyen"]["10m"]}}</span>
{% if weatherData[dt]["vent_rafales"]["10m"]>weatherData[dt]["vent_moyen"]["10m"] %}
| <span class="windGust">{{weatherData[dt]["vent_rafales"]["10m"]}}</span>
{% endif %}
<span class="unit">km/h</span>
<span class="windDirection">
<span class="windDirectionLetter">
{% set dir=weatherData[dt]["vent_direction"]["10m"] %}
{% if dir > 360 %}
{% set dir=dir-360 %}
{% endif %}
{% if dir < 22.5 or dir >= 337.5 %}
N
{% endif %}
{% if dir >= 22.5 and dir < 67.5 %}
NE
{% endif %}
{% if dir >= 67.5 and dir < 112.5 %}
E
{% endif %}
{% if dir >= 112.5 and dir < 157.5 %}
SE
{% endif %}
{% if dir >= 157.5 and dir < 202.5 %}
S
{% endif %}
{% if dir >= 202.5 and dir < 247.5 %}
SW
{% endif %}
{% if dir >= 247.5 and dir < 292.5 %}
W
{% endif %}
{% if dir >= 292.5 and dir < 337.5 %}
NW
{% endif %}
</span>
<span class="windDirectionDegree">({{dir}}°)</span>
</span>
</div>
{% if weatherData[dt]["pluie"]>0 %}
<div class="rain">
<span class="value">{{weatherData[dt]["pluie"]}}</span>
<span class="unit">mm/3h rain</span>
</div>
{% endif %}
{% if weatherData[dt]["risque_neige"]=="oui" %}
<div class="freezingLevel">
<span class="value">{{weatherData[dt]["iso_zero"]}}</span>
<span class="unit">m freezing level</span>
</div>
{% endif %}
</div>
{% endif %}
</td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
<div class="status">
<span class="run">Model run: {{weatherData["model_run"]}}</span>
<span class="fetchTime"> fetched {{fetchTime}} ago</span>
</div>
{% endblock %}

+ 14
- 0
templates/layout.html View File

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="{{ url_for('static', filename='img/skc.svg') }}" type="image/x-icon">
<title>{% block title %}{% endblock %}</title>
{% block head %}{% endblock %}
</head>
<body>
{% block body %}{% endblock %}
</body>
</html>

Loading…
Cancel
Save