feat: update the folder structure

parent d8697f3b

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

{
"cSpell.words": [
"Janith",
"SLIIT"
]
}
\ No newline at end of file
models/*
!models/
\ No newline at end of file
{
"cells": [
{
"cell_type": "code",
"execution_count": 6,
"id": "ade37944",
"metadata": {},
"outputs": [],
"source": [
"import tensorflow as tf\n",
"import os\n",
"import cv2\n",
"import numpy as np\n",
"from sklearn.model_selection import train_test_split\n",
"import mediapipe as mp"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "16176bf6",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['A',\n",
" 'Aah',\n",
" 'Ae',\n",
" 'Aeh',\n",
" 'Ah',\n",
" 'Ee',\n",
" 'Eeh',\n",
" 'Ig',\n",
" 'K',\n",
" 'O',\n",
" 'Ohh',\n",
" 'T',\n",
" 'Uh',\n",
" 'Uhh']"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"IMG_SIZE = 224 # image size\n",
"BATCH_SIZE = 32 # batch size\n",
"EPOCHS = 10 # number of epochs\n",
"CLASSES = os.listdir('D:/RP/data/training') # list of classes\n",
"NUM_CLASSES = len(CLASSES) # number of classes\n",
"\n",
"CLASSES"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "8f7b1301",
"metadata": {},
"outputs": [],
"source": [
"# Dictionary to map English letters to Sinhala letters\n",
"letter_mapping = {\n",
" 'Ah': 'අ',\n",
" 'Aah': 'ආ',\n",
" 'Aeh': 'ඇ',\n",
" 'Ee': 'ඉ',\n",
" 'Eeh': 'ඊ',\n",
" 'Uh': 'උ',\n",
" 'Uhh': 'ඌ',\n",
" 'A': 'එ',\n",
" 'Ae': 'ඒ',\n",
" 'O': 'ඔ',\n",
" 'Ohh': 'ඕ',\n",
" 'K': 'ක්',\n",
" 'Ig': 'ග්',\n",
" 'T': 'ටී'\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "c9034cbe",
"metadata": {},
"outputs": [],
"source": [
"def load_dataset(dataset_path):\n",
" data = []\n",
" labels = []\n",
" for class_name in CLASSES:\n",
" class_path = os.path.join(dataset_path, class_name)\n",
" for img_name in os.listdir(class_path):\n",
" try:\n",
" \n",
" img_path = os.path.join(class_path, img_name)\n",
" img = cv2.imread(img_path)\n",
" img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # convert color space\n",
" img = cv2.resize(img, (IMG_SIZE, IMG_SIZE)) # resize image\n",
" data.append(img)\n",
" labels.append(CLASSES.index(class_name))\n",
"\n",
" \n",
" except Exception as e:\n",
" print(f\"Error loading image {img_path}: {e}\")\n",
" data = np.array(data, dtype=np.float32) / 255.0 # normalize pixel values\n",
" labels = tf.keras.utils.to_categorical(labels, num_classes=NUM_CLASSES) # one-hot encode labels\n",
" return data, labels\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7adb379e",
"metadata": {},
"outputs": [],
"source": [
"data, labels = load_dataset('D:/RP/data/training')\n",
"train_data, val_data, train_labels, val_labels = train_test_split(data, labels, test_size=0.2, random_state=42)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d44f7806",
"metadata": {},
"outputs": [],
"source": [
"model = tf.keras.Sequential([\n",
" tf.keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(IMG_SIZE, IMG_SIZE, 3)),\n",
" tf.keras.layers.MaxPooling2D((2, 2)),\n",
" tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),\n",
" tf.keras.layers.MaxPooling2D((2, 2)),\n",
" tf.keras.layers.Conv2D(128, (3, 3), activation='relu'),\n",
" tf.keras.layers.MaxPooling2D((2, 2)),\n",
" tf.keras.layers.Flatten(),\n",
" tf.keras.layers.Dense(128, activation='relu'),\n",
" tf.keras.layers.Dense(NUM_CLASSES, activation='softmax')\n",
"])\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ff4f0d06",
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])\n",
"model.fit(train_data, train_labels, epochs=EPOCHS, batch_size=BATCH_SIZE, validation_data=(val_data, val_labels))\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "61d6a8d8",
"metadata": {},
"outputs": [],
"source": [
"model.save('./models/model')"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fdc9bfe6",
"metadata": {},
"outputs": [],
"source": [
"def load_test_dataset(dataset_path):\n",
" test_data = []\n",
" test_labels = []\n",
" for class_name in CLASSES:\n",
" class_path = os.path.join(dataset_path, class_name)\n",
" for img_name in os.listdir(class_path):\n",
" try:\n",
" img_path = os.path.join(class_path, img_name)\n",
" img = cv2.imread(img_path)\n",
" img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # convert color space\n",
" img = cv2.resize(img, (IMG_SIZE, IMG_SIZE)) # resize image\n",
" test_data.append(img)\n",
" test_labels.append(CLASSES.index(class_name))\n",
" except Exception as e:\n",
" print(f\"Error loading image {img_path}: {e}\")\n",
" test_data = np.array(test_data, dtype=np.float32) / 255.0 # normalize pixel values\n",
" test_labels = tf.keras.utils.to_categorical(test_labels, num_classes=NUM_CLASSES) # one-hot encode labels\n",
" return test_data, test_labels\n",
"\n",
"test_data, test_labels = load_test_dataset('D:/RP/data/validation')"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "297e3e3c",
"metadata": {},
"outputs": [],
"source": [
"predictions = model.predict(test_data)\n",
"predicted_classes = np.argmax(predictions, axis=1)\n",
"\n",
"accuracy = np.sum(predicted_classes == np.argmax(test_labels, axis=1)) / len(test_labels)\n",
"print(\"Test Accuracy:\", accuracy)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e22211b0",
"metadata": {},
"outputs": [],
"source": [
"# Save the trained model\n",
"model.save('./models/sign_language_model.h5')\n",
"\n",
"# Load the saved model\n",
"loaded_model = tf.keras.models.load_model('./models/sign_language_model.h5')\n",
"\n",
"# Use the loaded model for predictions\n",
"predictions = loaded_model.predict(test_data)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "885678c5",
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"img = cv2.imread('./scene00548.png')\n",
"img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n",
"img = cv2.resize(img, (IMG_SIZE, IMG_SIZE))\n",
"img = np.array([img], dtype=np.float32) / 255.0\n",
"prediction = model.predict(img)\n",
"class_index = np.argmax(prediction)\n",
"class_name = CLASSES[class_index]\n",
"sinhala_letter = letter_mapping.get(class_name, 'Unknown')\n",
"print(sinhala_letter)"
]
},
{
"cell_type": "markdown",
"id": "69b66fc1",
"metadata": {},
"source": [
"### Load saved model\n"
]
},
{
"cell_type": "code",
"execution_count": 29,
"id": "50944c95",
"metadata": {},
"outputs": [],
"source": [
"# Load the saved model\n",
"model = tf.keras.models.load_model('./models/model')"
]
},
{
"cell_type": "code",
"execution_count": 30,
"id": "75cef5e3",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1/1 [==============================] - 0s 100ms/step\n",
"Ohh\n",
"ඕ\n"
]
}
],
"source": [
"img = cv2.imread('./scene00001.png')\n",
"img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n",
"img = cv2.resize(img, (IMG_SIZE, IMG_SIZE))\n",
"img = np.array([img], dtype=np.float32) / 255.0\n",
"prediction = model.predict(img)\n",
"class_index = np.argmax(prediction)\n",
"class_name = CLASSES[class_index]\n",
"print(class_name)\n",
"sinhala_letter = letter_mapping.get(class_name, 'Unknown')\n",
"print(sinhala_letter)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.13"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
# TMP-23-029
SLIIT Final Year Project
\ No newline at end of file
DB_PASSWORD = JppbU6MZeHfOj7sp
DB_USERNAME = admin
\ No newline at end of file
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional stylelint cache
.stylelintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# vuepress v2.x temp and cache directory
.temp
.cache
# Docusaurus cache and generated files
.docusaurus
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
\ No newline at end of file
# TMP-23-029
SLIIT Final Year Project
\ No newline at end of file
import multer from "multer";
import videoService from "../service/videoService.js";
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "uploads/");
},
filename: function (req, file, cb) {
cb(null, Date.now() + "-" + file.originalname);
},
});
const upload = multer({ storage: storage }).single("video");
export function uploadVideo(req, res) {
upload(req, res, function (err) {
if (err) {
console.error(err);
return res
.status(500)
.send("An error occurred while uploading the video");
}
if (!req.file) {
return res.status(400).send("No video file provided");
}
res.status(200).send({
status: true,
message: "Translated Text",
data: "ආආආආආආආආආ",
});
// videoService
// .processVideo(req.file)
// .then(() => res.status(200).send("Video uploaded successfully"))
// .catch((error) => {
// console.error(error);
// res.status(500).send("An error occurred while processing the video");
// });
});
}
import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken';
import mongoose from 'mongoose';
import nodemailer from "nodemailer";
import { v4 as uuidv4 } from 'uuid';
import User from '../models/user.model.js';
export const signIn = async (req, res) => {
const { email, password } = req.body;
try {
if (email === null || typeof email == "undefined") return res.status(400).json({ code: "02", message: "Email Field Required" })
if (password === null || typeof password == "undefined") return res.status(400).json({ code: "02", message: "Password Field Required" })
const existingUser = await User.findOne({ email: email });
if (!existingUser) return res.status(404).json({ code: "02", message: "User doesn't exist" })
const isPasswordCorrect = await bcrypt.compare(password, existingUser.password)
if (!isPasswordCorrect) return res.status(400).json({ code: "02", message: "Invalid Credentials" })
const token = jwt.sign({ email: existingUser.email, id: existingUser._id }, 'test', { expiresIn: "1h" })
res.status(200).json({ code: "01", result: existingUser, token })
} catch (error) {
res.status(500).json({ code: "00", message: "Something went wrong" })
}
}
export const signUp = async (req, res) => {
const {
email,
password,
confirmPassword,
type,
userFirstName,
userLastName,
userContactNumber,
userAddressLine1,
userAddressLine2,
userAddressLine3,
} = req.body;
try {
if (!type) return res.status(400).json({ code: "02", message: "Type Field Required" })
if (!email) return res.status(400).json({ code: "02", message: "Email Field Required" })
if (!userFirstName) return res.status(400).json({ code: "02", message: "User First Name Field Required" })
if (!userLastName) return res.status(400).json({ code: "02", message: "User Last Name Field Required" })
if (!userContactNumber) return res.status(400).json({ code: "02", message: "User Contact Number Field Required" })
const existingUser = await User.findOne({ email })
if (existingUser) return res.status(400).json({ code: "02", message: "User already exists" })
if (type === "buyer") {
if (!password) return res.status(400).json({ code: "02", message: "Password Field Required" })
if (password !== confirmPassword) return res.status(400).json({ code: "02", message: "Passwords do not match" })
const hashedPassword = await bcrypt.hash(password, 12)
const userDetails = new User({
email,
password: hashedPassword,
type,
userDetails: {
userQNumber: uuidv4(),
userEmail: email,
userName: `${userFirstName} ${userLastName}`,
userContactNumber,
userAddress: `${userAddressLine1}, ${userAddressLine2}, ${userAddressLine3}`,
userType: type,
}
})
const userResult = await userDetails.save()
const token = jwt.sign({ email: userResult.email, id: userResult._id }, 'test', { expiresIn: "1h" })
res.status(200).json({ code: "01", result: userResult, token })
} else if (type === "trader") {
const userDetails = new User({
email,
type,
userDetails: {
userQNumber: uuidv4(),
userEmail: email,
userName: `${userFirstName} ${userLastName}`,
userContactNumber,
userAddress: `${userAddressLine1}, ${userAddressLine2}, ${userAddressLine3}`,
userType: type,
},
states: 2
})
const userResult = await userDetails.save()
const token = jwt.sign({ email: userResult.email, id: userResult._id }, 'test', { expiresIn: "1h" })
res.status(200).json({ code: "01", result: userResult, token })
}
} catch (error) {
res.status(500).json({ code: "00", message: "Something went wrong" })
}
}
export const getUsers = async (req, res) => {
try {
const users = await User.find();
res.status(200);
res.json(users);
} catch (error) {
console.log(error)
res.status(404);
res.json({ message: error.message })
}
}
export const getUser = async (req, res) => {
const { id } = req.params;
try {
const user = await User.findById(id);
res.status(200);
res.json({
code: "01",
result: user
});
} catch (error) {
res.status(404);
res.json({ "message": error.message });
}
}
export const getUserAccordingToType = async (req, res) => {
const { userType } = req.params;
try {
const users = await User.find({ type: userType });
res.status(200);
res.json(users);
} catch (error) {
res.status(404);
res.json({ "message": error.message });
}
}
export const updateUser = async (req, res) => {
const { id } = req.params;
const data = req.body;
try {
if (!mongoose.Types.ObjectId.isValid(id)) {
return res.status(404).json({ code: "02", message: `No User for this id: ${id}` });
}
if (data.type == "buyer" || data.type == "admin") {
const updateUser = { ...data, _id: id }
await User.findByIdAndUpdate(id, updateUser, { new: true })
res.status(200);
res.json({ code: "01", result: updateUser })
} else if (data.type == "trader") {
var password = Math.random().toString(36).slice(-8);
const hashPassword = await bcrypt.hash(password, 12)
const updateUser = { ...data, password: hashPassword, _id: id }
await User.findByIdAndUpdate(id, updateUser, { new: true })
//call email service
let transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
type: 'OAuth2',
user: process.env.MAIL_USERNAME,
pass: process.env.MAIL_PASSWORD,
clientId: process.env.OAUTH_CLIENTID,
clientSecret: process.env.OAUTH_CLIENT_SECRET,
refreshToken: process.env.OAUTH_REFRESH_TOKEN
}
});
let mailOptions = {
from: "janithgamage1.ed@gmail.com",
to: updateUser.email,
subject: 'Shop House Project',
text: `You are Successfully Approved, you're username: ${updateUser.email} , you're password : ${password}`
};
transporter.sendMail(mailOptions, function (err, data) {
if (err) {
console.log("Error " + err);
} else {
console.log("Email sent successfully");
}
});
res.status(200);
res.json({ code: "01", result: updateUser })
}
} catch (error) {
res.status(404);
res.json({ code: "00", "message": error.message });
}
}
export const deleteUser = async (req, res) => {
const { id } = req.params;
try {
if (!mongoose.Types.ObjectId.isValid(id)) {
return res.status(404).json({ code: "02", message: `No User for this id: ${id}` });
}
await User.findByIdAndDelete(id);
res.status(200);
res.json({ code: "01", "message": "User Deleted Successfully" });
} catch (error) {
res.status(404);
res.json({ code: "00", "message": error.message });
}
}
import jwt from 'jsonwebtoken';
const auth = async (req, res, next) => {
try {
if (req.headers.authorization != null) {
const token = req.headers.authorization.split(" ")[1];
const isCustomAuth = token.length < 500;
let decoderData;
if (token && isCustomAuth) {
decoderData = jwt.verify(token, 'test');
req.userId = decoderData?.id;
} else {
decoderData = jwt.decode(token)
req.userId = decoderData?.sub;
}
next();
}
else {
res.status(500).json({ message: 'user not authorized' })
}
} catch (error) {
console.log(error)
}
}
export default auth;
\ No newline at end of file
import mongoose from "mongoose";
const userSchema = mongoose.Schema({
email: {
type: String,
required: true,
unique: true
},
password: {
type: String
},
type: {
type: String,
required: true
},
userDetails: {
userQNumber: {
type: String,
required: true,
unique: true
},
userEmail: {
type: String,
required: true,
},
userName: {
type: String,
required: true
},
userContactNumber: {
type: String,
required: true
},
userAddress: {
type: String
},
userType: {
type: String,
required: true
},
},
states: {
type: String,
default: "1"
},
createdAt: {
type: Date
},
updatedAt: {
type: Date
}
});
const User = mongoose.model("Users", userSchema);
export default User;
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "server_node",
"version": "1.0.0",
"description": "SLIIT Final Year Research Project Server (NodeJS)",
"main": "server.js",
"type": "module",
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js"
},
"author": "devJanith",
"license": "ISC",
"dependencies": {
"bcryptjs": "^2.4.3",
"body-parser": "^1.20.2",
"cors": "^2.8.5",
"dotenv": "^16.0.3",
"express": "^4.18.2",
"jsonwebtoken": "^9.0.0",
"mongoose": "^7.1.1",
"multer": "^1.4.5-lts.1",
"nodemailer": "^6.9.1",
"nodemon": "^2.0.22",
"uuid": "^9.0.0"
}
}
import express from "express";
import { uploadVideo } from "../controllers/translate.controller.js";
const router = express.Router();
router.post("/upload", uploadVideo);
export default router;
import express from "express";
import { deleteUser, getUser, getUserAccordingToType, getUsers, signIn, signUp, updateUser } from "../controllers/user.controller.js";
const router = express.Router();
router.post('/sign-in', signIn)
router.post('/sign-up', signUp)
router.get('/all', getUsers);
router.get('/:id', getUser);
router.get('/test/:userType', getUserAccordingToType);
router.put('/:id', updateUser);
router.delete('/:id', deleteUser);
export default router;
\ No newline at end of file
import bodyParser from "body-parser";
import cors from "cors";
import dotenv from "dotenv";
import express from "express";
import mongoose from "mongoose";
//import routes
import userRoutes from "./routes/user.routes.js";
import translateRoutes from "./routes/translate.routes.js";
dotenv.config();
const app = express();
app.use(bodyParser.json({ limit: "30mb", extended: true }));
app.use(bodyParser.urlencoded({ limit: "30mb", extended: true }));
app.use(cors());
//end
app.get("/", (req, res) => {
res.json({ message: "Welcome to Server Node" });
});
//implement routes
app.use("/rest_node/user", userRoutes);
app.use("/rest_node/ssl", translateRoutes);
const CONNECTION_URL = `mongodb+srv://${process.env.DB_USERNAME}:${process.env.DB_PASSWORD}@cluster0.dmza8yi.mongodb.net/?retryWrites=true&w=majority`;
const PORT = process.env.PORT || 5000;
mongoose
.connect(CONNECTION_URL, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => {
app.listen(PORT, () =>
console.log(`Server Running on port :http://localhost:${PORT}`)
);
})
.catch((error) => {
console.error(error);
process.exit(1);
});
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send("Internal Server Error");
});
export default function processVideo(videoFile) {
return new Promise((resolve, reject) => {
// Perform video processing tasks here
// Example: store videoFile in a database, generate thumbnails, etc.
// Simulating asynchronous processing
setTimeout(() => {
// Resolve the promise to indicate successful processing
resolve();
}, 2000);
});
}
# Ignore video files
*.mp4
*.avi
*.mov
*.mkv
*.flv
*.wmv
*.mpeg
*.mpg
*.3gp
*.webm
*.vob
*.m4v
*.ts
files/*
!files/
*.pyc
*~
*.swp
# Created by https://www.toptal.com/developers/gitignore/api/python
# Edit at https://www.toptal.com/developers/gitignore?templates=python
### Python ###
# 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
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__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 maintained 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/
### Python Patch ###
# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
poetry.toml
# ruff
.ruff_cache/
# LSP config files
pyrightconfig.json
# End of https://www.toptal.com/developers/gitignore/api/python
\ No newline at end of file
# TMP-23-029
SLIIT Final Year Backend Project
## Installation
Install dependencies
Python Environment - Python 3.10.11
```bash
pip install -r requirements.txt
```
## Run Locally
Start the server
```bash
uvicorn main:app --reload
```
2023-05-19 00:32:23,385 - INFO - Received request at root endpoint.
2023-05-19 00:32:23,385 - INFO - Received request at root endpoint.
2023-05-19 00:32:48,522 - ERROR - Received request at root endpoint.
2023-05-19 00:32:48,522 - ERROR - Received request at root endpoint.
2023-05-19 23:09:38,565 - INFO - Failed to make predictions. name 'CLASSES' is not defined
2023-05-19 23:09:38,565 - INFO - Failed to make predictions. name 'CLASSES' is not defined
from fastapi import APIRouter, File, HTTPException,UploadFile
from pydantic import BaseModel
import tensorflow as tf
from core.logger import setup_logger
from services.translate_service import SignLanguagePredictionService
from utils import mappings
router = APIRouter()
logger = setup_logger()
class ImageRequest(BaseModel):
image: UploadFile
# Load your Keras model
model = tf.keras.models.load_model('../ML_Models/sign_language_to_text/models/sign_language_model.h5')
CLASSES = mappings.classes
NUM_CLASSES = len(mappings.classes) # number of classes
IMG_SIZE = 224 # image size
# Instantiate the service class
prediction_service = SignLanguagePredictionService(model, CLASSES, mappings)
@router.post("/upload/video")
async def upload_video(video: UploadFile = File(...)):
try:
file_location = f"files/{video.filename}"
with open(file_location, "wb") as file:
file.write(video.file.read())
return {"text": "ආආආආආආආ"}
except Exception as e:
logger.info(f"Failed to upload file. {e}")
raise HTTPException(
status_code=500,
detail="Failed to upload the video"
)
@router.post('/predict-sign-language/image')
def predict_using_image(image_request: UploadFile = File(...)):
try:
return prediction_service.predict_sign_language(image_request)
except Exception as e:
logger.info(f"Error. {e}")
raise HTTPException(
status_code=500,
detail="Request Failed."
)
@router.post('/predict-sign-language/video')
def predict_using_video(video_request: UploadFile = File(...)):
try:
return prediction_service.predict_sign_language_video(video_request)
except Exception as e:
logger.info(f"Error. {e}")
raise HTTPException(
status_code=500,
detail="Request Failed."
)
\ No newline at end of file
from fastapi import APIRouter
router = APIRouter()
@router.get("/ping")
def test():
# Your code here
return {"pong"}
@router.get("/users")
def get_users():
# Your code here
return {"message": "Get users endpoint"}
@router.post("/users")
def create_user():
# Your code here
return {"message": "Create user endpoint"}
import logging
def setup_logger():
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
# Create a file handler for logging to a file
file_handler = logging.FileHandler('app.log')
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(formatter)
# Create a stream handler for logging to console
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.INFO)
stream_handler.setFormatter(formatter)
# Add the handlers to the logger
logger.addHandler(file_handler)
logger.addHandler(stream_handler)
return logger
from fastapi import FastAPI
from controllers import translate_controler, users_controller
from fastapi.responses import RedirectResponse
from fastapi.middleware.cors import CORSMiddleware
from core.logger import setup_logger
app = FastAPI()
logger = setup_logger()
app.include_router(users_controller.router)
app.include_router(translate_controler.router)
# Add cores middleware
origins = [
"http://localhost",
"http://localhost:8080",
]
app.add_middleware(CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"])
@app.get('/')
async def root():
url = app.docs_url or '/docs'
return RedirectResponse(url)
\ No newline at end of file
fastapi
uvicorn
python-multipart==0.0.6
tensorflow==2.12.0
opencv-python==4.7.0.72
\ No newline at end of file
import os
import cv2
import numpy as np
from fastapi import HTTPException, UploadFile
from typing import Dict
from core.logger import setup_logger
logger = setup_logger()
IMG_SIZE = 224 # image size
class SignLanguagePredictionService:
def __init__(self, model, classes, mappings):
self.model = model
self.classes = classes
self.mappings = mappings
def predict_sign_language(self, image_request: UploadFile) -> Dict[str, str]:
try:
file_location = f"files/{image_request.filename}"
with open(file_location, "wb") as file:
file.write(image_request.file.read())
img = cv2.imread(file_location)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = cv2.resize(img, (IMG_SIZE, IMG_SIZE))
img = np.array([img], dtype=np.float32) / 255.0
prediction = self.model.predict(img)
class_index = np.argmax(prediction)
class_name = self.classes[class_index]
sinhala_letter = self.mappings.letter_mapping.get(class_name, 'Unknown')
# Delete the image file
os.remove(file_location)
return {'prediction': sinhala_letter}
except Exception as e:
logger.info(f"Failed to make predictions. {e}")
raise HTTPException(
status_code=500,
detail="Failed to make predictions"
)
def predict_sign_language_video(self, video_request: UploadFile) -> Dict[str, str]:
try:
# Create a temporary file to save the video
video_location = f"files/{video_request.filename}"
with open(video_location, "wb") as file:
file.write(video_request.file.read())
# Read the video using OpenCV
video = cv2.VideoCapture(video_location)
predictions = []
frame_count = 0
# Loop through the frames of the video
while frame_count < 20:
success, frame = video.read()
if not success:
break
# Preprocess the frame
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
frame = cv2.resize(frame, (IMG_SIZE, IMG_SIZE))
frame = np.array([frame], dtype=np.float32) / 255.0
# Make prediction
prediction = self.model.predict(frame)
class_index = np.argmax(prediction)
class_name = self.classes[class_index]
sinhala_letter = self.mappings.letter_mapping.get(class_name, 'Unknown')
# Store the prediction for the frame
predictions.append(sinhala_letter)
frame_count += 1
video.release()
# Delete the video file
os.remove(video_location)
return {'frame_count': frame_count, 'predictions': predictions}
except Exception as e:
logger.info(f"Failed to make predictions. {e}")
raise HTTPException(
status_code=500,
detail="Failed to make predictions"
)
letter_mapping = {
'Ah': 'අ',
'Aah': 'ආ',
'Aeh': 'ඇ',
'Ee': 'ඉ',
'Eeh': 'ඊ',
'Uh': 'උ',
'Uhh': 'ඌ',
'A': 'එ',
'Ae': 'ඒ',
'O': 'ඔ',
'Ohh': 'ඕ',
'K': 'ක්',
'Ig': 'ග්',
'T': 'ටී'
}
classes =['A',
'Aah',
'Ae',
'Aeh',
'Ah',
'Ee',
'Eeh',
'Ig',
'K',
'O',
'Ohh',
'T',
'Uh',
'Uhh']
\ No newline at end of file
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional stylelint cache
.stylelintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# vuepress v2.x temp and cache directory
.temp
.cache
# Docusaurus cache and generated files
.docusaurus
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
\ No newline at end of file
# TMP-23-029
SLIIT Final Year Project
\ No newline at end of file
# TMP-23-029
SLIIT Final Year Project
\ No newline at end of file
**/node_modules/*
**/out/*
**/.next/*
{
"plugins": [
"@typescript-eslint"
],
"extends": [
"next/core-web-vitals",
"plugin:@typescript-eslint/recommended",
"prettier"
],
"rules": {
"arrow-body-style": 1,
"react/display-name": 0,
"import/no-duplicates": 1,
"no-extra-boolean-cast": 1,
"react/no-children-prop": 0,
"react/self-closing-comp": 2,
"@next/next/no-img-element": 0,
"react/no-unescaped-entities": 0,
"import/no-useless-path-segments": 1,
"@typescript-eslint/ban-ts-comment": 0,
"@typescript-eslint/no-explicit-any": 0,
"@typescript-eslint/no-empty-function": 0,
"@typescript-eslint/no-non-null-assertion": 0,
"@typescript-eslint/explicit-module-boundary-types": 0,
"@typescript-eslint/no-unused-vars": [
1,
{
"vars": "all",
"args": "none"
}
]
}
}
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional stylelint cache
.stylelintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# vuepress v2.x temp and cache directory
.temp
.cache
# Docusaurus cache and generated files
.docusaurus
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
\ No newline at end of file
node_modules
.next
yarn.lock
package-lock.json
public
{
"printWidth": 100,
"singleQuote": true,
"trailingComma": "es5",
"tabWidth": 2
}
# TMP-23-029
SLIIT Final Year Project
## USING YARN (Recommend)
- yarn install
- yarn dev
## USING NPM
- npm i OR npm i --legacy-peer-deps
- npm run dev
[build]
command = "npm run build-netlify"
publish = ".next"
[[plugins]]
package = "@netlify/plugin-nextjs"
/// <reference types="next" />
/// <reference types="next/image-types/global" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
/* eslint-disable @typescript-eslint/no-var-requires */
const withTM = require('next-transpile-modules')([
'@fullcalendar/common',
'@fullcalendar/daygrid',
'@fullcalendar/interaction',
'@fullcalendar/list',
'@fullcalendar/react',
'@fullcalendar/timegrid',
'@fullcalendar/timeline',
]);
module.exports = withTM({
swcMinify: false,
trailingSlash: true,
env: {
// HOST
HOST_API_KEY: 'https://api-dev-minimal-v4.vercel.app',
// MAPBOX
MAPBOX_API: '',
// FIREBASE
FIREBASE_API_KEY: '',
FIREBASE_AUTH_DOMAIN: '',
FIREBASE_PROJECT_ID: '',
FIREBASE_STORAGE_BUCKET: '',
FIREBASE_MESSAGING_SENDER_ID: '',
FIREBASE_APPID: '',
FIREBASE_MEASUREMENT_ID: '',
// AWS COGNITO
AWS_COGNITO_USER_POOL_ID: '',
AWS_COGNITO_CLIENT_ID: '',
// AUTH0
AUTH0_DOMAIN: '',
AUTH0_CLIENT_ID: '',
},
});
This diff is collapsed.
{
"name": "@minimal/material-kit-nextjs",
"author": "Minimals UI",
"version": "4.0.0",
"description": "Next.Js & Typescript",
"private": true,
"scripts": {
"lint": "next lint",
"lint:es": "eslint --ext .ts,.tsx .",
"lint:fix": "eslint --fix --ext .ts,.tsx .",
"dev": "next dev -p 8004",
"start": "next start",
"build": "next build",
"build-netlify": "next build && cp -r .next _next && mv _next .next/",
"export": "yarn build && next export -o _static",
"clear-all": "rm -rf .next .swc _static node_modules",
"re-start": "rm -rf .next .swc _static node_modules && yarn install && yarn dev",
"re-build": "rm -rf .next .swc _static node_modules && yarn install && yarn build"
},
"dependencies": {
"@auth0/auth0-spa-js": "^1.22.5",
"@emotion/cache": "^11.10.3",
"@emotion/react": "^11.11.0",
"@emotion/server": "^11.10.0",
"@emotion/styled": "^11.11.0",
"@fullcalendar/common": "^5.11.3",
"@fullcalendar/daygrid": "^5.11.3",
"@fullcalendar/interaction": "^5.11.3",
"@fullcalendar/list": "^5.11.3",
"@fullcalendar/react": "^5.11.2",
"@fullcalendar/timegrid": "^5.11.3",
"@fullcalendar/timeline": "^5.11.3",
"@hookform/resolvers": "^2.9.8",
"@iconify/react": "^4.0.0",
"@mui/icons-material": "^5.11.16",
"@mui/lab": "^5.0.0-alpha.103",
"@mui/material": "^5.13.0",
"@mui/x-data-grid": "^5.17.7",
"@mui/x-date-pickers": "^5.0.4",
"@react-pdf/renderer": "^3.0.0",
"@reduxjs/toolkit": "^1.8.6",
"amazon-cognito-identity-js": "^5.2.11",
"apexcharts": "^3.36.0",
"autosuggest-highlight": "^3.3.4",
"axios": "^1.1.2",
"change-case": "^4.1.2",
"date-fns": "^2.29.3",
"firebase": "^9.12.1",
"framer-motion": "^7.5.3",
"highlight.js": "^11.6.0",
"i18next": "^21.10.0",
"i18next-browser-languagedetector": "^6.1.8",
"lodash": "^4.17.21",
"mapbox-gl": "^2.10.0",
"next": "^12.3.1",
"next-transpile-modules": "^9.1.0",
"notistack": "^2.0.5",
"nprogress": "^0.2.0",
"numeral": "^2.0.6",
"react": "^18.2.0",
"react-apexcharts": "^1.4.0",
"react-beautiful-dnd": "^13.1.1",
"react-dom": "^18.2.0",
"react-dropzone": "^14.2.3",
"react-hook-form": "^7.37.0",
"react-i18next": "^11.18.6",
"react-image-lightbox": "^5.1.4",
"react-lazy-load-image-component": "^1.5.5",
"react-map-gl": "^7.0.19",
"react-markdown": "^8.0.3",
"react-media-recorder": "^1.6.6",
"react-organizational-chart": "^2.2.0",
"react-quill": "^2.0.0",
"react-redux": "^8.0.4",
"react-slick": "^0.29.0",
"react-webcam": "^7.0.1",
"redux": "^4.2.0",
"redux-persist": "^6.0.0",
"rehype-raw": "^6.1.1",
"simplebar": "^5.3.9",
"simplebar-react": "^2.4.3",
"slick-carousel": "^1.8.1",
"stylis": "^4.1.2",
"stylis-plugin-rtl": "^2.1.1",
"yup": "^0.32.11"
},
"devDependencies": {
"@types/autosuggest-highlight": "^3.2.0",
"@types/mapbox-gl": "^2.7.6",
"@types/node": "^18.8.5",
"@types/nprogress": "^0.2.0",
"@types/numeral": "^2.0.2",
"@types/react": "^18.0.21",
"@types/react-beautiful-dnd": "^13.1.2",
"@types/react-lazy-load-image-component": "^1.5.2",
"@types/react-redux": "^7.1.24",
"@types/react-slick": "^0.23.10",
"@types/stylis": "^4.0.2",
"@typescript-eslint/eslint-plugin": "^5.40.0",
"@typescript-eslint/parser": "^5.40.0",
"eslint": "^8.25.0",
"eslint-config-next": "^12.3.1",
"eslint-config-prettier": "^8.5.0",
"prettier": "^2.7.1",
"typescript": "^4.8.4"
}
}
<svg height="1024" viewBox="0 0 1440 1024" width="1440" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><radialGradient id="a" cx="14.340549%" cy="-11.486891%" gradientTransform="matrix(.28937714 .91345637 -.64956887 .40693667 .027292 -.199119)" r="109.474303%"><stop offset="0" stop-color="#161c24" stop-opacity=".48"/><stop offset=".498646968" stop-color="#161c24" stop-opacity=".8"/><stop offset="1" stop-color="#161c24"/></radialGradient><path d="m0 0h1440v1024h-1440z" fill="url(#a)" fill-rule="evenodd" transform="matrix(-1 0 0 1 1440 0)"/></svg>
\ No newline at end of file
<svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.89746 4.19042C8.4759 -2.30199 18.8193 -1.02042 22.6861 6.56337C19.9642 6.56436 15.7018 6.56255 13.3932 6.56337C11.7189 6.56395 10.6378 6.52589 9.46712 7.1422C8.09079 7.86668 7.05232 9.20962 6.68982 10.787L2.89746 4.19042Z" fill="#EA4335"/>
<path d="M8.00781 12.0093C8.00781 14.2096 9.79692 15.9997 11.9961 15.9997C14.1952 15.9997 15.9843 14.2096 15.9843 12.0093C15.9843 9.80896 14.1952 8.0188 11.9961 8.0188C9.79692 8.0188 8.00781 9.80896 8.00781 12.0093Z" fill="#4285F4"/>
<path d="M13.5438 17.2326C11.3053 17.8979 8.68567 17.1601 7.25074 14.6832C6.15542 12.7926 3.26143 7.75096 1.94603 5.4585C-2.66093 12.5195 1.30962 22.1419 9.67323 23.7843L13.5438 17.2326Z" fill="#34A853"/>
<path d="M15.7005 8.0188C17.5649 9.75289 17.9711 12.5608 16.7082 14.7381C15.7567 16.3784 12.7199 21.5039 11.248 23.9859C19.8652 24.5171 26.1469 16.0716 23.3095 8.0188H15.7005Z" fill="#FBBC05"/>
</svg>
<svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4 22.5098L7.9997 15.5098H23.9998L19.9997 22.5098H4Z" fill="#3777E3"/>
<path d="M16.0003 15.5098H24.0001L16.0003 1.50977H8L16.0003 15.5098Z" fill="#FFCF63"/>
<path d="M0 15.5098L4.00024 22.5098L12 8.50977L7.99994 1.50977L0 15.5098Z" fill="#11A861"/>
</svg>
<svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.00015 4.65586L7.0599 0.00976562L12.0001 4.16598L12 4.16608L12 4.16609L4.8819 8.5959L0.00015 4.65586ZM19.1181 8.59585L12 4.16609L12.0001 4.166L12.0001 4.16598L16.9403 0.00984113L24 4.65594L19.1182 8.59597L19.1181 8.59582L19.1181 8.59585ZM19.1181 8.59585L19.1182 8.59597L23.9998 12.5366L16.9401 17.1827L11.9999 13.0265L7.05975 17.1826L0 12.5365L4.88175 8.5965L12 13.0264L19.1181 8.59585ZM12.0145 13.9206L7.05997 18.0648L4.93972 16.6693V18.2333L12.0145 22.5098L19.0892 18.2333V16.6693L16.969 18.0648L12.0145 13.9206Z" fill="#0F82E2"/>
</svg>
<svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M21.4549 4.1852C21.2763 3.22746 20.7093 2.75571 20.1961 2.57046C19.6433 2.36947 18.5213 2.16172 17.1116 1.99447C15.9777 1.86097 14.645 1.87147 13.8397 1.89622C13.7433 1.23173 13.2794 0.624981 12.7595 0.414981C11.376 -0.144514 9.23723 -0.00951439 8.68891 0.144986C8.25265 0.267231 7.76932 0.518481 7.50039 0.904726C7.32036 1.16273 7.20382 1.49422 7.20307 1.95622C7.20307 2.17287 7.20819 2.63205 7.21334 3.09432L7.21652 3.38121C7.2221 3.83713 7.2282 4.25323 7.23011 4.38335L7.23011 4.38345L7.23071 4.4252C7.23071 4.91344 6.83554 5.31169 6.34623 5.31244H4.10291C3.62407 5.31244 3.25802 5.39344 2.97938 5.52019C2.69925 5.64844 2.50129 5.82018 2.35039 6.02343C2.05083 6.42768 1.99854 6.92567 2.00003 7.43417C2.00003 7.43417 2.00451 7.85042 2.10461 8.65441C2.18753 9.2769 2.85986 13.6261 3.49857 14.9484C3.74583 15.4628 3.91093 15.6773 4.39724 15.9038C5.48118 16.3703 7.95757 16.8886 9.1177 17.0371C9.30985 17.0617 9.49013 17.0909 9.65916 17.1182C10.5094 17.2556 11.0751 17.3471 11.4365 16.5863C11.438 16.5841 11.5231 16.3591 11.6404 16.0298C12.0169 14.8854 12.0692 13.8699 12.0692 13.1356C12.0692 13.0606 12.1783 13.0576 12.1783 13.1356C12.1783 13.1644 12.178 13.1973 12.1776 13.2338V13.2338C12.1719 13.8539 12.1565 15.5172 13.4609 15.9826C14.0062 16.1768 15.1372 16.3493 16.2862 16.4851C17.3253 16.6051 18.0798 17.0153 18.0798 19.6921C18.0798 21.3203 17.7391 21.5438 15.9582 21.5438L15.8258 21.5439C14.4804 21.545 13.9637 21.5454 13.9637 20.43C13.9637 19.5785 14.7315 19.5877 15.3822 19.5954H15.3823C15.4428 19.5961 15.5023 19.5968 15.5601 19.5968C15.7515 19.5968 15.735 19.507 15.6966 19.2971C15.674 19.1737 15.6437 19.0086 15.6437 18.7958C15.6437 18.5535 15.7077 18.3545 15.7557 18.2051C15.8209 18.0023 15.8568 17.8908 15.6632 17.8861C13.313 17.8208 11.9303 17.8831 11.9303 20.8335C11.9303 23.5125 12.9514 24.0098 16.2862 24.0098C18.9015 24.0098 19.8233 23.9235 20.9028 20.5605C21.1164 19.8961 21.6334 17.8703 21.9457 14.4676C22.1436 12.3166 21.7596 5.82393 21.4549 4.1852ZM16.8965 11.3619C16.5738 11.3506 16.263 11.3709 15.9732 11.4174C16.0546 10.7566 16.3265 9.94515 17.2894 9.9789C18.3554 10.0164 18.5048 11.0274 18.5086 11.7129C18.0589 11.5111 17.5023 11.3836 16.8965 11.3619ZM3.99907 4.65844H3.99758C3.44628 4.65844 2.98611 4.75219 2.60662 4.92469C2.58944 4.93219 2.46618 4.99294 2.37579 5.03794C2.37803 5.02894 2.384 5.01919 2.39222 5.01244L6.75112 0.672231C6.76009 0.663981 6.7683 0.659481 6.77727 0.658731L6.70032 0.802726C6.53971 1.12523 6.44783 1.50922 6.44783 1.95022V1.95697C6.44783 2.47461 6.47282 4.28716 6.47462 4.41776L6.47472 4.4252C6.47472 4.5527 6.37088 4.65844 6.2424 4.65844H3.99907Z" fill="#20C05C"/>
</svg>
<svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.9993 0.509766C5.373 0.509766 0 5.90331 0 12.5581C0 17.8801 3.438 22.3957 8.20725 23.989C8.80725 24.0997 9.02625 23.7277 9.02625 23.4084C9.02625 23.1223 9.01575 22.3648 9.00975 21.3596C5.6715 22.0877 4.96725 19.7445 4.96725 19.7445C4.422 18.353 3.63525 17.9825 3.63525 17.9825C2.5455 17.2348 3.71775 17.2499 3.71775 17.2499C4.9215 17.3349 5.55525 18.4915 5.55525 18.4915C6.62625 20.3325 8.364 19.8009 9.048 19.4922C9.15675 18.7136 9.46725 18.1828 9.81 17.8816C7.14525 17.5774 4.344 16.5443 4.344 11.9278C4.344 10.6124 4.81125 9.53716 5.57925 8.69458C5.4555 8.38963 5.04375 7.16529 5.69625 5.50649C5.69625 5.50649 6.70425 5.18272 8.99625 6.74137C9.954 6.47407 10.98 6.34079 12.0007 6.33552C13.02 6.34079 14.0468 6.47407 15.0052 6.74137C17.2957 5.18272 18.3015 5.50649 18.3015 5.50649C18.9563 7.16529 18.5445 8.38963 18.4207 8.69458C19.1903 9.53716 19.6545 10.6124 19.6545 11.9278C19.6545 16.5556 16.8487 17.5744 14.1757 17.8726C14.6062 18.2445 14.9902 18.9794 14.9902 20.1036C14.9902 21.7142 14.9753 23.0131 14.9753 23.4084C14.9753 23.7307 15.1912 24.1057 15.8003 23.9875C20.565 22.3912 24 17.8786 24 12.5581C24 5.90331 18.627 0.509766 11.9993 0.509766Z" fill="#3E75C3"/>
</svg>
<svg width="24" height="25" viewBox="0 0 24 25" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16.9688 8.04883C16.8726 8.04883 16.7764 8.05136 16.6802 8.05628C15.5573 7.14011 14.1652 6.64258 12.6914 6.64253C12.4578 6.64253 12.2273 6.6556 12.0002 6.68039C9.14361 6.9922 6.852 9.2126 6.43223 12.0358C5.77022 12.3495 5.1788 12.8102 4.71169 13.3846C4.00087 14.2587 3.60938 15.3603 3.60938 16.4864C3.60938 16.8879 3.65808 17.2782 3.7492 17.6521C1.66284 17.5393 0 15.8066 0 13.6926C0 11.7306 1.43241 10.0968 3.30628 9.7818C3.62358 7.45089 5.62716 5.64888 8.04375 5.64888C8.35444 5.64888 8.66363 5.67907 8.96761 5.73888C9.78754 4.88342 10.8463 4.31708 12 4.10792C12.3286 4.04834 12.6648 4.01758 13.0055 4.01758C15.6187 4.01758 17.819 5.81786 18.4321 8.24322C17.9583 8.11525 17.4666 8.04883 16.9688 8.04883Z" fill="#0A49B2"/>
<path d="M7.77023 13.0537C7.76977 13.026 7.76953 12.9983 7.76953 12.9707C7.76953 10.4914 9.61228 8.43478 12 8.09766C12.226 8.06573 12.4567 8.04883 12.6914 8.04883C14.0249 8.04883 15.2824 8.58166 16.2056 9.52459C16.457 9.47837 16.7123 9.45508 16.9688 9.45508C19.0768 9.45508 20.8286 11.0091 21.1387 13.0317C22.7657 13.3392 24 14.7713 24 16.4863C24 18.4248 22.4229 20.002 20.4844 20.002L8.53125 20.0019C6.59273 20.0019 5.01562 18.4248 5.01562 16.4863C5.01562 14.809 6.19631 13.4023 7.77023 13.0537Z" fill="#0A49B2"/>
</svg>
<svg width="133" height="41" viewBox="0 0 133 41" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M76.9476 1.37896V4.41074C76.9476 4.80194 77.3388 5.09534 77.7299 5.19314H84.7715L76.6542 16.8313C76.1652 17.6137 76.1652 18.3961 76.1652 18.8851V21.9169C76.1652 22.4059 76.6542 22.7971 77.1432 22.6015C81.7397 20.1565 87.3143 20.4499 91.4219 22.6015C91.9109 22.8948 92.3999 22.4059 92.3999 21.9169V18.6895C92.3999 18.2983 92.2043 17.8093 91.7153 17.5159C89.3681 16.1467 86.6297 15.8533 83.9891 15.8533L91.0307 5.87774C91.1078 5.74915 91.1816 5.62733 91.2515 5.51183C91.7136 4.74882 92.0087 4.26151 92.0087 3.92175V1.37896C92.0087 0.987761 91.6175 0.596563 91.2263 0.596563H77.7299C77.241 0.596563 76.9476 0.889961 76.9476 1.37896ZM23.549 23.1882H27.6566C28.0478 23.1882 28.439 22.8949 28.2434 22.5037V11.2567C28.2434 11.1779 28.2433 11.0983 28.2432 11.0181C28.2403 8.51094 28.2366 5.38874 31.0796 5.38874C33.7136 5.38874 33.6676 8.22641 33.6307 10.505C33.6265 10.7645 33.6224 11.0167 33.6224 11.2567V22.5037C33.6224 22.8949 34.0136 23.286 34.4048 23.286H38.5124C38.9035 23.286 39.2948 22.8949 39.2948 22.5037V11.2567C39.2948 9.98532 39.2948 8.22492 39.6859 7.14913C40.0771 6.07334 41.1529 5.38874 42.1309 5.38874C43.4023 5.38874 44.2825 5.87774 44.5759 7.24693C44.7296 7.93851 44.7022 9.47537 44.6833 10.5292C44.6782 10.8166 44.6737 11.0681 44.6737 11.2567V22.5037C44.6737 22.8949 45.0649 23.286 45.4561 23.286H49.5637C49.9549 23.286 50.3461 22.8949 50.3461 22.5037V9.10512C50.3461 8.73553 50.3534 8.36109 50.3607 7.98562C50.3997 5.97655 50.4393 3.93795 49.3681 2.45475C48.1945 0.792162 46.3363 0.107565 44.5759 0.107565C42.1309 0.107565 39.8815 1.37896 38.9035 4.01955C37.8278 1.37896 36.1652 0.107565 33.6224 0.107565C31.1774 0.107565 29.2214 1.37896 28.2434 4.01955H28.1456V1.28116C28.0478 0.889961 27.7544 0.596563 27.3632 0.596563H23.549C23.1578 0.596563 22.7666 0.987761 22.7666 1.37896V22.5037C22.8644 22.8949 23.1578 23.1882 23.549 23.1882ZM94.4537 11.9413C94.3559 5.29094 97.6811 0.205365 103.647 0.205365C109.808 0.205365 113.133 5.38874 113.036 12.1369C113.036 18.5917 109.417 23.6772 103.647 23.6772C97.6811 23.6772 94.4537 18.4939 94.4537 11.9413ZM100.517 11.4834C100.514 14.1977 100.509 19.3741 103.647 19.3741C106.776 19.3741 106.972 14.8753 107.07 12.1369C107.07 10.3765 106.972 8.22492 106.483 6.56233C105.994 5.09534 105.016 4.50854 103.745 4.50854C100.713 4.50854 100.517 8.71392 100.517 11.2567C100.517 11.3301 100.517 11.4058 100.517 11.4834ZM116.85 23.1882H120.957C121.446 23.1882 121.838 22.8949 121.838 22.5037V11.0611C121.838 9.59412 121.935 8.32272 122.522 7.05133C122.913 6.07334 123.891 5.38874 124.869 5.38874C127.468 5.38874 127.439 8.17943 127.416 10.4523C127.414 10.6604 127.412 10.8642 127.412 11.0611V22.5037C127.51 22.8949 127.803 23.1882 128.194 23.1882H132.204C132.595 23.1882 132.987 22.8949 132.987 22.5037V9.20292C132.987 7.14913 132.987 4.31294 131.911 2.65035C130.737 0.889961 128.977 0.205365 127.119 0.205365C124.283 0.205365 122.718 1.47676 121.544 4.41074H121.446V1.18336C121.349 0.889961 121.055 0.596563 120.664 0.596563H116.85C116.459 0.596563 116.067 0.889961 116.067 1.28116V22.4059C116.067 22.7971 116.459 23.1882 116.85 23.1882ZM73.3194 19.095C73.3875 19.187 73.456 19.2798 73.5246 19.3741C73.818 19.7653 73.818 20.2543 73.4268 20.3521C72.9867 20.6944 72.3999 21.2078 71.8131 21.7213C71.2263 22.2347 70.6395 22.7482 70.1994 23.0905C69.906 23.286 69.5148 23.3838 69.2214 23.1882C68.173 22.3645 67.8127 21.8275 67.3501 21.1381C67.2086 20.9271 67.0575 20.7019 66.8742 20.4499C64.6248 22.7971 63.06 23.4816 60.126 23.4816C56.7031 23.4816 53.9647 21.3301 53.9647 17.1247C53.9647 13.7017 55.8229 11.4523 58.3657 10.3765C60.2246 9.56827 62.6847 9.29439 64.8076 9.05806C65.2534 9.00842 65.6844 8.96045 66.0918 8.90952V8.42052C66.0918 8.30031 66.0933 8.17715 66.0948 8.05193C66.1055 7.15845 66.1175 6.16074 65.6028 5.38874C65.1138 4.60634 64.2336 4.31294 63.3534 4.31294C61.7886 4.31294 60.3216 5.09534 60.0282 6.75793C59.9304 7.14913 59.7348 7.54033 59.3436 7.54033L55.3339 7.14913C55.0405 7.05133 54.6493 6.75793 54.7471 6.26893C55.7251 1.47676 60.0282 0.00976562 63.9402 0.00976562C65.994 0.00976562 68.6346 0.498763 70.1016 2.06356C71.9896 3.86162 71.9767 6.07292 71.9623 8.54549C71.9611 8.76266 71.9598 8.98183 71.9598 9.20292V15.5599C71.9598 17.2553 72.6111 18.1365 73.3194 19.095ZM62.571 19.3741C63.7446 19.3741 64.7226 18.6895 65.4072 17.5159C66.1896 16.0489 66.1896 14.6797 66.1896 13.1149V12.2347C63.1578 12.2347 60.0282 12.8215 60.0282 16.3423C60.0282 18.2005 61.0062 19.3741 62.571 19.3741ZM19.3341 19.095C19.4021 19.187 19.4707 19.2798 19.5392 19.3741C19.8326 19.7653 19.9304 20.2543 19.5392 20.3521C19.0992 20.6944 18.5124 21.2078 17.9256 21.7213C17.3388 22.2347 16.752 22.7482 16.3119 23.0905C16.0185 23.286 15.6273 23.3838 15.3339 23.1882C14.2855 22.3645 13.9252 21.8275 13.4626 21.1381C13.3211 20.9271 13.17 20.7019 12.9867 20.4499C10.7373 22.7971 9.1725 23.4816 6.23852 23.4816C2.81553 23.4816 0.0771484 21.3301 0.0771484 17.1247C0.0771484 13.7017 1.93534 11.4523 4.47813 10.3765C6.33709 9.56827 8.79722 9.29439 10.9201 9.05806C11.3659 9.00842 11.7969 8.96045 12.2043 8.90952V8.42052C12.2043 8.30031 12.2058 8.17713 12.2073 8.05191C12.218 7.15844 12.23 6.16074 11.7153 5.38874C11.2263 4.60634 10.3461 4.31294 9.4659 4.31294C7.90111 4.31294 6.43412 5.09534 6.14072 6.75793C6.04292 7.14913 5.84732 7.54033 5.45612 7.54033L1.44634 7.14913C1.05514 7.05133 0.761745 6.85573 0.859544 6.26893C1.83754 1.47676 6.14072 0.00976562 10.0527 0.00976562C12.0087 0.00976562 14.6493 0.498763 16.1163 2.06356C18.0042 3.86163 17.9914 6.07293 17.977 8.54551C17.9757 8.76266 17.9745 8.98184 17.9745 9.20292V15.5599C17.9745 17.2553 18.6257 18.1365 19.3341 19.095ZM8.68351 19.3741C9.8571 19.3741 10.8351 18.6895 11.5197 17.5159C12.3021 16.0489 12.3021 14.6797 12.3021 13.1149V12.2347C9.2703 12.2347 6.14072 12.8215 6.14072 16.3423C6.14072 18.2005 7.11871 19.3741 8.68351 19.3741ZM54.0644 40.0098C63.7465 40.0098 74.8956 36.978 82.6218 31.3056C83.8932 30.4254 82.8174 28.9584 81.4482 29.4474C72.8419 33.1638 63.3553 34.9242 54.8467 34.9242C42.1328 34.9242 29.8101 31.5012 19.9323 25.731C19.0521 25.1442 18.4653 26.0244 19.1499 26.709C28.4409 35.022 40.568 40.0098 54.0644 40.0098ZM76.9325 27.2861C79.4173 26.9878 84.8818 26.3317 85.8492 27.5892C86.7633 28.8689 84.9435 33.4804 83.9831 35.9143C83.9159 36.0846 83.853 36.2441 83.7954 36.3912C83.502 37.0758 84.0888 37.3692 84.7734 36.8802C88.9788 33.4572 90.0546 26.1222 89.1744 25.1442C88.2942 24.1663 81.057 23.1883 76.656 26.3178C75.9714 26.709 76.0692 27.3936 76.8516 27.2958L76.9325 27.2861Z" fill="white"/>
</svg>
<svg width="98" height="41" viewBox="0 0 98 41" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M17.7666 0.423559H28.5712V39.55H17.7666V25.0672H10.87V39.55H0.0654297V0.423559H10.87V15.1822H17.7666V0.423559ZM97.0769 20.0098C97.0769 31.0442 88.1114 40.0098 77.0769 40.0098C68.5942 40.0098 61.3298 34.6994 58.4332 27.2511C58.4562 27.504 58.4562 27.7799 58.4562 28.0557C58.4562 40.0098 48.1114 39.55 48.1114 39.55H30.87V0.423559H47.4217C50.4103 0.423559 58.916 2.05574 58.916 10.4236C58.916 10.8833 58.893 11.3201 58.87 11.7339C62.0195 4.81436 69.008 0.00976562 77.0769 0.00976562C88.1114 0.00976562 97.0769 8.97528 97.0769 20.0098ZM48.5712 27.1362C48.5712 24.3776 46.2723 24.3776 46.2723 24.3776H40.5252V30.3546H46.2723C46.2723 30.3546 48.5712 30.1247 48.5712 27.1362ZM48.5712 12.7684C48.5712 9.9408 46.2723 9.96379 46.2723 9.96379H40.5252V15.8718H46.2723C46.2723 15.8718 48.5712 15.596 48.5712 12.7684ZM57.3298 23.1362C57.1689 22.1247 57.0769 21.0672 57.0769 20.0098C57.0769 18.9523 57.1689 17.9408 57.3068 16.9293C56.1574 18.6534 54.5482 19.3661 53.1689 19.619C51.7896 19.8718 55.3988 19.7569 57.3298 23.1362ZM86.962 20.0098C86.962 14.5615 82.5252 10.1247 77.0769 10.1247C71.6286 10.1247 67.1919 14.5615 67.1919 20.0098C67.1919 25.458 71.6286 29.8948 77.0769 29.8948C82.5252 29.8948 86.962 25.458 86.962 20.0098ZM77.0769 11.9638C72.6401 11.9638 69.0309 15.573 69.0309 20.0098C69.0309 24.4465 72.6401 28.0557 77.0769 28.0557C81.5137 28.0557 85.1229 24.4465 85.1229 20.0098C85.1229 15.573 81.5137 11.9638 77.0769 11.9638Z" fill="white"/>
</svg>
<svg width="100" height="41" viewBox="0 0 100 41" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 0.00976562V2.73704H19.4318V0.00976562H0ZM22.2727 0.00976562V2.73704H50C50 2.73704 47.1591 0.00976562 43.4091 0.00976562H22.2727ZM55.4545 0.00976562V2.73704H72.2727L71.1364 0.00976562H55.4545ZM84.2045 0.00976562L83.1818 2.73704H99.7727V0.00976562H84.2045ZM0 5.35067V8.07795H19.4318V5.35067H0ZM22.2727 5.35067V8.07795H53.1818C53.1818 8.07795 52.8409 5.91886 52.1591 5.35067H22.2727ZM55.4545 5.35067V8.07795H74.0909L73.1818 5.35067H55.4545ZM82.2727 5.35067L81.3636 8.07795H99.8864V5.35067H82.2727ZM5.56818 10.6916V13.4189H13.9773V10.6916H5.56818ZM27.8409 10.6916V13.4189H36.25V10.6916H27.8409ZM44.4318 10.6916V13.4189H52.8409C52.8409 13.4189 53.4091 11.9416 53.4091 10.6916H44.4318ZM61.0227 10.6916V13.4189H76.0227L75 10.6916H61.0227ZM80.3409 10.6916L79.3182 13.4189H94.3182V10.6916H80.3409ZM5.56818 16.0325V18.7598H13.9773V16.0325H5.56818ZM27.8409 16.0325V18.7598H49.3182C49.3182 18.7598 51.1364 17.3961 51.7045 16.0325H27.8409ZM61.0227 16.0325V18.7598H69.4318V17.2825L70 18.7598H85.4545L86.0227 17.2825V18.7598H94.4318V16.0325H78.6364L77.8409 18.3052L77.0454 16.0325H61.0227ZM5.56818 21.2598V23.987H13.9773V21.2598H5.56818ZM27.8409 21.2598V23.987H51.7045C51.1364 22.6234 49.3182 21.2598 49.3182 21.2598H27.8409ZM61.0227 21.2598V23.987H69.4318V21.2598H61.0227ZM70.9091 21.2598L71.9318 23.987H83.5227L84.5454 21.2598H70.9091ZM86.0227 21.2598V23.987H94.4318V21.2598H86.0227ZM5.56818 26.6007V29.3279H13.9773V26.6007H5.56818ZM27.8409 26.6007V29.3279H36.25V26.6007H27.8409ZM44.4318 26.6007V29.3279H53.4091C53.4091 28.0779 52.8409 26.6007 52.8409 26.6007H44.4318ZM61.0227 26.6007V29.3279H69.4318V26.6007H61.0227ZM72.8409 26.6007L73.8636 29.3279H81.5909L82.6136 26.6007H72.8409ZM86.0227 26.6007V29.3279H94.4318V26.6007H86.0227ZM0.113636 31.9416V34.6689H19.5455V31.9416H0.113636ZM22.2727 31.9416V34.6689H52.2727C52.9545 33.987 53.2955 31.9416 53.2955 31.9416H22.2727ZM55.5682 31.9416V34.6689H69.4318V31.9416H55.5682ZM74.7727 31.9416L75.7954 34.6689H79.7727L80.6818 31.9416H74.7727ZM86.0227 31.9416V34.6689H100V31.9416H86.0227ZM0.113636 37.2825V40.0098H19.5455V37.2825H0.113636ZM22.2727 37.2825V40.0098H43.4091C47.1591 40.0098 50 37.2825 50 37.2825H22.2727ZM55.5682 37.2825V40.0098H69.4318V37.2825H55.5682ZM76.7045 37.2825L77.7273 40.0098H77.8409L78.8636 37.2825H76.7045ZM86.0227 37.2825V40.0098H100V37.2825H86.0227Z" fill="white"/>
</svg>
<svg width="59" height="41" viewBox="0 0 59 41" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M22.1428 20.9241C22.1428 21.2812 21.9714 21.6241 21.6785 21.8241C20.5285 22.6312 19.2857 21.8169 19.2857 20.7241V9.29551H10.7143V23.5812C10.7143 27.5169 13.9214 30.7241 17.8571 30.7241C19.5571 30.7241 21.2071 30.1169 22.5 29.0098C22.3643 30.0669 21.7857 30.9383 20.8143 31.5455C19.9071 32.1169 18.7214 32.4169 17.3928 32.4169C16.0214 32.4169 14.6286 32.0955 13.3643 31.4883C13.3643 31.4883 13.1357 31.3812 12.85 31.2169V38.8312C14.7571 39.6026 16.85 40.0098 18.8714 40.0098C22.0714 40.0098 24.9928 39.0098 27.1 37.1883C29.4643 35.1526 30.7143 32.1741 30.7143 28.5812V9.29551H22.1428V20.9241ZM8.57142 23.5812V0.724093H0V22.1526C0 28.0383 3.88571 30.7241 7.49999 30.7241C8.57856 30.7241 9.65713 30.4741 10.6214 30.0241C10.7643 29.9598 10.9928 29.8169 10.9928 29.8169C10.9928 29.8169 10.7786 29.5883 10.6857 29.4883C9.31428 27.9241 8.57142 25.8955 8.57142 23.5812ZM58.5714 17.8669V9.29551H55.5142C54.2357 2.55981 47.1571 -1.86876 40.0428 0.795521C36.0785 2.27409 32.8571 7.0098 32.8571 11.2455V30.7241H33.2285C35.4357 30.6312 37.5 29.6955 39.0357 28.0955C40.5785 26.4883 41.4285 24.3812 41.4285 22.1598H45V13.5812H41.4285V11.2241C41.4285 10.3098 41.9142 9.45265 42.7142 9.0098C44.9071 7.78837 47.1428 9.3598 47.1428 11.4384V19.2955C47.1428 22.4026 48.3142 25.2884 50.4428 27.4241C52.4785 29.4598 55.2357 30.6312 58.1999 30.7241H58.5642V22.1526C56.9642 22.1455 55.7071 20.8598 55.7071 19.2955V17.8669H58.5714Z" fill="white"/>
</svg>
<svg width="149" height="41" viewBox="0 0 149 41" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M126.571 37.3661C128.64 37.596 130.709 37.8259 132.663 38.0557L137.145 26.9063L141.398 39.0902C143.582 39.3201 145.766 39.6649 147.95 40.0098L140.479 18.6305L148.065 0.00976562H141.743L141.628 0.124708L137.605 10.1247L134.042 0.00976562H127.72L134.157 18.4006L126.571 37.3661ZM121.743 36.9063V0.00976563H115.421V36.4465C117.605 36.5615 119.674 36.7914 121.743 36.9063ZM74.5017 34.8374H79.5592V21.3891H87.1454V15.6419H79.5592V5.75689H88.2948V0.00976563H73.3523V34.8374H74.5017ZM55.0764 35.1822C57.1454 35.0672 59.2143 35.0672 61.3982 34.9523V5.75689H67.2603V0.00976563H49.2143V5.75689H55.0764V35.1822ZM6.91549 39.0902V17.1362L14.3868 38.2856L21.2833 37.596V0.00976563H15.3063V22.7684L7.26032 0.00976563H0.938477V39.8948C3.00744 39.6649 4.96146 39.4351 6.91549 39.0902ZM43.1224 5.75689V0.00976563H28.0649V36.9063C33.0074 36.4465 38.0649 36.1017 43.0074 35.8718V30.1247C40.1339 30.2397 37.2603 30.4695 34.2718 30.6994V21.3891H41.858V15.6419H34.2718V5.75689H43.1224ZM100.824 29.7799V0.00976563H94.5017V35.2971C99.5592 35.527 104.502 35.7569 109.559 36.1017V30.3546C106.571 30.0098 103.697 29.8948 100.824 29.7799Z" fill="white"/>
</svg>
<svg width="134" height="41" viewBox="0 0 134 41" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M20.5713 0.00976562C9.52523 0.00976562 0.571289 8.96371 0.571289 20.0098C0.571289 31.0558 9.52523 40.0098 20.5713 40.0098C31.6173 40.0098 40.5713 31.0558 40.5713 20.0098C40.5713 8.96507 31.6173 0.0111303 20.5713 0.00976562ZM29.7436 28.8545C29.3847 29.4441 28.6163 29.6283 28.0295 29.2694C23.3335 26.3994 17.4215 25.7512 10.4601 27.3411C9.78862 27.4953 9.11991 27.0749 8.96706 26.4035C8.81285 25.732 9.23181 25.0633 9.90462 24.9105C17.5225 23.1705 24.0582 23.9197 29.3301 27.1404C29.9169 27.5021 30.1039 28.2677 29.7436 28.8545ZM32.1905 23.4107C31.7388 24.1449 30.778 24.3741 30.0452 23.9238C24.6709 20.6198 16.4744 19.6631 10.1162 21.5928C9.29186 21.8426 8.42117 21.3772 8.17006 20.5543C7.92168 19.73 8.38705 18.8607 9.20998 18.6096C16.473 16.4055 25.5034 17.4727 31.676 21.2667C32.4103 21.7184 32.6423 22.6778 32.1905 23.4107ZM32.4007 17.7389C25.9538 13.9108 15.3198 13.5587 9.16494 15.4257C8.17688 15.7259 7.13151 15.1677 6.83263 14.1797C6.53376 13.1916 7.09057 12.1462 8.07999 11.846C15.1452 9.70202 26.8886 10.1155 34.3099 14.5209C35.1984 15.049 35.4904 16.1967 34.9636 17.0838C34.4382 17.9736 33.2878 18.267 32.4007 17.7389ZM54.9841 18.4731C51.5314 17.6502 50.9159 17.0715 50.9159 15.8569C50.9159 14.7092 51.9967 13.9381 53.603 13.9381C55.1602 13.9381 56.7037 14.5249 58.3236 15.7314C58.3727 15.7682 58.4341 15.7819 58.4942 15.7723C58.5542 15.7628 58.6075 15.73 58.6429 15.6795L60.3284 13.3022C60.398 13.2039 60.3789 13.0688 60.2861 12.9951C58.3591 11.4489 56.1905 10.6969 53.6535 10.6969C49.9251 10.6969 47.3212 12.935 47.3212 16.1353C47.3212 19.569 49.5675 20.7836 53.4502 21.7225C56.7542 22.484 57.3123 23.1213 57.3123 24.2609C57.3123 25.5246 56.1851 26.3093 54.37 26.3093C52.3543 26.3093 50.7098 25.6297 48.8715 24.0371C48.8265 23.9975 48.7637 23.9797 48.705 23.9825C48.6436 23.9879 48.589 24.0152 48.5495 24.0616L46.6593 26.3121C46.5802 26.4049 46.5897 26.5454 46.6811 26.6259C48.821 28.5365 51.4522 29.5451 54.2936 29.5451C58.3113 29.5451 60.907 27.3492 60.907 23.9524C60.9138 21.0838 59.197 19.4953 54.9909 18.4731H54.9841ZM69.9974 15.0681C68.256 15.0681 66.8272 15.7546 65.6494 17.1589V15.5771C65.6494 15.4516 65.5484 15.3506 65.4229 15.3506H62.3304C62.2049 15.3506 62.1039 15.453 62.1039 15.5771V33.1548C62.1039 33.2803 62.2049 33.3813 62.3304 33.3813H65.4229C65.5471 33.3813 65.6494 33.279 65.6494 33.1548V27.6058C66.8272 28.9282 68.256 29.5737 69.9974 29.5737C73.2332 29.5737 76.5085 27.0831 76.5085 22.3216C76.514 17.5587 73.2359 15.0667 70.0002 15.0667L69.9974 15.0681ZM72.9138 22.3216C72.9138 24.7467 71.4208 26.439 69.2809 26.439C67.167 26.439 65.5716 24.6703 65.5716 22.3216C65.5716 19.9743 67.167 18.2042 69.2809 18.2042C71.3853 18.2042 72.9138 19.9361 72.9138 22.3216ZM84.9043 15.0681C80.7364 15.0681 77.472 18.2766 77.472 22.3748C77.472 26.4281 80.7146 29.6024 84.8524 29.6024C89.0339 29.6024 92.3093 26.4049 92.3093 22.323C92.3106 18.2547 89.0571 15.0681 84.9043 15.0681ZM84.9043 26.4622C82.688 26.4622 81.0162 24.6812 81.0162 22.3202C81.0162 19.9484 82.6293 18.2288 84.8524 18.2288C87.0837 18.2288 88.7651 20.0098 88.7651 22.3721C88.7664 24.7426 87.1424 26.4622 84.9043 26.4622ZM101.21 15.3506H97.8077V11.8719C97.8077 11.7477 97.7067 11.6454 97.5826 11.6454H94.4915C94.3659 11.6454 94.2649 11.7477 94.2649 11.8719V15.3506H92.7787C92.6545 15.3506 92.5535 15.453 92.5535 15.5771V18.2343C92.5535 18.3585 92.6545 18.4608 92.7787 18.4608H94.2649V25.3363C94.2649 28.1148 95.6474 29.5232 98.3755 29.5232C99.485 29.5232 100.405 29.294 101.271 28.8027C101.342 28.7631 101.386 28.6867 101.386 28.6061V26.076C101.386 25.9982 101.345 25.9245 101.278 25.8835C101.211 25.8412 101.127 25.8385 101.058 25.8726C100.463 26.1728 99.8876 26.3107 99.2434 26.3107C98.2513 26.3107 97.8091 25.8603 97.8091 24.8504V18.4608H101.211C101.337 18.4608 101.437 18.3585 101.437 18.2343V15.5771C101.442 15.4516 101.341 15.3506 101.214 15.3506H101.21ZM113.065 15.3643V14.9371C113.065 13.6802 113.547 13.1193 114.628 13.1193C115.272 13.1193 115.791 13.2476 116.371 13.4414C116.442 13.4632 116.517 13.4523 116.574 13.41C116.634 13.3677 116.667 13.2981 116.667 13.2257V10.6191C116.667 10.5195 116.603 10.4308 116.507 10.4021C115.894 10.2193 115.111 10.0323 113.937 10.0323C111.081 10.0323 109.572 11.6399 109.572 14.6819V15.3356H108.085C107.961 15.3356 107.859 15.4379 107.859 15.5621V18.2329C107.859 18.3571 107.961 18.4594 108.085 18.4594H109.572V29.0661C109.572 29.1916 109.673 29.2926 109.797 29.2926H112.889C113.015 29.2926 113.116 29.1903 113.116 29.0661V18.4608H116.002L120.424 29.0647C119.922 30.1783 119.428 30.4008 118.755 30.4008C118.21 30.4008 117.636 30.2384 117.05 29.9176C116.996 29.8876 116.93 29.8822 116.87 29.9013C116.811 29.9217 116.761 29.9654 116.736 30.0227L115.688 32.3223C115.638 32.4315 115.681 32.5584 115.785 32.6143C116.88 33.2066 117.866 33.4591 119.088 33.4591C121.371 33.4591 122.633 32.396 123.746 29.5342L129.11 15.6727C129.138 15.6031 129.129 15.5239 129.086 15.4625C129.043 15.4011 128.975 15.3643 128.9 15.3643H125.681C125.584 15.3643 125.498 15.4257 125.467 15.5157L122.169 24.935L118.557 15.5103C118.524 15.4229 118.44 15.3643 118.345 15.3643H113.065ZM106.191 15.3506H103.099C102.973 15.3506 102.872 15.453 102.872 15.5771V29.0674C102.872 29.193 102.975 29.294 103.099 29.294H106.191C106.315 29.294 106.418 29.1916 106.418 29.0674V15.5785C106.418 15.453 106.317 15.352 106.191 15.3506C106.193 15.3506 106.191 15.3506 106.191 15.3506ZM104.663 9.20799C103.437 9.20799 102.444 10.2001 102.444 11.4243C102.444 12.6498 103.439 13.6433 104.663 13.6433C105.887 13.6433 106.88 12.6512 106.88 11.4243C106.88 10.2001 105.887 9.20799 104.663 9.20799ZM131.751 19.6877C130.527 19.6877 129.576 18.7051 129.576 17.511C129.576 16.3168 130.541 15.3233 131.763 15.3233C132.988 15.3233 133.939 16.3059 133.939 17.4987C133.937 18.6928 132.973 19.6877 131.751 19.6877ZM131.762 15.5403C130.647 15.5403 129.804 16.426 129.804 17.511C129.804 18.5959 130.642 19.4693 131.75 19.4693C132.865 19.4693 133.708 18.5836 133.708 17.4987C133.709 16.4151 132.872 15.5403 131.762 15.5403ZM132.245 17.7225L132.861 18.5836H132.342L131.788 17.7935H131.312V18.5836H130.878V16.2991H131.896C132.427 16.2991 132.776 16.5707 132.776 17.0278C132.779 17.4018 132.56 17.6311 132.248 17.7211L132.245 17.7225ZM131.877 16.6921H131.31V17.4141H131.877C132.159 17.4141 132.328 17.2762 132.328 17.0524C132.328 16.8177 132.159 16.6921 131.877 16.6921Z" fill="white"/>
</svg>
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment