chore(web): format files

This commit is contained in:
Kristofers Solo 2025-11-26 17:27:18 +02:00
parent f1a0ab75c3
commit a93ff3f920
Signed by: kristoferssolo
GPG Key ID: 8687F2D3EEE6F0ED
8 changed files with 404 additions and 463 deletions

View File

@ -48,7 +48,7 @@ panic = "abort"
[package.metadata.leptos] [package.metadata.leptos]
# The name used by wasm-bindgen/cargo-leptos for the JS/WASM bundle. Defaults to the crate name # The name used by wasm-bindgen/cargo-leptos for the JS/WASM bundle. Defaults to the crate name
output-name = "web2" output-name = "web"
# The site root folder is where cargo-leptos generate all output. WARNING: all content of this folder will be erased on a rebuild. Use it in your server setup. # The site root folder is where cargo-leptos generate all output. WARNING: all content of this folder will be erased on a rebuild. Use it in your server setup.
site-root = "target/site" site-root = "target/site"

View File

@ -1,91 +0,0 @@
<picture>
<source srcset="https://raw.githubusercontent.com/leptos-rs/leptos/main/docs/logos/Leptos_logo_Solid_White.svg" media="(prefers-color-scheme: dark)">
<img src="https://raw.githubusercontent.com/leptos-rs/leptos/main/docs/logos/Leptos_logo_RGB.svg" alt="Leptos Logo">
</picture>
# Leptos Axum Starter Template
This is a template for use with the [Leptos](https://github.com/leptos-rs/leptos) web framework and the [cargo-leptos](https://github.com/akesson/cargo-leptos) tool using [Axum](https://github.com/tokio-rs/axum).
## Creating your template repo
If you don't have `cargo-leptos` installed you can install it with
```bash
cargo install cargo-leptos --locked
```
Then run
```bash
cargo leptos new --git https://github.com/leptos-rs/start-axum
```
to generate a new project template.
```bash
cd web2
```
to go to your newly created project.
Feel free to explore the project structure, but the best place to start with your application code is in `src/app.rs`.
Additionally, Cargo.toml may need updating as new versions of the dependencies are released, especially if things are not working after a `cargo update`.
## Running your project
```bash
cargo leptos watch
```
## Installing Additional Tools
By default, `cargo-leptos` uses `nightly` Rust, `cargo-generate`, and `sass`. If you run into any trouble, you may need to install one or more of these tools.
1. `rustup toolchain install nightly --allow-downgrade` - make sure you have Rust nightly
2. `rustup target add wasm32-unknown-unknown` - add the ability to compile Rust to WebAssembly
3. `cargo install cargo-generate` - install `cargo-generate` binary (should be installed automatically in future)
4. `npm install -g sass` - install `dart-sass` (should be optional in future
5. Run `npm install` in end2end subdirectory before test
## Compiling for Release
```bash
cargo leptos build --release
```
Will generate your server binary in target/release and your site package in target/site
## Testing Your Project
```bash
cargo leptos end-to-end
```
```bash
cargo leptos end-to-end --release
```
Cargo-leptos uses Playwright as the end-to-end test tool.
Tests are located in end2end/tests directory.
## Executing a Server on a Remote Machine Without the Toolchain
After running a `cargo leptos build --release` the minimum files needed are:
1. The server binary located in `target/server/release`
2. The `site` directory and all files within located in `target/site`
Copy these files to your remote server. The directory structure should be:
```text
web2
site/
```
Set the following environment variables (updating for your project as needed):
```sh
export LEPTOS_OUTPUT_NAME="web2"
export LEPTOS_SITE_ROOT="site"
export LEPTOS_SITE_PKG_DIR="pkg"
export LEPTOS_SITE_ADDR="127.0.0.1:3000"
export LEPTOS_RELOAD_PORT="3001"
```
Finally, run the server binary.
## Licensing
This template itself is released under the Unlicense. You should replace the LICENSE for your own application with an appropriate license if you plan to release it publicly.

View File

@ -1,167 +1,167 @@
{ {
"name": "end2end", "name": "end2end",
"version": "1.0.0", "version": "1.0.0",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "end2end", "name": "end2end",
"version": "1.0.0", "version": "1.0.0",
"license": "ISC", "license": "ISC",
"devDependencies": { "devDependencies": {
"@playwright/test": "^1.44.1", "@playwright/test": "^1.44.1",
"@types/node": "^20.12.12", "@types/node": "^20.12.12",
"typescript": "^5.4.5" "typescript": "^5.4.5"
} }
},
"node_modules/@playwright/test": {
"version": "1.44.1",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.44.1.tgz",
"integrity": "sha512-1hZ4TNvD5z9VuhNJ/walIjvMVvYkZKf71axoF/uiAqpntQJXpG64dlXhoDXE3OczPuTuvjf/M5KWFg5VAVUS3Q==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"playwright": "1.44.1"
},
"bin": {
"playwright": "cli.js"
},
"engines": {
"node": ">=16"
}
},
"node_modules/@types/node": {
"version": "20.12.12",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz",
"integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==",
"dev": true,
"license": "MIT",
"dependencies": {
"undici-types": "~5.26.4"
}
},
"node_modules/fsevents": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/playwright": {
"version": "1.44.1",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.44.1.tgz",
"integrity": "sha512-qr/0UJ5CFAtloI3avF95Y0L1xQo6r3LQArLIg/z/PoGJ6xa+EwzrwO5lpNr/09STxdHuUoP2mvuELJS+hLdtgg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"playwright-core": "1.44.1"
},
"bin": {
"playwright": "cli.js"
},
"engines": {
"node": ">=16"
},
"optionalDependencies": {
"fsevents": "2.3.2"
}
},
"node_modules/playwright-core": {
"version": "1.44.1",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.44.1.tgz",
"integrity": "sha512-wh0JWtYTrhv1+OSsLPgFzGzt67Y7BE/ZS3jEqgGBlp2ppp1ZDj8c+9IARNW4dwf1poq5MgHreEM2KV/GuR4cFA==",
"dev": true,
"license": "Apache-2.0",
"bin": {
"playwright-core": "cli.js"
},
"engines": {
"node": ">=16"
}
},
"node_modules/typescript": {
"version": "5.4.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
"integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
"dev": true,
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
},
"node_modules/undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
"dev": true,
"license": "MIT"
}
}, },
"node_modules/@playwright/test": { "dependencies": {
"version": "1.44.1", "@playwright/test": {
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.44.1.tgz", "version": "1.44.1",
"integrity": "sha512-1hZ4TNvD5z9VuhNJ/walIjvMVvYkZKf71axoF/uiAqpntQJXpG64dlXhoDXE3OczPuTuvjf/M5KWFg5VAVUS3Q==", "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.44.1.tgz",
"dev": true, "integrity": "sha512-1hZ4TNvD5z9VuhNJ/walIjvMVvYkZKf71axoF/uiAqpntQJXpG64dlXhoDXE3OczPuTuvjf/M5KWFg5VAVUS3Q==",
"license": "Apache-2.0", "dev": true,
"dependencies": { "requires": {
"playwright": "1.44.1" "playwright": "1.44.1"
}, }
"bin": { },
"playwright": "cli.js" "@types/node": {
}, "version": "20.12.12",
"engines": { "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz",
"node": ">=16" "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==",
} "dev": true,
}, "requires": {
"node_modules/@types/node": { "undici-types": "~5.26.4"
"version": "20.12.12", }
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", },
"integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", "fsevents": {
"dev": true, "version": "2.3.2",
"license": "MIT", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"dependencies": { "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
"undici-types": "~5.26.4" "dev": true,
} "optional": true
}, },
"node_modules/fsevents": { "playwright": {
"version": "2.3.2", "version": "1.44.1",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.44.1.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "integrity": "sha512-qr/0UJ5CFAtloI3avF95Y0L1xQo6r3LQArLIg/z/PoGJ6xa+EwzrwO5lpNr/09STxdHuUoP2mvuELJS+hLdtgg==",
"dev": true, "dev": true,
"hasInstallScript": true, "requires": {
"license": "MIT", "fsevents": "2.3.2",
"optional": true, "playwright-core": "1.44.1"
"os": [ }
"darwin" },
], "playwright-core": {
"engines": { "version": "1.44.1",
"node": "^8.16.0 || ^10.6.0 || >=11.0.0" "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.44.1.tgz",
} "integrity": "sha512-wh0JWtYTrhv1+OSsLPgFzGzt67Y7BE/ZS3jEqgGBlp2ppp1ZDj8c+9IARNW4dwf1poq5MgHreEM2KV/GuR4cFA==",
}, "dev": true
"node_modules/playwright": { },
"version": "1.44.1", "typescript": {
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.44.1.tgz", "version": "5.4.5",
"integrity": "sha512-qr/0UJ5CFAtloI3avF95Y0L1xQo6r3LQArLIg/z/PoGJ6xa+EwzrwO5lpNr/09STxdHuUoP2mvuELJS+hLdtgg==", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
"dev": true, "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
"license": "Apache-2.0", "dev": true
"dependencies": { },
"playwright-core": "1.44.1" "undici-types": {
}, "version": "5.26.5",
"bin": { "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
"playwright": "cli.js" "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
}, "dev": true
"engines": { }
"node": ">=16"
},
"optionalDependencies": {
"fsevents": "2.3.2"
}
},
"node_modules/playwright-core": {
"version": "1.44.1",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.44.1.tgz",
"integrity": "sha512-wh0JWtYTrhv1+OSsLPgFzGzt67Y7BE/ZS3jEqgGBlp2ppp1ZDj8c+9IARNW4dwf1poq5MgHreEM2KV/GuR4cFA==",
"dev": true,
"license": "Apache-2.0",
"bin": {
"playwright-core": "cli.js"
},
"engines": {
"node": ">=16"
}
},
"node_modules/typescript": {
"version": "5.4.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
"integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
"dev": true,
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
},
"node_modules/undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
"dev": true,
"license": "MIT"
} }
},
"dependencies": {
"@playwright/test": {
"version": "1.44.1",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.44.1.tgz",
"integrity": "sha512-1hZ4TNvD5z9VuhNJ/walIjvMVvYkZKf71axoF/uiAqpntQJXpG64dlXhoDXE3OczPuTuvjf/M5KWFg5VAVUS3Q==",
"dev": true,
"requires": {
"playwright": "1.44.1"
}
},
"@types/node": {
"version": "20.12.12",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz",
"integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==",
"dev": true,
"requires": {
"undici-types": "~5.26.4"
}
},
"fsevents": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
"dev": true,
"optional": true
},
"playwright": {
"version": "1.44.1",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.44.1.tgz",
"integrity": "sha512-qr/0UJ5CFAtloI3avF95Y0L1xQo6r3LQArLIg/z/PoGJ6xa+EwzrwO5lpNr/09STxdHuUoP2mvuELJS+hLdtgg==",
"dev": true,
"requires": {
"fsevents": "2.3.2",
"playwright-core": "1.44.1"
}
},
"playwright-core": {
"version": "1.44.1",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.44.1.tgz",
"integrity": "sha512-wh0JWtYTrhv1+OSsLPgFzGzt67Y7BE/ZS3jEqgGBlp2ppp1ZDj8c+9IARNW4dwf1poq5MgHreEM2KV/GuR4cFA==",
"dev": true
},
"typescript": {
"version": "5.4.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
"integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
"dev": true
},
"undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
"dev": true
}
}
} }

View File

@ -1,15 +1,15 @@
{ {
"name": "end2end", "name": "end2end",
"version": "1.0.0", "version": "1.0.0",
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"scripts": {}, "scripts": {},
"keywords": [], "keywords": [],
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"devDependencies": { "devDependencies": {
"@playwright/test": "^1.44.1", "@playwright/test": "^1.44.1",
"@types/node": "^20.12.12", "@types/node": "^20.12.12",
"typescript": "^5.4.5" "typescript": "^5.4.5"
} }
} }

View File

@ -1,5 +1,5 @@
import type { PlaywrightTestConfig } from "@playwright/test"; import type { PlaywrightTestConfig } from "@playwright/test";
import { devices, defineConfig } from "@playwright/test"; import { defineConfig, devices } from "@playwright/test";
/** /**
* Read environment variables from file. * Read environment variables from file.
@ -11,95 +11,95 @@ import { devices, defineConfig } from "@playwright/test";
* See https://playwright.dev/docs/test-configuration. * See https://playwright.dev/docs/test-configuration.
*/ */
export default defineConfig({ export default defineConfig({
testDir: "./tests", testDir: "./tests",
/* Maximum time one test can run for. */ /* Maximum time one test can run for. */
timeout: 30 * 1000, timeout: 30 * 1000,
expect: { expect: {
/** /**
* Maximum time expect() should wait for the condition to be met. * Maximum time expect() should wait for the condition to be met.
* For example in `await expect(locator).toHaveText();` * For example in `await expect(locator).toHaveText();`
*/ */
timeout: 5000, timeout: 5000,
}, },
/* Run tests in files in parallel */ /* Run tests in files in parallel */
fullyParallel: true, fullyParallel: true,
/* Fail the build on CI if you accidentally left test.only in the source code. */ /* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI, forbidOnly: !!process.env.CI,
/* Retry on CI only */ /* Retry on CI only */
retries: process.env.CI ? 2 : 0, retries: process.env.CI ? 2 : 0,
/* Opt out of parallel tests on CI. */ /* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined, workers: process.env.CI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */ /* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: "html", reporter: "html",
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: { use: {
/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */ /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
actionTimeout: 0, actionTimeout: 0,
/* Base URL to use in actions like `await page.goto('/')`. */ /* Base URL to use in actions like `await page.goto('/')`. */
// baseURL: 'http://localhost:3000', // baseURL: 'http://localhost:3000',
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: "on-first-retry", trace: "on-first-retry",
}, },
/* Configure projects for major browsers */ /* Configure projects for major browsers */
projects: [ projects: [
{ {
name: "chromium", name: "chromium",
use: { use: {
...devices["Desktop Chrome"], ...devices["Desktop Chrome"],
}, },
}, },
{ {
name: "firefox", name: "firefox",
use: { use: {
...devices["Desktop Firefox"], ...devices["Desktop Firefox"],
}, },
}, },
{ {
name: "webkit", name: "webkit",
use: { use: {
...devices["Desktop Safari"], ...devices["Desktop Safari"],
}, },
}, },
/* Test against mobile viewports. */ /* Test against mobile viewports. */
// { // {
// name: 'Mobile Chrome', // name: 'Mobile Chrome',
// use: { // use: {
// ...devices['Pixel 5'], // ...devices['Pixel 5'],
// }, // },
// }, // },
// { // {
// name: 'Mobile Safari', // name: 'Mobile Safari',
// use: { // use: {
// ...devices['iPhone 12'], // ...devices['iPhone 12'],
// }, // },
// }, // },
/* Test against branded browsers. */ /* Test against branded browsers. */
// { // {
// name: 'Microsoft Edge', // name: 'Microsoft Edge',
// use: { // use: {
// channel: 'msedge', // channel: 'msedge',
// }, // },
// }, // },
// { // {
// name: 'Google Chrome', // name: 'Google Chrome',
// use: { // use: {
// channel: 'chrome', // channel: 'chrome',
// }, // },
// }, // },
], ],
/* Folder for test artifacts such as screenshots, videos, traces, etc. */ /* Folder for test artifacts such as screenshots, videos, traces, etc. */
// outputDir: 'test-results/', // outputDir: 'test-results/',
/* Run your local dev server before starting the tests */ /* Run your local dev server before starting the tests */
// webServer: { // webServer: {
// command: 'npm run start', // command: 'npm run start',
// port: 3000, // port: 3000,
// }, // },
}); });

View File

@ -1,9 +1,9 @@
import { test, expect } from "@playwright/test"; import { expect, test } from "@playwright/test";
test("homepage has title and heading text", async ({ page }) => { test("homepage has title and heading text", async ({ page }) => {
await page.goto("http://localhost:3000/"); await page.goto("http://localhost:3000/");
await expect(page).toHaveTitle("Welcome to Leptos"); await expect(page).toHaveTitle("Welcome to Leptos");
await expect(page.locator("h1")).toHaveText("Welcome to Leptos!"); await expect(page.locator("h1")).toHaveText("Welcome to Leptos!");
}); });

View File

@ -1,109 +1,101 @@
{ {
"compilerOptions": { "compilerOptions": {
/* Visit https://aka.ms/tsconfig to read more about this file */ /* Visit https://aka.ms/tsconfig to read more about this file */
/* Projects */
/* Projects */ // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ /* Language and Environment */
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
/* Language and Environment */ // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ // "jsx": "preserve", /* Specify what JSX code is generated. */
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
// "jsx": "preserve", /* Specify what JSX code is generated. */ // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ /* Modules */
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ "module": "commonjs", /* Specify what module code is generated. */
// "rootDir": "./", /* Specify the root folder within your source files. */
/* Modules */ // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
"module": "commonjs", /* Specify what module code is generated. */ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "rootDir": "./", /* Specify the root folder within your source files. */ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ // "types": [], /* Specify type package names to be included without being referenced in a source file. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
// "types": [], /* Specify type package names to be included without being referenced in a source file. */ // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ // "resolveJsonModule": true, /* Enable importing .json files. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ // "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
// "resolveJsonModule": true, /* Enable importing .json files. */ /* JavaScript Support */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */ // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
/* JavaScript Support */ /* Emit */
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ // "declarationMap": true, /* Create sourcemaps for d.ts files. */
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
/* Emit */ // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
// "declarationMap": true, /* Create sourcemaps for d.ts files. */ // "outDir": "./", /* Specify an output folder for all emitted files. */
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ // "removeComments": true, /* Disable emitting comments. */
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */ // "noEmit": true, /* Disable emitting files from a compilation. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
// "outDir": "./", /* Specify an output folder for all emitted files. */ // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
// "removeComments": true, /* Disable emitting comments. */ // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
// "noEmit": true, /* Disable emitting files from a compilation. */ // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ // "newLine": "crlf", /* Set the newline character for emitting files. */
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
// "newLine": "crlf", /* Set the newline character for emitting files. */ // "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ /* Interop Constraints */
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */ // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
/* Interop Constraints */ "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ /* Type Checking */
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ "strict": true, /* Enable all strict type-checking options. */
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
/* Type Checking */ // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
"strict": true, /* Enable all strict type-checking options. */ // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ /* Completeness */
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ "skipLibCheck": true /* Skip type checking all .d.ts files. */
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ }
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
/* Completeness */
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
}
} }

View File

@ -127,6 +127,46 @@ body {
} }
} }
.app-footer {
margin-top: auto;
padding: 2rem 0;
border-top: 1px solid var(--border);
background-color: var(--bg-card);
text-align: center;
font-size: 0.9rem;
color: var(--text-muted);
}
.footer-content {
max-width: 800px;
margin: 0 auto;
padding: 0 1rem;
p {
margin: 0 0 1rem 0;
line-height: 1.5;
strong {
color: var(--primary);
}
}
}
.footer-links {
a {
color: var(--secondary);
text-decoration: none;
font-weight: 600;
border-bottom: 1px dotted var(--secondary);
transition: all 0.2s;
&:hover {
color: var(--primary);
border-bottom-style: solid;
}
}
}
main { main {
padding: 2rem; padding: 2rem;
} }