forked from btclock/webui
Compare commits
14 commits
forgejo-ci
...
main
Author | SHA1 | Date | |
---|---|---|---|
|
85b9b17506 | ||
|
eff18ba0c3 | ||
|
266a99be96 | ||
|
653a39d0a3 | ||
|
68c247f3cc | ||
|
25e91b2086 | ||
|
f0fa58b5ea | ||
|
b8ed628bf5 | ||
|
00af5f6521 | ||
|
51cce2ee9f | ||
|
de99a221d6 | ||
|
93482b3be2 | ||
|
d74e9dab60 | ||
|
da3c70285d |
28 changed files with 1592 additions and 994 deletions
|
@ -81,7 +81,7 @@ jobs:
|
|||
- name: Check GZipped directory size
|
||||
run: |
|
||||
# Set the threshold size in bytes
|
||||
THRESHOLD=409600
|
||||
THRESHOLD=410000
|
||||
|
||||
# Calculate the total size of files in the directory
|
||||
DIRECTORY_SIZE=$(du -b -s build_gz | awk '{print $1}')
|
||||
|
@ -98,7 +98,7 @@ jobs:
|
|||
- name: Build LittleFS
|
||||
run: |
|
||||
set -e
|
||||
/tmp/mklittlefs/mklittlefs -c build_gz -s 409600 output/littlefs.bin
|
||||
/tmp/mklittlefs/mklittlefs -c build_gz -s 410000 output/littlefs.bin
|
||||
- name: Upload artifacts
|
||||
uses: https://code.forgejo.org/forgejo/upload-artifact@v4
|
||||
with:
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
"postinstall": "patch-package",
|
||||
"test": "npm run test:integration && npm run test:unit",
|
||||
"test:integration": "playwright test",
|
||||
"test:screenshots": "playwright test -c playwright.screenshot.config.ts",
|
||||
"test:unit": "vitest"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -58,6 +59,7 @@
|
|||
"msgpack-es": "^0.0.5",
|
||||
"nostr-tools": "^2.7.1",
|
||||
"patch-package": "^8.0.0",
|
||||
"svelte-bootstrap-icons": "^3.1.1",
|
||||
"svelte-i18n": "^4.0.0"
|
||||
},
|
||||
"resolutions": {
|
||||
|
|
17
patches/@sveltejs+kit+2.8.5.patch
Normal file
17
patches/@sveltejs+kit+2.8.5.patch
Normal file
|
@ -0,0 +1,17 @@
|
|||
diff --git a/node_modules/@sveltejs/kit/src/exports/vite/index.js b/node_modules/@sveltejs/kit/src/exports/vite/index.js
|
||||
index e6521e9..f31c28b 100644
|
||||
--- a/node_modules/@sveltejs/kit/src/exports/vite/index.js
|
||||
+++ b/node_modules/@sveltejs/kit/src/exports/vite/index.js
|
||||
@@ -639,9 +639,9 @@ async function kit({ svelte_config }) {
|
||||
input,
|
||||
output: {
|
||||
format: 'esm',
|
||||
- entryFileNames: ssr ? '[name].js' : `${prefix}/[name].[hash].${ext}`,
|
||||
- chunkFileNames: ssr ? 'chunks/[name].js' : `${prefix}/chunks/[name].[hash].${ext}`,
|
||||
- assetFileNames: `${prefix}/assets/[name].[hash][extname]`,
|
||||
+ entryFileNames: ssr ? '[name].js' : `${prefix}/[hash].${ext}`,
|
||||
+ chunkFileNames: ssr ? 'chunks/[name].js' : `${prefix}/chunks/[hash].${ext}`,
|
||||
+ assetFileNames: `${prefix}/assets/[hash][extname]`,
|
||||
hoistTransitiveImports: false,
|
||||
sourcemapIgnoreList
|
||||
},
|
|
@ -10,7 +10,7 @@ const config: PlaywrightTestConfig = {
|
|||
port: 4173
|
||||
},
|
||||
reporter: process.env.CI ? 'github' : 'list',
|
||||
testDir: 'tests',
|
||||
testDir: 'tests/playwright',
|
||||
testMatch: /(.+\.)?(test|spec)\.[jt]s/
|
||||
};
|
||||
|
||||
|
|
51
playwright.screenshot.config.ts
Normal file
51
playwright.screenshot.config.ts
Normal file
|
@ -0,0 +1,51 @@
|
|||
import { defineConfig, devices } from '@playwright/test';
|
||||
|
||||
export default defineConfig({
|
||||
reporter: 'html',
|
||||
use: {
|
||||
locale: 'en-GB',
|
||||
timezoneId: 'Europe/Amsterdam'
|
||||
},
|
||||
webServer: {
|
||||
command: 'npm run build && npm run preview',
|
||||
port: 4173
|
||||
},
|
||||
testDir: './tests/screenshots',
|
||||
outputDir: './test-results/screenshots',
|
||||
projects: [
|
||||
{
|
||||
name: 'MacBook Air 13 inch',
|
||||
use: {
|
||||
viewport: { width: 1440, height: 900 }
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'iPhone 14 Pro',
|
||||
use: { ...devices['iPhone 14 Pro'] }
|
||||
},
|
||||
{
|
||||
name: 'iPhone 15 Pro Landscape',
|
||||
use: { ...devices['iPhone 15 Pro Landscape'] }
|
||||
},
|
||||
{
|
||||
name: 'MacBook Pro 14 inch',
|
||||
use: {
|
||||
viewport: { width: 1512, height: 982 }
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'MacBook Pro 14 inch',
|
||||
use: {
|
||||
viewport: { width: 1512, height: 982 }
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'MacBook Pro 14 inch Firefox HiDPI',
|
||||
use: { ...devices['Desktop Firefox HiDPI'], viewport: { width: 1512, height: 982 } }
|
||||
},
|
||||
{
|
||||
name: 'MacBook Pro 14 inch Safari',
|
||||
use: { ...devices['Desktop Safari'], viewport: { width: 1512, height: 982 } }
|
||||
}
|
||||
]
|
||||
});
|
53
src/components/ColorSchemeSwitcher.svelte
Normal file
53
src/components/ColorSchemeSwitcher.svelte
Normal file
|
@ -0,0 +1,53 @@
|
|||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from '@sveltestrap/sveltestrap';
|
||||
|
||||
type Theme = 'light' | 'dark' | 'auto';
|
||||
|
||||
let theme: Theme = 'auto';
|
||||
|
||||
// Set the theme based on user selection and store it in localStorage
|
||||
function setTheme(newTheme: Theme) {
|
||||
theme = newTheme;
|
||||
localStorage.setItem('theme', newTheme);
|
||||
applyTheme(newTheme);
|
||||
}
|
||||
|
||||
// Apply the selected theme to the document
|
||||
function applyTheme(selectedTheme: Theme) {
|
||||
if (selectedTheme === 'auto') {
|
||||
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
document.documentElement.setAttribute('data-bs-theme', prefersDark ? 'dark' : 'light');
|
||||
} else {
|
||||
document.documentElement.setAttribute('data-bs-theme', selectedTheme);
|
||||
}
|
||||
}
|
||||
|
||||
// On component mount, check localStorage and apply the saved theme
|
||||
onMount(() => {
|
||||
const savedTheme = (localStorage.getItem('theme') as Theme) || 'auto';
|
||||
applyTheme(savedTheme);
|
||||
theme = savedTheme;
|
||||
|
||||
// Listen for changes in the system color scheme preference
|
||||
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
mediaQuery.addEventListener('change', () => {
|
||||
if (theme === 'auto') {
|
||||
applyTheme('auto');
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<Dropdown inNavbar>
|
||||
<DropdownToggle nav caret>
|
||||
{theme === 'auto' ? '🌗' : theme === 'dark' ? '🌙' : '☀️'}
|
||||
</DropdownToggle>
|
||||
<DropdownMenu end>
|
||||
<DropdownItem active={theme === 'light'} on:click={() => setTheme('light')}
|
||||
>☀️ Light</DropdownItem
|
||||
>
|
||||
<DropdownItem active={theme === 'dark'} on:click={() => setTheme('dark')}>🌙 Dark</DropdownItem>
|
||||
<DropdownItem active={theme === 'auto'} on:click={() => setTheme('auto')}>🌗 Auto</DropdownItem>
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
28
src/components/ToggleHeader.svelte
Normal file
28
src/components/ToggleHeader.svelte
Normal file
|
@ -0,0 +1,28 @@
|
|||
<script lang="ts">
|
||||
import { Fade } from '@sveltestrap/sveltestrap';
|
||||
import CaretRightFill from 'svelte-bootstrap-icons/lib/CaretRightFill.svelte';
|
||||
import CaretDownFill from 'svelte-bootstrap-icons/lib/CaretDownFill.svelte';
|
||||
|
||||
export let header;
|
||||
export let defaultOpen = false;
|
||||
export let isOpen = defaultOpen;
|
||||
</script>
|
||||
|
||||
<h4 style="cursor: pointer">
|
||||
<span
|
||||
role="link"
|
||||
on:click={() => (isOpen = !isOpen)}
|
||||
tabindex="0"
|
||||
on:keypress={() => (isOpen = !isOpen)}
|
||||
>
|
||||
{#if isOpen}
|
||||
<CaretDownFill></CaretDownFill>
|
||||
{:else}
|
||||
<CaretRightFill></CaretRightFill>
|
||||
{/if}
|
||||
{header}
|
||||
</span>
|
||||
</h4>
|
||||
<Fade {isOpen}>
|
||||
<slot></slot>
|
||||
</Fade>
|
|
@ -1,13 +0,0 @@
|
|||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
fill="currentColor"
|
||||
class="bi bi-eye"
|
||||
viewBox="0 0 16 16"
|
||||
>
|
||||
<path
|
||||
d="M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8M1.173 8a13 13 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5s3.879 1.168 5.168 2.457A13 13 0 0 1 14.828 8q-.086.13-.195.288c-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5s-3.879-1.168-5.168-2.457A13 13 0 0 1 1.172 8z"
|
||||
/>
|
||||
<path d="M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5M4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0" />
|
||||
</svg>
|
Before Width: | Height: | Size: 530 B |
|
@ -1,18 +0,0 @@
|
|||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
fill="currentColor"
|
||||
class="bi bi-eye-slash"
|
||||
viewBox="0 0 16 16"
|
||||
>
|
||||
<path
|
||||
d="M13.359 11.238C15.06 9.72 16 8 16 8s-3-5.5-8-5.5a7 7 0 0 0-2.79.588l.77.771A6 6 0 0 1 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13 13 0 0 1 14.828 8q-.086.13-.195.288c-.335.48-.83 1.12-1.465 1.755q-.247.248-.517.486z"
|
||||
/>
|
||||
<path
|
||||
d="M11.297 9.176a3.5 3.5 0 0 0-4.474-4.474l.823.823a2.5 2.5 0 0 1 2.829 2.829zm-2.943 1.299.822.822a3.5 3.5 0 0 1-4.474-4.474l.823.823a2.5 2.5 0 0 0 2.829 2.829"
|
||||
/>
|
||||
<path
|
||||
d="M3.35 5.47q-.27.24-.518.487A13 13 0 0 0 1.172 8l.195.288c.335.48.83 1.12 1.465 1.755C4.121 11.332 5.881 12.5 8 12.5c.716 0 1.39-.133 2.02-.36l.77.772A7 7 0 0 1 8 13.5C3 13.5 0 8 0 8s.939-1.721 2.641-3.238l.708.709zm10.296 8.884-12-12 .708-.708 12 12z"
|
||||
/>
|
||||
</svg>
|
Before Width: | Height: | Size: 814 B |
|
@ -42,7 +42,23 @@
|
|||
"httpAuthUser": "WebUI-Benutzername",
|
||||
"httpAuthPass": "WebUI-Passwort",
|
||||
"httpAuthText": "Schützt nur die WebUI mit einem Passwort, nicht API-Aufrufe.",
|
||||
"currencies": "Währungen"
|
||||
"currencies": "Währungen",
|
||||
"mowMode": "Mow suffixmodus",
|
||||
"suffixShareDot": "Kompakte Suffix-Notation",
|
||||
"section": {
|
||||
"displaysAndLed": "Anzeigen und LEDs",
|
||||
"screenSettings": "Infospezifisch",
|
||||
"dataSource": "Datenquelle",
|
||||
"extraFeatures": "Zusätzliche Funktionen",
|
||||
"system": "System"
|
||||
},
|
||||
"ledFlashOnZap": "LED blinkt bei Nostr Zap",
|
||||
"flFlashOnZap": "Displaybeleuchting bei Nostr Zap",
|
||||
"showAll": "Alle anzeigen",
|
||||
"hideAll": "Alles ausblenden",
|
||||
"flOffWhenDark": "Displaybeleuchtung aus, wenn es dunkel ist",
|
||||
"luxLightToggleText": "Zum Deaktivieren auf 0 setzen",
|
||||
"verticalDesc": "Vrtikale Bildschirmbeschreibung"
|
||||
},
|
||||
"control": {
|
||||
"systemInfo": "Systeminfo",
|
||||
|
|
|
@ -54,7 +54,23 @@
|
|||
"httpAuthText": "Only password-protects WebUI, not API-calls.",
|
||||
"currencies": "Currencies",
|
||||
"stagingSource": "Use Staging data source (for development)",
|
||||
"useNostrTooltip": "Very experimental and unstable. Nostr data source is not required for Nostr Zap notifications."
|
||||
"useNostrTooltip": "Very experimental and unstable. Nostr data source is not required for Nostr Zap notifications.",
|
||||
"mowMode": "Mow Suffix Mode",
|
||||
"suffixShareDot": "Suffix compact notation",
|
||||
"section": {
|
||||
"displaysAndLed": "Displays and LEDs",
|
||||
"screenSettings": "Screen specific",
|
||||
"dataSource": "Data source",
|
||||
"extraFeatures": "Extra features",
|
||||
"system": "System"
|
||||
},
|
||||
"ledFlashOnZap": "LED flash on Nostr Zap",
|
||||
"flFlashOnZap": "Frontlight flash on Nostr Zap",
|
||||
"showAll": "Show all",
|
||||
"hideAll": "Hide all",
|
||||
"flOffWhenDark": "Frontlight off when dark",
|
||||
"luxLightToggleText": "Set to 0 to disable",
|
||||
"verticalDesc": "Use vertical screen description"
|
||||
},
|
||||
"control": {
|
||||
"systemInfo": "System info",
|
||||
|
|
|
@ -41,7 +41,23 @@
|
|||
"httpAuthUser": "Nombre de usuario WebUI",
|
||||
"httpAuthPass": "Contraseña WebUI",
|
||||
"httpAuthText": "Solo la WebUI está protegida con contraseña, no las llamadas API.",
|
||||
"currencies": "Monedas"
|
||||
"currencies": "Monedas",
|
||||
"mowMode": "Modo de sufijo Mow",
|
||||
"suffixShareDot": "Notación compacta de sufijo",
|
||||
"section": {
|
||||
"displaysAndLed": "Pantallas y LED",
|
||||
"screenSettings": "Específico de la pantalla",
|
||||
"dataSource": "fuente de datos",
|
||||
"extraFeatures": "Funciones adicionales",
|
||||
"system": "Sistema"
|
||||
},
|
||||
"ledFlashOnZap": "LED parpadeante con Nostr Zap",
|
||||
"flFlashOnZap": "Flash de luz frontal con Nostr Zap",
|
||||
"showAll": "Mostrar todo",
|
||||
"hideAll": "Ocultar todo",
|
||||
"flOffWhenDark": "Luz de la pantalla cuando está oscuro",
|
||||
"luxLightToggleText": "Establecer en 0 para desactivar",
|
||||
"verticalDesc": "Descripción de pantalla vertical"
|
||||
},
|
||||
"control": {
|
||||
"turnOff": "Apagar",
|
||||
|
|
|
@ -42,7 +42,23 @@
|
|||
"httpAuthUser": "WebUI-gebruikersnaam",
|
||||
"httpAuthPass": "WebUI-wachtwoord",
|
||||
"httpAuthText": "Beveiligd enkel WebUI, niet de API.",
|
||||
"currencies": "Valuta's"
|
||||
"currencies": "Valuta's",
|
||||
"mowMode": "Mow achtervoegsel",
|
||||
"suffixShareDot": "Achtervoegsel compacte notatie",
|
||||
"section": {
|
||||
"displaysAndLed": "Displays en LED's",
|
||||
"screenSettings": "Schermspecifiek",
|
||||
"dataSource": "Gegevensbron",
|
||||
"extraFeatures": "Extra functies",
|
||||
"system": "Systeem"
|
||||
},
|
||||
"ledFlashOnZap": "Knipper LED bij Nostr Zap",
|
||||
"flFlashOnZap": "Knipper displaylicht bij Nostr Zap",
|
||||
"showAll": "Toon alles",
|
||||
"hideAll": "Alles verbergen",
|
||||
"flOffWhenDark": "Displaylicht uit als het donker is",
|
||||
"luxLightToggleText": "Stel in op 0 om uit te schakelen",
|
||||
"verticalDesc": "Verticale schermbeschrijving"
|
||||
},
|
||||
"control": {
|
||||
"systemInfo": "Systeeminformatie",
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
@import '../node_modules/bootstrap/scss/functions';
|
||||
@import '../node_modules/bootstrap/scss/variables';
|
||||
@import '../node_modules/bootstrap/scss/variables-dark';
|
||||
|
||||
//@import "@fontsource/antonio/latin-400.css";
|
||||
@import '@fontsource/ubuntu/latin-400.css';
|
||||
|
@ -9,11 +7,13 @@
|
|||
|
||||
@import './satsymbol';
|
||||
|
||||
$color-mode-type: media-query;
|
||||
$color-mode-type: data;
|
||||
$font-family-base: 'Ubuntu';
|
||||
$font-size-base: 0.9rem;
|
||||
$input-font-size-sm: $font-size-base * 0.875;
|
||||
|
||||
@import '../node_modules/bootstrap/scss/variables';
|
||||
@import '../node_modules/bootstrap/scss/variables-dark';
|
||||
// $border-radius: .675rem;
|
||||
|
||||
@import '../node_modules/bootstrap/scss/mixins';
|
||||
|
@ -43,6 +43,40 @@ $input-font-size-sm: $font-size-base * 0.875;
|
|||
@import '../node_modules/bootstrap/scss/helpers';
|
||||
@import '../node_modules/bootstrap/scss/utilities/api';
|
||||
|
||||
/* Default state (xs) - sticky */
|
||||
.sticky-xs-top {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1020;
|
||||
}
|
||||
|
||||
@media (max-width: 576px) {
|
||||
main {
|
||||
margin-top: 25px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove sticky behavior for larger screens */
|
||||
@media (min-width: 576px) {
|
||||
.sticky-xs-top {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
@include color-mode(dark) {
|
||||
.navbar {
|
||||
--bs-navbar-color: $light;
|
||||
background-color: $dark;
|
||||
}
|
||||
}
|
||||
|
||||
@include color-mode(light) {
|
||||
.navbar {
|
||||
--bs-navbar-color: $dark;
|
||||
background-color: $light;
|
||||
}
|
||||
}
|
||||
|
||||
nav {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
@ -53,6 +87,23 @@ nav {
|
|||
|
||||
.btn-group-sm .btn {
|
||||
font-size: 0.8rem;
|
||||
// text-overflow: ellipsis;
|
||||
// white-space: nowrap;
|
||||
// overflow: hidden;
|
||||
// width: 4rem;
|
||||
}
|
||||
|
||||
.btn-group-sm {
|
||||
display: flex !important;
|
||||
flex-wrap: wrap !important;
|
||||
gap: 0.25rem !important;
|
||||
}
|
||||
|
||||
/* Remove the border radius override that Bootstrap applies */
|
||||
.btn-group-sm > .btn {
|
||||
border-radius: 0.25rem !important;
|
||||
margin: 0 !important;
|
||||
position: relative !important;
|
||||
}
|
||||
|
||||
#customText {
|
||||
|
@ -63,7 +114,7 @@ nav {
|
|||
.btclock {
|
||||
background: #000;
|
||||
display: flex;
|
||||
font-size: calc(3vw + 3vh);
|
||||
font-size: calc(2vw + 2vh);
|
||||
font-family: 'Antonio', sans-serif;
|
||||
font-weight: 400;
|
||||
padding: 10px;
|
||||
|
@ -104,19 +155,25 @@ nav {
|
|||
flex-direction: column; /* Stack the text and line vertically */
|
||||
align-items: center;
|
||||
justify-content: space-around; /* Distribute items with space between */
|
||||
padding: 10px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.splitText div:first-child::after {
|
||||
&.verticalDesc > .splitText:first-child {
|
||||
.textcontainer {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
}
|
||||
|
||||
.splitText .textcontainer :first-child::after {
|
||||
display: block;
|
||||
content: '';
|
||||
margin-top: 0px;
|
||||
border-bottom: 2px solid;
|
||||
margin-bottom: 3px;
|
||||
// margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.splitText {
|
||||
font-size: calc(0.5vw + 1vh);
|
||||
font-size: calc(0.3vw + 1vh);
|
||||
|
||||
.top-text,
|
||||
.bottom-text {
|
||||
|
@ -242,3 +299,7 @@ nav {
|
|||
input[type='number'] {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.lightMode .bitaxelogo {
|
||||
filter: brightness(0) saturate(100%);
|
||||
}
|
||||
|
|
|
@ -12,9 +12,11 @@
|
|||
NavbarBrand,
|
||||
NavbarToggler
|
||||
} from '@sveltestrap/sveltestrap';
|
||||
import { _ } from 'svelte-i18n';
|
||||
|
||||
import { page } from '$app/stores';
|
||||
import { locale, locales, isLoading } from 'svelte-i18n';
|
||||
import ColorSchemeSwitcher from '../components/ColorSchemeSwitcher.svelte';
|
||||
|
||||
export const setLocale = (lang: string) => () => {
|
||||
locale.set(lang);
|
||||
|
@ -37,7 +39,7 @@
|
|||
return flagMap[lowercaseCode];
|
||||
} else {
|
||||
// Return null for unsupported language codes
|
||||
return null;
|
||||
return flagMap['en'];
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -60,8 +62,23 @@
|
|||
};
|
||||
</script>
|
||||
|
||||
<Navbar expand="md">
|
||||
<NavbarBrand>₿TClock</NavbarBrand>
|
||||
<Navbar expand="md" sticky="xs-top" theme="auto">
|
||||
<NavbarBrand class="d-none d-sm-block">₿TClock</NavbarBrand>
|
||||
<Nav class="d-md-none" pills>
|
||||
<NavItem>
|
||||
<NavLink href="#control" active>{$_('section.control.title', { default: 'Control' })}</NavLink
|
||||
>
|
||||
</NavItem>
|
||||
<NavItem>
|
||||
<NavLink href="#status">{$_('section.status.title', { default: 'Status' })}</NavLink>
|
||||
</NavItem>
|
||||
<NavItem>
|
||||
<NavLink class="nav-link" href="#settings"
|
||||
>{$_('section.settings.title', { default: 'Settings' })}</NavLink
|
||||
>
|
||||
</NavItem>
|
||||
</Nav>
|
||||
|
||||
<NavbarToggler on:click={toggle} />
|
||||
|
||||
<Collapse {isOpen} navbar expand="sm">
|
||||
|
@ -77,7 +94,7 @@
|
|||
</NavItem>
|
||||
</Nav>
|
||||
{#if !$isLoading}
|
||||
<Dropdown id="nav-language-dropdown" inNavbar>
|
||||
<Dropdown id="nav-language-dropdown" inNavbar class="me-3">
|
||||
<DropdownToggle nav caret>{getFlagEmoji($locale)} {languageNames[$locale]}</DropdownToggle>
|
||||
<DropdownMenu end>
|
||||
{#each $locales as locale}
|
||||
|
@ -88,8 +105,11 @@
|
|||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
{/if}
|
||||
<ColorSchemeSwitcher></ColorSchemeSwitcher>
|
||||
</Collapse>
|
||||
</Navbar>
|
||||
|
||||
<!-- +layout.svelte -->
|
||||
<main>
|
||||
<slot />
|
||||
</main>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
import { screenSize, updateScreenSize } from '$lib/screen';
|
||||
|
||||
import { Container, Row, Toast, ToastBody } from '@sveltestrap/sveltestrap';
|
||||
import { replaceState } from '$app/navigation';
|
||||
|
||||
import { onMount } from 'svelte';
|
||||
import { writable } from 'svelte/store';
|
||||
|
@ -16,12 +17,6 @@
|
|||
bgColor: '0'
|
||||
});
|
||||
|
||||
// let uiSettings = writable({
|
||||
// inputSize: 'sm',
|
||||
// selectClass: '',
|
||||
// btnSize: 'lg'
|
||||
// });
|
||||
|
||||
let status = writable({
|
||||
data: ['L', 'O', 'A', 'D', 'I', 'N', 'G'],
|
||||
espFreeHeap: 0,
|
||||
|
@ -60,7 +55,43 @@
|
|||
});
|
||||
};
|
||||
|
||||
let sections: (HTMLElement | null)[];
|
||||
let observer: IntersectionObserver;
|
||||
const SM_BREAKPOINT = 576;
|
||||
|
||||
const setupObserver = () => {
|
||||
if (window.innerWidth < SM_BREAKPOINT) {
|
||||
observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
const id = entry.target.id;
|
||||
replaceState(`#${id}`);
|
||||
|
||||
// Update nav pills
|
||||
document.querySelectorAll('.nav-link').forEach((link) => {
|
||||
link.classList.remove('active');
|
||||
if (link.getAttribute('href') === `#${id}`) {
|
||||
link.classList.add('active');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
{
|
||||
threshold: 0.25 // Trigger when section is 50% visible
|
||||
}
|
||||
);
|
||||
|
||||
sections = ['control', 'status', 'settings'].map((id) => document.getElementById(id));
|
||||
|
||||
sections.forEach((section) => observer.observe(section!));
|
||||
}
|
||||
};
|
||||
|
||||
onMount(() => {
|
||||
setupObserver();
|
||||
|
||||
fetchSettingsData();
|
||||
fetchStatusData();
|
||||
|
||||
|
@ -72,6 +103,11 @@
|
|||
});
|
||||
|
||||
function handleResize() {
|
||||
if (observer) {
|
||||
observer.disconnect();
|
||||
}
|
||||
setupObserver();
|
||||
|
||||
updateScreenSize();
|
||||
}
|
||||
|
||||
|
@ -125,7 +161,9 @@
|
|||
<Container fluid>
|
||||
<Row>
|
||||
<Control bind:settings on:showToast={showToast} bind:status lg="3" xxl="4"></Control>
|
||||
|
||||
<Status bind:settings bind:status lg="6" xxl="4"></Status>
|
||||
|
||||
<Settings bind:settings on:showToast={showToast} on:formReset={fetchSettingsData} lg="3" xxl="4"
|
||||
></Settings>
|
||||
</Row>
|
||||
|
|
|
@ -105,8 +105,8 @@
|
|||
export let xxl = xl;
|
||||
</script>
|
||||
|
||||
<Col {xs} {sm} {md} {lg} {xl} {xxl}>
|
||||
<Card>
|
||||
<Col {xs} {sm} {md} {lg} {xl} {xxl} class="mb-4 mb-xl-0">
|
||||
<Card id="control">
|
||||
<CardHeader>
|
||||
<CardTitle>{$_('section.control.title', { default: 'Control' })}</CardTitle>
|
||||
</CardHeader>
|
||||
|
|
|
@ -200,7 +200,7 @@
|
|||
<p>Loading...</p>
|
||||
{/if}
|
||||
<section class="row row-cols-lg-auto align-items-end">
|
||||
<div class="col-12">
|
||||
<div class="col flex-fill">
|
||||
<label for="firmwareFile" class="form-label">Firmware file ({getFirmwareBinaryName()})</label>
|
||||
<input
|
||||
type="file"
|
||||
|
@ -216,7 +216,7 @@
|
|||
>Update firmware</Button
|
||||
>
|
||||
</div>
|
||||
<div class="col mt-2">
|
||||
<div class="col flex-fill">
|
||||
<label for="webuiFile" class="form-label">WebUI file (littlefs.bin)</label>
|
||||
<input
|
||||
type="file"
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
};
|
||||
|
||||
export let className = 'btclock-wrapper';
|
||||
|
||||
export let verticalDesc = false;
|
||||
// Define the currency symbols as constants
|
||||
const CURRENCY_USD = '$';
|
||||
const CURRENCY_EUR = '[';
|
||||
|
@ -44,21 +44,22 @@
|
|||
</script>
|
||||
|
||||
<div class={className} id={className}>
|
||||
<div class="btclock">
|
||||
<div class={'btclock' + (verticalDesc ? ' verticalDesc' : '')}>
|
||||
{#each status.data as char}
|
||||
{#if isSplitText(char)}
|
||||
<div class="splitText">
|
||||
<div class="textcontainer">
|
||||
{#if char.split('/').length}
|
||||
<span class="top-text">{char.split('/')[0]}</span>
|
||||
<hr />
|
||||
<span class="bottom-text">{char.split('/')[1]}</span>
|
||||
{/if}
|
||||
</div>
|
||||
<!-- {#each char.split('/') as part}
|
||||
<div class="flex-items">{part}</div>
|
||||
{/each} -->
|
||||
</div>
|
||||
{:else if char.startsWith('mdi')}
|
||||
<div class="digit icon">
|
||||
<div class={'digit icon' + (char.endsWith('bitaxe') ? ' icon-img' : '')}>
|
||||
{#if char.endsWith('rocket')}
|
||||
<RocketIcon></RocketIcon>
|
||||
{/if}
|
||||
|
@ -68,6 +69,9 @@
|
|||
{#if char.endsWith('bolt')}
|
||||
<ZapIcon></ZapIcon>
|
||||
{/if}
|
||||
{#if char.endsWith('bitaxe')}
|
||||
<img src="/bitaxe.webp" class="bitaxelogo" alt="BitAxe logo" />
|
||||
{/if}
|
||||
</div>
|
||||
{:else if char === 'STS'}
|
||||
<div class="digit sats">S</div>
|
||||
|
@ -82,8 +86,22 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
<style lang="scss">
|
||||
.icon {
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
.btclock-wrapper .btclock .icon.icon-img {
|
||||
// padding: 0 15px;
|
||||
aspect-ratio: 1;
|
||||
width: calc(100 / 7);
|
||||
|
||||
img {
|
||||
max-width: 95%;
|
||||
}
|
||||
}
|
||||
|
||||
.bitaxelogo {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -21,9 +21,12 @@
|
|||
Tooltip,
|
||||
Row
|
||||
} from '@sveltestrap/sveltestrap';
|
||||
import EyeIcon from '../icons/EyeIcon.svelte';
|
||||
import EyeSlashIcon from '../icons/EyeSlashIcon.svelte';
|
||||
|
||||
import EyeIcon from 'svelte-bootstrap-icons/lib/Eye.svelte';
|
||||
import EyeSlashIcon from 'svelte-bootstrap-icons/lib/EyeSlash.svelte';
|
||||
|
||||
import { derived } from 'svelte/store';
|
||||
import ToggleHeader from '../components/ToggleHeader.svelte';
|
||||
|
||||
export let settings;
|
||||
|
||||
|
@ -196,21 +199,193 @@
|
|||
}
|
||||
};
|
||||
|
||||
const showAll = (show: boolean) => {
|
||||
screenSettingsIsOpen = show;
|
||||
displaysAndLedIsOpen = show;
|
||||
dataSourceIsOpen = show;
|
||||
extraFeaturesIsOpen = show;
|
||||
systemIsOpen = show;
|
||||
};
|
||||
|
||||
export let xs = 12;
|
||||
export let sm = xs;
|
||||
export let md = sm;
|
||||
export let lg = md;
|
||||
export let xl = lg;
|
||||
export let xxl = xl;
|
||||
|
||||
let screenSettingsIsOpen: boolean,
|
||||
displaysAndLedIsOpen: boolean,
|
||||
dataSourceIsOpen: boolean,
|
||||
extraFeaturesIsOpen: boolean,
|
||||
systemIsOpen: boolean;
|
||||
</script>
|
||||
|
||||
<Col {xs} {sm} {md} {lg} {xl} {xxl}>
|
||||
<Card>
|
||||
<Col {xs} {sm} {md} {lg} {xl} {xxl} class="mb-4 mb-xl-0">
|
||||
<Card id="settings">
|
||||
<CardHeader>
|
||||
<div class="float-end">
|
||||
<small
|
||||
><button
|
||||
on:click={() => {
|
||||
showAll(true);
|
||||
}}
|
||||
type="button">{$_('section.settings.showAll')}</button
|
||||
>
|
||||
|
|
||||
<button
|
||||
type="button"
|
||||
on:click={() => {
|
||||
showAll(false);
|
||||
}}>{$_('section.settings.hideAll')}</button
|
||||
></small
|
||||
>
|
||||
</div>
|
||||
<CardTitle>{$_('section.settings.title', { default: 'Settings' })}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardBody>
|
||||
<Form on:submit={onSave}>
|
||||
<Form on:submit={onSave} class="clearfix">
|
||||
<Row>
|
||||
<ToggleHeader
|
||||
header={$_('section.settings.section.screenSettings')}
|
||||
defaultOpen={true}
|
||||
isOpen={screenSettingsIsOpen}
|
||||
>
|
||||
<Row>
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="stealFocus"
|
||||
bind:checked={$settings.stealFocus}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={$_('section.settings.StealFocusOnNewBlock')}
|
||||
/>
|
||||
</Col>
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="mcapBigChar"
|
||||
bind:checked={$settings.mcapBigChar}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={$_('section.settings.useBigCharsMcap')}
|
||||
/>
|
||||
</Col>
|
||||
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="useBlkCountdown"
|
||||
bind:checked={$settings.useBlkCountdown}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={$_('section.settings.useBlkCountdown')}
|
||||
/>
|
||||
</Col>
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="useSatsSymbol"
|
||||
bind:checked={$settings.useSatsSymbol}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={$_('section.settings.useSatsSymbol')}
|
||||
/>
|
||||
</Col>
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="suffixPrice"
|
||||
bind:checked={$settings.suffixPrice}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={$_('section.settings.suffixPrice')}
|
||||
/>
|
||||
</Col>
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
disabled={!$settings.suffixPrice}
|
||||
id="mowMode"
|
||||
bind:checked={$settings.mowMode}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={$_('section.settings.mowMode')}
|
||||
/>
|
||||
</Col>
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
disabled={!$settings.suffixPrice}
|
||||
id="suffixShareDot"
|
||||
bind:checked={$settings.suffixShareDot}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={$_('section.settings.suffixShareDot')}
|
||||
/>
|
||||
</Col>
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="verticalDesc"
|
||||
bind:checked={$settings.verticalDesc}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={$_('section.settings.verticalDesc')}
|
||||
/>
|
||||
</Col>
|
||||
|
||||
{#if !$settings.actCurrencies}
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="fetchEurPrice"
|
||||
bind:checked={$settings.fetchEurPrice}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label="{$_('section.settings.fetchEuroPrice')} ({$_('restartRequired')})"
|
||||
/>
|
||||
</Col>
|
||||
{/if}
|
||||
</Row>
|
||||
<Row>
|
||||
<h5>{$_('section.settings.screens')}</h5>
|
||||
{#if $settings.screens}
|
||||
{#each $settings.screens as s}
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="screens_{s.id}"
|
||||
bind:checked={s.enabled}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={s.name}
|
||||
/>
|
||||
</Col>
|
||||
{/each}
|
||||
{/if}
|
||||
</Row>
|
||||
{#if $settings.actCurrencies && $settings.useNostr !== true}
|
||||
<Row>
|
||||
<h5>{$_('section.settings.currencies')}</h5>
|
||||
<small>{$_('restartRequired')}</small>
|
||||
{#if $settings.availableCurrencies}
|
||||
{#each $settings.availableCurrencies as c}
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<div class="form-check form-control-{$uiSettings.inputSize}">
|
||||
<input
|
||||
id="currency_{c}"
|
||||
bind:group={$settings.actCurrencies}
|
||||
value={c}
|
||||
type="checkbox"
|
||||
class="form-check-input"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={c}
|
||||
/>
|
||||
<label class="form-check-label" for="currency_{c}">{c}</label>
|
||||
</div>
|
||||
</Col>
|
||||
{/each}
|
||||
{/if}
|
||||
</Row>
|
||||
{/if}
|
||||
</ToggleHeader>
|
||||
</Row><Row>
|
||||
<ToggleHeader
|
||||
header={$_('section.settings.section.displaysAndLed')}
|
||||
isOpen={displaysAndLedIsOpen}
|
||||
>
|
||||
<Row>
|
||||
<Label md={6} for="textColor" size={$uiSettings.inputSize}
|
||||
>{$_('section.settings.textColor', { default: 'Text color' })}</Label
|
||||
|
@ -285,28 +460,6 @@
|
|||
<FormText>{$_('section.settings.shortAmountsWarning')}</FormText>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Label md={6} for="tzOffset" size={$uiSettings.inputSize}
|
||||
>{$_('section.settings.timezoneOffset')}</Label
|
||||
>
|
||||
<Col md="6">
|
||||
<InputGroup size={$uiSettings.inputSize}>
|
||||
<Input
|
||||
type="number"
|
||||
step="1"
|
||||
name="tzOffset"
|
||||
id="tzOffset"
|
||||
required
|
||||
bind:value={$settings.tzOffset}
|
||||
/>
|
||||
<InputGroupText>{$_('time.minutes')}</InputGroupText>
|
||||
<Button type="button" color="info" on:click={getTzOffsetFromSystem}
|
||||
>{$_('auto-detect')}</Button
|
||||
>
|
||||
</InputGroup>
|
||||
<FormText>{$_('section.settings.tzOffsetHelpText')}</FormText>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Label md={6} for="ledBrightness" size={$uiSettings.inputSize}
|
||||
>{$_('section.settings.ledBrightness')}</Label
|
||||
|
@ -373,9 +526,156 @@
|
|||
max={1000}
|
||||
step={1}
|
||||
/>
|
||||
<FormText>{$_('section.settings.luxLightToggleText')}</FormText>
|
||||
</Col>
|
||||
</Row>
|
||||
{/if}
|
||||
<Row>
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="ledTestOnPower"
|
||||
bind:checked={$settings.ledTestOnPower}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={$_('section.settings.ledPowerOnTest')}
|
||||
/>
|
||||
</Col>
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="ledFlashOnUpd"
|
||||
bind:checked={$settings.ledFlashOnUpd}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={$_('section.settings.ledFlashOnBlock')}
|
||||
/>
|
||||
</Col>
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="disableLeds"
|
||||
bind:checked={$settings.disableLeds}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={$_('section.settings.disableLeds')}
|
||||
/>
|
||||
</Col>
|
||||
{#if $settings.hasFrontlight}
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="flDisable"
|
||||
bind:checked={$settings.flDisable}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={$_('section.settings.flDisable')}
|
||||
/>
|
||||
</Col>
|
||||
{/if}
|
||||
{#if $settings.hasFrontlight && !$settings.flDisable}
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="flAlwaysOn"
|
||||
bind:checked={$settings.flAlwaysOn}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={$_('section.settings.flAlwaysOn')}
|
||||
/>
|
||||
</Col>
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="flFlashOnUpd"
|
||||
bind:checked={$settings.flFlashOnUpd}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={$_('section.settings.flFlashOnUpd')}
|
||||
/>
|
||||
</Col>
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="flOffWhenDark"
|
||||
bind:checked={$settings.flOffWhenDark}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={$_('section.settings.flOffWhenDark')}
|
||||
/>
|
||||
</Col>
|
||||
{/if}
|
||||
</Row>
|
||||
</ToggleHeader>
|
||||
</Row><Row>
|
||||
<ToggleHeader
|
||||
header={$_('section.settings.section.dataSource')}
|
||||
isOpen={dataSourceIsOpen}
|
||||
>
|
||||
<Row>
|
||||
<Label md={6} for="mempoolInstance" size="sm"
|
||||
>{$_('section.settings.mempoolnstance')}</Label
|
||||
>
|
||||
<Col md="6">
|
||||
<InputGroup size={$uiSettings.inputSize}>
|
||||
<Input
|
||||
type="text"
|
||||
bind:value={$settings.mempoolInstance}
|
||||
name="mempoolInstance"
|
||||
id="mempoolInstance"
|
||||
disabled={$settings.ownDataSource}
|
||||
bsSize="sm"
|
||||
required
|
||||
></Input>
|
||||
<InputGroupText>
|
||||
<Input
|
||||
addon
|
||||
type="checkbox"
|
||||
bind:checked={$settings.mempoolSecure}
|
||||
disabled={$settings.ownDataSource}
|
||||
bsSize={$uiSettings.inputSize}
|
||||
/>
|
||||
HTTPS
|
||||
</InputGroupText>
|
||||
</InputGroup>
|
||||
<FormText>{$_('section.settings.mempoolInstanceHelpText')}</FormText>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="ownDataSource"
|
||||
bind:checked={$settings.ownDataSource}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label="{$_('section.settings.ownDataSource')} ({$_('restartRequired')})"
|
||||
/>
|
||||
</Col>
|
||||
{#if $settings.nostrRelay}
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="useNostr"
|
||||
bind:checked={$settings.useNostr}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label="{$_('section.settings.useNostr')} ({$_('restartRequired')})"
|
||||
></Input>
|
||||
<Tooltip target="useNostr" placement="left">
|
||||
{$_('section.settings.useNostrTooltip')}
|
||||
</Tooltip>
|
||||
</Col>
|
||||
{/if}
|
||||
{#if 'stagingSource' in $settings}
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="stagingSource"
|
||||
bind:checked={$settings.stagingSource}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label="{$_('section.settings.stagingSource')} ({$_('restartRequired')})"
|
||||
/>
|
||||
</Col>
|
||||
{/if}
|
||||
</Row>
|
||||
</ToggleHeader>
|
||||
</Row><Row>
|
||||
<ToggleHeader
|
||||
header={$_('section.settings.section.extraFeatures')}
|
||||
isOpen={extraFeaturesIsOpen}
|
||||
>
|
||||
{#if $settings.bitaxeEnabled}
|
||||
<Row>
|
||||
<Label md={6} for="bitaxeHostname" size={$uiSettings.inputSize}
|
||||
|
@ -466,37 +766,79 @@
|
|||
</Row>
|
||||
{/if}
|
||||
<Row>
|
||||
<Label md={6} for="mempoolInstance" size="sm"
|
||||
>{$_('section.settings.mempoolnstance')}</Label
|
||||
{#if 'bitaxeEnabled' in $settings}
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="bitaxeEnabled"
|
||||
bind:checked={$settings.bitaxeEnabled}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label="{$_('section.settings.bitaxeEnabled')} ({$_('restartRequired')})"
|
||||
/>
|
||||
</Col>
|
||||
{/if}
|
||||
{#if 'nostrZapNotify' in $settings}
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="nostrZapNotify"
|
||||
bind:checked={$settings.nostrZapNotify}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label="{$_('section.settings.nostrZapNotify')} ({$_('restartRequired')})"
|
||||
/>
|
||||
</Col>
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="ledFlashOnZap"
|
||||
bind:checked={$settings.ledFlashOnZap}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={$_('section.settings.ledFlashOnZap')}
|
||||
/>
|
||||
</Col>
|
||||
{#if $settings.hasFrontlight && !$settings.flDisable}
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="flFlashOnZap"
|
||||
bind:checked={$settings.flFlashOnZap}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={$_('section.settings.flFlashOnZap')}
|
||||
/>
|
||||
</Col>
|
||||
{/if}
|
||||
{/if}
|
||||
</Row>
|
||||
</ToggleHeader>
|
||||
</Row><Row>
|
||||
<ToggleHeader header={$_('section.settings.section.system')} isOpen={systemIsOpen}>
|
||||
<Row>
|
||||
<Label md={6} for="tzOffset" size={$uiSettings.inputSize}
|
||||
>{$_('section.settings.timezoneOffset')}</Label
|
||||
>
|
||||
<Col md="6">
|
||||
<InputGroup size={$uiSettings.inputSize}>
|
||||
<Input
|
||||
type="text"
|
||||
bind:value={$settings.mempoolInstance}
|
||||
name="mempoolInstance"
|
||||
id="mempoolInstance"
|
||||
disabled={$settings.ownDataSource}
|
||||
bsSize="sm"
|
||||
type="number"
|
||||
step="1"
|
||||
name="tzOffset"
|
||||
id="tzOffset"
|
||||
required
|
||||
></Input>
|
||||
<InputGroupText>
|
||||
<Input
|
||||
addon
|
||||
type="checkbox"
|
||||
bind:checked={$settings.mempoolSecure}
|
||||
disabled={$settings.ownDataSource}
|
||||
bsSize={$uiSettings.inputSize}
|
||||
bind:value={$settings.tzOffset}
|
||||
/>
|
||||
HTTPS
|
||||
</InputGroupText>
|
||||
<InputGroupText>{$_('time.minutes')}</InputGroupText>
|
||||
<Button type="button" color="info" on:click={getTzOffsetFromSystem}
|
||||
>{$_('auto-detect')}</Button
|
||||
>
|
||||
</InputGroup>
|
||||
<FormText>{$_('section.settings.mempoolInstanceHelpText')}</FormText>
|
||||
<FormText>{$_('section.settings.tzOffsetHelpText')}</FormText>
|
||||
</Col>
|
||||
</Row>
|
||||
{#if $settings.httpAuthEnabled}
|
||||
<Row>
|
||||
<Label md={6} for="httpAuthUser" size="sm">{$_('section.settings.httpAuthUser')}</Label>
|
||||
<Label md={6} for="httpAuthUser" size="sm"
|
||||
>{$_('section.settings.httpAuthUser')}</Label
|
||||
>
|
||||
<Col md="6">
|
||||
<Input
|
||||
type="text"
|
||||
|
@ -509,7 +851,9 @@
|
|||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Label md={6} for="httpAuthPass" size="sm">{$_('section.settings.httpAuthPass')}</Label>
|
||||
<Label md={6} for="httpAuthPass" size="sm"
|
||||
>{$_('section.settings.httpAuthPass')}</Label
|
||||
>
|
||||
<Col md="6">
|
||||
<InputGroup size={$uiSettings.inputSize}>
|
||||
<Input
|
||||
|
@ -587,166 +931,6 @@
|
|||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="ledTestOnPower"
|
||||
bind:checked={$settings.ledTestOnPower}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={$_('section.settings.ledPowerOnTest')}
|
||||
/>
|
||||
</Col>
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="ledFlashOnUpd"
|
||||
bind:checked={$settings.ledFlashOnUpd}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={$_('section.settings.ledFlashOnBlock')}
|
||||
/>
|
||||
</Col>
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="stealFocus"
|
||||
bind:checked={$settings.stealFocus}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={$_('section.settings.StealFocusOnNewBlock')}
|
||||
/>
|
||||
</Col>
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="mcapBigChar"
|
||||
bind:checked={$settings.mcapBigChar}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={$_('section.settings.useBigCharsMcap')}
|
||||
/>
|
||||
</Col>
|
||||
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="useBlkCountdown"
|
||||
bind:checked={$settings.useBlkCountdown}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={$_('section.settings.useBlkCountdown')}
|
||||
/>
|
||||
</Col>
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="useSatsSymbol"
|
||||
bind:checked={$settings.useSatsSymbol}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={$_('section.settings.useSatsSymbol')}
|
||||
/>
|
||||
</Col>
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="suffixPrice"
|
||||
bind:checked={$settings.suffixPrice}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={$_('section.settings.suffixPrice')}
|
||||
/>
|
||||
</Col>
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="disableLeds"
|
||||
bind:checked={$settings.disableLeds}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={$_('section.settings.disableLeds')}
|
||||
/>
|
||||
</Col>
|
||||
{#if $settings.hasFrontlight}
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="flDisable"
|
||||
bind:checked={$settings.flDisable}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={$_('section.settings.flDisable')}
|
||||
/>
|
||||
</Col>
|
||||
{/if}
|
||||
{#if $settings.hasFrontlight && !$settings.flDisable}
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="flAlwaysOn"
|
||||
bind:checked={$settings.flAlwaysOn}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={$_('section.settings.flAlwaysOn')}
|
||||
/>
|
||||
</Col>
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="flFlashOnUpd"
|
||||
bind:checked={$settings.flFlashOnUpd}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={$_('section.settings.flFlashOnUpd')}
|
||||
/>
|
||||
</Col>
|
||||
{/if}
|
||||
{#if !$settings.actCurrencies}
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="fetchEurPrice"
|
||||
bind:checked={$settings.fetchEurPrice}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label="{$_('section.settings.fetchEuroPrice')} ({$_('restartRequired')})"
|
||||
/>
|
||||
</Col>
|
||||
{/if}
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="ownDataSource"
|
||||
bind:checked={$settings.ownDataSource}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label="{$_('section.settings.ownDataSource')} ({$_('restartRequired')})"
|
||||
/>
|
||||
</Col>
|
||||
{#if $settings.nostrRelay}
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="useNostr"
|
||||
bind:checked={$settings.useNostr}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label="{$_('section.settings.useNostr')} ({$_('restartRequired')})"
|
||||
></Input>
|
||||
<Tooltip target="useNostr" placement="left">
|
||||
{$_('section.settings.useNostrTooltip')}
|
||||
</Tooltip>
|
||||
</Col>
|
||||
{/if}
|
||||
{#if 'nostrZapNotify' in $settings}
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="nostrZapNotify"
|
||||
bind:checked={$settings.nostrZapNotify}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label="{$_('section.settings.nostrZapNotify')} ({$_('restartRequired')})"
|
||||
/>
|
||||
</Col>
|
||||
{/if}
|
||||
{#if 'bitaxeEnabled' in $settings}
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="bitaxeEnabled"
|
||||
bind:checked={$settings.bitaxeEnabled}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label="{$_('section.settings.bitaxeEnabled')} ({$_('restartRequired')})"
|
||||
/>
|
||||
</Col>
|
||||
{/if}
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="otaEnabled"
|
||||
|
@ -774,59 +958,10 @@
|
|||
label="{$_('section.settings.httpAuthEnabled')} ({$_('restartRequired')})"
|
||||
/>
|
||||
</Col>
|
||||
{#if 'stagingSource' in $settings}
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="stagingSource"
|
||||
bind:checked={$settings.stagingSource}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label="{$_('section.settings.stagingSource')} ({$_('restartRequired')})"
|
||||
/>
|
||||
</Col>
|
||||
{/if}
|
||||
</Row>
|
||||
</ToggleHeader>
|
||||
</Row>
|
||||
|
||||
<Row>
|
||||
<h3>{$_('section.settings.screens')}</h3>
|
||||
{#if $settings.screens}
|
||||
{#each $settings.screens as s}
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<Input
|
||||
id="screens_{s.id}"
|
||||
bind:checked={s.enabled}
|
||||
type="switch"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={s.name}
|
||||
/>
|
||||
</Col>
|
||||
{/each}
|
||||
{/if}
|
||||
</Row>
|
||||
{#if $settings.actCurrencies && $settings.useNostr !== true}
|
||||
<Row>
|
||||
<h3>{$_('section.settings.currencies')}</h3>
|
||||
<small>{$_('restartRequired')}</small>
|
||||
{#if $settings.availableCurrencies}
|
||||
{#each $settings.availableCurrencies as c}
|
||||
<Col md="6" xl="12" xxl="6">
|
||||
<div class="form-check form-control-{$uiSettings.inputSize}">
|
||||
<input
|
||||
id="currency_{c}"
|
||||
bind:group={$settings.actCurrencies}
|
||||
value={c}
|
||||
type="checkbox"
|
||||
class="form-check-input"
|
||||
bsSize={$uiSettings.inputSize}
|
||||
label={c}
|
||||
/>
|
||||
<label class="form-check-label" for="currency_{c}">{c}</label>
|
||||
</div>
|
||||
</Col>
|
||||
{/each}
|
||||
{/if}
|
||||
</Row>
|
||||
{/if}
|
||||
<Row>
|
||||
<Col class="d-flex justify-content-end">
|
||||
<Button on:click={handleReset} color="secondary">{$_('button.reset')}</Button>
|
||||
|
|
|
@ -104,8 +104,8 @@
|
|||
export let xxl = xl;
|
||||
</script>
|
||||
|
||||
<Col {xs} {sm} {md} {lg} {xl} {xxl}>
|
||||
<Card>
|
||||
<Col {xs} {sm} {md} {lg} {xl} {xxl} class="mb-4 mb-xl-0">
|
||||
<Card id="status">
|
||||
<CardHeader>
|
||||
<CardTitle>{$_('section.status.title', { default: 'Status' })}</CardTitle>
|
||||
</CardHeader>
|
||||
|
@ -136,7 +136,7 @@
|
|||
</ButtonGroup>
|
||||
</div>
|
||||
{#if $settings.actCurrencies && $settings.ownDataSource}
|
||||
<div class="d-flex justify-content-center d-none d-sm-flex mt-2">
|
||||
<div class="d-flex justify-content-center d-sm-flex mt-2">
|
||||
<ButtonGroup size="sm">
|
||||
{#each $settings.actCurrencies as c}
|
||||
<Button
|
||||
|
@ -151,7 +151,11 @@
|
|||
<hr />
|
||||
{#if $status.data}
|
||||
<section class={lightMode ? 'lightMode' : 'darkMode'}>
|
||||
<Rendered status={$status} className="btclock-wrapper"></Rendered>
|
||||
<Rendered
|
||||
status={$status}
|
||||
className="btclock-wrapper"
|
||||
verticalDesc={$settings.verticalDesc}
|
||||
></Rendered>
|
||||
</section>
|
||||
{$_('section.status.screenCycle')}:
|
||||
<a
|
||||
|
|
BIN
static/bitaxe.webp
Normal file
BIN
static/bitaxe.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.4 KiB |
|
@ -1,11 +1,11 @@
|
|||
import adapter from '@sveltejs/adapter-static';
|
||||
import preprocess from 'svelte-preprocess';
|
||||
import { sveltePreprocess } from 'svelte-preprocess';
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
|
||||
// for more information about preprocessors
|
||||
preprocess: preprocess({}),
|
||||
preprocess: sveltePreprocess({}),
|
||||
build: {
|
||||
rollupOptions: {
|
||||
output: {
|
||||
|
|
|
@ -1,114 +1,7 @@
|
|||
import { expect, test } from '@playwright/test';
|
||||
import { initMock, settingsJson, statusJson } from '../shared';
|
||||
|
||||
const statusJson = {
|
||||
currentScreen: 0,
|
||||
numScreens: 7,
|
||||
timerRunning: true,
|
||||
espUptime: 4479,
|
||||
espFreeHeap: 58508,
|
||||
espHeapSize: 342108,
|
||||
connectionStatus: { price: true, blocks: true },
|
||||
rssi: -66,
|
||||
data: ['BLOCK/HEIGHT', '8', '1', '8', '0', '2', '6'],
|
||||
rendered: ['BLOCK/HEIGHT', '8', '1', '8', '0', '2', '6'],
|
||||
leds: [
|
||||
{ red: 0, green: 0, blue: 0, hex: '#000000' },
|
||||
{ red: 0, green: 0, blue: 0, hex: '#000000' },
|
||||
{ red: 0, green: 0, blue: 0, hex: '#000000' },
|
||||
{ red: 0, green: 0, blue: 0, hex: '#000000' }
|
||||
]
|
||||
};
|
||||
|
||||
const settingsJson = {
|
||||
numScreens: 7,
|
||||
fgColor: 415029,
|
||||
bgColor: 0,
|
||||
timerSeconds: 1800,
|
||||
timerRunning: true,
|
||||
minSecPriceUpd: 30,
|
||||
fullRefreshMin: 60,
|
||||
wpTimeout: 600,
|
||||
tzOffset: 0,
|
||||
useBitcoinNode: false,
|
||||
mempoolInstance: 'mempool.space',
|
||||
ledTestOnPower: true,
|
||||
ledFlashOnUpd: true,
|
||||
ledBrightness: 128,
|
||||
stealFocus: true,
|
||||
mcapBigChar: true,
|
||||
mdnsEnabled: true,
|
||||
otaEnabled: true,
|
||||
fetchEurPrice: false,
|
||||
hostnamePrefix: 'btclock',
|
||||
hostname: 'btclock-d60b14',
|
||||
ip: '192.168.20.231',
|
||||
txPower: 78,
|
||||
gitRev: '25d8b92bcbc8938417c140355ea3ba99ff9eb4b7',
|
||||
gitTag: '3.1.9',
|
||||
bitaxeEnabled: false,
|
||||
bitaxeHostname: 'bitaxe1',
|
||||
nostrZapNotify: true,
|
||||
hwRev: 'REV_A_EPD_2_13',
|
||||
fsRev: '4c5d9616212b27e3f05c35370f0befcf2c5a04b2',
|
||||
nostrZapPubkey: 'b5127a08cf33616274800a4387881a9f98e04b9c37116e92de5250498635c422',
|
||||
lastBuildTime: '1700666677',
|
||||
screens: [
|
||||
{ id: 0, name: 'Block Height', enabled: true },
|
||||
{ id: 1, name: 'Sats per dollar', enabled: true },
|
||||
{ id: 2, name: 'Ticker', enabled: true },
|
||||
{ id: 3, name: 'Time', enabled: true },
|
||||
{ id: 4, name: 'Halving countdown', enabled: true },
|
||||
{ id: 5, name: 'Market Cap', enabled: true }
|
||||
]
|
||||
};
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.route('*/**/api/status', async (route) => {
|
||||
await route.fulfill({ json: statusJson });
|
||||
});
|
||||
|
||||
await page.route('*/**/api/show/screen/1', async (route) => {
|
||||
//if (route.request().url().includes('*/**/api/show/screen/1')) {
|
||||
statusJson.currentScreen = 1;
|
||||
statusJson.data = ['MSCW/TIME', ' ', ' ', '2', '6', '4', '4'];
|
||||
statusJson.rendered = statusJson.data;
|
||||
//}
|
||||
|
||||
await route.fulfill({ json: statusJson });
|
||||
});
|
||||
|
||||
await page.route('*/**/api/show/screen/2', async (route) => {
|
||||
statusJson.currentScreen = 2;
|
||||
statusJson.data = ['BTC/USD', '$', '3', '7', '8', '2', '4'];
|
||||
statusJson.rendered = statusJson.data;
|
||||
|
||||
await route.fulfill({ json: statusJson });
|
||||
});
|
||||
|
||||
await page.route('*/**/api/show/screen/4', async (route) => {
|
||||
statusJson.currentScreen = 4;
|
||||
statusJson.data = ['BIT/COIN', 'HALV/ING', '0/YRS', '149/DAYS', '8/HRS', '30/MINS', 'TO/GO'];
|
||||
statusJson.rendered = statusJson.data;
|
||||
|
||||
await route.fulfill({ json: statusJson });
|
||||
});
|
||||
|
||||
await page.route('*/**/api/settings', async (route) => {
|
||||
await route.fulfill({ json: settingsJson });
|
||||
});
|
||||
|
||||
await page.route('**/events', (route) => {
|
||||
const newStatus = statusJson;
|
||||
newStatus.data = ['BLOCK/HEIGHT', '8', '0', '0', '8', '1', '5'];
|
||||
|
||||
// Respond with a custom SSE message
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'text/event-stream',
|
||||
json: `${JSON.stringify(newStatus)}\n\n`
|
||||
});
|
||||
});
|
||||
});
|
||||
test.beforeEach(initMock);
|
||||
|
||||
test('index page has expected columns control, status, settings', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
|
@ -137,6 +30,8 @@ test('api page has expected load button', async ({ page }) => {
|
|||
|
||||
test('timezone can be negative, zero and positive', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.getByRole('button', { name: 'Show all' }).click();
|
||||
|
||||
const tzOffsetField = 'input#tzOffset';
|
||||
|
||||
for (const val of ['-10', '0', '42']) {
|
||||
|
@ -149,6 +44,7 @@ test('timezone can be negative, zero and positive', async ({ page }) => {
|
|||
|
||||
test('time values can not be zero or negative', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.getByRole('button', { name: 'Show all' }).click();
|
||||
|
||||
for (const field of ['#timePerScreen', '#fullRefreshMin', '#minSecPriceUpd']) {
|
||||
for (const val of ['42', '210']) {
|
||||
|
@ -178,7 +74,11 @@ test('time values can not be zero or negative', async ({ page }) => {
|
|||
});
|
||||
|
||||
test('info message when fetch eur price is enabled', async ({ page }) => {
|
||||
delete (settingsJson as { actCurrencies?: string[] }).actCurrencies;
|
||||
|
||||
await page.goto('/');
|
||||
await page.getByRole('button', { name: 'Show all' }).click();
|
||||
|
||||
const inputField = 'input#fetchEurPrice';
|
||||
const switchElement = await page.locator(inputField);
|
||||
|
||||
|
@ -197,6 +97,7 @@ test('info message when fetch eur price is enabled', async ({ page }) => {
|
|||
|
||||
test('npub values will be converted to hex pubkeys', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.getByRole('button', { name: 'Show all' }).click();
|
||||
|
||||
for (const field of ['#nostrZapPubkey']) {
|
||||
for (const val of ['npub1k5f85zx0xdskyayqpfpc0zq6n7vwqjuuxugkayk72fgynp34cs3qfcvqg2']) {
|
||||
|
@ -212,6 +113,7 @@ test('npub values will be converted to hex pubkeys', async ({ page }) => {
|
|||
|
||||
test('empty nostr relay field is not accepted', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.getByRole('button', { name: 'Show all' }).click();
|
||||
|
||||
const nostrRelayField = page.getByLabel('Nostr Relay');
|
||||
|
88
tests/screenshots/viewport-screenshots.spec.ts
Normal file
88
tests/screenshots/viewport-screenshots.spec.ts
Normal file
|
@ -0,0 +1,88 @@
|
|||
import { test, expect } from '@playwright/test';
|
||||
|
||||
import { initMock, settingsJson, statusJson } from '../shared';
|
||||
|
||||
test.beforeEach(initMock);
|
||||
|
||||
test('capture screenshots across devices', async ({ page }, testInfo) => {
|
||||
await page.goto('/');
|
||||
await expect(page.getByRole('heading', { name: 'Control' })).toBeVisible();
|
||||
await expect(page.getByRole('heading', { name: 'Status' })).toBeVisible();
|
||||
await expect(page.getByRole('heading', { name: 'Settings' })).toBeVisible();
|
||||
|
||||
const screenshot = await page.screenshot({
|
||||
path: `./test-results/screenshots/default-${test.info().project.name.toLowerCase().replace(' ', '_')}.png`
|
||||
});
|
||||
|
||||
await testInfo.attach(`default`, {
|
||||
body: screenshot,
|
||||
contentType: 'image/png'
|
||||
});
|
||||
});
|
||||
|
||||
test('capture screenshots across devices with bitaxe screens', async ({ page }, testInfo) => {
|
||||
settingsJson.screens = [
|
||||
{
|
||||
id: 0,
|
||||
name: 'Block Height',
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: 'Time',
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: 'Halving countdown',
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: 'Block Fee Rate',
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
name: 'Sats per dollar',
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
id: 20,
|
||||
name: 'Ticker',
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
id: 30,
|
||||
name: 'Market Cap',
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
id: 80,
|
||||
name: 'BitAxe Hashrate',
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
id: 81,
|
||||
name: 'BitAxe Best Difficulty',
|
||||
enabled: true
|
||||
}
|
||||
];
|
||||
|
||||
statusJson.data = ['mdi:bitaxe', '', 'mdi:pickaxe', '6', '3', '7', 'GH/S'];
|
||||
statusJson.rendered = ['mdi:bitaxe', '', 'mdi:pickaxe', '6', '3', '7', 'GH/S'];
|
||||
|
||||
await page.goto('/');
|
||||
await expect(page.getByRole('heading', { name: 'Control' })).toBeVisible();
|
||||
await expect(page.getByRole('heading', { name: 'Status' })).toBeVisible();
|
||||
await expect(page.getByRole('heading', { name: 'Settings' })).toBeVisible();
|
||||
|
||||
await page.screenshot({
|
||||
path: `./test-results/screenshots/bitaxe-${test.info().project.name.toLowerCase().replace(' ', '_')}.png`
|
||||
});
|
||||
|
||||
await testInfo.attach(`bitaxe`, {
|
||||
path: `./test-results/screenshots/bitaxe-${test.info().project.name.toLowerCase().replace(' ', '_')}.png`,
|
||||
contentType: 'image/png'
|
||||
});
|
||||
});
|
140
tests/shared.ts
Normal file
140
tests/shared.ts
Normal file
|
@ -0,0 +1,140 @@
|
|||
export const statusJson = {
|
||||
currentScreen: 0,
|
||||
numScreens: 7,
|
||||
timerRunning: true,
|
||||
espUptime: 4479,
|
||||
espFreeHeap: 58508,
|
||||
espHeapSize: 342108,
|
||||
connectionStatus: { price: true, blocks: true },
|
||||
rssi: -66,
|
||||
data: ['BLOCK/HEIGHT', '8', '1', '8', '0', '2', '6'],
|
||||
rendered: ['BLOCK/HEIGHT', '8', '1', '8', '0', '2', '6'],
|
||||
leds: [
|
||||
{ red: 0, green: 0, blue: 0, hex: '#000000' },
|
||||
{ red: 0, green: 0, blue: 0, hex: '#000000' },
|
||||
{ red: 0, green: 0, blue: 0, hex: '#000000' },
|
||||
{ red: 0, green: 0, blue: 0, hex: '#000000' }
|
||||
]
|
||||
};
|
||||
|
||||
export const settingsJson = {
|
||||
numScreens: 7,
|
||||
fgColor: 415029,
|
||||
bgColor: 0,
|
||||
timerSeconds: 1800,
|
||||
timerRunning: true,
|
||||
minSecPriceUpd: 30,
|
||||
fullRefreshMin: 60,
|
||||
wpTimeout: 600,
|
||||
tzOffset: 0,
|
||||
useBitcoinNode: false,
|
||||
mempoolInstance: 'mempool.space',
|
||||
ledTestOnPower: true,
|
||||
ledFlashOnUpd: true,
|
||||
ledBrightness: 128,
|
||||
stealFocus: true,
|
||||
mcapBigChar: true,
|
||||
mdnsEnabled: true,
|
||||
otaEnabled: true,
|
||||
fetchEurPrice: false,
|
||||
hostnamePrefix: 'btclock',
|
||||
hostname: 'btclock-d60b14',
|
||||
ip: '192.168.20.231',
|
||||
txPower: 78,
|
||||
gitRev: '25d8b92bcbc8938417c140355ea3ba99ff9eb4b7',
|
||||
gitTag: '3.1.9',
|
||||
bitaxeEnabled: false,
|
||||
bitaxeHostname: 'bitaxe1',
|
||||
nostrZapNotify: true,
|
||||
hwRev: 'REV_A_EPD_2_13',
|
||||
fsRev: '4c5d9616212b27e3f05c35370f0befcf2c5a04b2',
|
||||
nostrZapPubkey: 'b5127a08cf33616274800a4387881a9f98e04b9c37116e92de5250498635c422',
|
||||
lastBuildTime: '1700666677',
|
||||
screens: [
|
||||
{
|
||||
id: 0,
|
||||
name: 'Block Height',
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: 'Time',
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: 'Halving countdown',
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: 'Block Fee Rate',
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
name: 'Sats per dollar',
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
id: 20,
|
||||
name: 'Ticker',
|
||||
enabled: true
|
||||
},
|
||||
{
|
||||
id: 30,
|
||||
name: 'Market Cap',
|
||||
enabled: true
|
||||
}
|
||||
],
|
||||
actCurrencies: ['USD', 'EUR'],
|
||||
availableCurrencies: ['USD', 'EUR', 'GBP', 'JPY', 'AUD', 'CAD']
|
||||
};
|
||||
|
||||
export const initMock = async ({ page }) => {
|
||||
await page.route('*/**/api/status', async (route) => {
|
||||
await route.fulfill({ json: statusJson });
|
||||
});
|
||||
|
||||
await page.route('*/**/api/show/screen/1', async (route) => {
|
||||
//if (route.request().url().includes('*/**/api/show/screen/1')) {
|
||||
statusJson.currentScreen = 1;
|
||||
statusJson.data = ['MSCW/TIME', ' ', ' ', '2', '6', '4', '4'];
|
||||
statusJson.rendered = statusJson.data;
|
||||
//}
|
||||
|
||||
await route.fulfill({ json: statusJson });
|
||||
});
|
||||
|
||||
await page.route('*/**/api/show/screen/2', async (route) => {
|
||||
statusJson.currentScreen = 2;
|
||||
statusJson.data = ['BTC/USD', '$', '3', '7', '8', '2', '4'];
|
||||
statusJson.rendered = statusJson.data;
|
||||
|
||||
await route.fulfill({ json: statusJson });
|
||||
});
|
||||
|
||||
await page.route('*/**/api/show/screen/4', async (route) => {
|
||||
statusJson.currentScreen = 4;
|
||||
statusJson.data = ['BIT/COIN', 'HALV/ING', '0/YRS', '149/DAYS', '8/HRS', '30/MINS', 'TO/GO'];
|
||||
statusJson.rendered = statusJson.data;
|
||||
|
||||
await route.fulfill({ json: statusJson });
|
||||
});
|
||||
|
||||
await page.route('*/**/api/settings', async (route) => {
|
||||
await route.fulfill({ json: settingsJson });
|
||||
});
|
||||
|
||||
await page.route('**/events', (route) => {
|
||||
const newStatus = statusJson;
|
||||
newStatus.data = ['BLOCK/HEIGHT', '8', '0', '0', '8', '1', '5'];
|
||||
|
||||
// Respond with a custom SSE message
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'text/event-stream',
|
||||
json: `${JSON.stringify(newStatus)}\n\n`
|
||||
});
|
||||
});
|
||||
};
|
|
@ -76,6 +76,14 @@ export default defineConfig({
|
|||
}
|
||||
}
|
||||
},
|
||||
css: {
|
||||
preprocessorOptions: {
|
||||
scss: {
|
||||
quietDeps: true,
|
||||
silenceDeprecations: ['import']
|
||||
}
|
||||
}
|
||||
},
|
||||
test: {
|
||||
include: ['src/**/*.{test,spec}.{js,ts}'],
|
||||
globals: true,
|
||||
|
|
394
yarn.lock
394
yarn.lock
|
@ -295,18 +295,20 @@
|
|||
integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==
|
||||
|
||||
"@eslint/config-array@^0.19.0":
|
||||
version "0.19.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.19.0.tgz#3251a528998de914d59bb21ba4c11767cf1b3519"
|
||||
integrity sha512-zdHg2FPIFNKPdcHWtiNT+jEFCHYVplAXRDlQDyqy0zGx/q2parwh7brGJSiTxRk/TSMkbM//zt/f5CHgyTyaSQ==
|
||||
version "0.19.1"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.19.1.tgz#734aaea2c40be22bbb1f2a9dac687c57a6a4c984"
|
||||
integrity sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==
|
||||
dependencies:
|
||||
"@eslint/object-schema" "^2.1.4"
|
||||
"@eslint/object-schema" "^2.1.5"
|
||||
debug "^4.3.1"
|
||||
minimatch "^3.1.2"
|
||||
|
||||
"@eslint/core@^0.9.0":
|
||||
version "0.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.9.0.tgz#168ee076f94b152c01ca416c3e5cf82290ab4fcd"
|
||||
integrity sha512-7ATR9F0e4W85D/0w7cU0SNj7qkAexMG+bAHEZOjo9akvGuhHE2m7umzWzfnpa0XAg5Kxc1BWmtPMV67jJ+9VUg==
|
||||
version "0.9.1"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.9.1.tgz#31763847308ef6b7084a4505573ac9402c51f9d1"
|
||||
integrity sha512-GuUdqkyyzQI5RMIWkHhvTWLCyLo1jNK3vzkSyaExH5kHPDHcuL2VOpHjmMY+y3+NC69qAKToBqldTBgYeLSr9Q==
|
||||
dependencies:
|
||||
"@types/json-schema" "^7.0.15"
|
||||
|
||||
"@eslint/eslintrc@^3.2.0":
|
||||
version "3.2.0"
|
||||
|
@ -323,20 +325,20 @@
|
|||
minimatch "^3.1.2"
|
||||
strip-json-comments "^3.1.1"
|
||||
|
||||
"@eslint/js@9.15.0":
|
||||
version "9.15.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.15.0.tgz#df0e24fe869143b59731942128c19938fdbadfb5"
|
||||
integrity sha512-tMTqrY+EzbXmKJR5ToI8lxu7jaN5EdmrBFJpQk5JmSlyLsx6o4t27r883K5xsLuCYCpfKBCGswMSWXsM+jB7lg==
|
||||
"@eslint/js@9.16.0":
|
||||
version "9.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.16.0.tgz#3df2b2dd3b9163056616886c86e4082f45dbf3f4"
|
||||
integrity sha512-tw2HxzQkrbeuvyj1tG2Yqq+0H9wGoI2IMk4EOsQeX+vmd75FtJAzf+gTA69WF+baUKRYQ3x2kbLE08js5OsTVg==
|
||||
|
||||
"@eslint/object-schema@^2.1.4":
|
||||
version "2.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.4.tgz#9e69f8bb4031e11df79e03db09f9dbbae1740843"
|
||||
integrity sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==
|
||||
"@eslint/object-schema@^2.1.5":
|
||||
version "2.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.5.tgz#8670a8f6258a2be5b2c620ff314a1d984c23eb2e"
|
||||
integrity sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==
|
||||
|
||||
"@eslint/plugin-kit@^0.2.3":
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.3.tgz#812980a6a41ecf3a8341719f92a6d1e784a2e0e8"
|
||||
integrity sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==
|
||||
version "0.2.4"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.4.tgz#2b78e7bb3755784bb13faa8932a1d994d6537792"
|
||||
integrity sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==
|
||||
dependencies:
|
||||
levn "^0.4.1"
|
||||
|
||||
|
@ -605,11 +607,11 @@
|
|||
"@parcel/watcher-win32-x64" "2.5.0"
|
||||
|
||||
"@playwright/test@^1.46.0":
|
||||
version "1.49.0"
|
||||
resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.49.0.tgz#74227385b58317ee076b86b56d0e1e1b25cff01e"
|
||||
integrity sha512-DMulbwQURa8rNIQrf94+jPJQ4FmOVdpE5ZppRNvWVjvhC+6sOeo28r8MgIpQRYouXRtt/FCCXU7zn20jnHR4Qw==
|
||||
version "1.49.1"
|
||||
resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.49.1.tgz#55fa360658b3187bfb6371e2f8a64f50ef80c827"
|
||||
integrity sha512-Ky+BVzPz8pL6PQxHqNRW1k3mIyv933LML7HktS8uik0bUXNCdPhoS/kLihiO1tMf/egaJb4IutXd7UywvXEW+g==
|
||||
dependencies:
|
||||
playwright "1.49.0"
|
||||
playwright "1.49.1"
|
||||
|
||||
"@polka/url@^1.0.0-next.24":
|
||||
version "1.0.0-next.28"
|
||||
|
@ -767,9 +769,9 @@
|
|||
integrity sha512-MGJcesnJWj7FxDcB/GbrdYD3q24Uk0PIL4QIX149ku+hlJuj//nxUbb0HxUTpjkecWfHjVveSUnUaQWnPRXlpg==
|
||||
|
||||
"@sveltejs/kit@^2.0.0":
|
||||
version "2.7.5"
|
||||
resolved "https://registry.yarnpkg.com/@sveltejs/kit/-/kit-2.7.5.tgz#234ffbb4a0b7df9146807992849e9f0fedc2b94d"
|
||||
integrity sha512-8WIrVch2Ze2Rq3eIMPTqIIRFPM2zGQcGKHim2z43KVRdgdtYWBugAQ7nemH9ATnzlvbgztk6hwhEZOi8A8ZOPg==
|
||||
version "2.8.5"
|
||||
resolved "https://registry.yarnpkg.com/@sveltejs/kit/-/kit-2.8.5.tgz#6eb3617547619cf38b19fb2e00da6aa00d0a44c8"
|
||||
integrity sha512-5ry1jPd4r9knsphDK2eTYUFPhFZMqF0PHFfa8MdMQCqWaKwLSXdFMU/Vevih1I7C1/VNB5MvTuFl1kXu5vx8UA==
|
||||
dependencies:
|
||||
"@types/cookie" "^0.6.0"
|
||||
cookie "^0.6.0"
|
||||
|
@ -875,62 +877,62 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/swagger-ui/-/swagger-ui-3.52.4.tgz#96c4886e8f86ae392f8d940bf7029cf490a51c72"
|
||||
integrity sha512-7NV7q8BfupqdQxr26OkM0g0YEPB9uXnKGzXadgcearvI9MoCHt3F72lPTX3fZZIlrr21DC0IK26wcDMZ37oFDA==
|
||||
|
||||
"@typescript-eslint/eslint-plugin@8.16.0", "@typescript-eslint/eslint-plugin@^8.7.0":
|
||||
version "8.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.16.0.tgz#ac56825bcdf3b392fc76a94b1315d4a162f201a6"
|
||||
integrity sha512-5YTHKV8MYlyMI6BaEG7crQ9BhSc8RxzshOReKwZwRWN0+XvvTOm+L/UYLCYxFpfwYuAAqhxiq4yae0CMFwbL7Q==
|
||||
"@typescript-eslint/eslint-plugin@8.18.0", "@typescript-eslint/eslint-plugin@^8.7.0":
|
||||
version "8.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.18.0.tgz#0901933326aea4443b81df3f740ca7dfc45c7bea"
|
||||
integrity sha512-NR2yS7qUqCL7AIxdJUQf2MKKNDVNaig/dEB0GBLU7D+ZdHgK1NoH/3wsgO3OnPVipn51tG3MAwaODEGil70WEw==
|
||||
dependencies:
|
||||
"@eslint-community/regexpp" "^4.10.0"
|
||||
"@typescript-eslint/scope-manager" "8.16.0"
|
||||
"@typescript-eslint/type-utils" "8.16.0"
|
||||
"@typescript-eslint/utils" "8.16.0"
|
||||
"@typescript-eslint/visitor-keys" "8.16.0"
|
||||
"@typescript-eslint/scope-manager" "8.18.0"
|
||||
"@typescript-eslint/type-utils" "8.18.0"
|
||||
"@typescript-eslint/utils" "8.18.0"
|
||||
"@typescript-eslint/visitor-keys" "8.18.0"
|
||||
graphemer "^1.4.0"
|
||||
ignore "^5.3.1"
|
||||
natural-compare "^1.4.0"
|
||||
ts-api-utils "^1.3.0"
|
||||
|
||||
"@typescript-eslint/parser@8.16.0", "@typescript-eslint/parser@^8.7.0":
|
||||
version "8.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.16.0.tgz#ee5b2d6241c1ab3e2e53f03fd5a32d8e266d8e06"
|
||||
integrity sha512-D7DbgGFtsqIPIFMPJwCad9Gfi/hC0PWErRRHFnaCWoEDYi5tQUDiJCTmGUbBiLzjqAck4KcXt9Ayj0CNlIrF+w==
|
||||
"@typescript-eslint/parser@8.18.0", "@typescript-eslint/parser@^8.7.0":
|
||||
version "8.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.18.0.tgz#a1c9456cbb6a089730bf1d3fc47946c5fb5fe67b"
|
||||
integrity sha512-hgUZ3kTEpVzKaK3uNibExUYm6SKKOmTU2BOxBSvOYwtJEPdVQ70kZJpPjstlnhCHcuc2WGfSbpKlb/69ttyN5Q==
|
||||
dependencies:
|
||||
"@typescript-eslint/scope-manager" "8.16.0"
|
||||
"@typescript-eslint/types" "8.16.0"
|
||||
"@typescript-eslint/typescript-estree" "8.16.0"
|
||||
"@typescript-eslint/visitor-keys" "8.16.0"
|
||||
"@typescript-eslint/scope-manager" "8.18.0"
|
||||
"@typescript-eslint/types" "8.18.0"
|
||||
"@typescript-eslint/typescript-estree" "8.18.0"
|
||||
"@typescript-eslint/visitor-keys" "8.18.0"
|
||||
debug "^4.3.4"
|
||||
|
||||
"@typescript-eslint/scope-manager@8.16.0":
|
||||
version "8.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.16.0.tgz#ebc9a3b399a69a6052f3d88174456dd399ef5905"
|
||||
integrity sha512-mwsZWubQvBki2t5565uxF0EYvG+FwdFb8bMtDuGQLdCCnGPrDEDvm1gtfynuKlnpzeBRqdFCkMf9jg1fnAK8sg==
|
||||
"@typescript-eslint/scope-manager@8.18.0":
|
||||
version "8.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.18.0.tgz#30b040cb4557804a7e2bcc65cf8fdb630c96546f"
|
||||
integrity sha512-PNGcHop0jkK2WVYGotk/hxj+UFLhXtGPiGtiaWgVBVP1jhMoMCHlTyJA+hEj4rszoSdLTK3fN4oOatrL0Cp+Xw==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "8.16.0"
|
||||
"@typescript-eslint/visitor-keys" "8.16.0"
|
||||
"@typescript-eslint/types" "8.18.0"
|
||||
"@typescript-eslint/visitor-keys" "8.18.0"
|
||||
|
||||
"@typescript-eslint/type-utils@8.16.0":
|
||||
version "8.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.16.0.tgz#585388735f7ac390f07c885845c3d185d1b64740"
|
||||
integrity sha512-IqZHGG+g1XCWX9NyqnI/0CX5LL8/18awQqmkZSl2ynn8F76j579dByc0jhfVSnSnhf7zv76mKBQv9HQFKvDCgg==
|
||||
"@typescript-eslint/type-utils@8.18.0":
|
||||
version "8.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.18.0.tgz#6f0d12cf923b6fd95ae4d877708c0adaad93c471"
|
||||
integrity sha512-er224jRepVAVLnMF2Q7MZJCq5CsdH2oqjP4dT7K6ij09Kyd+R21r7UVJrF0buMVdZS5QRhDzpvzAxHxabQadow==
|
||||
dependencies:
|
||||
"@typescript-eslint/typescript-estree" "8.16.0"
|
||||
"@typescript-eslint/utils" "8.16.0"
|
||||
"@typescript-eslint/typescript-estree" "8.18.0"
|
||||
"@typescript-eslint/utils" "8.18.0"
|
||||
debug "^4.3.4"
|
||||
ts-api-utils "^1.3.0"
|
||||
|
||||
"@typescript-eslint/types@8.16.0":
|
||||
version "8.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.16.0.tgz#49c92ae1b57942458ab83d9ec7ccab3005e64737"
|
||||
integrity sha512-NzrHj6thBAOSE4d9bsuRNMvk+BvaQvmY4dDglgkgGC0EW/tB3Kelnp3tAKH87GEwzoxgeQn9fNGRyFJM/xd+GQ==
|
||||
"@typescript-eslint/types@8.18.0":
|
||||
version "8.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.18.0.tgz#3afcd30def8756bc78541268ea819a043221d5f3"
|
||||
integrity sha512-FNYxgyTCAnFwTrzpBGq+zrnoTO4x0c1CKYY5MuUTzpScqmY5fmsh2o3+57lqdI3NZucBDCzDgdEbIaNfAjAHQA==
|
||||
|
||||
"@typescript-eslint/typescript-estree@8.16.0":
|
||||
version "8.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.16.0.tgz#9d741e56e5b13469b5190e763432ce5551a9300c"
|
||||
integrity sha512-E2+9IzzXMc1iaBy9zmo+UYvluE3TW7bCGWSF41hVWUE01o8nzr1rvOQYSxelxr6StUvRcTMe633eY8mXASMaNw==
|
||||
"@typescript-eslint/typescript-estree@8.18.0":
|
||||
version "8.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.18.0.tgz#d8ca785799fbb9c700cdff1a79c046c3e633c7f9"
|
||||
integrity sha512-rqQgFRu6yPkauz+ms3nQpohwejS8bvgbPyIDq13cgEDbkXt4LH4OkDMT0/fN1RUtzG8e8AKJyDBoocuQh8qNeg==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "8.16.0"
|
||||
"@typescript-eslint/visitor-keys" "8.16.0"
|
||||
"@typescript-eslint/types" "8.18.0"
|
||||
"@typescript-eslint/visitor-keys" "8.18.0"
|
||||
debug "^4.3.4"
|
||||
fast-glob "^3.3.2"
|
||||
is-glob "^4.0.3"
|
||||
|
@ -938,80 +940,80 @@
|
|||
semver "^7.6.0"
|
||||
ts-api-utils "^1.3.0"
|
||||
|
||||
"@typescript-eslint/utils@8.16.0":
|
||||
version "8.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.16.0.tgz#c71264c437157feaa97842809836254a6fc833c3"
|
||||
integrity sha512-C1zRy/mOL8Pj157GiX4kaw7iyRLKfJXBR3L82hk5kS/GyHcOFmy4YUq/zfZti72I9wnuQtA/+xzft4wCC8PJdA==
|
||||
"@typescript-eslint/utils@8.18.0":
|
||||
version "8.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.18.0.tgz#48f67205d42b65d895797bb7349d1be5c39a62f7"
|
||||
integrity sha512-p6GLdY383i7h5b0Qrfbix3Vc3+J2k6QWw6UMUeY5JGfm3C5LbZ4QIZzJNoNOfgyRe0uuYKjvVOsO/jD4SJO+xg==
|
||||
dependencies:
|
||||
"@eslint-community/eslint-utils" "^4.4.0"
|
||||
"@typescript-eslint/scope-manager" "8.16.0"
|
||||
"@typescript-eslint/types" "8.16.0"
|
||||
"@typescript-eslint/typescript-estree" "8.16.0"
|
||||
"@typescript-eslint/scope-manager" "8.18.0"
|
||||
"@typescript-eslint/types" "8.18.0"
|
||||
"@typescript-eslint/typescript-estree" "8.18.0"
|
||||
|
||||
"@typescript-eslint/visitor-keys@8.16.0":
|
||||
version "8.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.16.0.tgz#d5086afc060b01ff7a4ecab8d49d13d5a7b07705"
|
||||
integrity sha512-pq19gbaMOmFE3CbL0ZB8J8BFCo2ckfHBfaIsaOZgBIF4EoISJIdLX5xRhd0FGB0LlHReNRuzoJoMGpTjq8F2CQ==
|
||||
"@typescript-eslint/visitor-keys@8.18.0":
|
||||
version "8.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.18.0.tgz#7b6d33534fa808e33a19951907231ad2ea5c36dd"
|
||||
integrity sha512-pCh/qEA8Lb1wVIqNvBke8UaRjJ6wrAWkJO5yyIbs8Yx6TNGYyfNjOo61tLv+WwLvoLPp4BQ8B7AHKijl8NGUfw==
|
||||
dependencies:
|
||||
"@typescript-eslint/types" "8.16.0"
|
||||
"@typescript-eslint/types" "8.18.0"
|
||||
eslint-visitor-keys "^4.2.0"
|
||||
|
||||
"@vitest/expect@2.1.5":
|
||||
version "2.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-2.1.5.tgz#5a6afa6314cae7a61847927bb5bc038212ca7381"
|
||||
integrity sha512-nZSBTW1XIdpZvEJyoP/Sy8fUg0b8od7ZpGDkTUcfJ7wz/VoZAFzFfLyxVxGFhUjJzhYqSbIpfMtl/+k/dpWa3Q==
|
||||
"@vitest/expect@2.1.8":
|
||||
version "2.1.8"
|
||||
resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-2.1.8.tgz#13fad0e8d5a0bf0feb675dcf1d1f1a36a1773bc1"
|
||||
integrity sha512-8ytZ/fFHq2g4PJVAtDX57mayemKgDR6X3Oa2Foro+EygiOJHUXhCqBAAKQYYajZpFoIfvBCF1j6R6IYRSIUFuw==
|
||||
dependencies:
|
||||
"@vitest/spy" "2.1.5"
|
||||
"@vitest/utils" "2.1.5"
|
||||
"@vitest/spy" "2.1.8"
|
||||
"@vitest/utils" "2.1.8"
|
||||
chai "^5.1.2"
|
||||
tinyrainbow "^1.2.0"
|
||||
|
||||
"@vitest/mocker@2.1.5":
|
||||
version "2.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@vitest/mocker/-/mocker-2.1.5.tgz#54ee50648bc0bb606dfc58e13edfacb8b9208324"
|
||||
integrity sha512-XYW6l3UuBmitWqSUXTNXcVBUCRytDogBsWuNXQijc00dtnU/9OqpXWp4OJroVrad/gLIomAq9aW8yWDBtMthhQ==
|
||||
"@vitest/mocker@2.1.8":
|
||||
version "2.1.8"
|
||||
resolved "https://registry.yarnpkg.com/@vitest/mocker/-/mocker-2.1.8.tgz#51dec42ac244e949d20009249e033e274e323f73"
|
||||
integrity sha512-7guJ/47I6uqfttp33mgo6ga5Gr1VnL58rcqYKyShoRK9ebu8T5Rs6HN3s1NABiBeVTdWNrwUMcHH54uXZBN4zA==
|
||||
dependencies:
|
||||
"@vitest/spy" "2.1.5"
|
||||
"@vitest/spy" "2.1.8"
|
||||
estree-walker "^3.0.3"
|
||||
magic-string "^0.30.12"
|
||||
|
||||
"@vitest/pretty-format@2.1.5", "@vitest/pretty-format@^2.1.5":
|
||||
version "2.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-2.1.5.tgz#bc79b8826d4a63dc04f2a75d2944694039fa50aa"
|
||||
integrity sha512-4ZOwtk2bqG5Y6xRGHcveZVr+6txkH7M2e+nPFd6guSoN638v/1XQ0K06eOpi0ptVU/2tW/pIU4IoPotY/GZ9fw==
|
||||
"@vitest/pretty-format@2.1.8", "@vitest/pretty-format@^2.1.8":
|
||||
version "2.1.8"
|
||||
resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-2.1.8.tgz#88f47726e5d0cf4ba873d50c135b02e4395e2bca"
|
||||
integrity sha512-9HiSZ9zpqNLKlbIDRWOnAWqgcA7xu+8YxXSekhr0Ykab7PAYFkhkwoqVArPOtJhPmYeE2YHgKZlj3CP36z2AJQ==
|
||||
dependencies:
|
||||
tinyrainbow "^1.2.0"
|
||||
|
||||
"@vitest/runner@2.1.5":
|
||||
version "2.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-2.1.5.tgz#4d5e2ba2dfc0af74e4b0f9f3f8be020559b26ea9"
|
||||
integrity sha512-pKHKy3uaUdh7X6p1pxOkgkVAFW7r2I818vHDthYLvUyjRfkKOU6P45PztOch4DZarWQne+VOaIMwA/erSSpB9g==
|
||||
"@vitest/runner@2.1.8":
|
||||
version "2.1.8"
|
||||
resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-2.1.8.tgz#b0e2dd29ca49c25e9323ea2a45a5125d8729759f"
|
||||
integrity sha512-17ub8vQstRnRlIU5k50bG+QOMLHRhYPAna5tw8tYbj+jzjcspnwnwtPtiOlkuKC4+ixDPTuLZiqiWWQ2PSXHVg==
|
||||
dependencies:
|
||||
"@vitest/utils" "2.1.5"
|
||||
"@vitest/utils" "2.1.8"
|
||||
pathe "^1.1.2"
|
||||
|
||||
"@vitest/snapshot@2.1.5":
|
||||
version "2.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-2.1.5.tgz#a09a8712547452a84e08b3ec97b270d9cc156b4f"
|
||||
integrity sha512-zmYw47mhfdfnYbuhkQvkkzYroXUumrwWDGlMjpdUr4jBd3HZiV2w7CQHj+z7AAS4VOtWxI4Zt4bWt4/sKcoIjg==
|
||||
"@vitest/snapshot@2.1.8":
|
||||
version "2.1.8"
|
||||
resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-2.1.8.tgz#d5dc204f4b95dc8b5e468b455dfc99000047d2de"
|
||||
integrity sha512-20T7xRFbmnkfcmgVEz+z3AU/3b0cEzZOt/zmnvZEctg64/QZbSDJEVm9fLnnlSi74KibmRsO9/Qabi+t0vCRPg==
|
||||
dependencies:
|
||||
"@vitest/pretty-format" "2.1.5"
|
||||
"@vitest/pretty-format" "2.1.8"
|
||||
magic-string "^0.30.12"
|
||||
pathe "^1.1.2"
|
||||
|
||||
"@vitest/spy@2.1.5":
|
||||
version "2.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-2.1.5.tgz#f790d1394a5030644217ce73562e92465e83147e"
|
||||
integrity sha512-aWZF3P0r3w6DiYTVskOYuhBc7EMc3jvn1TkBg8ttylFFRqNN2XGD7V5a4aQdk6QiUzZQ4klNBSpCLJgWNdIiNw==
|
||||
"@vitest/spy@2.1.8":
|
||||
version "2.1.8"
|
||||
resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-2.1.8.tgz#bc41af3e1e6a41ae3b67e51f09724136b88fa447"
|
||||
integrity sha512-5swjf2q95gXeYPevtW0BLk6H8+bPlMb4Vw/9Em4hFxDcaOxS+e0LOX4yqNxoHzMR2akEB2xfpnWUzkZokmgWDg==
|
||||
dependencies:
|
||||
tinyspy "^3.0.2"
|
||||
|
||||
"@vitest/ui@^2.0.5":
|
||||
version "2.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@vitest/ui/-/ui-2.1.5.tgz#71e9cc198b481380698c24207359bc2f1ba5cb72"
|
||||
integrity sha512-ERgKkDMTfngrZip6VG5h8L9B5D0AH/4+bga4yR1UzGH7c2cxv3LWogw2Dvuwr9cP3/iKDHYys7kIFLDKpxORTg==
|
||||
version "2.1.8"
|
||||
resolved "https://registry.yarnpkg.com/@vitest/ui/-/ui-2.1.8.tgz#4a4d88e20bcced4c8710826cd4e2795f5ec1f0a1"
|
||||
integrity sha512-5zPJ1fs0ixSVSs5+5V2XJjXLmNzjugHRyV11RqxYVR+oMcogZ9qTuSfKW+OcTV0JeFNznI83BNylzH6SSNJ1+w==
|
||||
dependencies:
|
||||
"@vitest/utils" "2.1.5"
|
||||
"@vitest/utils" "2.1.8"
|
||||
fflate "^0.8.2"
|
||||
flatted "^3.3.1"
|
||||
pathe "^1.1.2"
|
||||
|
@ -1019,12 +1021,12 @@
|
|||
tinyglobby "^0.2.10"
|
||||
tinyrainbow "^1.2.0"
|
||||
|
||||
"@vitest/utils@2.1.5":
|
||||
version "2.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-2.1.5.tgz#0e19ce677c870830a1573d33ee86b0d6109e9546"
|
||||
integrity sha512-yfj6Yrp0Vesw2cwJbP+cl04OC+IHFsuQsrsJBL9pyGeQXE56v1UAOQco+SR55Vf1nQzfV0QJg1Qum7AaWUwwYg==
|
||||
"@vitest/utils@2.1.8":
|
||||
version "2.1.8"
|
||||
resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-2.1.8.tgz#f8ef85525f3362ebd37fd25d268745108d6ae388"
|
||||
integrity sha512-dwSoui6djdwbfFmIgbIjX2ZhIoG7Ex/+xpxyiEgIGzjliY8xGkcpITKTlp6B4MgtGkF2ilvm97cPM96XZaAgcA==
|
||||
dependencies:
|
||||
"@vitest/pretty-format" "2.1.5"
|
||||
"@vitest/pretty-format" "2.1.8"
|
||||
loupe "^3.1.2"
|
||||
tinyrainbow "^1.2.0"
|
||||
|
||||
|
@ -1043,16 +1045,11 @@ acorn@^8.10.0:
|
|||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248"
|
||||
integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==
|
||||
|
||||
acorn@^8.14.0:
|
||||
acorn@^8.14.0, acorn@^8.9.0:
|
||||
version "8.14.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.0.tgz#063e2c70cac5fb4f6467f0b11152e04c682795b0"
|
||||
integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==
|
||||
|
||||
acorn@^8.9.0:
|
||||
version "8.13.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.13.0.tgz#2a30d670818ad16ddd6a35d3842dacec9e5d7ca3"
|
||||
integrity sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==
|
||||
|
||||
agent-base@^7.0.2, agent-base@^7.1.0:
|
||||
version "7.1.1"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.1.tgz#bdbded7dfb096b751a2a087eeeb9664725b2e317"
|
||||
|
@ -1345,13 +1342,20 @@ data-urls@^5.0.0:
|
|||
whatwg-mimetype "^4.0.0"
|
||||
whatwg-url "^14.0.0"
|
||||
|
||||
debug@4, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.7:
|
||||
debug@4:
|
||||
version "4.3.7"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52"
|
||||
integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==
|
||||
dependencies:
|
||||
ms "^2.1.3"
|
||||
|
||||
debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.7:
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a"
|
||||
integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==
|
||||
dependencies:
|
||||
ms "^2.1.3"
|
||||
|
||||
decimal.js@^10.4.3:
|
||||
version "10.4.3"
|
||||
resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23"
|
||||
|
@ -1546,9 +1550,9 @@ eslint-config-prettier@^9.1.0:
|
|||
integrity sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==
|
||||
|
||||
eslint-plugin-svelte@^2.36.0:
|
||||
version "2.46.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-svelte/-/eslint-plugin-svelte-2.46.0.tgz#87bcc2820233065f79114012203b082319ff03e9"
|
||||
integrity sha512-1A7iEMkzmCZ9/Iz+EAfOGYL8IoIG6zeKEq1SmpxGeM5SXmoQq+ZNnCpXFVJpsxPWYx8jIVGMerQMzX20cqUl0g==
|
||||
version "2.46.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-svelte/-/eslint-plugin-svelte-2.46.1.tgz#22691c8685420cd4eabf0cbaa31a0cfb8395595b"
|
||||
integrity sha512-7xYr2o4NID/f9OEYMqxsEQsCsj4KaMy4q5sANaKkAb6/QeCjYFxRmDm2S3YC3A3pl1kyPZ/syOx/i7LcWYSbIw==
|
||||
dependencies:
|
||||
"@eslint-community/eslint-utils" "^4.4.0"
|
||||
"@jridgewell/sourcemap-codec" "^1.4.15"
|
||||
|
@ -1589,16 +1593,16 @@ eslint-visitor-keys@^4.2.0:
|
|||
integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==
|
||||
|
||||
eslint@^9.11.0:
|
||||
version "9.15.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.15.0.tgz#77c684a4e980e82135ebff8ee8f0a9106ce6b8a6"
|
||||
integrity sha512-7CrWySmIibCgT1Os28lUU6upBshZ+GxybLOrmRzi08kS8MBuO8QA7pXEgYgY5W8vK3e74xv0lpjo9DbaGU9Rkw==
|
||||
version "9.16.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.16.0.tgz#66832e66258922ac0a626f803a9273e37747f2a6"
|
||||
integrity sha512-whp8mSQI4C8VXd+fLgSM0lh3UlmcFtVwUQjyKCFfsp+2ItAIYhlq/hqGahGqHE6cv9unM41VlqKk2VtKYR2TaA==
|
||||
dependencies:
|
||||
"@eslint-community/eslint-utils" "^4.2.0"
|
||||
"@eslint-community/regexpp" "^4.12.1"
|
||||
"@eslint/config-array" "^0.19.0"
|
||||
"@eslint/core" "^0.9.0"
|
||||
"@eslint/eslintrc" "^3.2.0"
|
||||
"@eslint/js" "9.15.0"
|
||||
"@eslint/js" "9.16.0"
|
||||
"@eslint/plugin-kit" "^0.2.3"
|
||||
"@humanfs/node" "^0.16.6"
|
||||
"@humanwhocodes/module-importer" "^1.0.1"
|
||||
|
@ -1629,9 +1633,9 @@ eslint@^9.11.0:
|
|||
optionator "^0.9.3"
|
||||
|
||||
esm-env@^1.0.0:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/esm-env/-/esm-env-1.1.4.tgz#340c78b03ee2298d31c5b9fab9793468ede828b0"
|
||||
integrity sha512-oO82nKPHKkzIj/hbtuDYy/JHqBHFlMIW36SDiPCVsj87ntDLcWN+sJ1erdVryd4NxODacFTsdrIE3b7IamqbOg==
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/esm-env/-/esm-env-1.2.0.tgz#637c0586244c0eb14bfd7f5e96a6b43b9e8f5c2b"
|
||||
integrity sha512-OhSQuHL3mUcaQHjGe8UMG8GsJIJHYYz0flR0h9fiTPNMupLMkb7TvcRD0EeJXW5a8GHBgfz08b6FDLNK7kkPQA==
|
||||
|
||||
esniff@^2.0.1:
|
||||
version "2.0.1"
|
||||
|
@ -2248,16 +2252,16 @@ magic-string@^0.30.10, magic-string@^0.30.4:
|
|||
"@jridgewell/sourcemap-codec" "^1.5.0"
|
||||
|
||||
magic-string@^0.30.12:
|
||||
version "0.30.13"
|
||||
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.13.tgz#92438e3ff4946cf54f18247c981e5c161c46683c"
|
||||
integrity sha512-8rYBO+MsWkgjDSOvLomYnzhdwEG51olQ4zL5KXnNJWV5MNmrb4rTZdrtkhxjnD/QyZUqR/Z/XDsUs/4ej2nx0g==
|
||||
version "0.30.15"
|
||||
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.15.tgz#d5474a2c4c5f35f041349edaba8a5cb02733ed3c"
|
||||
integrity sha512-zXeaYRgZ6ldS1RJJUrMrYgNJ4fdwnyI6tVqoiIhyCyv5IVTK9BU8Ic2l253GGETQHxI4HNUwhJ3fjDhKqEoaAw==
|
||||
dependencies:
|
||||
"@jridgewell/sourcemap-codec" "^1.5.0"
|
||||
|
||||
magic-string@^0.30.5:
|
||||
version "0.30.12"
|
||||
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.12.tgz#9eb11c9d072b9bcb4940a5b2c2e1a217e4ee1a60"
|
||||
integrity sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==
|
||||
version "0.30.14"
|
||||
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.14.tgz#e9bb29870b81cfc1ec3cc656552f5a7fcbf19077"
|
||||
integrity sha512-5c99P1WKTed11ZC0HMJOj6CDIue6F8ySu+bJL+85q1zBEIY8IklrJ1eiKC2NDRh3Ct3FcvmJPyQHb9erXMTJNw==
|
||||
dependencies:
|
||||
"@jridgewell/sourcemap-codec" "^1.5.0"
|
||||
|
||||
|
@ -2350,9 +2354,9 @@ msgpack-es@^0.0.5:
|
|||
integrity sha512-iK8YNWqs4csqE7udSmuY/1bz0MH8L80eX2ZGIlf8g7G2aq9wRUbVpTbyixqQNNJZ2kJ8v2NgVzj0npRqdJBMuA==
|
||||
|
||||
nanoid@^3.3.7:
|
||||
version "3.3.7"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8"
|
||||
integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==
|
||||
version "3.3.8"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.8.tgz#b1be3030bee36aaff18bacb375e5cce521684baf"
|
||||
integrity sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==
|
||||
|
||||
natural-compare@^1.4.0:
|
||||
version "1.4.0"
|
||||
|
@ -2370,9 +2374,9 @@ node-addon-api@^7.0.0:
|
|||
integrity sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==
|
||||
|
||||
nostr-tools@^2.7.1:
|
||||
version "2.10.3"
|
||||
resolved "https://registry.yarnpkg.com/nostr-tools/-/nostr-tools-2.10.3.tgz#9af17e72fde60b0b42f1bee381381355072e899b"
|
||||
integrity sha512-XL+eX/kyXNoCdtgEFFT26YlGaMq/eUMaxlGWVyR8lqdDvSa9m8rrHRUiR8IYZWwq5B0534E8VXbiSuoUgGGIDw==
|
||||
version "2.10.4"
|
||||
resolved "https://registry.yarnpkg.com/nostr-tools/-/nostr-tools-2.10.4.tgz#2ba0a36d1f2e1b3d77c724ca8fad880c8de6844d"
|
||||
integrity sha512-biU7sk+jxHgVASfobg2T5ttxOGGSt69wEVBC51sHHOEaKAAdzHBLV/I2l9Rf61UzClhliZwNouYhqIso4a3HYg==
|
||||
dependencies:
|
||||
"@noble/ciphers" "^0.5.1"
|
||||
"@noble/curves" "1.2.0"
|
||||
|
@ -2381,9 +2385,9 @@ nostr-tools@^2.7.1:
|
|||
"@scure/bip32" "1.3.1"
|
||||
"@scure/bip39" "1.2.1"
|
||||
optionalDependencies:
|
||||
nostr-wasm v0.1.0
|
||||
nostr-wasm "0.1.0"
|
||||
|
||||
nostr-wasm@v0.1.0:
|
||||
nostr-wasm@0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/nostr-wasm/-/nostr-wasm-0.1.0.tgz#17af486745feb2b7dd29503fdd81613a24058d94"
|
||||
integrity sha512-78BTryCLcLYv96ONU8Ws3Q1JzjlAt+43pWQhIl86xZmWeegYCNLPml7yQ+gG3vR6V5h4XGj+TxO+SS5dsThQIA==
|
||||
|
@ -2513,7 +2517,7 @@ periscopic@^3.1.0:
|
|||
estree-walker "^3.0.0"
|
||||
is-reference "^3.0.0"
|
||||
|
||||
picocolors@^1.0.0, picocolors@^1.1.0, picocolors@^1.1.1:
|
||||
picocolors@^1.0.0, picocolors@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
|
||||
integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
|
||||
|
@ -2528,17 +2532,17 @@ picomatch@^4.0.2:
|
|||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.2.tgz#77c742931e8f3b8820946c76cd0c1f13730d1dab"
|
||||
integrity sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==
|
||||
|
||||
playwright-core@1.49.0:
|
||||
version "1.49.0"
|
||||
resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.49.0.tgz#8e69ffed3f41855b854982f3632f2922c890afcb"
|
||||
integrity sha512-R+3KKTQF3npy5GTiKH/T+kdhoJfJojjHESR1YEWhYuEKRVfVaxH3+4+GvXE5xyCngCxhxnykk0Vlah9v8fs3jA==
|
||||
playwright-core@1.49.1:
|
||||
version "1.49.1"
|
||||
resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.49.1.tgz#32c62f046e950f586ff9e35ed490a424f2248015"
|
||||
integrity sha512-BzmpVcs4kE2CH15rWfzpjzVGhWERJfmnXmniSyKeRZUs9Ws65m+RGIi7mjJK/euCegfn3i7jvqWeWyHe9y3Vgg==
|
||||
|
||||
playwright@1.49.0:
|
||||
version "1.49.0"
|
||||
resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.49.0.tgz#df6b9e05423377a99658202844a294a8afb95d0a"
|
||||
integrity sha512-eKpmys0UFDnfNb3vfsf8Vx2LEOtflgRebl0Im2eQQnYMA4Aqd+Zw8bEOB+7ZKvN76901mRnqdsiOGKxzVTbi7A==
|
||||
playwright@1.49.1:
|
||||
version "1.49.1"
|
||||
resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.49.1.tgz#830266dbca3008022afa7b4783565db9944ded7c"
|
||||
integrity sha512-VYL8zLoNTBxVOrJBbDuRgDWa3i+mfQgDTrL8Ah9QXZ7ax4Dsj0MSq5bYgytRnDVVe+njoKnfsYkH3HzqVj5UZA==
|
||||
dependencies:
|
||||
playwright-core "1.49.0"
|
||||
playwright-core "1.49.1"
|
||||
optionalDependencies:
|
||||
fsevents "2.3.2"
|
||||
|
||||
|
@ -2568,16 +2572,7 @@ postcss-selector-parser@^6.1.0:
|
|||
cssesc "^3.0.0"
|
||||
util-deprecate "^1.0.2"
|
||||
|
||||
postcss@^8.4.38, postcss@^8.4.39:
|
||||
version "8.4.47"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.47.tgz#5bf6c9a010f3e724c503bf03ef7947dcb0fea365"
|
||||
integrity sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==
|
||||
dependencies:
|
||||
nanoid "^3.3.7"
|
||||
picocolors "^1.1.0"
|
||||
source-map-js "^1.2.1"
|
||||
|
||||
postcss@^8.4.43:
|
||||
postcss@^8.4.38, postcss@^8.4.39, postcss@^8.4.43:
|
||||
version "8.4.49"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.49.tgz#4ea479048ab059ab3ae61d082190fabfd994fe19"
|
||||
integrity sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==
|
||||
|
@ -2597,9 +2592,9 @@ prettier-plugin-svelte@^3.2.6:
|
|||
integrity sha512-kRPjH8wSj2iu+dO+XaUv4vD8qr5mdDmlak3IT/7AOgGIMRG86z/EHOLauFcClKEnOUf4A4nOA7sre5KrJD4Raw==
|
||||
|
||||
prettier@^3.3.3:
|
||||
version "3.3.3"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.3.3.tgz#30c54fe0be0d8d12e6ae61dbb10109ea00d53105"
|
||||
integrity sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==
|
||||
version "3.4.2"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.4.2.tgz#a5ce1fb522a588bf2b78ca44c6e6fe5aa5a2b13f"
|
||||
integrity sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==
|
||||
|
||||
pretty-format@^27.0.2:
|
||||
version "27.5.1"
|
||||
|
@ -2717,9 +2712,9 @@ sade@^1.7.4, sade@^1.8.1:
|
|||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
||||
|
||||
sass@^1.79.3:
|
||||
version "1.81.0"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.81.0.tgz#a9010c0599867909dfdbad057e4a6fbdd5eec941"
|
||||
integrity sha512-Q4fOxRfhmv3sqCLoGfvrC9pRV8btc0UtqL9mN6Yrv6Qi9ScL55CVH1vlPP863ISLEEMNLLuu9P+enCeGHlnzhA==
|
||||
version "1.82.0"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.82.0.tgz#30da277af3d0fa6042e9ceabd0d984ed6d07df70"
|
||||
integrity sha512-j4GMCTa8elGyN9A7x7bEglx0VgSpNUG4W4wNedQ33wSMdnkqQCT8HTwOaVSV4e6yQovcu/3Oc4coJP/l0xhL2Q==
|
||||
dependencies:
|
||||
chokidar "^4.0.0"
|
||||
immutable "^5.0.2"
|
||||
|
@ -2831,10 +2826,15 @@ supports-color@^7.1.0:
|
|||
dependencies:
|
||||
has-flag "^4.0.0"
|
||||
|
||||
svelte-bootstrap-icons@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/svelte-bootstrap-icons/-/svelte-bootstrap-icons-3.1.1.tgz#aafacdffd0082ef1aea041784f7818f40083089a"
|
||||
integrity sha512-ghJlt6TX3IX35M7wSvGyrmVgXeT5GMRF+7+q6L4OUT2RJWF09mQIvZTZ04Ii3FBfg10KdzFdvVuoB8M0cVHfzw==
|
||||
|
||||
svelte-check@^4.0.2:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/svelte-check/-/svelte-check-4.1.0.tgz#4389c1c88aa24f3d06fe0df94f9075a55017256d"
|
||||
integrity sha512-AflEZYqI578KuDZcpcorPSf597LStxlkN7XqXi38u09zlHODVKd7c+7OuubGzbhgGRUqNTdQCZ+Ga96iRXEf2g==
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/svelte-check/-/svelte-check-4.1.1.tgz#4d6a97651bdcff84ad10521d0394ce094dee187a"
|
||||
integrity sha512-NfaX+6Qtc8W/CyVGS/F7/XdiSSyXz+WGYA9ZWV3z8tso14V2vzjfXviKaTFEzB7g8TqfgO2FOzP6XT4ApSTUTw==
|
||||
dependencies:
|
||||
"@jridgewell/trace-mapping" "^0.3.25"
|
||||
chokidar "^4.0.1"
|
||||
|
@ -2996,9 +2996,9 @@ tr46@^5.0.0:
|
|||
punycode "^2.3.1"
|
||||
|
||||
ts-api-utils@^1.3.0:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.4.1.tgz#7c0a304cd446d9a497c24c960b8abbf0bc1611ae"
|
||||
integrity sha512-5RU2/lxTA3YUZxju61HO2U6EoZLvBLtmV2mbTvqyu4a/7s7RmJPT+1YekhMVsQhznRWk/czIwDUg+V8Q9ZuG4w==
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.4.3.tgz#bfc2215fe6528fecab2b0fba570a2e8a4263b064"
|
||||
integrity sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==
|
||||
|
||||
tslib@^2.7.0:
|
||||
version "2.8.1"
|
||||
|
@ -3023,13 +3023,13 @@ type@^2.7.2:
|
|||
integrity sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==
|
||||
|
||||
typescript-eslint@^8.7.0:
|
||||
version "8.16.0"
|
||||
resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.16.0.tgz#d608c972d6b2461ca10ec30fd3fa62a080baba19"
|
||||
integrity sha512-wDkVmlY6O2do4V+lZd0GtRfbtXbeD0q9WygwXXSJnC1xorE8eqyC2L1tJimqpSeFrOzRlYtWnUp/uzgHQOgfBQ==
|
||||
version "8.18.0"
|
||||
resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.18.0.tgz#41026f27a3481185f3239d817ae5b960572145a0"
|
||||
integrity sha512-Xq2rRjn6tzVpAyHr3+nmSg1/9k9aIHnJ2iZeOH7cfGOWqTkXTm3kwpQglEuLGdNrYvPF+2gtAs+/KF5rjVo+WQ==
|
||||
dependencies:
|
||||
"@typescript-eslint/eslint-plugin" "8.16.0"
|
||||
"@typescript-eslint/parser" "8.16.0"
|
||||
"@typescript-eslint/utils" "8.16.0"
|
||||
"@typescript-eslint/eslint-plugin" "8.18.0"
|
||||
"@typescript-eslint/parser" "8.18.0"
|
||||
"@typescript-eslint/utils" "8.18.0"
|
||||
|
||||
typescript@^5.5.4:
|
||||
version "5.6.3"
|
||||
|
@ -3063,10 +3063,10 @@ uuid@^8.3.2:
|
|||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
|
||||
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
|
||||
|
||||
vite-node@2.1.5:
|
||||
version "2.1.5"
|
||||
resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-2.1.5.tgz#cf28c637b2ebe65921f3118a165b7cf00a1cdf19"
|
||||
integrity sha512-rd0QIgx74q4S1Rd56XIiL2cYEdyWn13cunYBIuqh9mpmQr7gGS0IxXoP8R6OaZtNQQLyXSWbd4rXKYUbhFpK5w==
|
||||
vite-node@2.1.8:
|
||||
version "2.1.8"
|
||||
resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-2.1.8.tgz#9495ca17652f6f7f95ca7c4b568a235e0c8dbac5"
|
||||
integrity sha512-uPAwSr57kYjAUux+8E2j0q0Fxpn8M9VoyfGiRI8Kfktz9NcYMCenwY5RnZxnF1WTu3TGiYipirIzacLL3VVGFg==
|
||||
dependencies:
|
||||
cac "^6.7.14"
|
||||
debug "^4.3.7"
|
||||
|
@ -3098,17 +3098,17 @@ vitest-github-actions-reporter@^0.11.0:
|
|||
"@actions/core" "^1.10.0"
|
||||
|
||||
vitest@^2.1.1:
|
||||
version "2.1.5"
|
||||
resolved "https://registry.yarnpkg.com/vitest/-/vitest-2.1.5.tgz#a93b7b84a84650130727baae441354e6df118148"
|
||||
integrity sha512-P4ljsdpuzRTPI/kbND2sDZ4VmieerR2c9szEZpjc+98Z9ebvnXmM5+0tHEKqYZumXqlvnmfWsjeFOjXVriDG7A==
|
||||
version "2.1.8"
|
||||
resolved "https://registry.yarnpkg.com/vitest/-/vitest-2.1.8.tgz#2e6a00bc24833574d535c96d6602fb64163092fa"
|
||||
integrity sha512-1vBKTZskHw/aosXqQUlVWWlGUxSJR8YtiyZDJAFeW2kPAeX6S3Sool0mjspO+kXLuxVWlEDDowBAeqeAQefqLQ==
|
||||
dependencies:
|
||||
"@vitest/expect" "2.1.5"
|
||||
"@vitest/mocker" "2.1.5"
|
||||
"@vitest/pretty-format" "^2.1.5"
|
||||
"@vitest/runner" "2.1.5"
|
||||
"@vitest/snapshot" "2.1.5"
|
||||
"@vitest/spy" "2.1.5"
|
||||
"@vitest/utils" "2.1.5"
|
||||
"@vitest/expect" "2.1.8"
|
||||
"@vitest/mocker" "2.1.8"
|
||||
"@vitest/pretty-format" "^2.1.8"
|
||||
"@vitest/runner" "2.1.8"
|
||||
"@vitest/snapshot" "2.1.8"
|
||||
"@vitest/spy" "2.1.8"
|
||||
"@vitest/utils" "2.1.8"
|
||||
chai "^5.1.2"
|
||||
debug "^4.3.7"
|
||||
expect-type "^1.1.0"
|
||||
|
@ -3120,7 +3120,7 @@ vitest@^2.1.1:
|
|||
tinypool "^1.0.1"
|
||||
tinyrainbow "^1.2.0"
|
||||
vite "^5.0.0"
|
||||
vite-node "2.1.5"
|
||||
vite-node "2.1.8"
|
||||
why-is-node-running "^2.3.0"
|
||||
|
||||
w3c-xmlserializer@^5.0.0:
|
||||
|
|
Loading…
Reference in a new issue