Compare commits

..

11 Commits

Author SHA1 Message Date
Hamcha 42e5ac64a3
.....................
continuous-integration/woodpecker the build failed Details
2021-11-17 16:53:54 +01:00
Hamcha 17f3efae15
AAAAAAAAAAA p2
continuous-integration/woodpecker the build failed Details
2021-11-17 16:50:58 +01:00
Hamcha 20319285e6
LAST EDIT 2021-11-17 16:49:36 +01:00
Hamcha 9fa3dc834a
DOES THIS WORK????
continuous-integration/woodpecker the build failed Details
2021-11-17 16:47:39 +01:00
Hamcha ba9bb0bce5
wbnow
continuous-integration/woodpecker the build failed Details
2021-11-17 16:44:59 +01:00
Hamcha a3cff17506
BASTA BERE
continuous-integration/woodpecker the build was successful Details
2021-11-17 16:44:06 +01:00
Hamcha 75c3c867b4
aaaaa
continuous-integration/woodpecker the build failed Details
2021-11-17 16:42:28 +01:00
Hamcha ae12eaa6a0
Use more envy
continuous-integration/woodpecker the build failed Details
2021-11-17 16:35:38 +01:00
Hamcha 72e86f13ed
Re-add upload step
continuous-integration/woodpecker the build failed Details
2021-11-06 02:19:44 +01:00
Hamcha ee5bd442c3
hello i am mr dumb
continuous-integration/woodpecker the build was successful Details
2021-11-06 02:16:46 +01:00
Hamcha e50f8eb411
CI FUCKERY TIME
continuous-integration/woodpecker the build failed Details
2021-11-06 01:18:53 +01:00
26 changed files with 6991 additions and 10193 deletions

View File

@ -19,9 +19,7 @@ module.exports = {
"no-param-reassign": "off",
"no-alert": "off",
"no-console": "off",
"no-shadow": "off",
"func-names": "off",
"default-param-last": "off",
"dot-notation": ["error", { allowPattern: "^[A-Z][a-z]+$" }],
"@typescript-eslint/ban-ts-comment": [
"error",
@ -29,7 +27,5 @@ module.exports = {
"ts-expect-error": "allow-with-description",
},
],
"@typescript-eslint/no-shadow": ["error"],
"@typescript-eslint/default-param-last": ["error"],
},
};

View File

@ -1,32 +0,0 @@
name: Publish on GitHub Pages
on:
push:
branches:
- master
pull_request:
jobs:
deploy:
runs-on: ubuntu-20.04
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
steps:
- uses: actions/checkout@v3
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: 18
- name: Install dependencies
run: npm ci
- run: npm lint
- run: npm run build --if-present
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
if: ${{ github.ref == 'refs/heads/main' }}
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./dist

4
.gitignore vendored
View File

@ -1,6 +1,4 @@
node_modules
dist
.cache
.parcel-cache
yarn-error.log
*.ts.js
yarn-error.log

86
.woodpecker/build.yml Normal file
View File

@ -0,0 +1,86 @@
pipeline:
dependencies:
image: node
commands:
- yarn
build_versioned:
image: node
commands:
- export SUBPATH=/tghandbook/${DRONE_COMMIT_BRANCH/\//_}-${DRONE_COMMIT_SHA:0:8}
- export REVISION=${DRONE_COMMIT_SHA}
- yarn build
group: build
build_pr:
image: node
commands:
- export SUBPATH=/tghandbook/pr-$${DRONE_PULL_REQUEST}
- export REVISION=${DRONE_COMMIT_SHA}
- yarn build
environment:
- OUTDIR=./dist-pr
when:
event: pull_request
group: build
build_branch:
image: node
commands:
- export SUBPATH=/tghandbook/${DRONE_COMMIT_BRANCH/\//_}
- export REVISION=${DRONE_COMMIT_SHA}
- yarn build
environment:
- OUTDIR=./dist-branch
when:
event: push
group: build
upload_build_versioned:
image: woodpeckerci/plugin-s3
secrets: [minio_access, minio_secret]
settings:
bucket: tghandbook
source: ./dist/**/*
target: /${DRONE_COMMIT_BRANCH/\//_}-${DRONE_COMMIT_SHA:0:8}/
strip_prefix: dist/
path_style: true
endpoint: https://artifacts.fromouter.space
environment:
AWS_ACCESS_KEY_ID: $MINIO_ACCESS
AWS_SECRET_ACCESS_KEY: $MINIO_SECRET
when:
event: push
group: upload
upload_build_pr:
image: woodpeckerci/plugin-s3
secrets: [minio_access, minio_secret]
settings:
bucket: tghandbook
source: ./dist-pr/**/*
target: /pr-${DRONE_PULL_REQUEST}/
strip_prefix: dist-pr/
path_style: true
endpoint: https://artifacts.fromouter.space
environment:
AWS_ACCESS_KEY_ID: $MINIO_ACCESS
AWS_SECRET_ACCESS_KEY: $MINIO_SECRET
when:
event: pull_request
group: upload
upload_build_branch:
image: woodpeckerci/plugin-s3
secrets: [minio_access, minio_secret]
settings:
bucket: tghandbook
source: ./dist-branch/**/*
target: /${DRONE_COMMIT_BRANCH/\//_}/
strip_prefix: dist-branch/
path_style: true
endpoint: https://artifacts.fromouter.space
environment:
AWS_ACCESS_KEY_ID: $MINIO_ACCESS
AWS_SECRET_ACCESS_KEY: $MINIO_SECRET
group: upload

9
.woodpecker/lint.yml Normal file
View File

@ -0,0 +1,9 @@
pipeline:
dependencies:
image: node
commands:
- yarn
lint:
image: node
commands:
- yarn lint

24
LICENSE
View File

@ -1,5 +1,23 @@
Copyright 2020, Alessandro Gatti
This code is license under ISC, full copy below:
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
Copyright 2020, Alessandro Gatti
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
This code uses idb-keyval, licensed under Apache 2:
Copyright 2016, Jake Archibald
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -1,15 +1,11 @@
# /tg/station handbook
# /tg/ handbook
A fancier way to browse the /tg/ wiki. This handbook is a single page application that downloads 20+ pages from the /tg/station wiki (currently using a CORS proxy), adds some fancy filtering and Nanotrasen styling.
[![Build Status](https://ci.fromouter.space/api/badges/Hamcha/tghandbook/status.svg)](https://ci.fromouter.space/Hamcha/tghandbook)
It adapts the pages layout to be narrow as it's meant to be used in a small window, much like a PDA or an in-game book.
## Building
`yarn build`
## Development
Start hot-reloading server with `npm start`
Build with `npm run build`
## License
The project is licensed under ISC (SPDX identifier). Please see the LICENSE file for details.
`yarn dev`

24
build.js Normal file
View File

@ -0,0 +1,24 @@
/* eslint-disable */
const Bundler = require("parcel-bundler");
const Path = require("path");
const entryFiles = Path.join(__dirname, "./index.html");
// Bundler options
const options = {
outDir: process.env.OUTDIR || "./dist",
outFile: "index.html",
publicUrl: process.env.SUBPATH || "/",
watch: false,
contentHash: false,
scopeHoist: false,
target: "browser",
logLevel: 3, // 5 = save everything to a file, 4 = like 3, but with timestamps and additionally log http requests to dev server, 3 = log info, warnings & errors, 2 = log warnings & errors, 1 = log errors, 0 = log nothing
sourceMaps: true, // Enable or disable sourcemaps, defaults to enabled (minified builds currently always create sourcemaps)
autoInstall: true, // Enable or disable auto install of missing dependencies found during bundling
};
(async () => {
const bundler = new Bundler(entryFiles, options);
await bundler.bundle();
})();

10
env.d.ts vendored
View File

@ -1,10 +0,0 @@
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_SUBDIR: string;
readonly VITE_APP_REVISION: string;
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}

View File

@ -14,31 +14,31 @@
<link
rel="apple-touch-icon"
href="./assets/images/icons-manifest/icon152.png"
href="assets/images/icons-manifest/icon152.png"
/>
<link rel="manifest" href="./manifest.webmanifest" />
<link rel="icon" href="./favicon.ico" type="image/x-icon" />
<link rel="manifest" href="manifest.webmanifest" />
<link rel="icon" href="favicon.ico" type="image/x-icon" />
<link
rel="icon"
type="image/png"
sizes="32x32"
href="./assets/images/icons-manifest/icon32.png"
href="assets/images/icons-manifest/icon32.png"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="./assets/images/icons-manifest/icon16.png"
href="assets/images/icons-manifest/icon16.png"
/>
<link
rel="preload"
href="./assets/fonts/iosevka/iosevka-aile.css"
href="assets/fonts/iosevka/iosevka-aile.css"
as="style"
/>
<link rel="preload" href="./style/main.scss" as="style" />
<link rel="preload" href="./src/index.ts" as="script" />
<link rel="stylesheet" href="./assets/fonts/iosevka/iosevka-aile.css" />
<link rel="stylesheet" href="./style/main.scss" />
<link rel="preload" href="style/main.scss" as="style" />
<link rel="preload" href="src/index.ts" as="script" />
<link rel="stylesheet" href="assets/fonts/iosevka/iosevka-aile.css" />
<link rel="stylesheet" href="style/main.scss" />
<title>/tg/station Handbook</title>
</head>
<body>
@ -52,8 +52,8 @@
<div class="page special center" id="Welcome" data-tab="$Welcome">
<div class="wrapper">
<header>
<img class="icon" src="./assets/images/outline.svg" />
<img class="type" src="./assets/images/type.svg" />
<img class="icon" src="assets/images/outline.svg" />
<img class="type" src="assets/images/type.svg" />
</header>
<div class="maxw">
<p>
@ -79,7 +79,9 @@
<div class="action_buttons"></div>
</div>
<div class="features hidden" data-name="Extra features">
<h2>Extra Features</h2>
<h2>
Extra Features
</h2>
<div class="maxw">
<h3 class="nobg">Jump to section/item</h3>
<p>
@ -92,12 +94,12 @@
</p>
<div class="images">
<img
src="./assets/images/welcome/bs-local.png"
style="width: 40%"
src="assets/images/welcome/bs-local.png"
style="width: 40%;"
/>
<img
src="./assets/images/welcome/bs-global.png"
style="width: 40%"
src="assets/images/welcome/bs-global.png"
style="width: 40%;"
/>
</div>
<p>
@ -120,15 +122,17 @@
</div>
</div>
<div class="credits hidden" data-name="Other infos">
<h2>Other Informations</h2>
<h2>
Other Informations
</h2>
<p>
Thanks to /tg/station and every wiki contributor who did most of
the work!
</p>
<p>
This thing is Open Source:
<a href="https://github.com/Hamcha/tghandbook"
>github.com/Hamcha/tghandbook</a
<a href="https://git.fromouter.space/hamcha/tghandbook"
>git.fromouter.space/hamcha/tghandbook</a
>
</p>
<p>
@ -140,13 +144,9 @@
</section>
</main>
<noscript>
<h1>JavaScript is required for this tool</h1>
<h2>
This tools runs completely in your browser, therefore it needs
JavaScript to download all the pages, parse them and add all the spicy
extras.
</h2>
<h1>NO JS NO PARTY</h1>
<h2>JavaScript support is required to run this app.</h2>
</noscript>
<script src="./src/index.ts" async type="module"></script>
<script src="src/index.ts" async></script>
</body>
</html>

9934
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -3,28 +3,27 @@
"version": "1.0.0",
"main": "index.js",
"license": "ISC",
"type": "module",
"scripts": {
"start": "vite",
"dev": "parcel index.html",
"lint": "eslint src",
"build": "vite build --base=./"
"build": "node ./build.js"
},
"dependencies": {
"@types/node": "^17.0.31",
"@types/node": "^14.0.13",
"@types/service_worker_api": "^0.0.9",
"@typescript-eslint/eslint-plugin": "^5.23.0",
"@typescript-eslint/parser": "^5.23.0",
"eslint": "8.15.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "2.26.0",
"eslint-plugin-prettier": "^4.0.0",
"idb-keyval": "^6.1.0",
"prettier": "^2.6.2",
"sass": "^1.51.0",
"typescript": "^4.6.4",
"vite": "^2.9.8",
"vite-plugin-pwa": "^0.12.0"
"@typescript-eslint/eslint-plugin": "^3.3.0",
"@typescript-eslint/parser": "^3.3.0",
"eslint": "7.2.0",
"eslint-config-airbnb-base": "^14.2.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-import": "2.21.2",
"eslint-plugin-prettier": "^3.1.4",
"idb-keyval": "^3.2.0",
"parcel-bundler": "^1.12.4",
"parcel-plugin-sw-cache": "^0.3.1",
"prettier": "^2.0.5",
"sass": "^1.26.8",
"typescript": "^3.9.5"
},
"browserslist": [
"last 2 Chrome versions",

View File

@ -8,7 +8,6 @@ interface CacheEntry<T> {
export class Store {
readonly dbp: Promise<IDBDatabase>;
// eslint-disable-next-line default-param-last
constructor(dbName = "tg-cache", readonly storeName = "keyval") {
this.dbp = new Promise((resolve, reject) => {
const openreq = indexedDB.open(dbName, 1);
@ -52,8 +51,8 @@ export function get<Type>(
): Promise<CacheEntry<Type>> {
let req: IDBRequest;
return store
.withIDBStore("readonly", (idbstore) => {
req = idbstore.get(key);
.withIDBStore("readonly", (store) => {
req = store.get(key);
})
.then(() => req.result);
}
@ -64,8 +63,8 @@ export function set<Type>(
version: string,
store = getDefaultStore()
): Promise<void> {
return store.withIDBStore("readwrite", (idbstore) => {
idbstore.put({ version, value }, key);
return store.withIDBStore("readwrite", (store) => {
store.put({ version, value }, key);
});
}
@ -73,14 +72,14 @@ export function del(
key: IDBValidKey,
store = getDefaultStore()
): Promise<void> {
return store.withIDBStore("readwrite", (idbstore) => {
idbstore.delete(key);
return store.withIDBStore("readwrite", (store) => {
store.delete(key);
});
}
export function clear(store = getDefaultStore()): Promise<void> {
return store.withIDBStore("readwrite", (idbstore) => {
idbstore.clear();
return store.withIDBStore("readwrite", (store) => {
store.clear();
});
}
@ -88,15 +87,16 @@ export function keys(store = getDefaultStore()): Promise<IDBValidKey[]> {
const dbkeys: IDBValidKey[] = [];
return store
.withIDBStore("readonly", (idbstore) => {
.withIDBStore("readonly", (store) => {
// This would be store.getAllKeys(), but it isn't supported by Edge or Safari.
// And openKeyCursor isn't supported by Safari.
(idbstore.openKeyCursor || idbstore.openCursor).call(idbstore).onsuccess =
function () {
if (!this.result) return;
dbkeys.push(this.result.key);
this.result.continue();
};
(store.openKeyCursor || store.openCursor).call(
store
).onsuccess = function () {
if (!this.result) return;
dbkeys.push(this.result.key);
this.result.continue();
};
})
.then(() => dbkeys);
}

View File

@ -3,7 +3,8 @@ import sections from "./ui/sections";
import { nextAnimationFrame } from "./utils";
import { searchBox } from "./scripts/search";
import unknown from "@/assets/images/tab-icons/unknown.svg";
// @ts-expect-error: Parcel image import
import unknown from "~/assets/images/tab-icons/unknown.svg";
import { bindFunctions } from "./scripts/index";
// Enable single page mode for developing scripts
@ -73,9 +74,7 @@ async function load() {
});
}
if ("serviceWorker" in navigator) {
const x = import.meta.env.VITE_SUBDIR
? `${import.meta.env.VITE_SUBDIR}/sw.js`
: "sw.js";
const x = process.env.SUBPATH ? `${process.env.SUBPATH}/sw.js` : "sw.js";
navigator.serviceWorker
.register(x)
.then((registration) => {
@ -95,6 +94,4 @@ document.body.appendChild(searchBox());
// Add revision info
document
.getElementById("tgh-version")
.appendChild(
document.createTextNode(import.meta.env.VITE_APP_REVISION || "unknown")
);
.appendChild(document.createTextNode(process.env.REVISION || "unknown"));

View File

@ -18,30 +18,22 @@ export const PAGE_VERSIONS = {
const MAX_WIDTH = 440;
export function processHTML(root: HTMLElement, docname: string): void {
try {
processGlobal(root, docname);
} catch (e) {
console.error(`Error processing page: ${docname}`);
}
processGlobal(root, docname);
try {
switch (docname) {
case "Guide_to_chemistry":
processChemistry(root);
break;
case "Infections":
processVirology(root);
break;
case "Guide_to_food":
processFood(root);
break;
case "Guide_to_drinks":
processDrinks(root);
break;
default:
}
} catch (e) {
console.error(`Error processing page: ${docname} (specific enhancements)`);
switch (docname) {
case "Guide_to_chemistry":
processChemistry(root);
break;
case "Infections":
processVirology(root);
break;
case "Guide_to_food":
processFood(root);
break;
case "Guide_to_drinks":
processDrinks(root);
break;
default:
}
}

View File

@ -204,13 +204,12 @@ export function chemistryScript(root: HTMLElement): void {
);
registerSearchEntries(
Array.from(
root.querySelectorAll<HTMLElement>(
"table.wikitable > tbody > tr:not(:first-child) th .reagent-header"
)
).map((element, id) => ({
el.map((element, id) => ({
page: "Guide_to_chemistry",
name: element.textContent.trim().replace(/\n.+$/gm, "").replace("▮", ""),
name: element
.querySelector("th .reagent-header")
.textContent.trim()
.replace("▮", ""),
element,
alignment: "center",
id,

View File

@ -41,7 +41,6 @@ export function processFood(root: HTMLElement): void {
];
baseFoodTables.forEach(({ selector, title, process }) => {
const table = root.querySelector<HTMLElement>(`${selector} .wikitable`);
if (!table) return;
const foods = parseTable(table).map((row) => {
const foodBlock = document.createElement("td");
foodBlock.innerHTML = `<div class="food-block">
@ -109,7 +108,6 @@ export function processFood(root: HTMLElement): void {
];
foodRecipesTables.forEach((selector) => {
const table = root.querySelector<HTMLElement>(`${selector} .wikitable`);
if (!table) return;
const recipes = parseTable(table).map((row) => {
const foodBlock = document.createElement("td");
foodBlock.innerHTML = `

View File

@ -2,7 +2,7 @@ import { registerSearchEntries } from "../search";
export function genericScript(root: HTMLElement, docname: string): void {
const el = Array.from(
root.querySelectorAll<HTMLElement>(".mw-headline-cont[id][data-name]")
root.querySelectorAll<HTMLElement>("div.mw-headline-cont[id][data-name]")
);
// Init fuzzy search with headlines

View File

@ -75,10 +75,7 @@ export function processGlobal(root: HTMLElement, docname: string): void {
if (toc) {
const tocHeader = toc.querySelector("h2");
toc.parentNode.insertBefore(tocHeader, toc);
const tocTitle = toc.querySelector("#toctitle");
if (tocTitle != null) {
toc.removeChild(tocTitle);
}
toc.removeChild(toc.querySelector("#toctitle"));
}
// Group headers and content so stickies don't overlap
@ -102,16 +99,10 @@ export function processGlobal(root: HTMLElement, docname: string): void {
const container = findParent(span, (el) =>
el.classList.contains("mw-headline-cont")
);
if (
container &&
container.querySelectorAll<HTMLElement>(".mw-headline").length === 1
) {
if (container) {
container.id = span.id;
span.id += "-span";
container.dataset.name = span.textContent;
} else {
span.dataset.name = span.textContent;
span.classList.add("mw-headline-cont");
}
});
}

View File

@ -30,8 +30,8 @@ export function searchBox(): HTMLElement {
const jumpTo = (entry: SearchEntry) => {
// If page is different jump to that
if (global) {
const currentPage =
document.querySelector<HTMLElement>(".page.active").dataset.tab;
const currentPage = document.querySelector<HTMLElement>(".page.active")
.dataset.tab;
if (currentPage !== entry.page) {
TabManager.instance.setActive(entry.page);
}
@ -193,8 +193,9 @@ export function searchBox(): HTMLElement {
return;
default:
if (sel.value !== oldValue) {
const currentPage =
document.querySelector<HTMLElement>(".page.active");
const currentPage = document.querySelector<HTMLElement>(
".page.active"
);
search(sel.value, currentPage.dataset.tab);
oldValue = sel.value;
}

View File

@ -1,4 +1,5 @@
import speen from "@/assets/images/speen.svg";
// @ts-expect-error: Asset imports are handled by parcel
import speen from "~/assets/images/speen.svg";
import { getPageHTML } from "../wiki";
import {
processHTML,
@ -9,7 +10,8 @@ import {
import cache from "../cache";
import { nextAnimationFrame, delay } from "../utils";
import unknown from "@/assets/images/tab-icons/unknown.svg";
// @ts-expect-error: Parcel image import
import unknown from "~/assets/images/tab-icons/unknown.svg";
function initWaiting(elem: HTMLElement) {
// Add spinner
@ -185,8 +187,9 @@ export default class TabManager {
* @param name Section name
*/
showSection(name: string): void {
const active =
this.sectionListContainer.querySelector<HTMLElement>(".active");
const active = this.sectionListContainer.querySelector<HTMLElement>(
".active"
);
if (active) {
// De-activate current section
active.classList.remove("active");
@ -295,8 +298,9 @@ export default class TabManager {
.forEach((it) => it.classList.remove("active"));
// If section is not shown, show it!
const isSectionActive =
this.sections[section].element.classList.contains("active");
const isSectionActive = this.sections[section].element.classList.contains(
"active"
);
if (!isSectionActive) {
this.showSection(section);
}

View File

@ -1,55 +1,107 @@
import chemistry from "@/assets/images/tab-icons/chemistry.svg";
import medicine from "@/assets/images/tab-icons/medicine.svg";
import plumbing from "@/assets/images/tab-icons/plumbing.svg";
import grenade from "@/assets/images/tab-icons/grenade.svg";
import genetics from "@/assets/images/tab-icons/genetics.svg";
import virus from "@/assets/images/tab-icons/virus.svg";
import surgery from "@/assets/images/tab-icons/surgery.svg";
import trauma from "@/assets/images/tab-icons/trauma.svg";
import wound from "@/assets/images/tab-icons/wound.svg";
import ghetto from "@/assets/images/tab-icons/ghetto.svg";
import construction from "@/assets/images/tab-icons/construction.svg";
import machines from "@/assets/images/tab-icons/machines.svg";
import power from "@/assets/images/tab-icons/power.svg";
import solar from "@/assets/images/tab-icons/solar.svg";
import supermatter from "@/assets/images/tab-icons/supermatter.svg";
import shield from "@/assets/images/tab-icons/shield.svg";
import turbine from "@/assets/images/tab-icons/turbine.svg";
import atmos from "@/assets/images/tab-icons/atmos.svg";
import tcomm from "@/assets/images/tab-icons/tcomm.svg";
import rnd from "@/assets/images/tab-icons/rnd.svg";
import toxins from "@/assets/images/tab-icons/toxins.svg";
import xeno from "@/assets/images/tab-icons/xeno.svg";
import nanites from "@/assets/images/tab-icons/nanites.svg";
import rules from "@/assets/images/tab-icons/rules.svg";
import aimod from "@/assets/images/tab-icons/aimod.svg";
import tips from "@/assets/images/tab-icons/tips.svg";
import critter from "@/assets/images/tab-icons/critter.svg";
import races from "@/assets/images/tab-icons/races.svg";
import food from "@/assets/images/tab-icons/food.svg";
import hydro from "@/assets/images/tab-icons/hydro.svg";
import song from "@/assets/images/tab-icons/song.svg";
import crate from "@/assets/images/tab-icons/crate.svg";
import space from "@/assets/images/tab-icons/space.svg";
import aux from "@/assets/images/tab-icons/auxbase.svg";
import robo from "@/assets/images/tab-icons/robo.svg";
import security from "@/assets/images/tab-icons/security.svg";
import law from "@/assets/images/tab-icons/law.svg";
import sop from "@/assets/images/tab-icons/sop.svg";
import trial from "@/assets/images/tab-icons/trial.svg";
import traitor from "@/assets/images/tab-icons/traitor.svg";
import hacking from "@/assets/images/tab-icons/hacking.svg";
import weapons from "@/assets/images/tab-icons/weapons.svg";
import uplink from "@/assets/images/tab-icons/uplink.svg";
import rev from "@/assets/images/tab-icons/rev.svg";
import cult from "@/assets/images/tab-icons/cult.svg";
import nuke from "@/assets/images/tab-icons/nuke.svg";
import malf from "@/assets/images/tab-icons/malf.svg";
import combat from "@/assets/images/tab-icons/combat.svg";
import access from "@/assets/images/tab-icons/access.svg";
import xmorph from "@/assets/images/tab-icons/xmorph.svg";
import abduction from "@/assets/images/tab-icons/abduction.svg";
import mafia from "@/assets/images/tab-icons/mafia.svg";
// @ts-expect-error: Parcel image import
import chemistry from "~/assets/images/tab-icons/chemistry.svg";
// @ts-expect-error: Parcel image import
import medicine from "~/assets/images/tab-icons/medicine.svg";
// @ts-expect-error: Parcel image import
import plumbing from "~/assets/images/tab-icons/plumbing.svg";
// @ts-expect-error: Parcel image import
import grenade from "~/assets/images/tab-icons/grenade.svg";
// @ts-expect-error: Parcel image import
import genetics from "~/assets/images/tab-icons/genetics.svg";
// @ts-expect-error: Parcel image import
import virus from "~/assets/images/tab-icons/virus.svg";
// @ts-expect-error: Parcel image import
import surgery from "~/assets/images/tab-icons/surgery.svg";
// @ts-expect-error: Parcel image import
import trauma from "~/assets/images/tab-icons/trauma.svg";
// @ts-expect-error: Parcel image import
import wound from "~/assets/images/tab-icons/wound.svg";
// @ts-expect-error: Parcel image import
import ghetto from "~/assets/images/tab-icons/ghetto.svg";
// @ts-expect-error: Parcel image import
import construction from "~/assets/images/tab-icons/construction.svg";
// @ts-expect-error: Parcel image import
import machines from "~/assets/images/tab-icons/machines.svg";
// @ts-expect-error: Parcel image import
import power from "~/assets/images/tab-icons/power.svg";
// @ts-expect-error: Parcel image import
import solar from "~/assets/images/tab-icons/solar.svg";
// @ts-expect-error: Parcel image import
import supermatter from "~/assets/images/tab-icons/supermatter.svg";
// @ts-expect-error: Parcel image import
import shield from "~/assets/images/tab-icons/shield.svg";
// @ts-expect-error: Parcel image import
import turbine from "~/assets/images/tab-icons/turbine.svg";
// @ts-expect-error: Parcel image import
import atmos from "~/assets/images/tab-icons/atmos.svg";
// @ts-expect-error: Parcel image import
import tcomm from "~/assets/images/tab-icons/tcomm.svg";
// @ts-expect-error: Parcel image import
import rnd from "~/assets/images/tab-icons/rnd.svg";
// @ts-expect-error: Parcel image import
import toxins from "~/assets/images/tab-icons/toxins.svg";
// @ts-expect-error: Parcel image import
import xeno from "~/assets/images/tab-icons/xeno.svg";
// @ts-expect-error: Parcel image import
import nanites from "~/assets/images/tab-icons/nanites.svg";
// @ts-expect-error: Parcel image import
import rules from "~/assets/images/tab-icons/rules.svg";
// @ts-expect-error: Parcel image import
import aimod from "~/assets/images/tab-icons/aimod.svg";
// @ts-expect-error: Parcel image import
import tips from "~/assets/images/tab-icons/tips.svg";
// @ts-expect-error: Parcel image import
import critter from "~/assets/images/tab-icons/critter.svg";
// @ts-expect-error: Parcel image import
import races from "~/assets/images/tab-icons/races.svg";
// @ts-expect-error: Parcel image import
import food from "~/assets/images/tab-icons/food.svg";
// @ts-expect-error: Parcel image import
import hydro from "~/assets/images/tab-icons/hydro.svg";
// @ts-expect-error: Parcel image import
import song from "~/assets/images/tab-icons/song.svg";
// @ts-expect-error: Parcel image import
import crate from "~/assets/images/tab-icons/crate.svg";
// @ts-expect-error: Parcel image import
import space from "~/assets/images/tab-icons/space.svg";
// @ts-expect-error: Parcel image import
import aux from "~/assets/images/tab-icons/auxbase.svg";
// @ts-expect-error: Parcel image import
import robo from "~/assets/images/tab-icons/robo.svg";
// @ts-expect-error: Parcel image import
import security from "~/assets/images/tab-icons/security.svg";
// @ts-expect-error: Parcel image import
import law from "~/assets/images/tab-icons/law.svg";
// @ts-expect-error: Parcel image import
import sop from "~/assets/images/tab-icons/sop.svg";
// @ts-expect-error: Parcel image import
import trial from "~/assets/images/tab-icons/trial.svg";
// @ts-expect-error: Parcel image import
import traitor from "~/assets/images/tab-icons/traitor.svg";
// @ts-expect-error: Parcel image import
import hacking from "~/assets/images/tab-icons/hacking.svg";
// @ts-expect-error: Parcel image import
import weapons from "~/assets/images/tab-icons/weapons.svg";
// @ts-expect-error: Parcel image import
import uplink from "~/assets/images/tab-icons/uplink.svg";
// @ts-expect-error: Parcel image import
import rev from "~/assets/images/tab-icons/rev.svg";
// @ts-expect-error: Parcel image import
import cult from "~/assets/images/tab-icons/cult.svg";
// @ts-expect-error: Parcel image import
import nuke from "~/assets/images/tab-icons/nuke.svg";
// @ts-expect-error: Parcel image import
import malf from "~/assets/images/tab-icons/malf.svg";
// @ts-expect-error: Parcel image import
import combat from "~/assets/images/tab-icons/combat.svg";
// @ts-expect-error: Parcel image import
import access from "~/assets/images/tab-icons/access.svg";
// @ts-expect-error: Parcel image import
import xmorph from "~/assets/images/tab-icons/xmorph.svg";
// @ts-expect-error: Parcel image import
import abduction from "~/assets/images/tab-icons/abduction.svg";
// @ts-expect-error: Parcel image import
import mafia from "~/assets/images/tab-icons/mafia.svg";
export interface SectionInfo {
name: string;

View File

@ -1,7 +1,5 @@
export function nextAnimationFrame(): Promise<void> {
return new Promise((resolve) => {
requestAnimationFrame(() => resolve());
});
return new Promise((resolve) => requestAnimationFrame(() => resolve()));
}
export function delay(ms: number): Promise<void> {

View File

@ -1,11 +1,9 @@
{
"compilerOptions": {
"target": "es2020",
"module": "es2020",
"target": "ES2020",
"baseUrl": ".",
"allowSyntheticDefaultImports": true,
"paths": {
"@": ["."],
"~*": ["./src/*"]
}
}

View File

@ -1,19 +0,0 @@
import path from "path";
import { defineConfig } from "vite";
import { VitePWA } from "vite-plugin-pwa";
export default defineConfig({
plugins: [
VitePWA({
devOptions: {
enabled: true,
},
}),
],
resolve: {
alias: {
"~": path.resolve(__dirname, "./src"),
"@": path.resolve(__dirname),
},
},
});

6637
yarn.lock Normal file

File diff suppressed because it is too large Load Diff