big commit
This commit is contained in:
parent
e96f85efdc
commit
dcae12453c
26 changed files with 3183 additions and 8 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -8,3 +8,4 @@ node_modules
|
||||||
!.env.example
|
!.env.example
|
||||||
vite.config.js.timestamp-*
|
vite.config.js.timestamp-*
|
||||||
vite.config.ts.timestamp-*
|
vite.config.ts.timestamp-*
|
||||||
|
db
|
||||||
|
|
2271
package-lock.json
generated
Normal file
2271
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -13,5 +13,11 @@
|
||||||
"svelte": "^3.54.0",
|
"svelte": "^3.54.0",
|
||||||
"vite": "^4.0.0"
|
"vite": "^4.0.0"
|
||||||
},
|
},
|
||||||
"type": "module"
|
"type": "module",
|
||||||
|
"dependencies": {
|
||||||
|
"@sveltejs/adapter-node": "^1.1.4",
|
||||||
|
"bcrypt": "^5.1.0",
|
||||||
|
"sqlite": "^4.1.2",
|
||||||
|
"sqlite3": "^5.1.4"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
11
src/app.html
11
src/app.html
|
@ -2,11 +2,14 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
<link rel="icon" href="%sveltekit.assets%/icon_sanifae_black.svg" />
|
||||||
<meta name="viewport" content="width=device-width" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;700&display=swap" rel="stylesheet">
|
||||||
%sveltekit.head%
|
%sveltekit.head%
|
||||||
</head>
|
</head>
|
||||||
<body data-sveltekit-preload-data="hover">
|
<body data-sveltekit-preload-data="hover" style="margin: 0; padding: 0; overflow: hidden;">
|
||||||
<div style="display: contents">%sveltekit.body%</div>
|
<div>%sveltekit.body%</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
47
src/lib/Area.svelte
Normal file
47
src/lib/Area.svelte
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
<style>
|
||||||
|
#content {
|
||||||
|
background: var(--dark-1);
|
||||||
|
|
||||||
|
width: min(700px, 90vw);
|
||||||
|
padding: 20px;
|
||||||
|
padding-top: 8px;
|
||||||
|
margin: 25px;
|
||||||
|
|
||||||
|
border-radius: 25px;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header {
|
||||||
|
font-weight: bold;
|
||||||
|
|
||||||
|
font-size: 2rem;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#main {
|
||||||
|
min-height: 250px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div id='content'>
|
||||||
|
<div id='header'>
|
||||||
|
<slot name="header">
|
||||||
|
Header
|
||||||
|
</slot>
|
||||||
|
</div>
|
||||||
|
<div id='main'>
|
||||||
|
<slot name="main">
|
||||||
|
<p>Content</p>
|
||||||
|
</slot>
|
||||||
|
</div>
|
||||||
|
<div id='footer'>
|
||||||
|
<slot name="footer">
|
||||||
|
<p>Footer</p>
|
||||||
|
</slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
15
src/lib/Form.svelte
Normal file
15
src/lib/Form.svelte
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<script>
|
||||||
|
import Area from '$lib/Area.svelte';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Area>
|
||||||
|
<p slot="header">
|
||||||
|
Welcome to SvelteKit
|
||||||
|
</p>
|
||||||
|
<p slot="main">
|
||||||
|
Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation
|
||||||
|
</p>
|
||||||
|
<p slot="footer">
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</Area>
|
15
src/lib/Post.svelte
Normal file
15
src/lib/Post.svelte
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<script>
|
||||||
|
import Area from '$lib/Area.svelte';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Area>
|
||||||
|
<p slot="header">
|
||||||
|
Welcome to SvelteKit
|
||||||
|
</p>
|
||||||
|
<p slot="main">
|
||||||
|
Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation
|
||||||
|
</p>
|
||||||
|
<p slot="footer">
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</Area>
|
108
src/lib/db.js
Normal file
108
src/lib/db.js
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
import sqlite3 from 'sqlite3'
|
||||||
|
import { open } from 'sqlite'
|
||||||
|
import { hash, compare } from 'bcrypt'
|
||||||
|
|
||||||
|
const {
|
||||||
|
randomBytes
|
||||||
|
} = await import('node:crypto');
|
||||||
|
|
||||||
|
var db;
|
||||||
|
async function initDb() {
|
||||||
|
db = await open({
|
||||||
|
filename: `${process.cwd()}/db/main.db`,
|
||||||
|
driver: sqlite3.Database
|
||||||
|
});
|
||||||
|
|
||||||
|
await db.run('CREATE TABLE IF NOT EXISTS auth (username CHAR(64), password CHAR(1024))');
|
||||||
|
await db.run('CREATE TABLE IF NOT EXISTS token (username CHAR(64), token CHAR(1024))');
|
||||||
|
await db.run('CREATE TABLE IF NOT EXISTS post (username CHAR(64), id CHAR(64), content CHAR(10240), upvotes INTEGER, downvotes INTEGER)');
|
||||||
|
await db.run('CREATE TABLE IF NOT EXISTS vote (id CHAR(64), username CHAR(64), type INTEGER)');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function registerBackend({user, pass}) {
|
||||||
|
if (!db) await initDb();
|
||||||
|
|
||||||
|
var existingAccounts = await db.all('SELECT username FROM auth WHERE username = ?',[
|
||||||
|
user
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (existingAccounts && existingAccounts.length > 0)
|
||||||
|
return { success: 'Account already exists.' };
|
||||||
|
|
||||||
|
var passHash = await hash(pass,10);
|
||||||
|
|
||||||
|
await db.run('INSERT INTO auth (username, password) VALUES (?, ?)', [
|
||||||
|
user,
|
||||||
|
passHash
|
||||||
|
])
|
||||||
|
|
||||||
|
return { success: 'Successfully created account.' };
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loginBackend({user, pass}) {
|
||||||
|
if (!db) await initDb();
|
||||||
|
|
||||||
|
var existingAccounts = await db.all('SELECT username, password FROM auth WHERE username = ?',[
|
||||||
|
user
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (!existingAccounts || existingAccounts.length < 1)
|
||||||
|
return { success: 'Account does not exist.' };
|
||||||
|
|
||||||
|
var passHash = await compare(pass,existingAccounts[0].password);
|
||||||
|
|
||||||
|
if (!passHash)
|
||||||
|
return { success: 'Incorrect password.' };
|
||||||
|
|
||||||
|
var token = randomBytes(256).toString('hex');
|
||||||
|
|
||||||
|
await db.run('INSERT INTO token (username, token) VALUES (?, ?)', [
|
||||||
|
user,
|
||||||
|
token
|
||||||
|
])
|
||||||
|
|
||||||
|
return { success: 'Successfully logged into account.', token };
|
||||||
|
}
|
||||||
|
|
||||||
|
async function postCreateBackend({user, content}) {
|
||||||
|
var id = randomBytes(10).toString('hex');
|
||||||
|
|
||||||
|
await db.run('INSERT INTO post (username, id, content) VALUES (?, ?, ?)', [
|
||||||
|
user,
|
||||||
|
id,
|
||||||
|
content
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
async function postGetBackend({id}) {
|
||||||
|
var posts = await db.all('SELECT * from post WHERE id = ?', [
|
||||||
|
id
|
||||||
|
])
|
||||||
|
|
||||||
|
if (!posts || posts.length < 1) {
|
||||||
|
return {'success': 'Post does not exist.'}
|
||||||
|
}
|
||||||
|
|
||||||
|
return posts[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
async function tokenBackend({token}) {
|
||||||
|
if (!db) await initDb();
|
||||||
|
|
||||||
|
var existingAccounts = await db.all('SELECT username from token WHERE token = ?',[
|
||||||
|
token
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (!existingAccounts || existingAccounts.length < 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return existingAccounts[0].username;
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
registerBackend,
|
||||||
|
loginBackend,
|
||||||
|
tokenBackend,
|
||||||
|
postCreateBackend,
|
||||||
|
postGetBackend
|
||||||
|
}
|
26
src/lib/util.js
Normal file
26
src/lib/util.js
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
let checkLength = function(string, field, lowerBound, upperBound) {
|
||||||
|
if (string.length < lowerBound) {
|
||||||
|
if (string.length == 0) {
|
||||||
|
return { success: `${field} cannot be blank.` }
|
||||||
|
}
|
||||||
|
return { success: `${field} is too short (minimum length: ${lowerBound} characters).` }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.length > upperBound) {
|
||||||
|
return { success: `${field} is too long (maximum length: ${upperBound} characters).` }
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let checkRegex = function(string, field, regex) {
|
||||||
|
if (string.search(regex) != -1) {
|
||||||
|
return { success: `${field} contains illegal characters.` }
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
checkLength,
|
||||||
|
checkRegex
|
||||||
|
};
|
7
src/routes/+layout.js
Normal file
7
src/routes/+layout.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
/** @type {import('./$types').PageLoad} */
|
||||||
|
export async function load({ fetch, params }) {
|
||||||
|
const res = await fetch(`/api/session`);
|
||||||
|
const username = await res.text();
|
||||||
|
|
||||||
|
return { username };
|
||||||
|
}
|
91
src/routes/+layout.svelte
Normal file
91
src/routes/+layout.svelte
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
<style>
|
||||||
|
:global(:root) {
|
||||||
|
--dark-1: #1a1b1d;
|
||||||
|
--dark-2: #22242b;
|
||||||
|
|
||||||
|
--light-1: #ffffff;
|
||||||
|
|
||||||
|
--hyperlink: #97b9eb;
|
||||||
|
|
||||||
|
color: var(--light-1);
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(a) {
|
||||||
|
color: var(--hyperlink);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(input, textarea) {
|
||||||
|
border: 0;
|
||||||
|
border-radius: 0.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#content {
|
||||||
|
background: var(--dark-2);
|
||||||
|
|
||||||
|
height: 100vh;
|
||||||
|
width: calc(100vw - 50px);
|
||||||
|
padding: 25px;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
#logo {
|
||||||
|
background: var(--dark-1);
|
||||||
|
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
border-radius: 50px;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#logo a {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#logo img {
|
||||||
|
height: auto;
|
||||||
|
width: 125px;
|
||||||
|
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/** @type {import('./$types').PageData} */
|
||||||
|
export let data;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div id='content'>
|
||||||
|
<div id='logo'>
|
||||||
|
<a href='/'>
|
||||||
|
<img src='/logo_sanifae.svg' alt='Sanifae Logo'>
|
||||||
|
</a>
|
||||||
|
{#if data.username}
|
||||||
|
<a href='/users/{data.username}'>
|
||||||
|
{data.username}
|
||||||
|
</a>
|
||||||
|
<a href='/logout'>
|
||||||
|
Log out
|
||||||
|
</a>
|
||||||
|
<a href='/new_post'>
|
||||||
|
Create
|
||||||
|
</a>
|
||||||
|
{:else}
|
||||||
|
<a href='/account'>
|
||||||
|
Log in / Register
|
||||||
|
</a>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
|
|
@ -1,2 +1,15 @@
|
||||||
<h1>Welcome to SvelteKit</h1>
|
<script>
|
||||||
<p>Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation</p>
|
import Area from '$lib/Area.svelte';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Area>
|
||||||
|
<p slot="header">
|
||||||
|
Welcome to SvelteKit
|
||||||
|
</p>
|
||||||
|
<p slot="main">
|
||||||
|
Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation
|
||||||
|
</p>
|
||||||
|
<p slot="footer">
|
||||||
|
|
||||||
|
</p>
|
||||||
|
</Area>
|
59
src/routes/account/+page.server.js
Normal file
59
src/routes/account/+page.server.js
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
import { checkLength, checkRegex } from '../../lib/util.js';
|
||||||
|
import { registerBackend, loginBackend } from '../../lib/db.js';
|
||||||
|
|
||||||
|
async function basicChecks(data) {
|
||||||
|
const pass = data.get('pass') + '';
|
||||||
|
const user = data.get('user') + '';
|
||||||
|
|
||||||
|
var lengthCheck = false;
|
||||||
|
|
||||||
|
lengthCheck =
|
||||||
|
checkLength(pass,'Password',4,1024) ||
|
||||||
|
checkLength(user,'Username',1,64) ||
|
||||||
|
checkRegex(user,'Username',/[^A-Za-z0-9\-\_]/g);
|
||||||
|
|
||||||
|
return {
|
||||||
|
user,
|
||||||
|
pass,
|
||||||
|
lengthCheck
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @type {import('./$types').Actions} */
|
||||||
|
export const actions = {
|
||||||
|
register: async ({ request }) => {
|
||||||
|
const data = await request.formData();
|
||||||
|
|
||||||
|
const pass2 = data.get('pass2') + '';
|
||||||
|
|
||||||
|
var {lengthCheck, user, pass} = await basicChecks(data);
|
||||||
|
|
||||||
|
if (lengthCheck)
|
||||||
|
return lengthCheck;
|
||||||
|
|
||||||
|
if (pass != pass2)
|
||||||
|
return { success: 'Failed to confirm password.' };
|
||||||
|
|
||||||
|
return await registerBackend({ user, pass });
|
||||||
|
},
|
||||||
|
|
||||||
|
login: async ({ request, cookies }) => {
|
||||||
|
const data = await request.formData();
|
||||||
|
|
||||||
|
var {lengthCheck, user, pass} = await basicChecks(data);
|
||||||
|
|
||||||
|
if (lengthCheck)
|
||||||
|
return lengthCheck;
|
||||||
|
|
||||||
|
var result = await loginBackend({ user, pass });
|
||||||
|
|
||||||
|
if (result.token) {
|
||||||
|
cookies.set('token',result.token, {
|
||||||
|
maxAge: 60 * 60 * 24 * 7,
|
||||||
|
path: '/'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
37
src/routes/account/+page.svelte
Normal file
37
src/routes/account/+page.svelte
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<script>
|
||||||
|
import Area from '$lib/Area.svelte';
|
||||||
|
|
||||||
|
/** @type {import('./$types').PageData} */
|
||||||
|
export let data;
|
||||||
|
/** @type {import('./$types').ActionData} */
|
||||||
|
export let form;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Area>
|
||||||
|
<p slot="header">
|
||||||
|
Log in / Register
|
||||||
|
</p>
|
||||||
|
<form slot="main" method='POST'>
|
||||||
|
<p>
|
||||||
|
Username: <input name='user'>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Password: <input type='password' name='pass'>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Confirm Password: <input type='password' name='pass2'>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<input formaction="?/login" type='submit' value='Log in'>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<input formaction="?/register" type='submit' value='Register'>
|
||||||
|
</p>
|
||||||
|
</form>
|
||||||
|
<p slot="footer">
|
||||||
|
{#if form?.success}
|
||||||
|
<p>{form?.success}</p>
|
||||||
|
{/if}
|
||||||
|
By using the Sanifae service, you agree to the <a href='https://insfa.net/rules'>Terms of Service</a>.
|
||||||
|
</p>
|
||||||
|
</Area>
|
10
src/routes/api/post/+server.js
Normal file
10
src/routes/api/post/+server.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import { postGetBackend } from '../../../lib/db.js';
|
||||||
|
|
||||||
|
/** @type {import('./$types').RequestHandler} */
|
||||||
|
export async function GET({ url, cookies }) {
|
||||||
|
var id = url.searchParams.get('post');
|
||||||
|
|
||||||
|
var postData = await postGetBackend({ id });
|
||||||
|
|
||||||
|
return new Response(JSON.stringify(postData));
|
||||||
|
};
|
11
src/routes/api/session/+server.js
Normal file
11
src/routes/api/session/+server.js
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import { tokenBackend } from '../../../lib/db.js';
|
||||||
|
|
||||||
|
|
||||||
|
/** @type {import('./$types').RequestHandler} */
|
||||||
|
export async function GET({ url, cookies }) {
|
||||||
|
var token = cookies.get('token') || '';
|
||||||
|
|
||||||
|
var username = await tokenBackend({token});
|
||||||
|
|
||||||
|
return new Response(username + '');
|
||||||
|
};
|
27
src/routes/new_post/+page.server.js
Normal file
27
src/routes/new_post/+page.server.js
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
import { tokenBackend, postCreateBackend } from '../../lib/db.js';
|
||||||
|
import { checkLength, checkRegex } from '../../lib/util.js';
|
||||||
|
|
||||||
|
/** @type {import('./$types').Actions} */
|
||||||
|
export const actions = {
|
||||||
|
create: async ({ request, cookies }) => {
|
||||||
|
|
||||||
|
var user = await tokenBackend({
|
||||||
|
token: cookies.get('token')
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!user)
|
||||||
|
return {'success': 'Not logged in.'}
|
||||||
|
|
||||||
|
const data = await request.formData();
|
||||||
|
const content = data.get('content') + '';
|
||||||
|
|
||||||
|
var lengthCheck = checkLength(content,'Post content',1,10240);
|
||||||
|
|
||||||
|
if (lengthCheck)
|
||||||
|
return lengthCheck;
|
||||||
|
|
||||||
|
await postCreateBackend({user, content});
|
||||||
|
|
||||||
|
return {'success': 'Successfully posted.'};
|
||||||
|
}
|
||||||
|
};
|
35
src/routes/new_post/+page.svelte
Normal file
35
src/routes/new_post/+page.svelte
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<script>
|
||||||
|
import Area from '$lib/Area.svelte';
|
||||||
|
|
||||||
|
/** @type {import('./$types').PageData} */
|
||||||
|
export let data;
|
||||||
|
/** @type {import('./$types').ActionData} */
|
||||||
|
export let form;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
textarea {
|
||||||
|
width: 10rem;
|
||||||
|
height: 10rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<Area>
|
||||||
|
<p slot="header">
|
||||||
|
Create Post
|
||||||
|
</p>
|
||||||
|
<form slot="main" method='POST'>
|
||||||
|
<p>
|
||||||
|
<textarea name='content'></textarea>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<input formaction="?/create" type='submit' value='Post'>
|
||||||
|
</p>
|
||||||
|
</form>
|
||||||
|
<p slot="footer">
|
||||||
|
{#if form?.success}
|
||||||
|
<p>{form?.success}</p>
|
||||||
|
{/if}
|
||||||
|
Create a post for the world to see.
|
||||||
|
</p>
|
||||||
|
</Area>
|
12
src/routes/post/[post]/+page.js
Normal file
12
src/routes/post/[post]/+page.js
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/** @type {import('./$types').PageLoad} */
|
||||||
|
export async function load({ fetch, params, url }) {
|
||||||
|
var id = params.post;
|
||||||
|
const res = await fetch(`/api/post?post=${id}`);
|
||||||
|
const postJson = await res.json();
|
||||||
|
|
||||||
|
var search = url.searchParams;
|
||||||
|
|
||||||
|
var voteType = (search.get('upvote')) ? 1 : ((search.get('downvote')) ? 2 : 0);
|
||||||
|
|
||||||
|
return { postJson };
|
||||||
|
}
|
65
src/routes/post/[post]/+page.svelte
Normal file
65
src/routes/post/[post]/+page.svelte
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
<script>
|
||||||
|
import Area from '$lib/Area.svelte';
|
||||||
|
|
||||||
|
/** @type {import('./$types').PageData} */
|
||||||
|
export let data;
|
||||||
|
/** @type {import('./$types').ActionData} */
|
||||||
|
export let form;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.button {
|
||||||
|
width: auto;
|
||||||
|
height: 75px;
|
||||||
|
}
|
||||||
|
.votes {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
.vote-area {
|
||||||
|
margin-right: 30px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
{#if data.postJson.success}
|
||||||
|
<Area>
|
||||||
|
<p slot="header">
|
||||||
|
Error
|
||||||
|
</p>
|
||||||
|
<p slot="main">
|
||||||
|
{data.postJson.success}
|
||||||
|
</p>
|
||||||
|
<p slot="footer">
|
||||||
|
Failed to get post.
|
||||||
|
</p>
|
||||||
|
</Area>
|
||||||
|
{:else}
|
||||||
|
<Area>
|
||||||
|
<p slot="header">
|
||||||
|
<a href='/users/{data.postJson.username}'>
|
||||||
|
{data.postJson.username}
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
<p slot="main">
|
||||||
|
{data.postJson.content}
|
||||||
|
</p>
|
||||||
|
<p slot="footer">
|
||||||
|
<span class='vote-area'>
|
||||||
|
<a href='?upvote'>
|
||||||
|
<img src='/upvote.svg' class='button' alt='Upvote'>
|
||||||
|
</a>
|
||||||
|
<span class='votes'>
|
||||||
|
{data.postJson.upvotes + 0}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<span class='vote-area'>
|
||||||
|
<a href='?downvote'>
|
||||||
|
<img src='/downvote.svg' class='button' alt='Downvote'>
|
||||||
|
</a>
|
||||||
|
<span class='votes'>
|
||||||
|
{data.postJson.downvotes + 0}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</Area>
|
||||||
|
{/if}
|
53
static/downvote.svg
Normal file
53
static/downvote.svg
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="47.87009mm"
|
||||||
|
height="89.159485mm"
|
||||||
|
viewBox="0 0 47.87009 89.159485"
|
||||||
|
version="1.1"
|
||||||
|
id="svg14062"
|
||||||
|
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
|
||||||
|
sodipodi:docname="downvote.svg"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview14064"
|
||||||
|
pagecolor="#000000"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="1.0280428"
|
||||||
|
inkscape:cx="129.37205"
|
||||||
|
inkscape:cy="99.704021"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="996"
|
||||||
|
inkscape:window-x="-8"
|
||||||
|
inkscape:window-y="-8"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="layer1" />
|
||||||
|
<defs
|
||||||
|
id="defs14059" />
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-45.765321,-111.54473)">
|
||||||
|
<path
|
||||||
|
id="rect15084"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#e5a8ff;stroke-width:0;stroke-miterlimit:3.96999"
|
||||||
|
d="m 45.765322,189.40887 11.967521,11.29534 H 81.667887 L 93.635409,189.40886 69.700367,140.35985 Z"
|
||||||
|
sodipodi:nodetypes="cccccc" />
|
||||||
|
<path
|
||||||
|
id="rect15091"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#e5a8ff;stroke-width:0;stroke-miterlimit:3.96999"
|
||||||
|
d="m 58.540445,153.71391 v -42.16918 h 22.31984 v 42.16886 L 69.700364,130.84435 Z" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
61
static/icon_sanifae.svg
Normal file
61
static/icon_sanifae.svg
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="69.642113mm"
|
||||||
|
height="77.026108mm"
|
||||||
|
viewBox="0 0 69.642113 77.026108"
|
||||||
|
version="1.1"
|
||||||
|
id="svg5"
|
||||||
|
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
|
||||||
|
sodipodi:docname="template.svg"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview7"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="0.18173401"
|
||||||
|
inkscape:cx="2517.4155"
|
||||||
|
inkscape:cy="1532.4595"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="996"
|
||||||
|
inkscape:window-x="-8"
|
||||||
|
inkscape:window-y="-8"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showguides="true" />
|
||||||
|
<defs
|
||||||
|
id="defs2" />
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-41.180676,-30.027448)">
|
||||||
|
<g
|
||||||
|
id="g20517"
|
||||||
|
transform="matrix(0.68756186,0,0,0.68756186,-44.467038,-7.6059692)"
|
||||||
|
inkscape:export-filename="icon_sanifae.svg"
|
||||||
|
inkscape:export-xdpi="1031.03"
|
||||||
|
inkscape:export-ydpi="1031.03">
|
||||||
|
<path
|
||||||
|
id="path20351"
|
||||||
|
style="opacity:1;fill:#ffffff;stroke:#e5a8ff;stroke-width:0;stroke-miterlimit:3.96999"
|
||||||
|
d="m -179.12012,71.140402 a 38.853859,39.608299 0 0 1 38.85342,39.608018 38.853859,39.608299 0 0 1 -38.85342,39.60877 38.853859,39.608299 0 0 1 -38.85418,-39.60877 38.853859,39.608299 0 0 1 38.85418,-39.608018 z m -2.6689,2.086413 c -1.81603,0 -3.30098,1.484955 -3.30098,3.300981 0,1.816023 1.48495,3.301733 3.30098,3.301733 1.81603,0 3.30173,-1.48571 3.30173,-3.301733 0,-1.816026 -1.4857,-3.300981 -3.30173,-3.300981 z m 0,1.220581 c 1.15641,0 2.08115,0.923986 2.08115,2.0804 0,1.15641 -0.92474,2.081152 -2.08115,2.081152 -1.15641,0 -2.0804,-0.924742 -2.0804,-2.081152 0,-1.156414 0.92399,-2.0804 2.0804,-2.0804 z m 10.24266,4.441143 c -9.52749,0 -17.31963,7.79214 -17.31963,17.31963 0,9.527481 7.79214,17.319631 17.31963,17.319631 9.5275,0 17.32039,-7.79215 17.32039,-17.319631 0,-9.52749 -7.79289,-17.31963 -17.32039,-17.31963 z m 0,6.403543 c 6.06693,0 10.91684,4.849162 10.91684,10.916087 0,6.066921 -4.84991,10.916841 -10.91684,10.916841 -6.06692,0 -10.91608,-4.84992 -10.91608,-10.916841 0,-6.066925 4.84916,-10.916087 10.91608,-10.916087 z m -34.39424,8.417803 c -2.94896,0 -5.36109,2.411367 -5.36109,5.360337 0,2.948968 2.41213,5.361088 5.36109,5.361088 2.94898,0 5.36109,-2.41212 5.36109,-5.361088 0,-2.94897 -2.41211,-5.360337 -5.36109,-5.360337 z m 0,1.981942 c 1.87785,0 3.37915,1.500546 3.37915,3.378395 0,1.877858 -1.5013,3.379148 -3.37915,3.379148 -1.87785,0 -3.37914,-1.50129 -3.37914,-3.379148 0,-1.877849 1.50129,-3.378395 3.37914,-3.378395 z m 4.52081,14.621423 c -6.05882,0 -11.01454,4.95497 -11.01454,11.01379 0,6.05882 4.95572,11.01455 11.01454,11.01455 6.05883,0 11.0138,-4.95573 11.0138,-11.01455 0,-6.05882 -4.95497,-11.01379 -11.0138,-11.01379 z m 48.6271,3.30775 c -4.10155,0 -7.45577,3.35422 -7.45577,7.45576 0,4.10155 3.35422,7.45577 7.45577,7.45577 4.10153,0 7.45652,-3.35422 7.45652,-7.45577 0,-4.10154 -3.35499,-7.45576 -7.45652,-7.45576 z m -48.6271,0.76436 c 3.85814,0 6.94169,3.08354 6.94169,6.94168 0,3.85814 -3.08355,6.94244 -6.94169,6.94244 -3.85814,0 -6.94243,-3.0843 -6.94243,-6.94244 0,-3.85814 3.08429,-6.94168 6.94243,-6.94168 z m 25.33008,0.68245 c -5.772,0 -10.49295,4.72093 -10.49295,10.49294 0,5.77199 4.72095,10.49294 10.49295,10.49294 5.772,0 10.49294,-4.72095 10.49294,-10.49294 0,-5.77201 -4.72094,-10.49294 -10.49294,-10.49294 z m 23.29702,1.30927 c 2.61177,0 4.69969,2.0879 4.69969,4.69968 0,2.61179 -2.08792,4.69969 -4.69969,4.69969 -2.61179,0 -4.69969,-2.0879 -4.69969,-4.69969 0,-2.61178 2.0879,-4.69968 4.69969,-4.69968 z m -23.29702,2.57043 c 3.67549,0 6.61323,2.93773 6.61323,6.61324 0,3.67549 -2.93774,6.61323 -6.61323,6.61323 -3.6755,0 -6.61324,-2.93774 -6.61324,-6.61323 0,-3.67551 2.93774,-6.61324 6.61324,-6.61324 z m -14.74093,15.1776 c -2.09552,0 -3.80981,1.71429 -3.80981,3.80981 0,2.09552 1.71429,3.80905 3.80981,3.80905 2.09552,0 3.80906,-1.71353 3.80906,-3.80905 0,-2.09552 -1.71354,-3.80981 -3.80906,-3.80981 z m 0,1.40848 c 1.33439,0 2.40058,1.06694 2.40058,2.40133 0,1.33439 -1.06619,2.40058 -2.40058,2.40058 -1.33439,0 -2.40133,-1.06619 -2.40133,-2.40058 0,-1.33439 1.06694,-2.40133 2.40133,-2.40133 z m 20.57101,5.23708 c -1.99632,0 -3.62943,1.63235 -3.62943,3.62867 0,1.99632 1.63311,3.62943 3.62943,3.62943 1.99631,0 3.62867,-1.63311 3.62867,-3.62943 0,-1.99632 -1.63236,-3.62867 -3.62867,-3.62867 z m 0,1.34158 c 1.27121,0 2.28708,1.01587 2.28708,2.28709 0,1.27122 -1.01587,2.28784 -2.28708,2.28784 -1.27122,0 -2.28709,-1.01662 -2.28709,-2.28784 0,-1.27122 1.01587,-2.28709 2.28709,-2.28709 z"
|
||||||
|
transform="scale(-1,1)" />
|
||||||
|
<path
|
||||||
|
id="ellipse20462"
|
||||||
|
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#e5a8ff;stroke-width:0;stroke-miterlimit:3.96999;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 179.51388,54.73459 a 54.946752,56.013673 0 0 0 -54.9466,56.01424 54.946752,56.013673 0 0 0 54.9466,56.01365 54.946752,56.013673 0 0 0 46.32654,-25.93699 l -8.72245,-5.66291 a 44.605491,45.471613 0 0 1 -37.60409,21.05732 44.605491,45.471613 0 0 1 -44.60536,-45.47107 44.605491,45.471613 0 0 1 44.60536,-45.471649 44.605491,45.471613 0 0 1 37.61888,21.048209 l 8.72302,-5.662909 A 54.946752,56.013673 0 0 0 179.51388,54.73459 Z" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 5.7 KiB |
61
static/icon_sanifae_black.svg
Normal file
61
static/icon_sanifae_black.svg
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="69.642113mm"
|
||||||
|
height="77.026108mm"
|
||||||
|
viewBox="0 0 69.642113 77.026108"
|
||||||
|
version="1.1"
|
||||||
|
id="svg5"
|
||||||
|
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
|
||||||
|
sodipodi:docname="template.svg"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview7"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="0.18173401"
|
||||||
|
inkscape:cx="2517.4155"
|
||||||
|
inkscape:cy="1532.4595"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="996"
|
||||||
|
inkscape:window-x="-8"
|
||||||
|
inkscape:window-y="-8"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showguides="true" />
|
||||||
|
<defs
|
||||||
|
id="defs2" />
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-41.180676,-30.027448)">
|
||||||
|
<g
|
||||||
|
id="g20517"
|
||||||
|
transform="matrix(0.68756186,0,0,0.68756186,-44.467038,-7.6059692)"
|
||||||
|
inkscape:export-filename="icon_sanifae.svg"
|
||||||
|
inkscape:export-xdpi="1031.03"
|
||||||
|
inkscape:export-ydpi="1031.03">
|
||||||
|
<path
|
||||||
|
id="path20351"
|
||||||
|
style="opacity:1;fill:#000000;stroke:#e5a8ff;stroke-width:0;stroke-miterlimit:3.96999"
|
||||||
|
d="m -179.12012,71.140402 a 38.853859,39.608299 0 0 1 38.85342,39.608018 38.853859,39.608299 0 0 1 -38.85342,39.60877 38.853859,39.608299 0 0 1 -38.85418,-39.60877 38.853859,39.608299 0 0 1 38.85418,-39.608018 z m -2.6689,2.086413 c -1.81603,0 -3.30098,1.484955 -3.30098,3.300981 0,1.816023 1.48495,3.301733 3.30098,3.301733 1.81603,0 3.30173,-1.48571 3.30173,-3.301733 0,-1.816026 -1.4857,-3.300981 -3.30173,-3.300981 z m 0,1.220581 c 1.15641,0 2.08115,0.923986 2.08115,2.0804 0,1.15641 -0.92474,2.081152 -2.08115,2.081152 -1.15641,0 -2.0804,-0.924742 -2.0804,-2.081152 0,-1.156414 0.92399,-2.0804 2.0804,-2.0804 z m 10.24266,4.441143 c -9.52749,0 -17.31963,7.79214 -17.31963,17.31963 0,9.527481 7.79214,17.319631 17.31963,17.319631 9.5275,0 17.32039,-7.79215 17.32039,-17.319631 0,-9.52749 -7.79289,-17.31963 -17.32039,-17.31963 z m 0,6.403543 c 6.06693,0 10.91684,4.849162 10.91684,10.916087 0,6.066921 -4.84991,10.916841 -10.91684,10.916841 -6.06692,0 -10.91608,-4.84992 -10.91608,-10.916841 0,-6.066925 4.84916,-10.916087 10.91608,-10.916087 z m -34.39424,8.417803 c -2.94896,0 -5.36109,2.411367 -5.36109,5.360337 0,2.948968 2.41213,5.361088 5.36109,5.361088 2.94898,0 5.36109,-2.41212 5.36109,-5.361088 0,-2.94897 -2.41211,-5.360337 -5.36109,-5.360337 z m 0,1.981942 c 1.87785,0 3.37915,1.500546 3.37915,3.378395 0,1.877858 -1.5013,3.379148 -3.37915,3.379148 -1.87785,0 -3.37914,-1.50129 -3.37914,-3.379148 0,-1.877849 1.50129,-3.378395 3.37914,-3.378395 z m 4.52081,14.621423 c -6.05882,0 -11.01454,4.95497 -11.01454,11.01379 0,6.05882 4.95572,11.01455 11.01454,11.01455 6.05883,0 11.0138,-4.95573 11.0138,-11.01455 0,-6.05882 -4.95497,-11.01379 -11.0138,-11.01379 z m 48.6271,3.30775 c -4.10155,0 -7.45577,3.35422 -7.45577,7.45576 0,4.10155 3.35422,7.45577 7.45577,7.45577 4.10153,0 7.45652,-3.35422 7.45652,-7.45577 0,-4.10154 -3.35499,-7.45576 -7.45652,-7.45576 z m -48.6271,0.76436 c 3.85814,0 6.94169,3.08354 6.94169,6.94168 0,3.85814 -3.08355,6.94244 -6.94169,6.94244 -3.85814,0 -6.94243,-3.0843 -6.94243,-6.94244 0,-3.85814 3.08429,-6.94168 6.94243,-6.94168 z m 25.33008,0.68245 c -5.772,0 -10.49295,4.72093 -10.49295,10.49294 0,5.77199 4.72095,10.49294 10.49295,10.49294 5.772,0 10.49294,-4.72095 10.49294,-10.49294 0,-5.77201 -4.72094,-10.49294 -10.49294,-10.49294 z m 23.29702,1.30927 c 2.61177,0 4.69969,2.0879 4.69969,4.69968 0,2.61179 -2.08792,4.69969 -4.69969,4.69969 -2.61179,0 -4.69969,-2.0879 -4.69969,-4.69969 0,-2.61178 2.0879,-4.69968 4.69969,-4.69968 z m -23.29702,2.57043 c 3.67549,0 6.61323,2.93773 6.61323,6.61324 0,3.67549 -2.93774,6.61323 -6.61323,6.61323 -3.6755,0 -6.61324,-2.93774 -6.61324,-6.61323 0,-3.67551 2.93774,-6.61324 6.61324,-6.61324 z m -14.74093,15.1776 c -2.09552,0 -3.80981,1.71429 -3.80981,3.80981 0,2.09552 1.71429,3.80905 3.80981,3.80905 2.09552,0 3.80906,-1.71353 3.80906,-3.80905 0,-2.09552 -1.71354,-3.80981 -3.80906,-3.80981 z m 0,1.40848 c 1.33439,0 2.40058,1.06694 2.40058,2.40133 0,1.33439 -1.06619,2.40058 -2.40058,2.40058 -1.33439,0 -2.40133,-1.06619 -2.40133,-2.40058 0,-1.33439 1.06694,-2.40133 2.40133,-2.40133 z m 20.57101,5.23708 c -1.99632,0 -3.62943,1.63235 -3.62943,3.62867 0,1.99632 1.63311,3.62943 3.62943,3.62943 1.99631,0 3.62867,-1.63311 3.62867,-3.62943 0,-1.99632 -1.63236,-3.62867 -3.62867,-3.62867 z m 0,1.34158 c 1.27121,0 2.28708,1.01587 2.28708,2.28709 0,1.27122 -1.01587,2.28784 -2.28708,2.28784 -1.27122,0 -2.28709,-1.01662 -2.28709,-2.28784 0,-1.27122 1.01587,-2.28709 2.28709,-2.28709 z"
|
||||||
|
transform="scale(-1,1)" />
|
||||||
|
<path
|
||||||
|
id="ellipse20462"
|
||||||
|
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#e5a8ff;stroke-width:0;stroke-miterlimit:3.96999;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 179.51388,54.73459 a 54.946752,56.013673 0 0 0 -54.9466,56.01424 54.946752,56.013673 0 0 0 54.9466,56.01365 54.946752,56.013673 0 0 0 46.32654,-25.93699 l -8.72245,-5.66291 a 44.605491,45.471613 0 0 1 -37.60409,21.05732 44.605491,45.471613 0 0 1 -44.60536,-45.47107 44.605491,45.471613 0 0 1 44.60536,-45.471649 44.605491,45.471613 0 0 1 37.61888,21.048209 l 8.72302,-5.662909 A 54.946752,56.013673 0 0 0 179.51388,54.73459 Z" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 5.7 KiB |
87
static/logo_sanifae.svg
Normal file
87
static/logo_sanifae.svg
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="202.2982mm"
|
||||||
|
height="77.026108mm"
|
||||||
|
viewBox="0 0 202.2982 77.026108"
|
||||||
|
version="1.1"
|
||||||
|
id="svg5"
|
||||||
|
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
|
||||||
|
sodipodi:docname="template.svg"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview7"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="0.18173401"
|
||||||
|
inkscape:cx="2517.4155"
|
||||||
|
inkscape:cy="1532.4595"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="996"
|
||||||
|
inkscape:window-x="-8"
|
||||||
|
inkscape:window-y="-8"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showguides="true" />
|
||||||
|
<defs
|
||||||
|
id="defs2" />
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-41.180676,-30.027448)">
|
||||||
|
<g
|
||||||
|
id="g20517"
|
||||||
|
transform="matrix(0.68756186,0,0,0.68756186,-44.467038,-7.6059692)"
|
||||||
|
inkscape:export-filename="logo_sanifae.svg"
|
||||||
|
inkscape:export-xdpi="1031.03"
|
||||||
|
inkscape:export-ydpi="1031.03">
|
||||||
|
<path
|
||||||
|
id="path20351"
|
||||||
|
style="opacity:1;fill:#ffffff;stroke:#e5a8ff;stroke-width:0;stroke-miterlimit:3.96999"
|
||||||
|
d="m -179.12012,71.140402 a 38.853859,39.608299 0 0 1 38.85342,39.608018 38.853859,39.608299 0 0 1 -38.85342,39.60877 38.853859,39.608299 0 0 1 -38.85418,-39.60877 38.853859,39.608299 0 0 1 38.85418,-39.608018 z m -2.6689,2.086413 c -1.81603,0 -3.30098,1.484955 -3.30098,3.300981 0,1.816023 1.48495,3.301733 3.30098,3.301733 1.81603,0 3.30173,-1.48571 3.30173,-3.301733 0,-1.816026 -1.4857,-3.300981 -3.30173,-3.300981 z m 0,1.220581 c 1.15641,0 2.08115,0.923986 2.08115,2.0804 0,1.15641 -0.92474,2.081152 -2.08115,2.081152 -1.15641,0 -2.0804,-0.924742 -2.0804,-2.081152 0,-1.156414 0.92399,-2.0804 2.0804,-2.0804 z m 10.24266,4.441143 c -9.52749,0 -17.31963,7.79214 -17.31963,17.31963 0,9.527481 7.79214,17.319631 17.31963,17.319631 9.5275,0 17.32039,-7.79215 17.32039,-17.319631 0,-9.52749 -7.79289,-17.31963 -17.32039,-17.31963 z m 0,6.403543 c 6.06693,0 10.91684,4.849162 10.91684,10.916087 0,6.066921 -4.84991,10.916841 -10.91684,10.916841 -6.06692,0 -10.91608,-4.84992 -10.91608,-10.916841 0,-6.066925 4.84916,-10.916087 10.91608,-10.916087 z m -34.39424,8.417803 c -2.94896,0 -5.36109,2.411367 -5.36109,5.360337 0,2.948968 2.41213,5.361088 5.36109,5.361088 2.94898,0 5.36109,-2.41212 5.36109,-5.361088 0,-2.94897 -2.41211,-5.360337 -5.36109,-5.360337 z m 0,1.981942 c 1.87785,0 3.37915,1.500546 3.37915,3.378395 0,1.877858 -1.5013,3.379148 -3.37915,3.379148 -1.87785,0 -3.37914,-1.50129 -3.37914,-3.379148 0,-1.877849 1.50129,-3.378395 3.37914,-3.378395 z m 4.52081,14.621423 c -6.05882,0 -11.01454,4.95497 -11.01454,11.01379 0,6.05882 4.95572,11.01455 11.01454,11.01455 6.05883,0 11.0138,-4.95573 11.0138,-11.01455 0,-6.05882 -4.95497,-11.01379 -11.0138,-11.01379 z m 48.6271,3.30775 c -4.10155,0 -7.45577,3.35422 -7.45577,7.45576 0,4.10155 3.35422,7.45577 7.45577,7.45577 4.10153,0 7.45652,-3.35422 7.45652,-7.45577 0,-4.10154 -3.35499,-7.45576 -7.45652,-7.45576 z m -48.6271,0.76436 c 3.85814,0 6.94169,3.08354 6.94169,6.94168 0,3.85814 -3.08355,6.94244 -6.94169,6.94244 -3.85814,0 -6.94243,-3.0843 -6.94243,-6.94244 0,-3.85814 3.08429,-6.94168 6.94243,-6.94168 z m 25.33008,0.68245 c -5.772,0 -10.49295,4.72093 -10.49295,10.49294 0,5.77199 4.72095,10.49294 10.49295,10.49294 5.772,0 10.49294,-4.72095 10.49294,-10.49294 0,-5.77201 -4.72094,-10.49294 -10.49294,-10.49294 z m 23.29702,1.30927 c 2.61177,0 4.69969,2.0879 4.69969,4.69968 0,2.61179 -2.08792,4.69969 -4.69969,4.69969 -2.61179,0 -4.69969,-2.0879 -4.69969,-4.69969 0,-2.61178 2.0879,-4.69968 4.69969,-4.69968 z m -23.29702,2.57043 c 3.67549,0 6.61323,2.93773 6.61323,6.61324 0,3.67549 -2.93774,6.61323 -6.61323,6.61323 -3.6755,0 -6.61324,-2.93774 -6.61324,-6.61323 0,-3.67551 2.93774,-6.61324 6.61324,-6.61324 z m -14.74093,15.1776 c -2.09552,0 -3.80981,1.71429 -3.80981,3.80981 0,2.09552 1.71429,3.80905 3.80981,3.80905 2.09552,0 3.80906,-1.71353 3.80906,-3.80905 0,-2.09552 -1.71354,-3.80981 -3.80906,-3.80981 z m 0,1.40848 c 1.33439,0 2.40058,1.06694 2.40058,2.40133 0,1.33439 -1.06619,2.40058 -2.40058,2.40058 -1.33439,0 -2.40133,-1.06619 -2.40133,-2.40058 0,-1.33439 1.06694,-2.40133 2.40133,-2.40133 z m 20.57101,5.23708 c -1.99632,0 -3.62943,1.63235 -3.62943,3.62867 0,1.99632 1.63311,3.62943 3.62943,3.62943 1.99631,0 3.62867,-1.63311 3.62867,-3.62943 0,-1.99632 -1.63236,-3.62867 -3.62867,-3.62867 z m 0,1.34158 c 1.27121,0 2.28708,1.01587 2.28708,2.28709 0,1.27122 -1.01587,2.28784 -2.28708,2.28784 -1.27122,0 -2.28709,-1.01662 -2.28709,-2.28784 0,-1.27122 1.01587,-2.28709 2.28709,-2.28709 z"
|
||||||
|
transform="scale(-1,1)" />
|
||||||
|
<path
|
||||||
|
id="ellipse20462"
|
||||||
|
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#e5a8ff;stroke-width:0;stroke-miterlimit:3.96999;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 179.51388,54.73459 a 54.946752,56.013673 0 0 0 -54.9466,56.01424 54.946752,56.013673 0 0 0 54.9466,56.01365 54.946752,56.013673 0 0 0 46.32654,-25.93699 l -8.72245,-5.66291 a 44.605491,45.471613 0 0 1 -37.60409,21.05732 44.605491,45.471613 0 0 1 -44.60536,-45.47107 44.605491,45.471613 0 0 1 44.60536,-45.471649 44.605491,45.471613 0 0 1 37.61888,21.048209 l 8.72302,-5.662909 A 54.946752,56.013673 0 0 0 179.51388,54.73459 Z" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
aria-label="Sanifae"
|
||||||
|
id="text360"
|
||||||
|
style="font-weight:600;font-stretch:condensed;font-size:44.9535px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans Semi-Bold Condensed';fill:#ffffff;stroke-width:1.12384">
|
||||||
|
<path
|
||||||
|
d="m 140.84093,76.431687 q 0,2.809594 -1.0975,4.960689 -1.0975,2.151095 -3.09494,3.358342 -1.99745,1.207248 -4.71924,1.207248 -1.29505,0 -2.5023,-0.15365 -1.20724,-0.15365 -2.32669,-0.504849 -1.11945,-0.351199 -2.195,-0.899948 V 79.43883 q 1.6243,0.987748 3.4242,1.514547 1.82184,0.504849 3.38029,0.504849 1.38285,0 2.32669,-0.592649 0.94385,-0.614598 1.42675,-1.646246 0.4829,-1.031648 0.4829,-2.304745 0,-1.338947 -0.41705,-2.282795 -0.3951,-0.965798 -1.42675,-1.799896 -1.00969,-0.856048 -2.83154,-1.865746 -1.4048,-0.812148 -2.54619,-1.646246 -1.1414,-0.856048 -1.95355,-1.887696 -0.7902,-1.053597 -1.2292,-2.436444 -0.41705,-1.404797 -0.41705,-3.314443 -0.0439,-2.612044 1.0097,-4.587539 1.07555,-1.975496 3.02909,-3.051043 1.95355,-1.097498 4.58754,-1.075548 1.8877,0 3.6437,0.482899 1.77794,0.482899 3.24859,1.295047 l -1.4048,4.32414 q -1.4487,-0.834098 -2.80959,-1.229197 -1.33895,-0.417049 -2.52425,-0.417049 -1.27309,0 -2.15109,0.526799 -0.878,0.504849 -1.33895,1.426747 -0.46095,0.899947 -0.46095,2.085245 0,1.404797 0.41705,2.348645 0.439,0.943847 1.47065,1.755996 1.0536,0.812148 2.87544,1.821845 2.04135,1.141398 3.40224,2.436445 1.3609,1.273097 2.04135,2.875444 0.68045,1.602346 0.68045,3.731491 z"
|
||||||
|
id="path5030" />
|
||||||
|
<path
|
||||||
|
d="m 152.6061,60.715522 q 3.46809,0 5.11434,2.173046 1.64625,2.173045 1.64625,6.365485 v 16.264914 h -3.4242 l -0.72434,-3.358343 h -0.10975 q -0.6585,1.229197 -1.47065,2.085246 -0.81215,0.856048 -1.86575,1.273097 -1.03164,0.438999 -2.41449,0.438999 -1.95355,0 -3.18274,-1.031648 -1.2292,-1.053598 -1.7999,-2.743744 -0.5707,-1.690146 -0.5707,-3.599792 0,-3.709541 2.08525,-5.685037 2.10719,-1.975495 5.97038,-2.151095 l 2.8974,-0.15365 v -1.316997 q 0,-2.458394 -0.7024,-3.621742 -0.7024,-1.163347 -2.30475,-1.163347 -1.03164,0 -2.21694,0.395099 -1.16335,0.373149 -2.56815,1.185297 l -1.33894,-3.446142 q 1.51454,-0.943848 3.27054,-1.426747 1.77795,-0.482899 3.70954,-0.482899 z m 2.17305,13.082171 -1.9316,0.10975 q -2.21694,0.1317 -3.29249,1.251147 -1.07555,1.119447 -1.07555,3.248593 0,1.953545 0.68045,2.897393 0.7024,0.943848 1.95354,0.943848 1.69015,0 2.6779,-1.624296 0.98775,-1.646247 0.98775,-4.47779 z"
|
||||||
|
id="path5032" />
|
||||||
|
<path
|
||||||
|
d="m 174.64385,60.715522 q 2.98519,0 4.54364,2.129146 1.5804,2.129145 1.5804,6.321585 V 85.518967 H 176.1584 V 70.351551 q 0,-2.743744 -0.63655,-4.126591 -0.63655,-1.404797 -2.195,-1.404797 -2.10719,0 -3.02909,1.953546 -0.89995,1.953545 -0.89995,6.475235 v 12.270023 h -4.60949 V 61.176471 h 3.66564 l 0.4829,3.314443 h 0.3073 q 0.5268,-1.185297 1.317,-2.019395 0.7902,-0.856049 1.82185,-1.295048 1.03164,-0.460949 2.26084,-0.460949 z"
|
||||||
|
id="path5034" />
|
||||||
|
<path
|
||||||
|
d="m 190.82097,61.176471 v 24.342496 h -4.58754 V 61.176471 Z m -2.26085,-9.372628 q 1.33895,0 1.95355,0.768248 0.61459,0.768248 0.61459,2.173045 0,1.360897 -0.65849,2.129145 -0.63655,0.746298 -1.90965,0.746298 -1.25115,0 -1.95355,-0.746298 -0.68044,-0.768248 -0.68044,-2.129145 0,-1.448697 0.65849,-2.194995 0.6585,-0.746298 1.9755,-0.746298 z"
|
||||||
|
id="path5036" />
|
||||||
|
<path
|
||||||
|
d="m 205.35183,65.017713 h -3.88514 V 85.518967 H 196.8572 V 65.017713 h -2.8974 v -2.480345 l 2.8974,-1.426746 v -1.185298 q 0,-2.941293 0.54875,-4.894839 0.57069,-1.953545 1.86574,-2.919343 1.29505,-0.987748 3.46809,-0.987748 1.11945,0 2.04135,0.19755 0.94385,0.197549 2.08524,0.636548 l -1.07554,3.577842 q -0.6146,-0.219499 -1.16335,-0.329249 -0.5268,-0.1317 -1.07555,-0.1317 -1.16335,0 -1.62429,1.009698 -0.439,1.009698 -0.46095,3.577842 v 1.514546 h 3.88514 z"
|
||||||
|
id="path5038" />
|
||||||
|
<path
|
||||||
|
d="m 216.10731,60.715522 q 3.46809,0 5.11434,2.173046 1.64624,2.173045 1.64624,6.365485 v 16.264914 h -3.42419 l -0.72435,-3.358343 h -0.10975 q -0.6585,1.229197 -1.47064,2.085246 -0.81215,0.856048 -1.86575,1.273097 -1.03165,0.438999 -2.41449,0.438999 -1.95355,0 -3.18275,-1.031648 -1.22919,-1.053598 -1.79989,-2.743744 -0.5707,-1.690146 -0.5707,-3.599792 0,-3.709541 2.08524,-5.685037 2.1072,-1.975495 5.97039,-2.151095 L 218.2584,70.593 v -1.316997 q 0,-2.458394 -0.70239,-3.621742 -0.7024,-1.163347 -2.30475,-1.163347 -1.03165,0 -2.21694,0.395099 -1.16335,0.373149 -2.56815,1.185297 l -1.33895,-3.446142 q 1.51455,-0.943848 3.27055,-1.426747 1.77794,-0.482899 3.70954,-0.482899 z m 2.17304,13.082171 -1.93159,0.10975 q -2.21695,0.1317 -3.29249,1.251147 -1.07555,1.119447 -1.07555,3.248593 0,1.953545 0.68045,2.897393 0.70239,0.943848 1.95354,0.943848 1.69015,0 2.6779,-1.624296 0.98774,-1.646247 0.98774,-4.47779 z"
|
||||||
|
id="path5040" />
|
||||||
|
<path
|
||||||
|
d="m 235.59886,60.759422 q 2.61205,0 4.36804,1.404797 1.756,1.382847 2.634,3.841242 0.87799,2.458394 0.87799,5.641137 v 2.831544 h -11.58957 q 0.0439,3.863191 1.2731,5.772837 1.25114,1.887695 3.79734,1.887695 1.42675,0 2.74374,-0.395099 1.317,-0.417049 2.78765,-1.338947 v 3.950991 q -1.3609,0.812148 -2.87545,1.207248 -1.51454,0.395099 -3.24859,0.395099 -3.20469,0 -5.20214,-1.558447 -1.99744,-1.580396 -2.91934,-4.38999 -0.89995,-2.809594 -0.89995,-6.519135 0,-4.104641 0.9219,-6.936185 0.9219,-2.831543 2.76569,-4.30219 1.8438,-1.492597 4.56559,-1.492597 z m 0.0659,3.687592 q -1.69014,0 -2.65594,1.580397 -0.9658,1.580396 -1.07555,4.982638 h 7.26543 q 0,-1.887695 -0.3951,-3.358342 -0.39509,-1.492597 -1.18529,-2.348645 -0.76825,-0.856048 -1.95355,-0.856048 z"
|
||||||
|
id="path5042" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 11 KiB |
54
static/upvote.svg
Normal file
54
static/upvote.svg
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="47.87009mm"
|
||||||
|
height="89.159485mm"
|
||||||
|
viewBox="0 0 47.87009 89.159485"
|
||||||
|
version="1.1"
|
||||||
|
id="svg14062"
|
||||||
|
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
|
||||||
|
sodipodi:docname="upvote.svg"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview14064"
|
||||||
|
pagecolor="#000000"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="1.0280428"
|
||||||
|
inkscape:cx="129.37205"
|
||||||
|
inkscape:cy="99.704021"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="996"
|
||||||
|
inkscape:window-x="-8"
|
||||||
|
inkscape:window-y="-8"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="layer1" />
|
||||||
|
<defs
|
||||||
|
id="defs14059" />
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-45.765321,-111.54473)">
|
||||||
|
<path
|
||||||
|
id="rect15084"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#e5a8ff;stroke-width:0;stroke-miterlimit:3.96999"
|
||||||
|
transform="matrix(0.43855232,-0.89870566,0.43855232,0.89870566,0,0)"
|
||||||
|
d="m -16.165047,120.52049 19.9285745,7.36012 27.2886965,27.2887 7.360122,19.92858 -54.577393,0 z"
|
||||||
|
sodipodi:nodetypes="cccccc" />
|
||||||
|
<path
|
||||||
|
id="rect15091"
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:#e5a8ff;stroke-width:0;stroke-miterlimit:3.96999"
|
||||||
|
d="m 58.540445,158.53503 v 42.16918 h 22.31984 v -42.16886 l -11.159921,22.86924 z" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
|
@ -1,4 +1,4 @@
|
||||||
import adapter from '@sveltejs/adapter-auto';
|
import adapter from '@sveltejs/adapter-node';
|
||||||
|
|
||||||
/** @type {import('@sveltejs/kit').Config} */
|
/** @type {import('@sveltejs/kit').Config} */
|
||||||
const config = {
|
const config = {
|
||||||
|
|
Loading…
Reference in a new issue