Compare commits

...

13 Commits
main ... main

Author SHA1 Message Date
691beb9334 Update VoidCat/Controllers/NostrController.cs
All checks were successful
continuous-integration/drone/push Build is passing
2024-06-07 09:30:11 +00:00
d665b8bef4 Update .drone.yml
All checks were successful
continuous-integration/drone/push Build is passing
2024-06-06 18:00:19 +00:00
ff8727e249 Update VoidCat/Controllers/UploadController.cs
Some checks reported errors
continuous-integration/drone/push Build encountered an error
2024-06-06 17:36:02 +00:00
b69277f133
fixes #77
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-10 22:57:10 +00:00
1d23df110b fix: broken include
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-01 21:53:05 +00:00
a38428ac7f chore: cleanup
Some checks failed
continuous-integration/drone/push Build is failing
2024-01-01 21:49:38 +00:00
ce7c3613a8
add mediaDimensions
All checks were successful
continuous-integration/drone/push Build is passing
2023-12-26 18:29:21 +00:00
7a41651ec5
Always strip metadata of image uploads
All checks were successful
continuous-integration/drone/push Build is passing
2023-12-26 18:20:29 +00:00
a92e7d46fc
Return dimensions 2023-12-26 18:20:15 +00:00
b9f989986a
Admin delete / tailwind
All checks were successful
continuous-integration/drone/push Build is passing
2023-12-25 19:54:49 +00:00
097f97edc1
Use logo as default avatar
All checks were successful
continuous-integration/drone/push Build is passing
2023-12-25 18:56:26 +00:00
9837d917b9
Max upload size
All checks were successful
continuous-integration/drone/push Build is passing
2023-12-25 18:50:32 +00:00
d0458d094d
Fix prometheus
All checks were successful
continuous-integration/drone/push Build is passing
2023-12-25 18:08:12 +00:00
52 changed files with 933 additions and 605 deletions

View File

@ -8,12 +8,14 @@ metadata:
steps:
- name: build
image: r.j3ss.co/img
image: docker
privileged: true
environment:
TOKEN:
from_secret: gitea
commands:
- img login -u kieran -p $TOKEN git.v0l.io
- img build -t git.v0l.io/kieran/void-cat:latest .
- img push git.v0l.io/kieran/void-cat:latest
- dockerd &
- docker login -u kieran -p $TOKEN git.v0l.io
- docker buildx create --name mybuilder --bootstrap --use
- docker buildx build -t git.v0l.io/kieran/void-cat:latest --platform linux/amd64 --push .
- kill $(cat /var/run/docker.pid)

View File

@ -9,6 +9,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
ProjectSection(SolutionItems) = preProject
.gitignore = .gitignore
docker-compose.dev.yml = docker-compose.dev.yml
prometheus.yml = prometheus.yml
EndProjectSection
EndProject
Global

View File

@ -32,6 +32,7 @@ public class AdminController : Controller
/// </summary>
/// <param name="request">Page request</param>
/// <returns></returns>
[HttpOptions]
[HttpPost]
[Route("file")]
public async Task<RenderedResults<VoidFileResponse>> ListFiles([FromBody] PagedRequest request)
@ -51,6 +52,7 @@ public class AdminController : Controller
/// Delete a file from the system
/// </summary>
/// <param name="id">Id of the file to delete</param>
[HttpOptions]
[HttpDelete]
[Route("file/{id}")]
public async Task DeleteFile([FromRoute] string id)
@ -65,6 +67,7 @@ public class AdminController : Controller
/// </summary>
/// <param name="request">Page request</param>
/// <returns></returns>
[HttpOptions]
[HttpPost]
[Route("users")]
public async Task<RenderedResults<AdminListedUser>> ListUsers([FromBody] PagedRequest request)
@ -91,6 +94,7 @@ public class AdminController : Controller
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
[HttpOptions]
[HttpPost]
[Route("update-user")]
public async Task<IActionResult> UpdateUser([FromBody] AdminUpdateUser user)
@ -100,7 +104,7 @@ public class AdminController : Controller
oldUser.Storage = user.Storage;
oldUser.Email = user.Email;
await _userStore.AdminUpdateUser(oldUser);
return Ok();
}

View File

@ -158,6 +158,7 @@ public abstract class BaseDownloadController : Controller
Response.Headers.XFrameOptions = "SAMEORIGIN";
Response.Headers.ContentDisposition = $"inline; filename=\"{meta?.Metadata?.Name}\"";
Response.ContentType = meta?.Metadata?.MimeType ?? "application/octet-stream";
Response.ContentLength = (long?)meta?.Metadata?.Size;
return meta;
}

View File

@ -41,7 +41,10 @@ public class IndexController : Controller
};
var indexPath = Path.Combine(_webHost.WebRootPath, "index.html");
var indexContent = await System.IO.File.ReadAllTextAsync(indexPath);
var indexContent = System.IO.File.Exists(indexPath) ?
await System.IO.File.ReadAllTextAsync(indexPath)
: string.Empty;
var meta = (await _fileMetadata.Get(gid))?.ToMeta(false);
var tags = new List<KeyValuePair<string, string>>()

View File

@ -65,9 +65,12 @@ public class NostrController : BaseDownloadController
{
return Unauthorized();
}
try
{
if (_settings.MaintenanceMode)
{
throw new InvalidOperationException("Site is in maintenance mode");
}
var nostrUser = await _userManager.LoginOrRegister(pubkey);
var file = Request.Form.Files.First();
@ -86,17 +89,24 @@ public class NostrController : BaseDownloadController
await _fileMetadata.Add(vf);
await _userUploads.AddFile(nostrUser.Id, vf.Id);
List<List<string>> tags = new()
{
new() {"url", new Uri(_settings.SiteUrl, $"/nostr/{vf.OriginalDigest}{Path.GetExtension(vf.Name)}").ToString()},
new() {"ox", vf.OriginalDigest ?? "", _settings.SiteUrl.ToString()},
new() {"x", vf.Digest ?? ""},
new() {"m", vf.MimeType}
};
if (!string.IsNullOrEmpty(vf.MediaDimensions))
{
tags.Add(new() {"dim", vf.MediaDimensions});
}
var ret = new Nip96UploadResult
{
FileHeader = new()
{
Tags = new()
{
new() {"url", new Uri(_settings.SiteUrl, $"/nostr/{vf.OriginalDigest}{Path.GetExtension(vf.Name)}").ToString()},
new() {"ox", vf.OriginalDigest ?? "", _settings.SiteUrl.ToString()},
new() {"x", vf.Digest ?? ""},
new() {"m", vf.MimeType}
}
Tags = tags
}
};

View File

@ -57,6 +57,8 @@ namespace VoidCat.Controllers
/// <param name="cli">True if you want to return only the url of the file in the response</param>
/// <returns>Returns <see cref="UploadResult"/></returns>
[HttpPost]
[HttpOptions]
[HttpHead]
[DisableRequestSizeLimit]
[DisableFormValueModelBinding]
[Authorize(AuthenticationSchemes = "Bearer,Nostr", Policy = Policies.RequireNostr)]
@ -65,14 +67,21 @@ namespace VoidCat.Controllers
{
try
{
var stripMetadata = Request.Headers.GetHeader("V-Strip-Metadata")
?.Equals("true", StringComparison.InvariantCultureIgnoreCase) ?? false;
var mime = Request.Headers.GetHeader("V-Content-Type");
var stripMetadata = (mime?.StartsWith("image/") ?? false) || (Request.Headers.GetHeader("V-Strip-Metadata")
?.Equals("true", StringComparison.InvariantCultureIgnoreCase) ?? false);
if (_settings.MaintenanceMode && !stripMetadata)
if (_settings.MaintenanceMode)
{
throw new InvalidOperationException("Site is in maintenance mode");
}
var bodyLength = Request.ContentLength ?? 0;
if ((ulong)bodyLength >= (_settings.MaxFileSize ?? ulong.MaxValue))
{
throw new InvalidOperationException("File size too large");
}
var uid = HttpContext.GetUserId();
var pubkey = HttpContext.GetPubKey();
if (uid == default && !string.IsNullOrEmpty(pubkey))
@ -81,7 +90,6 @@ namespace VoidCat.Controllers
uid = nostrUser.Id;
}
var mime = Request.Headers.GetHeader("V-Content-Type");
var filename = Request.Headers.GetHeader("V-Filename");
if (string.IsNullOrEmpty(mime) && !string.IsNullOrEmpty(filename))

View File

@ -359,7 +359,8 @@ public static class Extensions
EditSecret = withEditSecret ? f.EditSecret : null,
Storage = f.Storage,
EncryptionParams = f.EncryptionParams,
MagnetLink = f.MagnetLink
MagnetLink = f.MagnetLink,
MediaDimensions = f.MediaDimensions
};
}

View File

@ -32,4 +32,5 @@ public class VoidFileMeta
public string Storage { get; init; } = "local-disk";
public string? EncryptionParams { get; init; }
public string? MagnetLink { get; init; }
public string? MediaDimensions { get; init; }
}

View File

@ -26,6 +26,11 @@ namespace VoidCat.Model
/// Size in bytes to split uploads into chunks
/// </summary>
public ulong? UploadSegmentSize { get; init; }
/// <summary>
/// Max file size for upload
/// </summary>
public ulong? MaxFileSize { get; init; }
/// <summary>
/// Tor configuration

View File

@ -40,6 +40,7 @@ public class CompressContent
}
}
var ffProbe = await TryProbe(input, cts);
var probe = isImage ? await ImageFile.FromFileAsync(input) : default;
var ffmpeg = FFMpegArguments
.FromFileInput(input)
@ -73,7 +74,9 @@ public class CompressContent
var result = await ffmpeg.ProcessAsynchronously();
return new(result, output)
{
MimeType = outMime
MimeType = outMime,
Width = ffProbe?.PrimaryVideoStream?.Width,
Height = ffProbe?.PrimaryVideoStream?.Height,
};
}
catch (Exception ex)
@ -84,8 +87,24 @@ public class CompressContent
return new(false, output);
}
private async Task<IMediaAnalysis?> TryProbe(string path, CancellationToken cts)
{
try
{
return await FFProbe.AnalyseAsync(path, cancellationToken: cts);
}
catch
{
// ignored
}
return default;
}
public record CompressResult(bool Success, string OutPath)
{
public string? MimeType { get; init; }
public int? Width { get; init; }
public int? Height { get; init; }
}
}

View File

@ -73,7 +73,8 @@ public class LocalDiskFileStore : StreamFileStore, IFileStore
Size = (ulong)fInfo.Length,
Digest = hash.ToHex(),
MimeType = res.MimeType ?? vf.MimeType,
OriginalDigest = originalHash.ToHex()
OriginalDigest = originalHash.ToHex(),
MediaDimensions = res is {Width: not null, Height: not null} ? $"{res.Width.Value}x{res.Height.Value}" : null
};
}
else

View File

@ -50,8 +50,9 @@
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
</ItemGroup>
<ItemGroup>
<!--<Protobuf Include="Services/Lightning/proto/*.proto" GrpcServices="Client" ProtoRoot="Services/Lightning/proto" />-->
<ItemGroup><!--<Protobuf Include="Services/Lightning/proto/*.proto" GrpcServices="Client" ProtoRoot="Services/Lightning/proto" />-->
<Folder Include="wwwroot\" />
</ItemGroup>
<ItemGroup>
<!-- Don't publish the SPA source files, but do show them in the project files list -->
@ -90,9 +91,6 @@
</AssemblyAttributes>
<Compile Include="$(IntermediateOutputPath)\build_date.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="Migrations\" />
</ItemGroup>
<Target Name="GetBuildDate" BeforeTargets="CoreCompile">
<WriteCodeFragment Language="C#" OutputFile="$(IntermediateOutputPath)\build_date.cs" AssemblyAttributes="@(AssemblyAttributes)" />
</Target>

View File

@ -0,0 +1,20 @@
#!/usr/bin/env node
const { existsSync } = require(`fs`);
const { createRequire } = require(`module`);
const { resolve } = require(`path`);
const relPnpApiPath = "../../../../.pnp.cjs";
const absPnpApiPath = resolve(__dirname, relPnpApiPath);
const absRequire = createRequire(absPnpApiPath);
if (existsSync(absPnpApiPath)) {
if (!process.versions.pnp) {
// Setup the environment to be able to require eslint/use-at-your-own-risk
require(absPnpApiPath).setup();
}
}
// Defer to the real eslint/use-at-your-own-risk your application uses
module.exports = absRequire(`eslint/use-at-your-own-risk`);

View File

@ -2,5 +2,13 @@
"name": "eslint",
"version": "8.51.0-sdk",
"main": "./lib/api.js",
"type": "commonjs"
"type": "commonjs",
"bin": {
"eslint": "./bin/eslint.js"
},
"exports": {
"./package.json": "./package.json",
".": "./lib/api.js",
"./use-at-your-own-risk": "./lib/unsupported-api.js"
}
}

View File

@ -1,6 +1,7 @@
{
"name": "prettier",
"version": "3.0.3-sdk",
"main": "./index.js",
"type": "commonjs"
"main": "./index.cjs",
"type": "commonjs",
"bin": "./bin/prettier.cjs"
}

View File

@ -11,10 +11,10 @@ const absRequire = createRequire(absPnpApiPath);
if (existsSync(absPnpApiPath)) {
if (!process.versions.pnp) {
// Setup the environment to be able to require typescript/lib/typescript.js
// Setup the environment to be able to require typescript
require(absPnpApiPath).setup();
}
}
// Defer to the real typescript/lib/typescript.js your application uses
module.exports = absRequire(`typescript/lib/typescript.js`);
// Defer to the real typescript your application uses
module.exports = absRequire(`typescript`);

View File

@ -1,6 +1,10 @@
{
"name": "typescript",
"version": "5.2.2-sdk",
"version": "5.3.3-sdk",
"main": "./lib/typescript.js",
"type": "commonjs"
"type": "commonjs",
"bin": {
"tsc": "./bin/tsc",
"tsserver": "./bin/tsserver"
}
}

View File

@ -1,6 +1,6 @@
{
"name": "@void-cat/api",
"version": "1.0.11",
"version": "1.0.12",
"description": "void.cat API package",
"main": "dist/index.js",
"types": "dist/index.d.ts",
@ -9,7 +9,7 @@
"author": "Kieran",
"license": "MIT",
"scripts": {
"build": "rm -rf dist && tsc"
"build": "tsc"
},
"devDependencies": {
"@types/sjcl": "^1.0.30",

View File

@ -1,192 +1,192 @@
import {
AdminProfile,
AdminUserListResult,
ApiError,
ApiKey,
LoginSession,
PagedRequest,
PagedResponse,
PaymentOrder,
Profile,
SetPaymentConfigRequest,
SiteInfoResponse,
VoidFileResponse,
AdminProfile,
AdminUserListResult,
ApiError,
ApiKey,
LoginSession,
PagedRequest,
PagedResponse,
PaymentOrder,
Profile,
SetPaymentConfigRequest,
SiteInfoResponse,
VoidFileResponse,
} from "./index";
import {
ProgressHandler,
ProxyChallengeHandler,
StateChangeHandler,
VoidUploader,
ProgressHandler,
ProxyChallengeHandler,
StateChangeHandler,
VoidUploader,
} from "./upload";
import {StreamUploader} from "./stream-uploader";
import {XHRUploader} from "./xhr-uploader";
import { StreamUploader } from "./stream-uploader";
import { XHRUploader } from "./xhr-uploader";
export type AuthHandler = (url: string, method: string) => Promise<string>;
export class VoidApi {
readonly #uri: string;
readonly #auth?: AuthHandler;
readonly #uri: string;
readonly #auth?: AuthHandler;
constructor(uri?: string, auth?: AuthHandler) {
this.#uri = uri ?? "";
this.#auth = auth;
constructor(uri?: string, auth?: AuthHandler) {
this.#uri = uri ?? "";
this.#auth = auth;
}
async #req<T>(method: string, url: string, body?: object): Promise<T> {
const absoluteUrl = `${this.#uri}${url}`;
const headers: HeadersInit = {
Accept: "application/json",
};
if (this.#auth) {
headers["Authorization"] = await this.#auth(absoluteUrl, method);
}
if (body) {
headers["Content-Type"] = "application/json";
}
async #req<T>(method: string, url: string, body?: object): Promise<T> {
const absoluteUrl = `${this.#uri}${url}`;
const headers: HeadersInit = {
Accept: "application/json",
};
if (this.#auth) {
headers["Authorization"] = await this.#auth(absoluteUrl, method);
}
if (body) {
headers["Content-Type"] = "application/json";
}
const res = await fetch(absoluteUrl, {
method,
headers,
mode: "cors",
body: body ? JSON.stringify(body) : undefined,
});
const text = await res.text();
if (res.ok) {
return text ? (JSON.parse(text) as T) : ({} as T);
} else {
throw new ApiError(res.status, text);
}
const res = await fetch(absoluteUrl, {
method,
headers,
mode: "cors",
body: body ? JSON.stringify(body) : undefined,
});
const text = await res.text();
if (res.ok) {
return text ? (JSON.parse(text) as T) : ({} as T);
} else {
throw new ApiError(res.status, text);
}
}
/**
* Get uploader for uploading files
*/
getUploader(
file: File | Blob,
stateChange?: StateChangeHandler,
progress?: ProgressHandler,
proxyChallenge?: ProxyChallengeHandler,
chunkSize?: number,
): VoidUploader {
if (StreamUploader.canUse()) {
return new StreamUploader(
this.#uri,
file,
stateChange,
progress,
proxyChallenge,
this.#auth,
chunkSize,
);
} else {
return new XHRUploader(
this.#uri,
file,
stateChange,
progress,
proxyChallenge,
this.#auth,
chunkSize,
);
}
/**
* Get uploader for uploading files
*/
getUploader(
file: File | Blob,
stateChange?: StateChangeHandler,
progress?: ProgressHandler,
proxyChallenge?: ProxyChallengeHandler,
chunkSize?: number,
): VoidUploader {
if (StreamUploader.canUse()) {
return new StreamUploader(
this.#uri,
file,
stateChange,
progress,
proxyChallenge,
this.#auth,
chunkSize,
);
} else {
return new XHRUploader(
this.#uri,
file,
stateChange,
progress,
proxyChallenge,
this.#auth,
chunkSize,
);
}
}
/**
* General site information
*/
info() {
return this.#req<SiteInfoResponse>("GET", "/info");
}
/**
* General site information
*/
info() {
return this.#req<SiteInfoResponse>("GET", "/info");
}
fileInfo(id: string) {
return this.#req<VoidFileResponse>("GET", `/upload/${id}`);
}
fileInfo(id: string) {
return this.#req<VoidFileResponse>("GET", `/upload/${id}`);
}
setPaymentConfig(id: string, cfg: SetPaymentConfigRequest) {
return this.#req("POST", `/upload/${id}/payment`, cfg);
}
setPaymentConfig(id: string, cfg: SetPaymentConfigRequest) {
return this.#req("POST", `/upload/${id}/payment`, cfg);
}
createOrder(id: string) {
return this.#req<PaymentOrder>("GET", `/upload/${id}/payment`);
}
createOrder(id: string) {
return this.#req<PaymentOrder>("GET", `/upload/${id}/payment`);
}
getOrder(file: string, order: string) {
return this.#req<PaymentOrder>("GET", `/upload/${file}/payment/${order}`);
}
getOrder(file: string, order: string) {
return this.#req<PaymentOrder>("GET", `/upload/${file}/payment/${order}`);
}
login(username: string, password: string, captcha?: string) {
return this.#req<LoginSession>("POST", `/auth/login`, {
username,
password,
captcha,
});
}
login(username: string, password: string, captcha?: string) {
return this.#req<LoginSession>("POST", `/auth/login`, {
username,
password,
captcha,
});
}
register(username: string, password: string, captcha?: string) {
return this.#req<LoginSession>("POST", `/auth/register`, {
username,
password,
captcha,
});
}
register(username: string, password: string, captcha?: string) {
return this.#req<LoginSession>("POST", `/auth/register`, {
username,
password,
captcha,
});
}
getUser(id: string) {
return this.#req<Profile>("GET", `/user/${id}`);
}
getUser(id: string) {
return this.#req<Profile>("GET", `/user/${id}`);
}
updateUser(u: Profile) {
return this.#req<void>("POST", `/user/${u.id}`, u);
}
updateUser(u: Profile) {
return this.#req<void>("POST", `/user/${u.id}`, u);
}
listUserFiles(uid: string, pageReq: PagedRequest) {
return this.#req<PagedResponse<VoidFileResponse>>(
"POST",
`/user/${uid}/files`,
pageReq,
);
}
listUserFiles(uid: string, pageReq: PagedRequest) {
return this.#req<PagedResponse<VoidFileResponse>>(
"POST",
`/user/${uid}/files`,
pageReq,
);
}
submitVerifyCode(uid: string, code: string) {
return this.#req<void>("POST", `/user/${uid}/verify`, {code});
}
submitVerifyCode(uid: string, code: string) {
return this.#req<void>("POST", `/user/${uid}/verify`, { code });
}
sendNewCode(uid: string) {
return this.#req<void>("GET", `/user/${uid}/verify`);
}
sendNewCode(uid: string) {
return this.#req<void>("GET", `/user/${uid}/verify`);
}
updateFileMetadata(id: string, meta: any) {
return this.#req<void>("POST", `/upload/${id}/meta`, meta);
}
updateFileMetadata(id: string, meta: any) {
return this.#req<void>("POST", `/upload/${id}/meta`, meta);
}
listApiKeys() {
return this.#req<Array<ApiKey>>("GET", `/auth/api-key`);
}
listApiKeys() {
return this.#req<Array<ApiKey>>("GET", `/auth/api-key`);
}
createApiKey(req: any) {
return this.#req<ApiKey>("POST", `/auth/api-key`, req);
}
createApiKey(req: any) {
return this.#req<ApiKey>("POST", `/auth/api-key`, req);
}
adminListFiles(pageReq: PagedRequest) {
return this.#req<PagedResponse<VoidFileResponse>>(
"POST",
"/admin/file",
pageReq,
);
}
adminListFiles(pageReq: PagedRequest) {
return this.#req<PagedResponse<VoidFileResponse>>(
"POST",
"/admin/file",
pageReq,
);
}
adminDeleteFile(id: string) {
return this.#req<void>("DELETE", `/admin/file/${id}`);
}
adminDeleteFile(id: string) {
return this.#req<void>("DELETE", `/admin/file/${id}`);
}
adminUserList(pageReq: PagedRequest) {
return this.#req<PagedResponse<AdminUserListResult>>(
"POST",
`/admin/users`,
pageReq,
);
}
adminUserList(pageReq: PagedRequest) {
return this.#req<PagedResponse<AdminUserListResult>>(
"POST",
`/admin/users`,
pageReq,
);
}
adminUpdateUser(u: AdminProfile) {
return this.#req<void>("POST", `/admin/update-user`, u);
}
adminUpdateUser(u: AdminProfile) {
return this.#req<void>("POST", `/admin/update-user`, u);
}
}

View File

@ -104,6 +104,7 @@ export interface VoidFileMeta {
encryptionParams?: string;
magnetLink?: string;
storage: string;
mediaDimensions?: string;
}
export interface VirusScanStatus {

View File

@ -1,41 +1,34 @@
<svg xmlns="http://www.w3.org/2000/svg">
<defs>
<symbol id="link" viewBox="0 0 22 22" fill="none">
<path d="M8.99996 12C9.42941 12.5742 9.97731 13.0492 10.6065 13.393C11.2357 13.7367 11.9315 13.9411 12.6466 13.9924C13.3617 14.0436 14.0795 13.9404 14.7513 13.6898C15.4231 13.4392 16.0331 13.0471 16.54 12.54L19.54 9.54003C20.4507 8.59702 20.9547 7.334 20.9433 6.02302C20.9319 4.71204 20.4061 3.45797 19.479 2.53093C18.552 1.60389 17.2979 1.07805 15.987 1.06666C14.676 1.05526 13.413 1.55924 12.47 2.47003L10.75 4.18003M13 10C12.5705 9.4259 12.0226 8.95084 11.3934 8.60709C10.7642 8.26333 10.0684 8.05891 9.3533 8.00769C8.63816 7.95648 7.92037 8.05966 7.24861 8.31025C6.57685 8.56083 5.96684 8.95296 5.45996 9.46003L2.45996 12.46C1.54917 13.403 1.04519 14.666 1.05659 15.977C1.06798 17.288 1.59382 18.5421 2.52086 19.4691C3.4479 20.3962 4.70197 20.922 6.01295 20.9334C7.32393 20.9448 8.58694 20.4408 9.52995 19.53L11.24 17.82"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M8.99996 12C9.42941 12.5742 9.97731 13.0492 10.6065 13.393C11.2357 13.7367 11.9315 13.9411 12.6466 13.9924C13.3617 14.0436 14.0795 13.9404 14.7513 13.6898C15.4231 13.4392 16.0331 13.0471 16.54 12.54L19.54 9.54003C20.4507 8.59702 20.9547 7.334 20.9433 6.02302C20.9319 4.71204 20.4061 3.45797 19.479 2.53093C18.552 1.60389 17.2979 1.07805 15.987 1.06666C14.676 1.05526 13.413 1.55924 12.47 2.47003L10.75 4.18003M13 10C12.5705 9.4259 12.0226 8.95084 11.3934 8.60709C10.7642 8.26333 10.0684 8.05891 9.3533 8.00769C8.63816 7.95648 7.92037 8.05966 7.24861 8.31025C6.57685 8.56083 5.96684 8.95296 5.45996 9.46003L2.45996 12.46C1.54917 13.403 1.04519 14.666 1.05659 15.977C1.06798 17.288 1.59382 18.5421 2.52086 19.4691C3.4479 20.3962 4.70197 20.922 6.01295 20.9334C7.32393 20.9448 8.58694 20.4408 9.52995 19.53L11.24 17.82" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</symbol>
<symbol id="download" viewBox="0 0 20 20" fill="none">
<path d="M19 13V14.2C19 15.8802 19 16.7202 18.673 17.362C18.3854 17.9265 17.9265 18.3854 17.362 18.673C16.7202 19 15.8802 19 14.2 19H5.8C4.11984 19 3.27976 19 2.63803 18.673C2.07354 18.3854 1.6146 17.9265 1.32698 17.362C1 16.7202 1 15.8802 1 14.2V13M15 8L10 13M10 13L5 8M10 13V1"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M19 13V14.2C19 15.8802 19 16.7202 18.673 17.362C18.3854 17.9265 17.9265 18.3854 17.362 18.673C16.7202 19 15.8802 19 14.2 19H5.8C4.11984 19 3.27976 19 2.63803 18.673C2.07354 18.3854 1.6146 17.9265 1.32698 17.362C1 16.7202 1 15.8802 1 14.2V13M15 8L10 13M10 13L5 8M10 13V1" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</symbol>
<symbol id="file" viewBox="0 0 18 22" fill="none">
<path d="M11 1.26953V5.40007C11 5.96012 11 6.24015 11.109 6.45406C11.2049 6.64222 11.3578 6.7952 11.546 6.89108C11.7599 7.00007 12.0399 7.00007 12.6 7.00007H16.7305M11 16H5M13 12H5M17 8.98822V16.2C17 17.8802 17 18.7202 16.673 19.362C16.3854 19.9265 15.9265 20.3854 15.362 20.673C14.7202 21 13.8802 21 12.2 21H5.8C4.11984 21 3.27976 21 2.63803 20.673C2.07354 20.3854 1.6146 19.9265 1.32698 19.362C1 18.7202 1 17.8802 1 16.2V5.8C1 4.11984 1 3.27976 1.32698 2.63803C1.6146 2.07354 2.07354 1.6146 2.63803 1.32698C3.27976 1 4.11984 1 5.8 1H9.01178C9.74555 1 10.1124 1 10.4577 1.08289C10.7638 1.15638 11.0564 1.27759 11.3249 1.44208C11.6276 1.6276 11.887 1.88703 12.4059 2.40589L15.5941 5.59411C16.113 6.11297 16.3724 6.3724 16.5579 6.67515C16.7224 6.94356 16.8436 7.2362 16.9171 7.5423C17 7.88757 17 8.25445 17 8.98822Z"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M11 1.26953V5.40007C11 5.96012 11 6.24015 11.109 6.45406C11.2049 6.64222 11.3578 6.7952 11.546 6.89108C11.7599 7.00007 12.0399 7.00007 12.6 7.00007H16.7305M11 16H5M13 12H5M17 8.98822V16.2C17 17.8802 17 18.7202 16.673 19.362C16.3854 19.9265 15.9265 20.3854 15.362 20.673C14.7202 21 13.8802 21 12.2 21H5.8C4.11984 21 3.27976 21 2.63803 20.673C2.07354 20.3854 1.6146 19.9265 1.32698 19.362C1 18.7202 1 17.8802 1 16.2V5.8C1 4.11984 1 3.27976 1.32698 2.63803C1.6146 2.07354 2.07354 1.6146 2.63803 1.32698C3.27976 1 4.11984 1 5.8 1H9.01178C9.74555 1 10.1124 1 10.4577 1.08289C10.7638 1.15638 11.0564 1.27759 11.3249 1.44208C11.6276 1.6276 11.887 1.88703 12.4059 2.40589L15.5941 5.59411C16.113 6.11297 16.3724 6.3724 16.5579 6.67515C16.7224 6.94356 16.8436 7.2362 16.9171 7.5423C17 7.88757 17 8.25445 17 8.98822Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</symbol>
<symbol id="download-cloud" viewBox="0 0 22 20" fill="none">
<path d="M3 14.2422C1.79401 13.435 1 12.0602 1 10.5C1 8.15643 2.79151 6.23129 5.07974 6.01937C5.54781 3.17213 8.02024 1 11 1C13.9798 1 16.4522 3.17213 16.9203 6.01937C19.2085 6.23129 21 8.15643 21 10.5C21 12.0602 20.206 13.435 19 14.2422M7 15L11 19M11 19L15 15M11 19V10"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3 14.2422C1.79401 13.435 1 12.0602 1 10.5C1 8.15643 2.79151 6.23129 5.07974 6.01937C5.54781 3.17213 8.02024 1 11 1C13.9798 1 16.4522 3.17213 16.9203 6.01937C19.2085 6.23129 21 8.15643 21 10.5C21 12.0602 20.206 13.435 19 14.2422M7 15L11 19M11 19L15 15M11 19V10" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</symbol>
<symbol id="upload-cloud" viewBox="0 0 22 20" fill="none">
<path d="M3 14.2422C1.79401 13.435 1 12.0602 1 10.5C1 8.15643 2.79151 6.23129 5.07974 6.01937C5.54781 3.17213 8.02024 1 11 1C13.9798 1 16.4522 3.17213 16.9203 6.01937C19.2085 6.23129 21 8.15643 21 10.5C21 12.0602 20.206 13.435 19 14.2422M7 14L11 10M11 10L15 14M11 10V19"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3 14.2422C1.79401 13.435 1 12.0602 1 10.5C1 8.15643 2.79151 6.23129 5.07974 6.01937C5.54781 3.17213 8.02024 1 11 1C13.9798 1 16.4522 3.17213 16.9203 6.01937C19.2085 6.23129 21 8.15643 21 10.5C21 12.0602 20.206 13.435 19 14.2422M7 14L11 10M11 10L15 14M11 10V19" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</symbol>
<symbol id="save" viewBox="0 0 20 20" fill="none">
<path d="M5 1V4.4C5 4.96005 5 5.24008 5.10899 5.45399C5.20487 5.64215 5.35785 5.79513 5.54601 5.89101C5.75992 6 6.03995 6 6.6 6H13.4C13.9601 6 14.2401 6 14.454 5.89101C14.6422 5.79513 14.7951 5.64215 14.891 5.45399C15 5.24008 15 4.96005 15 4.4V2M15 19V12.6C15 12.0399 15 11.7599 14.891 11.546C14.7951 11.3578 14.6422 11.2049 14.454 11.109C14.2401 11 13.9601 11 13.4 11H6.6C6.03995 11 5.75992 11 5.54601 11.109C5.35785 11.2049 5.20487 11.3578 5.10899 11.546C5 11.7599 5 12.0399 5 12.6V19M19 7.32548V14.2C19 15.8802 19 16.7202 18.673 17.362C18.3854 17.9265 17.9265 18.3854 17.362 18.673C16.7202 19 15.8802 19 14.2 19H5.8C4.11984 19 3.27976 19 2.63803 18.673C2.07354 18.3854 1.6146 17.9265 1.32698 17.362C1 16.7202 1 15.8802 1 14.2V5.8C1 4.11984 1 3.27976 1.32698 2.63803C1.6146 2.07354 2.07354 1.6146 2.63803 1.32698C3.27976 1 4.11984 1 5.8 1H12.6745C13.1637 1 13.4083 1 13.6385 1.05526C13.8425 1.10425 14.0376 1.18506 14.2166 1.29472C14.4184 1.4184 14.5914 1.59135 14.9373 1.93726L18.0627 5.06274C18.4086 5.40865 18.5816 5.5816 18.7053 5.78343C18.8149 5.96237 18.8957 6.15746 18.9447 6.36154C19 6.59171 19 6.8363 19 7.32548Z"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M5 1V4.4C5 4.96005 5 5.24008 5.10899 5.45399C5.20487 5.64215 5.35785 5.79513 5.54601 5.89101C5.75992 6 6.03995 6 6.6 6H13.4C13.9601 6 14.2401 6 14.454 5.89101C14.6422 5.79513 14.7951 5.64215 14.891 5.45399C15 5.24008 15 4.96005 15 4.4V2M15 19V12.6C15 12.0399 15 11.7599 14.891 11.546C14.7951 11.3578 14.6422 11.2049 14.454 11.109C14.2401 11 13.9601 11 13.4 11H6.6C6.03995 11 5.75992 11 5.54601 11.109C5.35785 11.2049 5.20487 11.3578 5.10899 11.546C5 11.7599 5 12.0399 5 12.6V19M19 7.32548V14.2C19 15.8802 19 16.7202 18.673 17.362C18.3854 17.9265 17.9265 18.3854 17.362 18.673C16.7202 19 15.8802 19 14.2 19H5.8C4.11984 19 3.27976 19 2.63803 18.673C2.07354 18.3854 1.6146 17.9265 1.32698 17.362C1 16.7202 1 15.8802 1 14.2V5.8C1 4.11984 1 3.27976 1.32698 2.63803C1.6146 2.07354 2.07354 1.6146 2.63803 1.32698C3.27976 1 4.11984 1 5.8 1H12.6745C13.1637 1 13.4083 1 13.6385 1.05526C13.8425 1.10425 14.0376 1.18506 14.2166 1.29472C14.4184 1.4184 14.5914 1.59135 14.9373 1.93726L18.0627 5.06274C18.4086 5.40865 18.5816 5.5816 18.7053 5.78343C18.8149 5.96237 18.8957 6.15746 18.9447 6.36154C19 6.59171 19 6.8363 19 7.32548Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</symbol>
<symbol id="hash" viewBox="0 0 18 20" fill="none">
<path d="M1 6H17M1 14H17M5 1V19M13 1V19" stroke="currentColor" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round"/>
<path d="M1 6H17M1 14H17M5 1V19M13 1V19" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</symbol>
<symbol id="check-circle" viewBox="0 0 22 22" fill="none">
<path d="M6.5 11L9.5 14L15.5 8M21 11C21 16.5228 16.5228 21 11 21C5.47715 21 1 16.5228 1 11C1 5.47715 5.47715 1 11 1C16.5228 1 21 5.47715 21 11Z"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M6.5 11L9.5 14L15.5 8M21 11C21 16.5228 16.5228 21 11 21C5.47715 21 1 16.5228 1 11C1 5.47715 5.47715 1 11 1C16.5228 1 21 5.47715 21 11Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</symbol>
<symbol id="alert-circle" viewBox="0 0 22 22" fill="none">
<path d="M11 7V11M11 15H11.01M21 11C21 16.5228 16.5228 21 11 21C5.47715 21 1 16.5228 1 11C1 5.47715 5.47715 1 11 1C16.5228 1 21 5.47715 21 11Z"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M11 7V11M11 15H11.01M21 11C21 16.5228 16.5228 21 11 21C5.47715 21 1 16.5228 1 11C1 5.47715 5.47715 1 11 1C16.5228 1 21 5.47715 21 11Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</symbol>
<symbol id="trash" viewBox="0 0 20 22" fill="none">
<path d="M14 5V4.2C14 3.0799 14 2.51984 13.782 2.09202C13.5903 1.71569 13.2843 1.40973 12.908 1.21799C12.4802 1 11.9201 1 10.8 1H9.2C8.07989 1 7.51984 1 7.09202 1.21799C6.71569 1.40973 6.40973 1.71569 6.21799 2.09202C6 2.51984 6 3.0799 6 4.2V5M8 10.5V15.5M12 10.5V15.5M1 5H19M17 5V16.2C17 17.8802 17 18.7202 16.673 19.362C16.3854 19.9265 15.9265 20.3854 15.362 20.673C14.7202 21 13.8802 21 12.2 21H7.8C6.11984 21 5.27976 21 4.63803 20.673C4.07354 20.3854 3.6146 19.9265 3.32698 19.362C3 18.7202 3 17.8802 3 16.2V5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</symbol>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@ -1,18 +1,18 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<link rel="icon" href="/logo_32.png"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta name="theme-color" content="#000000"/>
<meta name="description" content="void.cat - free, simple file sharing."/>
<link rel="apple-touch-icon" href="/logo_256.png"/>
<link rel="manifest" href="/manifest.json"/>
<head>
<meta charset="utf-8" />
<link rel="icon" href="/logo_32.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="void.cat - free, simple file sharing." />
<link rel="apple-touch-icon" href="/logo_256.png" />
<link rel="manifest" href="/manifest.json" />
<title>void.cat</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script src="./src/index.tsx" type="module"></script>
</body>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script src="./src/index.tsx" type="module"></script>
</body>
</html>

View File

@ -2,7 +2,6 @@
"name": "@void-cat/app",
"version": "0.1.0",
"private": true,
"proxy": "http://localhost:7195",
"dependencies": {
"@hcaptcha/react-hcaptcha": "^1.1.1",
"@reduxjs/toolkit": "^1.7.2",
@ -27,16 +26,19 @@
"@types/react-redux": "^7.1.26",
"@types/sjcl": "^1.0.30",
"@vitejs/plugin-react": "^4.2.1",
"autoprefixer": "^10.4.16",
"eslint": "^8.47.0",
"eslint-config-react-app": "^7.0.1",
"postcss": "^8.4.32",
"rollup-plugin-visualizer": "^5.11.0",
"tailwindcss": "^3.4.0",
"typescript": "^5.3.3",
"vite": "^5.0.10",
"vite-plugin-pwa": "^0.17.4",
"vite-plugin-version-mark": "^0.0.10"
},
"scripts": {
"start": "vite start",
"start": "vite",
"build": "vite build"
},
"eslintConfig": {

View File

@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};

View File

@ -1,41 +1,34 @@
<svg xmlns="http://www.w3.org/2000/svg">
<defs>
<symbol id="link" viewBox="0 0 22 22" fill="none">
<path d="M8.99996 12C9.42941 12.5742 9.97731 13.0492 10.6065 13.393C11.2357 13.7367 11.9315 13.9411 12.6466 13.9924C13.3617 14.0436 14.0795 13.9404 14.7513 13.6898C15.4231 13.4392 16.0331 13.0471 16.54 12.54L19.54 9.54003C20.4507 8.59702 20.9547 7.334 20.9433 6.02302C20.9319 4.71204 20.4061 3.45797 19.479 2.53093C18.552 1.60389 17.2979 1.07805 15.987 1.06666C14.676 1.05526 13.413 1.55924 12.47 2.47003L10.75 4.18003M13 10C12.5705 9.4259 12.0226 8.95084 11.3934 8.60709C10.7642 8.26333 10.0684 8.05891 9.3533 8.00769C8.63816 7.95648 7.92037 8.05966 7.24861 8.31025C6.57685 8.56083 5.96684 8.95296 5.45996 9.46003L2.45996 12.46C1.54917 13.403 1.04519 14.666 1.05659 15.977C1.06798 17.288 1.59382 18.5421 2.52086 19.4691C3.4479 20.3962 4.70197 20.922 6.01295 20.9334C7.32393 20.9448 8.58694 20.4408 9.52995 19.53L11.24 17.82"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M8.99996 12C9.42941 12.5742 9.97731 13.0492 10.6065 13.393C11.2357 13.7367 11.9315 13.9411 12.6466 13.9924C13.3617 14.0436 14.0795 13.9404 14.7513 13.6898C15.4231 13.4392 16.0331 13.0471 16.54 12.54L19.54 9.54003C20.4507 8.59702 20.9547 7.334 20.9433 6.02302C20.9319 4.71204 20.4061 3.45797 19.479 2.53093C18.552 1.60389 17.2979 1.07805 15.987 1.06666C14.676 1.05526 13.413 1.55924 12.47 2.47003L10.75 4.18003M13 10C12.5705 9.4259 12.0226 8.95084 11.3934 8.60709C10.7642 8.26333 10.0684 8.05891 9.3533 8.00769C8.63816 7.95648 7.92037 8.05966 7.24861 8.31025C6.57685 8.56083 5.96684 8.95296 5.45996 9.46003L2.45996 12.46C1.54917 13.403 1.04519 14.666 1.05659 15.977C1.06798 17.288 1.59382 18.5421 2.52086 19.4691C3.4479 20.3962 4.70197 20.922 6.01295 20.9334C7.32393 20.9448 8.58694 20.4408 9.52995 19.53L11.24 17.82" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</symbol>
<symbol id="download" viewBox="0 0 20 20" fill="none">
<path d="M19 13V14.2C19 15.8802 19 16.7202 18.673 17.362C18.3854 17.9265 17.9265 18.3854 17.362 18.673C16.7202 19 15.8802 19 14.2 19H5.8C4.11984 19 3.27976 19 2.63803 18.673C2.07354 18.3854 1.6146 17.9265 1.32698 17.362C1 16.7202 1 15.8802 1 14.2V13M15 8L10 13M10 13L5 8M10 13V1"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M19 13V14.2C19 15.8802 19 16.7202 18.673 17.362C18.3854 17.9265 17.9265 18.3854 17.362 18.673C16.7202 19 15.8802 19 14.2 19H5.8C4.11984 19 3.27976 19 2.63803 18.673C2.07354 18.3854 1.6146 17.9265 1.32698 17.362C1 16.7202 1 15.8802 1 14.2V13M15 8L10 13M10 13L5 8M10 13V1" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</symbol>
<symbol id="file" viewBox="0 0 18 22" fill="none">
<path d="M11 1.26953V5.40007C11 5.96012 11 6.24015 11.109 6.45406C11.2049 6.64222 11.3578 6.7952 11.546 6.89108C11.7599 7.00007 12.0399 7.00007 12.6 7.00007H16.7305M11 16H5M13 12H5M17 8.98822V16.2C17 17.8802 17 18.7202 16.673 19.362C16.3854 19.9265 15.9265 20.3854 15.362 20.673C14.7202 21 13.8802 21 12.2 21H5.8C4.11984 21 3.27976 21 2.63803 20.673C2.07354 20.3854 1.6146 19.9265 1.32698 19.362C1 18.7202 1 17.8802 1 16.2V5.8C1 4.11984 1 3.27976 1.32698 2.63803C1.6146 2.07354 2.07354 1.6146 2.63803 1.32698C3.27976 1 4.11984 1 5.8 1H9.01178C9.74555 1 10.1124 1 10.4577 1.08289C10.7638 1.15638 11.0564 1.27759 11.3249 1.44208C11.6276 1.6276 11.887 1.88703 12.4059 2.40589L15.5941 5.59411C16.113 6.11297 16.3724 6.3724 16.5579 6.67515C16.7224 6.94356 16.8436 7.2362 16.9171 7.5423C17 7.88757 17 8.25445 17 8.98822Z"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M11 1.26953V5.40007C11 5.96012 11 6.24015 11.109 6.45406C11.2049 6.64222 11.3578 6.7952 11.546 6.89108C11.7599 7.00007 12.0399 7.00007 12.6 7.00007H16.7305M11 16H5M13 12H5M17 8.98822V16.2C17 17.8802 17 18.7202 16.673 19.362C16.3854 19.9265 15.9265 20.3854 15.362 20.673C14.7202 21 13.8802 21 12.2 21H5.8C4.11984 21 3.27976 21 2.63803 20.673C2.07354 20.3854 1.6146 19.9265 1.32698 19.362C1 18.7202 1 17.8802 1 16.2V5.8C1 4.11984 1 3.27976 1.32698 2.63803C1.6146 2.07354 2.07354 1.6146 2.63803 1.32698C3.27976 1 4.11984 1 5.8 1H9.01178C9.74555 1 10.1124 1 10.4577 1.08289C10.7638 1.15638 11.0564 1.27759 11.3249 1.44208C11.6276 1.6276 11.887 1.88703 12.4059 2.40589L15.5941 5.59411C16.113 6.11297 16.3724 6.3724 16.5579 6.67515C16.7224 6.94356 16.8436 7.2362 16.9171 7.5423C17 7.88757 17 8.25445 17 8.98822Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</symbol>
<symbol id="download-cloud" viewBox="0 0 22 20" fill="none">
<path d="M3 14.2422C1.79401 13.435 1 12.0602 1 10.5C1 8.15643 2.79151 6.23129 5.07974 6.01937C5.54781 3.17213 8.02024 1 11 1C13.9798 1 16.4522 3.17213 16.9203 6.01937C19.2085 6.23129 21 8.15643 21 10.5C21 12.0602 20.206 13.435 19 14.2422M7 15L11 19M11 19L15 15M11 19V10"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3 14.2422C1.79401 13.435 1 12.0602 1 10.5C1 8.15643 2.79151 6.23129 5.07974 6.01937C5.54781 3.17213 8.02024 1 11 1C13.9798 1 16.4522 3.17213 16.9203 6.01937C19.2085 6.23129 21 8.15643 21 10.5C21 12.0602 20.206 13.435 19 14.2422M7 15L11 19M11 19L15 15M11 19V10" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</symbol>
<symbol id="upload-cloud" viewBox="0 0 22 20" fill="none">
<path d="M3 14.2422C1.79401 13.435 1 12.0602 1 10.5C1 8.15643 2.79151 6.23129 5.07974 6.01937C5.54781 3.17213 8.02024 1 11 1C13.9798 1 16.4522 3.17213 16.9203 6.01937C19.2085 6.23129 21 8.15643 21 10.5C21 12.0602 20.206 13.435 19 14.2422M7 14L11 10M11 10L15 14M11 10V19"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3 14.2422C1.79401 13.435 1 12.0602 1 10.5C1 8.15643 2.79151 6.23129 5.07974 6.01937C5.54781 3.17213 8.02024 1 11 1C13.9798 1 16.4522 3.17213 16.9203 6.01937C19.2085 6.23129 21 8.15643 21 10.5C21 12.0602 20.206 13.435 19 14.2422M7 14L11 10M11 10L15 14M11 10V19" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</symbol>
<symbol id="save" viewBox="0 0 20 20" fill="none">
<path d="M5 1V4.4C5 4.96005 5 5.24008 5.10899 5.45399C5.20487 5.64215 5.35785 5.79513 5.54601 5.89101C5.75992 6 6.03995 6 6.6 6H13.4C13.9601 6 14.2401 6 14.454 5.89101C14.6422 5.79513 14.7951 5.64215 14.891 5.45399C15 5.24008 15 4.96005 15 4.4V2M15 19V12.6C15 12.0399 15 11.7599 14.891 11.546C14.7951 11.3578 14.6422 11.2049 14.454 11.109C14.2401 11 13.9601 11 13.4 11H6.6C6.03995 11 5.75992 11 5.54601 11.109C5.35785 11.2049 5.20487 11.3578 5.10899 11.546C5 11.7599 5 12.0399 5 12.6V19M19 7.32548V14.2C19 15.8802 19 16.7202 18.673 17.362C18.3854 17.9265 17.9265 18.3854 17.362 18.673C16.7202 19 15.8802 19 14.2 19H5.8C4.11984 19 3.27976 19 2.63803 18.673C2.07354 18.3854 1.6146 17.9265 1.32698 17.362C1 16.7202 1 15.8802 1 14.2V5.8C1 4.11984 1 3.27976 1.32698 2.63803C1.6146 2.07354 2.07354 1.6146 2.63803 1.32698C3.27976 1 4.11984 1 5.8 1H12.6745C13.1637 1 13.4083 1 13.6385 1.05526C13.8425 1.10425 14.0376 1.18506 14.2166 1.29472C14.4184 1.4184 14.5914 1.59135 14.9373 1.93726L18.0627 5.06274C18.4086 5.40865 18.5816 5.5816 18.7053 5.78343C18.8149 5.96237 18.8957 6.15746 18.9447 6.36154C19 6.59171 19 6.8363 19 7.32548Z"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M5 1V4.4C5 4.96005 5 5.24008 5.10899 5.45399C5.20487 5.64215 5.35785 5.79513 5.54601 5.89101C5.75992 6 6.03995 6 6.6 6H13.4C13.9601 6 14.2401 6 14.454 5.89101C14.6422 5.79513 14.7951 5.64215 14.891 5.45399C15 5.24008 15 4.96005 15 4.4V2M15 19V12.6C15 12.0399 15 11.7599 14.891 11.546C14.7951 11.3578 14.6422 11.2049 14.454 11.109C14.2401 11 13.9601 11 13.4 11H6.6C6.03995 11 5.75992 11 5.54601 11.109C5.35785 11.2049 5.20487 11.3578 5.10899 11.546C5 11.7599 5 12.0399 5 12.6V19M19 7.32548V14.2C19 15.8802 19 16.7202 18.673 17.362C18.3854 17.9265 17.9265 18.3854 17.362 18.673C16.7202 19 15.8802 19 14.2 19H5.8C4.11984 19 3.27976 19 2.63803 18.673C2.07354 18.3854 1.6146 17.9265 1.32698 17.362C1 16.7202 1 15.8802 1 14.2V5.8C1 4.11984 1 3.27976 1.32698 2.63803C1.6146 2.07354 2.07354 1.6146 2.63803 1.32698C3.27976 1 4.11984 1 5.8 1H12.6745C13.1637 1 13.4083 1 13.6385 1.05526C13.8425 1.10425 14.0376 1.18506 14.2166 1.29472C14.4184 1.4184 14.5914 1.59135 14.9373 1.93726L18.0627 5.06274C18.4086 5.40865 18.5816 5.5816 18.7053 5.78343C18.8149 5.96237 18.8957 6.15746 18.9447 6.36154C19 6.59171 19 6.8363 19 7.32548Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</symbol>
<symbol id="hash" viewBox="0 0 18 20" fill="none">
<path d="M1 6H17M1 14H17M5 1V19M13 1V19" stroke="currentColor" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round"/>
<path d="M1 6H17M1 14H17M5 1V19M13 1V19" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</symbol>
<symbol id="check-circle" viewBox="0 0 22 22" fill="none">
<path d="M6.5 11L9.5 14L15.5 8M21 11C21 16.5228 16.5228 21 11 21C5.47715 21 1 16.5228 1 11C1 5.47715 5.47715 1 11 1C16.5228 1 21 5.47715 21 11Z"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M6.5 11L9.5 14L15.5 8M21 11C21 16.5228 16.5228 21 11 21C5.47715 21 1 16.5228 1 11C1 5.47715 5.47715 1 11 1C16.5228 1 21 5.47715 21 11Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</symbol>
<symbol id="alert-circle" viewBox="0 0 22 22" fill="none">
<path d="M11 7V11M11 15H11.01M21 11C21 16.5228 16.5228 21 11 21C5.47715 21 1 16.5228 1 11C1 5.47715 5.47715 1 11 1C16.5228 1 21 5.47715 21 11Z"
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M11 7V11M11 15H11.01M21 11C21 16.5228 16.5228 21 11 21C5.47715 21 1 16.5228 1 11C1 5.47715 5.47715 1 11 1C16.5228 1 21 5.47715 21 11Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</symbol>
<symbol id="trash" viewBox="0 0 20 22" fill="none">
<path d="M14 5V4.2C14 3.0799 14 2.51984 13.782 2.09202C13.5903 1.71569 13.2843 1.40973 12.908 1.21799C12.4802 1 11.9201 1 10.8 1H9.2C8.07989 1 7.51984 1 7.09202 1.21799C6.71569 1.40973 6.40973 1.71569 6.21799 2.09202C6 2.51984 6 3.0799 6 4.2V5M8 10.5V15.5M12 10.5V15.5M1 5H19M17 5V16.2C17 17.8802 17 18.7202 16.673 19.362C16.3854 19.9265 15.9265 20.3854 15.362 20.673C14.7202 21 13.8802 21 12.2 21H7.8C6.11984 21 5.27976 21 4.63803 20.673C4.07354 20.3854 3.6146 19.9265 3.32698 19.362C3 18.7202 3 17.8802 3 16.2V5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</symbol>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@ -12,6 +12,7 @@ import EditUser from "./EditUser";
import useApi from "@/Hooks/UseApi";
import { RootState } from "@/Store";
import ImageGrid from "@/Components/Shared/ImageGrid";
import { IconButton } from "@/Components/Shared/Icon";
export function Admin() {
const auth = useSelector((state: RootState) => state.login.jwt);
@ -45,7 +46,21 @@ export function Admin() {
/>
<h2>Files</h2>
<ImageGrid loadPage={(r) => AdminApi.adminListFiles(r)} />
<ImageGrid
loadPage={(r) => AdminApi.adminListFiles(r)}
actions={(f) => (
<>
<IconButton
name="trash"
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
deleteFile(f.id);
}}
/>
</>
)}
/>
{editUser && (
<VoidModal title="Edit user">

View File

@ -34,7 +34,12 @@ const router = createBrowserRouter([
path: "/u/:id",
loader: async ({ params }: LoaderFunctionArgs) => {
const state = store.getState();
const api = new VoidApi(import.meta.env.VITE_API_HOST, state.login.jwt ? () => Promise.resolve(`Bearer ${state.login.jwt}`) : undefined);
const api = new VoidApi(
import.meta.env.VITE_API_HOST,
state.login.jwt
? () => Promise.resolve(`Bearer ${state.login.jwt}`)
: undefined,
);
if (params.id) {
try {
return await api.getUser(params.id);

View File

@ -89,7 +89,7 @@ export function FileEdit({ file }: FileEditProps) {
return (
<div className="file-edit flex">
<div className="flx-1">
<div className="flex-1">
<h3>File info</h3>
<dl>
<dt>Filename:</dt>
@ -131,7 +131,7 @@ export function FileEdit({ file }: FileEditProps) {
Save
</VoidButton>
</div>
<div className="flx-1">
<div className="flex-1">
<h3>Payment Config</h3>
Type:
<select

View File

@ -1,20 +0,0 @@
.footer {
margin-top: 15px;
text-align: center;
}
.footer > a {
margin-left: 10px;
padding-right: 10px;
border-right: 1px solid;
}
.footer > a:last-child {
border: none;
}
.footer > a > img {
filter: invert(1);
vertical-align: middle;
height: 20px;
}

View File

@ -1,4 +1,3 @@
import "./FooterLinks.css";
import { useSelector } from "react-redux";
import { Link } from "react-router-dom";
@ -8,7 +7,7 @@ export function FooterLinks() {
const profile = useSelector((s: RootState) => s.login.profile);
return (
<div className="footer">
<footer className="flex gap-4 items-center justify-center">
<a href="https://discord.gg/8BkxTGs" target="_blank" rel="noreferrer">
Discord
</a>
@ -21,6 +20,6 @@ export function FooterLinks() {
</a>
<Link to="/donate">Donate</Link>
{profile?.roles?.includes("Admin") ? <a href="/admin">Admin</a> : null}
</div>
</footer>
);
}

View File

@ -1,41 +0,0 @@
.stats {
display: grid;
grid-auto-flow: column;
margin: 0 30px;
line-height: 32px;
text-align: center;
}
.stats svg {
vertical-align: middle;
margin-right: 10px;
}
.stats > div {
}
@media (max-width: 900px) {
.stats {
margin: 0 5px;
font-size: 14px;
}
.stats svg {
height: 16px;
width: 16px;
}
.build-info {
width: 100vw;
}
}
.build-info {
position: fixed;
left: 0;
bottom: 0;
color: #888;
text-align: center;
font-size: x-small;
padding: 10px;
}

View File

@ -1,6 +1,4 @@
import "./GlobalStats.css";
import { Fragment } from "react";
import moment from "moment";
import moment from "moment";
import { useSelector } from "react-redux";
import Icon from "@/Components/Shared/Icon";
@ -11,32 +9,32 @@ export function GlobalStats() {
let stats = useSelector((s: RootState) => s.info.info);
return (
<Fragment>
<dl className="stats">
<div>
<>
<div className="flex justify-around py-2">
<div className="flex gap-2 items-center">
<Icon name="upload-cloud" />
{FormatBytes(stats?.bandwidth?.ingress ?? 0, 2)}
</div>
<div>
<div className="flex gap-2 items-center">
<Icon name="download-cloud" />
{FormatBytes(stats?.bandwidth?.egress ?? 0, 2)}
</div>
<div>
<div className="flex gap-2 items-center">
<Icon name="save" />
{FormatBytes(stats?.totalBytes ?? 0, 2)}
</div>
<div>
<div className="flex gap-2 items-center">
<Icon name="hash" />
{stats?.count ?? 0}
{(stats?.count ?? 0).toLocaleString()}
</div>
</dl>
</div>
{stats?.buildInfo && (
<div className="build-info">
<div className="fixed bottom-2 left-2 text-xs text-slate-700">
{stats.buildInfo.version}-{stats.buildInfo.gitHash}
<br />
{moment(stats.buildInfo.buildTime).fromNow()}
</div>
)}
</Fragment>
</>
);
}

View File

@ -1,4 +1,4 @@
import { Bar, BarChart, Tooltip, XAxis } from "recharts";
import { Bar, BarChart, ResponsiveContainer, Tooltip, XAxis } from "recharts";
import moment from "moment";
import { BandwidthPoint } from "@void-cat/api";
@ -11,24 +11,24 @@ export function MetricsGraph({ metrics }: MetricsGraphProps) {
if (!metrics || metrics.length === 0) return null;
return (
<BarChart
width={Math.min(window.innerWidth, 900)}
height={200}
data={metrics}
margin={{ left: 0, right: 0 }}
style={{ userSelect: "none" }}
>
<XAxis
dataKey="time"
tickFormatter={(v) => `${moment(v).format("DD-MMM")}`}
/>
<Bar dataKey="egress" fill="#ccc" />
<Tooltip
formatter={(v) => FormatBytes(v as number)}
labelStyle={{ color: "#aaa" }}
itemStyle={{ color: "#eee" }}
contentStyle={{ backgroundColor: "#111" }}
/>
</BarChart>
<ResponsiveContainer height={200}>
<BarChart
data={metrics}
margin={{ left: 0, right: 0 }}
style={{ userSelect: "none" }}
>
<XAxis
dataKey="time"
tickFormatter={(v) => `${moment(v).format("DD-MMM")}`}
/>
<Bar dataKey="egress" fill="#ccc" />
<Tooltip
formatter={(v) => FormatBytes(v as number)}
labelStyle={{ color: "#aaa" }}
itemStyle={{ color: "#eee" }}
contentStyle={{ backgroundColor: "#111" }}
/>
</BarChart>
</ResponsiveContainer>
);
}

View File

@ -44,7 +44,7 @@ export default function ApiKeyList() {
return (
<>
<div className="flex flex-center">
<div className="flx-grow">
<div className="grow">
<h1>API Keys</h1>
</div>
<div>

View File

@ -1,16 +0,0 @@
.header {
user-select: none;
display: flex;
padding: 5px 0;
align-items: center;
}
.header .title {
font-size: 30px;
line-height: 2;
flex-grow: 1;
}
.header img.logo {
height: 80px;
}

View File

@ -1,5 +1,3 @@
import "./Header.css";
import { useEffect } from "react";
import { Link } from "react-router-dom";
import { useDispatch, useSelector } from "react-redux";
@ -48,11 +46,11 @@ export function Header() {
}, [jwt]);
return (
<div className="header page">
<img src="/logo_128.jpg" alt="logo" className="logo" />
<div className="title">
<Link to="/">{window.location.hostname}</Link>
</div>
<div className="flex justify-between items-center page">
<Link to="/" className="flex gap-2 items-center">
<img src="/logo_128.jpg" alt="logo" className="h-20" />
<div className="text-2xl">{window.location.hostname}</div>
</Link>
{profile ? (
<InlineProfile
profile={profile}

View File

@ -1,13 +1,11 @@
import { MouseEventHandler } from "react";
type Props = {
export interface IconProps {
name: string;
size?: number;
className?: string;
onClick?: MouseEventHandler<SVGSVGElement>;
};
onClick?: React.MouseEventHandler;
}
const Icon = (props: Props) => {
const Icon = (props: IconProps) => {
const size = props.size || 20;
const href = "/icons.svg#" + props.name;
@ -23,4 +21,14 @@ const Icon = (props: Props) => {
);
};
export function IconButton({ onClick, ...props }: IconProps) {
return (
<button
onClick={onClick}
className="p-2 bg-slate-800 rounded-xl hover:bg-slate-600"
>
<Icon {...props} />
</button>
);
}
export default Icon;

View File

@ -8,7 +8,7 @@ import {
PageSortOrder,
VoidFileResponse,
} from "@void-cat/api";
import { useEffect, useState } from "react";
import { useEffect, useState, ReactNode } from "react";
import { Link } from "react-router-dom";
import { useDispatch } from "react-redux";
@ -17,6 +17,7 @@ import { PageSelector } from "./PageSelector";
interface ImageGridProps {
loadPage: (req: PagedRequest) => Promise<PagedResponse<any>>;
actions?: (f: VoidFileResponse) => ReactNode;
}
export default function ImageGrid(props: ImageGridProps) {
@ -104,8 +105,13 @@ export default function ImageGrid(props: ImageGridProps) {
<>
<div className="image-grid">
{files?.results.map((v) => (
<Link key={v.id} to={`/${v.id}`}>
<Link key={v.id} to={`/${v.id}`} className="relative">
{renderPreview(v)}
{props.actions && (
<div className="absolute hover:opacity-100 h-full w-full opacity-0 border border-slate-600 flex flex-wrap gap-2 items-center justify-center bg-[rgba(0,0,0,0.5)]">
{props.actions(v)}
</div>
)}
</Link>
))}
</div>

View File

@ -3,8 +3,6 @@ import { CSSProperties } from "react";
import { Link } from "react-router-dom";
import { Profile } from "@void-cat/api";
import { DefaultAvatar } from "@/Const";
const DefaultSize = 64;
interface InlineProfileProps {
@ -24,8 +22,8 @@ export function InlineProfile({ profile, options }: InlineProfileProps) {
...options,
};
let avatarUrl = profile.avatar ?? DefaultAvatar;
if (!avatarUrl.startsWith("http")) {
let avatarUrl = profile.avatar ?? "/logo_256.jpg";
if (profile.avatar && !avatarUrl.startsWith("http")) {
avatarUrl = `/d/${avatarUrl}`;
}
let avatarStyles = {

View File

@ -1,5 +1,3 @@
export const DefaultAvatar = "https://i.imgur.com/8A5Fu65.jpeg";
/**
* @constant {number} - Size of 1 kiB
*/

View File

@ -5,5 +5,8 @@ import { RootState } from "@/Store";
export default function useApi() {
const auth = useSelector((s: RootState) => s.login.jwt);
return new VoidApi(import.meta.env.VITE_API_HOST, auth ? () => Promise.resolve(`Bearer ${auth}`) : undefined);
return new VoidApi(
import.meta.env.VITE_API_HOST,
auth ? () => Promise.resolve(`Bearer ${auth}`) : undefined,
);
}

View File

@ -248,7 +248,9 @@ export function FilePreview() {
useEffect(() => {
if (info) {
const fileLink = info.metadata?.url ?? `${import.meta.env.VITE_API_HOST ?? ""}/d/${info.id}`;
const fileLink =
info.metadata?.url ??
`${import.meta.env.VITE_API_HOST ?? ""}/d/${info.id}`;
setFileSize(info.metadata?.size ?? 0);
const order = window.localStorage.getItem(`payment-${info.id}`);
@ -274,8 +276,8 @@ export function FilePreview() {
{renderOpenGraphTags()}
</Helmet>
{renderVirusWarning()}
<div className="flex flex-center">
<div className="flx-grow">
<div className="flex items-center">
<div className="grow">
{info.uploader ? <InlineProfile profile={info.uploader} /> : null}
</div>
<div>
@ -308,12 +310,12 @@ export function FilePreview() {
{renderPayment()}
{renderPreview()}
{renderEncryptedDownload()}
<div className="file-stats">
<div>
<div className="flex justify-around py-2">
<div className="flex gap-2 items-center">
<Icon name="download-cloud" />
{FormatBytes(info?.bandwidth?.egress ?? 0, 2)}
</div>
<div>
<div className="flex gap-2 items-center">
<Icon name="save" />
{FormatBytes(info?.metadata?.size ?? 0, 2)}
</div>

View File

@ -7,7 +7,6 @@ import { Profile } from "@void-cat/api";
import useApi from "@/Hooks/UseApi";
import { RootState } from "@/Store";
import { DefaultAvatar } from "@/Const";
import { logout, setProfile as setGlobalProfile } from "@/LoginState";
import { FileList } from "@/Components/Shared/FileList";
@ -173,9 +172,8 @@ export function ProfilePage() {
}
if (profile) {
let avatarUrl = profile.avatar ?? DefaultAvatar;
if (!avatarUrl.startsWith("http")) {
// assume void-cat hosted avatar
let avatarUrl = profile.avatar ?? "/logo_256.jpg";
if (profile.avatar && !avatarUrl.startsWith("http")) {
avatarUrl = `/d/${avatarUrl}`;
}
let avatarStyles = {
@ -200,7 +198,7 @@ export function ProfilePage() {
)}
</div>
<div className="flex">
<div className="flx-1">
<div className="flex-1">
<div className="avatar" style={avatarStyles}>
{cantEditProfile ? (
<div className="edit-avatar" onClick={() => changeAvatar()}>
@ -209,7 +207,7 @@ export function ProfilePage() {
) : null}
</div>
</div>
<div className="flx-1">
<div className="flex-1">
<dl>
<dt>Created</dt>
<dd>{moment(profile.created).fromNow()}</dd>

View File

@ -1,14 +1,25 @@
@import url("https://fonts.googleapis.com/css2?family=Source+Code+Pro:wght@400;700&display=swap");
@tailwind base;
@tailwind components;
@tailwind utilities;
body {
margin: 0;
font-family: "Source Code Pro", monospace;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
background-color: black;
color: white;
}
h1 {
font-size: 2rem;
}
h2 {
font-size: 1.75rem;
}
h3 {
font-size: 1.5rem;
}
a {
color: white;
text-decoration: none;
@ -36,30 +47,6 @@ a:hover {
background-color: #666;
}
.flex {
display: flex;
}
.flex-inline {
display: inline-flex;
}
.flx-1 {
flex: 1;
}
.flx-2 {
flex: 2;
}
.flx-grow {
flex-grow: 1;
}
.flex-center {
align-items: center;
}
input[type="text"],
input[type="number"],
input[type="password"],
@ -72,6 +59,7 @@ select {
padding: 10px 20px;
margin: 5px;
border: 0;
color: black;
}
input[type="checkbox"] {

View File

@ -1,18 +0,0 @@
const { createProxyMiddleware } = require("http-proxy-middleware");
const settings = require("../package.json");
module.exports = function (app) {
const proxy = createProxyMiddleware({
target: settings.proxy,
changeOrigin: true,
secure: false,
});
app.use("/admin", proxy);
app.use("/d", proxy);
app.use("/info", proxy);
app.use("/upload", proxy);
app.use("/auth", proxy);
app.use("/swagger", proxy);
app.use("/user", proxy);
};

View File

@ -0,0 +1,8 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./index.html", "./src/**/*.{ts,tsx}"],
theme: {
extend: {},
},
plugins: [],
};

View File

@ -1,34 +1,38 @@
import react from "@vitejs/plugin-react";
import {visualizer} from "rollup-plugin-visualizer";
import {defineConfig} from "vite";
import {vitePluginVersionMark} from "vite-plugin-version-mark";
import { visualizer } from "rollup-plugin-visualizer";
import { defineConfig } from "vite";
import { vitePluginVersionMark } from "vite-plugin-version-mark";
export default defineConfig({
plugins: [
react(),
visualizer({
open: true,
gzipSize: true,
filename: "build/stats.html",
}),
vitePluginVersionMark({
name: "void_cat",
ifGitSHA: true,
command: "git describe --always --tags",
ifMeta: false,
}),
],
assetsInclude: [],
build: {
outDir: "build"
plugins: [
react(),
visualizer({
open: true,
gzipSize: true,
filename: "build/stats.html",
}),
vitePluginVersionMark({
name: "void_cat",
ifGitSHA: true,
command: "git describe --always --tags",
ifMeta: false,
}),
],
assetsInclude: [],
build: {
outDir: "build",
},
base: "/",
clearScreen: false,
resolve: {
alias: {
"@": "/src",
},
base: "/",
clearScreen: false,
resolve: {
alias: {
"@": "/src",
},
},
define: {},
server: {
proxy: {
"/d": "http://localhost:7195/",
},
define: {}
},
});

View File

@ -12,6 +12,13 @@ __metadata:
languageName: node
linkType: hard
"@alloc/quick-lru@npm:^5.2.0":
version: 5.2.0
resolution: "@alloc/quick-lru@npm:5.2.0"
checksum: bdc35758b552bcf045733ac047fb7f9a07c4678b944c641adfbd41f798b4b91fffd0fdc0df2578d9b0afc7b4d636aa6e110ead5d6281a2adc1ab90efd7f057f8
languageName: node
linkType: hard
"@ampproject/remapping@npm:^2.2.0":
version: 2.2.1
resolution: "@ampproject/remapping@npm:2.2.1"
@ -3274,19 +3281,6 @@ __metadata:
languageName: node
linkType: hard
"@types/babel__core@npm:^7.1.12":
version: 7.20.0
resolution: "@types/babel__core@npm:7.20.0"
dependencies:
"@babel/parser": "npm:^7.20.7"
"@babel/types": "npm:^7.20.7"
"@types/babel__generator": "npm:*"
"@types/babel__template": "npm:*"
"@types/babel__traverse": "npm:*"
checksum: b82e432bfc42075d4f6218e5ed5c4a7cdeb087e0416f969fc65a755c41d129d7e369c93e9a9dc59d43291327aa8d7cd149f3573d1c3b54d0192561d02bb225eb
languageName: node
linkType: hard
"@types/babel__core@npm:^7.20.5":
version: 7.20.5
resolution: "@types/babel__core@npm:7.20.5"
@ -3414,15 +3408,6 @@ __metadata:
languageName: node
linkType: hard
"@types/http-proxy@npm:^1.17.8":
version: 1.17.11
resolution: "@types/http-proxy@npm:1.17.11"
dependencies:
"@types/node": "npm:*"
checksum: 7cda456611b4adfdd87e4317745af643153d502576fb7095806d5b1b397b9a878b105e14abff9b7ab1d1c71132b61b5fc7052461f766165963950f1b46e18315
languageName: node
linkType: hard
"@types/json-schema@npm:^7.0.9":
version: 7.0.11
resolution: "@types/json-schema@npm:7.0.11"
@ -3458,13 +3443,6 @@ __metadata:
languageName: node
linkType: hard
"@types/preval.macro@npm:^3.0.0":
version: 3.0.0
resolution: "@types/preval.macro@npm:3.0.0"
checksum: 76aa51a31bb4632383763f283297c63f7dc664ea85e637ddd9b8a91c6583e690a0306d021dc7bdce52d1f3898f798cec5bb0ae9ae072b8999f1a79d56991616a
languageName: node
linkType: hard
"@types/prop-types@npm:*":
version: 15.7.5
resolution: "@types/prop-types@npm:15.7.5"
@ -3735,7 +3713,6 @@ __metadata:
"@hcaptcha/react-hcaptcha": "npm:^1.1.1"
"@reduxjs/toolkit": "npm:^1.7.2"
"@types/node": "npm:^20.5.3"
"@types/preval.macro": "npm:^3.0.0"
"@types/qrcode.react": "npm:^1.0.2"
"@types/react": "npm:^18.2.0"
"@types/react-dom": "npm:^18.2.1"
@ -3744,11 +3721,11 @@ __metadata:
"@types/sjcl": "npm:^1.0.30"
"@vitejs/plugin-react": "npm:^4.2.1"
"@void-cat/api": "npm:^1.0.10"
autoprefixer: "npm:^10.4.16"
eslint: "npm:^8.47.0"
eslint-config-react-app: "npm:^7.0.1"
http-proxy-middleware: "npm:^2.0.6"
moment: "npm:^2.29.4"
preval.macro: "npm:^5.0.0"
postcss: "npm:^8.4.32"
prop-types: "npm:^15.8.1"
qrcode.react: "npm:^3.1.0"
react: "npm:^18.2.0"
@ -3759,6 +3736,7 @@ __metadata:
recharts: "npm:^2.1.10"
rollup-plugin-visualizer: "npm:^5.11.0"
sjcl: "npm:^1.0.8"
tailwindcss: "npm:^3.4.0"
typescript: "npm:^5.3.3"
vite: "npm:^5.0.10"
vite-plugin-pwa: "npm:^0.17.4"
@ -3882,6 +3860,30 @@ __metadata:
languageName: node
linkType: hard
"any-promise@npm:^1.0.0":
version: 1.3.0
resolution: "any-promise@npm:1.3.0"
checksum: 6737469ba353b5becf29e4dc3680736b9caa06d300bda6548812a8fee63ae7d336d756f88572fa6b5219aed36698d808fa55f62af3e7e6845c7a1dc77d240edb
languageName: node
linkType: hard
"anymatch@npm:~3.1.2":
version: 3.1.3
resolution: "anymatch@npm:3.1.3"
dependencies:
normalize-path: "npm:^3.0.0"
picomatch: "npm:^2.0.4"
checksum: 3e044fd6d1d26545f235a9fe4d7a534e2029d8e59fa7fd9f2a6eb21230f6b5380ea1eaf55136e60cbf8e613544b3b766e7a6fa2102e2a3a117505466e3025dc2
languageName: node
linkType: hard
"arg@npm:^5.0.2":
version: 5.0.2
resolution: "arg@npm:5.0.2"
checksum: 92fe7de222054a060fd2329e92e867410b3ea260328147ee3fb7855f78efae005f4087e698d4e688a856893c56bb09951588c40f2c901cf6996cd8cd7bcfef2c
languageName: node
linkType: hard
"argparse@npm:^2.0.1":
version: 2.0.1
resolution: "argparse@npm:2.0.1"
@ -4001,6 +4003,24 @@ __metadata:
languageName: node
linkType: hard
"autoprefixer@npm:^10.4.16":
version: 10.4.16
resolution: "autoprefixer@npm:10.4.16"
dependencies:
browserslist: "npm:^4.21.10"
caniuse-lite: "npm:^1.0.30001538"
fraction.js: "npm:^4.3.6"
normalize-range: "npm:^0.1.2"
picocolors: "npm:^1.0.0"
postcss-value-parser: "npm:^4.2.0"
peerDependencies:
postcss: ^8.1.0
bin:
autoprefixer: bin/autoprefixer
checksum: 3514a4ae63f1f55006c96eb93acef4a0284d78b640d8f27d3178d40b302576e346619001ca139b4ddc5e7b0c5e66921aa45d8e3752d8d521598119aab8ff4997
languageName: node
linkType: hard
"available-typed-arrays@npm:^1.0.5":
version: 1.0.5
resolution: "available-typed-arrays@npm:1.0.5"
@ -4024,7 +4044,7 @@ __metadata:
languageName: node
linkType: hard
"babel-plugin-macros@npm:^3.0.1, babel-plugin-macros@npm:^3.1.0":
"babel-plugin-macros@npm:^3.1.0":
version: 3.1.0
resolution: "babel-plugin-macros@npm:3.1.0"
dependencies:
@ -4107,18 +4127,6 @@ __metadata:
languageName: node
linkType: hard
"babel-plugin-preval@npm:^5.0.0":
version: 5.1.0
resolution: "babel-plugin-preval@npm:5.1.0"
dependencies:
"@babel/runtime": "npm:^7.12.5"
"@types/babel__core": "npm:^7.1.12"
babel-plugin-macros: "npm:^3.0.1"
require-from-string: "npm:^2.0.2"
checksum: d4507d1f134a610b8a2d4de911afe147eba7aab782ea34e7b687e99bdfd2e28d2056e16b7fa4b66acb59bcbd681acc40e851a20f03f7be719ee4cc51fc88eee0
languageName: node
linkType: hard
"babel-plugin-transform-react-remove-prop-types@npm:^0.4.24":
version: 0.4.24
resolution: "babel-plugin-transform-react-remove-prop-types@npm:0.4.24"
@ -4157,6 +4165,13 @@ __metadata:
languageName: node
linkType: hard
"binary-extensions@npm:^2.0.0":
version: 2.2.0
resolution: "binary-extensions@npm:2.2.0"
checksum: ccd267956c58d2315f5d3ea6757cf09863c5fc703e50fbeb13a7dc849b812ef76e3cf9ca8f35a0c48498776a7478d7b4a0418e1e2b8cb9cb9731f2922aaad7f8
languageName: node
linkType: hard
"brace-expansion@npm:^1.1.7":
version: 1.1.11
resolution: "brace-expansion@npm:1.1.11"
@ -4176,7 +4191,7 @@ __metadata:
languageName: node
linkType: hard
"braces@npm:^3.0.2":
"braces@npm:^3.0.2, braces@npm:~3.0.2":
version: 3.0.2
resolution: "braces@npm:3.0.2"
dependencies:
@ -4185,6 +4200,20 @@ __metadata:
languageName: node
linkType: hard
"browserslist@npm:^4.21.10, browserslist@npm:^4.22.2":
version: 4.22.2
resolution: "browserslist@npm:4.22.2"
dependencies:
caniuse-lite: "npm:^1.0.30001565"
electron-to-chromium: "npm:^1.4.601"
node-releases: "npm:^2.0.14"
update-browserslist-db: "npm:^1.0.13"
bin:
browserslist: cli.js
checksum: e3590793db7f66ad3a50817e7b7f195ce61e029bd7187200244db664bfbe0ac832f784e4f6b9c958aef8ea4abe001ae7880b7522682df521f4bc0a5b67660b5e
languageName: node
linkType: hard
"browserslist@npm:^4.21.3, browserslist@npm:^4.21.5":
version: 4.21.5
resolution: "browserslist@npm:4.21.5"
@ -4199,20 +4228,6 @@ __metadata:
languageName: node
linkType: hard
"browserslist@npm:^4.22.2":
version: 4.22.2
resolution: "browserslist@npm:4.22.2"
dependencies:
caniuse-lite: "npm:^1.0.30001565"
electron-to-chromium: "npm:^1.4.601"
node-releases: "npm:^2.0.14"
update-browserslist-db: "npm:^1.0.13"
bin:
browserslist: cli.js
checksum: e3590793db7f66ad3a50817e7b7f195ce61e029bd7187200244db664bfbe0ac832f784e4f6b9c958aef8ea4abe001ae7880b7522682df521f4bc0a5b67660b5e
languageName: node
linkType: hard
"buffer-from@npm:^1.0.0":
version: 1.1.2
resolution: "buffer-from@npm:1.1.2"
@ -4275,6 +4290,13 @@ __metadata:
languageName: node
linkType: hard
"camelcase-css@npm:^2.0.1":
version: 2.0.1
resolution: "camelcase-css@npm:2.0.1"
checksum: 1cec2b3b3dcb5026688a470b00299a8db7d904c4802845c353dbd12d9d248d3346949a814d83bfd988d4d2e5b9904c07efe76fecd195a1d4f05b543e7c0b56b1
languageName: node
linkType: hard
"caniuse-lite@npm:^1.0.30001449":
version: 1.0.30001489
resolution: "caniuse-lite@npm:1.0.30001489"
@ -4282,7 +4304,7 @@ __metadata:
languageName: node
linkType: hard
"caniuse-lite@npm:^1.0.30001565":
"caniuse-lite@npm:^1.0.30001538, caniuse-lite@npm:^1.0.30001565":
version: 1.0.30001571
resolution: "caniuse-lite@npm:1.0.30001571"
checksum: 04f53b9a74776c9214476314613af95c62c43a9ddbc2ae555e176e896cc312110f9b74683f278fd07b8b83ab8ef6bee87b88f466df6ae560461a117fbd678b69
@ -4310,6 +4332,25 @@ __metadata:
languageName: node
linkType: hard
"chokidar@npm:^3.5.3":
version: 3.5.3
resolution: "chokidar@npm:3.5.3"
dependencies:
anymatch: "npm:~3.1.2"
braces: "npm:~3.0.2"
fsevents: "npm:~2.3.2"
glob-parent: "npm:~5.1.2"
is-binary-path: "npm:~2.1.0"
is-glob: "npm:~4.0.1"
normalize-path: "npm:~3.0.0"
readdirp: "npm:~3.6.0"
dependenciesMeta:
fsevents:
optional: true
checksum: 863e3ff78ee7a4a24513d2a416856e84c8e4f5e60efbe03e8ab791af1a183f569b62fc6f6b8044e2804966cb81277ddbbc1dc374fba3265bd609ea8efd62f5b3
languageName: node
linkType: hard
"chownr@npm:^2.0.0":
version: 2.0.0
resolution: "chownr@npm:2.0.0"
@ -4381,6 +4422,13 @@ __metadata:
languageName: node
linkType: hard
"commander@npm:^4.0.0":
version: 4.1.1
resolution: "commander@npm:4.1.1"
checksum: 3b2dc4125f387dab73b3294dbcb0ab2a862f9c0ad748ee2b27e3544d25325b7a8cdfbcc228d103a98a716960b14478114a5206b5415bd48cdafa38797891562c
languageName: node
linkType: hard
"common-tags@npm:^1.8.0":
version: 1.8.2
resolution: "common-tags@npm:1.8.2"
@ -4472,6 +4520,15 @@ __metadata:
languageName: node
linkType: hard
"cssesc@npm:^3.0.0":
version: 3.0.0
resolution: "cssesc@npm:3.0.0"
bin:
cssesc: bin/cssesc
checksum: 0e161912c1306861d8f46e1883be1cbc8b1b2879f0f509287c0db71796e4ddfb97ac96bdfca38f77f452e2c10554e1bb5678c99b07a5cf947a12778f73e47e12
languageName: node
linkType: hard
"csstype@npm:^3.0.2":
version: 3.1.2
resolution: "csstype@npm:3.1.2"
@ -4675,6 +4732,13 @@ __metadata:
languageName: node
linkType: hard
"didyoumean@npm:^1.2.2":
version: 1.2.2
resolution: "didyoumean@npm:1.2.2"
checksum: de7f11b6a0c8c61018629b7f405bb9746d6e994ce87c1a4b7655c3c718442dc69037a3d46d804950604fd9cbe85c074f7b224a119fc1bda851690a74540c6cf8
languageName: node
linkType: hard
"dir-glob@npm:^3.0.1":
version: 3.0.1
resolution: "dir-glob@npm:3.0.1"
@ -4684,6 +4748,13 @@ __metadata:
languageName: node
linkType: hard
"dlv@npm:^1.1.3":
version: 1.1.3
resolution: "dlv@npm:1.1.3"
checksum: 836459ec6b50e43e9ed388a5fc28954be99e3481af3fa4b5d82a600762eb65ef8faacd454097ed7fc2f8a60aea2800d65a4cece5cd0d81ab82b2031f3f759e6e
languageName: node
linkType: hard
"doctrine@npm:^2.1.0":
version: 2.1.0
resolution: "doctrine@npm:2.1.0"
@ -5393,7 +5464,7 @@ __metadata:
languageName: node
linkType: hard
"eventemitter3@npm:^4.0.0, eventemitter3@npm:^4.0.1":
"eventemitter3@npm:^4.0.1":
version: 4.0.7
resolution: "eventemitter3@npm:4.0.7"
checksum: 8030029382404942c01d0037079f1b1bc8fed524b5849c237b80549b01e2fc49709e1d0c557fa65ca4498fc9e24cff1475ef7b855121fcc15f9d61f93e282346
@ -5434,7 +5505,7 @@ __metadata:
languageName: node
linkType: hard
"fast-glob@npm:^3.3.2":
"fast-glob@npm:^3.3.0, fast-glob@npm:^3.3.2":
version: 3.3.2
resolution: "fast-glob@npm:3.3.2"
dependencies:
@ -5524,16 +5595,6 @@ __metadata:
languageName: node
linkType: hard
"follow-redirects@npm:^1.0.0":
version: 1.15.2
resolution: "follow-redirects@npm:1.15.2"
peerDependenciesMeta:
debug:
optional: true
checksum: 8be0d39919770054812537d376850ccde0b4762b0501c440bd08724971a078123b55f57704f2984e0664fecc0c86adea85add63295804d9dce401cd9604c91d3
languageName: node
linkType: hard
"for-each@npm:^0.3.3":
version: 0.3.3
resolution: "for-each@npm:0.3.3"
@ -5553,6 +5614,13 @@ __metadata:
languageName: node
linkType: hard
"fraction.js@npm:^4.3.6":
version: 4.3.7
resolution: "fraction.js@npm:4.3.7"
checksum: bb5ebcdeeffcdc37b68ead3bdfc244e68de188e0c64e9702197333c72963b95cc798883ad16adc21588088b942bca5b6a6ff4aeb1362d19f6f3b629035dc15f5
languageName: node
linkType: hard
"fs-extra@npm:^9.0.1":
version: 9.1.0
resolution: "fs-extra@npm:9.1.0"
@ -5709,7 +5777,7 @@ __metadata:
languageName: node
linkType: hard
"glob-parent@npm:^5.1.2":
"glob-parent@npm:^5.1.2, glob-parent@npm:~5.1.2":
version: 5.1.2
resolution: "glob-parent@npm:5.1.2"
dependencies:
@ -5922,35 +5990,6 @@ __metadata:
languageName: node
linkType: hard
"http-proxy-middleware@npm:^2.0.6":
version: 2.0.6
resolution: "http-proxy-middleware@npm:2.0.6"
dependencies:
"@types/http-proxy": "npm:^1.17.8"
http-proxy: "npm:^1.18.1"
is-glob: "npm:^4.0.1"
is-plain-obj: "npm:^3.0.0"
micromatch: "npm:^4.0.2"
peerDependencies:
"@types/express": ^4.17.13
peerDependenciesMeta:
"@types/express":
optional: true
checksum: 768e7ae5a422bbf4b866b64105b4c2d1f468916b7b0e9c96750551c7732383069b411aa7753eb7b34eab113e4f77fb770122cb7fb9c8ec87d138d5ddaafda891
languageName: node
linkType: hard
"http-proxy@npm:^1.18.1":
version: 1.18.1
resolution: "http-proxy@npm:1.18.1"
dependencies:
eventemitter3: "npm:^4.0.0"
follow-redirects: "npm:^1.0.0"
requires-port: "npm:^1.0.0"
checksum: 2489e98aba70adbfd8b9d41ed1ff43528be4598c88616c558b109a09eaffe4bb35e551b6c75ac42ed7d948bb7530a22a2be6ef4f0cecacb5927be139f4274594
languageName: node
linkType: hard
"https-proxy-agent@npm:^7.0.1":
version: 7.0.2
resolution: "https-proxy-agent@npm:7.0.2"
@ -6094,6 +6133,15 @@ __metadata:
languageName: node
linkType: hard
"is-binary-path@npm:~2.1.0":
version: 2.1.0
resolution: "is-binary-path@npm:2.1.0"
dependencies:
binary-extensions: "npm:^2.0.0"
checksum: 078e51b4f956c2c5fd2b26bb2672c3ccf7e1faff38e0ebdba45612265f4e3d9fc3127a1fa8370bbf09eab61339203c3d3b7af5662cbf8be4030f8fac37745b0e
languageName: node
linkType: hard
"is-boolean-object@npm:^1.1.0":
version: 1.1.2
resolution: "is-boolean-object@npm:1.1.2"
@ -6120,6 +6168,15 @@ __metadata:
languageName: node
linkType: hard
"is-core-module@npm:^2.13.0":
version: 2.13.1
resolution: "is-core-module@npm:2.13.1"
dependencies:
hasown: "npm:^2.0.0"
checksum: d53bd0cc24b0a0351fb4b206ee3908f71b9bbf1c47e9c9e14e5f06d292af1663704d2abd7e67700d6487b2b7864e0d0f6f10a1edf1892864bdffcb197d1845a2
languageName: node
linkType: hard
"is-date-object@npm:^1.0.1, is-date-object@npm:^1.0.5":
version: 1.0.5
resolution: "is-date-object@npm:1.0.5"
@ -6152,7 +6209,7 @@ __metadata:
languageName: node
linkType: hard
"is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3":
"is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3, is-glob@npm:~4.0.1":
version: 4.0.3
resolution: "is-glob@npm:4.0.3"
dependencies:
@ -6219,13 +6276,6 @@ __metadata:
languageName: node
linkType: hard
"is-plain-obj@npm:^3.0.0":
version: 3.0.0
resolution: "is-plain-obj@npm:3.0.0"
checksum: a6ebdf8e12ab73f33530641972a72a4b8aed6df04f762070d823808303e4f76d87d5ea5bd76f96a7bbe83d93f04ac7764429c29413bd9049853a69cb630fb21c
languageName: node
linkType: hard
"is-regex@npm:^1.1.4":
version: 1.1.4
resolution: "is-regex@npm:1.1.4"
@ -6400,6 +6450,15 @@ __metadata:
languageName: node
linkType: hard
"jiti@npm:^1.19.1":
version: 1.21.0
resolution: "jiti@npm:1.21.0"
bin:
jiti: bin/jiti.js
checksum: 005a0239e50381b5c9919f59dbab86128367bd64872f3376dbbde54b6523f41bd134bf22909e2a509e38fd87e1c22125ca255b9b6b53e7df0fedd23f737334cc
languageName: node
linkType: hard
"js-tokens@npm:^3.0.0 || ^4.0.0, js-tokens@npm:^4.0.0":
version: 4.0.0
resolution: "js-tokens@npm:4.0.0"
@ -6554,6 +6613,20 @@ __metadata:
languageName: node
linkType: hard
"lilconfig@npm:^2.1.0":
version: 2.1.0
resolution: "lilconfig@npm:2.1.0"
checksum: b1314a2e55319013d5e7d7d08be39015829d2764a1eaee130129545d40388499d81b1c31b0f9b3417d4db12775a88008b72ec33dd06e0184cf7503b32ca7cc0b
languageName: node
linkType: hard
"lilconfig@npm:^3.0.0":
version: 3.0.0
resolution: "lilconfig@npm:3.0.0"
checksum: 55f60f4f9f7b41358cc33875e3696919412683a35aec30c6c60c4f6ecb16fb6d11f7ac856b8458b9b82b21d5f4629649fbfca1de034e8d5b0cc7a70836266db6
languageName: node
linkType: hard
"lines-and-columns@npm:^1.1.6":
version: 1.2.4
resolution: "lines-and-columns@npm:1.2.4"
@ -6676,7 +6749,7 @@ __metadata:
languageName: node
linkType: hard
"micromatch@npm:^4.0.2, micromatch@npm:^4.0.4":
"micromatch@npm:^4.0.4, micromatch@npm:^4.0.5":
version: 4.0.5
resolution: "micromatch@npm:4.0.5"
dependencies:
@ -6834,6 +6907,17 @@ __metadata:
languageName: node
linkType: hard
"mz@npm:^2.7.0":
version: 2.7.0
resolution: "mz@npm:2.7.0"
dependencies:
any-promise: "npm:^1.0.0"
object-assign: "npm:^4.0.1"
thenify-all: "npm:^1.0.0"
checksum: 8427de0ece99a07e9faed3c0c6778820d7543e3776f9a84d22cf0ec0a8eb65f6e9aee9c9d353ff9a105ff62d33a9463c6ca638974cc652ee8140cd1e35951c87
languageName: node
linkType: hard
"nanoid@npm:^3.3.7":
version: 3.3.7
resolution: "nanoid@npm:3.3.7"
@ -6909,13 +6993,34 @@ __metadata:
languageName: node
linkType: hard
"object-assign@npm:^4.1.1":
"normalize-path@npm:^3.0.0, normalize-path@npm:~3.0.0":
version: 3.0.0
resolution: "normalize-path@npm:3.0.0"
checksum: 88eeb4da891e10b1318c4b2476b6e2ecbeb5ff97d946815ffea7794c31a89017c70d7f34b3c2ebf23ef4e9fc9fb99f7dffe36da22011b5b5c6ffa34f4873ec20
languageName: node
linkType: hard
"normalize-range@npm:^0.1.2":
version: 0.1.2
resolution: "normalize-range@npm:0.1.2"
checksum: 9b2f14f093593f367a7a0834267c24f3cb3e887a2d9809c77d8a7e5fd08738bcd15af46f0ab01cc3a3d660386f015816b5c922cea8bf2ee79777f40874063184
languageName: node
linkType: hard
"object-assign@npm:^4.0.1, object-assign@npm:^4.1.1":
version: 4.1.1
resolution: "object-assign@npm:4.1.1"
checksum: fcc6e4ea8c7fe48abfbb552578b1c53e0d194086e2e6bbbf59e0a536381a292f39943c6e9628af05b5528aa5e3318bb30d6b2e53cadaf5b8fe9e12c4b69af23f
languageName: node
linkType: hard
"object-hash@npm:^3.0.0":
version: 3.0.0
resolution: "object-hash@npm:3.0.0"
checksum: f498d456a20512ba7be500cef4cf7b3c183cc72c65372a549c9a0e6dd78ce26f375e9b1315c07592d3fde8f10d5019986eba35970570d477ed9a2a702514432a
languageName: node
linkType: hard
"object-inspect@npm:^1.12.3, object-inspect@npm:^1.9.0":
version: 1.12.3
resolution: "object-inspect@npm:1.12.3"
@ -7136,13 +7241,90 @@ __metadata:
languageName: node
linkType: hard
"picomatch@npm:^2.2.2, picomatch@npm:^2.3.1":
"picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.2.2, picomatch@npm:^2.3.1":
version: 2.3.1
resolution: "picomatch@npm:2.3.1"
checksum: 60c2595003b05e4535394d1da94850f5372c9427ca4413b71210f437f7b2ca091dbd611c45e8b37d10036fa8eade25c1b8951654f9d3973bfa66a2ff4d3b08bc
languageName: node
linkType: hard
"pify@npm:^2.3.0":
version: 2.3.0
resolution: "pify@npm:2.3.0"
checksum: 9503aaeaf4577acc58642ad1d25c45c6d90288596238fb68f82811c08104c800e5a7870398e9f015d82b44ecbcbef3dc3d4251a1cbb582f6e5959fe09884b2ba
languageName: node
linkType: hard
"pirates@npm:^4.0.1":
version: 4.0.6
resolution: "pirates@npm:4.0.6"
checksum: d02dda76f4fec1cbdf395c36c11cf26f76a644f9f9a1bfa84d3167d0d3154d5289aacc72677aa20d599bb4a6937a471de1b65c995e2aea2d8687cbcd7e43ea5f
languageName: node
linkType: hard
"postcss-import@npm:^15.1.0":
version: 15.1.0
resolution: "postcss-import@npm:15.1.0"
dependencies:
postcss-value-parser: "npm:^4.0.0"
read-cache: "npm:^1.0.0"
resolve: "npm:^1.1.7"
peerDependencies:
postcss: ^8.0.0
checksum: 33c91b7e6b794b5c33d7d7d4730e5f0729c131d2de1ada7fcc116955625a78c3ce613983f019fa9447681795cf3f851e9c38dfbe3f48a2d08a8aef917c70a32a
languageName: node
linkType: hard
"postcss-js@npm:^4.0.1":
version: 4.0.1
resolution: "postcss-js@npm:4.0.1"
dependencies:
camelcase-css: "npm:^2.0.1"
peerDependencies:
postcss: ^8.4.21
checksum: ef2cfe8554daab4166cfcb290f376e7387964c36503f5bd42008778dba735685af8d4f5e0aba67cae999f47c855df40a1cd31ae840e0df320ded36352581045e
languageName: node
linkType: hard
"postcss-load-config@npm:^4.0.1":
version: 4.0.2
resolution: "postcss-load-config@npm:4.0.2"
dependencies:
lilconfig: "npm:^3.0.0"
yaml: "npm:^2.3.4"
peerDependencies:
postcss: ">=8.0.9"
ts-node: ">=9.0.0"
peerDependenciesMeta:
postcss:
optional: true
ts-node:
optional: true
checksum: e2c2ed9b7998a5b123e1ce0c124daf6504b1454c67dcc1c8fdbcc5ffb2597b7de245e3ac34f63afc928d3fd3260b1e36492ebbdb01a9ff63f16b3c8b7b925d1b
languageName: node
linkType: hard
"postcss-nested@npm:^6.0.1":
version: 6.0.1
resolution: "postcss-nested@npm:6.0.1"
dependencies:
postcss-selector-parser: "npm:^6.0.11"
peerDependencies:
postcss: ^8.2.14
checksum: 02aaac682f599879fae6aab3210aee59b8b5bde3ba242527f6fd103726955b74ffa05c2b765920be5f403e758045582534d11b1e19add01586c19743ed99e3fe
languageName: node
linkType: hard
"postcss-selector-parser@npm:^6.0.11":
version: 6.0.13
resolution: "postcss-selector-parser@npm:6.0.13"
dependencies:
cssesc: "npm:^3.0.0"
util-deprecate: "npm:^1.0.2"
checksum: e779aa1f8ca9ee45d562400aac6109a2bccc59559b6e15adec8bc2a71d395ca563a378fd68f6a61963b4ef2ca190e0c0486e6dc6c41d755f3b82dd6e480e6941
languageName: node
linkType: hard
"postcss-value-parser@npm:^3.3.0":
version: 3.3.1
resolution: "postcss-value-parser@npm:3.3.1"
@ -7150,7 +7332,14 @@ __metadata:
languageName: node
linkType: hard
"postcss@npm:^8.4.32":
"postcss-value-parser@npm:^4.0.0, postcss-value-parser@npm:^4.2.0":
version: 4.2.0
resolution: "postcss-value-parser@npm:4.2.0"
checksum: e4e4486f33b3163a606a6ed94f9c196ab49a37a7a7163abfcd469e5f113210120d70b8dd5e33d64636f41ad52316a3725655421eb9a1094f1bcab1db2f555c62
languageName: node
linkType: hard
"postcss@npm:^8.4.23, postcss@npm:^8.4.32":
version: 8.4.32
resolution: "postcss@npm:8.4.32"
dependencies:
@ -7191,15 +7380,6 @@ __metadata:
languageName: node
linkType: hard
"preval.macro@npm:^5.0.0":
version: 5.0.0
resolution: "preval.macro@npm:5.0.0"
dependencies:
babel-plugin-preval: "npm:^5.0.0"
checksum: 4e58715a7dacd5999c85f8f930029251921955fb46f981a54848c21a370a73efb1825eb9ab08a32cb3a53978b489c6a55ebc1bbddf6eceaef2aa297e0a007401
languageName: node
linkType: hard
"proc-log@npm:^3.0.0":
version: 3.0.0
resolution: "proc-log@npm:3.0.0"
@ -7425,6 +7605,24 @@ __metadata:
languageName: node
linkType: hard
"read-cache@npm:^1.0.0":
version: 1.0.0
resolution: "read-cache@npm:1.0.0"
dependencies:
pify: "npm:^2.3.0"
checksum: 83a39149d9dfa38f0c482ea0d77b34773c92fef07fe7599cdd914d255b14d0453e0229ef6379d8d27d6947f42d7581635296d0cfa7708f05a9bd8e789d398b31
languageName: node
linkType: hard
"readdirp@npm:~3.6.0":
version: 3.6.0
resolution: "readdirp@npm:3.6.0"
dependencies:
picomatch: "npm:^2.2.1"
checksum: 196b30ef6ccf9b6e18c4e1724b7334f72a093d011a99f3b5920470f0b3406a51770867b3e1ae9711f227ef7a7065982f6ee2ce316746b2cb42c88efe44297fe7
languageName: node
linkType: hard
"recharts-scale@npm:^0.4.4":
version: 0.4.5
resolution: "recharts-scale@npm:0.4.5"
@ -7592,13 +7790,6 @@ __metadata:
languageName: node
linkType: hard
"requires-port@npm:^1.0.0":
version: 1.0.0
resolution: "requires-port@npm:1.0.0"
checksum: 878880ee78ccdce372784f62f52a272048e2d0827c29ae31e7f99da18b62a2b9463ea03a75f277352f4697c100183debb0532371ad515a2d49d4bfe596dd4c20
languageName: node
linkType: hard
"reselect@npm:^4.1.8":
version: 4.1.8
resolution: "reselect@npm:4.1.8"
@ -7613,6 +7804,19 @@ __metadata:
languageName: node
linkType: hard
"resolve@npm:^1.1.7, resolve@npm:^1.22.2":
version: 1.22.8
resolution: "resolve@npm:1.22.8"
dependencies:
is-core-module: "npm:^2.13.0"
path-parse: "npm:^1.0.7"
supports-preserve-symlinks-flag: "npm:^1.0.0"
bin:
resolve: bin/resolve
checksum: c473506ee01eb45cbcfefb68652ae5759e092e6b0fb64547feadf9736a6394f258fbc6f88e00c5ca36d5477fbb65388b272432a3600fa223062e54333c156753
languageName: node
linkType: hard
"resolve@npm:^1.14.2, resolve@npm:^1.19.0, resolve@npm:^1.22.1":
version: 1.22.2
resolution: "resolve@npm:1.22.2"
@ -7639,6 +7843,19 @@ __metadata:
languageName: node
linkType: hard
"resolve@patch:resolve@npm%3A^1.1.7#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.22.2#optional!builtin<compat/resolve>":
version: 1.22.8
resolution: "resolve@patch:resolve@npm%3A1.22.8#optional!builtin<compat/resolve>::version=1.22.8&hash=c3c19d"
dependencies:
is-core-module: "npm:^2.13.0"
path-parse: "npm:^1.0.7"
supports-preserve-symlinks-flag: "npm:^1.0.0"
bin:
resolve: bin/resolve
checksum: f345cd37f56a2c0275e3fe062517c650bb673815d885e7507566df589375d165bbbf4bdb6aa95600a9bc55f4744b81f452b5a63f95b9f10a72787dba3c90890a
languageName: node
linkType: hard
"resolve@patch:resolve@npm%3A^1.14.2#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.19.0#optional!builtin<compat/resolve>, resolve@patch:resolve@npm%3A^1.22.1#optional!builtin<compat/resolve>":
version: 1.22.2
resolution: "resolve@patch:resolve@npm%3A1.22.2#optional!builtin<compat/resolve>::version=1.22.2&hash=c3c19d"
@ -8246,6 +8463,24 @@ __metadata:
languageName: node
linkType: hard
"sucrase@npm:^3.32.0":
version: 3.35.0
resolution: "sucrase@npm:3.35.0"
dependencies:
"@jridgewell/gen-mapping": "npm:^0.3.2"
commander: "npm:^4.0.0"
glob: "npm:^10.3.10"
lines-and-columns: "npm:^1.1.6"
mz: "npm:^2.7.0"
pirates: "npm:^4.0.1"
ts-interface-checker: "npm:^0.1.9"
bin:
sucrase: bin/sucrase
sucrase-node: bin/sucrase-node
checksum: bc601558a62826f1c32287d4fdfa4f2c09fe0fec4c4d39d0e257fd9116d7d6227a18309721d4185ec84c9dc1af0d5ec0e05a42a337fbb74fc293e068549aacbe
languageName: node
linkType: hard
"supports-color@npm:^5.3.0":
version: 5.5.0
resolution: "supports-color@npm:5.5.0"
@ -8271,6 +8506,39 @@ __metadata:
languageName: node
linkType: hard
"tailwindcss@npm:^3.4.0":
version: 3.4.0
resolution: "tailwindcss@npm:3.4.0"
dependencies:
"@alloc/quick-lru": "npm:^5.2.0"
arg: "npm:^5.0.2"
chokidar: "npm:^3.5.3"
didyoumean: "npm:^1.2.2"
dlv: "npm:^1.1.3"
fast-glob: "npm:^3.3.0"
glob-parent: "npm:^6.0.2"
is-glob: "npm:^4.0.3"
jiti: "npm:^1.19.1"
lilconfig: "npm:^2.1.0"
micromatch: "npm:^4.0.5"
normalize-path: "npm:^3.0.0"
object-hash: "npm:^3.0.0"
picocolors: "npm:^1.0.0"
postcss: "npm:^8.4.23"
postcss-import: "npm:^15.1.0"
postcss-js: "npm:^4.0.1"
postcss-load-config: "npm:^4.0.1"
postcss-nested: "npm:^6.0.1"
postcss-selector-parser: "npm:^6.0.11"
resolve: "npm:^1.22.2"
sucrase: "npm:^3.32.0"
bin:
tailwind: lib/cli.js
tailwindcss: lib/cli.js
checksum: e69de4856308b3a6bcd084cc6745b6e3dcf6623553414f042d0365adceb70d79e41ec97a2a38c3aea0d5a875aa1eb4e84e04ad35ea1f0f7debcb7150779eae52
languageName: node
linkType: hard
"tar@npm:^6.1.11, tar@npm:^6.1.2":
version: 6.2.0
resolution: "tar@npm:6.2.0"
@ -8325,6 +8593,24 @@ __metadata:
languageName: node
linkType: hard
"thenify-all@npm:^1.0.0":
version: 1.6.0
resolution: "thenify-all@npm:1.6.0"
dependencies:
thenify: "npm:>= 3.1.0 < 4"
checksum: dba7cc8a23a154cdcb6acb7f51d61511c37a6b077ec5ab5da6e8b874272015937788402fd271fdfc5f187f8cb0948e38d0a42dcc89d554d731652ab458f5343e
languageName: node
linkType: hard
"thenify@npm:>= 3.1.0 < 4":
version: 3.3.1
resolution: "thenify@npm:3.3.1"
dependencies:
any-promise: "npm:^1.0.0"
checksum: 486e1283a867440a904e36741ff1a177faa827cf94d69506f7e3ae4187b9afdf9ec368b3d8da225c192bfe2eb943f3f0080594156bf39f21b57cd1411e2e7f6d
languageName: node
linkType: hard
"to-fast-properties@npm:^2.0.0":
version: 2.0.0
resolution: "to-fast-properties@npm:2.0.0"
@ -8350,6 +8636,13 @@ __metadata:
languageName: node
linkType: hard
"ts-interface-checker@npm:^0.1.9":
version: 0.1.13
resolution: "ts-interface-checker@npm:0.1.13"
checksum: 9f7346b9e25bade7a1050c001ec5a4f7023909c0e1644c5a96ae20703a131627f081479e6622a4ecee2177283d0069e651e507bedadd3904fc4010ab28ffce00
languageName: node
linkType: hard
"tsconfig-paths@npm:^3.14.1":
version: 3.14.2
resolution: "tsconfig-paths@npm:3.14.2"
@ -8591,6 +8884,13 @@ __metadata:
languageName: node
linkType: hard
"util-deprecate@npm:^1.0.2":
version: 1.0.2
resolution: "util-deprecate@npm:1.0.2"
checksum: 474acf1146cb2701fe3b074892217553dfcf9a031280919ba1b8d651a068c9b15d863b7303cb15bd00a862b498e6cf4ad7b4a08fb134edd5a6f7641681cb54a2
languageName: node
linkType: hard
"victory-vendor@npm:^36.6.8":
version: 36.6.10
resolution: "victory-vendor@npm:36.6.10"
@ -9016,6 +9316,13 @@ __metadata:
languageName: node
linkType: hard
"yaml@npm:^2.3.4":
version: 2.3.4
resolution: "yaml@npm:2.3.4"
checksum: f8207ce43065a22268a2806ea6a0fa3974c6fde92b4b2fa0082357e487bc333e85dc518910007e7ac001b532c7c84bd3eccb6c7757e94182b564028b0008f44b
languageName: node
linkType: hard
"yargs-parser@npm:^21.1.1":
version: 21.1.1
resolution: "yargs-parser@npm:21.1.1"

View File

@ -13,4 +13,10 @@ services:
clamav:
image: "clamav/clamav"
ports:
- "3320:3310"
- "3320:3310"
prometheus:
image: bitnami/prometheus
ports:
- "9090:9090"
volumes:
- "./prometheus.yml:/opt/bitnami/prometheus/conf/prometheus.yml:ro"

View File

@ -3,4 +3,4 @@ global:
scrape_configs:
- job_name: void-cat
static_configs:
- targets: [ "web:9090" ]
- targets: [ "web:80" ]