├── .browserslistrc ├── .eslintrc.js ├── .gitignore ├── .yarnrc.yml ├── LICENSE ├── README.md ├── env.d.ts ├── index.html ├── package-lock.json ├── package.json ├── public ├── favicon.ico ├── fonts │ ├── hack-bold.woff │ ├── hack-bold.woff2 │ ├── hack-regular.woff │ └── hack-regular.woff2 ├── packages.crvx.fr.gpg ├── raphael@crvx.fr.gpg ├── robots.txt └── social_icon.jpg ├── scripts └── gh-pages-deploy.js ├── src ├── App.vue ├── assets │ ├── avatar.webp │ ├── error.gif │ ├── fork-banner.png │ └── main.css ├── components │ └── ReturnLink.vue ├── config.ts ├── main.ts ├── router │ └── index.ts ├── types.d.ts └── views │ ├── ArticlesView.vue │ ├── ContactView.vue │ ├── FilmmakingView.vue │ ├── HomeView.vue │ ├── LinksView.vue │ ├── NotFound.vue │ ├── SponsorsView.vue │ └── WorkView.vue ├── tsconfig.app.json ├── tsconfig.json ├── tsconfig.node.json ├── tsconfig.node.tsbuildinfo ├── tsconfig.vitest.json ├── vercel.json ├── vite.config.ts └── vitest.config.ts /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | extends: [ 7 | "plugin:vue/essential", 8 | "eslint:recommended", 9 | "@vue/typescript/recommended", 10 | "@vue/prettier", 11 | "@vue/prettier/@typescript-eslint" 12 | ], 13 | parserOptions: { 14 | ecmaVersion: 2020 15 | }, 16 | rules: { 17 | "no-console": process.env.NODE_ENV === "production" ? "error" : "off", 18 | "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off" 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | nodeLinker: node-modules 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. All rights reserved. 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # website 2 | 3 | 2019 version of my personal website. 4 | 5 | ## Project Setup 6 | 7 | ```sh 8 | npm install 9 | ``` 10 | 11 | ### Compile and Hot-Reload for Development 12 | 13 | ```sh 14 | npm run dev 15 | ``` 16 | 17 | ### Type-Check, Compile and Minify for Production 18 | 19 | ```sh 20 | npm run build 21 | ``` 22 | 23 | ### Run Unit Tests with [Vitest](https://vitest.dev/) 24 | 25 | ```sh 26 | npm run test:unit 27 | ``` 28 | 29 | ### Lint with [ESLint](https://eslint.org/) 30 | 31 | ```sh 32 | npm run lint 33 | ``` 34 | -------------------------------------------------------------------------------- /env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | Raphaël Cerveaux, Software Engineer 11 | 12 | 16 | 20 | 24 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "website", 3 | "version": "0.0.0", 4 | "private": true, 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "run-p type-check \"build-only {@}\" --", 9 | "preview": "vite preview", 10 | "test:unit": "vitest", 11 | "build-only": "vite build", 12 | "type-check": "vue-tsc --build --force", 13 | "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore", 14 | "format": "prettier --write src/", 15 | "deploy": "node ./scripts/gh-pages-deploy.js" 16 | }, 17 | "dependencies": { 18 | "@vercel/analytics": "1.2.2", 19 | "vue": "3.3.11", 20 | "vue-router": "4.2.5" 21 | }, 22 | "devDependencies": { 23 | "@rushstack/eslint-patch": "1.3.3", 24 | "@tsconfig/node18": "18.2.2", 25 | "@types/jsdom": "21.1.6", 26 | "@types/node": "18.19.3", 27 | "@vitejs/plugin-vue": "4.5.2", 28 | "@vue/eslint-config-prettier": "8.0.0", 29 | "@vue/eslint-config-typescript": "12.0.0", 30 | "@vue/test-utils": "2.4.3", 31 | "@vue/tsconfig": "0.5.0", 32 | "eslint": "8.49.0", 33 | "eslint-plugin-vue": "9.17.0", 34 | "execa": "8.0.1", 35 | "jsdom": "23.0.1", 36 | "npm-run-all2": "6.1.1", 37 | "prettier": "3.0.3", 38 | "typescript": "~5.3.0", 39 | "vite": "5.1.5", 40 | "vitest": "1.0.4", 41 | "vue-tsc": "1.8.25" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sundowndev/website/0e32a464936a6ecd74075acb17049ed3c7fcacdb/public/favicon.ico -------------------------------------------------------------------------------- /public/fonts/hack-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sundowndev/website/0e32a464936a6ecd74075acb17049ed3c7fcacdb/public/fonts/hack-bold.woff -------------------------------------------------------------------------------- /public/fonts/hack-bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sundowndev/website/0e32a464936a6ecd74075acb17049ed3c7fcacdb/public/fonts/hack-bold.woff2 -------------------------------------------------------------------------------- /public/fonts/hack-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sundowndev/website/0e32a464936a6ecd74075acb17049ed3c7fcacdb/public/fonts/hack-regular.woff -------------------------------------------------------------------------------- /public/fonts/hack-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sundowndev/website/0e32a464936a6ecd74075acb17049ed3c7fcacdb/public/fonts/hack-regular.woff2 -------------------------------------------------------------------------------- /public/packages.crvx.fr.gpg: -------------------------------------------------------------------------------- 1 | -----BEGIN PGP PUBLIC KEY BLOCK----- 2 | 3 | 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 52 | =5Hq2 53 | -----END PGP PUBLIC KEY BLOCK----- 54 | -------------------------------------------------------------------------------- /public/raphael@crvx.fr.gpg: -------------------------------------------------------------------------------- 1 | -----BEGIN PGP PUBLIC KEY BLOCK----- 2 | Version: OpenPGP.js v4.10.10 3 | Comment: https://openpgpjs.org 4 | 5 | xjMEYa85WBYJKwYBBAHaRw8BAQdAfA1LnmElb1FlYCnWkgORMbDE1pNz8kpy 6 | diP6yB24D8XNIXJhcGhhZWxAY3J2eC5mciA8cmFwaGFlbEBjcnZ4LmZyPsKP 7 | BBAWCgAgBQJhrzlYBgsJBwgDAgQVCAoCBBYCAQACGQECGwMCHgEAIQkQEAzi 8 | eZ2XhGIWIQTmh4WnswF0N2z0ZukQDOJ5nZeEYqJIAQDPSOpAxurnHThMRDg6 9 | hTiFb6ifGuJbRMBqjuVJJB7s6gEA4lrocS1eCLOcxwK8pKsT7n5Qm3Ze66q/ 10 | zAQ9sQIUYwHOOARhrzlYEgorBgEEAZdVAQUBAQdAue52rJFfw7+QsGvN/T4G 11 | t/ckS4WfSmMXh+GpmCrfe2EDAQgHwngEGBYIAAkFAmGvOVgCGwwAIQkQEAzi 12 | eZ2XhGIWIQTmh4WnswF0N2z0ZukQDOJ5nZeEYpacAQC/R34PHFAugKnieqMe 13 | E/U0/HLfNmPOJTag2O3yNsckpQEArrDRJvQRjZhfCBSPeEsmWsDqB+8mpGWa 14 | QfXb7xjogwQ= 15 | =+UKQ 16 | -----END PGP PUBLIC KEY BLOCK----- 17 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: /publickey.asc 3 | -------------------------------------------------------------------------------- /public/social_icon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sundowndev/website/0e32a464936a6ecd74075acb17049ed3c7fcacdb/public/social_icon.jpg -------------------------------------------------------------------------------- /scripts/gh-pages-deploy.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | import { execa } from 'execa' 3 | import fs from 'fs' 4 | 5 | const baseBranch = 'master'; 6 | const targetBranch = 'gh-pages'; 7 | 8 | (async () => { 9 | try { 10 | await execa("git", ["checkout", "--orphan", targetBranch]); 11 | // eslint-disable-next-line no-console 12 | console.log("Building started..."); 13 | await execa("npm", ["run", "build"]); 14 | // Understand if it's dist or build folder 15 | const folderName = fs.existsSync("dist") ? "dist" : "build"; 16 | await execa("git", ["--work-tree", folderName, "add", "--all"]); 17 | await execa("git", ["--work-tree", folderName, "commit", "-m", targetBranch]); 18 | console.log(`Pushing to ${targetBranch}...`); 19 | await execa("git", ["push", "origin", "HEAD:gh-pages", "--force"]); 20 | await execa("rm", ["-r", folderName]); 21 | await execa("git", ["checkout", "-f", baseBranch]); 22 | await execa("git", ["branch", "-D", targetBranch]); 23 | console.log("Successfully deployed, check your settings"); 24 | } catch (e) { 25 | // eslint-disable-next-line no-console 26 | console.log(e.message); 27 | process.exit(1); 28 | } 29 | })(); 30 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 36 | 37 | 56 | 57 | 76 | -------------------------------------------------------------------------------- /src/assets/avatar.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sundowndev/website/0e32a464936a6ecd74075acb17049ed3c7fcacdb/src/assets/avatar.webp -------------------------------------------------------------------------------- /src/assets/error.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sundowndev/website/0e32a464936a6ecd74075acb17049ed3c7fcacdb/src/assets/error.gif -------------------------------------------------------------------------------- /src/assets/fork-banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sundowndev/website/0e32a464936a6ecd74075acb17049ed3c7fcacdb/src/assets/fork-banner.png -------------------------------------------------------------------------------- /src/assets/main.css: -------------------------------------------------------------------------------- 1 | .fade-enter-active, 2 | .fade-leave-active { 3 | transition: opacity 0.5s ease; 4 | } 5 | .fade-enter, 6 | .fade-leave-active { 7 | opacity: 0; 8 | } 9 | 10 | /* Reset style */ 11 | html, 12 | body, 13 | div, 14 | span, 15 | applet, 16 | object, 17 | iframe, 18 | h1, 19 | h2, 20 | h3, 21 | h4, 22 | h5, 23 | h6, 24 | p, 25 | blockquote, 26 | pre, 27 | a, 28 | abbr, 29 | acronym, 30 | address, 31 | big, 32 | cite, 33 | code, 34 | del, 35 | dfn, 36 | em, 37 | img, 38 | ins, 39 | kbd, 40 | q, 41 | s, 42 | samp, 43 | small, 44 | strike, 45 | strong, 46 | sub, 47 | sup, 48 | tt, 49 | var, 50 | b, 51 | u, 52 | i, 53 | center, 54 | dl, 55 | dt, 56 | dd, 57 | ol, 58 | ul, 59 | li, 60 | fieldset, 61 | form, 62 | label, 63 | legend, 64 | table, 65 | caption, 66 | tbody, 67 | tfoot, 68 | thead, 69 | tr, 70 | th, 71 | td, 72 | article, 73 | aside, 74 | canvas, 75 | details, 76 | embed, 77 | figure, 78 | figcaption, 79 | footer, 80 | header, 81 | hgroup, 82 | menu, 83 | nav, 84 | output, 85 | ruby, 86 | section, 87 | summary, 88 | time, 89 | mark, 90 | audio, 91 | video { 92 | margin: 0; 93 | padding: 0; 94 | border: 0; 95 | font-size: 100%; 96 | font: inherit; 97 | vertical-align: baseline; 98 | } 99 | 100 | /* HTML5 display-role reset for older browsers */ 101 | article, 102 | aside, 103 | details, 104 | figcaption, 105 | figure, 106 | footer, 107 | header, 108 | hgroup, 109 | menu, 110 | nav, 111 | section { 112 | display: block; 113 | } 114 | 115 | body { 116 | line-height: 1; 117 | } 118 | 119 | ol, 120 | ul { 121 | list-style: none; 122 | } 123 | 124 | blockquote, 125 | q { 126 | quotes: none; 127 | } 128 | 129 | blockquote:before, 130 | blockquote:after { 131 | content: ""; 132 | content: none; 133 | } 134 | 135 | q:before, 136 | q:after { 137 | content: ""; 138 | content: none; 139 | } 140 | 141 | table { 142 | border-collapse: collapse; 143 | border-spacing: 0; 144 | } 145 | 146 | /* FONT PATHS */ 147 | @font-face { 148 | font-family: "Hack"; 149 | src: 150 | url("/fonts/hack-regular.woff2") format("woff2"), 151 | url("/fonts/hack-regular.woff") format("woff"); 152 | font-weight: 400; 153 | font-style: normal; 154 | } 155 | 156 | @font-face { 157 | font-family: "Hack"; 158 | src: 159 | url("/fonts/hack-bold.woff2") format("woff2"), 160 | url("/fonts/hack-bold.woff") format("woff"); 161 | font-weight: 700; 162 | font-style: normal; 163 | } 164 | 165 | /* Actual style */ 166 | #top-mode-btn { 167 | padding: 5px; 168 | font-size: 0.8em; 169 | cursor: pointer; 170 | display: inline-block; 171 | } 172 | 173 | body { 174 | font-family: Hack, monospace; 175 | background-color: #f5f5f5; 176 | color: #161616; 177 | } 178 | 179 | body.dark { 180 | background-color: #161616; 181 | color: #f5f5f5; 182 | } 183 | 184 | .margin-top { 185 | margin-top: 15px; 186 | } 187 | 188 | .margin-top-30 { 189 | margin-top: 30px; 190 | } 191 | 192 | .margin-bottom { 193 | margin-bottom: 15px; 194 | } 195 | 196 | .margin-bottom-30 { 197 | margin-bottom: 30px; 198 | } 199 | 200 | .text-center { 201 | text-align: center; 202 | } 203 | 204 | img { 205 | max-width: 100%; 206 | } 207 | 208 | .section img.avatar { 209 | border-radius: 130px; 210 | margin-bottom: 30px; 211 | filter: drop-shadow(0 0 0.75rem rgba(0, 0, 0, 0.1)); 212 | } 213 | 214 | body.dark .section img.avatar { 215 | filter: drop-shadow(0 0 0.75rem rgba(219, 196, 30, 0.1)) sepia(35%); 216 | } 217 | 218 | .container { 219 | z-index: 3; 220 | position: relative; 221 | } 222 | 223 | .container.main-content { 224 | width: 900px; 225 | margin: auto; 226 | min-height: 95vh; 227 | display: -webkit-box; 228 | display: -webkit-flex; 229 | display: -ms-flexbox; 230 | display: flex; 231 | -webkit-box-orient: vertical; 232 | -webkit-box-direction: normal; 233 | -webkit-flex-direction: column; 234 | -ms-flex-direction: column; 235 | flex-direction: column; 236 | -webkit-box-pack: center; 237 | -webkit-justify-content: center; 238 | -ms-flex-pack: center; 239 | justify-content: center; 240 | } 241 | 242 | @media (max-width: 900px) { 243 | .container { 244 | margin: 0 30px; 245 | } 246 | .container.main-content { 247 | width: 92%; 248 | min-height: 0; 249 | margin-top: 50px; 250 | margin-bottom: 50px; 251 | } 252 | .container.main-content .section { 253 | width: 100%; 254 | } 255 | #bottom-note { 256 | width: 100px; 257 | } 258 | } 259 | 260 | section { 261 | margin: auto; 262 | width: 100%; 263 | padding: 80px 0 80px 0; 264 | } 265 | 266 | section.active { 267 | display: block; 268 | } 269 | 270 | section h1 { 271 | font-size: 24px; 272 | font-weight: bold; 273 | padding: 15px 0; 274 | margin-bottom: 20px; 275 | } 276 | 277 | section h2 { 278 | font-size: 16px; 279 | font-weight: bold; 280 | margin-bottom: 20px; 281 | background: #393939; 282 | color: #ffffff; 283 | padding: 5px; 284 | width: max-content; 285 | } 286 | 287 | body.dark section h2 { 288 | background: #eee; 289 | color: #161616; 290 | } 291 | 292 | section h3, 293 | section ul.list li { 294 | font-size: 14px; 295 | font-weight: bold; 296 | margin-bottom: 20px; 297 | display: block; 298 | } 299 | 300 | section p { 301 | font-weight: 300; 302 | line-height: 32px; 303 | margin-bottom: 30px; 304 | } 305 | 306 | section .icon { 307 | font-size: 32px; 308 | } 309 | 310 | a { 311 | text-decoration: none; 312 | color: #000; 313 | padding-bottom: 3px; 314 | border-bottom: 2px solid #1616163b; 315 | -webkit-transition: 0.25s; 316 | transition: 0.25s; 317 | } 318 | 319 | body.dark a { 320 | color: #dbc41e; 321 | border-bottom: 2px solid rgba(219, 196, 30, 0.35); 322 | } 323 | 324 | a:hover { 325 | border-bottom: 2px solid #161616d2; 326 | } 327 | 328 | body.dark a:hover { 329 | border-bottom: 2px solid rgba(219, 196, 30, 0.9); 330 | } 331 | 332 | strong { 333 | font-weight: bold; 334 | } 335 | -------------------------------------------------------------------------------- /src/components/ReturnLink.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | -------------------------------------------------------------------------------- /src/config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | repository: "https://github.com/sundowndev/website", 3 | links: { 4 | social: { 5 | linkedin: "https://www.linkedin.com/in/thispersondoesnotexist/", 6 | medium: "https://medium.com/@SundownDEV", 7 | github: "https://github.com/sundowndev", 8 | gitlab: "https://gitlab.com/sundowndev1", 9 | }, 10 | }, 11 | }; 12 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import "./assets/main.css"; 2 | 3 | import { createApp } from "vue"; 4 | import App from "./App.vue"; 5 | import router from "./router"; 6 | import { inject } from "@vercel/analytics"; 7 | 8 | const app = createApp(App); 9 | 10 | app.use(router); 11 | 12 | app.mount("#app"); 13 | 14 | // Inject Vercel Analytics 15 | inject(); 16 | -------------------------------------------------------------------------------- /src/router/index.ts: -------------------------------------------------------------------------------- 1 | import { createRouter, createWebHistory } from "vue-router"; 2 | import HomeView from "../views/HomeView.vue"; 3 | import Articles from "@/views/ArticlesView.vue"; 4 | import Work from "@/views/WorkView.vue"; 5 | import Links from "@/views/LinksView.vue"; 6 | import NotFound from "@/views/NotFound.vue"; 7 | import Contact from "@/views/ContactView.vue"; 8 | import Sponsors from "@/views/SponsorsView.vue"; 9 | import Filmmaking from "@/views/FilmmakingView.vue"; 10 | 11 | const router = createRouter({ 12 | history: createWebHistory(import.meta.env.BASE_URL), 13 | routes: [ 14 | { path: "/", name: "home", component: HomeView }, 15 | { path: "/writeups", name: "articles", component: Articles }, 16 | { path: "/work", name: "work", component: Work }, 17 | { path: "/filmmaking", name: "fpv", component: Filmmaking }, 18 | { path: "/links", name: "links", component: Links }, 19 | { path: "/sponsors", name: "sponsors", component: Sponsors }, 20 | { path: "/contact", name: "contact", component: Contact }, 21 | { path: "/:pathMatch(.*)*", component: NotFound }, 22 | 23 | // Handle legacy paths 24 | { path: "/articles", redirect: "/writeups" }, 25 | { path: "/resources", redirect: "/links" }, 26 | { path: "/fpv", redirect: "/filmmaking" }, 27 | ], 28 | }); 29 | 30 | export default router; 31 | -------------------------------------------------------------------------------- /src/types.d.ts: -------------------------------------------------------------------------------- 1 | export interface Link { 2 | title: string; 3 | url: string; 4 | } 5 | -------------------------------------------------------------------------------- /src/views/ArticlesView.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 52 | 53 | 59 | -------------------------------------------------------------------------------- /src/views/ContactView.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 34 | -------------------------------------------------------------------------------- /src/views/FilmmakingView.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 89 | 90 | 111 | -------------------------------------------------------------------------------- /src/views/HomeView.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | 49 | -------------------------------------------------------------------------------- /src/views/LinksView.vue: -------------------------------------------------------------------------------- 1 | 73 | 74 | 106 | 107 | 113 | -------------------------------------------------------------------------------- /src/views/NotFound.vue: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /src/views/SponsorsView.vue: -------------------------------------------------------------------------------- 1 | 44 | 45 | 83 | 84 | 99 | -------------------------------------------------------------------------------- /src/views/WorkView.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 60 | -------------------------------------------------------------------------------- /tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.dom.json", 3 | "include": ["env.d.ts", "src/**/*", "src/**/*.vue"], 4 | "exclude": ["src/**/__tests__/*"], 5 | "compilerOptions": { 6 | "composite": true, 7 | "noEmit": true, 8 | "baseUrl": ".", 9 | "paths": { 10 | "@/*": ["./src/*"] 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { 5 | "path": "./tsconfig.node.json" 6 | }, 7 | { 8 | "path": "./tsconfig.app.json" 9 | }, 10 | { 11 | "path": "./tsconfig.vitest.json" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/node18/tsconfig.json", 3 | "include": [ 4 | "vite.config.*", 5 | "vitest.config.*", 6 | "cypress.config.*", 7 | "nightwatch.conf.*", 8 | "playwright.config.*" 9 | ], 10 | "compilerOptions": { 11 | "composite": true, 12 | "noEmit": true, 13 | "module": "ESNext", 14 | "moduleResolution": "Bundler", 15 | "types": ["node"] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tsconfig.node.tsbuildinfo: -------------------------------------------------------------------------------- 1 | {"program":{"fileNames":["./node_modules/typescript/lib/lib.es5.d.ts","./node_modules/typescript/lib/lib.es2015.d.ts","./node_modules/typescript/lib/lib.es2016.d.ts","./node_modules/typescript/lib/lib.es2017.d.ts","./node_modules/typescript/lib/lib.es2018.d.ts","./node_modules/typescript/lib/lib.es2019.d.ts","./node_modules/typescript/lib/lib.es2020.d.ts","./node_modules/typescript/lib/lib.es2021.d.ts","./node_modules/typescript/lib/lib.es2022.d.ts","./node_modules/typescript/lib/lib.es2023.d.ts","./node_modules/typescript/lib/lib.es2015.core.d.ts","./node_modules/typescript/lib/lib.es2015.collection.d.ts","./node_modules/typescript/lib/lib.es2015.generator.d.ts","./node_modules/typescript/lib/lib.es2015.iterable.d.ts","./node_modules/typescript/lib/lib.es2015.promise.d.ts","./node_modules/typescript/lib/lib.es2015.proxy.d.ts","./node_modules/typescript/lib/lib.es2015.reflect.d.ts","./node_modules/typescript/lib/lib.es2015.symbol.d.ts","./node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","./node_modules/typescript/lib/lib.es2016.array.include.d.ts","./node_modules/typescript/lib/lib.es2017.date.d.ts","./node_modules/typescript/lib/lib.es2017.object.d.ts","./node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","./node_modules/typescript/lib/lib.es2017.string.d.ts","./node_modules/typescript/lib/lib.es2017.intl.d.ts","./node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","./node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","./node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","./node_modules/typescript/lib/lib.es2018.intl.d.ts","./node_modules/typescript/lib/lib.es2018.promise.d.ts","./node_modules/typescript/lib/lib.es2018.regexp.d.ts","./node_modules/typescript/lib/lib.es2019.array.d.ts","./node_modules/typescript/lib/lib.es2019.object.d.ts","./node_modules/typescript/lib/lib.es2019.string.d.ts","./node_modules/typescript/lib/lib.es2019.symbol.d.ts","./node_modules/typescript/lib/lib.es2019.intl.d.ts","./node_modules/typescript/lib/lib.es2020.bigint.d.ts","./node_modules/typescript/lib/lib.es2020.date.d.ts","./node_modules/typescript/lib/lib.es2020.promise.d.ts","./node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","./node_modules/typescript/lib/lib.es2020.string.d.ts","./node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","./node_modules/typescript/lib/lib.es2020.intl.d.ts","./node_modules/typescript/lib/lib.es2020.number.d.ts","./node_modules/typescript/lib/lib.es2021.promise.d.ts","./node_modules/typescript/lib/lib.es2021.string.d.ts","./node_modules/typescript/lib/lib.es2021.weakref.d.ts","./node_modules/typescript/lib/lib.es2021.intl.d.ts","./node_modules/typescript/lib/lib.es2022.array.d.ts","./node_modules/typescript/lib/lib.es2022.error.d.ts","./node_modules/typescript/lib/lib.es2022.intl.d.ts","./node_modules/typescript/lib/lib.es2022.object.d.ts","./node_modules/typescript/lib/lib.es2022.sharedmemory.d.ts","./node_modules/typescript/lib/lib.es2022.string.d.ts","./node_modules/typescript/lib/lib.es2022.regexp.d.ts","./node_modules/typescript/lib/lib.es2023.array.d.ts","./node_modules/typescript/lib/lib.es2023.collection.d.ts","./node_modules/typescript/lib/lib.esnext.intl.d.ts","./node_modules/typescript/lib/lib.decorators.d.ts","./node_modules/typescript/lib/lib.decorators.legacy.d.ts","./node_modules/@vue/reactivity/node_modules/@vue/shared/dist/shared.d.ts","./node_modules/@vue/reactivity/dist/reactivity.d.ts","./node_modules/@vue/runtime-core/node_modules/@vue/shared/dist/shared.d.ts","./node_modules/@vue/runtime-core/dist/runtime-core.d.ts","./node_modules/csstype/index.d.ts","./node_modules/@vue/runtime-dom/dist/runtime-dom.d.ts","./node_modules/vue/jsx-runtime/index.d.ts","./node_modules/@babel/parser/typings/babel-parser.d.ts","./node_modules/source-map-js/source-map.d.ts","./node_modules/vue/node_modules/@vue/shared/dist/shared.d.ts","./node_modules/vue/node_modules/@vue/compiler-core/dist/compiler-core.d.ts","./node_modules/vue/node_modules/@vue/compiler-dom/dist/compiler-dom.d.ts","./node_modules/vue/jsx.d.ts","./node_modules/vue/dist/vue.d.mts","./__VLS_types.d.ts","./node_modules/@types/node/assert.d.ts","./node_modules/@types/node/assert/strict.d.ts","./node_modules/undici-types/header.d.ts","./node_modules/undici-types/readable.d.ts","./node_modules/undici-types/file.d.ts","./node_modules/undici-types/fetch.d.ts","./node_modules/undici-types/formdata.d.ts","./node_modules/undici-types/connector.d.ts","./node_modules/undici-types/client.d.ts","./node_modules/undici-types/errors.d.ts","./node_modules/undici-types/dispatcher.d.ts","./node_modules/undici-types/global-dispatcher.d.ts","./node_modules/undici-types/global-origin.d.ts","./node_modules/undici-types/pool-stats.d.ts","./node_modules/undici-types/pool.d.ts","./node_modules/undici-types/handlers.d.ts","./node_modules/undici-types/balanced-pool.d.ts","./node_modules/undici-types/agent.d.ts","./node_modules/undici-types/mock-interceptor.d.ts","./node_modules/undici-types/mock-agent.d.ts","./node_modules/undici-types/mock-client.d.ts","./node_modules/undici-types/mock-pool.d.ts","./node_modules/undici-types/mock-errors.d.ts","./node_modules/undici-types/proxy-agent.d.ts","./node_modules/undici-types/api.d.ts","./node_modules/undici-types/cookies.d.ts","./node_modules/undici-types/patch.d.ts","./node_modules/undici-types/filereader.d.ts","./node_modules/undici-types/diagnostics-channel.d.ts","./node_modules/undici-types/websocket.d.ts","./node_modules/undici-types/content-type.d.ts","./node_modules/undici-types/cache.d.ts","./node_modules/undici-types/interceptors.d.ts","./node_modules/undici-types/index.d.ts","./node_modules/@types/node/globals.d.ts","./node_modules/@types/node/async_hooks.d.ts","./node_modules/@types/node/buffer.d.ts","./node_modules/@types/node/child_process.d.ts","./node_modules/@types/node/cluster.d.ts","./node_modules/@types/node/console.d.ts","./node_modules/@types/node/constants.d.ts","./node_modules/@types/node/crypto.d.ts","./node_modules/@types/node/dgram.d.ts","./node_modules/@types/node/diagnostics_channel.d.ts","./node_modules/@types/node/dns.d.ts","./node_modules/@types/node/dns/promises.d.ts","./node_modules/@types/node/domain.d.ts","./node_modules/@types/node/dom-events.d.ts","./node_modules/@types/node/events.d.ts","./node_modules/@types/node/fs.d.ts","./node_modules/@types/node/fs/promises.d.ts","./node_modules/@types/node/http.d.ts","./node_modules/@types/node/http2.d.ts","./node_modules/@types/node/https.d.ts","./node_modules/@types/node/inspector.d.ts","./node_modules/@types/node/module.d.ts","./node_modules/@types/node/net.d.ts","./node_modules/@types/node/os.d.ts","./node_modules/@types/node/path.d.ts","./node_modules/@types/node/perf_hooks.d.ts","./node_modules/@types/node/process.d.ts","./node_modules/@types/node/punycode.d.ts","./node_modules/@types/node/querystring.d.ts","./node_modules/@types/node/readline.d.ts","./node_modules/@types/node/readline/promises.d.ts","./node_modules/@types/node/repl.d.ts","./node_modules/@types/node/stream.d.ts","./node_modules/@types/node/stream/promises.d.ts","./node_modules/@types/node/stream/consumers.d.ts","./node_modules/@types/node/stream/web.d.ts","./node_modules/@types/node/string_decoder.d.ts","./node_modules/@types/node/test.d.ts","./node_modules/@types/node/timers.d.ts","./node_modules/@types/node/timers/promises.d.ts","./node_modules/@types/node/tls.d.ts","./node_modules/@types/node/trace_events.d.ts","./node_modules/@types/node/tty.d.ts","./node_modules/@types/node/url.d.ts","./node_modules/@types/node/util.d.ts","./node_modules/@types/node/v8.d.ts","./node_modules/@types/node/vm.d.ts","./node_modules/@types/node/wasi.d.ts","./node_modules/@types/node/worker_threads.d.ts","./node_modules/@types/node/zlib.d.ts","./node_modules/@types/node/globals.global.d.ts","./node_modules/@types/node/index.d.ts","./node_modules/rollup/dist/rollup.d.ts","./node_modules/rollup/dist/parseAst.d.ts","./node_modules/vite/types/hmrPayload.d.ts","./node_modules/vite/types/customEvent.d.ts","./node_modules/vite/types/hot.d.ts","./node_modules/vite/dist/node/types.d-AKzkD8vd.d.ts","./node_modules/esbuild/lib/main.d.ts","./node_modules/postcss/lib/previous-map.d.ts","./node_modules/postcss/lib/input.d.ts","./node_modules/postcss/lib/css-syntax-error.d.ts","./node_modules/postcss/lib/declaration.d.ts","./node_modules/postcss/lib/root.d.ts","./node_modules/postcss/lib/warning.d.ts","./node_modules/postcss/lib/lazy-result.d.ts","./node_modules/postcss/lib/no-work-result.d.ts","./node_modules/postcss/lib/processor.d.ts","./node_modules/postcss/lib/result.d.ts","./node_modules/postcss/lib/document.d.ts","./node_modules/postcss/lib/rule.d.ts","./node_modules/postcss/lib/node.d.ts","./node_modules/postcss/lib/comment.d.ts","./node_modules/postcss/lib/container.d.ts","./node_modules/postcss/lib/at-rule.d.ts","./node_modules/postcss/lib/list.d.ts","./node_modules/postcss/lib/postcss.d.ts","./node_modules/postcss/lib/postcss.d.mts","./node_modules/vite/dist/node/runtime.d.ts","./node_modules/vite/types/importGlob.d.ts","./node_modules/vite/types/metadata.d.ts","./node_modules/vite/dist/node/index.d.ts","./node_modules/@vue/compiler-sfc/node_modules/@vue/compiler-core/dist/compiler-core.d.ts","./node_modules/magic-string/dist/magic-string.es.d.mts","./node_modules/typescript/lib/typescript.d.ts","./node_modules/@vue/reactivity-transform/dist/reactivity-transform.d.ts","./node_modules/@vue/compiler-sfc/dist/compiler-sfc.d.ts","./node_modules/vue/compiler-sfc/index.d.mts","./node_modules/@vitejs/plugin-vue/dist/index.d.mts","./vite.config.ts","./node_modules/@vitest/utils/dist/types.d.ts","./node_modules/@vitest/utils/dist/helpers.d.ts","./node_modules/@sinclair/typebox/typebox.d.ts","./node_modules/@jest/schemas/build/index.d.ts","./node_modules/pretty-format/build/index.d.ts","./node_modules/@vitest/utils/dist/index.d.ts","./node_modules/@vitest/runner/dist/tasks-rsXe_qLO.d.ts","./node_modules/@vitest/utils/dist/types-widbdqe5.d.ts","./node_modules/@vitest/utils/dist/diff.d.ts","./node_modules/@vitest/runner/dist/types.d.ts","./node_modules/@vitest/utils/dist/error.d.ts","./node_modules/@vitest/runner/dist/index.d.ts","./node_modules/vite-node/dist/trace-mapping.d-aA9jxPtH.d.ts","./node_modules/vite-node/dist/index-IeUJleJC.d.ts","./node_modules/vite-node/dist/index.d.ts","./node_modules/@vitest/snapshot/dist/environment-1emuyggI.d.ts","./node_modules/@vitest/snapshot/dist/index-K5cwkiJB.d.ts","./node_modules/@vitest/snapshot/dist/index.d.ts","./node_modules/@vitest/expect/dist/chai.d.cts","./node_modules/@vitest/expect/dist/index.d.ts","./node_modules/@vitest/expect/index.d.ts","./node_modules/@vitest/runner/dist/utils.d.ts","./node_modules/tinybench/dist/index.d.ts","./node_modules/vite-node/dist/client.d.ts","./node_modules/@vitest/snapshot/dist/manager.d.ts","./node_modules/vite-node/dist/server.d.ts","./node_modules/vitest/dist/reporters-OH1c16Kq.d.ts","./node_modules/vitest/dist/config.d.ts","./node_modules/vitest/config.d.ts","./vitest.config.ts"],"fileInfos":[{"version":"0","affectsGlobalScope":true},"0","0","0","0","0","0","0","0","0",{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},"0","0","0",{"version":"0","affectsGlobalScope":true},"0","0","0","0","0","0","0","0",{"version":"0","affectsGlobalScope":true},"0",{"version":"0","affectsGlobalScope":true},"0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0",{"version":"0","affectsGlobalScope":true},"0",{"version":"0","affectsGlobalScope":true},"0","0",{"version":"0","affectsGlobalScope":true},"0","0","0","0","0","0","0",{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},"0","0","0","0","0","0",{"version":"0","affectsGlobalScope":true},"0","0","0",{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},"0","0","0","0","0","0","0","0","0","0",{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},"0","0","0","0",{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},"0","0","0",{"version":"0","affectsGlobalScope":true},"0",{"version":"0","affectsGlobalScope":true},"0",{"version":"0","affectsGlobalScope":true},"0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0",{"version":"0","affectsGlobalScope":true},{"version":"0","affectsGlobalScope":true},"0","0","0","0","0","0",{"version":"0","affectsGlobalScope":true},"0","0","0"],"root":[75,199,229],"options":{"composite":true,"esModuleInterop":true,"module":99,"skipLibCheck":true,"strict":true,"target":9},"fileIdsList":[[64,66,67,74],[202],[76],[111],[112,117,145],[113,124,125,132,142,153],[113,114,124,132],[115,154],[116,117,125,133],[117,142,150],[118,120,124,132],[119],[120,121],[124],[122,124],[111,124],[124,125,126,142,153],[124,125,126,139,142,145],[109,158],[120,124,127,132,142,153],[124,125,127,128,132,142,150,153],[127,129,142,150,153],[76,77,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160],[124,130],[131,153,158],[120,124,132,142],[133],[134],[111,135],[136,152,158],[137],[138],[124,139,140],[139,141,154,156],[112,124,142,143,144,145],[112,142,144],[142,143],[145],[146],[111,142],[124,148,149],[148,149],[117,132,142,150],[151],[132,152],[112,127,138,153],[117,154],[142,155],[131,156],[157],[112,117,124,126,135,142,153,156,158],[142,159],[191,197,226],[205,208],[219],[205,206,208,209,210],[205],[205,206,208],[205,206],[204,215],[204,215,216],[204,207],[200],[200,201,204],[204],[68,69,71,187,193,194,195],[61,68,69],[68,193],[61],[61,62,64,66],[62,64,65],[183],[181,183],[172,180,181,182,184],[170],[173,178,183,186],[169,186],[173,174,177,178,179,186],[173,174,175,177,178,186],[170,171,172,173,174,178,179,180,182,183,184,186],[186],[69,170,171,172,173,174,175,177,178,179,180,181,182,183,184,185],[69,186],[173,175,176,178,179,186],[177,186],[178,179,183,186],[171,181],[203],[162,190],[69],[86,90,153],[86,142,153],[81],[83,86,150,153],[132,150],[161],[81,161],[83,86,132,153],[78,79,82,85,112,124,142,153],[78,84],[82,86,112,145,153,161],[112,161],[102,112,161],[80,81,161],[86],[80,81,82,83,84,85,86,87,88,90,91,92,93,94,95,96,97,98,99,100,101,103,104,105,106,107,108],[86,93,94],[84,86,94,95],[85],[78,81,86],[86,90,94,95],[90],[84,86,89,153],[78,83,84,86,90,93],[112,142],[81,86,102,112,158,161],[212,213],[212],[191,212,213,226],[124,125,127,128,129,132,142,150,153,159,161,162,163,164,165,166,167,168,187,188,189,190],[164,165,166,167],[164,165,166],[164],[165],[162],[227],[125,158,191,205,211,214,217,218,220,221,222,223,224,225,226],[196],[66,72,73],[66],[71],[153,191,198,226],[153,199,228]],"referencedMap":[[75,1],[203,2],[76,3],[77,3],[111,4],[112,5],[113,6],[114,7],[115,8],[116,9],[117,10],[118,11],[119,12],[120,13],[121,13],[123,14],[122,15],[124,16],[125,17],[126,18],[110,19],[127,20],[128,21],[129,22],[161,23],[130,24],[131,25],[132,26],[133,27],[134,28],[135,29],[136,30],[137,31],[138,32],[139,33],[140,33],[141,34],[142,35],[144,36],[143,37],[145,38],[146,39],[147,40],[148,41],[149,42],[150,43],[151,44],[152,45],[153,46],[154,47],[155,48],[156,49],[157,50],[158,51],[159,52],[198,53],[219,54],[220,55],[211,56],[206,57],[209,58],[221,59],[216,60],[217,61],[224,61],[208,62],[210,62],[201,63],[205,64],[207,65],[196,66],[192,67],[195,68],[62,69],[64,70],[66,71],[184,72],[182,73],[183,74],[171,75],[172,73],[179,76],[170,77],[175,78],[176,79],[181,80],[187,81],[186,82],[169,83],[177,84],[178,85],[173,86],[180,72],[174,87],[204,88],[163,89],[69,90],[93,91],[100,92],[92,91],[107,93],[84,94],[83,95],[106,96],[101,97],[104,98],[86,99],[85,100],[81,101],[80,102],[103,103],[82,104],[87,105],[91,105],[109,106],[108,105],[95,107],[96,108],[98,109],[94,110],[97,111],[102,96],[89,112],[90,113],[99,114],[79,115],[105,116],[223,117],[213,118],[214,117],[225,119],[191,120],[188,121],[167,122],[165,123],[166,124],[190,125],[228,126],[227,127],[226,127],[197,128],[74,129],[67,130],[73,130],[71,67],[72,131],[199,132],[229,133]],"exportedModulesMap":[[75,1],[203,2],[76,3],[77,3],[111,4],[112,5],[113,6],[114,7],[115,8],[116,9],[117,10],[118,11],[119,12],[120,13],[121,13],[123,14],[122,15],[124,16],[125,17],[126,18],[110,19],[127,20],[128,21],[129,22],[161,23],[130,24],[131,25],[132,26],[133,27],[134,28],[135,29],[136,30],[137,31],[138,32],[139,33],[140,33],[141,34],[142,35],[144,36],[143,37],[145,38],[146,39],[147,40],[148,41],[149,42],[150,43],[151,44],[152,45],[153,46],[154,47],[155,48],[156,49],[157,50],[158,51],[159,52],[198,53],[219,54],[220,55],[211,56],[206,57],[209,58],[221,59],[216,60],[217,61],[224,61],[208,62],[210,62],[201,63],[205,64],[207,65],[196,66],[192,67],[195,68],[62,69],[64,70],[66,71],[184,72],[182,73],[183,74],[171,75],[172,73],[179,76],[170,77],[175,78],[176,79],[181,80],[187,81],[186,82],[169,83],[177,84],[178,85],[173,86],[180,72],[174,87],[204,88],[163,89],[69,90],[93,91],[100,92],[92,91],[107,93],[84,94],[83,95],[106,96],[101,97],[104,98],[86,99],[85,100],[81,101],[80,102],[103,103],[82,104],[87,105],[91,105],[109,106],[108,105],[95,107],[96,108],[98,109],[94,110],[97,111],[102,96],[89,112],[90,113],[99,114],[79,115],[105,116],[223,117],[213,118],[214,117],[225,119],[191,120],[188,121],[167,122],[165,123],[166,124],[190,125],[228,126],[227,127],[226,127],[197,128],[74,129],[67,130],[73,130],[71,67],[72,131],[199,132],[229,133]],"semanticDiagnosticsPerFile":[75,68,203,202,76,77,111,112,113,114,115,116,117,118,119,120,121,123,122,124,125,126,110,160,127,128,129,161,130,131,132,133,134,135,136,137,138,139,140,141,142,144,143,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,198,218,219,220,211,206,209,221,215,216,217,224,208,210,201,205,207,200,196,192,195,62,61,64,63,66,65,168,193,184,182,183,171,172,179,170,175,185,176,181,187,186,169,177,178,173,180,174,204,163,162,69,222,59,60,12,11,2,13,14,15,16,17,18,19,20,3,4,21,25,22,23,24,26,27,28,5,29,30,31,32,6,36,33,34,35,37,7,38,43,44,39,40,41,42,8,48,45,46,47,49,9,50,51,52,55,53,54,56,57,10,1,58,194,93,100,92,107,84,83,106,101,104,86,85,81,80,103,82,87,88,91,78,109,108,95,96,98,94,97,102,89,90,99,79,105,223,213,214,225,212,191,188,167,165,164,166,189,190,228,227,226,197,74,67,73,71,72,70,199,229],"affectedFilesPendingEmit":[199,229],"emitSignatures":[199,229]},"version":"5.3.3"} -------------------------------------------------------------------------------- /tsconfig.vitest.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.app.json", 3 | "exclude": [], 4 | "compilerOptions": { 5 | "composite": true, 6 | "lib": [], 7 | "types": ["node", "jsdom"] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "rewrites": [{ "source": "/(.*)", "destination": "/" }] 3 | } 4 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath, URL } from 'node:url' 2 | 3 | import { defineConfig } from 'vite' 4 | import vue from '@vitejs/plugin-vue' 5 | 6 | // https://vitejs.dev/config/ 7 | export default defineConfig({ 8 | plugins: [ 9 | vue(), 10 | ], 11 | resolve: { 12 | alias: { 13 | '@': fileURLToPath(new URL('./src', import.meta.url)) 14 | } 15 | } 16 | }) 17 | -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath } from 'node:url' 2 | import { mergeConfig, defineConfig, configDefaults } from 'vitest/config' 3 | import viteConfig from './vite.config' 4 | 5 | export default mergeConfig( 6 | viteConfig, 7 | defineConfig({ 8 | test: { 9 | environment: 'jsdom', 10 | exclude: [...configDefaults.exclude, 'e2e/*'], 11 | root: fileURLToPath(new URL('./', import.meta.url)) 12 | } 13 | }) 14 | ) 15 | --------------------------------------------------------------------------------