Update prettier config + Run pnpm format

This commit is contained in:
venashial
2022-05-26 19:17:15 -07:00
parent 89571d57bd
commit 8d4da009af
62 changed files with 8612 additions and 8618 deletions

View File

@@ -1,20 +1,20 @@
module.exports = { module.exports = {
root: true, root: true,
parser: '@typescript-eslint/parser', parser: '@typescript-eslint/parser',
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'], extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
plugins: ['svelte3', '@typescript-eslint'], plugins: ['svelte3', '@typescript-eslint'],
ignorePatterns: ['*.cjs'], ignorePatterns: ['*.cjs'],
overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }], overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }],
settings: { settings: {
'svelte3/typescript': () => require('typescript'), 'svelte3/typescript': () => require('typescript'),
}, },
parserOptions: { parserOptions: {
sourceType: 'module', sourceType: 'module',
ecmaVersion: 2020, ecmaVersion: 2020,
}, },
env: { env: {
browser: true, browser: true,
es2017: true, es2017: true,
node: true, node: true,
}, },
}; }

View File

@@ -3,16 +3,16 @@ name: Deploy
on: push on: push
jobs: jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Wait for CF Pages - name: Wait for CF Pages
id: cf-pages id: cf-pages
uses: WalshyDev/cf-pages-await@v1 uses: WalshyDev/cf-pages-await@v1
with: with:
accountEmail: ${{ secrets.CF_ACCOUNT_EMAIL }} accountEmail: ${{ secrets.CF_ACCOUNT_EMAIL }}
apiKey: ${{ secrets.CF_API_KEY }} apiKey: ${{ secrets.CF_API_KEY }}
accountId: '9ddae624c98677d68d93df6e524a6061' accountId: '9ddae624c98677d68d93df6e524a6061'
project: 'omorphia' project: 'omorphia'
githubToken: ${{ secrets.GITHUB_TOKEN }} githubToken: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,50 +1,50 @@
name: Release name: Release
on: on:
push: push:
branches: branches:
- 'main' - 'main'
jobs: jobs:
release: release:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v2
- uses: pnpm/action-setup@v2.1.0 - uses: pnpm/action-setup@v2.1.0
with: with:
version: 6.32.0 version: 6.32.0
- name: Setup Node - name: Setup Node
uses: actions/setup-node@v2 uses: actions/setup-node@v2
with: with:
node-version: '18' node-version: '18'
registry-url: 'https://registry.npmjs.org' registry-url: 'https://registry.npmjs.org'
- name: Cache pnpm modules - name: Cache pnpm modules
uses: actions/cache@v2 uses: actions/cache@v2
with: with:
path: ~/.pnpm-store path: ~/.pnpm-store
key: ${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }} key: ${{ runner.os }}-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: | restore-keys: |
${{ runner.os }}- ${{ runner.os }}-
- name: Install dependencies - name: Install dependencies
run: pnpm install run: pnpm install
- name: Package - name: Package
run: | run: |
pnpm version patch --commit-hooks false --git-tag-version false pnpm version patch --commit-hooks false --git-tag-version false
pnpm package pnpm package
- name: Publish - name: Publish
run: | run: |
cd package cd package
pnpm publish --no-git-checks --tag alpha pnpm publish --no-git-checks --tag alpha
env: env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- uses: EndBug/add-and-commit@v9 - uses: EndBug/add-and-commit@v9
with: with:
message: 'Bump package version [skip ci]' message: 'Bump package version [skip ci]'
default_author: github_actions default_author: github_actions

View File

@@ -1,5 +1,7 @@
{ {
"singleQuote": true, "useTabs": true,
"printWidth": 100, "singleQuote": true,
"tabWidth": 4 "printWidth": 100,
"bracketSameLine": true,
"semi": false
} }

12
.vscode/settings.json vendored
View File

@@ -1,8 +1,8 @@
{ {
"editor.formatOnSave": true, "editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode", "editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnPaste": true, "editor.formatOnPaste": true,
"[javascript]": { "[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode" "editor.defaultFormatter": "esbenp.prettier-vscode"
} }
} }

View File

@@ -1,29 +1,29 @@
import { defineMDSveXConfig as defineConfig } from 'mdsvex'; import { defineMDSveXConfig as defineConfig } from 'mdsvex'
import examples from 'mdsvexamples'; import examples from 'mdsvexamples'
import path from 'path'; import path from 'path'
const config = defineConfig({ const config = defineConfig({
extensions: ['.svelte.md', '.md', '.svx'], extensions: ['.svelte.md', '.md', '.svx'],
smartypants: { smartypants: {
dashes: 'oldschool', dashes: 'oldschool',
}, },
remarkPlugins: [ remarkPlugins: [
[ [
examples, examples,
{ {
defaults: { defaults: {
Wrapper: path.resolve('./src/docs/components/Example.svelte'), Wrapper: path.resolve('./src/docs/components/Example.svelte'),
}, },
}, },
], ],
], ],
rehypePlugins: [], rehypePlugins: [],
layout: { layout: {
_: './src/docs/layout/page.svelte', _: './src/docs/layout/page.svelte',
}, },
}); })
export default config; export default config

View File

@@ -1,88 +1,88 @@
{ {
"name": "omorphia", "name": "omorphia",
"version": "0.0.26", "version": "0.0.26",
"description": "A beautiful Svelte component & style library", "description": "A beautiful Svelte component & style library",
"scripts": { "scripts": {
"dev": "svelte-kit dev", "dev": "svelte-kit dev",
"build": "svelte-kit build", "build": "svelte-kit build",
"package": "svelte-kit package", "package": "svelte-kit package",
"preview": "svelte-kit preview", "preview": "svelte-kit preview",
"prepare": "svelte-kit sync", "prepare": "svelte-kit sync",
"check": "svelte-check --tsconfig ./tsconfig.json", "check": "svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-check --tsconfig ./tsconfig.json --watch", "check:watch": "svelte-check --tsconfig ./tsconfig.json --watch",
"lint": "prettier --ignore-path .gitignore --check --plugin-search-dir=. . && eslint --ignore-path .gitignore .", "lint": "prettier --ignore-path .gitignore --check --plugin-search-dir=. . && eslint --ignore-path .gitignore .",
"format": "prettier --ignore-path .gitignore --write --plugin-search-dir=. ." "format": "prettier --ignore-path .gitignore --write --plugin-search-dir=. ."
}, },
"devDependencies": { "devDependencies": {
"@sveltejs/adapter-static": "^1.0.0-next.29", "@sveltejs/adapter-static": "^1.0.0-next.29",
"@sveltejs/kit": "next", "@sveltejs/kit": "next",
"@typescript-eslint/eslint-plugin": "^5.10.1", "@typescript-eslint/eslint-plugin": "^5.10.1",
"@typescript-eslint/parser": "^5.10.1", "@typescript-eslint/parser": "^5.10.1",
"eslint": "^7.32.0", "eslint": "^7.32.0",
"eslint-config-prettier": "^8.3.0", "eslint-config-prettier": "^8.3.0",
"eslint-plugin-svelte3": "^3.2.1", "eslint-plugin-svelte3": "^3.2.1",
"mdsvex": "^0.10.5", "mdsvex": "^0.10.5",
"mdsvexamples": "^0.3.0", "mdsvexamples": "^0.3.0",
"nodemon": "^2.0.15", "nodemon": "^2.0.15",
"prettier": "^2.6.2", "prettier": "^2.6.2",
"sveld": "^0.13.4", "sveld": "^0.13.4",
"svelte": "^3.48.0", "svelte": "^3.48.0",
"svelte-check": "^2.2.6", "svelte-check": "^2.2.6",
"svelte-preprocess": "^4.10.1", "svelte-preprocess": "^4.10.1",
"svelte2tsx": "^0.5.5", "svelte2tsx": "^0.5.5",
"tslib": "^2.3.1", "tslib": "^2.3.1",
"typescript": "~4.6.2" "typescript": "~4.6.2"
}, },
"type": "module", "type": "module",
"svelte": "index.js", "svelte": "index.js",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/modrinth/omorphia.git" "url": "https://github.com/modrinth/omorphia.git"
}, },
"keywords": [ "keywords": [
"UI", "UI",
"framework", "framework",
"components", "components",
"library" "library"
], ],
"license": "MIT", "license": "MIT",
"bugs": { "bugs": {
"url": "https://github.com/modrinth/omorphia/issues" "url": "https://github.com/modrinth/omorphia/issues"
}, },
"homepage": "https://omorphia.modrinth.com", "homepage": "https://omorphia.modrinth.com",
"dependencies": { "dependencies": {
"@iconify-json/carbon": "^1.1.1", "@iconify-json/carbon": "^1.1.1",
"@iconify-json/fa-regular": "^1.1.1", "@iconify-json/fa-regular": "^1.1.1",
"@iconify-json/heroicons-outline": "^1.1.1", "@iconify-json/heroicons-outline": "^1.1.1",
"@iconify-json/heroicons-solid": "^1.1.1", "@iconify-json/heroicons-solid": "^1.1.1",
"@iconify-json/lucide": "^1.1.7", "@iconify-json/lucide": "^1.1.7",
"@poppanator/sveltekit-svg": "^0.3.1", "@poppanator/sveltekit-svg": "^0.3.1",
"autoprefixer": "^10.4.2", "autoprefixer": "^10.4.2",
"cli-progress": "^3.11.1", "cli-progress": "^3.11.1",
"cssnano": "^5.1.1", "cssnano": "^5.1.1",
"fast-average-color-node": "^2.2.0", "fast-average-color-node": "^2.2.0",
"highlight.js": "^11.5.0", "highlight.js": "^11.5.0",
"insane": "^2.6.2", "insane": "^2.6.2",
"jimp": "^0.16.1", "jimp": "^0.16.1",
"marked": "^4.0.12", "marked": "^4.0.12",
"postcss": "^8.4.8", "postcss": "^8.4.8",
"postcss-easy-import": "^4.0.0", "postcss-easy-import": "^4.0.0",
"postcss-extend-rule": "^4.0.0", "postcss-extend-rule": "^4.0.0",
"postcss-import": "^14.0.2", "postcss-import": "^14.0.2",
"postcss-import-ext-glob": "^2.0.1", "postcss-import-ext-glob": "^2.0.1",
"postcss-load-config": "^3.1.4", "postcss-load-config": "^3.1.4",
"postcss-nested": "^5.0.6", "postcss-nested": "^5.0.6",
"postcss-preset-env": "^7.4.2", "postcss-preset-env": "^7.4.2",
"postcss-pxtorem": "^6.0.0", "postcss-pxtorem": "^6.0.0",
"postcss-strip-inline-comments": "^0.1.5", "postcss-strip-inline-comments": "^0.1.5",
"sanitize.css": "^13.0.0", "sanitize.css": "^13.0.0",
"svelte-tiny-virtual-list": "^2.0.1", "svelte-tiny-virtual-list": "^2.0.1",
"svelte-use-click-outside": "^1.0.0", "svelte-use-click-outside": "^1.0.0",
"throttle-debounce": "^3.0.1", "throttle-debounce": "^3.0.1",
"undici": "^5.2.0", "undici": "^5.2.0",
"unplugin-icons": "^0.13.3" "unplugin-icons": "^0.13.3"
}, },
"engines": { "engines": {
"node": ">=16.5.0" "node": ">=16.5.0"
} }
} }

View File

@@ -1,58 +1,55 @@
import { ComponentParser } from 'sveld'; import { ComponentParser } from 'sveld'
import * as svelte from 'svelte/compiler'; import * as svelte from 'svelte/compiler'
import fs from 'fs/promises'; import fs from 'fs/promises'
import path from 'path'; import path from 'path'
import { preprocess } from '../src/package/config/svelte.config.js'; import { preprocess } from '../src/package/config/svelte.config.js'
export default function sveld() { export default function sveld() {
return { return {
name: 'vite-plugin-sveld', name: 'vite-plugin-sveld',
async transform(src, id) { async transform(src, id) {
if (id.endsWith('?raw&sveld')) { if (id.endsWith('?raw&sveld')) {
const raw = JSON.parse(src.split('export default ')[1]); const raw = JSON.parse(src.split('export default ')[1])
const data = await parseRaw(raw, id); const data = await parseRaw(raw, id)
return { return {
code: `export default ${JSON.stringify(data)}`, code: `export default ${JSON.stringify(data)}`,
map: null, map: null,
}; }
} }
}, },
// This generates a `COMPONENT_API.json` with sveld in the `/_app` folder on build, which is used by the docs about components (only when built statically) // This generates a `COMPONENT_API.json` with sveld in the `/_app` folder on build, which is used by the docs about components (only when built statically)
async buildStart() { async buildStart() {
const output = {}; const output = {}
const componentFiles = await fs.readdir(path.resolve('./src/package/components')); const componentFiles = await fs.readdir(path.resolve('./src/package/components'))
for (const fileName of componentFiles.filter((name) => name.endsWith('.svelte'))) { for (const fileName of componentFiles.filter((name) => name.endsWith('.svelte'))) {
const filePath = path.resolve('./src/package/components', fileName); const filePath = path.resolve('./src/package/components', fileName)
const raw = (await fs.readFile(filePath)).toString(); const raw = (await fs.readFile(filePath)).toString()
output[fileName] = await parseRaw(raw, filePath); output[fileName] = await parseRaw(raw, filePath)
} }
try { try {
await fs.mkdir(path.resolve('./src/generated')); await fs.mkdir(path.resolve('./src/generated'))
} catch { } catch {
// Do nothing, directory already exists // Do nothing, directory already exists
} }
await fs.writeFile( await fs.writeFile(path.resolve('./src/generated/COMPONENT_API.json'), JSON.stringify(output))
path.resolve('./src/generated/COMPONENT_API.json'), },
JSON.stringify(output) }
);
},
};
} }
async function parseRaw(raw, filePath) { async function parseRaw(raw, filePath) {
let { code } = await svelte.preprocess(raw, preprocess, { let { code } = await svelte.preprocess(raw, preprocess, {
filename: filePath, filename: filePath,
}); })
return new ComponentParser({ return new ComponentParser({
verbose: false, verbose: false,
}).parseSvelteComponent(code, { }).parseSvelteComponent(code, {
filePath, filePath,
moduleName: filePath, moduleName: filePath,
}); })
} }

13356
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1 +1 @@
module.exports = require('./src/package/config/postcss.config.cjs'); module.exports = require('./src/package/config/postcss.config.cjs')

8
src/app.d.ts vendored
View File

@@ -4,8 +4,8 @@
// See https://kit.svelte.dev/docs/types#the-app-namespace // See https://kit.svelte.dev/docs/types#the-app-namespace
// for information about these interfaces // for information about these interfaces
declare namespace App { declare namespace App {
// interface Locals {} // interface Locals {}
// interface Platform {} // interface Platform {}
// interface Session {} // interface Session {}
// interface Stuff {} // interface Stuff {}
} }

View File

@@ -1,19 +1,19 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en" data-color-mode="light"> <html lang="en" data-color-mode="light">
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="description" content="" /> <meta name="description" content="" />
<link rel="icon" href="%svelte.assets%/assets/omorphia.png" /> <link rel="icon" href="%svelte.assets%/assets/omorphia.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#CF1971" /> <meta name="theme-color" content="#CF1971" />
<meta name="twitter:card" content="summary" /> <meta name="twitter:card" content="summary" />
<meta name="twitter:image" content="https://omorphia.modrinth.com/assets/omorphia.png" /> <meta name="twitter:image" content="https://omorphia.modrinth.com/assets/omorphia.png" />
<meta property="og:site_name" content="Modrinth" /> <meta property="og:site_name" content="Modrinth" />
%svelte.head% %svelte.head%
</head> </head>
<body> <body>
%svelte.body% %svelte.body%
</body> </body>
</html> </html>

View File

@@ -1,392 +1,392 @@
*:not(.example__preview *) { *:not(.example__preview *) {
:where(a) { :where(a) {
text-decoration: none; text-decoration: none;
&.absent { &.absent {
color: #cc0000; color: #cc0000;
} }
&.anchor { &.anchor {
display: block; display: block;
padding-left: 30px; padding-left: 30px;
margin-left: -30px; margin-left: -30px;
cursor: pointer; cursor: pointer;
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
bottom: 0; bottom: 0;
} }
} }
&:where(h1, h2, h3, h4, h5, h6) { &:where(h1, h2, h3, h4, h5, h6) {
margin: 30px 0 10px; margin: 30px 0 10px;
padding: 0; padding: 0;
font-weight: bold; font-weight: bold;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
cursor: text; cursor: text;
position: relative; position: relative;
} }
&:where(h2:first-child, h1:first-child, h1:first-child &:where(h2:first-child, h1:first-child, h1:first-child
+ h2, h3:first-child, h4:first-child, h5:first-child, h6:first-child) { + h2, h3:first-child, h4:first-child, h5:first-child, h6:first-child) {
margin-top: 0; margin-top: 0;
padding-top: 0; padding-top: 0;
} }
&:where(h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover &:where(h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover
a.anchor, h6:hover a.anchor) { a.anchor, h6:hover a.anchor) {
text-decoration: none; text-decoration: none;
} }
&:where(h1 tt, h1 code) { &:where(h1 tt, h1 code) {
font-size: inherit; font-size: inherit;
} }
&:where(h2 tt, h2 code) { &:where(h2 tt, h2 code) {
font-size: inherit; font-size: inherit;
} }
&:where(h3 tt, h3 code) { &:where(h3 tt, h3 code) {
font-size: inherit; font-size: inherit;
} }
&:where(h4 tt, h4 code) { &:where(h4 tt, h4 code) {
font-size: inherit; font-size: inherit;
} }
&:where(h5 tt, h5 code) { &:where(h5 tt, h5 code) {
font-size: inherit; font-size: inherit;
} }
&:where(h6 tt, h6 code) { &:where(h6 tt, h6 code) {
font-size: inherit; font-size: inherit;
} }
&:where(h1) { &:where(h1) {
font-size: 40px; font-size: 40px;
color: black; color: black;
font-weight: 600; font-weight: 600;
@media (--md) { @media (--md) {
font-size: 54px; font-size: 54px;
} }
} }
&:where(h2) { &:where(h2) {
font-size: 24px; font-size: 24px;
/*border-bottom: 1px solid #cccccc;*/ /*border-bottom: 1px solid #cccccc;*/
color: black; color: black;
margin-top: 50px; margin-top: 50px;
} }
&:where(h3) { &:where(h3) {
font-size: 18px; font-size: 18px;
} }
&:where(h4) { &:where(h4) {
font-size: 16px; font-size: 16px;
} }
&:where(h5) { &:where(h5) {
font-size: 14px; font-size: 14px;
} }
&:where(h6) { &:where(h6) {
color: #777777; color: #777777;
font-size: 14px; font-size: 14px;
} }
&:where(p, blockquote, ul, ol, dl, li, table, pre) { &:where(p, blockquote, ul, ol, dl, li, table, pre) {
margin: 15px 0; margin: 15px 0;
} }
&:where(hr) { &:where(hr) {
border: 0 none; border: 0 none;
color: #cccccc; color: #cccccc;
height: 4px; height: 4px;
padding: 0; padding: 0;
} }
&:where(body > h2:first-child) { &:where(body > h2:first-child) {
margin-top: 0; margin-top: 0;
padding-top: 0; padding-top: 0;
} }
&:where(body > h1:first-child) { &:where(body > h1:first-child) {
margin-top: 0; margin-top: 0;
padding-top: 0; padding-top: 0;
} }
&:where(body > h1:first-child + h2) { &:where(body > h1:first-child + h2) {
margin-top: 0; margin-top: 0;
padding-top: 0; padding-top: 0;
} }
&:where(body > h3:first-child, body > h4:first-child, body > h5:first-child, body &:where(body > h3:first-child, body > h4:first-child, body > h5:first-child, body
> h6:first-child) { > h6:first-child) {
margin-top: 0; margin-top: 0;
padding-top: 0; padding-top: 0;
} }
&:where(a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child &:where(a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child
h5, a:first-child h6) { h5, a:first-child h6) {
margin-top: 0; margin-top: 0;
padding-top: 0; padding-top: 0;
} }
&:where(h1 p, h2 p, h3 p, h4 p, h5 p, h6 p) { &:where(h1 p, h2 p, h3 p, h4 p, h5 p, h6 p) {
margin-top: 0; margin-top: 0;
} }
&:where(li p.first) { &:where(li p.first) {
display: inline-block; display: inline-block;
} }
&:where(ul, ol) { &:where(ul, ol) {
padding-left: 30px; padding-left: 30px;
} }
&:where(ul :first-child, ol :first-child) { &:where(ul :first-child, ol :first-child) {
margin-top: 0; margin-top: 0;
} }
&:where(ul :last-child, ol :last-child) { &:where(ul :last-child, ol :last-child) {
margin-bottom: 0; margin-bottom: 0;
} }
&:where(dl) { &:where(dl) {
padding: 0; padding: 0;
} }
&:where(dl dt) { &:where(dl dt) {
font-size: 14px; font-size: 14px;
font-weight: bold; font-weight: bold;
font-style: italic; font-style: italic;
padding: 0; padding: 0;
margin: 15px 0 5px; margin: 15px 0 5px;
} }
&:where(dl dt:first-child) { &:where(dl dt:first-child) {
padding: 0; padding: 0;
} }
&:where(dl dt > :first-child) { &:where(dl dt > :first-child) {
margin-top: 0; margin-top: 0;
} }
&:where(dl dt > :last-child) { &:where(dl dt > :last-child) {
margin-bottom: 0; margin-bottom: 0;
} }
&:where(dl dd) { &:where(dl dd) {
margin: 0 0 15px; margin: 0 0 15px;
padding: 0 15px; padding: 0 15px;
} }
&:where(dl dd > :first-child) { &:where(dl dd > :first-child) {
margin-top: 0; margin-top: 0;
} }
&:where(dl dd > :last-child) { &:where(dl dd > :last-child) {
margin-bottom: 0; margin-bottom: 0;
} }
&:where(blockquote) { &:where(blockquote) {
border-left: 4px solid #dddddd; border-left: 4px solid #dddddd;
padding: 0 15px; padding: 0 15px;
color: #777777; color: #777777;
} }
&:where(blockquote > :first-child) { &:where(blockquote > :first-child) {
margin-top: 0; margin-top: 0;
} }
&:where(blockquote > :last-child) { &:where(blockquote > :last-child) {
margin-bottom: 0; margin-bottom: 0;
} }
&:where(table) { &:where(table) {
padding: 0; padding: 0;
} }
&:where(table tr) { &:where(table tr) {
border-top: 1px solid #cccccc; border-top: 1px solid #cccccc;
background-color: white; background-color: white;
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
&:where(table tr:nth-child(2n)) { &:where(table tr:nth-child(2n)) {
background-color: #f8f8f8; background-color: #f8f8f8;
} }
&:where(table tr th) { &:where(table tr th) {
font-weight: bold; font-weight: bold;
border: 1px solid #cccccc; border: 1px solid #cccccc;
text-align: left; text-align: left;
margin: 0; margin: 0;
padding: 6px 13px; padding: 6px 13px;
} }
&:where(table tr td) { &:where(table tr td) {
border: 1px solid #cccccc; border: 1px solid #cccccc;
text-align: left; text-align: left;
margin: 0; margin: 0;
padding: 6px 13px; padding: 6px 13px;
} }
&:where(table tr th :first-child, table tr td :first-child) { &:where(table tr th :first-child, table tr td :first-child) {
margin-top: 0; margin-top: 0;
} }
&:where(table tr th :last-child, table tr td :last-child) { &:where(table tr th :last-child, table tr td :last-child) {
margin-bottom: 0; margin-bottom: 0;
} }
&:where(img) { &:where(img) {
max-width: 100%; max-width: 100%;
} }
&:where(span.frame) { &:where(span.frame) {
display: block; display: block;
overflow: hidden; overflow: hidden;
} }
&:where(span.frame > span) { &:where(span.frame > span) {
border: 1px solid #dddddd; border: 1px solid #dddddd;
display: block; display: block;
float: left; float: left;
overflow: hidden; overflow: hidden;
margin: 13px 0 0; margin: 13px 0 0;
padding: 7px; padding: 7px;
width: auto; width: auto;
} }
&:where(span.frame span img) { &:where(span.frame span img) {
display: block; display: block;
float: left; float: left;
} }
&:where(span.frame span span) { &:where(span.frame span span) {
clear: both; clear: both;
color: #333333; color: #333333;
display: block; display: block;
padding: 5px 0 0; padding: 5px 0 0;
} }
&:where(span.align-center) { &:where(span.align-center) {
display: block; display: block;
overflow: hidden; overflow: hidden;
clear: both; clear: both;
} }
&:where(span.align-center > span) { &:where(span.align-center > span) {
display: block; display: block;
overflow: hidden; overflow: hidden;
margin: 13px auto 0; margin: 13px auto 0;
text-align: center; text-align: center;
} }
&:where(span.align-center span img) { &:where(span.align-center span img) {
margin: 0 auto; margin: 0 auto;
text-align: center; text-align: center;
} }
&:where(span.align-right) { &:where(span.align-right) {
display: block; display: block;
overflow: hidden; overflow: hidden;
clear: both; clear: both;
} }
&:where(span.align-right > span) { &:where(span.align-right > span) {
display: block; display: block;
overflow: hidden; overflow: hidden;
margin: 13px 0 0; margin: 13px 0 0;
text-align: right; text-align: right;
} }
&:where(span.align-right span img) { &:where(span.align-right span img) {
margin: 0; margin: 0;
text-align: right; text-align: right;
} }
&:where(span.float-left) { &:where(span.float-left) {
display: block; display: block;
margin-right: 13px; margin-right: 13px;
overflow: hidden; overflow: hidden;
float: left; float: left;
} }
&:where(span.float-left span) { &:where(span.float-left span) {
margin: 13px 0 0; margin: 13px 0 0;
} }
&:where(span.float-right) { &:where(span.float-right) {
display: block; display: block;
margin-left: 13px; margin-left: 13px;
overflow: hidden; overflow: hidden;
float: right; float: right;
} }
&:where(span.float-right > span) { &:where(span.float-right > span) {
display: block; display: block;
overflow: hidden; overflow: hidden;
margin: 13px auto 0; margin: 13px auto 0;
text-align: right; text-align: right;
} }
&:where(code, tt) { &:where(code, tt) {
margin: 0 2px; margin: 0 2px;
padding: 0 5px; padding: 0 5px;
white-space: nowrap; white-space: nowrap;
border: 1px solid #eaeaea; border: 1px solid #eaeaea;
background-color: #f8f8f8; background-color: #f8f8f8;
border-radius: 3px; border-radius: 3px;
} }
&:where(pre code) { &:where(pre code) {
margin: 0; margin: 0;
padding: 0; padding: 0;
white-space: pre; white-space: pre;
border: none; border: none;
background: transparent; background: transparent;
} }
&:where(pre) { &:where(pre) {
background-color: #f8f8f8; background-color: #f8f8f8;
font-size: 13px; font-size: 13px;
line-height: 19px; line-height: 19px;
overflow: auto; overflow: auto;
padding: 6px 10px; padding: 6px 10px;
border-radius: var(--rounded-sm) !important; border-radius: var(--rounded-sm) !important;
} }
&:where(pre code, pre tt) { &:where(pre code, pre tt) {
background-color: transparent; background-color: transparent;
border: none; border: none;
} }
&:where(h2) { &:where(h2) {
font-weight: 500; font-weight: 500;
} }
&:where(blockquote) { &:where(blockquote) {
border-left: 4px solid var(--accent-color); border-left: 4px solid var(--accent-color);
padding: 15px 15px; padding: 15px 15px;
color: unset; color: unset;
background-color: var(--accent-color-transparent); background-color: var(--accent-color-transparent);
} }
&:where(a) { &:where(a) {
color: var(--accent-color); color: var(--accent-color);
&:hover { &:hover {
text-decoration: underline; text-decoration: underline;
} }
} }
&:where(p) { &:where(p) {
line-height: 1.5; line-height: 1.5;
} }
} }

View File

@@ -30,75 +30,75 @@
code[class*='language-'], code[class*='language-'],
pre[class*='language-'] { pre[class*='language-'] {
background: hsl(220, 13%, 18%); background: hsl(220, 13%, 18%);
color: hsl(220, 14%, 71%); color: hsl(220, 14%, 71%);
text-shadow: 0 1px rgba(0, 0, 0, 0.3); text-shadow: 0 1px rgba(0, 0, 0, 0.3);
font-family: 'Fira Code', 'Fira Mono', Menlo, Consolas, 'DejaVu Sans Mono', monospace; font-family: 'Fira Code', 'Fira Mono', Menlo, Consolas, 'DejaVu Sans Mono', monospace;
direction: ltr; direction: ltr;
text-align: left; text-align: left;
white-space: pre; white-space: pre;
word-spacing: normal; word-spacing: normal;
word-break: normal; word-break: normal;
line-height: 1.5; line-height: 1.5;
-moz-tab-size: 2; -moz-tab-size: 2;
-o-tab-size: 2; -o-tab-size: 2;
tab-size: 2; tab-size: 2;
-webkit-hyphens: none; -webkit-hyphens: none;
-moz-hyphens: none; -moz-hyphens: none;
-ms-hyphens: none; -ms-hyphens: none;
hyphens: none; hyphens: none;
} }
/* Selection */ /* Selection */
code[class*='language-']::-moz-selection, code[class*='language-']::-moz-selection,
code[class*='language-'] *::-moz-selection, code[class*='language-'] *::-moz-selection,
pre[class*='language-'] *::-moz-selection { pre[class*='language-'] *::-moz-selection {
background: hsl(220, 13%, 28%); background: hsl(220, 13%, 28%);
color: inherit; color: inherit;
text-shadow: none; text-shadow: none;
} }
code[class*='language-']::selection, code[class*='language-']::selection,
code[class*='language-'] *::selection, code[class*='language-'] *::selection,
pre[class*='language-'] *::selection { pre[class*='language-'] *::selection {
background: hsl(220, 13%, 28%); background: hsl(220, 13%, 28%);
color: inherit; color: inherit;
text-shadow: none; text-shadow: none;
} }
/* Code blocks */ /* Code blocks */
pre[class*='language-'] { pre[class*='language-'] {
padding: 16px; padding: 16px;
margin: 0.5em 0; margin: 0.5em 0;
overflow: auto; overflow: auto;
border-radius: var(--rounded); border-radius: var(--rounded);
} }
/* Inline code */ /* Inline code */
:not(pre) > code[class*='language-'] { :not(pre) > code[class*='language-'] {
padding: 0.2em 0.3em; padding: 0.2em 0.3em;
border-radius: 0.3em; border-radius: 0.3em;
white-space: normal; white-space: normal;
} }
/* Print */ /* Print */
@media print { @media print {
code[class*='language-'], code[class*='language-'],
pre[class*='language-'] { pre[class*='language-'] {
text-shadow: none; text-shadow: none;
} }
} }
.token.comment, .token.comment,
.token.prolog, .token.prolog,
.token.cdata { .token.cdata {
color: hsl(220, 10%, 40%); color: hsl(220, 10%, 40%);
} }
.token.doctype, .token.doctype,
.token.punctuation, .token.punctuation,
.token.entity { .token.entity {
color: hsl(220, 14%, 71%); color: hsl(220, 14%, 71%);
} }
.token.attr-name, .token.attr-name,
@@ -107,11 +107,11 @@ pre[class*='language-'] {
.token.constant, .token.constant,
.token.number, .token.number,
.token.atrule { .token.atrule {
color: hsl(29, 54%, 61%); color: hsl(29, 54%, 61%);
} }
.token.keyword { .token.keyword {
color: hsl(286, 60%, 67%); color: hsl(286, 60%, 67%);
} }
.token.property, .token.property,
@@ -119,8 +119,8 @@ pre[class*='language-'] {
.token.symbol, .token.symbol,
.token.deleted, .token.deleted,
.token.important { .token.important {
color: hsl(355, 65%, 65%) !important; color: hsl(355, 65%, 65%) !important;
display: unset; display: unset;
} }
.token.selector, .token.selector,
@@ -131,126 +131,126 @@ pre[class*='language-'] {
.token.regex, .token.regex,
.token.attr-value, .token.attr-value,
.token.attr-value > .token.punctuation { .token.attr-value > .token.punctuation {
color: hsl(95, 38%, 62%); color: hsl(95, 38%, 62%);
} }
.token.variable, .token.variable,
.token.operator, .token.operator,
.token.function { .token.function {
color: hsl(207, 82%, 66%); color: hsl(207, 82%, 66%);
} }
.token.url { .token.url {
color: hsl(187, 47%, 55%); color: hsl(187, 47%, 55%);
} }
/* HTML overrides */ /* HTML overrides */
.token.attr-value > .token.punctuation.attr-equals, .token.attr-value > .token.punctuation.attr-equals,
.token.special-attr > .token.attr-value > .token.value.css { .token.special-attr > .token.attr-value > .token.value.css {
color: hsl(220, 14%, 71%); color: hsl(220, 14%, 71%);
} }
/* CSS overrides */ /* CSS overrides */
.language-css .token.selector { .language-css .token.selector {
color: hsl(355, 65%, 65%); color: hsl(355, 65%, 65%);
} }
.language-css .token.property { .language-css .token.property {
color: hsl(220, 14%, 71%); color: hsl(220, 14%, 71%);
} }
.language-css .token.function, .language-css .token.function,
.language-css .token.url > .token.function { .language-css .token.url > .token.function {
color: hsl(187, 47%, 55%); color: hsl(187, 47%, 55%);
} }
.language-css .token.url > .token.string.url { .language-css .token.url > .token.string.url {
color: hsl(95, 38%, 62%); color: hsl(95, 38%, 62%);
} }
.language-css .token.important, .language-css .token.important,
.language-css .token.atrule .token.rule { .language-css .token.atrule .token.rule {
color: hsl(286, 60%, 67%); color: hsl(286, 60%, 67%);
} }
/* JS overrides */ /* JS overrides */
.language-javascript .token.operator { .language-javascript .token.operator {
color: hsl(286, 60%, 67%); color: hsl(286, 60%, 67%);
} }
.language-javascript .language-javascript
.token.template-string .token.template-string
> .token.interpolation > .token.interpolation
> .token.interpolation-punctuation.punctuation { > .token.interpolation-punctuation.punctuation {
color: hsl(5, 48%, 51%); color: hsl(5, 48%, 51%);
} }
/* JSON overrides */ /* JSON overrides */
.language-json .token.operator { .language-json .token.operator {
color: hsl(220, 14%, 71%); color: hsl(220, 14%, 71%);
} }
.language-json .token.null.keyword { .language-json .token.null.keyword {
color: hsl(29, 54%, 61%); color: hsl(29, 54%, 61%);
} }
/* MD overrides */ /* MD overrides */
.language-markdown .token.url, .language-markdown .token.url,
.language-markdown .token.url > .token.operator, .language-markdown .token.url > .token.operator,
.language-markdown .token.url-reference.url > .token.string { .language-markdown .token.url-reference.url > .token.string {
color: hsl(220, 14%, 71%); color: hsl(220, 14%, 71%);
} }
.language-markdown .token.url > .token.content { .language-markdown .token.url > .token.content {
color: hsl(207, 82%, 66%); color: hsl(207, 82%, 66%);
} }
.language-markdown .token.url > .token.url, .language-markdown .token.url > .token.url,
.language-markdown .token.url-reference.url { .language-markdown .token.url-reference.url {
color: hsl(187, 47%, 55%); color: hsl(187, 47%, 55%);
} }
.language-markdown .token.blockquote.punctuation, .language-markdown .token.blockquote.punctuation,
.language-markdown .token.hr.punctuation { .language-markdown .token.hr.punctuation {
color: hsl(220, 10%, 40%); color: hsl(220, 10%, 40%);
font-style: italic; font-style: italic;
} }
.language-markdown .token.code-snippet { .language-markdown .token.code-snippet {
color: hsl(95, 38%, 62%); color: hsl(95, 38%, 62%);
} }
.language-markdown .token.bold .token.content { .language-markdown .token.bold .token.content {
color: hsl(29, 54%, 61%); color: hsl(29, 54%, 61%);
} }
.language-markdown .token.italic .token.content { .language-markdown .token.italic .token.content {
color: hsl(286, 60%, 67%); color: hsl(286, 60%, 67%);
} }
.language-markdown .token.strike .token.content, .language-markdown .token.strike .token.content,
.language-markdown .token.strike .token.punctuation, .language-markdown .token.strike .token.punctuation,
.language-markdown .token.list.punctuation, .language-markdown .token.list.punctuation,
.language-markdown .token.title.important > .token.punctuation { .language-markdown .token.title.important > .token.punctuation {
color: hsl(355, 65%, 65%); color: hsl(355, 65%, 65%);
} }
/* General */ /* General */
.token.bold { .token.bold {
font-weight: bold; font-weight: bold;
} }
.token.comment, .token.comment,
.token.italic { .token.italic {
font-style: italic; font-style: italic;
} }
.token.entity { .token.entity {
cursor: help; cursor: help;
} }
.token.namespace { .token.namespace {
opacity: 0.8; opacity: 0.8;
} }
/* Plugin overrides */ /* Plugin overrides */
@@ -261,24 +261,24 @@ pre[class*='language-'] {
.token.token.cr:before, .token.token.cr:before,
.token.token.lf:before, .token.token.lf:before,
.token.token.space:before { .token.token.space:before {
color: hsla(220, 14%, 71%, 0.15); color: hsla(220, 14%, 71%, 0.15);
text-shadow: none; text-shadow: none;
} }
/* Toolbar plugin overrides */ /* Toolbar plugin overrides */
/* Space out all buttons and move them away from the right edge of the code block */ /* Space out all buttons and move them away from the right edge of the code block */
div.code-toolbar > .toolbar.toolbar > .toolbar-item { div.code-toolbar > .toolbar.toolbar > .toolbar-item {
margin-right: 0.4em; margin-right: 0.4em;
} }
/* Styling the buttons */ /* Styling the buttons */
div.code-toolbar > .toolbar.toolbar > .toolbar-item > button, div.code-toolbar > .toolbar.toolbar > .toolbar-item > button,
div.code-toolbar > .toolbar.toolbar > .toolbar-item > a, div.code-toolbar > .toolbar.toolbar > .toolbar-item > a,
div.code-toolbar > .toolbar.toolbar > .toolbar-item > span { div.code-toolbar > .toolbar.toolbar > .toolbar-item > span {
background: hsl(220, 13%, 26%); background: hsl(220, 13%, 26%);
color: hsl(220, 9%, 55%); color: hsl(220, 9%, 55%);
padding: 0.1em 0.4em; padding: 0.1em 0.4em;
border-radius: 0.3em; border-radius: 0.3em;
} }
div.code-toolbar > .toolbar.toolbar > .toolbar-item > button:hover, div.code-toolbar > .toolbar.toolbar > .toolbar-item > button:hover,
@@ -287,43 +287,43 @@ div.code-toolbar > .toolbar.toolbar > .toolbar-item > a:hover,
div.code-toolbar > .toolbar.toolbar > .toolbar-item > a:focus, div.code-toolbar > .toolbar.toolbar > .toolbar-item > a:focus,
div.code-toolbar > .toolbar.toolbar > .toolbar-item > span:hover, div.code-toolbar > .toolbar.toolbar > .toolbar-item > span:hover,
div.code-toolbar > .toolbar.toolbar > .toolbar-item > span:focus { div.code-toolbar > .toolbar.toolbar > .toolbar-item > span:focus {
background: hsl(220, 13%, 28%); background: hsl(220, 13%, 28%);
color: hsl(220, 14%, 71%); color: hsl(220, 14%, 71%);
} }
/* Line Highlight plugin overrides */ /* Line Highlight plugin overrides */
/* The highlighted line itself */ /* The highlighted line itself */
.line-highlight.line-highlight { .line-highlight.line-highlight {
background: hsla(220, 100%, 80%, 0.04); background: hsla(220, 100%, 80%, 0.04);
} }
/* Default line numbers in Line Highlight plugin */ /* Default line numbers in Line Highlight plugin */
.line-highlight.line-highlight:before, .line-highlight.line-highlight:before,
.line-highlight.line-highlight[data-end]:after { .line-highlight.line-highlight[data-end]:after {
background: hsl(220, 13%, 26%); background: hsl(220, 13%, 26%);
color: hsl(220, 14%, 71%); color: hsl(220, 14%, 71%);
padding: 0.1em 0.6em; padding: 0.1em 0.6em;
border-radius: 0.3em; border-radius: 0.3em;
box-shadow: 0 2px 0 0 rgba(0, 0, 0, 0.2); /* same as Toolbar plugin default */ box-shadow: 0 2px 0 0 rgba(0, 0, 0, 0.2); /* same as Toolbar plugin default */
} }
/* Hovering over a linkable line number (in the gutter area) */ /* Hovering over a linkable line number (in the gutter area) */
/* Requires Line Numbers plugin as well */ /* Requires Line Numbers plugin as well */
pre[id].linkable-line-numbers.linkable-line-numbers span.line-numbers-rows > span:hover:before { pre[id].linkable-line-numbers.linkable-line-numbers span.line-numbers-rows > span:hover:before {
background-color: hsla(220, 100%, 80%, 0.04); background-color: hsla(220, 100%, 80%, 0.04);
} }
/* Line Numbers and Command Line plugins overrides */ /* Line Numbers and Command Line plugins overrides */
/* Line separating gutter from coding area */ /* Line separating gutter from coding area */
.line-numbers.line-numbers .line-numbers-rows, .line-numbers.line-numbers .line-numbers-rows,
.command-line .command-line-prompt { .command-line .command-line-prompt {
border-right-color: hsla(220, 14%, 71%, 0.15); border-right-color: hsla(220, 14%, 71%, 0.15);
} }
/* Stuff in the gutter */ /* Stuff in the gutter */
.line-numbers .line-numbers-rows > span:before, .line-numbers .line-numbers-rows > span:before,
.command-line .command-line-prompt > span:before { .command-line .command-line-prompt > span:before {
color: hsl(220, 14%, 45%); color: hsl(220, 14%, 45%);
} }
/* Match Braces plugin overrides */ /* Match Braces plugin overrides */
@@ -331,65 +331,65 @@ pre[id].linkable-line-numbers.linkable-line-numbers span.line-numbers-rows > spa
.rainbow-braces .token.token.punctuation.brace-level-1, .rainbow-braces .token.token.punctuation.brace-level-1,
.rainbow-braces .token.token.punctuation.brace-level-5, .rainbow-braces .token.token.punctuation.brace-level-5,
.rainbow-braces .token.token.punctuation.brace-level-9 { .rainbow-braces .token.token.punctuation.brace-level-9 {
color: hsl(355, 65%, 65%); color: hsl(355, 65%, 65%);
} }
.rainbow-braces .token.token.punctuation.brace-level-2, .rainbow-braces .token.token.punctuation.brace-level-2,
.rainbow-braces .token.token.punctuation.brace-level-6, .rainbow-braces .token.token.punctuation.brace-level-6,
.rainbow-braces .token.token.punctuation.brace-level-10 { .rainbow-braces .token.token.punctuation.brace-level-10 {
color: hsl(95, 38%, 62%); color: hsl(95, 38%, 62%);
} }
.rainbow-braces .token.token.punctuation.brace-level-3, .rainbow-braces .token.token.punctuation.brace-level-3,
.rainbow-braces .token.token.punctuation.brace-level-7, .rainbow-braces .token.token.punctuation.brace-level-7,
.rainbow-braces .token.token.punctuation.brace-level-11 { .rainbow-braces .token.token.punctuation.brace-level-11 {
color: hsl(207, 82%, 66%); color: hsl(207, 82%, 66%);
} }
.rainbow-braces .token.token.punctuation.brace-level-4, .rainbow-braces .token.token.punctuation.brace-level-4,
.rainbow-braces .token.token.punctuation.brace-level-8, .rainbow-braces .token.token.punctuation.brace-level-8,
.rainbow-braces .token.token.punctuation.brace-level-12 { .rainbow-braces .token.token.punctuation.brace-level-12 {
color: hsl(286, 60%, 67%); color: hsl(286, 60%, 67%);
} }
/* Diff Highlight plugin overrides */ /* Diff Highlight plugin overrides */
/* Taken from https://github.com/atom/github/blob/master/styles/variables.less */ /* Taken from https://github.com/atom/github/blob/master/styles/variables.less */
pre.diff-highlight > code .token.token.deleted:not(.prefix), pre.diff-highlight > code .token.token.deleted:not(.prefix),
pre > code.diff-highlight .token.token.deleted:not(.prefix) { pre > code.diff-highlight .token.token.deleted:not(.prefix) {
background-color: hsla(353, 100%, 66%, 0.15); background-color: hsla(353, 100%, 66%, 0.15);
} }
pre.diff-highlight > code .token.token.deleted:not(.prefix)::-moz-selection, pre.diff-highlight > code .token.token.deleted:not(.prefix)::-moz-selection,
pre.diff-highlight > code .token.token.deleted:not(.prefix) *::-moz-selection, pre.diff-highlight > code .token.token.deleted:not(.prefix) *::-moz-selection,
pre > code.diff-highlight .token.token.deleted:not(.prefix)::-moz-selection, pre > code.diff-highlight .token.token.deleted:not(.prefix)::-moz-selection,
pre > code.diff-highlight .token.token.deleted:not(.prefix) *::-moz-selection { pre > code.diff-highlight .token.token.deleted:not(.prefix) *::-moz-selection {
background-color: hsla(353, 95%, 66%, 0.25); background-color: hsla(353, 95%, 66%, 0.25);
} }
pre.diff-highlight > code .token.token.deleted:not(.prefix)::selection, pre.diff-highlight > code .token.token.deleted:not(.prefix)::selection,
pre.diff-highlight > code .token.token.deleted:not(.prefix) *::selection, pre.diff-highlight > code .token.token.deleted:not(.prefix) *::selection,
pre > code.diff-highlight .token.token.deleted:not(.prefix)::selection, pre > code.diff-highlight .token.token.deleted:not(.prefix)::selection,
pre > code.diff-highlight .token.token.deleted:not(.prefix) *::selection { pre > code.diff-highlight .token.token.deleted:not(.prefix) *::selection {
background-color: hsla(353, 95%, 66%, 0.25); background-color: hsla(353, 95%, 66%, 0.25);
} }
pre.diff-highlight > code .token.token.inserted:not(.prefix), pre.diff-highlight > code .token.token.inserted:not(.prefix),
pre > code.diff-highlight .token.token.inserted:not(.prefix) { pre > code.diff-highlight .token.token.inserted:not(.prefix) {
background-color: hsla(137, 100%, 55%, 0.15); background-color: hsla(137, 100%, 55%, 0.15);
} }
pre.diff-highlight > code .token.token.inserted:not(.prefix)::-moz-selection, pre.diff-highlight > code .token.token.inserted:not(.prefix)::-moz-selection,
pre.diff-highlight > code .token.token.inserted:not(.prefix) *::-moz-selection, pre.diff-highlight > code .token.token.inserted:not(.prefix) *::-moz-selection,
pre > code.diff-highlight .token.token.inserted:not(.prefix)::-moz-selection, pre > code.diff-highlight .token.token.inserted:not(.prefix)::-moz-selection,
pre > code.diff-highlight .token.token.inserted:not(.prefix) *::-moz-selection { pre > code.diff-highlight .token.token.inserted:not(.prefix) *::-moz-selection {
background-color: hsla(135, 73%, 55%, 0.25); background-color: hsla(135, 73%, 55%, 0.25);
} }
pre.diff-highlight > code .token.token.inserted:not(.prefix)::selection, pre.diff-highlight > code .token.token.inserted:not(.prefix)::selection,
pre.diff-highlight > code .token.token.inserted:not(.prefix) *::selection, pre.diff-highlight > code .token.token.inserted:not(.prefix) *::selection,
pre > code.diff-highlight .token.token.inserted:not(.prefix)::selection, pre > code.diff-highlight .token.token.inserted:not(.prefix)::selection,
pre > code.diff-highlight .token.token.inserted:not(.prefix) *::selection { pre > code.diff-highlight .token.token.inserted:not(.prefix) *::selection {
background-color: hsla(135, 73%, 55%, 0.25); background-color: hsla(135, 73%, 55%, 0.25);
} }
/* Previewers plugin overrides */ /* Previewers plugin overrides */
@@ -397,48 +397,48 @@ pre > code.diff-highlight .token.token.inserted:not(.prefix) *::selection {
/* Border around popup */ /* Border around popup */
.prism-previewer.prism-previewer:before, .prism-previewer.prism-previewer:before,
.prism-previewer-gradient.prism-previewer-gradient div { .prism-previewer-gradient.prism-previewer-gradient div {
border-color: hsl(224, 13%, 17%); border-color: hsl(224, 13%, 17%);
} }
/* Angle and time should remain as circles and are hence not included */ /* Angle and time should remain as circles and are hence not included */
.prism-previewer-color.prism-previewer-color:before, .prism-previewer-color.prism-previewer-color:before,
.prism-previewer-gradient.prism-previewer-gradient div, .prism-previewer-gradient.prism-previewer-gradient div,
.prism-previewer-easing.prism-previewer-easing:before { .prism-previewer-easing.prism-previewer-easing:before {
border-radius: 0.3em; border-radius: 0.3em;
} }
/* Triangles pointing to the code */ /* Triangles pointing to the code */
.prism-previewer.prism-previewer:after { .prism-previewer.prism-previewer:after {
border-top-color: hsl(224, 13%, 17%); border-top-color: hsl(224, 13%, 17%);
} }
.prism-previewer-flipped.prism-previewer-flipped.after { .prism-previewer-flipped.prism-previewer-flipped.after {
border-bottom-color: hsl(224, 13%, 17%); border-bottom-color: hsl(224, 13%, 17%);
} }
/* Background colour within the popup */ /* Background colour within the popup */
.prism-previewer-angle.prism-previewer-angle:before, .prism-previewer-angle.prism-previewer-angle:before,
.prism-previewer-time.prism-previewer-time:before, .prism-previewer-time.prism-previewer-time:before,
.prism-previewer-easing.prism-previewer-easing { .prism-previewer-easing.prism-previewer-easing {
background: hsl(219, 13%, 22%); background: hsl(219, 13%, 22%);
} }
/* For angle, this is the positive area (eg. 90deg will display one quadrant in this colour) */ /* For angle, this is the positive area (eg. 90deg will display one quadrant in this colour) */
/* For time, this is the alternate colour */ /* For time, this is the alternate colour */
.prism-previewer-angle.prism-previewer-angle circle, .prism-previewer-angle.prism-previewer-angle circle,
.prism-previewer-time.prism-previewer-time circle { .prism-previewer-time.prism-previewer-time circle {
stroke: hsl(220, 14%, 71%); stroke: hsl(220, 14%, 71%);
stroke-opacity: 1; stroke-opacity: 1;
} }
/* Stroke colours of the handle, direction point, and vector itself */ /* Stroke colours of the handle, direction point, and vector itself */
.prism-previewer-easing.prism-previewer-easing circle, .prism-previewer-easing.prism-previewer-easing circle,
.prism-previewer-easing.prism-previewer-easing path, .prism-previewer-easing.prism-previewer-easing path,
.prism-previewer-easing.prism-previewer-easing line { .prism-previewer-easing.prism-previewer-easing line {
stroke: hsl(220, 14%, 71%); stroke: hsl(220, 14%, 71%);
} }
/* Fill colour of the handle */ /* Fill colour of the handle */
.prism-previewer-easing.prism-previewer-easing circle { .prism-previewer-easing.prism-previewer-easing circle {
fill: transparent; fill: transparent;
} }

6
src/global.d.ts vendored
View File

@@ -1,8 +1,8 @@
/// <reference types="vite-plugin-sveld" /> /// <reference types="vite-plugin-sveld" />
declare module '$assets/images/*'; declare module '$assets/images/*'
declare module '$locales/*'; declare module '$locales/*'
declare module '*.svg' { declare module '*.svg' {
export { SvelteComponentDev as default } from 'svelte/internal'; export { SvelteComponentDev as default } from 'svelte/internal'
} }

View File

@@ -1,8 +1,8 @@
import type { SvelteComponentDev } from 'svelte/internal'; import type { SvelteComponentDev } from 'svelte/internal'
export interface Option { export interface Option {
label: string; label: string
/** The element that will be in the `value` array while the option is checked */ /** The element that will be in the `value` array while the option is checked */
value: string | number; value: string | number
icon?: SvelteComponentDev | string; icon?: SvelteComponentDev | string
} }

View File

@@ -1,33 +1,33 @@
const config = { const config = {
plugins: [ plugins: [
require('postcss-import-ext-glob'), require('postcss-import-ext-glob'),
require('postcss-import'), require('postcss-import'),
require('postcss-strip-inline-comments'), require('postcss-strip-inline-comments'),
require('postcss-extend-rule'), require('postcss-extend-rule'),
require('postcss-nested'), require('postcss-nested'),
require('postcss-preset-env')({ require('postcss-preset-env')({
features: { features: {
'custom-media-queries': { 'custom-media-queries': {
importFrom: [ importFrom: [
{ {
customMedia: { customMedia: {
'--sm': '(min-width: 544px)', '--sm': '(min-width: 544px)',
'--md': '(min-width: 768px)', '--md': '(min-width: 768px)',
'--lg': '(min-width: 1012px)', '--lg': '(min-width: 1012px)',
'--xl': '(min-width: 1280px)', '--xl': '(min-width: 1280px)',
}, },
}, },
], ],
}, },
}, },
}), }),
require('postcss-pxtorem'), require('postcss-pxtorem'),
require('autoprefixer'), require('autoprefixer'),
process.env.NODE_ENV === 'development' && process.env.NODE_ENV === 'development' &&
require('cssnano')({ require('cssnano')({
preset: 'default', preset: 'default',
}), }),
], ],
}; }
module.exports = config; module.exports = config

View File

@@ -1,17 +1,17 @@
import sveltePreprocess from 'svelte-preprocess'; import sveltePreprocess from 'svelte-preprocess'
import Icons from 'unplugin-icons/vite'; import Icons from 'unplugin-icons/vite'
import svelteSvg from '@poppanator/sveltekit-svg'; import svelteSvg from '@poppanator/sveltekit-svg'
export const preprocess = sveltePreprocess({ export const preprocess = sveltePreprocess({
postcss: true, postcss: true,
preserve: ['ld+json'], preserve: ['ld+json'],
}); })
export const plugins = [ export const plugins = [
svelteSvg(), svelteSvg(),
Icons({ Icons({
compiler: 'svelte', compiler: 'svelte',
defaultClass: 'icon', defaultClass: 'icon',
scale: 1, scale: 1,
}), }),
]; ]

View File

@@ -1,25 +1,25 @@
/* COMPONENTS */ /* COMPONENTS */
export { default as Avatar } from './components/Avatar.svelte'; export { default as Avatar } from './components/Avatar.svelte'
export { default as Badge } from './components/Badge.svelte'; export { default as Badge } from './components/Badge.svelte'
export { default as Button } from './components/Button.svelte'; export { default as Button } from './components/Button.svelte'
export { default as Checkbox } from './components/Checkbox.svelte'; export { default as Checkbox } from './components/Checkbox.svelte'
export { default as CheckboxList } from './components/CheckboxList.svelte'; export { default as CheckboxList } from './components/CheckboxList.svelte'
export { default as CheckboxVirtualList } from './components/CheckboxVirtualList.svelte'; export { default as CheckboxVirtualList } from './components/CheckboxVirtualList.svelte'
export { default as Chips } from './components/Chips.svelte'; export { default as Chips } from './components/Chips.svelte'
export { default as FormField } from './components/FormField.svelte'; export { default as FormField } from './components/FormField.svelte'
export { default as NavRow } from './components/NavRow.svelte'; export { default as NavRow } from './components/NavRow.svelte'
export { default as Pagination } from './components/Pagination.svelte'; export { default as Pagination } from './components/Pagination.svelte'
export { default as Select } from './components/Select.svelte'; export { default as Select } from './components/Select.svelte'
export { default as Slider } from './components/Slider.svelte'; export { default as Slider } from './components/Slider.svelte'
export { default as TextInput } from './components/TextInput.svelte'; export { default as TextInput } from './components/TextInput.svelte'

View File

@@ -1,10 +1,10 @@
export default function Generator(options: PluginOptions): { export default function Generator(options: PluginOptions): {
name: string; name: string
buildStart(): Promise<void>; buildStart(): Promise<void>
}; }
export interface PluginOptions { export interface PluginOptions {
projectColors: boolean; projectColors: boolean
landingPage: boolean; landingPage: boolean
gameVersions: boolean; gameVersions: boolean
tags: boolean; tags: boolean
} }

View File

@@ -1,58 +1,58 @@
import { promises as fs } from 'fs'; import { promises as fs } from 'fs'
import { landingPage } from './outputs/landingPage.js'; import { landingPage } from './outputs/landingPage.js'
import { projectColors } from './outputs/projectColors.js'; import { projectColors } from './outputs/projectColors.js'
import { gameVersions } from './outputs/gameVersions.js'; import { gameVersions } from './outputs/gameVersions.js'
import { tags } from './outputs/tags.js'; import { tags } from './outputs/tags.js'
const API_URL = const API_URL =
process.env.VITE_API_URL && process.env.VITE_API_URL === 'https://staging-api.modrinth.com/v2/' process.env.VITE_API_URL && process.env.VITE_API_URL === 'https://staging-api.modrinth.com/v2/'
? 'https://staging-api.modrinth.com/v2/' ? 'https://staging-api.modrinth.com/v2/'
: 'https://api.modrinth.com/v2/'; : 'https://api.modrinth.com/v2/'
// Time to live: 7 days // Time to live: 7 days
const TTL = 7 * 24 * 60 * 60 * 1000; const TTL = 7 * 24 * 60 * 60 * 1000
export default function Generator(options) { export default function Generator(options) {
return { return {
name: 'rollup-plugin-omorphia-generator', name: 'rollup-plugin-omorphia-generator',
async buildStart() { async buildStart() {
let state = {}; let state = {}
try { try {
state = JSON.parse(await fs.readFile('./generated/state.json', 'utf8')); state = JSON.parse(await fs.readFile('./generated/state.json', 'utf8'))
} catch { } catch {
// File doesn't exist, create folder // File doesn't exist, create folder
await fs.mkdir('./generated', { recursive: true }); await fs.mkdir('./generated', { recursive: true })
await fs.writeFile( await fs.writeFile(
'./generated/state.json', './generated/state.json',
JSON.stringify( JSON.stringify(
{ {
options, options,
}, },
null, null,
2 2
) )
); )
} }
// Don't generate if the last generation was less than TTL and the options are the same // Don't generate if the last generation was less than TTL and the options are the same
if ( if (
state?.lastGenerated && state?.lastGenerated &&
new Date(state.lastGenerated).getTime() + TTL > new Date().getTime() && new Date(state.lastGenerated).getTime() + TTL > new Date().getTime() &&
JSON.stringify(state.options) === JSON.stringify(options) JSON.stringify(state.options) === JSON.stringify(options)
) { ) {
return; return
} }
if (options.tags) await tags(API_URL); if (options.tags) await tags(API_URL)
if (options.landingPage) await landingPage(API_URL); if (options.landingPage) await landingPage(API_URL)
if (options.gameVersions) await gameVersions(API_URL); if (options.gameVersions) await gameVersions(API_URL)
if (options.projectColors) await projectColors(API_URL); if (options.projectColors) await projectColors(API_URL)
// Write new state // Write new state
state.lastGenerated = new Date().toISOString(); state.lastGenerated = new Date().toISOString()
state.options = options; state.options = options
await fs.writeFile('./generated/state.json', JSON.stringify(state, null, 2)); await fs.writeFile('./generated/state.json', JSON.stringify(state, null, 2))
}, },
}; }
} }

View File

@@ -1 +1 @@
export declare function gameVersions(API_URL: string): Promise<void>; export declare function gameVersions(API_URL: string): Promise<void>

View File

@@ -1,22 +1,22 @@
import { fetch } from 'undici'; import { fetch } from 'undici'
import { promises as fs } from 'fs'; import { promises as fs } from 'fs'
import cliProgress from 'cli-progress'; import cliProgress from 'cli-progress'
export async function gameVersions(API_URL) { export async function gameVersions(API_URL) {
const progressBar = new cliProgress.SingleBar({ const progressBar = new cliProgress.SingleBar({
format: 'Generating game versions | {bar} | {percentage}%', format: 'Generating game versions | {bar} | {percentage}%',
barCompleteChar: '\u2588', barCompleteChar: '\u2588',
barIncompleteChar: '\u2591', barIncompleteChar: '\u2591',
hideCursor: true, hideCursor: true,
}); })
progressBar.start(2, 0); progressBar.start(2, 0)
const gameVersions = await (await fetch(API_URL + 'tag/game_version')).json(); const gameVersions = await (await fetch(API_URL + 'tag/game_version')).json()
progressBar.increment(); progressBar.increment()
// Write JSON file // Write JSON file
await fs.writeFile('./generated/gameVersions.json', JSON.stringify(gameVersions)); await fs.writeFile('./generated/gameVersions.json', JSON.stringify(gameVersions))
progressBar.increment(); progressBar.increment()
progressBar.stop(); progressBar.stop()
} }

View File

@@ -1 +1 @@
export declare function landingPage(API_URL: string): Promise<void>; export declare function landingPage(API_URL: string): Promise<void>

View File

@@ -1,40 +1,40 @@
import { fetch } from 'undici'; import { fetch } from 'undici'
import { promises as fs } from 'fs'; import { promises as fs } from 'fs'
import cliProgress from 'cli-progress'; import cliProgress from 'cli-progress'
export async function landingPage(API_URL) { export async function landingPage(API_URL) {
const progressBar = new cliProgress.SingleBar({ const progressBar = new cliProgress.SingleBar({
format: 'Generating landing page | {bar} | {percentage}% || {value}/{total} mods', format: 'Generating landing page | {bar} | {percentage}% || {value}/{total} mods',
barCompleteChar: '\u2588', barCompleteChar: '\u2588',
barIncompleteChar: '\u2591', barIncompleteChar: '\u2591',
hideCursor: true, hideCursor: true,
}); })
progressBar.start(100, 0); progressBar.start(100, 0)
// Fetch top 100 mods // Fetch top 100 mods
const response = await ( const response = await (
await fetch(API_URL + 'search?limit=100&facets=[["project_type:mod"]]') await fetch(API_URL + 'search?limit=100&facets=[["project_type:mod"]]')
).json(); ).json()
// Simplified array with the format: ['id', 'slug', 'icon_extension'] // Simplified array with the format: ['id', 'slug', 'icon_extension']
const compressed = response.hits const compressed = response.hits
.filter((project) => project.icon_url) .filter((project) => project.icon_url)
.map((project) => { .map((project) => {
progressBar.increment(); progressBar.increment()
return [ return [
project.project_id, project.project_id,
project.slug || '', project.slug || '',
project.icon_url.match(/\.[0-9a-z]+$/i)[0].substring(1), project.icon_url.match(/\.[0-9a-z]+$/i)[0].substring(1),
]; ]
}); })
// Write JSON file // Write JSON file
await fs.writeFile( await fs.writeFile(
'./generated/landingPage.json', './generated/landingPage.json',
JSON.stringify({ JSON.stringify({
mods: compressed, mods: compressed,
random: Math.random(), random: Math.random(),
}) })
); )
progressBar.stop(); progressBar.stop()
} }

View File

@@ -1 +1 @@
export declare function projectColors(API_URL: string): Promise<void>; export declare function projectColors(API_URL: string): Promise<void>

View File

@@ -1,86 +1,86 @@
import { fetch } from 'undici'; import { fetch } from 'undici'
import { promises as fs, createWriteStream } from 'fs'; import { promises as fs, createWriteStream } from 'fs'
import cliProgress from 'cli-progress'; import cliProgress from 'cli-progress'
import Jimp from 'jimp'; import Jimp from 'jimp'
import { getAverageColor } from 'fast-average-color-node'; import { getAverageColor } from 'fast-average-color-node'
// Note: This function has issues and will occasionally fail with some project icons. It averages at a 99.4% success rate. Most issues are from ECONNRESET errors & Jimp not being able to handle webp & svg images. // Note: This function has issues and will occasionally fail with some project icons. It averages at a 99.4% success rate. Most issues are from ECONNRESET errors & Jimp not being able to handle webp & svg images.
export async function projectColors(API_URL) { export async function projectColors(API_URL) {
const progressBar = new cliProgress.SingleBar({ const progressBar = new cliProgress.SingleBar({
format: 'Generating project colors | {bar} | {percentage}% || {value}/{total} projects', format: 'Generating project colors | {bar} | {percentage}% || {value}/{total} projects',
barCompleteChar: '\u2588', barCompleteChar: '\u2588',
barIncompleteChar: '\u2591', barIncompleteChar: '\u2591',
hideCursor: true, hideCursor: true,
}); })
// Get total number of projects // Get total number of projects
const projectCount = (await (await fetch(API_URL + 'search?limit=0')).json()).total_hits; const projectCount = (await (await fetch(API_URL + 'search?limit=0')).json()).total_hits
progressBar.start(projectCount, 0); progressBar.start(projectCount, 0)
const writeStream = createWriteStream('./generated/projects.json'); const writeStream = createWriteStream('./generated/projects.json')
writeStream.write('{'); writeStream.write('{')
// Used to form the JSON string (so that the first doesn't have a comma prefix) // Used to form the JSON string (so that the first doesn't have a comma prefix)
let first = true; let first = true
let completed = 0; let completed = 0
// Number of pages through search to fetch // Number of pages through search to fetch
const requestCount = Math.ceil(projectCount / 100); const requestCount = Math.ceil(projectCount / 100)
await Promise.allSettled( await Promise.allSettled(
Array.from({ length: requestCount }, async (_, index) => { Array.from({ length: requestCount }, async (_, index) => {
const response = await fetch(API_URL + `search?limit=100&offset=${index * 100}`); const response = await fetch(API_URL + `search?limit=100&offset=${index * 100}`)
if (!response.ok) { if (!response.ok) {
throw new Error(`Failed to fetch projects: ${response.statusText}`); throw new Error(`Failed to fetch projects: ${response.statusText}`)
} }
// Get project hits & use map to get rid of extra data // Get project hits & use map to get rid of extra data
const hits = (await response.json()).hits.map((project) => ({ const hits = (await response.json()).hits.map((project) => ({
project_id: project.project_id, project_id: project.project_id,
slug: project.slug, slug: project.slug,
title: project.title, title: project.title,
icon_url: project.icon_url, icon_url: project.icon_url,
})); }))
// Try parsing the icon of each project // Try parsing the icon of each project
await Promise.allSettled( await Promise.allSettled(
hits.map(async (project) => { hits.map(async (project) => {
if ( if (
project.icon_url && project.icon_url &&
// Jimp doesn't support webp or svg // Jimp doesn't support webp or svg
!project.icon_url.endsWith('.webp') && !project.icon_url.endsWith('.webp') &&
!project.icon_url.endsWith('.svg') !project.icon_url.endsWith('.svg')
) { ) {
try { try {
const image = await Jimp.read( const image = await Jimp.read(
project.icon_url.replace('cdn', 'cdn-raw') // Skip redirect to raw CDN project.icon_url.replace('cdn', 'cdn-raw') // Skip redirect to raw CDN
); )
// Resize image before getting average color (faster) // Resize image before getting average color (faster)
image.resize(256, 256); image.resize(256, 256)
// Get bottom edge of image // Get bottom edge of image
const edge = image.clone().crop(0, 255, 256, 1); const edge = image.clone().crop(0, 255, 256, 1)
const buffer = await edge.getBufferAsync(Jimp.AUTO); const buffer = await edge.getBufferAsync(Jimp.AUTO)
let color = (await getAverageColor(buffer)).hexa; let color = (await getAverageColor(buffer)).hexa
// If the edge is transparent, use the average color of the entire image // If the edge is transparent, use the average color of the entire image
if (color === '#00000000') { if (color === '#00000000') {
const buffer = await image.getBufferAsync(Jimp.AUTO); const buffer = await image.getBufferAsync(Jimp.AUTO)
color = (await getAverageColor(buffer)).hexa; color = (await getAverageColor(buffer)).hexa
} }
// Remove color transparency // Remove color transparency
color = color.replace(/.{2}$/, ''); color = color.replace(/.{2}$/, '')
// Only use comma prefix if not first // Only use comma prefix if not first
let prefix = ','; let prefix = ','
if (first) { if (first) {
prefix = ''; prefix = ''
first = false; first = false
} }
writeStream.write(`${prefix}"${project.project_id}":"${color}"`); writeStream.write(`${prefix}"${project.project_id}":"${color}"`)
completed++; completed++
} catch (error) { } catch (error) {
// Ignore errors // Ignore errors
// console.log(error); // console.log(error);
} }
} }
progressBar.increment(); progressBar.increment()
}) })
); )
}) })
); )
writeStream.write('}'); writeStream.write('}')
writeStream.end(); writeStream.end()
progressBar.stop(); progressBar.stop()
console.log(`Failed to parse ${projectCount - completed} project icons.`); console.log(`Failed to parse ${projectCount - completed} project icons.`)
} }

View File

@@ -1 +1 @@
export declare function tags(API_URL: string): Promise<void>; export declare function tags(API_URL: string): Promise<void>

View File

@@ -1,50 +1,50 @@
import { fetch } from 'undici'; import { fetch } from 'undici'
import { promises as fs } from 'fs'; import { promises as fs } from 'fs'
import cliProgress from 'cli-progress'; import cliProgress from 'cli-progress'
export async function tags(API_URL) { export async function tags(API_URL) {
const progressBar = new cliProgress.SingleBar({ const progressBar = new cliProgress.SingleBar({
format: 'Generating tags | {bar} | {percentage}%', format: 'Generating tags | {bar} | {percentage}%',
barCompleteChar: '\u2588', barCompleteChar: '\u2588',
barIncompleteChar: '\u2591', barIncompleteChar: '\u2591',
hideCursor: true, hideCursor: true,
}); })
progressBar.start(7, 0); progressBar.start(7, 0)
// eslint-disable-next-line prefer-const // eslint-disable-next-line prefer-const
let [categories, loaders, licenses, donationPlatforms] = await Promise.all([ let [categories, loaders, licenses, donationPlatforms] = await Promise.all([
await (await fetch(API_URL + 'tag/category')).json(), await (await fetch(API_URL + 'tag/category')).json(),
await (await fetch(API_URL + 'tag/loader')).json(), await (await fetch(API_URL + 'tag/loader')).json(),
await (await fetch(API_URL + 'tag/license')).json(), await (await fetch(API_URL + 'tag/license')).json(),
await (await fetch(API_URL + 'tag/donation_platform')).json(), await (await fetch(API_URL + 'tag/donation_platform')).json(),
]); ])
progressBar.update(4); progressBar.update(4)
const tagIconReducer = (a, v) => ({ const tagIconReducer = (a, v) => ({
...a, ...a,
[v.name]: v.icon.replace('<svg', '<svg class="icon"'), [v.name]: v.icon.replace('<svg', '<svg class="icon"'),
}); })
// Create single object with icons // Create single object with icons
const tagIcons = { const tagIcons = {
...categories.reduce(tagIconReducer, {}), ...categories.reduce(tagIconReducer, {}),
...loaders.reduce(tagIconReducer, {}), ...loaders.reduce(tagIconReducer, {}),
}; }
progressBar.increment(); progressBar.increment()
// Delete icons from original arrays // Delete icons from original arrays
categories = categories.map(({ icon, ...rest }) => rest); categories = categories.map(({ icon, ...rest }) => rest)
loaders = loaders.map(({ icon, ...rest }) => rest); loaders = loaders.map(({ icon, ...rest }) => rest)
progressBar.increment(); progressBar.increment()
// Set project types // Set project types
const projectTypes = ['mod', 'modpack']; const projectTypes = ['mod', 'modpack']
// Write JSON file // Write JSON file
await fs.writeFile( await fs.writeFile(
'./generated/tags.json', './generated/tags.json',
JSON.stringify({ categories, loaders, projectTypes, licenses, donationPlatforms, tagIcons }) JSON.stringify({ categories, loaders, projectTypes, licenses, donationPlatforms, tagIcons })
); )
progressBar.increment(); progressBar.increment()
progressBar.stop(); progressBar.stop()
} }

View File

@@ -1,20 +1,20 @@
.actions { .actions {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: flex-end; align-items: flex-end;
grid-gap: 0.5rem; grid-gap: 0.5rem;
flex-wrap: wrap; flex-wrap: wrap;
margin-left: auto; margin-left: auto;
min-width: fit-content; min-width: fit-content;
> *:last-child { > *:last-child {
margin-top: auto; margin-top: auto;
color: var(--color-text-light); color: var(--color-text-light);
} }
@media (width <= 1000px) { @media (width <= 1000px) {
flex-direction: row; flex-direction: row;
align-items: flex-start; align-items: flex-start;
margin-left: unset; margin-left: unset;
} }
} }

View File

@@ -1,23 +1,23 @@
.base { .base {
background-color: var(--color-bg); background-color: var(--color-bg);
color: var(--color-text); color: var(--color-text);
font-family: var(--font-standard); font-family: var(--font-standard);
font-size: var(--font-size); font-size: var(--font-size);
font-weight: var(--font-weight-regular); font-weight: var(--font-weight-regular);
scrollbar-color: var(--color-scrollbar) var(--color-bg); scrollbar-color: var(--color-scrollbar) var(--color-bg);
&::-webkit-scrollbar { &::-webkit-scrollbar {
width: 14px; width: 14px;
} }
&::-webkit-scrollbar-track { &::-webkit-scrollbar-track {
background-color: var(--color-bg); background-color: var(--color-bg);
} }
&::-webkit-scrollbar-thumb { &::-webkit-scrollbar-thumb {
background-color: var(--color-scrollbar); background-color: var(--color-scrollbar);
border-radius: 999px; border-radius: 999px;
border: 3px solid var(--color-bg); border: 3px solid var(--color-bg);
} }
} }

View File

@@ -1,5 +1,5 @@
.button-group { .button-group {
display: flex; display: flex;
grid-gap: 0.5rem; grid-gap: 0.5rem;
flex-wrap: wrap; flex-wrap: wrap;
} }

View File

@@ -1,101 +1,101 @@
.card { .card {
--padding: 1rem; --padding: 1rem;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
position: relative; position: relative;
background-color: var(--color-raised-bg); background-color: var(--color-raised-bg);
border-radius: var(--rounded-lg); border-radius: var(--rounded-lg);
overflow: hidden; overflow: hidden;
box-shadow: var(--shadow-raised), var(--shadow-inset); box-shadow: var(--shadow-raised), var(--shadow-inset);
padding: var(--padding); padding: var(--padding);
grid-gap: 1rem; grid-gap: 1rem;
max-width: 100%; max-width: 100%;
.profile-picture { .profile-picture {
z-index: 1; z-index: 1;
} }
&--gap { &--gap {
&-compressed { &-compressed {
grid-gap: 0.6rem; grid-gap: 0.6rem;
} }
&-none { &-none {
grid-gap: 0; grid-gap: 0;
} }
} }
&--pad { &--pad {
&-top { &-top {
padding-top: 2.5rem; padding-top: 2.5rem;
} }
} }
&--overflow-visible { &--overflow-visible {
overflow: visible; overflow: visible;
} }
&__banner { &__banner {
--inverse-padding: calc(var(--padding) * -1); --inverse-padding: calc(var(--padding) * -1);
margin: var(--inverse-padding) var(--inverse-padding) 0 var(--inverse-padding); margin: var(--inverse-padding) var(--inverse-padding) 0 var(--inverse-padding);
z-index: 0; z-index: 0;
background-color: var(--color-divider); background-color: var(--color-divider);
&:-moz-loading { &:-moz-loading {
visibility: hidden; visibility: hidden;
} }
&--short { &--short {
height: 6.5rem; height: 6.5rem;
object-fit: cover; object-fit: cover;
object-position: center; object-position: center;
} }
&--dark { &--dark {
filter: brightness(0.7); filter: brightness(0.7);
} }
} }
&__overlay { &__overlay {
position: absolute; position: absolute;
top: 1rem; top: 1rem;
right: 1rem; right: 1rem;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: flex-end; align-items: flex-end;
grid-gap: 0.5rem; grid-gap: 0.5rem;
z-index: 1; z-index: 1;
&--row { &--row {
flex-direction: row; flex-direction: row;
} }
} }
&--row { &--row {
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
} }
&--strip { &--strip {
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
} }
&--pad-x { &--pad-x {
--padding: 1rem 1.3rem; --padding: 1rem 1.3rem;
} }
&.markdown { &.markdown {
--padding: 1.5rem; --padding: 1.5rem;
} }
p { p {
line-height: 130%; line-height: 130%;
} }
} }

View File

@@ -1,6 +1,6 @@
.divider { .divider {
margin: 0.25rem 0; margin: 0.25rem 0;
border: none; border: none;
border-top: 1px solid var(--color-divider); border-top: 1px solid var(--color-divider);
width: 100%; width: 100%;
} }

View File

@@ -1,16 +1,16 @@
.illustration { .illustration {
width: 100%; width: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
grid-gap: 2rem; grid-gap: 2rem;
&__image { &__image {
max-width: 300px; max-width: 300px;
} }
&__description { &__description {
font-size: 1.2rem; font-size: 1.2rem;
color: var(--color-text-light); color: var(--color-text-light);
} }
} }

View File

@@ -1,11 +1,11 @@
.info-table { .info-table {
display: grid; display: grid;
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);
grid-gap: 0.25rem 2rem; grid-gap: 0.25rem 2rem;
width: fit-content; width: fit-content;
&__label { &__label {
color: var(--color-text-lightest); color: var(--color-text-lightest);
font-weight: var(--font-weight-medium); font-weight: var(--font-weight-medium);
} }
} }

View File

@@ -1,25 +1,25 @@
.link { .link {
color: var(--color-link); color: var(--color-link);
display: flex; display: flex;
align-items: center; align-items: center;
gap: 4px; gap: 4px;
line-height: 100%; line-height: 100%;
&:hover { &:hover {
text-decoration: underline; text-decoration: underline;
} }
} }
.link-group { .link-group {
display: grid; display: grid;
grid-template-columns: repeat(3, auto); grid-template-columns: repeat(3, auto);
grid-gap: 0.75rem; grid-gap: 0.75rem;
.link { .link {
color: var(--color-text); color: var(--color-text);
&:hover { &:hover {
color: var(--color-link); color: var(--color-link);
} }
} }
} }

View File

@@ -1,137 +1,137 @@
.markdown { .markdown {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
grid-gap: 1rem; grid-gap: 1rem;
blockquote, blockquote,
details, details,
dl, dl,
ol, ol,
p, p,
code, code,
pre, pre,
table, table,
ul { ul {
margin: 0; margin: 0;
} }
p { p {
line-height: 1.5; line-height: 1.5;
word-wrap: break-word; word-wrap: break-word;
overflow-wrap: anywhere; overflow-wrap: anywhere;
} }
h1, h1,
h2 { h2 {
padding-bottom: 0.2em; padding-bottom: 0.2em;
border-bottom: 1px solid var(--color-divider); border-bottom: 1px solid var(--color-divider);
} }
blockquote { blockquote {
padding: 0 1rem; padding: 0 1rem;
color: var(--color-text); color: var(--color-text);
border-left: 0.25rem solid var(--color-divider); border-left: 0.25rem solid var(--color-divider);
} }
a { a {
color: var(--color-link); color: var(--color-link);
&:hover { &:hover {
text-decoration: underline; text-decoration: underline;
} }
} }
img, img,
iframe { iframe {
max-width: 100%; max-width: 100%;
height: auto; height: auto;
border-radius: var(--rounded-sm); border-radius: var(--rounded-sm);
} }
iframe { iframe {
width: 35rem; width: 35rem;
aspect-ratio: 16/9; aspect-ratio: 16/9;
} }
code { code {
padding: 0.2rem 0.4rem; padding: 0.2rem 0.4rem;
font-size: 80%; font-size: 80%;
border-radius: var(--rounded-sm); border-radius: var(--rounded-sm);
background-color: var(--color-code-bg); background-color: var(--color-code-bg);
color: var(--color-code-text); color: var(--color-code-text);
} }
pre { pre {
padding: 1rem; padding: 1rem;
border-radius: var(--rounded-sm); border-radius: var(--rounded-sm);
overflow-x: auto; overflow-x: auto;
code { code {
font-size: 80%; font-size: 80%;
padding: 0; padding: 0;
border-radius: 0; border-radius: 0;
background-color: unset; background-color: unset;
} }
} }
hr { hr {
margin: 0; margin: 0;
color: var(--color-divider); color: var(--color-divider);
} }
table { table {
display: block; display: block;
width: max-content; width: max-content;
max-width: 100%; max-width: 100%;
overflow: auto; overflow: auto;
border-collapse: collapse; border-collapse: collapse;
line-height: 1.5; line-height: 1.5;
th { th {
font-weight: 600; font-weight: 600;
} }
td, td,
th { th {
padding: 0.4rem 0.85rem; padding: 0.4rem 0.85rem;
border: 0.1rem solid var(--color-table-border); border: 0.1rem solid var(--color-table-border);
} }
tr:nth-child(2n) { tr:nth-child(2n) {
background-color: var(--color-table-alternate-row); background-color: var(--color-table-alternate-row);
} }
} }
details { details {
border: 0.15rem solid var(--color-button-bg); border: 0.15rem solid var(--color-button-bg);
border-radius: var(--rounded-sm); border-radius: var(--rounded-sm);
padding: 0.5rem 0.5rem 0; padding: 0.5rem 0.5rem 0;
overflow: hidden; overflow: hidden;
summary { summary {
font-weight: bold; font-weight: bold;
margin: -0.5rem -0.5rem 0; margin: -0.5rem -0.5rem 0;
padding: 0.5rem 0.8rem; padding: 0.5rem 0.8rem;
cursor: pointer; cursor: pointer;
background-color: var(--color-button-bg); background-color: var(--color-button-bg);
&:hover { &:hover {
background-color: var(--color-button-bg-hover); background-color: var(--color-button-bg-hover);
} }
} }
&[open] { &[open] {
padding: 0.5rem; padding: 0.5rem;
summary { summary {
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
} }
} }
} }
li:has(> input) { li:has(> input) {
list-style: none; list-style: none;
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
} }

View File

@@ -1,13 +1,13 @@
.member { .member {
display: flex; display: flex;
grid-gap: 0.75rem; grid-gap: 0.75rem;
&__info { &__info {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
&__link { &__link {
font-weight: var(--font-weight-medium); font-weight: var(--font-weight-medium);
} }
} }
} }

View File

@@ -1,23 +1,23 @@
.stat { .stat {
display: flex; display: flex;
align-items: baseline; align-items: baseline;
grid-gap: 0.4rem; grid-gap: 0.4rem;
&--light { &--light {
color: var(--color-text-lightest); color: var(--color-text-lightest);
} }
.icon { .icon {
align-self: center; align-self: center;
} }
strong { strong {
font-size: 20px; font-size: 20px;
} }
} }
.stat-group { .stat-group {
display: flex; display: flex;
grid-gap: 0.5rem; grid-gap: 0.5rem;
flex-wrap: wrap; flex-wrap: wrap;
} }

View File

@@ -1,18 +1,18 @@
.tag { .tag {
display: flex; display: flex;
align-items: center; align-items: center;
grid-gap: 0.25rem; grid-gap: 0.25rem;
color: var(--color-text-lightest); color: var(--color-text-lightest);
svg { svg {
width: 1rem; width: 1rem;
height: auto; height: auto;
} }
} }
.tag-group { .tag-group {
display: inline-flex; display: inline-flex;
flex-wrap: wrap; flex-wrap: wrap;
margin-top: auto; margin-top: auto;
grid-gap: 0.25rem 0.6rem; grid-gap: 0.25rem 0.6rem;
} }

View File

@@ -1,14 +1,14 @@
.title-primary { .title-primary {
font-size: 24px; font-size: 24px;
font-weight: var(--font-weight-bold); font-weight: var(--font-weight-bold);
} }
.title-secondary { .title-secondary {
font-size: 20px; font-size: 20px;
font-weight: var(--font-weight-bold); font-weight: var(--font-weight-bold);
} }
.title-tertiary { .title-tertiary {
font-size: 16px; font-size: 16px;
font-weight: var(--font-weight-bold); font-weight: var(--font-weight-bold);
} }

View File

@@ -5,38 +5,38 @@
/* Overrides */ /* Overrides */
button { button {
margin: 0; margin: 0;
padding: 0; padding: 0;
font-size: inherit; font-size: inherit;
box-shadow: none; box-shadow: none;
border: none; border: none;
cursor: pointer; cursor: pointer;
} }
a { a {
color: inherit; color: inherit;
text-decoration: none; text-decoration: none;
} }
*:focus { *:focus {
outline: none; outline: none;
} }
button:focus-visible, button:focus-visible,
a:focus-visible, a:focus-visible,
[tabindex='0']:focus-visible { [tabindex='0']:focus-visible {
outline: 0.2rem solid var(--color-brand); outline: 0.2rem solid var(--color-brand);
} }
html, html,
body, body,
#svelte { #svelte {
height: 100%; height: 100%;
} }
html { html {
overflow-y: hidden; overflow-y: hidden;
overflow-x: hidden; overflow-x: hidden;
} }
h1, h1,
@@ -46,17 +46,17 @@ h4,
h5, h5,
h6, h6,
p { p {
line-height: 100%; line-height: 100%;
margin: 0; margin: 0;
} }
ul { ul {
padding: 0 0 0 1.5rem; padding: 0 0 0 1.5rem;
} }
.icon { .icon {
height: auto; height: auto;
width: 16px; width: 16px;
min-width: 16px; min-width: 16px;
aspect-ratio: 1 / 1; aspect-ratio: 1 / 1;
} }

View File

@@ -1,17 +1,17 @@
:root { :root {
--rounded: 1rem; --rounded: 1rem;
--rounded-top: 1rem 1rem 0 0; --rounded-top: 1rem 1rem 0 0;
--rounded-bottom: 0 0 1rem 1rem; --rounded-bottom: 0 0 1rem 1rem;
--rounded-sm: 0.6rem; --rounded-sm: 0.6rem;
--rounded-max: 999999999px; --rounded-max: 999999999px;
--font-standard: Inter, -apple-system, BlinkMacSystemFont, Segoe UI, Oxygen, Ubuntu, Roboto, --font-standard: Inter, -apple-system, BlinkMacSystemFont, Segoe UI, Oxygen, Ubuntu, Roboto,
Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
--font-size-nm: 1rem; /* 16px */ --font-size-nm: 1rem; /* 16px */
--font-size-xl: 1.5rem; /* 24px */ --font-size-xl: 1.5rem; /* 24px */
--font-weight-regular: 400; --font-weight-regular: 400;
--font-weight-medium: 600; --font-weight-medium: 600;
--font-weight-bold: 700; --font-weight-bold: 700;
} }

View File

@@ -1,63 +1,63 @@
.theme-dark { .theme-dark {
/* Brand colors */ /* Brand colors */
--color-brand: hsl(145, 78%, 48%); --color-brand: hsl(145, 78%, 48%);
--color-brand-light: hsl(155, 54%, 35%); --color-brand-light: hsl(155, 54%, 35%);
--color-brand-dark: hsl(155, 58%, 25%); --color-brand-dark: hsl(155, 58%, 25%);
--color-brand-contrast: hsl(0, 0%, 0%); --color-brand-contrast: hsl(0, 0%, 0%);
--color-secondary: hsl(231, 5%, 80%); --color-secondary: hsl(231, 5%, 80%);
--color-tertiary: hsl(231, 3%, 45%); --color-tertiary: hsl(231, 3%, 45%);
/* Shadows */ /* Shadows */
--shadow-inset-lg: inset 0px -2px 2px hsla(221, 39%, 11%, 0.1); --shadow-inset-lg: inset 0px -2px 2px hsla(221, 39%, 11%, 0.1);
--shadow-inset: inset 0px -2px 2px hsla(221, 39%, 11%, 0.05); --shadow-inset: inset 0px -2px 2px hsla(221, 39%, 11%, 0.05);
--shadow-inset-sm: inset 0px -1px 1px hsla(221, 39%, 11%, 0.25); --shadow-inset-sm: inset 0px -1px 1px hsla(221, 39%, 11%, 0.25);
--shadow-raised-lg: 0px 2px 4px hsla(221, 39%, 11%, 0.2); --shadow-raised-lg: 0px 2px 4px hsla(221, 39%, 11%, 0.2);
--shadow-raised: 0px -2px 4px hsla(221, 39%, 11%, 0.1); --shadow-raised: 0px -2px 4px hsla(221, 39%, 11%, 0.1);
--shadow-floating: hsla(0, 0%, 0%, 0) 0px 0px 0px 0px, hsla(0, 0%, 0%, 0) 0px 0px 0px 0px, --shadow-floating: hsla(0, 0%, 0%, 0) 0px 0px 0px 0px, hsla(0, 0%, 0%, 0) 0px 0px 0px 0px,
hsla(0, 0%, 0%, 0.1) 0px 4px 6px -1px, rgba(0, 0, 0, 0.06) 0px 2px 4px -1px; hsla(0, 0%, 0%, 0.1) 0px 4px 6px -1px, rgba(0, 0, 0, 0.06) 0px 2px 4px -1px;
--shadow-mobile-bar: hsla(0, 0%, 0%, 0.3) 0 0 20px 2px; --shadow-mobile-bar: hsla(0, 0%, 0%, 0.3) 0 0 20px 2px;
/* Text colors */ /* Text colors */
--color-text: hsl(221, 39%, 90%); --color-text: hsl(221, 39%, 90%);
--color-text-light: hsl(215, 14%, 74%); --color-text-light: hsl(215, 14%, 74%);
--color-text-lightest: hsl(220, 9%, 70%); --color-text-lightest: hsl(220, 9%, 70%);
--color-heading: hsl(222, 16%, 80%); --color-heading: hsl(222, 16%, 80%);
--color-link: hsl(215, 100%, 75%); --color-link: hsl(215, 100%, 75%);
/* Container colors */ /* Container colors */
--color-bg: hsl(220, 13%, 15%); --color-bg: hsl(220, 13%, 15%);
--color-bg-contrast: hsl(0, 0%, 100%); --color-bg-contrast: hsl(0, 0%, 100%);
--color-raised-bg: hsl(220, 13%, 25%); --color-raised-bg: hsl(220, 13%, 25%);
--color-divider: hsl(220, 13%, 50%); --color-divider: hsl(220, 13%, 50%);
--color-button-bg: hsl(222, 13%, 35%); --color-button-bg: hsl(222, 13%, 35%);
/* Label colors */ /* Label colors */
--color-badge-gray-text: hsl(0, 2%, 69%); --color-badge-gray-text: hsl(0, 2%, 69%);
--color-badge-gray-dot: hsl(0, 6%, 77%); --color-badge-gray-dot: hsl(0, 6%, 77%);
--color-badge-red-text: hsl(343, 63%, 67%); --color-badge-red-text: hsl(343, 63%, 67%);
--color-badge-red-dot: hsl(342, 70%, 53%); --color-badge-red-dot: hsl(342, 70%, 53%);
--color-badge-green-text: hsl(156, 53%, 50%); --color-badge-green-text: hsl(156, 53%, 50%);
--color-badge-green-dot: hsl(140, 64%, 40%); --color-badge-green-dot: hsl(140, 64%, 40%);
--color-badge-yellow-text: hsl(40, 57%, 60%); --color-badge-yellow-text: hsl(40, 57%, 60%);
--color-badge-yellow-dot: hsl(40, 92%, 62%); --color-badge-yellow-dot: hsl(40, 92%, 62%);
/* Markdown colors */ /* Markdown colors */
--color-table-border: hsl(214, 12%, 35%); --color-table-border: hsl(214, 12%, 35%);
--color-table-alternate-row: hsl(216, 12%, 17%); --color-table-alternate-row: hsl(216, 12%, 17%);
--color-code-bg: hsl(217, 12%, 29%); --color-code-bg: hsl(217, 12%, 29%);
/* Ad colors */ /* Ad colors */
--color-ad-bg: hsl(200, 70%, 25%); --color-ad-bg: hsl(200, 70%, 25%);
--color-ad-link: hsl(200, 70%, 50%); --color-ad-link: hsl(200, 70%, 50%);
/* Popup colors */ /* Popup colors */
--color-popup-danger-bg: hsl(355, 70%, 20%); --color-popup-danger-bg: hsl(355, 70%, 20%);
--color-popup-danger-text: hsl(342, 70%, 75%); --color-popup-danger-text: hsl(342, 70%, 75%);
--color-input-light: hsl(220, 13%, 20%); --color-input-light: hsl(220, 13%, 20%);
/* Scrollbar color */ /* Scrollbar color */
--color-scrollbar-thumb: hsl(220, 13%, 40%); --color-scrollbar-thumb: hsl(220, 13%, 40%);
} }

View File

@@ -1,62 +1,62 @@
.theme-light { .theme-light {
/* Brand colors */ /* Brand colors */
--color-brand: hsl(155, 58%, 44%); --color-brand: hsl(155, 58%, 44%);
--color-brand-light: hsl(135, 50%, 78%); --color-brand-light: hsl(135, 50%, 78%);
--color-brand-dark: hsl(155, 58%, 38%); --color-brand-dark: hsl(155, 58%, 38%);
--color-brand-contrast: hsl(0, 0%, 100%); --color-brand-contrast: hsl(0, 0%, 100%);
--color-secondary: hsl(231, 5%, 45%); --color-secondary: hsl(231, 5%, 45%);
--color-tertiary: hsl(231, 3%, 75%); --color-tertiary: hsl(231, 3%, 75%);
/* Shadows */ /* Shadows */
--shadow-inset-lg: inset 0px -2px 2px hsla(221, 39%, 11%, 0.1); --shadow-inset-lg: inset 0px -2px 2px hsla(221, 39%, 11%, 0.1);
--shadow-inset: inset 0px -2px 2px hsla(221, 39%, 11%, 0.05); --shadow-inset: inset 0px -2px 2px hsla(221, 39%, 11%, 0.05);
--shadow-inset-sm: inset 0px -1px 2px hsla(221, 39%, 11%, 0.15); --shadow-inset-sm: inset 0px -1px 2px hsla(221, 39%, 11%, 0.15);
--shadow-raised-lg: 0px 2px 4px hsla(221, 39%, 11%, 0.2); --shadow-raised-lg: 0px 2px 4px hsla(221, 39%, 11%, 0.2);
--shadow-raised: 0px 2px 4px hsla(221, 39%, 11%, 0.1); --shadow-raised: 0px 2px 4px hsla(221, 39%, 11%, 0.1);
--shadow-floating: hsla(0, 0%, 0%, 0) 0px 0px 0px 0px, hsla(0, 0%, 0%, 0) 0px 0px 0px 0px, --shadow-floating: hsla(0, 0%, 0%, 0) 0px 0px 0px 0px, hsla(0, 0%, 0%, 0) 0px 0px 0px 0px,
hsla(0, 0%, 0%, 0.1) 0px 4px 6px -1px, hsla(0, 0%, 0%, 0.1) 0px 2px 4px -1px; hsla(0, 0%, 0%, 0.1) 0px 4px 6px -1px, hsla(0, 0%, 0%, 0.1) 0px 2px 4px -1px;
--shadow-mobile-bar: hsla(0, 0%, 0%, 0.3) 0 0 20px 2px; --shadow-mobile-bar: hsla(0, 0%, 0%, 0.3) 0 0 20px 2px;
/* Text colors */ /* Text colors */
--color-text: hsl(221, 39%, 11%); --color-text: hsl(221, 39%, 11%);
--color-text-light: hsl(215, 14%, 34%); --color-text-light: hsl(215, 14%, 34%);
--color-text-lightest: hsl(220, 9%, 46%); --color-text-lightest: hsl(220, 9%, 46%);
--color-heading: hsl(222, 16%, 20%); --color-heading: hsl(222, 16%, 20%);
--color-link: hsl(221, 55%, 50%); --color-link: hsl(221, 55%, 50%);
/* Container colors */ /* Container colors */
--color-bg: hsl(220, 13%, 91%); --color-bg: hsl(220, 13%, 91%);
--color-bg-contrast: hsl(0, 0%, 0%); --color-bg-contrast: hsl(0, 0%, 0%);
--color-raised-bg: hsl(0, 0%, 100%); --color-raised-bg: hsl(0, 0%, 100%);
--color-divider: hsl(220, 13%, 91%); --color-divider: hsl(220, 13%, 91%);
--color-button-bg: hsl(220, 13%, 91%); --color-button-bg: hsl(220, 13%, 91%);
--color-input-text-light: hsl(0, 0%, 94%); --color-input-text-light: hsl(0, 0%, 94%);
/* Label colors */ /* Label colors */
--color-badge-gray-text: hsl(0, 2%, 39%); --color-badge-gray-text: hsl(0, 2%, 39%);
--color-badge-gray-dot: hsl(0, 6%, 77%); --color-badge-gray-dot: hsl(0, 6%, 77%);
--color-badge-red-text: hsl(343, 63%, 27%); --color-badge-red-text: hsl(343, 63%, 27%);
--color-badge-red-dot: hsl(342, 70%, 53%); --color-badge-red-dot: hsl(342, 70%, 53%);
--color-badge-green-text: hsl(156, 53%, 20%); --color-badge-green-text: hsl(156, 53%, 20%);
--color-badge-green-dot: hsl(140, 64%, 40%); --color-badge-green-dot: hsl(140, 64%, 40%);
--color-badge-yellow-text: hsl(40, 57%, 29%); --color-badge-yellow-text: hsl(40, 57%, 29%);
--color-badge-yellow-dot: hsl(40, 92%, 62%); --color-badge-yellow-dot: hsl(40, 92%, 62%);
/* Markdown colors */ /* Markdown colors */
--color-table-border: hsl(210, 10%, 89%); --color-table-border: hsl(210, 10%, 89%);
--color-table-alternate-row: hsl(210, 29%, 97%); --color-table-alternate-row: hsl(210, 29%, 97%);
--color-code-bg: hsl(210, 29%, 96%); --color-code-bg: hsl(210, 29%, 96%);
/* Ad colors */ /* Ad colors */
--color-ad-bg: hsl(200, 70%, 82%); --color-ad-bg: hsl(200, 70%, 82%);
--color-ad-link: hsl(200, 80%, 40%); --color-ad-link: hsl(200, 80%, 40%);
/* Popup colors */ /* Popup colors */
--color-popup-danger-bg: hsl(355, 70%, 88%); --color-popup-danger-bg: hsl(355, 70%, 88%);
--color-popup-danger-text: hsl(342, 70%, 35%); --color-popup-danger-text: hsl(342, 70%, 35%);
/* Scrollbar color */ /* Scrollbar color */
--color-scrollbar-thumb: hsl(220, 13%, 70%); --color-scrollbar-thumb: hsl(220, 13%, 70%);
} }

View File

@@ -1,14 +1,14 @@
.theme-oled { .theme-oled {
@extend .dark-theme; @extend .dark-theme;
/* Container colors */ /* Container colors */
--color-bg: hsl(220, 13%, 0%); --color-bg: hsl(220, 13%, 0%);
--color-raised-bg: hsl(220, 13%, 10%); --color-raised-bg: hsl(220, 13%, 10%);
--color-raised-bg-hover: hsl(220, 13%, 20%); --color-raised-bg-hover: hsl(220, 13%, 20%);
--color-divider: hsl(220, 13%, 35%); --color-divider: hsl(220, 13%, 35%);
--color-button-bg: hsl(220, 13%, 20%); --color-button-bg: hsl(220, 13%, 20%);
/* Ad colors */ /* Ad colors */
--color-ad-bg: hsl(200, 70%, 15%); --color-ad-bg: hsl(200, 70%, 15%);
--color-ad-link: hsl(200, 70%, 45%); --color-ad-link: hsl(200, 70%, 45%);
} }

View File

@@ -1,16 +1,16 @@
:root { :root {
/* Borders */ /* Borders */
--border-width: 1px; --border-width: 1px;
--border-style: solid; --border-style: solid;
--border: var(--border-width) var(--border-style); --border: var(--border-width) var(--border-style);
/* Rounded radii */ /* Rounded radii */
--rounded-sm: 8px; --rounded-sm: 8px;
--rounded: 10px; --rounded: 10px;
--rounded-lg: 14px; --rounded-lg: 14px;
--rounded-max: 100px; --rounded-max: 100px;
--rounded-top: var(--rounded) var(--rounded) 0 0; --rounded-top: var(--rounded) var(--rounded) 0 0;
--rounded-bottom: 0 0 var(--rounded) var(--rounded); --rounded-bottom: 0 0 var(--rounded) var(--rounded);
--rounded-sm-top: var(--rounded-sm) var(--rounded-sm) 0 0; --rounded-sm-top: var(--rounded-sm) var(--rounded-sm) 0 0;
--rounded-sm-bottom: 0 0 var(--rounded-sm) var(--rounded-sm); --rounded-sm-bottom: 0 0 var(--rounded-sm) var(--rounded-sm);
} }

View File

@@ -1,6 +1,6 @@
:root { :root {
/* these are values for the display CSS property */ /* these are values for the display CSS property */
/* /*
--display-values: ( --display-values: (
block, block,
flex, flex,
@@ -21,7 +21,7 @@
); );
*/ */
/* /*
These are our margin and padding utility spacers. The default step size we These are our margin and padding utility spacers. The default step size we
use is 8px. This gives us a key of: use is 8px. This gives us a key of:
0 => 0px 0 => 0px
@@ -31,18 +31,18 @@
4 => 24px 4 => 24px
5 => 32px 5 => 32px
6 => 40px */ 6 => 40px */
--spacer: 8px; --spacer: 8px;
/* Our spacing scale */ /* Our spacing scale */
--spacer-0: 0; /* 0 */ --spacer-0: 0; /* 0 */
--spacer-1: calc(var(--spacer) * 0.5); /* 4px */ --spacer-1: calc(var(--spacer) * 0.5); /* 4px */
--spacer-2: --spacer; /* 8px */ --spacer-2: --spacer; /* 8px */
--spacer-3: calc(var(--spacer) * 2); /* 16px */ --spacer-3: calc(var(--spacer) * 2); /* 16px */
--spacer-4: calc(var(--spacer) * 3); /* 24px */ --spacer-4: calc(var(--spacer) * 3); /* 24px */
--spacer-5: calc(var(--spacer) * 4); /* 32px */ --spacer-5: calc(var(--spacer) * 4); /* 32px */
--spacer-6: calc(var(--spacer) * 5); /* 40px */ --spacer-6: calc(var(--spacer) * 5); /* 40px */
/* /*
/* The list of spacer values /* The list of spacer values
--spacers: ( --spacers: (
--spacer-0, --spacer-0,

View File

@@ -1,39 +1,39 @@
:root { :root {
/* Heading sizes - mobile */ /* Heading sizes - mobile */
/* h4-h6 remain the same size on both mobile & desktop */ /* h4-h6 remain the same size on both mobile & desktop */
--h00-size-mobile: 40px; --h00-size-mobile: 40px;
--h0-size-mobile: 32px; --h0-size-mobile: 32px;
--h1-size-mobile: 26px; --h1-size-mobile: 26px;
--h2-size-mobile: 22px; --h2-size-mobile: 22px;
--h3-size-mobile: 18px; --h3-size-mobile: 18px;
/* Heading sizes - desktop */ /* Heading sizes - desktop */
--h00-size: 48px; --h00-size: 48px;
--h0-size: 40px; --h0-size: 40px;
--h1-size: 32px; --h1-size: 32px;
--h2-size: 24px; --h2-size: 24px;
--h3-size: 20px; --h3-size: 20px;
--h4-size: 16px; --h4-size: 16px;
--h5-size: 14px; --h5-size: 14px;
--h6-size: 12px; --h6-size: 12px;
--font-size-lg: 19px; --font-size-lg: 19px;
--font-size-sm: 13px; --font-size-sm: 13px;
--font-size: 16px; --font-size: 16px;
/* Line heights */ /* Line heights */
--lh-condensed-ultra: 1; --lh-condensed-ultra: 1;
--lh-condensed: 1.25; --lh-condensed: 1.25;
--lh-default: 1.5; --lh-default: 1.5;
/* Font weights */ /* Font weights */
--font-weight-light: 300; --font-weight-light: 300;
--font-weight-normal: 400; --font-weight-normal: 400;
--font-weight-semibold: 500; --font-weight-semibold: 500;
--font-weight-bold: 600; --font-weight-bold: 600;
/* Font stacks */ /* Font stacks */
--body-font: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, --body-font: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif,
'Apple Color Emoji', 'Segoe UI Emoji'; 'Apple Color Emoji', 'Segoe UI Emoji';
--mono-font: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace; --mono-font: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace;
} }

View File

@@ -4,56 +4,54 @@
* @see https://stackoverflow.com/a/67338038/938822 * @see https://stackoverflow.com/a/67338038/938822
*/ */
export function ago( export function ago(
/** A Date object, timestamp or string parsable with Date.parse() */ /** A Date object, timestamp or string parsable with Date.parse() */
date: string | number | Date, date: string | number | Date,
/** A Date object, timestamp or string parsable with Date.parse() */ /** A Date object, timestamp or string parsable with Date.parse() */
nowDate: string | number | Date = Date.now(), nowDate: string | number | Date = Date.now(),
/** A Intl formater */ /** A Intl formater */
rft: Intl.RelativeTimeFormat = new Intl.RelativeTimeFormat(undefined, { numeric: 'auto' }) rft: Intl.RelativeTimeFormat = new Intl.RelativeTimeFormat(undefined, { numeric: 'auto' })
): string { ): string {
const SECOND = 1000; const SECOND = 1000
const MINUTE = 60 * SECOND; const MINUTE = 60 * SECOND
const HOUR = 60 * MINUTE; const HOUR = 60 * MINUTE
const DAY = 24 * HOUR; const DAY = 24 * HOUR
const WEEK = 7 * DAY; const WEEK = 7 * DAY
const MONTH = 30 * DAY; const MONTH = 30 * DAY
const YEAR = 365 * DAY; const YEAR = 365 * DAY
const intervals = [ const intervals = [
{ ge: YEAR, divisor: YEAR, unit: 'year' }, { ge: YEAR, divisor: YEAR, unit: 'year' },
{ ge: MONTH, divisor: MONTH, unit: 'month' }, { ge: MONTH, divisor: MONTH, unit: 'month' },
{ ge: WEEK, divisor: WEEK, unit: 'week' }, { ge: WEEK, divisor: WEEK, unit: 'week' },
{ ge: DAY, divisor: DAY, unit: 'day' }, { ge: DAY, divisor: DAY, unit: 'day' },
{ ge: HOUR, divisor: HOUR, unit: 'hour' }, { ge: HOUR, divisor: HOUR, unit: 'hour' },
{ ge: MINUTE, divisor: MINUTE, unit: 'minute' }, { ge: MINUTE, divisor: MINUTE, unit: 'minute' },
{ ge: 30 * SECOND, divisor: SECOND, unit: 'seconds' }, { ge: 30 * SECOND, divisor: SECOND, unit: 'seconds' },
{ ge: 0, divisor: 1, text: 'just now' }, { ge: 0, divisor: 1, text: 'just now' },
]; ]
const now = typeof nowDate === 'object' ? nowDate.getTime() : new Date(nowDate).getTime(); const now = typeof nowDate === 'object' ? nowDate.getTime() : new Date(nowDate).getTime()
const diff = now - (typeof date === 'object' ? date : new Date(date)).getTime(); const diff = now - (typeof date === 'object' ? date : new Date(date)).getTime()
const diffAbs = Math.abs(diff); const diffAbs = Math.abs(diff)
for (const interval of intervals) { for (const interval of intervals) {
if (diffAbs >= interval.ge) { if (diffAbs >= interval.ge) {
const x = Math.round(Math.abs(diff) / interval.divisor); const x = Math.round(Math.abs(diff) / interval.divisor)
const isFuture = diff < 0; const isFuture = diff < 0
return interval.unit return interval.unit ? rft.format(isFuture ? x : -x, interval.unit as Unit) : interval.text
? rft.format(isFuture ? x : -x, interval.unit as Unit) }
: interval.text; }
}
}
} }
type Unit = type Unit =
| 'second' | 'second'
| 'seconds' | 'seconds'
| 'minute' | 'minute'
| 'minutes' | 'minutes'
| 'hour' | 'hour'
| 'hours' | 'hours'
| 'day' | 'day'
| 'days' | 'days'
| 'week' | 'week'
| 'weeks' | 'weeks'
| 'month' | 'month'
| 'months' | 'months'
| 'year' | 'year'
| 'years'; | 'years'

View File

@@ -1,3 +1,3 @@
export function classCombine(names) { export function classCombine(names) {
return names.filter((name) => name && !name.includes('undefined')).join(' '); return names.filter((name) => name && !name.includes('undefined')).join(' ')
} }

View File

@@ -1,4 +1,4 @@
export { ago } from './ago'; export { ago } from './ago'
export { Permissions } from './permissions'; export { Permissions } from './permissions'
export { formatVersions, getPrimary, downloadUrl } from './versions'; export { formatVersions, getPrimary, downloadUrl } from './versions'
export { markdown, markdownInline } from './parse'; export { markdown, markdownInline } from './parse'

View File

@@ -1,142 +1,142 @@
import { marked } from 'marked'; import { marked } from 'marked'
import hljs from 'highlight.js'; import hljs from 'highlight.js'
import insane from 'insane'; import insane from 'insane'
const renderer = new marked.Renderer(); const renderer = new marked.Renderer()
renderer.image = (href, text) => { renderer.image = (href, text) => {
if (/^https?:\/\/(www\.)?youtube\.com\/watch\?v=[a-zA-Z0-9_]{11}$/.test(href)) { if (/^https?:\/\/(www\.)?youtube\.com\/watch\?v=[a-zA-Z0-9_]{11}$/.test(href)) {
const id = href.substring(32, 43); const id = href.substring(32, 43)
return `<iframe src="https://www.youtube-nocookie.com/embed/${id}?&modestbranding=1&autoplay=0&rel=0" frameborder="0" allowfullscreen></iframe>`; return `<iframe src="https://www.youtube-nocookie.com/embed/${id}?&modestbranding=1&autoplay=0&rel=0" frameborder="0" allowfullscreen></iframe>`
} else { } else {
return `<img src="${href}" alt="${text}" />`; return `<img src="${href}" alt="${text}" />`
} }
}; }
renderer.link = (href, title, text) => { renderer.link = (href, title, text) => {
if (href === null) { if (href === null) {
return text; return text
} }
let out = '<a href="' + href + '" rel="external nofollow"'; let out = '<a href="' + href + '" rel="external nofollow"'
if (title) { if (title) {
out += ' title="' + title + '"'; out += ' title="' + title + '"'
} }
out += '>' + text + '</a>'; out += '>' + text + '</a>'
return out; return out
}; }
marked.setOptions({ marked.setOptions({
renderer, renderer,
highlight: function (code, lang) { highlight: function (code, lang) {
const language = hljs.getLanguage(lang) ? lang : 'plaintext'; const language = hljs.getLanguage(lang) ? lang : 'plaintext'
return hljs.highlight(code, { language }).value; return hljs.highlight(code, { language }).value
}, },
langPrefix: 'hljs language-', langPrefix: 'hljs language-',
headerPrefix: '', headerPrefix: '',
gfm: true, gfm: true,
smartLists: true, smartLists: true,
}); })
function sanitize(html: string): string { function sanitize(html: string): string {
return insane(html, { return insane(html, {
allowedAttributes: { allowedAttributes: {
a: ['href', 'target', 'title', 'rel'], a: ['href', 'target', 'title', 'rel'],
iframe: ['allowfullscreen', 'src', 'width', 'height'], iframe: ['allowfullscreen', 'src', 'width', 'height'],
img: ['src', 'width', 'height', 'alt'], img: ['src', 'width', 'height', 'alt'],
h1: ['id'], h1: ['id'],
h2: ['id'], h2: ['id'],
h3: ['id'], h3: ['id'],
h4: ['id'], h4: ['id'],
h5: ['id'], h5: ['id'],
h6: ['id'], h6: ['id'],
code: ['class'], code: ['class'],
span: ['class'], span: ['class'],
input: ['type', 'checked', 'disabled'], input: ['type', 'checked', 'disabled'],
font: ['color'], font: ['color'],
}, },
allowedClasses: {}, allowedClasses: {},
allowedSchemes: ['http', 'https', 'mailto'], allowedSchemes: ['http', 'https', 'mailto'],
allowedTags: [ allowedTags: [
'a', 'a',
'b', 'b',
'blockquote', 'blockquote',
'br', 'br',
'caption', 'caption',
'center', 'center',
'code', 'code',
'del', 'del',
'details', 'details',
'div', 'div',
'em', 'em',
'font', 'font',
'h1', 'h1',
'h2', 'h2',
'h3', 'h3',
'h4', 'h4',
'h5', 'h5',
'h6', 'h6',
'hr', 'hr',
'i', 'i',
'iframe', 'iframe',
'img', 'img',
'input', 'input',
'ins', 'ins',
'kbd', 'kbd',
'li', 'li',
'main', 'main',
'ol', 'ol',
'p', 'p',
'pre', 'pre',
'span', 'span',
'strike', 'strike',
'strong', 'strong',
'sub', 'sub',
'summary', 'summary',
'sup', 'sup',
'table', 'table',
'tbody', 'tbody',
'td', 'td',
'th', 'th',
'thead', 'thead',
'tr', 'tr',
'u', 'u',
'ul', 'ul',
], ],
filter: ({ tag, attrs }): boolean => { filter: ({ tag, attrs }): boolean => {
if (tag === 'iframe') { if (tag === 'iframe') {
return /^https?:\/\/(www\.)?(youtube|youtube-nocookie)\.com\/embed\/[a-zA-Z0-9_]{11}(\?)?(&modestbranding=1)?(&autoplay=0)?(&loop=1)?(&playlist=[a-zA-Z0-9_]{11})?(&rel=0)?$/.test( return /^https?:\/\/(www\.)?(youtube|youtube-nocookie)\.com\/embed\/[a-zA-Z0-9_]{11}(\?)?(&modestbranding=1)?(&autoplay=0)?(&loop=1)?(&playlist=[a-zA-Z0-9_]{11})?(&rel=0)?$/.test(
attrs.src || '' attrs.src || ''
); )
} else if (['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(tag)) { } else if (['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(tag)) {
return attrs.id !== 'svelte'; return attrs.id !== 'svelte'
} else if (tag === 'input') { } else if (tag === 'input') {
return attrs.type === 'checkbox' && attrs.disabled === ''; return attrs.type === 'checkbox' && attrs.disabled === ''
} else if (tag === 'code' || tag === 'span') { } else if (tag === 'code' || tag === 'span') {
return !attrs.class || attrs.class.replace(' ', '').startsWith('hljs'); return !attrs.class || attrs.class.replace(' ', '').startsWith('hljs')
} else { } else {
return true; return true
} }
}, },
transformText: null, transformText: null,
}); })
} }
export function markdownInline(markdown: string): string { export function markdownInline(markdown: string): string {
return insane( return insane(
marked.parseInline(markdown), marked.parseInline(markdown),
{ {
allowedAttributes: { allowedAttributes: {
a: ['href', 'target', 'title', 'rel'], a: ['href', 'target', 'title', 'rel'],
}, },
allowedClasses: {}, allowedClasses: {},
allowedSchemes: ['http', 'https', 'mailto'], allowedSchemes: ['http', 'https', 'mailto'],
allowedTags: ['a', 'b', 'br', 'code', 'em', 'i', 'strike', 'strong', 'sub', 'sup', 'u'], allowedTags: ['a', 'b', 'br', 'code', 'em', 'i', 'strike', 'strong', 'sub', 'sup', 'u'],
transformText: null, transformText: null,
}, },
true true
); )
} }
export function markdown(markdown: string): string { export function markdown(markdown: string): string {
return sanitize(marked.parse(markdown)); return sanitize(marked.parse(markdown))
} }

View File

@@ -1,38 +1,38 @@
export class Permissions { export class Permissions {
data = { data = {
uploadVersions: false, uploadVersions: false,
deleteVersion: false, deleteVersion: false,
editDetails: false, editDetails: false,
editBody: false, editBody: false,
manageInvites: false, manageInvites: false,
removeMember: false, removeMember: false,
editMember: false, editMember: false,
deleteProject: false, deleteProject: false,
}; }
get settingsPage(): boolean { get settingsPage(): boolean {
return ( return (
this.data.manageInvites || this.data.manageInvites ||
this.data.removeMember || this.data.removeMember ||
this.data.editMember || this.data.editMember ||
this.data.deleteProject this.data.deleteProject
); )
} }
constructor(from: number | 'ALL' | null) { constructor(from: number | 'ALL' | null) {
if (from === 'ALL' || from === 0b11111111 || from === null) { if (from === 'ALL' || from === 0b11111111 || from === null) {
Object.keys(this.data).forEach((v) => (this.data[v] = true)); Object.keys(this.data).forEach((v) => (this.data[v] = true))
} else if (typeof from === 'number') { } else if (typeof from === 'number') {
this.data = { this.data = {
uploadVersions: !!(from & (1 << 0)), uploadVersions: !!(from & (1 << 0)),
deleteVersion: !!(from & (1 << 1)), deleteVersion: !!(from & (1 << 1)),
editDetails: !!(from & (1 << 2)), editDetails: !!(from & (1 << 2)),
editBody: !!(from & (1 << 3)), editBody: !!(from & (1 << 3)),
manageInvites: !!(from & (1 << 4)), manageInvites: !!(from & (1 << 4)),
removeMember: !!(from & (1 << 5)), removeMember: !!(from & (1 << 5)),
editMember: !!(from & (1 << 6)), editMember: !!(from & (1 << 6)),
deleteProject: !!(from & (1 << 7)), deleteProject: !!(from & (1 << 7)),
}; }
} }
} }
} }

View File

@@ -1,6 +1,6 @@
let idCounter = 0; let idCounter = 0
export function uniqueId(prefix = ''): string { export function uniqueId(prefix = ''): string {
const id = ++idCounter; const id = ++idCounter
return prefix + id; return prefix + id
} }

View File

@@ -1,86 +1,83 @@
import gameVersions from '$generated/gameVersions.json'; import gameVersions from '$generated/gameVersions.json'
export function formatVersions(versionArray: string[]): string { export function formatVersions(versionArray: string[]): string {
const allVersions = gameVersions.slice().reverse(); const allVersions = gameVersions.slice().reverse()
const allReleases = allVersions.filter((x) => x.version_type === 'release'); const allReleases = allVersions.filter((x) => x.version_type === 'release')
const intervals = []; const intervals = []
let currentInterval = 0; let currentInterval = 0
for (let i = 0; i < versionArray.length; i++) { for (let i = 0; i < versionArray.length; i++) {
const index = allVersions.findIndex((x) => x.version === versionArray[i]); const index = allVersions.findIndex((x) => x.version === versionArray[i])
const releaseIndex = allReleases.findIndex((x) => x.version === versionArray[i]); const releaseIndex = allReleases.findIndex((x) => x.version === versionArray[i])
if (i === 0) { if (i === 0) {
intervals.push([[versionArray[i], index, releaseIndex]]); intervals.push([[versionArray[i], index, releaseIndex]])
} else { } else {
const intervalBase = intervals[currentInterval]; const intervalBase = intervals[currentInterval]
if ( if (
(index - intervalBase[intervalBase.length - 1][1] === 1 || (index - intervalBase[intervalBase.length - 1][1] === 1 ||
releaseIndex - intervalBase[intervalBase.length - 1][2] === 1) && releaseIndex - intervalBase[intervalBase.length - 1][2] === 1) &&
(allVersions[intervalBase[0][1]].version_type === 'release' || (allVersions[intervalBase[0][1]].version_type === 'release' ||
allVersions[index].version_type !== 'release') allVersions[index].version_type !== 'release')
) { ) {
intervalBase[1] = [versionArray[i], index, releaseIndex]; intervalBase[1] = [versionArray[i], index, releaseIndex]
} else { } else {
currentInterval += 1; currentInterval += 1
intervals[currentInterval] = [[versionArray[i], index, releaseIndex]]; intervals[currentInterval] = [[versionArray[i], index, releaseIndex]]
} }
} }
} }
const newIntervals = []; const newIntervals = []
for (let i = 0; i < intervals.length; i++) { for (let i = 0; i < intervals.length; i++) {
const interval = intervals[i]; const interval = intervals[i]
if (interval.length === 2 && interval[0][2] !== -1 && interval[1][2] === -1) { if (interval.length === 2 && interval[0][2] !== -1 && interval[1][2] === -1) {
let lastSnapshot = null; let lastSnapshot = null
for (let j = interval[1][1]; j > interval[0][1]; j--) { for (let j = interval[1][1]; j > interval[0][1]; j--) {
if (allVersions[j].version_type === 'release') { if (allVersions[j].version_type === 'release') {
newIntervals.push([ newIntervals.push([
interval[0], interval[0],
[ [
allVersions[j].version, allVersions[j].version,
j, j,
allReleases.findIndex((x) => x.version === allVersions[j].version), allReleases.findIndex((x) => x.version === allVersions[j].version),
], ],
]); ])
if (lastSnapshot !== null && lastSnapshot !== j + 1) { if (lastSnapshot !== null && lastSnapshot !== j + 1) {
newIntervals.push([ newIntervals.push([[allVersions[lastSnapshot].version, lastSnapshot, -1], interval[1]])
[allVersions[lastSnapshot].version, lastSnapshot, -1], } else {
interval[1], newIntervals.push([interval[1]])
]); }
} else {
newIntervals.push([interval[1]]);
}
break; break
} else { } else {
lastSnapshot = j; lastSnapshot = j
} }
} }
} else { } else {
newIntervals.push(interval); newIntervals.push(interval)
} }
} }
const output = []; const output = []
for (const interval of newIntervals) { for (const interval of newIntervals) {
if (interval.length === 2) { if (interval.length === 2) {
output.push(`${interval[0][0]}${interval[1][0]}`); output.push(`${interval[0][0]}${interval[1][0]}`)
} else { } else {
output.push(interval[0][0]); output.push(interval[0][0])
} }
} }
return output.join(', '); return output.join(', ')
} }
export const getPrimary = (files) => files.find((file) => file.primary) || files[0]; export const getPrimary = (files) => files.find((file) => file.primary) || files[0]
export function downloadUrl(file): string { export function downloadUrl(file): string {
return import.meta.env.VITE_API_URL + `version_file/${file?.hashes.sha1}/download`; return import.meta.env.VITE_API_URL + `version_file/${file?.hashes.sha1}/download`
} }

View File

@@ -9,20 +9,20 @@ To make use of the built-in icons, styles, and plugins in omorphia, you will nee
Add the following parts to your `svelte.config.js` file: Add the following parts to your `svelte.config.js` file:
```js ```js
import { preprocess, plugins } from 'omorphia/config/svelte.config'; import { preprocess, plugins } from 'omorphia/config/svelte.config'
/** @type {import('@sveltejs/kit').Config} */ /** @type {import('@sveltejs/kit').Config} */
const config = { const config = {
preprocess: [preprocess], preprocess: [preprocess],
kit: { kit: {
vite: { vite: {
plugins: [...plugins], plugins: [...plugins],
}, },
}, },
}; }
export default config; export default config
``` ```
## PostCSS ## PostCSS
@@ -32,5 +32,5 @@ Create a `postcss.config.cjs` file in the root of your project.
Add the following line to that file: Add the following line to that file:
```js ```js
module.exports = require('omorphia/config/postcss.config.cjs'); module.exports = require('omorphia/config/postcss.config.cjs')
``` ```

View File

@@ -6,33 +6,33 @@ The generator plugin creates static files from API responses to increase perform
### Current options ### Current options
- `projectColors` (false) generates colors for every project - `projectColors` (false) generates colors for every project
- `tags` (false) copies & parses tags from API - `tags` (false) copies & parses tags from API
- `gameVersions` copes game versions from API - `gameVersions` copes game versions from API
- `landingPage` gets icon urls for top 100 mods - `landingPage` gets icon urls for top 100 mods
> All options are disabled by default > All options are disabled by default
## Configuration ## Configuration
```js ```js
import Generator from 'omorphia/plugins/generator'; import Generator from 'omorphia/plugins/generator'
/** @type {import('@sveltejs/kit').Config} */ /** @type {import('@sveltejs/kit').Config} */
const config = { const config = {
kit: { kit: {
vite: { vite: {
plugins: [ plugins: [
Generator({ Generator({
projectColors: true, projectColors: true,
tags: true, tags: true,
gameVersions: true, gameVersions: true,
landingPage: true, landingPage: true,
}), }),
], ],
}, },
}, },
}; }
export default config; export default config
``` ```

View File

@@ -59,14 +59,14 @@ The `markdownInline` parser is perfect for translations and short bios. It doesn
The `Permissions` class provides an easy way to manage user permissions. The `Permissions` class provides an easy way to manage user permissions.
```ts ```ts
import { Permissions } from 'omorphia/utils'; import { Permissions } from 'omorphia/utils'
const adminLevel = new Permissions('ALL'); const adminLevel = new Permissions('ALL')
const memberLevel = new Permissions(member.permissions); /* `member` from API */ const memberLevel = new Permissions(member.permissions) /* `member` from API */
const userLevel = new Permissions(0); const userLevel = new Permissions(0)
if (memberLevel.data.uploadVersions) { if (memberLevel.data.uploadVersions) {
console.log('Can upload versions!'); console.log('Can upload versions!')
} }
``` ```

View File

@@ -1,59 +1,59 @@
import { mdsvex } from 'mdsvex'; import { mdsvex } from 'mdsvex'
import mdsvexConfig from './mdsvex.config.js'; import mdsvexConfig from './mdsvex.config.js'
import adapter from '@sveltejs/adapter-static'; import adapter from '@sveltejs/adapter-static'
import examples from 'mdsvexamples/vite'; import examples from 'mdsvexamples/vite'
import sveld from './plugins/sveld.js'; import sveld from './plugins/sveld.js'
import path from 'path'; import path from 'path'
import { preprocess, plugins } from './src/package/config/svelte.config.js'; import { preprocess, plugins } from './src/package/config/svelte.config.js'
import Generator from './src/package/plugins/generator/index.js'; import Generator from './src/package/plugins/generator/index.js'
/** @type {import('@sveltejs/kit').Config} */ /** @type {import('@sveltejs/kit').Config} */
const config = { const config = {
extensions: ['.svelte', ...mdsvexConfig.extensions], extensions: ['.svelte', ...mdsvexConfig.extensions],
preprocess: [preprocess, mdsvex(mdsvexConfig)], preprocess: [preprocess, mdsvex(mdsvexConfig)],
kit: { kit: {
adapter: adapter(), adapter: adapter(),
prerender: { prerender: {
default: true, default: true,
onError: 'continue', onError: 'continue',
}, },
vite: { vite: {
plugins: [ plugins: [
Generator({ Generator({
gameVersions: true, gameVersions: true,
}), }),
...plugins, ...plugins,
examples, examples,
sveld(), sveld(),
], ],
resolve: { resolve: {
alias: { alias: {
$package: path.resolve('./src/package'), $package: path.resolve('./src/package'),
$routes: path.resolve('./src/routes'), $routes: path.resolve('./src/routes'),
$generated: path.resolve('./generated'), $generated: path.resolve('./generated'),
omorphia: path.resolve('./src/package'), omorphia: path.resolve('./src/package'),
}, },
}, },
build: { build: {
rollupOptions: { rollupOptions: {
external: '/_app/COMPONENT_API.json', external: '/_app/COMPONENT_API.json',
}, },
}, },
server: { server: {
fs: { fs: {
allow: ['generated'], allow: ['generated'],
}, },
}, },
}, },
files: { files: {
lib: 'src/package', lib: 'src/package',
}, },
}, },
}; }
export default config; export default config

View File

@@ -1,16 +1,16 @@
{ {
"compilerOptions": { "compilerOptions": {
"paths": { "paths": {
"omorphia/*": ["src/package/*"], "omorphia/*": ["src/package/*"],
"omorphia": ["src/package"], "omorphia": ["src/package"],
"$package/*": ["src/package/*"], "$package/*": ["src/package/*"],
"$routes/*": ["src/routes/*"], "$routes/*": ["src/routes/*"],
"$generated/*": ["generated/*"], "$generated/*": ["generated/*"],
"$lib": ["src/package"], "$lib": ["src/package"],
"$lib/*": ["src/package/*"] "$lib/*": ["src/package/*"]
}, },
"resolveJsonModule": true, "resolveJsonModule": true,
"esModuleInterop": true "esModuleInterop": true
}, },
"extends": "./.svelte-kit/tsconfig.json" "extends": "./.svelte-kit/tsconfig.json"
} }