chore: format

This commit is contained in:
Tomáš Mládek 2025-09-26 22:19:02 +02:00
parent e6009c619c
commit 9a46fd53c6
15 changed files with 244 additions and 230 deletions

View file

@ -9,7 +9,7 @@ steps:
- /var/run/docker.sock:/var/run/docker.sock - /var/run/docker.sock:/var/run/docker.sock
environment: environment:
FORCE_COLOR: 1 FORCE_COLOR: 1
EARTHLY_EXEC_CMD: "/bin/sh" EARTHLY_EXEC_CMD: '/bin/sh'
EARTHLY_CONFIGURATION: EARTHLY_CONFIGURATION:
from_secret: EARTHLY_CONFIGURATION from_secret: EARTHLY_CONFIGURATION
SSH_CONFIG: SSH_CONFIG:
@ -25,4 +25,4 @@ steps:
- earthly bootstrap - earthly bootstrap
- earthly --secret SSH_CONFIG --secret SSH_UPLOAD_KEY --secret SSH_KNOWN_HOSTS --secret SSH_TARGET --push +deploy - earthly --secret SSH_CONFIG --secret SSH_UPLOAD_KEY --secret SSH_KNOWN_HOSTS --secret SSH_TARGET --push +deploy
when: when:
branch: ["main"] branch: ['main']

View file

@ -1,11 +1,11 @@
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<title>AV SYNC</title> <title>AV SYNC</title>
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>
<script type="module" src="/src/main.ts"></script> <script type="module" src="/src/main.ts"></script>
</body> </body>
</html> </html>

View file

@ -1,3 +1,4 @@
html, body { html,
margin: 0; body {
} margin: 0;
}

View file

@ -1,7 +1,7 @@
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
export default { export default {
// Consult https://svelte.dev/docs#compile-time-svelte-preprocess // Consult https://svelte.dev/docs#compile-time-svelte-preprocess
// for more information about preprocessors // for more information about preprocessors
preprocess: vitePreprocess(), preprocess: vitePreprocess()
} };

View file

@ -1,20 +1,20 @@
{ {
"extends": "@tsconfig/svelte/tsconfig.json", "extends": "@tsconfig/svelte/tsconfig.json",
"compilerOptions": { "compilerOptions": {
"target": "ESNext", "target": "ESNext",
"useDefineForClassFields": true, "useDefineForClassFields": true,
"module": "ESNext", "module": "ESNext",
"resolveJsonModule": true, "resolveJsonModule": true,
/** /**
* Typecheck JS in `.svelte` and `.js` files by default. * Typecheck JS in `.svelte` and `.js` files by default.
* Disable checkJs if you'd like to use dynamic types in JS. * Disable checkJs if you'd like to use dynamic types in JS.
* Note that setting allowJs false does not prevent the use * Note that setting allowJs false does not prevent the use
* of JS in `.svelte` files. * of JS in `.svelte` files.
*/ */
"allowJs": true, "allowJs": true,
"checkJs": true, "checkJs": true,
"isolatedModules": true "isolatedModules": true
}, },
"include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"], "include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"],
"references": [{ "path": "./tsconfig.node.json" }] "references": [{ "path": "./tsconfig.node.json" }]
} }

View file

@ -1,10 +1,10 @@
{ {
"compilerOptions": { "compilerOptions": {
"composite": true, "composite": true,
"skipLibCheck": true, "skipLibCheck": true,
"module": "ESNext", "module": "ESNext",
"moduleResolution": "bundler", "moduleResolution": "bundler",
"strict": true "strict": true
}, },
"include": ["vite.config.ts"] "include": ["vite.config.ts"]
} }

View file

@ -1,7 +1,7 @@
import { defineConfig } from 'vite' import { defineConfig } from 'vite';
import { svelte } from '@sveltejs/vite-plugin-svelte' import { svelte } from '@sveltejs/vite-plugin-svelte';
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
plugins: [svelte()], plugins: [svelte()]
}) });

View file

@ -1,61 +1,61 @@
{ {
"name": "testcard", "name": "testcard",
"version": "0.0.0", "version": "0.0.0",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "vite dev", "dev": "vite dev",
"build": "vite build", "build": "vite build",
"preview": "vite preview", "preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"lint": "prettier --check . && eslint .", "lint": "prettier --check . && eslint .",
"format": "prettier --write .", "format": "prettier --write .",
"generate-assets": "earthly +assets-generated", "generate-assets": "earthly +assets-generated",
"av:dev": "cd av-sync && vite", "av:dev": "cd av-sync && vite",
"av:render:video": "cd av-sync && concurrently -P -k -s command-1 \"vite --port 8626\" \"wait-on http://localhost:8626 && node render-video.js --url http://localhost:8626 {@}\" --", "av:render:video": "cd av-sync && concurrently -P -k -s command-1 \"vite --port 8626\" \"wait-on http://localhost:8626 && node render-video.js --url http://localhost:8626 {@}\" --",
"av:render:audio": "cd av-sync && node render-audio.js" "av:render:audio": "cd av-sync && node render-audio.js"
}, },
"devDependencies": { "devDependencies": {
"@tsconfig/svelte": "^5.0.4", "@tsconfig/svelte": "^5.0.4",
"@types/debug": "^4.1.12", "@types/debug": "^4.1.12",
"@types/eslint": "8.56.0", "@types/eslint": "8.56.0",
"@types/lodash": "^4.17.15", "@types/lodash": "^4.17.15",
"@typescript-eslint/eslint-plugin": "^6.21.0", "@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0", "@typescript-eslint/parser": "^6.21.0",
"commander": "^12.1.0", "commander": "^12.1.0",
"concurrently": "^8.2.2", "concurrently": "^8.2.2",
"eslint": "^8.57.1", "eslint": "^8.57.1",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-svelte": "^2.46.1", "eslint-plugin-svelte": "^2.46.1",
"node-wav": "^0.0.2", "node-wav": "^0.0.2",
"prettier": "^3.5.0", "prettier": "^3.5.0",
"prettier-plugin-svelte": "^3.3.3", "prettier-plugin-svelte": "^3.3.3",
"puppeteer": "^22.15.0", "puppeteer": "^22.15.0",
"svelte-check": "^4.0.0", "svelte-check": "^4.0.0",
"wait-on": "^7.2.0" "wait-on": "^7.2.0"
}, },
"type": "module", "type": "module",
"dependencies": { "dependencies": {
"@fontsource/atkinson-hyperlegible": "^5.1.1", "@fontsource/atkinson-hyperlegible": "^5.1.1",
"@fontsource/b612": "^5.1.1", "@fontsource/b612": "^5.1.1",
"@sveltejs/adapter-auto": "^3.3.1", "@sveltejs/adapter-auto": "^3.3.1",
"@sveltejs/adapter-static": "^3.0.8", "@sveltejs/adapter-static": "^3.0.8",
"@sveltejs/kit": "^2.17.1", "@sveltejs/kit": "^2.17.1",
"@sveltejs/vite-plugin-svelte": "^4.0.0", "@sveltejs/vite-plugin-svelte": "^4.0.0",
"@tabler/icons-webfont": "^2.47.0", "@tabler/icons-webfont": "^2.47.0",
"debug": "^4.4.0", "debug": "^4.4.0",
"i18next": "^23.16.8", "i18next": "^23.16.8",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"normalize.css": "^8.0.1", "normalize.css": "^8.0.1",
"svelte": "^5.0.0", "svelte": "^5.0.0",
"svelte-i18next": "^2.2.2", "svelte-i18next": "^2.2.2",
"tslib": "^2.8.1", "tslib": "^2.8.1",
"typescript": "^5.7.3", "typescript": "^5.7.3",
"vite": "^5.4.14" "vite": "^5.4.14"
}, },
"trustedDependencies": [ "trustedDependencies": [
"esbuild", "esbuild",
"puppeteer", "puppeteer",
"svelte-preprocess" "svelte-preprocess"
] ]
} }

View file

@ -1,75 +1,81 @@
body, html { body,
height: 100%; html {
margin: 0; height: 100%;
display: flex; margin: 0;
justify-content: center; display: flex;
align-items: center; justify-content: center;
align-items: center;
color: white; color: white;
background-color: black; background-color: black;
font-family: 'Atkinson Hyperlegible', 'B612', 'IBM Plex Sans', 'Helvetica Neue', Arial, sans-serif; font-family:
font-size: 20px; 'Atkinson Hyperlegible', 'B612', 'IBM Plex Sans', 'Helvetica Neue', Arial, sans-serif;
font-size: 20px;
} }
* { * {
box-sizing: border-box; box-sizing: border-box;
} }
a { a {
color: white; color: white;
} }
h1,
h1, h2, h3, h4 { h2,
margin-top: 0; h3,
h4 {
margin-top: 0;
} }
button, .button { button,
display: inline-flex; .button {
align-items: center; display: inline-flex;
gap: 0.25em; align-items: center;
text-decoration: none; gap: 0.25em;
border: 1px solid white; text-decoration: none;
cursor: pointer; border: 1px solid white;
cursor: pointer;
padding: 0.25em 0.5em; padding: 0.25em 0.5em;
border-radius: 0.25em; border-radius: 0.25em;
background: black; background: black;
color: white; color: white;
&:disabled { &:disabled {
opacity: 0.7; opacity: 0.7;
} }
} }
input[type="number"], input[type="search"], input[type="text"] { input[type='number'],
background: transparent; input[type='search'],
color: white; input[type='text'] {
border: 1px solid white; background: transparent;
border-radius: 4px; color: white;
padding: 0.2em; border: 1px solid white;
border-radius: 4px;
padding: 0.2em;
&:focus {
outline: solid rgba(255, 255, 255, 0.66);
}
&:focus { &:disabled {
outline: solid rgba(255, 255, 255, 0.66); opacity: 0.7;
} pointer-events: none;
}
&:disabled {
opacity: 0.7;
pointer-events: none;
}
} }
select { select {
background: black; background: black;
color: white; color: white;
padding: 0.25em 0.5em; padding: 0.25em 0.5em;
border-radius: 0.25em; border-radius: 0.25em;
border: 1px solid white; border: 1px solid white;
&:disabled { &:disabled {
opacity: 0.7; opacity: 0.7;
} }
} }

View file

@ -115,9 +115,9 @@
</div> </div>
<div class="grid"> <div class="grid">
{#each [...Array(verticalCount).keys()] as x} {#each [...Array(verticalCount).keys()] as x}
<div class="row" data-idx="{x}"> <div class="row" data-idx={x}>
{#each [...Array(horizontalCount).keys()] as y} {#each [...Array(horizontalCount).keys()] as y}
<div class="block" data-idx="{y}"></div> <div class="block" data-idx={y}></div>
{/each} {/each}
</div> </div>
{/each} {/each}

View file

@ -20,15 +20,15 @@
<style> <style>
.clock { .clock {
display: flex; display: flex;
font-size: 3em; font-size: 3em;
text-align: center; text-align: center;
letter-spacing: -0.05em; letter-spacing: -0.05em;
} }
.separator { .separator {
position: relative; position: relative;
bottom: .15em; bottom: 0.15em;
margin: 0 .05em; margin: 0 0.05em;
} }
</style> </style>

View file

@ -5,7 +5,7 @@
let screenResolution = $state('... x ...'); let screenResolution = $state('... x ...');
let windowResolution = $state(''); let windowResolution = $state('');
let dpr = $state("1"); let dpr = $state('1');
function updateResolution() { function updateResolution() {
const realWidth = Math.round(screen.width) * window.devicePixelRatio; const realWidth = Math.round(screen.width) * window.devicePixelRatio;
@ -35,8 +35,8 @@
<div class="value">{windowResolution}</div> <div class="value">{windowResolution}</div>
</div> </div>
{/if} {/if}
{#if dpr !== "1"} {#if dpr !== '1'}
<div class="dpr">{$i18n.t("Device Pixel Ratio")}: {dpr}</div> <div class="dpr">{$i18n.t('Device Pixel Ratio')}: {dpr}</div>
{/if} {/if}
</div> </div>
</div> </div>
@ -51,7 +51,8 @@
font-weight: bold; font-weight: bold;
} }
.window, .dpr { .window,
.dpr {
margin-top: calc(1em / 0.8); margin-top: calc(1em / 0.8);
font-size: 0.8em; font-size: 0.8em;
} }

View file

@ -1,49 +1,48 @@
{ {
"tests": { "tests": {
"audio": { "audio": {
"label": "Audio", "label": "Audio",
"description": "Check your stereo channels or surround audio output, verify if your speakers are in phase." "description": "Check your stereo channels or surround audio output, verify if your speakers are in phase."
}, },
"av-sync": { "av-sync": {
"label": "Audio/Video Sync", "label": "Audio/Video Sync",
"description": "Check if your audio and video are in sync, and measure the delay." "description": "Check if your audio and video are in sync, and measure the delay."
}, },
"card": { "card": {
"label": "Card", "label": "Card",
"description": "Test card for your display or projector, check colors, resolution and geometry." "description": "Test card for your display or projector, check colors, resolution and geometry."
}, },
"camera": { "camera": {
"label": "Camera", "label": "Camera",
"description": "Check whether your webcam or capture device is working, its image quality, resolution and frame rate. Take a snapshot." "description": "Check whether your webcam or capture device is working, its image quality, resolution and frame rate. Take a snapshot."
}, },
"gamepad": { "gamepad": {
"label": "Gamepad", "label": "Gamepad",
"description": "Test your gamepad, check if it's working, all the buttons and joysticks, stick drift, dead zones and calibration." "description": "Test your gamepad, check if it's working, all the buttons and joysticks, stick drift, dead zones and calibration."
}, },
"keyboard": { "keyboard": {
"label": "Keyboard", "label": "Keyboard",
"description": "Check if all keys are working and what key codes they send." "description": "Check if all keys are working and what key codes they send."
}, },
"microphone": { "microphone": {
"label": "Microphone", "label": "Microphone",
"description": "Check if your microphone is working, its quality, volume and noise." "description": "Check if your microphone is working, its quality, volume and noise."
}, },
"mouse": { "mouse": {
"label": "Mouse", "label": "Mouse",
"description": "Check if your mouse or touch device works properly, if there are dead zones or jitter." "description": "Check if your mouse or touch device works properly, if there are dead zones or jitter."
}, },
"sensors": { "sensors": {
"label": "Sensors", "label": "Sensors",
"description": "See the output of your device's sensors, e.g. GPS, accelerometer, gyroscope, compass, etc." "description": "See the output of your device's sensors, e.g. GPS, accelerometer, gyroscope, compass, etc."
},
}, "internet": {
"internet": { "label": "Internet speed",
"label": "Internet speed", "description": "Measure your internet speed, ping and jitter."
"description": "Measure your internet speed, ping and jitter." },
}, "timer": {
"timer": { "label": "High resolution timer",
"label": "High resolution timer", "description": "Display a millisecond resolution timer on screen, useful for measuring video pipeline latency."
"description": "Display a millisecond resolution timer on screen, useful for measuring video pipeline latency." }
} }
}
} }

View file

@ -4,7 +4,7 @@
import { version } from '../../../package.json'; import { version } from '../../../package.json';
import { i18n } from '$lib/i18n'; import { i18n } from '$lib/i18n';
import type { Snapshot } from '@sveltejs/kit'; import type { Snapshot } from '@sveltejs/kit';
const buildDate = import.meta.env.VITE_BUILD_DATE || "???"; const buildDate = import.meta.env.VITE_BUILD_DATE || '???';
let search = $state(''); let search = $state('');
@ -155,13 +155,15 @@
} }
} }
let nonEmptyCategories = $derived(categories.filter((category) => { let nonEmptyCategories = $derived(
const categoryTests = filteredTests.filter((test) => test.categories.includes(category.id)); categories.filter((category) => {
return categoryTests.some( const categoryTests = filteredTests.filter((test) => test.categories.includes(category.id));
(test) => return categoryTests.some(
!filteredCategories.length || filteredCategories.every((f) => test.categories.includes(f)) (test) =>
); !filteredCategories.length || filteredCategories.every((f) => test.categories.includes(f))
})); );
})
);
export const snapshot: Snapshot<string> = { export const snapshot: Snapshot<string> = {
capture: () => JSON.stringify({ filtered: filteredCategories, search }), capture: () => JSON.stringify({ filtered: filteredCategories, search }),
@ -224,7 +226,12 @@
{/each} {/each}
</div> </div>
</nav> </nav>
<footer><a href="https://git.thm.place/thm/test-card">testcard v{version} {#if version.startsWith("0")}({buildDate}){/if}</a></footer> <footer>
<a href="https://git.thm.place/thm/test-card"
>testcard v{version}
{#if version.startsWith('0')}({buildDate}){/if}</a
>
</footer>
<style> <style>
nav { nav {

View file

@ -3,5 +3,5 @@ import type { PageLoad } from './$types';
export const load: PageLoad = () => { export const load: PageLoad = () => {
return { return {
root: true root: true
} };
} };