Ported from old SvelteKit version

This commit is contained in:
tdgmdev 2023-03-06 17:58:14 -05:00
commit 61e65915ca
16 changed files with 3566 additions and 0 deletions

11
.gitignore vendored Normal file
View file

@ -0,0 +1,11 @@
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
db

2708
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

27
package.json Normal file
View file

@ -0,0 +1,27 @@
{
"name": "my-app",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview"
},
"devDependencies": {
"@sveltejs/adapter-auto": "^1.0.0",
"@sveltejs/kit": "^1.0.0",
"svelte": "^3.54.0",
"vite": "^4.0.0"
},
"type": "module",
"dependencies": {
"@sveltejs/adapter-cloudflare": "^2.1.0",
"@sveltejs/adapter-node": "^1.1.1",
"archiver": "^5.3.1",
"crypto": "^1.0.1",
"dotenv": "^16.0.3",
"image-size": "^1.0.2",
"sqlite": "^4.1.2",
"sqlite3": "^5.1.4"
}
}

20
src/app.html Normal file
View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
<style>
body {
font-family: monospace;
padding: 0;
margin: 0;
overflow-x: hidden;
}
</style>
</head>
<body>
<div>%sveltekit.body%</div>
</body>
</html>

146
src/lib/Main.svelte Normal file
View file

@ -0,0 +1,146 @@
<script>
export let textTop = "";
export let textBottom = "";
export let fgColor = "var(--grayish)"; //"rgb(255,255,255)";
export let bgColor = "var(--grayish)"; //"rgb(255,255,255)";
export let bgImg = "url('/img/bg.svg')";
export let download = "/";
export let date = "N/A";
export let turbowarp = false;
export let classes = "";
var changeTheme = function () {
localStorage.setItem(
"theme",
localStorage.getItem("theme") == "dark" ? "" : "dark"
);
window.location.href = "";
};
</script>
<body style="--bg-bg: {bgColor}; --bg-fg: {fgColor}" class={classes}>
<div class="banner-wrapper">
<div class="banner" style="background-image: {bgImg}">
<div class="banner-text">
<p>
{textTop}
<a
class="download"
download={textTop.split("/").pop()}
href={download}>(Download)</a
> <a href="././" class="download">(../)</a>
<a href="/" class="download">(/)</a>
{#if turbowarp}
<a
class="download"
href="https://turbowarp.org/editor?project_url={download}"
>(TurboWarp)</a
>
{/if}
</p>
</div>
<slot />
<div class="banner-text">
{textBottom}
<a href="https://tdgmdev.net/" class="download">(Home)</a>
<a href="#" class="download" on:click={changeTheme}
>(Change theme)</a
>
</div>
</div>
</div>
</body>
<style lang="css">
body {
--blue: #4689e8;
--blue-again: #5687d9;
--white: rgb(255, 255, 255);
--grayish: rgb(240, 240, 240);
--gray: rgb(210, 210, 210);
--black: rgb(0, 0, 0);
color: var(--black);
}
.dark {
--white: rgb(32, 32, 32);
--grayish: rgb(47, 47, 47);
--gray: rgb(70, 70, 70);
--black: rgb(255, 255, 255);
--blue: rgb(128, 128, 128);
--blue-again: rgb(190, 190, 190);
}
.banner {
width: 100%;
height: 100vh;
background-size: auto 75%;
background-position: center;
background-repeat: no-repeat;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
font-weight: bold;
font-size: 24px;
}
body {
background: radial-gradient(
circle at 5px 5px,
var(--bg-fg) 1px,
var(--bg-bg) 0px,
var(--bg-bg) 8px
);
background-size: 10px 10px;
background-repeat: repeat;
/*background: url('/bg.png');
background-size: cover;
*/
}
.banner-part {
height: 500px;
}
.banner-text {
/*color: white;*/
margin: 30px;
/*filter: drop-shadow( 0px 0px 10px rgba(0, 0, 0, 1));*/
text-align: center;
}
.banner-mid {
width: calc(100% - 50px);
font-size: 12px;
max-height: 100%;
display: flex;
justify-content: space-around;
height: 100%;
overflow: auto;
font-weight: normal;
}
.download {
font-size: 50%;
}
p {
margin-block-start: 0;
margin-block-end: 0;
}
.banner-mid {
border: solid var(--gray) 1px;
border-radius: 10px;
}
a {
text-decoration: none;
color: var(--blue-again);
}
.dark {
}
</style>

8
src/routes/+page.svelte Normal file
View file

@ -0,0 +1,8 @@
<script context="module">
export async function load() {
return {
status: 302,
redirect: "/data/",
};
}
</script>

View file

@ -0,0 +1,69 @@
import fs from 'fs';
import archiver from 'archiver';
import crypto from 'crypto';
/** @type {import('./$types').RequestHandler} */
export async function GET({ params }) {
const DATA_DIRECTORY = "/files/";
const ZIP_DIRECTORY = "/zips/";
let currDirectory = DATA_DIRECTORY + params.path;
currDirectory = currDirectory.replaceAll(/\/+/g,'/');
var path, contents;
if (currDirectory.indexOf('./') != -1 || currDirectory.indexOf('../') != -1 || currDirectory.indexOf('//') != -1 || !fs.existsSync(currDirectory)) {
return new Response('Invalid Path');
} else if (fs.lstatSync(currDirectory).isDirectory()) {
var zipDir = ZIP_DIRECTORY + (crypto.createHash('md5').update(params.path).digest('hex')) + ".zip";
const files = fs.readdirSync(currDirectory);
const stats = files.map(file => fs.statSync(currDirectory + '/' + file));
var recursive = false;
files.forEach(file => {
if (fs.statSync(currDirectory + '/' + file).isDirectory()) {
recursive = true;
return;
}
});
if (recursive == true) return new Response('Recursive directories cannot be downloaded.');
const size = stats.reduce((accumulator, { size }) => accumulator + size, 0);
if (size > 1024 * 1024 * 128) {
return new Response('That directory is too large to request a download of.');
}
const mtime = stats.reduce((accumulator, { mtime }) => Math.max(accumulator, mtime), 0);
var updated = false;
if (fs.existsSync(zipDir) && mtime > fs.statSync(zipDir).mtime) {
fs.unlinkSync(zipDir);
updated = true;
}
if (!fs.existsSync(zipDir) || updated) {
const output = fs.createWriteStream(zipDir);
const archive = archiver('zip', {
zlib: { level: 9 }
});
await new Promise((resolve, reject) => {
archive.pipe(output);
archive.directory(currDirectory, 'data');
archive.finalize();
output.on('close', resolve);
});
}
return new Response(fs.readFileSync(zipDir));
} else {
return new Response(fs.readFileSync(currDirectory));
}
}

View file

@ -0,0 +1,104 @@
import fs from 'fs';
import sizeOf from 'image-size';
function compareFiles(a, b, dir) {
var oldA = a;
var oldB = b;
a = dir + '/' + a;
b = dir + '/' + b;
if (oldA[0] == '!' && oldB[0] != '!') return -1;
if (oldB[0] == '!' && oldA[0] != '!') return;
if (fs.statSync(a).isDirectory() && !fs.statSync(b).isDirectory()) return -1;
if (fs.statSync(b).isDirectory() && !fs.statSync(a).isDirectory()) return 1;
return (fs.statSync(b).mtime - fs.statSync(a).mtime);
}
function getData(file, dir, path) {
var fileData = fs.statSync(dir + '/' + file);
var suffix = "";
if (fileData.isDirectory()) suffix += '/';
var d = fileData.mtime;
return {
"name": file + suffix,
"link": file,
"dir": path + '/' + file,
"mtime": d.toUTCString(),
"extension": file.split('.').pop()
};
}
/** @type {import('./$types').PageLoad} */
export async function load({ params, url }) {
const DATA_DIRECTORY = "/files/";
let currDirectory = DATA_DIRECTORY + params.path;
var path, contents, raw, date;
var isDark = (url.searchParams.get('dark')) ? "dark" : "";
if (currDirectory.indexOf('./') != -1 || currDirectory.indexOf('../') != -1 || currDirectory.indexOf('//') != -1 || !fs.existsSync(currDirectory)) {
path = "Invalid Path";
contents = "";
} else if (fs.statSync(currDirectory).isDirectory()) {
var files = [];
fs.readdirSync(currDirectory).forEach(file => {
if (file.search(/dir\.zip$/) != -1) return;
files.push(file);
});
files.sort(function (a, b) { return compareFiles(a, b, currDirectory) });
if (params.path != '') {
files = [".", "..", ...files];
} else {
files = [".", ...files];
}
for (var i = 0; i < files.length; i++) {
files[i] = getData(files[i], currDirectory, params.path);
}
path = currDirectory;
contents = files;
date = fs.statSync(currDirectory).mtime;
} else {
path = currDirectory;
contents = [];
raw = true;
var extension = params.path.split('.').pop();
var width, height;
width = "calc(100vw - 100px)";
if (extension == "png" || extension == "jpg") {
var dimensions = sizeOf(currDirectory);
width = dimensions.width + "px";
height = dimensions.height;
}
if (extension == "sb3" || extension == "sjson") {
width = "100vmin";
}
date = fs.statSync(currDirectory).mtime;
return {
body: {
path, contents, raw: true, currPath: '/api/file/' + params.path,
width: width, height: height + "px",
extension: extension,
date: date + "",
isDark: isDark
}
};
}
return {
path, contents, raw: false, currPath: '/api/file/' + params.path, width: "calc(100vw - 100px)", extension: 'none', date: date + "", isDark: isDark
};
}

View file

@ -0,0 +1,166 @@
<script>
import Main from "$lib/Main.svelte";
import { page } from "$app/stores";
import { goto } from "$app/navigation";
import { browser } from "$app/environment";
/** @type {import('./$types').PageData} */
export let data;
let {path, contents, raw, currPath, extension, width, height, date} = data;
var isDark = browser
? localStorage.getItem("theme") == "dark"
? "dark"
: ""
: "";
</script>
<Main
classes={isDark}
textTop={path}
download="/{currPath}"
textBottom="File viewer by tdgmdev.net"
turbowarp={extension == "sjson" || extension == "sb3"}
>
<div class="banner-mid" style="--width: {width}">
{#if !raw}
<table style="--width: 100%">
<tr>
<td>Name</td>
<td>Modified on</td>
<td>Download</td>
<td>Special actions</td>
</tr>
{#each contents as content}
<tr>
<td
><a href="{$page.url.pathname}/{content.link}"
>{content.name}</a
></td
>
<td><span>{content.mtime}</td>
<td
><a
href="/api/file/{content.dir}"
download={!content.extension ? `${currPath.split('/').pop()}.zip` : content.name}>Download</a
></td
>
{#if content.extension == "sjson" || content.extension == "sb3"}
<td
><a
href="https://turbowarp.org/editor?project_url=https://files.tdgmdev.net/api/file/{content.dir}"
download={content.name}>TurboWarp</a
></td
>
{/if}
</tr>
{/each}
</table>
{/if}
{#if raw}
<table style="--width: {width}">
<tr>
<td>File Viewer</td>
</tr>
{#if extension == "sb3" || extension == "sjson"}
<iframe
src="https://turbowarp.org/embed?project_url=https://files.tdgmdev.net{currPath}"
class="turbowarp"
width="800px"
height="600px"
style="background-color:white; --width: {width}; --height: {height}"
/>
{/if}
{#if extension != "sb3" && extension != "sjson"}
<iframe
src={currPath}
class="file-{extension}"
width="800px"
height="800px"
style="background-color:white; --width: {width}; --height: {height}"
/>
{/if}
</table>
{/if}
</div>
</Main>
<style>
iframe {
width: 100%;
height: 98%;
}
table .file-jpg,
table .file-png {
height: var(--height);
}
.file-sb3 {
display: none;
}
table .turbowarp {
height: 75vmin;
}
.banner-entry {
display: table-row;
}
table {
overflow-y: auto;
overflow-x: auto;
width: var(--width);
max-width: 100vw;
display: block;
}
td {
width: 200px;
}
iframe {
border: none;
}
tr:not(:last-child) {
border-bottom: solid var(--gray) 1px;
}
tr:first-child {
background-color: var(--blue);
color: white;
position: sticky;
top: 0;
}
tr {
display: block;
padding: 7px;
}
a {
text-decoration: none;
color: var(--blue-again);
}
.banner-mid {
border: solid var(--gray) 1px;
border-radius: 10px;
}
.banner-mid {
width: var(--width);
font-size: 12px;
max-height: 100%;
display: flex;
justify-content: space-around;
height: 100%;
overflow: auto;
font-weight: normal;
background: var(--white);
}
</style>

BIN
static/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

79
static/img/border.svg Normal file
View file

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="92.684387mm"
height="15.23604mm"
viewBox="0 0 92.684385 15.23604"
version="1.1"
id="svg1110"
sodipodi:docname="border.svg"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
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="namedview1112"
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="1.5518659"
inkscape:cx="273.54168"
inkscape:cy="-22.231303"
inkscape:window-width="1868"
inkscape:window-height="1006"
inkscape:window-x="24"
inkscape:window-y="46"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs1107" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-1.5551306,-179.57009)">
<path
id="rect1646"
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke-width:15.875;stroke-linecap:round;stroke-linejoin:round;paint-order:stroke fill markers"
d="m 1.5551306,187.34265 c 0,0 14.7844384,-7.77255 23.1710964,-7.77255 16.773316,0 29.568876,15.5451 46.342193,15.5451 8.386658,0 23.171094,-7.77255 23.171094,-7.77255 v 9.91277 H 1.5551306 Z"
sodipodi:nodetypes="caacccc" />
<circle
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke-width:15.875;stroke-linecap:round;stroke-linejoin:round;paint-order:stroke fill markers"
id="path1859"
cx="62.078156"
cy="185.98183"
r="2.2243786" />
<circle
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke-width:15.875;stroke-linecap:round;stroke-linejoin:round;paint-order:stroke fill markers"
id="circle1867"
cx="72.732628"
cy="184.888"
r="3.4143901" />
<circle
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke-width:15.875;stroke-linecap:round;stroke-linejoin:round;paint-order:stroke fill markers"
id="circle1869"
cx="82.285164"
cy="185.48705"
r="1.2911379" />
<circle
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke-width:15.875;stroke-linecap:round;stroke-linejoin:round;paint-order:stroke fill markers"
id="circle1871"
cx="48.922638"
cy="182.27203"
r="1.2911379" />
<circle
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke-width:15.875;stroke-linecap:round;stroke-linejoin:round;paint-order:stroke fill markers"
id="circle1873"
cx="70.383842"
cy="192.68364"
r="0.87060106" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 127.14 96.36"><defs><style>.cls-1{fill:#222;}</style></defs><g id="图层_2" data-name="图层 2"><g id="Discord_Logos" data-name="Discord Logos"><g id="Discord_Logo_-_Large_-_White" data-name="Discord Logo - Large - White"><path class="cls-1" d="M107.7,8.07A105.15,105.15,0,0,0,81.47,0a72.06,72.06,0,0,0-3.36,6.83A97.68,97.68,0,0,0,49,6.83,72.37,72.37,0,0,0,45.64,0,105.89,105.89,0,0,0,19.39,8.09C2.79,32.65-1.71,56.6.54,80.21h0A105.73,105.73,0,0,0,32.71,96.36,77.7,77.7,0,0,0,39.6,85.25a68.42,68.42,0,0,1-10.85-5.18c.91-.66,1.8-1.34,2.66-2a75.57,75.57,0,0,0,64.32,0c.87.71,1.76,1.39,2.66,2a68.68,68.68,0,0,1-10.87,5.19,77,77,0,0,0,6.89,11.1A105.25,105.25,0,0,0,126.6,80.22h0C129.24,52.84,122.09,29.11,107.7,8.07ZM42.45,65.69C36.18,65.69,31,60,31,53s5-12.74,11.43-12.74S54,46,53.89,53,48.84,65.69,42.45,65.69Zm42.24,0C78.41,65.69,73.25,60,73.25,53s5-12.74,11.44-12.74S96.23,46,96.12,53,91.08,65.69,84.69,65.69Z"/></g></g></g></svg>

After

Width:  |  Height:  |  Size: 986 B

209
static/img/favicon.svg Normal file
View file

@ -0,0 +1,209 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="636.23572"
height="636.23572"
viewBox="0 0 636.23571 636.2357"
version="1.1"
id="svg5"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="favicon.svg"
inkscape:export-filename="tdgmdev-banner2.png"
inkscape:export-xdpi="192.05"
inkscape:export-ydpi="192.05"
xml:space="preserve"
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="px"
showgrid="false"
inkscape:zoom="0.2570107"
inkscape:cx="-254.8532"
inkscape:cy="282.08942"
inkscape:window-width="1868"
inkscape:window-height="1006"
inkscape:window-x="24"
inkscape:window-y="46"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" /><defs
id="defs2"><filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter18739"
x="-0.097691614"
y="-0.097691614"
width="1.1953832"
height="1.1953832"><feGaussianBlur
inkscape:collect="always"
stdDeviation="1.3462276"
id="feGaussianBlur18741" /></filter><filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter18743"
x="-0.097691614"
y="-0.097691614"
width="1.1953832"
height="1.1953832"><feGaussianBlur
inkscape:collect="always"
stdDeviation="1.3462276"
id="feGaussianBlur18745" /></filter><filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter18751"
x="-0.097691614"
y="-0.097691614"
width="1.1953832"
height="1.1953832"><feGaussianBlur
inkscape:collect="always"
stdDeviation="1.3462276"
id="feGaussianBlur18753" /></filter><filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter18747"
x="-0.097691614"
y="-0.097691614"
width="1.1953832"
height="1.1953832"><feGaussianBlur
inkscape:collect="always"
stdDeviation="1.3462276"
id="feGaussianBlur18749" /></filter><filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter18721"
x="-0.09455217"
y="-0.094552167"
width="1.1891043"
height="1.1891043"><feGaussianBlur
inkscape:collect="always"
stdDeviation="1.4593209"
id="feGaussianBlur18723" /></filter><filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter9926"
x="-0.024739079"
y="-0.11562142"
width="1.0494782"
height="1.2312428"><feGaussianBlur
inkscape:collect="always"
stdDeviation="11.624891"
id="feGaussianBlur9928" /></filter></defs><g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-571.99581,-304.73986)"><g
aria-label="T"
id="g5506"
style="font-size:10.5833px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#95c7b9;fill-opacity:1;stroke:none;stroke-width:0.0328121;stroke-dasharray:none;stroke-opacity:1"
transform="matrix(16.127163,0,0,16.127163,-1450.517,-704.52306)" /><g
id="g8696-4"
transform="matrix(8.7626449,0,0,8.7626449,55.238563,-130.00498)"
style="stroke-width:0.431323"><circle
style="fill:#ff0000;fill-opacity:0.5;stroke-width:1.14121;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.96999;paint-order:stroke fill markers;filter:url(#filter18739)"
id="path18727-5"
cx="-69.380829"
cy="78.74015"
r="16.536457"
transform="rotate(-90)" /><circle
style="fill:#80ff00;fill-opacity:0.5;stroke-width:1.14121;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.96999;paint-order:stroke fill markers;filter:url(#filter18743)"
id="circle18733-0"
cx="-69.380829"
cy="111.81307"
r="16.536457"
transform="rotate(-90)" /><circle
style="fill:#00ffff;fill-opacity:0.5;stroke-width:1.14121;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.96999;paint-order:stroke fill markers;filter:url(#filter18751)"
id="circle18735-3"
cx="-102.45375"
cy="78.74015"
r="16.536457"
transform="rotate(-90)" /><circle
style="fill:#8000ff;fill-opacity:0.5;stroke-width:1.14121;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.96999;paint-order:stroke fill markers;filter:url(#filter18747)"
id="circle18737-6"
cx="-102.45375"
cy="111.81307"
r="16.536457"
transform="rotate(-90)" /><circle
style="opacity:0.388158;fill:#80ff00;fill-opacity:0.5;stroke-width:1.14121;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.96999;paint-order:stroke fill markers"
id="circle18757"
cx="-69.380829"
cy="111.81307"
r="16.536457"
transform="rotate(-90)" /><circle
style="opacity:0.388158;fill:#00ffff;fill-opacity:0.5;stroke-width:1.14121;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.96999;paint-order:stroke fill markers"
id="circle18759"
cx="-102.45375"
cy="78.74015"
r="16.536457"
transform="rotate(-90)" /><circle
style="opacity:0.388158;fill:#8000ff;fill-opacity:0.5;stroke-width:1.14121;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.96999;paint-order:stroke fill markers"
id="circle18761"
cx="-102.45375"
cy="111.81307"
r="16.536457"
transform="rotate(-90)" /><circle
style="opacity:0.388158;fill:#ff0000;fill-opacity:0.5;stroke-width:1.14121;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.96999;paint-order:stroke fill markers"
id="circle18755"
cx="-69.380829"
cy="78.74015"
r="16.536457"
transform="rotate(-90)" /><g
id="g18719"
style="fill:#ffffff;fill-opacity:1;stroke-width:0.431323;filter:url(#filter18721)"><path
id="path18711"
style="fill:#ffffff;fill-opacity:1;stroke-width:1.1412;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.96999;paint-order:stroke fill markers"
d="m 91.969323,72.688126 3.307291,-5.291666 3.307292,5.291666 v 26.45833 l -3.307291,5.291674 -3.307292,-5.291674 z"
sodipodi:nodetypes="ccccccc" /><path
id="path18713"
style="fill:#ffffff;fill-opacity:1;stroke-width:1.1412;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.96999;paint-order:stroke fill markers"
d="m 108.50579,82.610006 5.29166,3.30729 -5.29166,3.30729 H 82.047448 l -5.291667,-3.30729 5.291667,-3.30729 z"
sodipodi:nodetypes="ccccccc" /><path
id="path18715"
style="fill:#ffffff;fill-opacity:1;stroke-width:1.1412;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.96999;paint-order:stroke fill markers"
d="m 102.29245,74.224251 6.08038,-1.403165 -1.40317,6.080382 -18.708871,18.708868 -6.080381,1.40317 1.403165,-6.08039 z"
sodipodi:nodetypes="ccccccc" /><path
id="path18717"
style="fill:#ffffff;fill-opacity:1;stroke-width:1.1412;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.96999;paint-order:stroke fill markers"
d="m 106.96966,92.933116 1.40317,6.08038 -6.08038,-1.40316 -18.708877,-18.708868 -1.403166,-6.080381 6.080382,1.403165 z"
sodipodi:nodetypes="ccccccc" /></g><g
id="g18709-1"
style="fill:#ffffff;fill-opacity:1;stroke-width:0.431323"><path
id="rect17499-0"
style="fill:#ffffff;fill-opacity:1;stroke-width:1.1412;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.96999;paint-order:stroke fill markers"
d="m 91.969323,72.688126 3.307291,-5.291666 3.307292,5.291666 v 26.45833 l -3.307291,5.291674 -3.307292,-5.291674 z"
sodipodi:nodetypes="ccccccc" /><path
id="path17521-6"
style="fill:#ffffff;fill-opacity:1;stroke-width:1.1412;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.96999;paint-order:stroke fill markers"
d="m 108.50579,82.610006 5.29166,3.30729 -5.29166,3.30729 H 82.047448 l -5.291667,-3.30729 5.291667,-3.30729 z"
sodipodi:nodetypes="ccccccc" /><path
id="path17515-3"
style="fill:#ffffff;fill-opacity:1;stroke-width:1.1412;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.96999;paint-order:stroke fill markers"
d="m 102.29245,74.224251 6.08038,-1.403165 -1.40317,6.080382 -18.708871,18.708868 -6.080381,1.40317 1.403165,-6.08039 z"
sodipodi:nodetypes="ccccccc" /><path
id="path17523-2"
style="fill:#ffffff;fill-opacity:1;stroke-width:1.1412;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:3.96999;paint-order:stroke fill markers"
d="m 106.96966,92.933116 1.40317,6.08038 -6.08038,-1.40316 -18.708877,-18.708868 -1.403166,-6.080381 6.080382,1.403165 z"
sodipodi:nodetypes="ccccccc" /></g></g><g
aria-label="T"
id="g5506-0"
style="font-size:10.5833px;line-height:1.25;font-family:'Open Sans';-inkscape-font-specification:'Open Sans';fill:#95c7b9;fill-opacity:1;stroke:none;stroke-width:0.174407;stroke-dasharray:none;stroke-opacity:1"
transform="matrix(11.467406,0,0,11.467406,-588.53565,-578.07927)" /><text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:240.102px;line-height:1.25;font-family:monospace;-inkscape-font-specification:'monospace Bold';text-align:end;text-anchor:end;mix-blend-mode:normal;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:25;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers;filter:url(#filter9926)"
x="1047.2435"
y="231.5193"
id="text9924"
transform="matrix(1.0004344,0,0,0.9995658,27.878782,278.56378)"><tspan
sodipodi:role="line"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:monospace;-inkscape-font-specification:'monospace Bold';text-align:end;text-anchor:end;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:25;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
x="1047.2435"
y="231.5193"
id="tspan9922" /></text></g></svg>

After

Width:  |  Height:  |  Size: 11 KiB

View file

@ -0,0 +1 @@
<svg width="98" height="96" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z" fill="#222"/></svg>

After

Width:  |  Height:  |  Size: 961 B

10
svelte.config.js Normal file
View file

@ -0,0 +1,10 @@
import adapter from '@sveltejs/adapter-cloudflare';
/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: {
adapter: adapter()
}
};
export default config;

7
vite.config.js Normal file
View file

@ -0,0 +1,7 @@
import { sveltekit } from '@sveltejs/kit/vite';
const config = {
plugins: [sveltekit()]
};
export default config;