Compare commits

...

5 Commits

Author SHA1 Message Date
0f8ee33279 feat: show lnurl as payment method
All checks were successful
continuous-integration/drone/push Build is passing
2025-05-02 13:59:37 +01:00
f28c785cbd feat: show default username for ssh
All checks were successful
continuous-integration/drone/push Build is passing
2025-05-02 09:50:10 +01:00
e4bee1a568 fix: icons
All checks were successful
continuous-integration/drone/push Build is passing
2025-05-01 17:59:59 +01:00
51d7cea581 feat: navigate invoice
All checks were successful
continuous-integration/drone/push Build is passing
2025-05-01 17:47:00 +01:00
9a04548627 feat: payment history 2025-05-01 15:32:00 +01:00
8 changed files with 539 additions and 214 deletions

View File

@ -43,7 +43,7 @@
"tailwindcss": "^3.4.8", "tailwindcss": "^3.4.8",
"typescript": "^5.5.3", "typescript": "^5.5.3",
"typescript-eslint": "^8.0.0", "typescript-eslint": "^8.0.0",
"vite": "^5.4.0" "vite": "^6.3.4"
}, },
"packageManager": "yarn@4.4.0" "packageManager": "yarn@4.4.0"
} }

View File

@ -137,6 +137,7 @@ export interface VmOsImage {
flavour: string; flavour: string;
version: string; version: string;
release_date: string; release_date: string;
default_username?: string;
} }
export interface UserSshKey { export interface UserSshKey {
@ -149,8 +150,10 @@ export interface VmPayment {
created: string; created: string;
expires: string; expires: string;
amount: number; amount: number;
currency: string;
tax: number; tax: number;
is_paid: boolean; is_paid: boolean;
time: number;
data: { data: {
lightning?: string; lightning?: string;
revolut?: { revolut?: {
@ -358,6 +361,22 @@ export class LNVpsApi {
return data; return data;
} }
async invoiceLink(id: string) {
const u = `${this.url}/api/v1/payment/${id}/invoice`;
const auth = await this.#auth_event(u, "GET");
const auth_b64 = base64.encode(
new TextEncoder().encode(JSON.stringify(auth)),
);
return `${u}?auth=${auth_b64}`;
}
async listPayments(id: number) {
const { data } = await this.#handleResponse<ApiResponse<Array<VmPayment>>>(
await this.#req(`/api/v1/vm/${id}/payments`, "GET"),
);
return data;
}
async getPaymentMethods() { async getPaymentMethods() {
const { data } = await this.#handleResponse< const { data } = await this.#handleResponse<
ApiResponse<Array<PaymentMethod>> ApiResponse<Array<PaymentMethod>>
@ -368,11 +387,10 @@ export class LNVpsApi {
async connect_terminal(id: number) { async connect_terminal(id: number) {
const u = `${this.url}/api/v1/vm/${id}/console`; const u = `${this.url}/api/v1/vm/${id}/console`;
const auth = await this.#auth_event(u, "GET"); const auth = await this.#auth_event(u, "GET");
const ws = new WebSocket( const auth_b64 = base64.encode(
`${u}?auth=${base64.encode( new TextEncoder().encode(JSON.stringify(auth)),
new TextEncoder().encode(JSON.stringify(auth)),
)}`,
); );
const ws = new WebSocket(`${u}?auth=${auth_b64}`);
return await new Promise<WebSocket>((resolve, reject) => { return await new Promise<WebSocket>((resolve, reject) => {
ws.onopen = () => { ws.onopen = () => {
resolve(ws); resolve(ws);

View File

@ -1,6 +1,8 @@
import classNames from "classnames"; import classNames from "classnames";
import { MouseEventHandler } from "react"; import { MouseEventHandler } from "react";
import Icons from "../icons.svg?no-inline";
type Props = { type Props = {
name: string; name: string;
size?: number; size?: number;
@ -10,7 +12,7 @@ type Props = {
export function Icon(props: Props) { export function Icon(props: Props) {
const size = props.size || 20; const size = props.size || 20;
const href = `/icons.svg#${props.name}`; const href = `${Icons}#${props.name}`;
return ( return (
<svg <svg

View File

@ -1,25 +1,25 @@
<svg xmlns="http://www.w3.org/2000/svg"> <svg xmlns="http://www.w3.org/2000/svg">
<defs> <defs>
<svg id="start" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <symbol id="start" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M24 0V24H0V0H24Z" fill="white" fill-opacity="0.01"/> <path d="M24 0V24H0V0H24Z" fill="white" fill-opacity="0.01"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.5 3C13.5 2.17157 12.8284 1.5 12 1.5C11.1716 1.5 10.5 2.17157 10.5 3V13C10.5 13.8284 11.1716 14.5 12 14.5C12.8284 14.5 13.5 13.8284 13.5 13V3ZM7.85385 5.7491C8.54371 5.29043 8.73113 4.35936 8.27245 3.6695C7.81378 2.97963 6.8827 2.79222 6.19284 3.2509C3.36739 5.12948 1.5 8.34635 1.5 12C1.5 17.799 6.20101 22.5 12 22.5C17.799 22.5 22.5 17.799 22.5 12C22.5 8.34635 20.6326 5.12948 17.8072 3.2509C17.1173 2.79222 16.1862 2.97963 15.7275 3.6695C15.2689 4.35936 15.4563 5.29043 16.1461 5.7491C18.1708 7.09528 19.5 9.39275 19.5 12C19.5 16.1422 16.1421 19.5 12 19.5C7.85786 19.5 4.5 16.1422 4.5 12C4.5 9.39275 5.82917 7.09528 7.85385 5.7491Z" fill="#F7F9FC"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M13.5 3C13.5 2.17157 12.8284 1.5 12 1.5C11.1716 1.5 10.5 2.17157 10.5 3V13C10.5 13.8284 11.1716 14.5 12 14.5C12.8284 14.5 13.5 13.8284 13.5 13V3ZM7.85385 5.7491C8.54371 5.29043 8.73113 4.35936 8.27245 3.6695C7.81378 2.97963 6.8827 2.79222 6.19284 3.2509C3.36739 5.12948 1.5 8.34635 1.5 12C1.5 17.799 6.20101 22.5 12 22.5C17.799 22.5 22.5 17.799 22.5 12C22.5 8.34635 20.6326 5.12948 17.8072 3.2509C17.1173 2.79222 16.1862 2.97963 15.7275 3.6695C15.2689 4.35936 15.4563 5.29043 16.1461 5.7491C18.1708 7.09528 19.5 9.39275 19.5 12C19.5 16.1422 16.1421 19.5 12 19.5C7.85786 19.5 4.5 16.1422 4.5 12C4.5 9.39275 5.82917 7.09528 7.85385 5.7491Z" fill="#F7F9FC"/>
</svg> </symbol>
<svg id="stop" viewBox="0 0 24 24" fill="none"> <symbol id="stop" viewBox="0 0 24 24" fill="none">
<path d="M24 0V24H0V0H24Z" fill="white" fill-opacity="0.01"/> <path d="M24 0V24H0V0H24Z" fill="white" fill-opacity="0.01"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 6C4 4.89543 4.89543 4 6 4H18C19.1046 4 20 4.89543 20 6V18C20 19.1046 19.1046 20 18 20H6C4.89543 20 4 19.1046 4 18V6Z" fill="white"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M4 6C4 4.89543 4.89543 4 6 4H18C19.1046 4 20 4.89543 20 6V18C20 19.1046 19.1046 20 18 20H6C4.89543 20 4 19.1046 4 18V6Z" fill="white"/>
</svg> </symbol>
<svg id="delete" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <symbol id="delete" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M24 0V24H0V0H24Z" fill="white" fill-opacity="0.01"/> <path d="M24 0V24H0V0H24Z" fill="white" fill-opacity="0.01"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M9 3C9 2.44772 9.44772 2 10 2H14C14.5523 2 15 2.44772 15 3C15 3.55228 14.5523 4 14 4H10C9.44772 4 9 3.55228 9 3ZM5.92032 5H4C3.44772 5 3 5.44772 3 6C3 6.55228 3.44772 7 4 7H4.99745L5.9362 20.1425C6.01096 21.1891 6.88184 22 7.93112 22H16.0689C17.1182 22 17.989 21.1891 18.0638 20.1425L19.0025 7H20C20.5523 7 21 6.55228 21 6C21 5.44772 20.5523 5 20 5H18.0797C18.0735 4.99994 18.0673 4.99994 18.0611 5H5.93889C5.93271 4.99994 5.92652 4.99994 5.92032 5Z" fill="#F7F9FC"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M9 3C9 2.44772 9.44772 2 10 2H14C14.5523 2 15 2.44772 15 3C15 3.55228 14.5523 4 14 4H10C9.44772 4 9 3.55228 9 3ZM5.92032 5H4C3.44772 5 3 5.44772 3 6C3 6.55228 3.44772 7 4 7H4.99745L5.9362 20.1425C6.01096 21.1891 6.88184 22 7.93112 22H16.0689C17.1182 22 17.989 21.1891 18.0638 20.1425L19.0025 7H20C20.5523 7 21 6.55228 21 6C21 5.44772 20.5523 5 20 5H18.0797C18.0735 4.99994 18.0673 4.99994 18.0611 5H5.93889C5.93271 4.99994 5.92652 4.99994 5.92032 5Z" fill="#F7F9FC"/>
</svg> </symbol>
<svg id="refresh-1" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <symbol id="refresh-1" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M24 0V24H0V0H24Z" fill="white" fill-opacity="0.01"/> <path d="M24 0V24H0V0H24Z" fill="white" fill-opacity="0.01"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.0589 19.2443C12.8824 20.0009 15.764 19.0421 17.5934 16.9994C18.146 16.3822 19.0943 16.33 19.7115 16.8826C20.3286 17.4353 20.3808 18.3836 19.8282 19.0008C17.2737 21.8532 13.2404 23.2026 9.28249 22.1421C3.6811 20.6412 0.35698 14.8837 1.85787 9.2823C3.35876 3.68091 9.1163 0.356795 14.7177 1.85768C18.9224 2.98433 21.8407 6.50832 22.4032 10.5596C22.4653 11.0066 22.4987 11.4603 22.502 11.9179C22.5117 13.2319 21.0529 13.9572 20.01 13.2545L17.3364 11.4531C15.8701 10.4651 16.8533 8.17943 18.579 8.56459L18.6789 8.58688C17.7458 6.76269 16.0738 5.32688 13.9412 4.75546C9.94024 3.6834 5.82771 6.05777 4.75565 10.0588C3.68358 14.0598 6.05795 18.1723 10.0589 19.2443Z" fill="#F7F9FC"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M10.0589 19.2443C12.8824 20.0009 15.764 19.0421 17.5934 16.9994C18.146 16.3822 19.0943 16.33 19.7115 16.8826C20.3286 17.4353 20.3808 18.3836 19.8282 19.0008C17.2737 21.8532 13.2404 23.2026 9.28249 22.1421C3.6811 20.6412 0.35698 14.8837 1.85787 9.2823C3.35876 3.68091 9.1163 0.356795 14.7177 1.85768C18.9224 2.98433 21.8407 6.50832 22.4032 10.5596C22.4653 11.0066 22.4987 11.4603 22.502 11.9179C22.5117 13.2319 21.0529 13.9572 20.01 13.2545L17.3364 11.4531C15.8701 10.4651 16.8533 8.17943 18.579 8.56459L18.6789 8.58688C17.7458 6.76269 16.0738 5.32688 13.9412 4.75546C9.94024 3.6834 5.82771 6.05777 4.75565 10.0588C3.68358 14.0598 6.05795 18.1723 10.0589 19.2443Z" fill="#F7F9FC"/>
</svg> </symbol>
<svg id="pencil" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <symbol id="pencil" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M24 0V24H0V0H24Z" fill="white" fill-opacity="0.01"/> <path d="M24 0V24H0V0H24Z" fill="white" fill-opacity="0.01"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M20.1315 3.16087C18.9599 1.9893 17.0604 1.9893 15.8888 3.16087L15.1817 3.86798L20.1315 8.81773L20.8386 8.11062C22.0101 6.93905 22.0101 5.03955 20.8386 3.86798L20.1315 3.16087ZM18.7172 10.2319L13.7675 5.28219L4.6765 14.3732C4.47771 14.572 4.33879 14.8226 4.27557 15.0966L3.24752 19.5515C3.08116 20.2723 3.72726 20.9182 4.44797 20.7519L8.90288 19.7239C9.17681 19.6606 9.42746 19.5217 9.62625 19.3229L18.7172 10.2319Z" fill="#F7F9FC"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M20.1315 3.16087C18.9599 1.9893 17.0604 1.9893 15.8888 3.16087L15.1817 3.86798L20.1315 8.81773L20.8386 8.11062C22.0101 6.93905 22.0101 5.03955 20.8386 3.86798L20.1315 3.16087ZM18.7172 10.2319L13.7675 5.28219L4.6765 14.3732C4.47771 14.572 4.33879 14.8226 4.27557 15.0966L3.24752 19.5515C3.08116 20.2723 3.72726 20.9182 4.44797 20.7519L8.90288 19.7239C9.17681 19.6606 9.42746 19.5217 9.62625 19.3229L18.7172 10.2319Z" fill="#F7F9FC"/>
</svg> </symbol>
<symbol id="printer" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-printer-icon lucide-printer"><path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"/><path d="M6 9V3a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v6"/><rect x="6" y="14" width="12" height="8" rx="1"/></symbol>
</defs> </defs>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -4,8 +4,13 @@ import { PaymentMethod, VmInstance, VmPayment } from "../api";
import VpsPayment from "../components/vps-payment"; import VpsPayment from "../components/vps-payment";
import useLogin from "../hooks/login"; import useLogin from "../hooks/login";
import { AsyncButton } from "../components/button"; import { AsyncButton } from "../components/button";
import CostLabel from "../components/cost"; import CostLabel, { CostAmount } from "../components/cost";
import { RevolutPayWidget } from "../components/revolut"; import { RevolutPayWidget } from "../components/revolut";
import { timeValue } from "../utils";
import { Icon } from "../components/icon";
import { ApiUrl } from "../const";
import QrCode from "../components/qr";
import { LNURL } from "@snort/shared";
export function VmBillingPage() { export function VmBillingPage() {
const location = useLocation() as { state?: VmInstance }; const location = useLocation() as { state?: VmInstance };
@ -15,8 +20,15 @@ export function VmBillingPage() {
const [methods, setMethods] = useState<Array<PaymentMethod>>(); const [methods, setMethods] = useState<Array<PaymentMethod>>();
const [method, setMethod] = useState<PaymentMethod>(); const [method, setMethod] = useState<PaymentMethod>();
const [payment, setPayment] = useState<VmPayment>(); const [payment, setPayment] = useState<VmPayment>();
const [payments, setPayments] = useState<Array<VmPayment>>([]);
const [state, setState] = useState<VmInstance | undefined>(location?.state); const [state, setState] = useState<VmInstance | undefined>(location?.state);
async function listPayments() {
if (!state) return;
const history = await login?.api.listPayments(state.id);
setPayments(history ?? []);
}
async function reloadVmState() { async function reloadVmState() {
if (!state) return; if (!state) return;
const newState = await login?.api.getVm(state.id); const newState = await login?.api.getVm(state.id);
@ -39,7 +51,29 @@ export function VmBillingPage() {
const className = const className =
"flex items-center justify-between px-3 py-2 bg-neutral-900 rounded-xl cursor-pointer"; "flex items-center justify-between px-3 py-2 bg-neutral-900 rounded-xl cursor-pointer";
const nameRow = (v: PaymentMethod) => {
return (
<div>
{v.name.toUpperCase()} ({v.currencies.join(",")})
</div>
);
};
switch (v.name) { switch (v.name) {
case "lnurl": {
const addr = v.metadata?.["address"];
return (
<div
key={v.name}
className={className}
onClick={() => {
setMethod(v);
}}
>
{nameRow(v)}
<div>{addr}</div>
</div>
);
}
case "lightning": { case "lightning": {
return ( return (
<div <div
@ -50,9 +84,7 @@ export function VmBillingPage() {
renew(v.name); renew(v.name);
}} }}
> >
<div> {nameRow(v)}
{v.name.toUpperCase()} ({v.currencies.join(",")})
</div>
<div className="rounded-lg p-2 bg-green-800">Pay Now</div> <div className="rounded-lg p-2 bg-green-800">Pay Now</div>
</div> </div>
); );
@ -62,9 +94,7 @@ export function VmBillingPage() {
if (!pkey) return <b>Missing Revolut pubkey</b>; if (!pkey) return <b>Missing Revolut pubkey</b>;
return ( return (
<div key={v.name} className={className}> <div key={v.name} className={className}>
<div> {nameRow(v)}
{v.name.toUpperCase()} ({v.currencies.join(",")})
</div>
{state && ( {state && (
<RevolutPayWidget <RevolutPayWidget
mode={import.meta.env.VITE_REVOLUT_MODE} mode={import.meta.env.VITE_REVOLUT_MODE}
@ -110,12 +140,26 @@ export function VmBillingPage() {
if (params["action"] === "renew" && login && state) { if (params["action"] === "renew" && login && state) {
loadPaymentMethods(); loadPaymentMethods();
} }
if (login && state) {
listPayments();
}
}, [login, state, params, renew]); }, [login, state, params, renew]);
if (!state) return; if (!state) return;
const expireDate = new Date(state.expires); const expireDate = new Date(state.expires);
const days = const days =
(expireDate.getTime() - new Date().getTime()) / 1000 / 24 / 60 / 60; (expireDate.getTime() - new Date().getTime()) / 1000 / 24 / 60 / 60;
const lud16 = `${state.id}@${new URL(ApiUrl).host}`;
// Static LNURL payment method
const lnurl = {
name: "lnurl",
currencies: ["BTC"],
metadata: {
address: lud16,
},
} as PaymentMethod;
return ( return (
<div className="flex flex-col gap-4"> <div className="flex flex-col gap-4">
<Link to={"/vm"} state={state}> <Link to={"/vm"} state={state}>
@ -144,7 +188,23 @@ export function VmBillingPage() {
{methods && !method && ( {methods && !method && (
<> <>
<div className="text-xl">Payment Method:</div> <div className="text-xl">Payment Method:</div>
{methods.map((v) => paymentMethod(v))} {[lnurl, ...methods].map((v) => paymentMethod(v))}
</>
)}
{method?.name === "lnurl" && (
<>
<div className="flex flex-col gap-4 rounded-xl p-3 bg-neutral-900 items-center">
<QrCode
data={`lightning:${new LNURL(lud16).lnurl}`}
width={512}
height={512}
avatar="/logo.jpg"
className="cursor-pointer rounded-xl overflow-hidden"
/>
<div className="monospace select-all break-all text-center text-sm">
{lud16}
</div>
</div>
</> </>
)} )}
{payment && ( {payment && (
@ -159,6 +219,69 @@ export function VmBillingPage() {
/> />
</> </>
)} )}
{!methods && (
<>
<div className="text-xl">Payment History</div>
<table className="table bg-neutral-900 rounded-xl text-center">
<thead>
<tr>
<th>Date</th>
<th>Amount</th>
<th>Time</th>
<th>Status</th>
<th></th>
</tr>
</thead>
<tbody>
{payments
.sort(
(a, b) =>
new Date(b.created).getTime() -
new Date(a.created).getTime(),
)
.map((a) => (
<tr key={a.id}>
<td className="pl-4">
{new Date(a.created).toLocaleString()}
</td>
<td>
<CostAmount
cost={{
amount:
(a.amount + a.tax) /
(a.currency === "BTC" ? 1e11 : 100),
currency: a.currency,
}}
converted={false}
/>
</td>
<td>{timeValue(a.time)}</td>
<td>
{a.is_paid
? "Paid"
: new Date(a.expires) <= new Date()
? "Expired"
: "Unpaid"}
</td>
<td>
{a.is_paid && (
<div
title="Generate Invoice"
onClick={async () => {
const l = await login?.api.invoiceLink(a.id);
window.open(l, "_blank");
}}
>
<Icon name="printer" />
</div>
)}
</td>
</tr>
))}
</tbody>
</table>
</>
)}
</div> </div>
); );
} }

View File

@ -1,6 +1,6 @@
import "@xterm/xterm/css/xterm.css"; import "@xterm/xterm/css/xterm.css";
import { useLocation, useNavigate } from "react-router-dom"; import { Link, useLocation, useNavigate } from "react-router-dom";
import { VmInstance, VmIpAssignment } from "../api"; import { VmInstance, VmIpAssignment } from "../api";
import VpsInstanceRow from "../components/vps-instance"; import VpsInstanceRow from "../components/vps-instance";
import useLogin from "../hooks/login"; import useLogin from "../hooks/login";
@ -59,9 +59,10 @@ export default function VmPage() {
); );
} }
const hasNoIps = (state?.ip_assignments?.length ?? 0) === 0;
function networkInfo() { function networkInfo() {
if (!state) return; if (!state) return;
if ((state.ip_assignments?.length ?? 0) === 0) { if (hasNoIps) {
return <div className="text-sm text-red-500">No IP's assigned</div>; return <div className="text-sm text-red-500">No IP's assigned</div>;
} }
return <>{state.ip_assignments?.map((i) => ipRow(i, true))}</>; return <>{state.ip_assignments?.map((i) => ipRow(i, true))}</>;
@ -72,28 +73,48 @@ export default function VmPage() {
return () => clearInterval(t); return () => clearInterval(t);
}, []); }, []);
function bestHost() {
if (!state) return;
if (state.ip_assignments.length > 0) {
const ip = state.ip_assignments.at(0)!;
return ip.forward_dns ? ip.forward_dns : ip.ip.split("/")[0];
}
}
if (!state) { if (!state) {
return <h2>No VM selected</h2>; return <h2>No VM selected</h2>;
} }
return ( return (
<div className="flex flex-col gap-4"> <div className="flex flex-col gap-4">
<Link to={"/account"}>&lt; Back</Link>
<VpsInstanceRow vm={state} actions={true} /> <VpsInstanceRow vm={state} actions={true} />
<div className="text-xl">Network:</div> <div className="text-xl">Network:</div>
<div className="grid grid-cols-2 gap-4">{networkInfo()}</div> <div className="grid grid-cols-2 gap-4">{networkInfo()}</div>
<div className="flex gap-2 items-center"> <div className="text-xl">SSH:</div>
<div className="text-xl">SSH Key:</div> <div className="grid grid-cols-2 gap-4">
<div className="text-sm bg-neutral-900 px-3 py-1 rounded-lg"> <div className="bg-neutral-900 px-2 py-3 rounded-lg flex gap-2 items-center">
{state.ssh_key?.name} <div>Key:</div>
<div className="text-sm bg-neutral-900 px-3 py-1 rounded-lg">
{state.ssh_key?.name}
</div>
<Icon name="pencil" onClick={() => setEditKey(true)} />
</div> </div>
<Icon name="pencil" onClick={() => setEditKey(true)} /> {!hasNoIps && (
<div className="bg-neutral-900 px-2 py-3 rounded-lg flex gap-2 items-center">
<div>Login:</div>
<pre className="select-all bg-neutral-800 px-3 py-1 rounded-full">
ssh {state.image.default_username}@{bestHost()}
</pre>
</div>
)}
</div> </div>
<hr /> <hr />
<div className="flex gap-4"> <div className="flex gap-4">
<AsyncButton onClick={() => navigate("/vm/console", { state })}> {/*<AsyncButton onClick={() => navigate("/vm/console", { state })}>
Console Console
</AsyncButton> </AsyncButton>*/}
<AsyncButton onClick={() => navigate("/vm/billing", { state })}> <AsyncButton onClick={() => navigate("/vm/billing", { state })}>
Billing Billing
</AsyncButton> </AsyncButton>

View File

@ -51,3 +51,29 @@ export function toEui64(prefix: string, mac: string) {
base16.encode(macExtended.subarray(6, 8)) base16.encode(macExtended.subarray(6, 8))
).toLowerCase(); ).toLowerCase();
} }
export function timeValue(n: number): string {
if (!Number.isFinite(n) || n < 0) {
return "Invalid input";
}
if (n >= 86400) {
const days = Math.floor(n / 86400);
return days.toLocaleString() + " day" + (days !== 1 ? "s" : "");
}
if (n >= 3600) {
const hours = Math.floor(n / 3600);
const minutes = Math.floor((n % 3600) / 60);
return (
hours +
" hr" +
(hours !== 1 ? "s" : "") +
(minutes > 0 ? " " + minutes + " min" + (minutes !== 1 ? "s" : "") : "")
);
}
if (n >= 60) {
const minutes = Math.floor(n / 60);
return minutes + " min" + (minutes !== 1 ? "s" : "");
}
return n + " sec" + (n !== 1 ? "s" : "");
}

495
yarn.lock
View File

@ -250,163 +250,177 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/aix-ppc64@npm:0.21.5": "@esbuild/aix-ppc64@npm:0.25.3":
version: 0.21.5 version: 0.25.3
resolution: "@esbuild/aix-ppc64@npm:0.21.5" resolution: "@esbuild/aix-ppc64@npm:0.25.3"
conditions: os=aix & cpu=ppc64 conditions: os=aix & cpu=ppc64
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/android-arm64@npm:0.21.5": "@esbuild/android-arm64@npm:0.25.3":
version: 0.21.5 version: 0.25.3
resolution: "@esbuild/android-arm64@npm:0.21.5" resolution: "@esbuild/android-arm64@npm:0.25.3"
conditions: os=android & cpu=arm64 conditions: os=android & cpu=arm64
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/android-arm@npm:0.21.5": "@esbuild/android-arm@npm:0.25.3":
version: 0.21.5 version: 0.25.3
resolution: "@esbuild/android-arm@npm:0.21.5" resolution: "@esbuild/android-arm@npm:0.25.3"
conditions: os=android & cpu=arm conditions: os=android & cpu=arm
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/android-x64@npm:0.21.5": "@esbuild/android-x64@npm:0.25.3":
version: 0.21.5 version: 0.25.3
resolution: "@esbuild/android-x64@npm:0.21.5" resolution: "@esbuild/android-x64@npm:0.25.3"
conditions: os=android & cpu=x64 conditions: os=android & cpu=x64
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/darwin-arm64@npm:0.21.5": "@esbuild/darwin-arm64@npm:0.25.3":
version: 0.21.5 version: 0.25.3
resolution: "@esbuild/darwin-arm64@npm:0.21.5" resolution: "@esbuild/darwin-arm64@npm:0.25.3"
conditions: os=darwin & cpu=arm64 conditions: os=darwin & cpu=arm64
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/darwin-x64@npm:0.21.5": "@esbuild/darwin-x64@npm:0.25.3":
version: 0.21.5 version: 0.25.3
resolution: "@esbuild/darwin-x64@npm:0.21.5" resolution: "@esbuild/darwin-x64@npm:0.25.3"
conditions: os=darwin & cpu=x64 conditions: os=darwin & cpu=x64
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/freebsd-arm64@npm:0.21.5": "@esbuild/freebsd-arm64@npm:0.25.3":
version: 0.21.5 version: 0.25.3
resolution: "@esbuild/freebsd-arm64@npm:0.21.5" resolution: "@esbuild/freebsd-arm64@npm:0.25.3"
conditions: os=freebsd & cpu=arm64 conditions: os=freebsd & cpu=arm64
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/freebsd-x64@npm:0.21.5": "@esbuild/freebsd-x64@npm:0.25.3":
version: 0.21.5 version: 0.25.3
resolution: "@esbuild/freebsd-x64@npm:0.21.5" resolution: "@esbuild/freebsd-x64@npm:0.25.3"
conditions: os=freebsd & cpu=x64 conditions: os=freebsd & cpu=x64
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/linux-arm64@npm:0.21.5": "@esbuild/linux-arm64@npm:0.25.3":
version: 0.21.5 version: 0.25.3
resolution: "@esbuild/linux-arm64@npm:0.21.5" resolution: "@esbuild/linux-arm64@npm:0.25.3"
conditions: os=linux & cpu=arm64 conditions: os=linux & cpu=arm64
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/linux-arm@npm:0.21.5": "@esbuild/linux-arm@npm:0.25.3":
version: 0.21.5 version: 0.25.3
resolution: "@esbuild/linux-arm@npm:0.21.5" resolution: "@esbuild/linux-arm@npm:0.25.3"
conditions: os=linux & cpu=arm conditions: os=linux & cpu=arm
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/linux-ia32@npm:0.21.5": "@esbuild/linux-ia32@npm:0.25.3":
version: 0.21.5 version: 0.25.3
resolution: "@esbuild/linux-ia32@npm:0.21.5" resolution: "@esbuild/linux-ia32@npm:0.25.3"
conditions: os=linux & cpu=ia32 conditions: os=linux & cpu=ia32
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/linux-loong64@npm:0.21.5": "@esbuild/linux-loong64@npm:0.25.3":
version: 0.21.5 version: 0.25.3
resolution: "@esbuild/linux-loong64@npm:0.21.5" resolution: "@esbuild/linux-loong64@npm:0.25.3"
conditions: os=linux & cpu=loong64 conditions: os=linux & cpu=loong64
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/linux-mips64el@npm:0.21.5": "@esbuild/linux-mips64el@npm:0.25.3":
version: 0.21.5 version: 0.25.3
resolution: "@esbuild/linux-mips64el@npm:0.21.5" resolution: "@esbuild/linux-mips64el@npm:0.25.3"
conditions: os=linux & cpu=mips64el conditions: os=linux & cpu=mips64el
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/linux-ppc64@npm:0.21.5": "@esbuild/linux-ppc64@npm:0.25.3":
version: 0.21.5 version: 0.25.3
resolution: "@esbuild/linux-ppc64@npm:0.21.5" resolution: "@esbuild/linux-ppc64@npm:0.25.3"
conditions: os=linux & cpu=ppc64 conditions: os=linux & cpu=ppc64
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/linux-riscv64@npm:0.21.5": "@esbuild/linux-riscv64@npm:0.25.3":
version: 0.21.5 version: 0.25.3
resolution: "@esbuild/linux-riscv64@npm:0.21.5" resolution: "@esbuild/linux-riscv64@npm:0.25.3"
conditions: os=linux & cpu=riscv64 conditions: os=linux & cpu=riscv64
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/linux-s390x@npm:0.21.5": "@esbuild/linux-s390x@npm:0.25.3":
version: 0.21.5 version: 0.25.3
resolution: "@esbuild/linux-s390x@npm:0.21.5" resolution: "@esbuild/linux-s390x@npm:0.25.3"
conditions: os=linux & cpu=s390x conditions: os=linux & cpu=s390x
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/linux-x64@npm:0.21.5": "@esbuild/linux-x64@npm:0.25.3":
version: 0.21.5 version: 0.25.3
resolution: "@esbuild/linux-x64@npm:0.21.5" resolution: "@esbuild/linux-x64@npm:0.25.3"
conditions: os=linux & cpu=x64 conditions: os=linux & cpu=x64
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/netbsd-x64@npm:0.21.5": "@esbuild/netbsd-arm64@npm:0.25.3":
version: 0.21.5 version: 0.25.3
resolution: "@esbuild/netbsd-x64@npm:0.21.5" resolution: "@esbuild/netbsd-arm64@npm:0.25.3"
conditions: os=netbsd & cpu=arm64
languageName: node
linkType: hard
"@esbuild/netbsd-x64@npm:0.25.3":
version: 0.25.3
resolution: "@esbuild/netbsd-x64@npm:0.25.3"
conditions: os=netbsd & cpu=x64 conditions: os=netbsd & cpu=x64
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/openbsd-x64@npm:0.21.5": "@esbuild/openbsd-arm64@npm:0.25.3":
version: 0.21.5 version: 0.25.3
resolution: "@esbuild/openbsd-x64@npm:0.21.5" resolution: "@esbuild/openbsd-arm64@npm:0.25.3"
conditions: os=openbsd & cpu=arm64
languageName: node
linkType: hard
"@esbuild/openbsd-x64@npm:0.25.3":
version: 0.25.3
resolution: "@esbuild/openbsd-x64@npm:0.25.3"
conditions: os=openbsd & cpu=x64 conditions: os=openbsd & cpu=x64
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/sunos-x64@npm:0.21.5": "@esbuild/sunos-x64@npm:0.25.3":
version: 0.21.5 version: 0.25.3
resolution: "@esbuild/sunos-x64@npm:0.21.5" resolution: "@esbuild/sunos-x64@npm:0.25.3"
conditions: os=sunos & cpu=x64 conditions: os=sunos & cpu=x64
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/win32-arm64@npm:0.21.5": "@esbuild/win32-arm64@npm:0.25.3":
version: 0.21.5 version: 0.25.3
resolution: "@esbuild/win32-arm64@npm:0.21.5" resolution: "@esbuild/win32-arm64@npm:0.25.3"
conditions: os=win32 & cpu=arm64 conditions: os=win32 & cpu=arm64
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/win32-ia32@npm:0.21.5": "@esbuild/win32-ia32@npm:0.25.3":
version: 0.21.5 version: 0.25.3
resolution: "@esbuild/win32-ia32@npm:0.21.5" resolution: "@esbuild/win32-ia32@npm:0.25.3"
conditions: os=win32 & cpu=ia32 conditions: os=win32 & cpu=ia32
languageName: node languageName: node
linkType: hard linkType: hard
"@esbuild/win32-x64@npm:0.21.5": "@esbuild/win32-x64@npm:0.25.3":
version: 0.21.5 version: 0.25.3
resolution: "@esbuild/win32-x64@npm:0.21.5" resolution: "@esbuild/win32-x64@npm:0.25.3"
conditions: os=win32 & cpu=x64 conditions: os=win32 & cpu=x64
languageName: node languageName: node
linkType: hard linkType: hard
@ -627,114 +641,142 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@rollup/rollup-android-arm-eabi@npm:4.20.0": "@rollup/rollup-android-arm-eabi@npm:4.40.1":
version: 4.20.0 version: 4.40.1
resolution: "@rollup/rollup-android-arm-eabi@npm:4.20.0" resolution: "@rollup/rollup-android-arm-eabi@npm:4.40.1"
conditions: os=android & cpu=arm conditions: os=android & cpu=arm
languageName: node languageName: node
linkType: hard linkType: hard
"@rollup/rollup-android-arm64@npm:4.20.0": "@rollup/rollup-android-arm64@npm:4.40.1":
version: 4.20.0 version: 4.40.1
resolution: "@rollup/rollup-android-arm64@npm:4.20.0" resolution: "@rollup/rollup-android-arm64@npm:4.40.1"
conditions: os=android & cpu=arm64 conditions: os=android & cpu=arm64
languageName: node languageName: node
linkType: hard linkType: hard
"@rollup/rollup-darwin-arm64@npm:4.20.0": "@rollup/rollup-darwin-arm64@npm:4.40.1":
version: 4.20.0 version: 4.40.1
resolution: "@rollup/rollup-darwin-arm64@npm:4.20.0" resolution: "@rollup/rollup-darwin-arm64@npm:4.40.1"
conditions: os=darwin & cpu=arm64 conditions: os=darwin & cpu=arm64
languageName: node languageName: node
linkType: hard linkType: hard
"@rollup/rollup-darwin-x64@npm:4.20.0": "@rollup/rollup-darwin-x64@npm:4.40.1":
version: 4.20.0 version: 4.40.1
resolution: "@rollup/rollup-darwin-x64@npm:4.20.0" resolution: "@rollup/rollup-darwin-x64@npm:4.40.1"
conditions: os=darwin & cpu=x64 conditions: os=darwin & cpu=x64
languageName: node languageName: node
linkType: hard linkType: hard
"@rollup/rollup-linux-arm-gnueabihf@npm:4.20.0": "@rollup/rollup-freebsd-arm64@npm:4.40.1":
version: 4.20.0 version: 4.40.1
resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.20.0" resolution: "@rollup/rollup-freebsd-arm64@npm:4.40.1"
conditions: os=freebsd & cpu=arm64
languageName: node
linkType: hard
"@rollup/rollup-freebsd-x64@npm:4.40.1":
version: 4.40.1
resolution: "@rollup/rollup-freebsd-x64@npm:4.40.1"
conditions: os=freebsd & cpu=x64
languageName: node
linkType: hard
"@rollup/rollup-linux-arm-gnueabihf@npm:4.40.1":
version: 4.40.1
resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.40.1"
conditions: os=linux & cpu=arm & libc=glibc conditions: os=linux & cpu=arm & libc=glibc
languageName: node languageName: node
linkType: hard linkType: hard
"@rollup/rollup-linux-arm-musleabihf@npm:4.20.0": "@rollup/rollup-linux-arm-musleabihf@npm:4.40.1":
version: 4.20.0 version: 4.40.1
resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.20.0" resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.40.1"
conditions: os=linux & cpu=arm & libc=musl conditions: os=linux & cpu=arm & libc=musl
languageName: node languageName: node
linkType: hard linkType: hard
"@rollup/rollup-linux-arm64-gnu@npm:4.20.0": "@rollup/rollup-linux-arm64-gnu@npm:4.40.1":
version: 4.20.0 version: 4.40.1
resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.20.0" resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.40.1"
conditions: os=linux & cpu=arm64 & libc=glibc conditions: os=linux & cpu=arm64 & libc=glibc
languageName: node languageName: node
linkType: hard linkType: hard
"@rollup/rollup-linux-arm64-musl@npm:4.20.0": "@rollup/rollup-linux-arm64-musl@npm:4.40.1":
version: 4.20.0 version: 4.40.1
resolution: "@rollup/rollup-linux-arm64-musl@npm:4.20.0" resolution: "@rollup/rollup-linux-arm64-musl@npm:4.40.1"
conditions: os=linux & cpu=arm64 & libc=musl conditions: os=linux & cpu=arm64 & libc=musl
languageName: node languageName: node
linkType: hard linkType: hard
"@rollup/rollup-linux-powerpc64le-gnu@npm:4.20.0": "@rollup/rollup-linux-loongarch64-gnu@npm:4.40.1":
version: 4.20.0 version: 4.40.1
resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.20.0" resolution: "@rollup/rollup-linux-loongarch64-gnu@npm:4.40.1"
conditions: os=linux & cpu=loong64 & libc=glibc
languageName: node
linkType: hard
"@rollup/rollup-linux-powerpc64le-gnu@npm:4.40.1":
version: 4.40.1
resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.40.1"
conditions: os=linux & cpu=ppc64 & libc=glibc conditions: os=linux & cpu=ppc64 & libc=glibc
languageName: node languageName: node
linkType: hard linkType: hard
"@rollup/rollup-linux-riscv64-gnu@npm:4.20.0": "@rollup/rollup-linux-riscv64-gnu@npm:4.40.1":
version: 4.20.0 version: 4.40.1
resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.20.0" resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.40.1"
conditions: os=linux & cpu=riscv64 & libc=glibc conditions: os=linux & cpu=riscv64 & libc=glibc
languageName: node languageName: node
linkType: hard linkType: hard
"@rollup/rollup-linux-s390x-gnu@npm:4.20.0": "@rollup/rollup-linux-riscv64-musl@npm:4.40.1":
version: 4.20.0 version: 4.40.1
resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.20.0" resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.40.1"
conditions: os=linux & cpu=riscv64 & libc=musl
languageName: node
linkType: hard
"@rollup/rollup-linux-s390x-gnu@npm:4.40.1":
version: 4.40.1
resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.40.1"
conditions: os=linux & cpu=s390x & libc=glibc conditions: os=linux & cpu=s390x & libc=glibc
languageName: node languageName: node
linkType: hard linkType: hard
"@rollup/rollup-linux-x64-gnu@npm:4.20.0": "@rollup/rollup-linux-x64-gnu@npm:4.40.1":
version: 4.20.0 version: 4.40.1
resolution: "@rollup/rollup-linux-x64-gnu@npm:4.20.0" resolution: "@rollup/rollup-linux-x64-gnu@npm:4.40.1"
conditions: os=linux & cpu=x64 & libc=glibc conditions: os=linux & cpu=x64 & libc=glibc
languageName: node languageName: node
linkType: hard linkType: hard
"@rollup/rollup-linux-x64-musl@npm:4.20.0": "@rollup/rollup-linux-x64-musl@npm:4.40.1":
version: 4.20.0 version: 4.40.1
resolution: "@rollup/rollup-linux-x64-musl@npm:4.20.0" resolution: "@rollup/rollup-linux-x64-musl@npm:4.40.1"
conditions: os=linux & cpu=x64 & libc=musl conditions: os=linux & cpu=x64 & libc=musl
languageName: node languageName: node
linkType: hard linkType: hard
"@rollup/rollup-win32-arm64-msvc@npm:4.20.0": "@rollup/rollup-win32-arm64-msvc@npm:4.40.1":
version: 4.20.0 version: 4.40.1
resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.20.0" resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.40.1"
conditions: os=win32 & cpu=arm64 conditions: os=win32 & cpu=arm64
languageName: node languageName: node
linkType: hard linkType: hard
"@rollup/rollup-win32-ia32-msvc@npm:4.20.0": "@rollup/rollup-win32-ia32-msvc@npm:4.40.1":
version: 4.20.0 version: 4.40.1
resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.20.0" resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.40.1"
conditions: os=win32 & cpu=ia32 conditions: os=win32 & cpu=ia32
languageName: node languageName: node
linkType: hard linkType: hard
"@rollup/rollup-win32-x64-msvc@npm:4.20.0": "@rollup/rollup-win32-x64-msvc@npm:4.40.1":
version: 4.20.0 version: 4.40.1
resolution: "@rollup/rollup-win32-x64-msvc@npm:4.20.0" resolution: "@rollup/rollup-win32-x64-msvc@npm:4.40.1"
conditions: os=win32 & cpu=x64 conditions: os=win32 & cpu=x64
languageName: node languageName: node
linkType: hard linkType: hard
@ -967,10 +1009,10 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/estree@npm:1.0.5": "@types/estree@npm:1.0.7":
version: 1.0.5 version: 1.0.7
resolution: "@types/estree@npm:1.0.5" resolution: "@types/estree@npm:1.0.7"
checksum: 10c0/b3b0e334288ddb407c7b3357ca67dbee75ee22db242ca7c56fe27db4e1a31989cb8af48a84dd401deb787fe10cc6b2ab1ee82dc4783be87ededbe3d53c79c70d checksum: 10c0/be815254316882f7c40847336cd484c3bc1c3e34f710d197160d455dc9d6d050ffbf4c3bc76585dba86f737f020ab20bdb137ebe0e9116b0c86c7c0342221b8c
languageName: node languageName: node
linkType: hard linkType: hard
@ -1771,33 +1813,35 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"esbuild@npm:^0.21.3": "esbuild@npm:^0.25.0":
version: 0.21.5 version: 0.25.3
resolution: "esbuild@npm:0.21.5" resolution: "esbuild@npm:0.25.3"
dependencies: dependencies:
"@esbuild/aix-ppc64": "npm:0.21.5" "@esbuild/aix-ppc64": "npm:0.25.3"
"@esbuild/android-arm": "npm:0.21.5" "@esbuild/android-arm": "npm:0.25.3"
"@esbuild/android-arm64": "npm:0.21.5" "@esbuild/android-arm64": "npm:0.25.3"
"@esbuild/android-x64": "npm:0.21.5" "@esbuild/android-x64": "npm:0.25.3"
"@esbuild/darwin-arm64": "npm:0.21.5" "@esbuild/darwin-arm64": "npm:0.25.3"
"@esbuild/darwin-x64": "npm:0.21.5" "@esbuild/darwin-x64": "npm:0.25.3"
"@esbuild/freebsd-arm64": "npm:0.21.5" "@esbuild/freebsd-arm64": "npm:0.25.3"
"@esbuild/freebsd-x64": "npm:0.21.5" "@esbuild/freebsd-x64": "npm:0.25.3"
"@esbuild/linux-arm": "npm:0.21.5" "@esbuild/linux-arm": "npm:0.25.3"
"@esbuild/linux-arm64": "npm:0.21.5" "@esbuild/linux-arm64": "npm:0.25.3"
"@esbuild/linux-ia32": "npm:0.21.5" "@esbuild/linux-ia32": "npm:0.25.3"
"@esbuild/linux-loong64": "npm:0.21.5" "@esbuild/linux-loong64": "npm:0.25.3"
"@esbuild/linux-mips64el": "npm:0.21.5" "@esbuild/linux-mips64el": "npm:0.25.3"
"@esbuild/linux-ppc64": "npm:0.21.5" "@esbuild/linux-ppc64": "npm:0.25.3"
"@esbuild/linux-riscv64": "npm:0.21.5" "@esbuild/linux-riscv64": "npm:0.25.3"
"@esbuild/linux-s390x": "npm:0.21.5" "@esbuild/linux-s390x": "npm:0.25.3"
"@esbuild/linux-x64": "npm:0.21.5" "@esbuild/linux-x64": "npm:0.25.3"
"@esbuild/netbsd-x64": "npm:0.21.5" "@esbuild/netbsd-arm64": "npm:0.25.3"
"@esbuild/openbsd-x64": "npm:0.21.5" "@esbuild/netbsd-x64": "npm:0.25.3"
"@esbuild/sunos-x64": "npm:0.21.5" "@esbuild/openbsd-arm64": "npm:0.25.3"
"@esbuild/win32-arm64": "npm:0.21.5" "@esbuild/openbsd-x64": "npm:0.25.3"
"@esbuild/win32-ia32": "npm:0.21.5" "@esbuild/sunos-x64": "npm:0.25.3"
"@esbuild/win32-x64": "npm:0.21.5" "@esbuild/win32-arm64": "npm:0.25.3"
"@esbuild/win32-ia32": "npm:0.25.3"
"@esbuild/win32-x64": "npm:0.25.3"
dependenciesMeta: dependenciesMeta:
"@esbuild/aix-ppc64": "@esbuild/aix-ppc64":
optional: true optional: true
@ -1833,8 +1877,12 @@ __metadata:
optional: true optional: true
"@esbuild/linux-x64": "@esbuild/linux-x64":
optional: true optional: true
"@esbuild/netbsd-arm64":
optional: true
"@esbuild/netbsd-x64": "@esbuild/netbsd-x64":
optional: true optional: true
"@esbuild/openbsd-arm64":
optional: true
"@esbuild/openbsd-x64": "@esbuild/openbsd-x64":
optional: true optional: true
"@esbuild/sunos-x64": "@esbuild/sunos-x64":
@ -1847,7 +1895,7 @@ __metadata:
optional: true optional: true
bin: bin:
esbuild: bin/esbuild esbuild: bin/esbuild
checksum: 10c0/fa08508adf683c3f399e8a014a6382a6b65542213431e26206c0720e536b31c09b50798747c2a105a4bbba1d9767b8d3615a74c2f7bf1ddf6d836cd11eb672de checksum: 10c0/127aff654310ede4e2eb232a7b1d8823f5b5d69222caf17aa7f172574a5b6b75f71ce78c6d8a40030421d7c75b784dc640de0fb1b87b7ea77ab2a1c832fa8df8
languageName: node languageName: node
linkType: hard linkType: hard
@ -2072,6 +2120,18 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"fdir@npm:^6.4.4":
version: 6.4.4
resolution: "fdir@npm:6.4.4"
peerDependencies:
picomatch: ^3 || ^4
peerDependenciesMeta:
picomatch:
optional: true
checksum: 10c0/6ccc33be16945ee7bc841e1b4178c0b4cf18d3804894cb482aa514651c962a162f96da7ffc6ebfaf0df311689fb70091b04dd6caffe28d56b9ebdc0e7ccadfdd
languageName: node
linkType: hard
"file-entry-cache@npm:^8.0.0": "file-entry-cache@npm:^8.0.0":
version: 8.0.0 version: 8.0.0
resolution: "file-entry-cache@npm:8.0.0" resolution: "file-entry-cache@npm:8.0.0"
@ -2637,7 +2697,7 @@ __metadata:
tailwindcss: "npm:^3.4.8" tailwindcss: "npm:^3.4.8"
typescript: "npm:^5.5.3" typescript: "npm:^5.5.3"
typescript-eslint: "npm:^8.0.0" typescript-eslint: "npm:^8.0.0"
vite: "npm:^5.4.0" vite: "npm:^6.3.4"
languageName: unknown languageName: unknown
linkType: soft linkType: soft
@ -2875,6 +2935,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"nanoid@npm:^3.3.8":
version: 3.3.11
resolution: "nanoid@npm:3.3.11"
bin:
nanoid: bin/nanoid.cjs
checksum: 10c0/40e7f70b3d15f725ca072dfc4f74e81fcf1fbb02e491cf58ac0c79093adc9b0a73b152bcde57df4b79cd097e13023d7504acb38404a4da7bc1cd8e887b82fe0b
languageName: node
linkType: hard
"natural-compare@npm:^1.4.0": "natural-compare@npm:^1.4.0":
version: 1.4.0 version: 1.4.0
resolution: "natural-compare@npm:1.4.0" resolution: "natural-compare@npm:1.4.0"
@ -3064,6 +3133,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"picocolors@npm:^1.1.1":
version: 1.1.1
resolution: "picocolors@npm:1.1.1"
checksum: 10c0/e2e3e8170ab9d7c7421969adaa7e1b31434f789afb9b3f115f6b96d91945041ac3ceb02e9ec6fe6510ff036bcc0bf91e69a1772edc0b707e12b19c0f2d6bcf58
languageName: node
linkType: hard
"picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.3.1": "picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.3.1":
version: 2.3.1 version: 2.3.1
resolution: "picomatch@npm:2.3.1" resolution: "picomatch@npm:2.3.1"
@ -3071,6 +3147,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"picomatch@npm:^4.0.2":
version: 4.0.2
resolution: "picomatch@npm:4.0.2"
checksum: 10c0/7c51f3ad2bb42c776f49ebf964c644958158be30d0a510efd5a395e8d49cb5acfed5b82c0c5b365523ce18e6ab85013c9ebe574f60305892ec3fa8eee8304ccc
languageName: node
linkType: hard
"pify@npm:^2.3.0": "pify@npm:^2.3.0":
version: 2.3.0 version: 2.3.0
resolution: "pify@npm:2.3.0" resolution: "pify@npm:2.3.0"
@ -3155,7 +3238,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"postcss@npm:^8.4.23, postcss@npm:^8.4.40, postcss@npm:^8.4.41": "postcss@npm:^8.4.23, postcss@npm:^8.4.41":
version: 8.4.41 version: 8.4.41
resolution: "postcss@npm:8.4.41" resolution: "postcss@npm:8.4.41"
dependencies: dependencies:
@ -3166,6 +3249,17 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"postcss@npm:^8.5.3":
version: 8.5.3
resolution: "postcss@npm:8.5.3"
dependencies:
nanoid: "npm:^3.3.8"
picocolors: "npm:^1.1.1"
source-map-js: "npm:^1.2.1"
checksum: 10c0/b75510d7b28c3ab728c8733dd01538314a18c52af426f199a3c9177e63eb08602a3938bfb66b62dc01350b9aed62087eabbf229af97a1659eb8d3513cec823b3
languageName: node
linkType: hard
"prelude-ls@npm:^1.2.1": "prelude-ls@npm:^1.2.1":
version: 1.2.1 version: 1.2.1
resolution: "prelude-ls@npm:1.2.1" resolution: "prelude-ls@npm:1.2.1"
@ -3441,27 +3535,31 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"rollup@npm:^4.13.0": "rollup@npm:^4.34.9":
version: 4.20.0 version: 4.40.1
resolution: "rollup@npm:4.20.0" resolution: "rollup@npm:4.40.1"
dependencies: dependencies:
"@rollup/rollup-android-arm-eabi": "npm:4.20.0" "@rollup/rollup-android-arm-eabi": "npm:4.40.1"
"@rollup/rollup-android-arm64": "npm:4.20.0" "@rollup/rollup-android-arm64": "npm:4.40.1"
"@rollup/rollup-darwin-arm64": "npm:4.20.0" "@rollup/rollup-darwin-arm64": "npm:4.40.1"
"@rollup/rollup-darwin-x64": "npm:4.20.0" "@rollup/rollup-darwin-x64": "npm:4.40.1"
"@rollup/rollup-linux-arm-gnueabihf": "npm:4.20.0" "@rollup/rollup-freebsd-arm64": "npm:4.40.1"
"@rollup/rollup-linux-arm-musleabihf": "npm:4.20.0" "@rollup/rollup-freebsd-x64": "npm:4.40.1"
"@rollup/rollup-linux-arm64-gnu": "npm:4.20.0" "@rollup/rollup-linux-arm-gnueabihf": "npm:4.40.1"
"@rollup/rollup-linux-arm64-musl": "npm:4.20.0" "@rollup/rollup-linux-arm-musleabihf": "npm:4.40.1"
"@rollup/rollup-linux-powerpc64le-gnu": "npm:4.20.0" "@rollup/rollup-linux-arm64-gnu": "npm:4.40.1"
"@rollup/rollup-linux-riscv64-gnu": "npm:4.20.0" "@rollup/rollup-linux-arm64-musl": "npm:4.40.1"
"@rollup/rollup-linux-s390x-gnu": "npm:4.20.0" "@rollup/rollup-linux-loongarch64-gnu": "npm:4.40.1"
"@rollup/rollup-linux-x64-gnu": "npm:4.20.0" "@rollup/rollup-linux-powerpc64le-gnu": "npm:4.40.1"
"@rollup/rollup-linux-x64-musl": "npm:4.20.0" "@rollup/rollup-linux-riscv64-gnu": "npm:4.40.1"
"@rollup/rollup-win32-arm64-msvc": "npm:4.20.0" "@rollup/rollup-linux-riscv64-musl": "npm:4.40.1"
"@rollup/rollup-win32-ia32-msvc": "npm:4.20.0" "@rollup/rollup-linux-s390x-gnu": "npm:4.40.1"
"@rollup/rollup-win32-x64-msvc": "npm:4.20.0" "@rollup/rollup-linux-x64-gnu": "npm:4.40.1"
"@types/estree": "npm:1.0.5" "@rollup/rollup-linux-x64-musl": "npm:4.40.1"
"@rollup/rollup-win32-arm64-msvc": "npm:4.40.1"
"@rollup/rollup-win32-ia32-msvc": "npm:4.40.1"
"@rollup/rollup-win32-x64-msvc": "npm:4.40.1"
"@types/estree": "npm:1.0.7"
fsevents: "npm:~2.3.2" fsevents: "npm:~2.3.2"
dependenciesMeta: dependenciesMeta:
"@rollup/rollup-android-arm-eabi": "@rollup/rollup-android-arm-eabi":
@ -3472,6 +3570,10 @@ __metadata:
optional: true optional: true
"@rollup/rollup-darwin-x64": "@rollup/rollup-darwin-x64":
optional: true optional: true
"@rollup/rollup-freebsd-arm64":
optional: true
"@rollup/rollup-freebsd-x64":
optional: true
"@rollup/rollup-linux-arm-gnueabihf": "@rollup/rollup-linux-arm-gnueabihf":
optional: true optional: true
"@rollup/rollup-linux-arm-musleabihf": "@rollup/rollup-linux-arm-musleabihf":
@ -3480,10 +3582,14 @@ __metadata:
optional: true optional: true
"@rollup/rollup-linux-arm64-musl": "@rollup/rollup-linux-arm64-musl":
optional: true optional: true
"@rollup/rollup-linux-loongarch64-gnu":
optional: true
"@rollup/rollup-linux-powerpc64le-gnu": "@rollup/rollup-linux-powerpc64le-gnu":
optional: true optional: true
"@rollup/rollup-linux-riscv64-gnu": "@rollup/rollup-linux-riscv64-gnu":
optional: true optional: true
"@rollup/rollup-linux-riscv64-musl":
optional: true
"@rollup/rollup-linux-s390x-gnu": "@rollup/rollup-linux-s390x-gnu":
optional: true optional: true
"@rollup/rollup-linux-x64-gnu": "@rollup/rollup-linux-x64-gnu":
@ -3500,7 +3606,7 @@ __metadata:
optional: true optional: true
bin: bin:
rollup: dist/bin/rollup rollup: dist/bin/rollup
checksum: 10c0/9b23bf0e3380e64573a5f68a55274d5c7969036e55c19aab9fb4deea2e938d76769db70f3c95ee3783c24af152bea1772ad73f9e3625b6ffd4e600a788fe97ea checksum: 10c0/11c44b5ef9b3fd521c5501b3f1c36af4ca07821aeff41d41f45336eee324d8f5b46c1a92189f5c8cd146bc21ac10418d57cb4571637ea09aced1ae831a2a4ae0
languageName: node languageName: node
linkType: hard linkType: hard
@ -3619,6 +3725,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"source-map-js@npm:^1.2.1":
version: 1.2.1
resolution: "source-map-js@npm:1.2.1"
checksum: 10c0/7bda1fc4c197e3c6ff17de1b8b2c20e60af81b63a52cb32ec5a5d67a20a7d42651e2cb34ebe93833c5a2a084377e17455854fee3e21e7925c64a51b6a52b0faf
languageName: node
linkType: hard
"sprintf-js@npm:^1.1.3": "sprintf-js@npm:^1.1.3":
version: 1.1.3 version: 1.1.3
resolution: "sprintf-js@npm:1.1.3" resolution: "sprintf-js@npm:1.1.3"
@ -3804,6 +3917,16 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"tinyglobby@npm:^0.2.13":
version: 0.2.13
resolution: "tinyglobby@npm:0.2.13"
dependencies:
fdir: "npm:^6.4.4"
picomatch: "npm:^4.0.2"
checksum: 10c0/ef07dfaa7b26936601d3f6d999f7928a4d1c6234c5eb36896bb88681947c0d459b7ebe797022400e555fe4b894db06e922b95d0ce60cb05fd827a0a66326b18c
languageName: node
linkType: hard
"to-fast-properties@npm:^2.0.0": "to-fast-properties@npm:^2.0.0":
version: 2.0.0 version: 2.0.0
resolution: "to-fast-properties@npm:2.0.0" resolution: "to-fast-properties@npm:2.0.0"
@ -3965,29 +4088,37 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"vite@npm:^5.4.0": "vite@npm:^6.3.4":
version: 5.4.0 version: 6.3.4
resolution: "vite@npm:5.4.0" resolution: "vite@npm:6.3.4"
dependencies: dependencies:
esbuild: "npm:^0.21.3" esbuild: "npm:^0.25.0"
fdir: "npm:^6.4.4"
fsevents: "npm:~2.3.3" fsevents: "npm:~2.3.3"
postcss: "npm:^8.4.40" picomatch: "npm:^4.0.2"
rollup: "npm:^4.13.0" postcss: "npm:^8.5.3"
rollup: "npm:^4.34.9"
tinyglobby: "npm:^0.2.13"
peerDependencies: peerDependencies:
"@types/node": ^18.0.0 || >=20.0.0 "@types/node": ^18.0.0 || ^20.0.0 || >=22.0.0
jiti: ">=1.21.0"
less: "*" less: "*"
lightningcss: ^1.21.0 lightningcss: ^1.21.0
sass: "*" sass: "*"
sass-embedded: "*" sass-embedded: "*"
stylus: "*" stylus: "*"
sugarss: "*" sugarss: "*"
terser: ^5.4.0 terser: ^5.16.0
tsx: ^4.8.1
yaml: ^2.4.2
dependenciesMeta: dependenciesMeta:
fsevents: fsevents:
optional: true optional: true
peerDependenciesMeta: peerDependenciesMeta:
"@types/node": "@types/node":
optional: true optional: true
jiti:
optional: true
less: less:
optional: true optional: true
lightningcss: lightningcss:
@ -4002,9 +4133,13 @@ __metadata:
optional: true optional: true
terser: terser:
optional: true optional: true
tsx:
optional: true
yaml:
optional: true
bin: bin:
vite: bin/vite.js vite: bin/vite.js
checksum: 10c0/122de7795e1c3c08cd0acc7d77296f908398266b424492be7310400107f37a3cf4c9506f2b4b16619e57299ca2859b8ca187aac5e25f8e66d84f9204a1d72d18 checksum: 10c0/f1534a3f42d14b30e11c58e5e451903d965d5f5ba18d8c81f9df208589e3d2c65535abaa3268d3963573174b8e056ea7bc445f567622c65fcdf98eb4acc1bf4e
languageName: node languageName: node
linkType: hard linkType: hard