├── static ├── .nojekyll └── favicon.png ├── .npmrc ├── src ├── routes │ ├── +page.svelte │ ├── +layout.ts │ ├── +error.svelte │ ├── +page.ts │ ├── products │ │ ├── +page.ts │ │ └── +page.svelte │ ├── +layout.svelte │ ├── summary │ │ └── [id] │ │ │ └── +page.svelte │ └── order │ │ └── +page.svelte ├── app.html ├── app.d.ts └── lib │ ├── store │ └── globalStates.svelte.ts │ ├── components │ ├── Header.svelte │ ├── CategoryList.svelte │ └── ProductItem.svelte │ ├── api │ └── services.ts │ ├── data │ └── mockData.json │ └── type │ └── entities.ts ├── .devcontainer ├── setup.sh └── devcontainer.json ├── db ├── data.sqlite3 ├── data.sqlite3_backup └── scheme.sql ├── main.go ├── vite.config.ts ├── .vscode └── extensions.json ├── .dockerignore ├── .gitignore ├── svelte.config.js ├── backend ├── entities.go ├── server.go └── service.go ├── tsconfig.json ├── Dockerfile ├── .github ├── workflows │ └── dependabot-test.yml └── dependabot.yml ├── LICENSE ├── go.mod ├── package.json ├── go.sum ├── README.md └── yarn.lock /static/.nojekyll: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true 2 | -------------------------------------------------------------------------------- /src/routes/+page.svelte: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/routes/+layout.ts: -------------------------------------------------------------------------------- 1 | export const prerender = false; 2 | -------------------------------------------------------------------------------- /.devcontainer/setup.sh: -------------------------------------------------------------------------------- 1 | npm i -g yarn@latest 2 | yarn setup-full -------------------------------------------------------------------------------- /db/data.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alankrantas/svelteapp-typescript-go/HEAD/db/data.sqlite3 -------------------------------------------------------------------------------- /static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alankrantas/svelteapp-typescript-go/HEAD/static/favicon.png -------------------------------------------------------------------------------- /db/data.sqlite3_backup: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alankrantas/svelteapp-typescript-go/HEAD/db/data.sqlite3_backup -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "main/backend" 4 | 5 | func main() { 6 | backend.Server() // start Golang backend server/service 7 | } 8 | -------------------------------------------------------------------------------- /src/routes/+error.svelte: -------------------------------------------------------------------------------- 1 | 4 | 5 |

{$page.status}: {$page.error?.message}

6 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { sveltekit } from '@sveltejs/kit/vite'; 2 | import { defineConfig } from 'vite'; 3 | 4 | export default defineConfig({ 5 | plugins: [sveltekit()] 6 | }); 7 | -------------------------------------------------------------------------------- /src/routes/+page.ts: -------------------------------------------------------------------------------- 1 | import { redirect } from '@sveltejs/kit'; 2 | import type { PageLoad } from './$types'; 3 | 4 | export const load: PageLoad = async () => redirect(301, '/products'); 5 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "ms-vscode.vscode-typescript-next", 4 | "svelte.svelte-vscode", 5 | "golang.go", 6 | "github.vscode-github-actions" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /.devcontainer 4 | /.github 5 | /.vscode 6 | /.svelte-kit 7 | /build 8 | /package 9 | .env 10 | .env.* 11 | !.env.example 12 | README.md 13 | LICENSE 14 | main 15 | main.exe 16 | -------------------------------------------------------------------------------- /src/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | %sveltekit.head% 8 | 9 | 10 |
%sveltekit.body%
11 | 12 | 13 | -------------------------------------------------------------------------------- /src/routes/products/+page.ts: -------------------------------------------------------------------------------- 1 | import type { PageLoad } from './$types'; 2 | import { loadProducts } from '$lib/api/services'; 3 | 4 | export const load: PageLoad = async () => { 5 | // load product data from backend service before mounting Product component 6 | return { 7 | products: await loadProducts() 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | main 3 | main.exe 4 | 5 | # Output 6 | .output 7 | .vercel 8 | .netlify 9 | .wrangler 10 | /.svelte-kit 11 | /build 12 | 13 | # OS 14 | .DS_Store 15 | Thumbs.db 16 | 17 | # Env 18 | .env 19 | .env.* 20 | !.env.example 21 | !.env.test 22 | 23 | # Vite 24 | vite.config.js.timestamp-* 25 | vite.config.ts.timestamp-* 26 | -------------------------------------------------------------------------------- /src/app.d.ts: -------------------------------------------------------------------------------- 1 | // See https://svelte.dev/docs/kit/types#app.d.ts 2 | // for information about these interfaces 3 | declare global { 4 | namespace App { 5 | // interface Error {} 6 | // interface Locals {} 7 | // interface PageData {} 8 | // interface PageState {} 9 | // interface Platform {} 10 | } 11 | } 12 | 13 | export { }; 14 | -------------------------------------------------------------------------------- /src/lib/store/globalStates.svelte.ts: -------------------------------------------------------------------------------- 1 | import type { OrderLine } from '$lib/type/entities'; 2 | 3 | const getStore = (value: T) => { 4 | let _store: T = $state(value); 5 | 6 | return { 7 | get current(): T { 8 | return _store; 9 | }, 10 | set current(value: T) { 11 | _store = value; 12 | } 13 | }; 14 | }; 15 | 16 | export const orderLines = getStore([]); 17 | -------------------------------------------------------------------------------- /svelte.config.js: -------------------------------------------------------------------------------- 1 | import adapter from '@sveltejs/adapter-static'; 2 | import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; 3 | 4 | /** @type {import('@sveltejs/kit').Config} */ 5 | const config = { 6 | // Consult https://kit.svelte.dev/docs/integrations#preprocessors 7 | // for more information about preprocessors 8 | preprocess: vitePreprocess(), 9 | 10 | kit: { 11 | adapter: adapter({ 12 | pages: 'build', 13 | assets: 'build', 14 | fallback: 'index.html', 15 | precompress: true, 16 | strict: true 17 | }) 18 | } 19 | }; 20 | 21 | export default config; 22 | -------------------------------------------------------------------------------- /backend/entities.go: -------------------------------------------------------------------------------- 1 | package backend 2 | 3 | // Product data 4 | type Product struct { 5 | Id int `json:"id"` 6 | Name string `json:"name"` 7 | Category string `json:"category"` 8 | Description string `json:"description"` 9 | Price float32 `json:"price"` 10 | } 11 | 12 | // Order data 13 | type Order struct { 14 | Lines []Line `json:"lines"` 15 | } 16 | 17 | // Line data in an order 18 | type Line struct { 19 | ProductId int `json:"productId"` 20 | ProductName string `json:"productName"` 21 | Quantity int `json:"quantity"` 22 | } 23 | 24 | // Result data 25 | type Result struct { 26 | Id int `json:"id"` 27 | } 28 | -------------------------------------------------------------------------------- /src/routes/+layout.svelte: -------------------------------------------------------------------------------- 1 | 11 | 12 | 13 | Sports Store Demo App 14 | 15 | 16 | 17 | {@render children?.()} 18 | 19 | {#snippet failed(error: any, reset)} 20 |

Svelte app rendering error

21 |

{error?.message}

22 | {/snippet} 23 |
24 | 25 | 30 | -------------------------------------------------------------------------------- /src/routes/summary/[id]/+page.svelte: -------------------------------------------------------------------------------- 1 | 12 | 13 | {#if ready} 14 |
18 |

Thanks!

19 |

Thanks for placing your order.

20 |

Your order is #{$page.params.id}

21 |

We'll ship your goods as soon as possible.

22 | OK 23 |
24 | {/if} 25 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.svelte-kit/tsconfig.json", 3 | "compilerOptions": { 4 | "allowJs": true, 5 | "checkJs": true, 6 | "esModuleInterop": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "resolveJsonModule": true, 9 | "skipLibCheck": true, 10 | "sourceMap": true, 11 | "strict": true, 12 | "moduleResolution": "bundler" 13 | } 14 | // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias 15 | // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files 16 | // 17 | // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes 18 | // from the referenced tsconfig.json - TypeScript does not merge them in 19 | } -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # svelte-builder 3 | # 4 | 5 | FROM node:alpine as app-builder 6 | 7 | WORKDIR /app 8 | COPY . /app 9 | 10 | RUN yarn install --frozen-lockfile 11 | RUN yarn check 12 | RUN yarn vite build 13 | 14 | # 15 | # server-builder (CGO is required) 16 | # 17 | 18 | FROM golang:alpine as server-builder 19 | 20 | ENV CGO_ENABLED=1 21 | RUN apk add build-base 22 | 23 | WORKDIR /app 24 | 25 | COPY backend /app/backend 26 | COPY go.* /app 27 | COPY *.go /app 28 | 29 | RUN go build -buildvcs=false -mod=readonly -v 30 | 31 | # 32 | # deploy 33 | # 34 | 35 | FROM alpine as deployment 36 | 37 | WORKDIR /app 38 | 39 | COPY db /app/db 40 | COPY --from=app-builder /app/build /app/build 41 | COPY --from=server-builder /app/main /app 42 | 43 | EXPOSE 8080 44 | 45 | CMD ./main -docker 46 | -------------------------------------------------------------------------------- /src/lib/components/Header.svelte: -------------------------------------------------------------------------------- 1 | 16 | 17 |
18 | 19 | {displayText} 20 | 21 | 22 | Submit Order 23 |
24 | -------------------------------------------------------------------------------- /src/lib/components/CategoryList.svelte: -------------------------------------------------------------------------------- 1 | 16 | 17 |
18 | {#each categories as category} 19 | 28 | {/each} 29 |
30 | -------------------------------------------------------------------------------- /.github/workflows/dependabot-test.yml: -------------------------------------------------------------------------------- 1 | name: Dependabot Test Build 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - main 7 | workflow_dispatch: 8 | 9 | permissions: 10 | pull-requests: write 11 | issues: write 12 | contents: read 13 | id-token: write 14 | 15 | jobs: 16 | test-build: 17 | if: github.actor == 'dependabot[bot]' 18 | runs-on: ubuntu-latest 19 | 20 | steps: 21 | - name: Checkout Repo 22 | uses: actions/checkout@v5 23 | 24 | - name: Setup Nodejs 25 | uses: actions/setup-node@v5 26 | with: 27 | node-version: 22 28 | 29 | - name: Setup Go 30 | uses: actions/setup-go@v6 31 | with: 32 | go-version: '1.x' 33 | 34 | - name: Install Dependencies 35 | run: | 36 | npm i -g yarn 37 | yarn setup-full 38 | 39 | - name: Build Production 40 | run: yarn build-full 41 | env: 42 | CGO_ENABLED: 1 43 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: 'npm' 4 | directory: '/' 5 | schedule: 6 | interval: 'weekly' 7 | time: '09:00' 8 | day: 'monday' 9 | timezone: 'Asia/Taipei' 10 | open-pull-requests-limit: 10 11 | versioning-strategy: increase 12 | 13 | - package-ecosystem: 'gomod' 14 | directory: '/' 15 | schedule: 16 | interval: 'weekly' 17 | time: '09:00' 18 | day: 'monday' 19 | timezone: 'Asia/Taipei' 20 | open-pull-requests-limit: 10 21 | 22 | - package-ecosystem: 'docker' 23 | directory: '/' 24 | schedule: 25 | interval: 'weekly' 26 | time: '09:00' 27 | day: 'monday' 28 | timezone: 'Asia/Taipei' 29 | open-pull-requests-limit: 10 30 | 31 | - package-ecosystem: 'github-actions' 32 | directory: '/' 33 | schedule: 34 | interval: 'weekly' 35 | time: '09:00' 36 | day: 'monday' 37 | timezone: 'Asia/Taipei' 38 | open-pull-requests-limit: 10 39 | -------------------------------------------------------------------------------- /src/lib/components/ProductItem.svelte: -------------------------------------------------------------------------------- 1 | 12 | 13 |
14 |

15 | {product.name} 16 | 17 | ${product.price.toFixed(2)} 18 | 19 |

20 |
21 | {product.description} 22 | 31 | 36 |
37 |
38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Alan Wang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /db/scheme.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE "products" ( 2 | "id" INTEGER NOT NULL UNIQUE, -- product ID 3 | "name" TEXT NOT NULL, 4 | "category" TEXT NOT NULL, 5 | "description" TEXT, 6 | "price" REAL NOT NULL, 7 | PRIMARY KEY("id" AUTOINCREMENT) 8 | ); 9 | 10 | CREATE TABLE "orders" ( 11 | "id" INTEGER NOT NULL, -- order ID 12 | "product_id" INTEGER NOT NULL, -- product ID 13 | "quantity" INTEGER NOT NULL 14 | ); 15 | 16 | INSERT INTO "main"."products" ( 17 | "id", 18 | "name", 19 | "category", 20 | "description", 21 | "price" 22 | ) 23 | VALUES 24 | ('1', 'Kayak', 'Watersports', 'A boat for one person', '275.0'), 25 | ('2', 'Lifejacket', 'Watersports', 'Protective and fashionable', '48.95'), 26 | ('3', 'Soccer Ball', 'Soccer', 'FIFA-approved size and weight', '19.5'), 27 | ('4', 'Corner Flags', 'Soccer', 'Give your playing field a professional touch', '34.95'), 28 | ('5', 'Stadium', 'Soccer', 'Flat-packed 35,000-seat stadium', '79500.0'), 29 | ('6', 'Thinking Cap', 'Chess', 'Improve brain efficiency by 75%', '16.0'), 30 | ('7', 'Unsteady Chair', 'Chess', 'Secretly give your opponent a disadvantage', '29.95'), 31 | ('8', 'Human Chess Board', 'Chess', 'A fun game for the family', '75.0'), 32 | ('9', 'Bling Bling King', 'Chess', 'Gold-plated, diamond-studded King', '1200.0'); -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the 2 | // README at: https://github.com/devcontainers/templates/tree/main/src/ubuntu 3 | { 4 | "name": "Ubuntu", 5 | // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile 6 | "image": "mcr.microsoft.com/devcontainers/base:ubuntu", 7 | // Features to add to the dev container. More info: https://containers.dev/features. 8 | "features": { 9 | "ghcr.io/devcontainers/features/go:1": { 10 | "version": "latest" 11 | }, 12 | "ghcr.io/devcontainers/features/node:1": { 13 | "nodeGypDependencies": true, 14 | "version": "lts" 15 | } 16 | }, 17 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 18 | // "forwardPorts": [], 19 | // Use 'postCreateCommand' to run commands after the container is created. 20 | "updateContentCommand": "bash .devcontainer/setup.sh", 21 | // Configure tool-specific properties. 22 | "customizations": { 23 | "vscode": { 24 | "extensions": [ 25 | "ms-vscode.vscode-typescript-next", 26 | "svelte.svelte-vscode", 27 | "golang.go", 28 | "github.vscode-github-actions" 29 | ] 30 | } 31 | }, 32 | // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. 33 | "remoteUser": "root" 34 | } 35 | -------------------------------------------------------------------------------- /src/lib/api/services.ts: -------------------------------------------------------------------------------- 1 | import type { Product, OrderData, Order, Result } from '../type/entities'; 2 | 3 | import { dev } from '$app/environment'; 4 | import mockProducts from '$lib/data/mockData.json'; 5 | 6 | const api = { 7 | loadProductsPath: '/api/products', 8 | storeOrderPath: '/api/orders' 9 | }; 10 | 11 | export const loadProducts = async (): Promise => { 12 | if (dev) return mockProducts; 13 | 14 | try { 15 | return await (await fetch(api.loadProductsPath)).json(); 16 | } catch { 17 | return []; 18 | } 19 | }; 20 | 21 | export const storeOrder = async (order: Order): Promise => { 22 | if (dev) return { id: 42 }; 23 | 24 | const orderData: OrderData = { 25 | lines: [...order.orderLines.currents()].map((ol) => ({ 26 | productId: ol.product.id, 27 | productName: ol.product.name, 28 | quantity: ol.quantity 29 | })) 30 | }; 31 | 32 | try { 33 | const result: Result = await ( 34 | await fetch(api.storeOrderPath, { 35 | method: 'POST', 36 | headers: { 37 | 'content-type': 'application/json; charset=UTF-8' 38 | }, 39 | body: JSON.stringify(orderData) 40 | }) 41 | ).json(); 42 | return result; 43 | } catch { 44 | return { id: -1 }; 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /src/lib/data/mockData.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 1, 4 | "name": "Mock product 1", 5 | "category": "Category 1", 6 | "description": "Product description 1", 7 | "price": 10 8 | }, 9 | { 10 | "id": 2, 11 | "name": "Mock product 2", 12 | "category": "Category 1", 13 | "description": "Product description 2", 14 | "price": 20 15 | }, 16 | { 17 | "id": 3, 18 | "name": "Mock product 3", 19 | "category": "Category 1", 20 | "description": "Product description 3", 21 | "price": 30 22 | }, 23 | { 24 | "id": 4, 25 | "name": "Mock product 4", 26 | "category": "Category 2", 27 | "description": "Product description 4", 28 | "price": 40 29 | }, 30 | { 31 | "id": 5, 32 | "name": "Mock product 5", 33 | "category": "Category 2", 34 | "description": "Product description 5", 35 | "price": 50 36 | }, 37 | { 38 | "id": 6, 39 | "name": "Mock product 6", 40 | "category": "Category 3", 41 | "description": "Product description 6", 42 | "price": 60 43 | }, 44 | { 45 | "id": 7, 46 | "name": "Mock product 7", 47 | "category": "Category 3", 48 | "description": "Product description 7", 49 | "price": 70 50 | }, 51 | { 52 | "id": 8, 53 | "name": "Mock product 8", 54 | "category": "Category 3", 55 | "description": "Product description 8", 56 | "price": 80 57 | }, 58 | { 59 | "id": 9, 60 | "name": "Mock product 9", 61 | "category": "Category 3", 62 | "description": "Product description 9", 63 | "price": 90 64 | } 65 | ] 66 | -------------------------------------------------------------------------------- /src/lib/type/entities.ts: -------------------------------------------------------------------------------- 1 | export interface Product { 2 | id: number; 3 | name: string; 4 | description: string; 5 | category: string; 6 | price: number; 7 | } 8 | 9 | export interface OrderData { 10 | lines: { 11 | productId: number; 12 | productName: string; 13 | quantity: number; 14 | }[]; 15 | } 16 | 17 | export class OrderLine { 18 | constructor( 19 | public product: Product, 20 | public quantity: number 21 | ) {} 22 | 23 | get total(): number { 24 | return this.product.price * this.quantity; 25 | } 26 | } 27 | 28 | export class Order { 29 | private lines = new Map(); 30 | 31 | constructor(initialLines?: OrderLine[]) { 32 | if (initialLines) initialLines.forEach((ol) => this.lines.set(ol.product.id, ol)); 33 | } 34 | 35 | public addProduct(prod: Product, quantity: number) { 36 | if (this.lines.has(prod.id)) { 37 | if (quantity === 0) { 38 | this.removeProduct(prod.id); 39 | } else { 40 | const orderLine = this.lines.get(prod.id); 41 | if (orderLine) 42 | // type guard against undefined 43 | orderLine.quantity += quantity; 44 | } 45 | } else { 46 | this.lines.set(prod.id, new OrderLine(prod, quantity)); 47 | } 48 | } 49 | 50 | public removeProduct(id: number) { 51 | this.lines.delete(id); 52 | } 53 | 54 | get orderLines(): OrderLine[] { 55 | return [...this.lines.values()]; 56 | } 57 | 58 | get productCount(): number { 59 | return [...this.lines.values()].reduce((total, ol) => (total += ol.quantity), 0); 60 | } 61 | 62 | get total(): number { 63 | return [...this.lines.values()].reduce((total, ol) => (total += ol.total), 0); 64 | } 65 | } 66 | 67 | export interface Result { 68 | id: number; 69 | } 70 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module main 2 | 3 | go 1.23.0 4 | 5 | toolchain go1.24.1 6 | 7 | require ( 8 | github.com/gin-contrib/static v1.1.5 9 | github.com/gin-gonic/gin v1.11.0 10 | github.com/mattn/go-sqlite3 v1.14.32 11 | ) 12 | 13 | require ( 14 | github.com/bytedance/sonic v1.14.0 // indirect 15 | github.com/bytedance/sonic/loader v0.3.0 // indirect 16 | github.com/cloudwego/base64x v0.1.6 // indirect 17 | github.com/gabriel-vasile/mimetype v1.4.8 // indirect 18 | github.com/gin-contrib/sse v1.1.0 // indirect 19 | github.com/go-playground/locales v0.14.1 // indirect 20 | github.com/go-playground/universal-translator v0.18.1 // indirect 21 | github.com/go-playground/validator/v10 v10.27.0 // indirect 22 | github.com/goccy/go-json v0.10.5 // indirect 23 | github.com/goccy/go-yaml v1.18.0 // indirect 24 | github.com/json-iterator/go v1.1.12 // indirect 25 | github.com/klauspost/cpuid/v2 v2.3.0 // indirect 26 | github.com/leodido/go-urn v1.4.0 // indirect 27 | github.com/mattn/go-isatty v0.0.20 // indirect 28 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 29 | github.com/modern-go/reflect2 v1.0.2 // indirect 30 | github.com/pelletier/go-toml/v2 v2.2.4 // indirect 31 | github.com/quic-go/qpack v0.5.1 // indirect 32 | github.com/quic-go/quic-go v0.54.0 // indirect 33 | github.com/twitchyliquid64/golang-asm v0.15.1 // indirect 34 | github.com/ugorji/go/codec v1.3.0 // indirect 35 | go.uber.org/mock v0.5.0 // indirect 36 | golang.org/x/arch v0.20.0 // indirect 37 | golang.org/x/crypto v0.40.0 // indirect 38 | golang.org/x/mod v0.25.0 // indirect 39 | golang.org/x/net v0.42.0 // indirect 40 | golang.org/x/sync v0.16.0 // indirect 41 | golang.org/x/sys v0.35.0 // indirect 42 | golang.org/x/text v0.27.0 // indirect 43 | golang.org/x/tools v0.34.0 // indirect 44 | google.golang.org/protobuf v1.36.9 // indirect 45 | ) 46 | -------------------------------------------------------------------------------- /src/routes/products/+page.svelte: -------------------------------------------------------------------------------- 1 | 37 | 38 |
39 |
40 |
41 |
42 |
43 | 44 |
45 |
46 | {#each filteredProducts as product} 47 |
48 | 49 |
50 | {/each} 51 |
52 |
53 |
54 |
55 | -------------------------------------------------------------------------------- /src/routes/order/+page.svelte: -------------------------------------------------------------------------------- 1 | 18 | 19 |
20 |

Order Summary

21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | {#each order.orderLines as line} 33 | 34 | 35 | 36 | 37 | 38 | 39 | {/each} 40 | 41 | 42 | 43 | 44 | 52 | 53 | 54 |
QuantityProductPriceSubtotal
{line.quantity}{line.product.name}${line.product.price.toFixed(2)}${line.total.toFixed(2)}
Total: 45 | 49 | ${order.total.toFixed(2)} 50 | 51 |
55 |
56 |
57 | Back 58 | 59 |
60 |
61 | -------------------------------------------------------------------------------- /backend/server.go: -------------------------------------------------------------------------------- 1 | package backend 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "flag" 7 | "fmt" 8 | "log" 9 | "net/http" 10 | "os" 11 | "os/signal" 12 | "syscall" 13 | "time" 14 | 15 | "github.com/gin-contrib/static" 16 | "github.com/gin-gonic/gin" 17 | ) 18 | 19 | // Server is the main program 20 | func Server() { 21 | 22 | // read command-line flags 23 | host := flag.String("host", "localhost", "Server host") 24 | port := flag.Int("port", 8080, "Server port") 25 | docker := flag.Bool("docker", false, "Running in docker") 26 | flag.Parse() 27 | 28 | // prepare service, http handler and server 29 | gin.SetMode(gin.ReleaseMode) 30 | router := gin.Default() 31 | service := Service{} 32 | 33 | // apis 34 | api := router.Group("/api") 35 | api.GET("/products", service.ProductService) // api: /api/products 36 | api.POST("/orders", service.OrderService) // api: /api/orders 37 | 38 | // serve static files 39 | router.Use(static.Serve("/", static.LocalFile("./build", true))) 40 | router.NoRoute(func(c *gin.Context) { // fallback 41 | c.File("./build/index.html") 42 | }) 43 | 44 | var serverPath string 45 | if *docker { 46 | serverPath = "0.0.0.0:8080" 47 | log.Println("Server started at http://localhost:8080 ...") 48 | } else { 49 | serverPath = fmt.Sprintf("%s:%d", *host, *port) 50 | log.Printf("Server started at http://%s ...\n", serverPath) 51 | } 52 | 53 | server := &http.Server{ 54 | Addr: serverPath, 55 | Handler: router, 56 | ReadTimeout: 10 * time.Second, 57 | WriteTimeout: 10 * time.Second, 58 | } 59 | 60 | // start server 61 | go func() { 62 | if err := server.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) { 63 | log.Fatalln(err) 64 | } 65 | }() 66 | 67 | // graceful shutdown 68 | quit := make(chan os.Signal, 1) 69 | signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) 70 | <-quit 71 | log.Println("Shutdown Server ...") 72 | 73 | ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) 74 | defer cancel() 75 | if err := server.Shutdown(ctx); err != nil { 76 | log.Fatalln(err) 77 | } 78 | log.Println("Server exiting") 79 | } 80 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "svelteapp-typescript-go", 3 | "version": "0.1.0", 4 | "license": "MIT", 5 | "private": true, 6 | "scripts": { 7 | "setup-app": "yarn install --frozen-lockfile", 8 | "setup-server": "echo \"Download Golang dependencies...\" && go mod download", 9 | "setup-full": "yarn setup-app && yarn setup-server", 10 | "setup-all": "yarn setup-full", 11 | "upgrade-app": "yarn-upgrade-all && yarn upgrade", 12 | "upgrade-server": "echo \"Update Golang dependencies...\" && go get -u ./...", 13 | "upgrade-full": "yarn upgrade-app && yarn upgrade-server", 14 | "upgrade-all": "yarn upgrade-full", 15 | "dev": "vite dev --port 3000 --open --host", 16 | "preview": "vite preview --port 8080 --open --host", 17 | "start": "yarn dev", 18 | "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", 19 | "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", 20 | "build-app": "yarn check && yarn vite build", 21 | "build-server": "echo \"Building Golang binary...\" && go env -w CGO_ENABLED=1 && go build -buildvcs=false -mod=readonly -v", 22 | "build-full": "yarn build-app && yarn build-server", 23 | "build-all": "yarn build-full", 24 | "build": "yarn build-full", 25 | "serve": "open-cli http://localhost:8080 && ./main", 26 | "serve-win": "open-cli http://localhost:8080 && main", 27 | "docker": "docker build . -t svelte-ts-go -f Dockerfile", 28 | "docker-run": "open-cli http://localhost:8080 && docker run -p 8080:8080 --rm svelte-ts-go", 29 | "commit": "git pull origin main && git add . && git commit -m \"Updating\" && git push origin main" 30 | }, 31 | "devDependencies": { 32 | "@sveltejs/adapter-static": "^3.0.9", 33 | "@sveltejs/kit": "^2.42.2", 34 | "@sveltejs/vite-plugin-svelte": "^6.2.0", 35 | "globals": "^16.4.0", 36 | "open-cli": "^8.0.0", 37 | "svelte": "^5.39.4", 38 | "svelte-check": "^4.3.1", 39 | "svelte-preprocess": "^6.0.3", 40 | "typescript": "^5.9.2", 41 | "vite": "^7.1.6", 42 | "yarn-upgrade-all": "^0.7.5" 43 | }, 44 | "type": "module", 45 | "dependencies": { 46 | "@fontsource/open-sans": "^5.2.7", 47 | "bootstrap": "^5.3.8" 48 | }, 49 | "resolutions": { 50 | "picomatch": "^4.0.2" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /backend/service.go: -------------------------------------------------------------------------------- 1 | package backend 2 | 3 | import ( 4 | "database/sql" 5 | "errors" 6 | "log" 7 | "net/http" 8 | 9 | "github.com/gin-gonic/gin" 10 | 11 | // blank import for side effect 12 | _ "github.com/mattn/go-sqlite3" 13 | ) 14 | 15 | const dbFileName = "./db/data.sqlite3" 16 | 17 | // Service is the backend DB/REST api struct 18 | type Service struct { 19 | } 20 | 21 | func (s *Service) getDatabase() (*sql.DB, error) { 22 | return sql.Open("sqlite3", dbFileName) 23 | } 24 | 25 | // LoadProductsFromDatabase load product list from DB 26 | func (s *Service) LoadProductsFromDatabase() (products []Product, err error) { 27 | 28 | db, err := s.getDatabase() 29 | if err != nil { 30 | log.Println(err) 31 | return 32 | } 33 | defer db.Close() 34 | 35 | if err = db.Ping(); err != nil { 36 | log.Println(err) 37 | return 38 | } 39 | 40 | rows, err := db.Query("SELECT * FROM products") 41 | if err != nil { 42 | log.Println(err) 43 | return 44 | } 45 | defer rows.Close() 46 | 47 | for rows.Next() { 48 | p := Product{} 49 | if err := rows.Scan(&p.Id, &p.Name, &p.Category, &p.Description, &p.Price); err != nil { 50 | log.Println(err) 51 | continue 52 | } 53 | products = append(products, p) 54 | } 55 | 56 | log.Printf("Queried %d product(s)", len(products)) 57 | return 58 | } 59 | 60 | // StoreOrderIntoDatabase insert new order into DB 61 | func (s *Service) StoreOrderIntoDatabase(newOrder Order) (newID int, err error) { 62 | 63 | db, err := s.getDatabase() 64 | if err != nil { 65 | log.Println(err) 66 | return 67 | } 68 | defer db.Close() 69 | 70 | if err = db.Ping(); err != nil { 71 | log.Println(err) 72 | return 73 | } 74 | 75 | rowStmt, err := db.Prepare("SELECT MAX(id) AS id FROM orders") 76 | if err != nil { 77 | log.Println(err) 78 | return 79 | } 80 | defer rowStmt.Close() 81 | 82 | // get the last order id 83 | 84 | var id sql.NullInt32 85 | if err = rowStmt.QueryRow().Scan(&id); err != nil { 86 | log.Println(err) 87 | return 88 | } 89 | if id.Valid { 90 | newID = int(id.Int32) + 1 91 | } else { 92 | newID = 1 93 | } 94 | 95 | // write each order line as a row 96 | 97 | insertStmt, err := db.Prepare("INSERT INTO orders (id, product_id, quantity) values (?, ?, ?)") 98 | if err != nil { 99 | log.Println(err) 100 | return 101 | } 102 | defer insertStmt.Close() 103 | 104 | var itemCount int 105 | for _, line := range newOrder.Lines { 106 | itemCount += line.Quantity 107 | if _, err = insertStmt.Exec(newID, line.ProductId, line.Quantity); err != nil { 108 | log.Println(err) 109 | } 110 | } 111 | 112 | log.Printf("Order #%d (%d items) added\n", newID, itemCount) 113 | return 114 | } 115 | 116 | // ProductService is the GET service for product list 117 | func (s *Service) ProductService(c *gin.Context) { 118 | 119 | products, err := s.LoadProductsFromDatabase() 120 | if err != nil { 121 | log.Println(err) 122 | c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 123 | return 124 | } 125 | 126 | // return JSON 127 | c.JSON(http.StatusOK, products) 128 | } 129 | 130 | // OrderService is the POST service to add new oerder 131 | func (s *Service) OrderService(c *gin.Context) { 132 | 133 | newOrder := Order{} 134 | if err := c.BindJSON(&newOrder); err != nil { 135 | log.Println(err) 136 | c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 137 | return 138 | } 139 | 140 | newId, err := s.StoreOrderIntoDatabase(newOrder) 141 | if err != nil || newId == 0 { 142 | if newId == 0 { 143 | err = errors.New("unable to get new order id") 144 | } 145 | log.Println(err) 146 | c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) 147 | return 148 | } 149 | 150 | // return the new order id 151 | result := Result{ Id: newId } 152 | c.JSON(http.StatusCreated, result) 153 | } 154 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/bytedance/sonic v1.14.0 h1:/OfKt8HFw0kh2rj8N0F6C/qPGRESq0BbaNZgcNXXzQQ= 2 | github.com/bytedance/sonic v1.14.0/go.mod h1:WoEbx8WTcFJfzCe0hbmyTGrfjt8PzNEBdxlNUO24NhA= 3 | github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZwvZJyqeA= 4 | github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= 5 | github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= 6 | github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= 7 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 8 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 9 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 10 | github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= 11 | github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= 12 | github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w= 13 | github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= 14 | github.com/gin-contrib/static v1.1.5 h1:bAPqT4KTZN+4uDY1b90eSrD1t8iNzod7Jj8njwmnzz4= 15 | github.com/gin-contrib/static v1.1.5/go.mod h1:8JSEXwZHcQ0uCrLPcsvnAJ4g+ODxeupP8Zetl9fd8wM= 16 | github.com/gin-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk= 17 | github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls= 18 | github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= 19 | github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= 20 | github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= 21 | github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= 22 | github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= 23 | github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= 24 | github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4= 25 | github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= 26 | github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= 27 | github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= 28 | github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= 29 | github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= 30 | github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= 31 | github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= 32 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 33 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 34 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 35 | github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= 36 | github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= 37 | github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= 38 | github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= 39 | github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= 40 | github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 41 | github.com/mattn/go-sqlite3 v1.14.32 h1:JD12Ag3oLy1zQA+BNn74xRgaBbdhbNIDYvQUEuuErjs= 42 | github.com/mattn/go-sqlite3 v1.14.32/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= 43 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 44 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 45 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 46 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 47 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 48 | github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= 49 | github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= 50 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 51 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 52 | github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= 53 | github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= 54 | github.com/quic-go/quic-go v0.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQBg= 55 | github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY= 56 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 57 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 58 | github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 59 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 60 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 61 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 62 | github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 63 | github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= 64 | github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= 65 | github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= 66 | github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= 67 | github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA= 68 | github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= 69 | go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= 70 | go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= 71 | golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c= 72 | golang.org/x/arch v0.20.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk= 73 | golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM= 74 | golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY= 75 | golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w= 76 | golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= 77 | golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= 78 | golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= 79 | golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= 80 | golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= 81 | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 82 | golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= 83 | golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 84 | golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4= 85 | golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU= 86 | golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo= 87 | golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg= 88 | google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw= 89 | google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= 90 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 91 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 92 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 93 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 94 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # A Full-Stack, Self-Contained Shopping Demo App With Svelte, Golang and SQLite 2 | 3 | ![ezgif-5-22d3d39425](https://user-images.githubusercontent.com/44191076/148008744-14f89c9d-5343-483a-8bdc-c05618a84acc.gif) 4 | 5 | This is a simple shopping demo app, based on the same Angular/React/Vue.js examples in [Essential Typescript](https://github.com/Apress/essential-typescript-4) by Adam Freeman: 6 | 7 | - Front-end: (`/src`) 8 | - [TypeScript](https://www.typescriptlang.org/) 9 | - Component framework: [Svelte 5](https://svelte.dev/) (upgraded to Svelte 5 syntax) 10 | - Application framework: [SvelteKit 2](https://kit.svelte.dev/) 11 | - Static site generation: [@sveltejs/adapter-static](https://www.npmjs.com/package/@sveltejs/adapter-static) 12 | - CSS styles: [Bootstrap 5](https://getbootstrap.com/) 13 | - Back-end: (`/backend`) 14 | - [Golang](https://go.dev/) 15 | - Static web server/RESTful web services: [gin](https://github.com/gin-gonic/gin) 16 | - SQLite driver: [go-sqlite3](https://github.com/mattn/go-sqlite3) 17 | - Database: (`/db`) 18 | - [SQLite](https://www.sqlite.org/index.html) 19 | 20 | The project comes with a [Dockerfile](https://github.com/alankrantas/svelteapp-typescript-go/blob/main/Dockerfile) that can create a single small container with multi-stage builds (image size ~25 MB) and also support to be opened in [DevContainer](https://code.visualstudio.com/docs/devcontainers/containers)/[CodeSpace](https://github.com/features/codespaces). 21 | 22 | A [Github Action workflow](https://github.com/alankrantas/svelteapp-typescript-go/blob/main/.github/workflows/dependabot-test.yml) is created to run build test for dependabot's pull-requests for dependency updates. 23 | 24 | The purpose of project is a demonstration to build a small and self-contained full-stack monolithic application with modern frameworks, but not meant to be a practical template for any real world applications. For example, error handlings between front-end and authentication are mostly ignored. 25 | 26 | > A similar version using Vue.js, Express, MongoDB and Docker Compose [can be found here](https://github.com/alankrantas/vueapp-typescript-express) (no longer maintained). 27 | 28 | ## Routes 29 | 30 | The Svelte app has the following routes: 31 | 32 | | Route | Page | 33 | | --------------- | ---------------------------------------- | 34 | | `/` | Index (will redirect to `/products`) | 35 | | `/products` | Browse and add products to shopping cart | 36 | | `/order` | View and checkout order | 37 | | `/summary/{id}` | Order result | 38 | 39 | ### The Application Flow 40 | 41 | 1. When the app is opened at `/`, it will immediately redirect to `/products`. 42 | 2. `/products` loads the list of products from an API service and display the categories and items. 43 | 3. The user can filter items using the category buttons. 44 | 4. When the user clicks `Add To Cart` on any items, it will be added to the cart (global state array `orderLines`). 45 | 5. When the user clicks `Submit Order` on `/products`, the app will redirect to `/order`, whcih will show the detail of the order. 46 | 6. When the user clicks `Submit Order` on `/order`, the app will send the order to an API service and get the order ID. 47 | 7. After the order is "sent", the app will redirect to `/summary/[id]` as the result. 48 | 49 | ## Backend APIs 50 | 51 | The backend creates two RESTful-like APIs: 52 | 53 | | API | Function | 54 | | ------------------- | ------------------------------------------------ | 55 | | GET `/api/products` | Query DB and return product data | 56 | | POST `/api/orders` | Write order data into DB and return new order ID | 57 | 58 | Adam Freeman's original projects use [`json-server`](https://github.com/typicode/json-server) on an Express server as mock API services. I keep the input/output spec of the services for the sake of demonstration. Right now, like all the original examples, the app only reads product lists and write order data. The `Axios` package used in the original examples is also replaced with `fetch`. 59 | 60 | > SvelteKit also has a feature to create ["backend APIs"](https://kit.svelte.dev/docs/routing#server). However the Golang server here is enough, so we don't really need to create duplicated APIs. 61 | 62 | ### `/api/products` 63 | 64 | Return a list of products from the database. The `category` will be used to create category filter buttons on the app. 65 | 66 | Example request body: 67 | 68 | (none) 69 | 70 | Example response body: 71 | 72 | ```json 73 | [ 74 | { 75 | "id": 1, 76 | "name": "Kayak", 77 | "category": "Watersports", 78 | "description": "A boat for one person", 79 | "price": 275.0 80 | }, 81 | { 82 | "id": 2, 83 | "name": "Lifejacket", 84 | "category": "Watersports", 85 | "description": "Protective and fashionable", 86 | "price": 48.95 87 | } 88 | ] 89 | ``` 90 | 91 | ### `/api/orders` 92 | 93 | Write ordered item and quantities. The service will create a new order ID and associate it with the ordered products. 94 | 95 | Example request body: 96 | 97 | ```json 98 | { 99 | "lines": [ 100 | { 101 | "productId": 1, 102 | "productName": "Kayak", 103 | "quantity": 2 104 | }, 105 | { 106 | "productId": 2, 107 | "productName": "Lifejacket", 108 | "quantity": 4 109 | } 110 | ] 111 | } 112 | ``` 113 | 114 | Example response body: 115 | 116 | ```json 117 | { 118 | "id": 42 119 | } 120 | ``` 121 | 122 | --- 123 | 124 | ## Database Schemes and Example Data 125 | 126 | The SQLite database (`./db/data.sqlite3`) in this repo already contains the table `products` with 9 product records (which can be found in many Adam Freeman's books) and an empty table `orders`. You can use [DB Browser for SQLite](https://sqlitebrowser.org/) to read the database. There is also a backup file in case you need to restore the database. 127 | 128 | Here's the SQL statements to recreate them: 129 | 130 | ```sql 131 | CREATE TABLE "products" ( 132 | "id" INTEGER NOT NULL UNIQUE, -- product ID 133 | "name" TEXT NOT NULL, 134 | "category" TEXT NOT NULL, 135 | "description" TEXT, 136 | "price" REAL NOT NULL, 137 | PRIMARY KEY("id" AUTOINCREMENT) 138 | ); 139 | 140 | CREATE TABLE "orders" ( 141 | "id" INTEGER NOT NULL, -- order ID 142 | "product_id" INTEGER NOT NULL, -- product ID 143 | "quantity" INTEGER NOT NULL 144 | ); 145 | 146 | INSERT INTO "main"."products" ( 147 | "id", 148 | "name", 149 | "category", 150 | "description", 151 | "price" 152 | ) 153 | VALUES 154 | ('1', 'Kayak', 'Watersports', 'A boat for one person', '275.0'), 155 | ('2', 'Lifejacket', 'Watersports', 'Protective and fashionable', '48.95'), 156 | ('3', 'Soccer Ball', 'Soccer', 'FIFA-approved size and weight', '19.5'), 157 | ('4', 'Corner Flags', 'Soccer', 'Give your playing field a professional touch', '34.95'), 158 | ('5', 'Stadium', 'Soccer', 'Flat-packed 35,000-seat stadium', '79500.0'), 159 | ('6', 'Thinking Cap', 'Chess', 'Improve brain efficiency by 75%', '16.0'), 160 | ('7', 'Unsteady Chair', 'Chess', 'Secretly give your opponent a disadvantage', '29.95'), 161 | ('8', 'Human Chess Board', 'Chess', 'A fun game for the family', '75.0'), 162 | ('9', 'Bling Bling King', 'Chess', 'Gold-plated, diamond-studded King', '1200.0'); 163 | ``` 164 | 165 | --- 166 | 167 | ## Setup Local Project 168 | 169 | For local development you'll need 170 | 171 | - [Git](https://git-scm.com/download/) 172 | - [Node.js](https://nodejs.org/en/download/) (for dev or production) 173 | - [Golang](https://go.dev/dl/) (for production) 174 | - [Docker](https://docs.docker.com/get-docker/) (only required for generating the container) 175 | 176 | > Note: the `go-sqlite3` package requires GCC to compile with the environment variable `CGO_ENABLED=1`. 177 | > 178 | > For Windows users, it can be installed with [MinGW](https://winlibs.com/#download-release) (unzip and add `\mingw64\bin` to `$PATH`, then restart VS Code). On Linux it can be installed with the package `build-essential`. 179 | 180 | ### Clone Repository 181 | 182 | ```bash 183 | git clone https://github.com/alankrantas/svelteapp-typescript-go.git 184 | cd svelteapp-typescript-go 185 | npm i -g yarn@latest 186 | yarn setup-full 187 | ``` 188 | 189 | And install/upgrade yarn: 190 | 191 | ```bash 192 | npm i -g yarn@latest 193 | ``` 194 | 195 | ### Serve Frontend in Dev Mode 196 | 197 | Run the Svelte app in development mode. The app _will not_ call any backend APIs, instead it returns mock product data and the returned order number is always `42`. 198 | 199 | ```bash 200 | yarn dev 201 | ``` 202 | 203 | The app will be open at `http://localhost:3000`. 204 | 205 | ### Download Dependencies 206 | 207 | ```bash 208 | # download frontend dependencies 209 | yarn 210 | 211 | # download backend dependencies 212 | yarn setup-server 213 | 214 | # download both dependencies 215 | yarn setup-full 216 | # or 217 | # yarn setup-all 218 | ``` 219 | 220 | ### Upgrade Dependencies 221 | 222 | ```bash 223 | # upgrade frontend dependencies 224 | yarn upgrade-app 225 | 226 | # upgrade backend dependencies 227 | yarn upgrade-server 228 | 229 | # upgrade both dependencies 230 | yarn upgrade-full 231 | # or 232 | # yarn upgrade-all 233 | ``` 234 | 235 | ### Build Production 236 | 237 | Install dependencies, build both front-end and back-end apps and run the local server: 238 | 239 | ```bash 240 | # build frontend app 241 | yarn build-app 242 | 243 | # build backend server (which will set CGO_ENABLED=1) 244 | yarn build-server 245 | 246 | # build both 247 | yarn build-full 248 | # or 249 | # yarn build 250 | # yarn build-all 251 | ``` 252 | 253 | ### Serve Production 254 | 255 | ```bash 256 | # serve in macOS or Linux 257 | yarn serve 258 | 259 | # serve in Windows 260 | yarn serve-win 261 | ``` 262 | 263 | The app would open at `http://localhost:8080`. 264 | 265 | --- 266 | 267 | ### Build and Run as a Docker Container 268 | 269 | ```bash 270 | # build container 271 | yarn docker 272 | 273 | # run container 274 | yarn docker-run 275 | ``` 276 | 277 | The app would open at `http://localhost:8080`. 278 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@esbuild/aix-ppc64@0.25.2": 6 | version "0.25.2" 7 | resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz#b87036f644f572efb2b3c75746c97d1d2d87ace8" 8 | integrity sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag== 9 | 10 | "@esbuild/android-arm64@0.25.2": 11 | version "0.25.2" 12 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.25.2.tgz#5ca7dc20a18f18960ad8d5e6ef5cf7b0a256e196" 13 | integrity sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w== 14 | 15 | "@esbuild/android-arm@0.25.2": 16 | version "0.25.2" 17 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.25.2.tgz#3c49f607b7082cde70c6ce0c011c362c57a194ee" 18 | integrity sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA== 19 | 20 | "@esbuild/android-x64@0.25.2": 21 | version "0.25.2" 22 | resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.25.2.tgz#8a00147780016aff59e04f1036e7cb1b683859e2" 23 | integrity sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg== 24 | 25 | "@esbuild/darwin-arm64@0.25.2": 26 | version "0.25.2" 27 | resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.2.tgz#486efe7599a8d90a27780f2bb0318d9a85c6c423" 28 | integrity sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA== 29 | 30 | "@esbuild/darwin-x64@0.25.2": 31 | version "0.25.2" 32 | resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.25.2.tgz#95ee222aacf668c7a4f3d7ee87b3240a51baf374" 33 | integrity sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA== 34 | 35 | "@esbuild/freebsd-arm64@0.25.2": 36 | version "0.25.2" 37 | resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.2.tgz#67efceda8554b6fc6a43476feba068fb37fa2ef6" 38 | integrity sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w== 39 | 40 | "@esbuild/freebsd-x64@0.25.2": 41 | version "0.25.2" 42 | resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.2.tgz#88a9d7ecdd3adadbfe5227c2122d24816959b809" 43 | integrity sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ== 44 | 45 | "@esbuild/linux-arm64@0.25.2": 46 | version "0.25.2" 47 | resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.25.2.tgz#87be1099b2bbe61282333b084737d46bc8308058" 48 | integrity sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g== 49 | 50 | "@esbuild/linux-arm@0.25.2": 51 | version "0.25.2" 52 | resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.25.2.tgz#72a285b0fe64496e191fcad222185d7bf9f816f6" 53 | integrity sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g== 54 | 55 | "@esbuild/linux-ia32@0.25.2": 56 | version "0.25.2" 57 | resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.25.2.tgz#337a87a4c4dd48a832baed5cbb022be20809d737" 58 | integrity sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ== 59 | 60 | "@esbuild/linux-loong64@0.25.2": 61 | version "0.25.2" 62 | resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.25.2.tgz#1b81aa77103d6b8a8cfa7c094ed3d25c7579ba2a" 63 | integrity sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w== 64 | 65 | "@esbuild/linux-mips64el@0.25.2": 66 | version "0.25.2" 67 | resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.2.tgz#afbe380b6992e7459bf7c2c3b9556633b2e47f30" 68 | integrity sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q== 69 | 70 | "@esbuild/linux-ppc64@0.25.2": 71 | version "0.25.2" 72 | resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.2.tgz#6bf8695cab8a2b135cca1aa555226dc932d52067" 73 | integrity sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g== 74 | 75 | "@esbuild/linux-riscv64@0.25.2": 76 | version "0.25.2" 77 | resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.2.tgz#43c2d67a1a39199fb06ba978aebb44992d7becc3" 78 | integrity sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw== 79 | 80 | "@esbuild/linux-s390x@0.25.2": 81 | version "0.25.2" 82 | resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.25.2.tgz#419e25737ec815c6dce2cd20d026e347cbb7a602" 83 | integrity sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q== 84 | 85 | "@esbuild/linux-x64@0.25.2": 86 | version "0.25.2" 87 | resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.25.2.tgz#22451f6edbba84abe754a8cbd8528ff6e28d9bcb" 88 | integrity sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg== 89 | 90 | "@esbuild/netbsd-arm64@0.25.2": 91 | version "0.25.2" 92 | resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.2.tgz#744affd3b8d8236b08c5210d828b0698a62c58ac" 93 | integrity sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw== 94 | 95 | "@esbuild/netbsd-x64@0.25.2": 96 | version "0.25.2" 97 | resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.2.tgz#dbbe7521fd6d7352f34328d676af923fc0f8a78f" 98 | integrity sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg== 99 | 100 | "@esbuild/openbsd-arm64@0.25.2": 101 | version "0.25.2" 102 | resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.2.tgz#f9caf987e3e0570500832b487ce3039ca648ce9f" 103 | integrity sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg== 104 | 105 | "@esbuild/openbsd-x64@0.25.2": 106 | version "0.25.2" 107 | resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.2.tgz#d2bb6a0f8ffea7b394bb43dfccbb07cabd89f768" 108 | integrity sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw== 109 | 110 | "@esbuild/sunos-x64@0.25.2": 111 | version "0.25.2" 112 | resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.25.2.tgz#49b437ed63fe333b92137b7a0c65a65852031afb" 113 | integrity sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA== 114 | 115 | "@esbuild/win32-arm64@0.25.2": 116 | version "0.25.2" 117 | resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.25.2.tgz#081424168463c7d6c7fb78f631aede0c104373cf" 118 | integrity sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q== 119 | 120 | "@esbuild/win32-ia32@0.25.2": 121 | version "0.25.2" 122 | resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.25.2.tgz#3f9e87143ddd003133d21384944a6c6cadf9693f" 123 | integrity sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg== 124 | 125 | "@esbuild/win32-x64@0.25.2": 126 | version "0.25.2" 127 | resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.25.2.tgz#839f72c2decd378f86b8f525e1979a97b920c67d" 128 | integrity sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA== 129 | 130 | "@fontsource/open-sans@^5.2.7": 131 | version "5.2.7" 132 | resolved "https://registry.yarnpkg.com/@fontsource/open-sans/-/open-sans-5.2.7.tgz#dc82cec21f3995163bfb15affea937083b4701fb" 133 | integrity sha512-8yfgDYjE5O0vmTPdrcjV35y4yMnctsokmi9gN49Gcsr0sjzkMkR97AnKDe6OqZh2SFkYlR28fxOvi21bYEgMSw== 134 | 135 | "@jridgewell/gen-mapping@^0.3.5": 136 | version "0.3.8" 137 | resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz#4f0e06362e01362f823d348f1872b08f666d8142" 138 | integrity sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA== 139 | dependencies: 140 | "@jridgewell/set-array" "^1.2.1" 141 | "@jridgewell/sourcemap-codec" "^1.4.10" 142 | "@jridgewell/trace-mapping" "^0.3.24" 143 | 144 | "@jridgewell/remapping@^2.3.4": 145 | version "2.3.5" 146 | resolved "https://registry.yarnpkg.com/@jridgewell/remapping/-/remapping-2.3.5.tgz#375c476d1972947851ba1e15ae8f123047445aa1" 147 | integrity sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ== 148 | dependencies: 149 | "@jridgewell/gen-mapping" "^0.3.5" 150 | "@jridgewell/trace-mapping" "^0.3.24" 151 | 152 | "@jridgewell/resolve-uri@^3.1.0": 153 | version "3.1.2" 154 | resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" 155 | integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== 156 | 157 | "@jridgewell/set-array@^1.2.1": 158 | version "1.2.1" 159 | resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280" 160 | integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== 161 | 162 | "@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15", "@jridgewell/sourcemap-codec@^1.5.0": 163 | version "1.5.0" 164 | resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" 165 | integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== 166 | 167 | "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": 168 | version "0.3.25" 169 | resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" 170 | integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== 171 | dependencies: 172 | "@jridgewell/resolve-uri" "^3.1.0" 173 | "@jridgewell/sourcemap-codec" "^1.4.14" 174 | 175 | "@polka/url@^1.0.0-next.24": 176 | version "1.0.0-next.28" 177 | resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.28.tgz#d45e01c4a56f143ee69c54dd6b12eade9e270a73" 178 | integrity sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw== 179 | 180 | "@rollup/rollup-android-arm-eabi@4.46.2": 181 | version "4.46.2" 182 | resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.46.2.tgz#292e25953d4988d3bd1af0f5ebbd5ee4d65c90b4" 183 | integrity sha512-Zj3Hl6sN34xJtMv7Anwb5Gu01yujyE/cLBDB2gnHTAHaWS1Z38L7kuSG+oAh0giZMqG060f/YBStXtMH6FvPMA== 184 | 185 | "@rollup/rollup-android-arm64@4.46.2": 186 | version "4.46.2" 187 | resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.46.2.tgz#053b3def3451e6fc1a9078188f22799e868d7c59" 188 | integrity sha512-nTeCWY83kN64oQ5MGz3CgtPx8NSOhC5lWtsjTs+8JAJNLcP3QbLCtDDgUKQc/Ro/frpMq4SHUaHN6AMltcEoLQ== 189 | 190 | "@rollup/rollup-darwin-arm64@4.46.2": 191 | version "4.46.2" 192 | resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.46.2.tgz#98d90445282dec54fd05440305a5e8df79a91ece" 193 | integrity sha512-HV7bW2Fb/F5KPdM/9bApunQh68YVDU8sO8BvcW9OngQVN3HHHkw99wFupuUJfGR9pYLLAjcAOA6iO+evsbBaPQ== 194 | 195 | "@rollup/rollup-darwin-x64@4.46.2": 196 | version "4.46.2" 197 | resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.46.2.tgz#fe05f95a736423af5f9c3a59a70f41ece52a1f20" 198 | integrity sha512-SSj8TlYV5nJixSsm/y3QXfhspSiLYP11zpfwp6G/YDXctf3Xkdnk4woJIF5VQe0of2OjzTt8EsxnJDCdHd2xMA== 199 | 200 | "@rollup/rollup-freebsd-arm64@4.46.2": 201 | version "4.46.2" 202 | resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.46.2.tgz#41e1fbdc1f8c3dc9afb6bc1d6e3fb3104bd81eee" 203 | integrity sha512-ZyrsG4TIT9xnOlLsSSi9w/X29tCbK1yegE49RYm3tu3wF1L/B6LVMqnEWyDB26d9Ecx9zrmXCiPmIabVuLmNSg== 204 | 205 | "@rollup/rollup-freebsd-x64@4.46.2": 206 | version "4.46.2" 207 | resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.46.2.tgz#69131e69cb149d547abb65ef3b38fc746c940e24" 208 | integrity sha512-pCgHFoOECwVCJ5GFq8+gR8SBKnMO+xe5UEqbemxBpCKYQddRQMgomv1104RnLSg7nNvgKy05sLsY51+OVRyiVw== 209 | 210 | "@rollup/rollup-linux-arm-gnueabihf@4.46.2": 211 | version "4.46.2" 212 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.46.2.tgz#977ded91c7cf6fc0d9443bb9c0a064e45a805267" 213 | integrity sha512-EtP8aquZ0xQg0ETFcxUbU71MZlHaw9MChwrQzatiE8U/bvi5uv/oChExXC4mWhjiqK7azGJBqU0tt5H123SzVA== 214 | 215 | "@rollup/rollup-linux-arm-musleabihf@4.46.2": 216 | version "4.46.2" 217 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.46.2.tgz#dc034fc3c0f0eb5c75b6bc3eca3b0b97fd35f49a" 218 | integrity sha512-qO7F7U3u1nfxYRPM8HqFtLd+raev2K137dsV08q/LRKRLEc7RsiDWihUnrINdsWQxPR9jqZ8DIIZ1zJJAm5PjQ== 219 | 220 | "@rollup/rollup-linux-arm64-gnu@4.46.2": 221 | version "4.46.2" 222 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.46.2.tgz#5e92613768d3de3ffcabc965627dd0a59b3e7dfc" 223 | integrity sha512-3dRaqLfcOXYsfvw5xMrxAk9Lb1f395gkoBYzSFcc/scgRFptRXL9DOaDpMiehf9CO8ZDRJW2z45b6fpU5nwjng== 224 | 225 | "@rollup/rollup-linux-arm64-musl@4.46.2": 226 | version "4.46.2" 227 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.46.2.tgz#2a44f88e83d28b646591df6e50aa0a5a931833d8" 228 | integrity sha512-fhHFTutA7SM+IrR6lIfiHskxmpmPTJUXpWIsBXpeEwNgZzZZSg/q4i6FU4J8qOGyJ0TR+wXBwx/L7Ho9z0+uDg== 229 | 230 | "@rollup/rollup-linux-loongarch64-gnu@4.46.2": 231 | version "4.46.2" 232 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.46.2.tgz#bd5897e92db7fbf7dc456f61d90fff96c4651f2e" 233 | integrity sha512-i7wfGFXu8x4+FRqPymzjD+Hyav8l95UIZ773j7J7zRYc3Xsxy2wIn4x+llpunexXe6laaO72iEjeeGyUFmjKeA== 234 | 235 | "@rollup/rollup-linux-ppc64-gnu@4.46.2": 236 | version "4.46.2" 237 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.46.2.tgz#a7065025411c14ad9ec34cc1cd1414900ec2a303" 238 | integrity sha512-B/l0dFcHVUnqcGZWKcWBSV2PF01YUt0Rvlurci5P+neqY/yMKchGU8ullZvIv5e8Y1C6wOn+U03mrDylP5q9Yw== 239 | 240 | "@rollup/rollup-linux-riscv64-gnu@4.46.2": 241 | version "4.46.2" 242 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.46.2.tgz#17f9c0c675e13ef4567cfaa3730752417257ccc3" 243 | integrity sha512-32k4ENb5ygtkMwPMucAb8MtV8olkPT03oiTxJbgkJa7lJ7dZMr0GCFJlyvy+K8iq7F/iuOr41ZdUHaOiqyR3iQ== 244 | 245 | "@rollup/rollup-linux-riscv64-musl@4.46.2": 246 | version "4.46.2" 247 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.46.2.tgz#bc6ed3db2cedc1ba9c0a2183620fe2f792c3bf3f" 248 | integrity sha512-t5B2loThlFEauloaQkZg9gxV05BYeITLvLkWOkRXogP4qHXLkWSbSHKM9S6H1schf/0YGP/qNKtiISlxvfmmZw== 249 | 250 | "@rollup/rollup-linux-s390x-gnu@4.46.2": 251 | version "4.46.2" 252 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.46.2.tgz#440c4f6753274e2928e06d2a25613e5a1cf97b41" 253 | integrity sha512-YKjekwTEKgbB7n17gmODSmJVUIvj8CX7q5442/CK80L8nqOUbMtf8b01QkG3jOqyr1rotrAnW6B/qiHwfcuWQA== 254 | 255 | "@rollup/rollup-linux-x64-gnu@4.46.2": 256 | version "4.46.2" 257 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.46.2.tgz#1e936446f90b2574ea4a83b4842a762cc0a0aed3" 258 | integrity sha512-Jj5a9RUoe5ra+MEyERkDKLwTXVu6s3aACP51nkfnK9wJTraCC8IMe3snOfALkrjTYd2G1ViE1hICj0fZ7ALBPA== 259 | 260 | "@rollup/rollup-linux-x64-musl@4.46.2": 261 | version "4.46.2" 262 | resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.46.2.tgz#c6f304dfba1d5faf2be5d8b153ccbd8b5d6f1166" 263 | integrity sha512-7kX69DIrBeD7yNp4A5b81izs8BqoZkCIaxQaOpumcJ1S/kmqNFjPhDu1LHeVXv0SexfHQv5cqHsxLOjETuqDuA== 264 | 265 | "@rollup/rollup-win32-arm64-msvc@4.46.2": 266 | version "4.46.2" 267 | resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.46.2.tgz#b4ad4a79219892aac112ed1c9d1356cad0566ef5" 268 | integrity sha512-wiJWMIpeaak/jsbaq2HMh/rzZxHVW1rU6coyeNNpMwk5isiPjSTx0a4YLSlYDwBH/WBvLz+EtsNqQScZTLJy3g== 269 | 270 | "@rollup/rollup-win32-ia32-msvc@4.46.2": 271 | version "4.46.2" 272 | resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.46.2.tgz#b1b22eb2a9568048961e4a6f540438b4a762aa62" 273 | integrity sha512-gBgaUDESVzMgWZhcyjfs9QFK16D8K6QZpwAaVNJxYDLHWayOta4ZMjGm/vsAEy3hvlS2GosVFlBlP9/Wb85DqQ== 274 | 275 | "@rollup/rollup-win32-x64-msvc@4.46.2": 276 | version "4.46.2" 277 | resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.46.2.tgz#87079f137b5fdb75da11508419aa998cc8cc3d8b" 278 | integrity sha512-CvUo2ixeIQGtF6WvuB87XWqPQkoFAFqW+HUo/WzHwuHDvIwZCtjdWXoYCcr06iKGydiqTclC4jU/TNObC/xKZg== 279 | 280 | "@standard-schema/spec@^1.0.0": 281 | version "1.0.0" 282 | resolved "https://registry.yarnpkg.com/@standard-schema/spec/-/spec-1.0.0.tgz#f193b73dc316c4170f2e82a881da0f550d551b9c" 283 | integrity sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA== 284 | 285 | "@sveltejs/acorn-typescript@^1.0.5": 286 | version "1.0.5" 287 | resolved "https://registry.yarnpkg.com/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.5.tgz#f518101d1b2e12ce80854f1cd850d3b9fb91d710" 288 | integrity sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ== 289 | 290 | "@sveltejs/adapter-static@^3.0.9": 291 | version "3.0.9" 292 | resolved "https://registry.yarnpkg.com/@sveltejs/adapter-static/-/adapter-static-3.0.9.tgz#f31e4c8e54a08598e88eca9d7ebd864e9f4080dc" 293 | integrity sha512-aytHXcMi7lb9ljsWUzXYQ0p5X1z9oWud2olu/EpmH7aCu4m84h7QLvb5Wp+CFirKcwoNnYvYWhyP/L8Vh1ztdw== 294 | 295 | "@sveltejs/kit@^2.42.2": 296 | version "2.42.2" 297 | resolved "https://registry.yarnpkg.com/@sveltejs/kit/-/kit-2.42.2.tgz#bc6316fbe884798ae36854f35f228f5ef1eddf57" 298 | integrity sha512-FcNICFvlSYjPiAgk8BpqTEnXkaUj6I6wDwpQBxKMpsYhUc2Q5STgsVpXOG5LqwFpUAoLAXQ4wdWul7EcAG67JQ== 299 | dependencies: 300 | "@standard-schema/spec" "^1.0.0" 301 | "@sveltejs/acorn-typescript" "^1.0.5" 302 | "@types/cookie" "^0.6.0" 303 | acorn "^8.14.1" 304 | cookie "^0.6.0" 305 | devalue "^5.3.2" 306 | esm-env "^1.2.2" 307 | kleur "^4.1.5" 308 | magic-string "^0.30.5" 309 | mrmime "^2.0.0" 310 | sade "^1.8.1" 311 | set-cookie-parser "^2.6.0" 312 | sirv "^3.0.0" 313 | 314 | "@sveltejs/vite-plugin-svelte-inspector@^5.0.0": 315 | version "5.0.0" 316 | resolved "https://registry.yarnpkg.com/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-5.0.0.tgz#6daf8fb9fced43390614caf449409371847ba655" 317 | integrity sha512-iwQ8Z4ET6ZFSt/gC+tVfcsSBHwsqc6RumSaiLUkAurW3BCpJam65cmHw0oOlDMTO0u+PZi9hilBRYN+LZNHTUQ== 318 | dependencies: 319 | debug "^4.4.1" 320 | 321 | "@sveltejs/vite-plugin-svelte@^6.2.0": 322 | version "6.2.0" 323 | resolved "https://registry.yarnpkg.com/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-6.2.0.tgz#5a7516fbbda37cfbf81e398891b15f046dc8dafd" 324 | integrity sha512-nJsV36+o7rZUDlrnSduMNl11+RoDE1cKqOI0yUEBCcqFoAZOk47TwD3dPKS2WmRutke9StXnzsPBslY7prDM9w== 325 | dependencies: 326 | "@sveltejs/vite-plugin-svelte-inspector" "^5.0.0" 327 | debug "^4.4.1" 328 | deepmerge "^4.3.1" 329 | magic-string "^0.30.17" 330 | vitefu "^1.1.1" 331 | 332 | "@tokenizer/token@^0.3.0": 333 | version "0.3.0" 334 | resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276" 335 | integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A== 336 | 337 | "@types/cookie@^0.6.0": 338 | version "0.6.0" 339 | resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.6.0.tgz#eac397f28bf1d6ae0ae081363eca2f425bedf0d5" 340 | integrity sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA== 341 | 342 | "@types/estree@1.0.8", "@types/estree@^1.0.5", "@types/estree@^1.0.6": 343 | version "1.0.8" 344 | resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e" 345 | integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== 346 | 347 | abort-controller@^3.0.0: 348 | version "3.0.0" 349 | resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" 350 | integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== 351 | dependencies: 352 | event-target-shim "^5.0.0" 353 | 354 | acorn@^8.12.1, acorn@^8.14.1: 355 | version "8.14.1" 356 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.1.tgz#721d5dc10f7d5b5609a891773d47731796935dfb" 357 | integrity sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg== 358 | 359 | aria-query@^5.3.1: 360 | version "5.3.2" 361 | resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.2.tgz#93f81a43480e33a338f19163a3d10a50c01dcd59" 362 | integrity sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw== 363 | 364 | axobject-query@^4.1.0: 365 | version "4.1.0" 366 | resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-4.1.0.tgz#28768c76d0e3cff21bc62a9e2d0b6ac30042a1ee" 367 | integrity sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ== 368 | 369 | base64-js@^1.3.1: 370 | version "1.5.1" 371 | resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" 372 | integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== 373 | 374 | bootstrap@^5.3.8: 375 | version "5.3.8" 376 | resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.3.8.tgz#6401a10057a22752d21f4e19055508980656aeed" 377 | integrity sha512-HP1SZDqaLDPwsNiqRqi5NcP0SSXciX2s9E+RyqJIIqGo+vJeN5AJVM98CXmW/Wux0nQ5L7jeWUdplCEf0Ee+tg== 378 | 379 | buffer@^6.0.3: 380 | version "6.0.3" 381 | resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" 382 | integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== 383 | dependencies: 384 | base64-js "^1.3.1" 385 | ieee754 "^1.2.1" 386 | 387 | bundle-name@^4.1.0: 388 | version "4.1.0" 389 | resolved "https://registry.yarnpkg.com/bundle-name/-/bundle-name-4.1.0.tgz#f3b96b34160d6431a19d7688135af7cfb8797889" 390 | integrity sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q== 391 | dependencies: 392 | run-applescript "^7.0.0" 393 | 394 | chokidar@^4.0.1: 395 | version "4.0.3" 396 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-4.0.3.tgz#7be37a4c03c9aee1ecfe862a4a23b2c70c205d30" 397 | integrity sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA== 398 | dependencies: 399 | readdirp "^4.0.1" 400 | 401 | clsx@^2.1.1: 402 | version "2.1.1" 403 | resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999" 404 | integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== 405 | 406 | color-loggers@^0.3.2: 407 | version "0.3.2" 408 | resolved "https://registry.yarnpkg.com/color-loggers/-/color-loggers-0.3.2.tgz#04b12224f4ef3f78c1bdfb238f2cee50f72d7e51" 409 | integrity sha512-asfXyY1/9N+Cxt30jb0PFy5tccybuMnWVc9J8EJuYoJVlcsUshn+pt2QuyUB3BWKMXVvEH8jgLrCFs11Am8QZA== 410 | 411 | cookie@^0.6.0: 412 | version "0.6.0" 413 | resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" 414 | integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== 415 | 416 | crypto-random-string@^4.0.0: 417 | version "4.0.0" 418 | resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-4.0.0.tgz#5a3cc53d7dd86183df5da0312816ceeeb5bb1fc2" 419 | integrity sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA== 420 | dependencies: 421 | type-fest "^1.0.1" 422 | 423 | debug@^4.4.1: 424 | version "4.4.1" 425 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.1.tgz#e5a8bc6cbc4c6cd3e64308b0693a3d4fa550189b" 426 | integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ== 427 | dependencies: 428 | ms "^2.1.3" 429 | 430 | deepmerge@^4.3.1: 431 | version "4.3.1" 432 | resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" 433 | integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== 434 | 435 | default-browser-id@^5.0.0: 436 | version "5.0.0" 437 | resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-5.0.0.tgz#a1d98bf960c15082d8a3fa69e83150ccccc3af26" 438 | integrity sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA== 439 | 440 | default-browser@^5.2.1: 441 | version "5.2.1" 442 | resolved "https://registry.yarnpkg.com/default-browser/-/default-browser-5.2.1.tgz#7b7ba61204ff3e425b556869ae6d3e9d9f1712cf" 443 | integrity sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg== 444 | dependencies: 445 | bundle-name "^4.1.0" 446 | default-browser-id "^5.0.0" 447 | 448 | define-lazy-prop@^3.0.0: 449 | version "3.0.0" 450 | resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" 451 | integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== 452 | 453 | devalue@^5.3.2: 454 | version "5.3.2" 455 | resolved "https://registry.yarnpkg.com/devalue/-/devalue-5.3.2.tgz#1d9a00f0d126a2f768589f236da8b67d6988d285" 456 | integrity sha512-UDsjUbpQn9kvm68slnrs+mfxwFkIflOhkanmyabZ8zOYk8SMEIbJ3TK+88g70hSIeytu4y18f0z/hYHMTrXIWw== 457 | 458 | esbuild@^0.25.0: 459 | version "0.25.2" 460 | resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.25.2.tgz#55a1d9ebcb3aa2f95e8bba9e900c1a5061bc168b" 461 | integrity sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ== 462 | optionalDependencies: 463 | "@esbuild/aix-ppc64" "0.25.2" 464 | "@esbuild/android-arm" "0.25.2" 465 | "@esbuild/android-arm64" "0.25.2" 466 | "@esbuild/android-x64" "0.25.2" 467 | "@esbuild/darwin-arm64" "0.25.2" 468 | "@esbuild/darwin-x64" "0.25.2" 469 | "@esbuild/freebsd-arm64" "0.25.2" 470 | "@esbuild/freebsd-x64" "0.25.2" 471 | "@esbuild/linux-arm" "0.25.2" 472 | "@esbuild/linux-arm64" "0.25.2" 473 | "@esbuild/linux-ia32" "0.25.2" 474 | "@esbuild/linux-loong64" "0.25.2" 475 | "@esbuild/linux-mips64el" "0.25.2" 476 | "@esbuild/linux-ppc64" "0.25.2" 477 | "@esbuild/linux-riscv64" "0.25.2" 478 | "@esbuild/linux-s390x" "0.25.2" 479 | "@esbuild/linux-x64" "0.25.2" 480 | "@esbuild/netbsd-arm64" "0.25.2" 481 | "@esbuild/netbsd-x64" "0.25.2" 482 | "@esbuild/openbsd-arm64" "0.25.2" 483 | "@esbuild/openbsd-x64" "0.25.2" 484 | "@esbuild/sunos-x64" "0.25.2" 485 | "@esbuild/win32-arm64" "0.25.2" 486 | "@esbuild/win32-ia32" "0.25.2" 487 | "@esbuild/win32-x64" "0.25.2" 488 | 489 | esm-env@^1.2.1, esm-env@^1.2.2: 490 | version "1.2.2" 491 | resolved "https://registry.yarnpkg.com/esm-env/-/esm-env-1.2.2.tgz#263c9455c55861f41618df31b20cb571fc20b75e" 492 | integrity sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA== 493 | 494 | esrap@^2.1.0: 495 | version "2.1.0" 496 | resolved "https://registry.yarnpkg.com/esrap/-/esrap-2.1.0.tgz#70df8f20129df3ad82f20e306dc4000dd5947813" 497 | integrity sha512-yzmPNpl7TBbMRC5Lj2JlJZNPml0tzqoqP5B1JXycNUwtqma9AKCO0M2wHrdgsHcy1WRW7S9rJknAMtByg3usgA== 498 | dependencies: 499 | "@jridgewell/sourcemap-codec" "^1.4.15" 500 | 501 | event-target-shim@^5.0.0: 502 | version "5.0.1" 503 | resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" 504 | integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== 505 | 506 | events@^3.3.0: 507 | version "3.3.0" 508 | resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" 509 | integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== 510 | 511 | fdir@^6.2.0, fdir@^6.5.0: 512 | version "6.5.0" 513 | resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.5.0.tgz#ed2ab967a331ade62f18d077dae192684d50d350" 514 | integrity sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg== 515 | 516 | file-type@^18.7.0: 517 | version "18.7.0" 518 | resolved "https://registry.yarnpkg.com/file-type/-/file-type-18.7.0.tgz#cddb16f184d6b94106cfc4bb56978726b25cb2a2" 519 | integrity sha512-ihHtXRzXEziMrQ56VSgU7wkxh55iNchFkosu7Y9/S+tXHdKyrGjVK0ujbqNnsxzea+78MaLhN6PGmfYSAv1ACw== 520 | dependencies: 521 | readable-web-to-node-stream "^3.0.2" 522 | strtok3 "^7.0.0" 523 | token-types "^5.0.1" 524 | 525 | fsevents@~2.3.2, fsevents@~2.3.3: 526 | version "2.3.3" 527 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" 528 | integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== 529 | 530 | get-stdin@^9.0.0: 531 | version "9.0.0" 532 | resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-9.0.0.tgz#3983ff82e03d56f1b2ea0d3e60325f39d703a575" 533 | integrity sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA== 534 | 535 | globals@^16.4.0: 536 | version "16.4.0" 537 | resolved "https://registry.yarnpkg.com/globals/-/globals-16.4.0.tgz#574bc7e72993d40cf27cf6c241f324ee77808e51" 538 | integrity sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw== 539 | 540 | ieee754@^1.2.1: 541 | version "1.2.1" 542 | resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" 543 | integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== 544 | 545 | is-docker@^3.0.0: 546 | version "3.0.0" 547 | resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-3.0.0.tgz#90093aa3106277d8a77a5910dbae71747e15a200" 548 | integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ== 549 | 550 | is-inside-container@^1.0.0: 551 | version "1.0.0" 552 | resolved "https://registry.yarnpkg.com/is-inside-container/-/is-inside-container-1.0.0.tgz#e81fba699662eb31dbdaf26766a61d4814717ea4" 553 | integrity sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA== 554 | dependencies: 555 | is-docker "^3.0.0" 556 | 557 | is-reference@^3.0.3: 558 | version "3.0.3" 559 | resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-3.0.3.tgz#9ef7bf9029c70a67b2152da4adf57c23d718910f" 560 | integrity sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw== 561 | dependencies: 562 | "@types/estree" "^1.0.6" 563 | 564 | is-stream@^3.0.0: 565 | version "3.0.0" 566 | resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" 567 | integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== 568 | 569 | is-wsl@^3.1.0: 570 | version "3.1.0" 571 | resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-3.1.0.tgz#e1c657e39c10090afcbedec61720f6b924c3cbd2" 572 | integrity sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw== 573 | dependencies: 574 | is-inside-container "^1.0.0" 575 | 576 | kleur@^4.1.5: 577 | version "4.1.5" 578 | resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.5.tgz#95106101795f7050c6c650f350c683febddb1780" 579 | integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ== 580 | 581 | locate-character@^3.0.0: 582 | version "3.0.0" 583 | resolved "https://registry.yarnpkg.com/locate-character/-/locate-character-3.0.0.tgz#0305c5b8744f61028ef5d01f444009e00779f974" 584 | integrity sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA== 585 | 586 | magic-string@^0.30.11, magic-string@^0.30.17, magic-string@^0.30.5: 587 | version "0.30.17" 588 | resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.17.tgz#450a449673d2460e5bbcfba9a61916a1714c7453" 589 | integrity sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA== 590 | dependencies: 591 | "@jridgewell/sourcemap-codec" "^1.5.0" 592 | 593 | meow@^12.1.1: 594 | version "12.1.1" 595 | resolved "https://registry.yarnpkg.com/meow/-/meow-12.1.1.tgz#e558dddbab12477b69b2e9a2728c327f191bace6" 596 | integrity sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw== 597 | 598 | mri@^1.1.0: 599 | version "1.2.0" 600 | resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b" 601 | integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA== 602 | 603 | mrmime@^2.0.0: 604 | version "2.0.1" 605 | resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-2.0.1.tgz#bc3e87f7987853a54c9850eeb1f1078cd44adddc" 606 | integrity sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ== 607 | 608 | ms@^2.1.3: 609 | version "2.1.3" 610 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" 611 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== 612 | 613 | nanoid@^3.3.11: 614 | version "3.3.11" 615 | resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b" 616 | integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== 617 | 618 | open-cli@^8.0.0: 619 | version "8.0.0" 620 | resolved "https://registry.yarnpkg.com/open-cli/-/open-cli-8.0.0.tgz#077d11bd5f1247895028d41ab3ea74c3d63e6c02" 621 | integrity sha512-3muD3BbfLyzl+aMVSEfn2FfOqGdPYR0O4KNnxXsLEPE2q9OSjBfJAaB6XKbrUzLgymoSMejvb5jpXJfru/Ko2A== 622 | dependencies: 623 | file-type "^18.7.0" 624 | get-stdin "^9.0.0" 625 | meow "^12.1.1" 626 | open "^10.0.0" 627 | tempy "^3.1.0" 628 | 629 | open@^10.0.0: 630 | version "10.1.0" 631 | resolved "https://registry.yarnpkg.com/open/-/open-10.1.0.tgz#a7795e6e5d519abe4286d9937bb24b51122598e1" 632 | integrity sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw== 633 | dependencies: 634 | default-browser "^5.2.1" 635 | define-lazy-prop "^3.0.0" 636 | is-inside-container "^1.0.0" 637 | is-wsl "^3.1.0" 638 | 639 | peek-readable@^5.1.3: 640 | version "5.4.2" 641 | resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-5.4.2.tgz#aff1e1ba27a7d6911ddb103f35252ffc1787af49" 642 | integrity sha512-peBp3qZyuS6cNIJ2akRNG1uo1WJ1d0wTxg/fxMdZ0BqCVhx242bSFHM9eNqflfJVS9SsgkzgT/1UgnsurBOTMg== 643 | 644 | picocolors@^1.0.0, picocolors@^1.1.1: 645 | version "1.1.1" 646 | resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" 647 | integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== 648 | 649 | picomatch@^4.0.2, picomatch@^4.0.3: 650 | version "4.0.2" 651 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.2.tgz#77c742931e8f3b8820946c76cd0c1f13730d1dab" 652 | integrity sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg== 653 | 654 | postcss@^8.5.6: 655 | version "8.5.6" 656 | resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.6.tgz#2825006615a619b4f62a9e7426cc120b349a8f3c" 657 | integrity sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg== 658 | dependencies: 659 | nanoid "^3.3.11" 660 | picocolors "^1.1.1" 661 | source-map-js "^1.2.1" 662 | 663 | process@^0.11.10: 664 | version "0.11.10" 665 | resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" 666 | integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== 667 | 668 | readable-stream@^4.7.0: 669 | version "4.7.0" 670 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-4.7.0.tgz#cedbd8a1146c13dfff8dab14068028d58c15ac91" 671 | integrity sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg== 672 | dependencies: 673 | abort-controller "^3.0.0" 674 | buffer "^6.0.3" 675 | events "^3.3.0" 676 | process "^0.11.10" 677 | string_decoder "^1.3.0" 678 | 679 | readable-web-to-node-stream@^3.0.2: 680 | version "3.0.4" 681 | resolved "https://registry.yarnpkg.com/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.4.tgz#392ba37707af5bf62d725c36c1b5d6ef4119eefc" 682 | integrity sha512-9nX56alTf5bwXQ3ZDipHJhusu9NTQJ/CVPtb/XHAJCXihZeitfJvIRS4GqQ/mfIoOE3IelHMrpayVrosdHBuLw== 683 | dependencies: 684 | readable-stream "^4.7.0" 685 | 686 | readdirp@^4.0.1: 687 | version "4.1.2" 688 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-4.1.2.tgz#eb85801435fbf2a7ee58f19e0921b068fc69948d" 689 | integrity sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg== 690 | 691 | rollup@^4.43.0: 692 | version "4.46.2" 693 | resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.46.2.tgz#09b1a45d811e26d09bed63dc3ecfb6831c16ce32" 694 | integrity sha512-WMmLFI+Boh6xbop+OAGo9cQ3OgX9MIg7xOQjn+pTCwOkk+FNDAeAemXkJ3HzDJrVXleLOFVa1ipuc1AmEx1Dwg== 695 | dependencies: 696 | "@types/estree" "1.0.8" 697 | optionalDependencies: 698 | "@rollup/rollup-android-arm-eabi" "4.46.2" 699 | "@rollup/rollup-android-arm64" "4.46.2" 700 | "@rollup/rollup-darwin-arm64" "4.46.2" 701 | "@rollup/rollup-darwin-x64" "4.46.2" 702 | "@rollup/rollup-freebsd-arm64" "4.46.2" 703 | "@rollup/rollup-freebsd-x64" "4.46.2" 704 | "@rollup/rollup-linux-arm-gnueabihf" "4.46.2" 705 | "@rollup/rollup-linux-arm-musleabihf" "4.46.2" 706 | "@rollup/rollup-linux-arm64-gnu" "4.46.2" 707 | "@rollup/rollup-linux-arm64-musl" "4.46.2" 708 | "@rollup/rollup-linux-loongarch64-gnu" "4.46.2" 709 | "@rollup/rollup-linux-ppc64-gnu" "4.46.2" 710 | "@rollup/rollup-linux-riscv64-gnu" "4.46.2" 711 | "@rollup/rollup-linux-riscv64-musl" "4.46.2" 712 | "@rollup/rollup-linux-s390x-gnu" "4.46.2" 713 | "@rollup/rollup-linux-x64-gnu" "4.46.2" 714 | "@rollup/rollup-linux-x64-musl" "4.46.2" 715 | "@rollup/rollup-win32-arm64-msvc" "4.46.2" 716 | "@rollup/rollup-win32-ia32-msvc" "4.46.2" 717 | "@rollup/rollup-win32-x64-msvc" "4.46.2" 718 | fsevents "~2.3.2" 719 | 720 | run-applescript@^7.0.0: 721 | version "7.0.0" 722 | resolved "https://registry.yarnpkg.com/run-applescript/-/run-applescript-7.0.0.tgz#e5a553c2bffd620e169d276c1cd8f1b64778fbeb" 723 | integrity sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A== 724 | 725 | sade@^1.7.4, sade@^1.8.1: 726 | version "1.8.1" 727 | resolved "https://registry.yarnpkg.com/sade/-/sade-1.8.1.tgz#0a78e81d658d394887be57d2a409bf703a3b2701" 728 | integrity sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A== 729 | dependencies: 730 | mri "^1.1.0" 731 | 732 | safe-buffer@~5.2.0: 733 | version "5.2.1" 734 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 735 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 736 | 737 | set-cookie-parser@^2.6.0: 738 | version "2.7.1" 739 | resolved "https://registry.yarnpkg.com/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz#3016f150072202dfbe90fadee053573cc89d2943" 740 | integrity sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ== 741 | 742 | sirv@^3.0.0: 743 | version "3.0.1" 744 | resolved "https://registry.yarnpkg.com/sirv/-/sirv-3.0.1.tgz#32a844794655b727f9e2867b777e0060fbe07bf3" 745 | integrity sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A== 746 | dependencies: 747 | "@polka/url" "^1.0.0-next.24" 748 | mrmime "^2.0.0" 749 | totalist "^3.0.0" 750 | 751 | source-map-js@^1.2.1: 752 | version "1.2.1" 753 | resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" 754 | integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== 755 | 756 | string_decoder@^1.3.0: 757 | version "1.3.0" 758 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" 759 | integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== 760 | dependencies: 761 | safe-buffer "~5.2.0" 762 | 763 | strtok3@^7.0.0: 764 | version "7.1.1" 765 | resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-7.1.1.tgz#f548fd9dc59d0a76d5567ff8c16be31221f29dfc" 766 | integrity sha512-mKX8HA/cdBqMKUr0MMZAFssCkIGoZeSCMXgnt79yKxNFguMLVFgRe6wB+fsL0NmoHDbeyZXczy7vEPSoo3rkzg== 767 | dependencies: 768 | "@tokenizer/token" "^0.3.0" 769 | peek-readable "^5.1.3" 770 | 771 | svelte-check@^4.3.1: 772 | version "4.3.1" 773 | resolved "https://registry.yarnpkg.com/svelte-check/-/svelte-check-4.3.1.tgz#7b469e8156e5600da2c762e71bbceace2b19d4c8" 774 | integrity sha512-lkh8gff5gpHLjxIV+IaApMxQhTGnir2pNUAqcNgeKkvK5bT/30Ey/nzBxNLDlkztCH4dP7PixkMt9SWEKFPBWg== 775 | dependencies: 776 | "@jridgewell/trace-mapping" "^0.3.25" 777 | chokidar "^4.0.1" 778 | fdir "^6.2.0" 779 | picocolors "^1.0.0" 780 | sade "^1.7.4" 781 | 782 | svelte-preprocess@^6.0.3: 783 | version "6.0.3" 784 | resolved "https://registry.yarnpkg.com/svelte-preprocess/-/svelte-preprocess-6.0.3.tgz#fdc1f9dc41b6f22bf8b1f059e9f21eaaae181eeb" 785 | integrity sha512-PLG2k05qHdhmRG7zR/dyo5qKvakhm8IJ+hD2eFRQmMLHp7X3eJnjeupUtvuRpbNiF31RjVw45W+abDwHEmP5OA== 786 | 787 | svelte@^5.39.4: 788 | version "5.39.4" 789 | resolved "https://registry.yarnpkg.com/svelte/-/svelte-5.39.4.tgz#e17ce368279337e181e0c7de2d8af39d923884c6" 790 | integrity sha512-VU729KzEau1l6d6d25EnRQhdkwwYdTQxQrF8gdUfjZ3dCjrG7VmRMylMxx92ayO9/z5PKWpDrShJdzc4PGW1uA== 791 | dependencies: 792 | "@jridgewell/remapping" "^2.3.4" 793 | "@jridgewell/sourcemap-codec" "^1.5.0" 794 | "@sveltejs/acorn-typescript" "^1.0.5" 795 | "@types/estree" "^1.0.5" 796 | acorn "^8.12.1" 797 | aria-query "^5.3.1" 798 | axobject-query "^4.1.0" 799 | clsx "^2.1.1" 800 | esm-env "^1.2.1" 801 | esrap "^2.1.0" 802 | is-reference "^3.0.3" 803 | locate-character "^3.0.0" 804 | magic-string "^0.30.11" 805 | zimmerframe "^1.1.2" 806 | 807 | temp-dir@^3.0.0: 808 | version "3.0.0" 809 | resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-3.0.0.tgz#7f147b42ee41234cc6ba3138cd8e8aa2302acffa" 810 | integrity sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw== 811 | 812 | tempy@^3.1.0: 813 | version "3.1.0" 814 | resolved "https://registry.yarnpkg.com/tempy/-/tempy-3.1.0.tgz#00958b6df85db8589cb595465e691852aac038e9" 815 | integrity sha512-7jDLIdD2Zp0bDe5r3D2qtkd1QOCacylBuL7oa4udvN6v2pqr4+LcCr67C8DR1zkpaZ8XosF5m1yQSabKAW6f2g== 816 | dependencies: 817 | is-stream "^3.0.0" 818 | temp-dir "^3.0.0" 819 | type-fest "^2.12.2" 820 | unique-string "^3.0.0" 821 | 822 | tinyglobby@^0.2.15: 823 | version "0.2.15" 824 | resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.15.tgz#e228dd1e638cea993d2fdb4fcd2d4602a79951c2" 825 | integrity sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ== 826 | dependencies: 827 | fdir "^6.5.0" 828 | picomatch "^4.0.3" 829 | 830 | token-types@^5.0.1: 831 | version "5.0.1" 832 | resolved "https://registry.yarnpkg.com/token-types/-/token-types-5.0.1.tgz#aa9d9e6b23c420a675e55413b180635b86a093b4" 833 | integrity sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg== 834 | dependencies: 835 | "@tokenizer/token" "^0.3.0" 836 | ieee754 "^1.2.1" 837 | 838 | totalist@^3.0.0: 839 | version "3.0.1" 840 | resolved "https://registry.yarnpkg.com/totalist/-/totalist-3.0.1.tgz#ba3a3d600c915b1a97872348f79c127475f6acf8" 841 | integrity sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ== 842 | 843 | type-fest@^1.0.1: 844 | version "1.4.0" 845 | resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1" 846 | integrity sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA== 847 | 848 | type-fest@^2.12.2: 849 | version "2.19.0" 850 | resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" 851 | integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== 852 | 853 | typescript@^5.9.2: 854 | version "5.9.2" 855 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.2.tgz#d93450cddec5154a2d5cabe3b8102b83316fb2a6" 856 | integrity sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A== 857 | 858 | unique-string@^3.0.0: 859 | version "3.0.0" 860 | resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-3.0.0.tgz#84a1c377aff5fd7a8bc6b55d8244b2bd90d75b9a" 861 | integrity sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ== 862 | dependencies: 863 | crypto-random-string "^4.0.0" 864 | 865 | vite@^7.1.6: 866 | version "7.1.6" 867 | resolved "https://registry.yarnpkg.com/vite/-/vite-7.1.6.tgz#336806d29983135677f498a05efb0fd46c5eef2d" 868 | integrity sha512-SRYIB8t/isTwNn8vMB3MR6E+EQZM/WG1aKmmIUCfDXfVvKfc20ZpamngWHKzAmmu9ppsgxsg4b2I7c90JZudIQ== 869 | dependencies: 870 | esbuild "^0.25.0" 871 | fdir "^6.5.0" 872 | picomatch "^4.0.3" 873 | postcss "^8.5.6" 874 | rollup "^4.43.0" 875 | tinyglobby "^0.2.15" 876 | optionalDependencies: 877 | fsevents "~2.3.3" 878 | 879 | vitefu@^1.1.1: 880 | version "1.1.1" 881 | resolved "https://registry.yarnpkg.com/vitefu/-/vitefu-1.1.1.tgz#c39b7e4c91bf2f6c590fb96e0758f394dff5795b" 882 | integrity sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ== 883 | 884 | yarn-upgrade-all@^0.7.5: 885 | version "0.7.5" 886 | resolved "https://registry.yarnpkg.com/yarn-upgrade-all/-/yarn-upgrade-all-0.7.5.tgz#dc0a8335234298a6d548d0956d78c45471aa34e8" 887 | integrity sha512-yC2DgKX2Vzeb4LznSHukF/U5AapE7i/A4cBoh8P2FsEy1RBPaXEdd320ZK5Phgj6/Y/1pmFkP36S7GxS0YrzCg== 888 | dependencies: 889 | color-loggers "^0.3.2" 890 | 891 | zimmerframe@^1.1.2: 892 | version "1.1.2" 893 | resolved "https://registry.yarnpkg.com/zimmerframe/-/zimmerframe-1.1.2.tgz#5b75f1fa83b07ae2a428d51e50f58e2ae6855e5e" 894 | integrity sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w== 895 | --------------------------------------------------------------------------------