add source codes
This commit is contained in:
parent
9da3d1044d
commit
1a26f0aaf4
55 changed files with 2774 additions and 0 deletions
6
.env.example
Normal file
6
.env.example
Normal file
|
@ -0,0 +1,6 @@
|
|||
# Hostname
|
||||
PUBLIC_HOSTNAME = 'moris.day'
|
||||
|
||||
# Post
|
||||
POST_DIR = '/home/user/BlogPosts'
|
||||
PUBLIC_POST_REPO = 'https://github.com/moris/Posts'
|
1
.npmrc
Normal file
1
.npmrc
Normal file
|
@ -0,0 +1 @@
|
|||
engine-strict=true
|
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"npm.packageManager": "bun",
|
||||
}
|
7
Caddyfile
Normal file
7
Caddyfile
Normal file
|
@ -0,0 +1,7 @@
|
|||
localhost:80, macbookair.local:80 {
|
||||
file_server
|
||||
|
||||
handle_path /blog/* {
|
||||
root build
|
||||
}
|
||||
}
|
BIN
bun.lockb
Executable file
BIN
bun.lockb
Executable file
Binary file not shown.
735
package-lock.json
generated
Normal file
735
package-lock.json
generated
Normal file
|
@ -0,0 +1,735 @@
|
|||
{
|
||||
"name": "day.moris.blog",
|
||||
"version": "0.0.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "day.moris.blog",
|
||||
"version": "0.0.1",
|
||||
"devDependencies": {
|
||||
"@sveltejs/adapter-auto": "^3.0.0",
|
||||
"@sveltejs/adapter-static": "^3.0.8",
|
||||
"@sveltejs/kit": "^2.0.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^4.0.0",
|
||||
"svelte": "^5.0.0",
|
||||
"svelte-check": "^4.0.0",
|
||||
"typescript": "^5.0.0",
|
||||
"vite": "^5.4.11"
|
||||
}
|
||||
},
|
||||
"node_modules/@ampproject/remapping": {
|
||||
"version": "2.3.0",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@jridgewell/gen-mapping": "^0.3.5",
|
||||
"@jridgewell/trace-mapping": "^0.3.24"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-arm64": {
|
||||
"version": "0.21.5",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/gen-mapping": {
|
||||
"version": "0.3.8",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/set-array": "^1.2.1",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10",
|
||||
"@jridgewell/trace-mapping": "^0.3.24"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/resolve-uri": {
|
||||
"version": "3.1.2",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/set-array": {
|
||||
"version": "1.2.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/sourcemap-codec": {
|
||||
"version": "1.5.0",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@jridgewell/trace-mapping": {
|
||||
"version": "0.3.25",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/resolve-uri": "^3.1.0",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@polka/url": {
|
||||
"version": "1.0.0-next.28",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||
"version": "4.29.1",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
]
|
||||
},
|
||||
"node_modules/@sveltejs/adapter-auto": {
|
||||
"version": "3.3.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"import-meta-resolve": "^4.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@sveltejs/kit": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@sveltejs/adapter-static": {
|
||||
"version": "3.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.8.tgz",
|
||||
"integrity": "sha512-YaDrquRpZwfcXbnlDsSrBQNCChVOT9MGuSg+dMAyfsAa1SmiAhrA5jUYUiIMC59G92kIbY/AaQOWcBdq+lh+zg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@sveltejs/kit": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@sveltejs/kit": {
|
||||
"version": "2.15.1",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/cookie": "^0.6.0",
|
||||
"cookie": "^0.6.0",
|
||||
"devalue": "^5.1.0",
|
||||
"esm-env": "^1.2.1",
|
||||
"import-meta-resolve": "^4.1.0",
|
||||
"kleur": "^4.1.5",
|
||||
"magic-string": "^0.30.5",
|
||||
"mrmime": "^2.0.0",
|
||||
"sade": "^1.8.1",
|
||||
"set-cookie-parser": "^2.6.0",
|
||||
"sirv": "^3.0.0",
|
||||
"tiny-glob": "^0.2.9"
|
||||
},
|
||||
"bin": {
|
||||
"svelte-kit": "svelte-kit.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.13"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0",
|
||||
"svelte": "^4.0.0 || ^5.0.0-next.0",
|
||||
"vite": "^5.0.3 || ^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@sveltejs/vite-plugin-svelte": {
|
||||
"version": "4.0.4",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@sveltejs/vite-plugin-svelte-inspector": "^3.0.0-next.0||^3.0.0",
|
||||
"debug": "^4.3.7",
|
||||
"deepmerge": "^4.3.1",
|
||||
"kleur": "^4.1.5",
|
||||
"magic-string": "^0.30.12",
|
||||
"vitefu": "^1.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.0.0 || ^20.0.0 || >=22"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"svelte": "^5.0.0-next.96 || ^5.0.0",
|
||||
"vite": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@sveltejs/vite-plugin-svelte-inspector": {
|
||||
"version": "3.0.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^4.3.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.0.0 || ^20.0.0 || >=22"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@sveltejs/vite-plugin-svelte": "^4.0.0-next.0||^4.0.0",
|
||||
"svelte": "^5.0.0-next.96 || ^5.0.0",
|
||||
"vite": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/cookie": {
|
||||
"version": "0.6.0",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/estree": {
|
||||
"version": "1.0.6",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.14.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/acorn-typescript": {
|
||||
"version": "1.4.13",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"acorn": ">=8.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/aria-query": {
|
||||
"version": "5.3.2",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/axobject-query": {
|
||||
"version": "4.1.0",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/chokidar": {
|
||||
"version": "4.0.3",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"readdirp": "^4.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14.16.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/clsx": {
|
||||
"version": "2.1.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/cookie": {
|
||||
"version": "0.6.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.4.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "^2.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"supports-color": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/deepmerge": {
|
||||
"version": "4.3.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/devalue": {
|
||||
"version": "5.1.1",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.21.5",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"esbuild": "bin/esbuild"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@esbuild/aix-ppc64": "0.21.5",
|
||||
"@esbuild/android-arm": "0.21.5",
|
||||
"@esbuild/android-arm64": "0.21.5",
|
||||
"@esbuild/android-x64": "0.21.5",
|
||||
"@esbuild/darwin-arm64": "0.21.5",
|
||||
"@esbuild/darwin-x64": "0.21.5",
|
||||
"@esbuild/freebsd-arm64": "0.21.5",
|
||||
"@esbuild/freebsd-x64": "0.21.5",
|
||||
"@esbuild/linux-arm": "0.21.5",
|
||||
"@esbuild/linux-arm64": "0.21.5",
|
||||
"@esbuild/linux-ia32": "0.21.5",
|
||||
"@esbuild/linux-loong64": "0.21.5",
|
||||
"@esbuild/linux-mips64el": "0.21.5",
|
||||
"@esbuild/linux-ppc64": "0.21.5",
|
||||
"@esbuild/linux-riscv64": "0.21.5",
|
||||
"@esbuild/linux-s390x": "0.21.5",
|
||||
"@esbuild/linux-x64": "0.21.5",
|
||||
"@esbuild/netbsd-x64": "0.21.5",
|
||||
"@esbuild/openbsd-x64": "0.21.5",
|
||||
"@esbuild/sunos-x64": "0.21.5",
|
||||
"@esbuild/win32-arm64": "0.21.5",
|
||||
"@esbuild/win32-ia32": "0.21.5",
|
||||
"@esbuild/win32-x64": "0.21.5"
|
||||
}
|
||||
},
|
||||
"node_modules/esm-env": {
|
||||
"version": "1.2.1",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/esrap": {
|
||||
"version": "1.3.2",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/sourcemap-codec": "^1.4.15"
|
||||
}
|
||||
},
|
||||
"node_modules/fdir": {
|
||||
"version": "6.4.2",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"picomatch": "^3 || ^4"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"picomatch": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/globalyzer": {
|
||||
"version": "0.1.0",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/globrex": {
|
||||
"version": "0.1.2",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/import-meta-resolve": {
|
||||
"version": "4.1.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/is-reference": {
|
||||
"version": "3.0.3",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/estree": "^1.0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/kleur": {
|
||||
"version": "4.1.5",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/locate-character": {
|
||||
"version": "3.0.0",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/magic-string": {
|
||||
"version": "0.30.17",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/sourcemap-codec": "^1.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/mri": {
|
||||
"version": "1.2.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/mrmime": {
|
||||
"version": "2.0.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.8",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"nanoid": "bin/nanoid.cjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.1.1",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.4.49",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/postcss/"
|
||||
},
|
||||
{
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/funding/github/npm/postcss"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.7",
|
||||
"picocolors": "^1.1.1",
|
||||
"source-map-js": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || >=14"
|
||||
}
|
||||
},
|
||||
"node_modules/readdirp": {
|
||||
"version": "4.0.2",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 14.16.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "individual",
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/rollup": {
|
||||
"version": "4.29.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/estree": "1.0.6"
|
||||
},
|
||||
"bin": {
|
||||
"rollup": "dist/bin/rollup"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0",
|
||||
"npm": ">=8.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rollup/rollup-android-arm-eabi": "4.29.1",
|
||||
"@rollup/rollup-android-arm64": "4.29.1",
|
||||
"@rollup/rollup-darwin-arm64": "4.29.1",
|
||||
"@rollup/rollup-darwin-x64": "4.29.1",
|
||||
"@rollup/rollup-freebsd-arm64": "4.29.1",
|
||||
"@rollup/rollup-freebsd-x64": "4.29.1",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.29.1",
|
||||
"@rollup/rollup-linux-arm-musleabihf": "4.29.1",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.29.1",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.29.1",
|
||||
"@rollup/rollup-linux-loongarch64-gnu": "4.29.1",
|
||||
"@rollup/rollup-linux-powerpc64le-gnu": "4.29.1",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.29.1",
|
||||
"@rollup/rollup-linux-s390x-gnu": "4.29.1",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.29.1",
|
||||
"@rollup/rollup-linux-x64-musl": "4.29.1",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.29.1",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.29.1",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.29.1",
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/sade": {
|
||||
"version": "1.8.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mri": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/set-cookie-parser": {
|
||||
"version": "2.7.1",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/sirv": {
|
||||
"version": "3.0.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@polka/url": "^1.0.0-next.24",
|
||||
"mrmime": "^2.0.0",
|
||||
"totalist": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.2.1",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte": {
|
||||
"version": "5.16.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ampproject/remapping": "^2.3.0",
|
||||
"@jridgewell/sourcemap-codec": "^1.5.0",
|
||||
"@types/estree": "^1.0.5",
|
||||
"acorn": "^8.12.1",
|
||||
"acorn-typescript": "^1.4.13",
|
||||
"aria-query": "^5.3.1",
|
||||
"axobject-query": "^4.1.0",
|
||||
"clsx": "^2.1.1",
|
||||
"esm-env": "^1.2.1",
|
||||
"esrap": "^1.3.2",
|
||||
"is-reference": "^3.0.3",
|
||||
"locate-character": "^3.0.0",
|
||||
"magic-string": "^0.30.11",
|
||||
"zimmerframe": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-check": {
|
||||
"version": "4.1.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/trace-mapping": "^0.3.25",
|
||||
"chokidar": "^4.0.1",
|
||||
"fdir": "^6.2.0",
|
||||
"picocolors": "^1.0.0",
|
||||
"sade": "^1.7.4"
|
||||
},
|
||||
"bin": {
|
||||
"svelte-check": "bin/svelte-check"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"svelte": "^4.0.0 || ^5.0.0-next.0",
|
||||
"typescript": ">=5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tiny-glob": {
|
||||
"version": "0.2.9",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"globalyzer": "0.1.0",
|
||||
"globrex": "^0.1.2"
|
||||
}
|
||||
},
|
||||
"node_modules/totalist": {
|
||||
"version": "3.0.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.7.2",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "5.4.11",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"esbuild": "^0.21.3",
|
||||
"postcss": "^8.4.43",
|
||||
"rollup": "^4.20.0"
|
||||
},
|
||||
"bin": {
|
||||
"vite": "bin/vite.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.0.0 || >=20.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/vitejs/vite?sponsor=1"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "~2.3.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/node": "^18.0.0 || >=20.0.0",
|
||||
"less": "*",
|
||||
"lightningcss": "^1.21.0",
|
||||
"sass": "*",
|
||||
"sass-embedded": "*",
|
||||
"stylus": "*",
|
||||
"sugarss": "*",
|
||||
"terser": "^5.4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/node": {
|
||||
"optional": true
|
||||
},
|
||||
"less": {
|
||||
"optional": true
|
||||
},
|
||||
"lightningcss": {
|
||||
"optional": true
|
||||
},
|
||||
"sass": {
|
||||
"optional": true
|
||||
},
|
||||
"sass-embedded": {
|
||||
"optional": true
|
||||
},
|
||||
"stylus": {
|
||||
"optional": true
|
||||
},
|
||||
"sugarss": {
|
||||
"optional": true
|
||||
},
|
||||
"terser": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/vitefu": {
|
||||
"version": "1.0.4",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"workspaces": [
|
||||
"tests/deps/*",
|
||||
"tests/projects/*"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"vite": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/zimmerframe": {
|
||||
"version": "1.1.2",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
}
|
39
package.json
Normal file
39
package.json
Normal file
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"name": "day.moris.blog",
|
||||
"private": true,
|
||||
"version": "0.0.1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/adapter-static": "^3.0.8",
|
||||
"@sveltejs/kit": "^2.0.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^4.0.0",
|
||||
"svelte": "^5.0.0",
|
||||
"svelte-check": "^4.0.0",
|
||||
"typescript": "^5.0.0",
|
||||
"vite": "^5.4.11",
|
||||
"@types/bun": "latest"
|
||||
},
|
||||
"dependencies": {
|
||||
"@twemoji/parser": "^15.1.1",
|
||||
"github-slugger": "^2.0.0",
|
||||
"rehype-external-links": "^3.0.0",
|
||||
"rehype-highlight": "^7.0.1",
|
||||
"rehype-katex": "^7.0.1",
|
||||
"rehype-slug": "^6.0.0",
|
||||
"rehype-stringify": "^10.0.1",
|
||||
"remark": "^15.0.1",
|
||||
"remark-breaks": "^4.0.0",
|
||||
"remark-gfm": "^4.0.0",
|
||||
"remark-math": "^6.0.0",
|
||||
"remark-rehype": "^11.1.1",
|
||||
"yaml": "^2.6.1"
|
||||
},
|
||||
"module": "index.ts"
|
||||
}
|
99
src/app.css
Normal file
99
src/app.css
Normal file
|
@ -0,0 +1,99 @@
|
|||
@property --theme-color {
|
||||
syntax: "<color>";
|
||||
inherits: true;
|
||||
}
|
||||
@property --back-color {
|
||||
syntax: "<color>";
|
||||
inherits: true;
|
||||
}
|
||||
@property --grid-color {
|
||||
syntax: "<color>";
|
||||
inherits: true;
|
||||
}
|
||||
|
||||
/* theme color */
|
||||
body, body.light {
|
||||
--color-scheme: light;
|
||||
--white-black: white;
|
||||
--black-white: black;
|
||||
--theme-color: hsl(85, 50%, 60%);
|
||||
--back-color: hsl(60, 100%, 98%);
|
||||
--font-color: #222;
|
||||
--grid-color: #fff;
|
||||
--code-color: #ddd;
|
||||
--code-block: #30303a;
|
||||
--frame-shadow: #999;
|
||||
}
|
||||
|
||||
body.dark {
|
||||
--color-scheme: dark;
|
||||
--white-black: black;
|
||||
--black-white: white;
|
||||
--theme-color: teal;
|
||||
--back-color: hsl(210, 7%, 18%);
|
||||
--font-color: #f5f5f5;
|
||||
--grid-color: #333;
|
||||
--code-color: #445;
|
||||
--code-block: #23232a;
|
||||
--frame-shadow: #111;
|
||||
}
|
||||
|
||||
@media(prefers-color-scheme: dark){
|
||||
body {
|
||||
--color-scheme: dark;
|
||||
--white-black: black;
|
||||
--black-white: white;
|
||||
--theme-color: teal;
|
||||
--back-color: hsl(210, 7%, 18%);
|
||||
--font-color: #fafafa;
|
||||
--grid-color: #333;
|
||||
--code-color: #445;
|
||||
--code-block: #23232a;
|
||||
--frame-shadow: #111;
|
||||
}
|
||||
}
|
||||
|
||||
/* general */
|
||||
body {
|
||||
margin: 0;
|
||||
color: var(--font-color);
|
||||
}
|
||||
|
||||
img {
|
||||
-webkit-user-drag: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
@media (scripting: none) {
|
||||
.js {display: none !important;}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* font */
|
||||
body {
|
||||
font-family: "-apple-system", "BlinkMacSystemFont", "Hiragino Kaku Gothic ProN", "Noto Sans CJK JP", "Segoe UI", "BIZ UDPGothic", sans-serif;
|
||||
/* Apple | Linux | win-en win-jp */
|
||||
}
|
||||
code {
|
||||
font-family: "Source Code Pro", "Monaco", "Consolas", "BIZ UDGothic", monospace;
|
||||
/* Linux | Apple | windows | 和文 */
|
||||
}
|
||||
em {
|
||||
font-family: serif;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* link style */
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: var(--theme-color);
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
&:visited {
|
||||
color: hsl(290, 40%, 50%);
|
||||
}
|
||||
}
|
13
src/app.d.ts
vendored
Normal file
13
src/app.d.ts
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
// See https://svelte.dev/docs/kit/types#app.d.ts
|
||||
// for information about these interfaces
|
||||
declare global {
|
||||
namespace App {
|
||||
// interface Error {}
|
||||
// interface Locals {}
|
||||
// interface PageData {}
|
||||
// interface PageState {}
|
||||
// interface Platform {}
|
||||
}
|
||||
}
|
||||
|
||||
export {};
|
12
src/app.html
Normal file
12
src/app.html
Normal file
|
@ -0,0 +1,12 @@
|
|||
<!doctype html>
|
||||
<html lang="ja">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="https://moris.day/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
<body data-sveltekit-preload-data="hover">
|
||||
<div style="display: contents">%sveltekit.body%</div>
|
||||
</body>
|
||||
</html>
|
193
src/lib/components/Markdown.css
Normal file
193
src/lib/components/Markdown.css
Normal file
|
@ -0,0 +1,193 @@
|
|||
.markdown {
|
||||
width: 100%;
|
||||
overflow-wrap: anywhere;
|
||||
|
||||
@media (width>480px) {
|
||||
font-size: 1.125em;
|
||||
}
|
||||
|
||||
& h1, h2 {
|
||||
font-weight: 600;
|
||||
padding-top: 25px;
|
||||
@media(width>999px){padding-top:50px; margin-top:0;}
|
||||
|
||||
&::before {
|
||||
display: inline-block;
|
||||
content: '§';
|
||||
margin-right: 4px;
|
||||
width: 4px;
|
||||
color: #0000;
|
||||
background-color: var(--theme-color);
|
||||
}
|
||||
}
|
||||
|
||||
& p {
|
||||
margin: 0 0.5em;
|
||||
line-height: 2em;
|
||||
@media (width>480px) {
|
||||
margin: 1em 2em;
|
||||
}
|
||||
}
|
||||
|
||||
& a[target="_blank"]:after {
|
||||
content: '■';
|
||||
font-size: 1em;
|
||||
line-height: 1em;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
display: inline-block;
|
||||
mask-image: url('data:image/svg+xml;utf-8,<svg viewBox="0 -960 960 960" xmlns="http://www.w3.org/2000/svg"><path d="m293.3-240q-22 0-37.67-15.67-15.67-15.67-15.67-37.67v-373.3q0-22 15.67-37.67 15.67-15.67 37.67-15.67h186.7v53.33h-186.7v373.3h373.3v-186.7h53.33v186.7q0 22-15.67 37.67-15.67 15.67-37.67 15.67zm125.3-141.3-37.33-37.33 248-248h-96v-53.33h186.7v186.7h-53.33v-96z"/></svg>');
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
& li {
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
& img {
|
||||
display: block;
|
||||
margin: 1em auto;
|
||||
max-width: 100%;
|
||||
max-height: 60vh;
|
||||
}
|
||||
|
||||
& code {
|
||||
font-size: 1rem;
|
||||
margin: 0 3px;
|
||||
padding: 0 3px;
|
||||
border-radius: 3px;
|
||||
background-color: var(--code-color);
|
||||
}
|
||||
& details {
|
||||
margin: 0 0.5em;
|
||||
padding: 0 .5em;
|
||||
border: dashed #8888 2px;
|
||||
border-radius: 6px;
|
||||
line-height: 2em;
|
||||
@media (width>480px) {
|
||||
margin: 1em 2em;
|
||||
}
|
||||
}
|
||||
& pre {
|
||||
position: relative;
|
||||
margin: 1em;
|
||||
padding: 1em;
|
||||
box-sizing: border-box;
|
||||
border-radius: 8px;
|
||||
background-color: var(--code-block);
|
||||
color: #d1d9e1;
|
||||
overflow: auto;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: #aaa #444;
|
||||
|
||||
@media (width<480px) {
|
||||
margin: 1em 0;
|
||||
}
|
||||
& code {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
background-color: #fff0;
|
||||
}
|
||||
/*
|
||||
issue: 擬似要素は { イベントリスナを設置できない, アニメーション不可, スクロールに巻き込まれる }
|
||||
&::after {
|
||||
content: '';
|
||||
background-image: url('data:image/svg+xml;utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="white"><path d="m200-120c-44 0-80-35.6-80-80v-560c0-44 35.6-80 80-80h167c15-47.5 62.7-80 113-80 55.7 0 100 35 114 80h166c44 0 80 35.6 80 80v560c0 44-35.6 80-80 80zm0-80h560v-560h-80v120h-400v-120h-80zm280-560c22.8 0 40-17.2 40-40 0-22.8-17.2-40-40-40-22.8 0-40 17.2-40 40 0 22.8 17.2 40 40 40z"/></svg>');
|
||||
width: 1.5em;
|
||||
height: 1.5em;
|
||||
position: absolute;
|
||||
top: 1em;
|
||||
right: 1em;
|
||||
} */
|
||||
}
|
||||
& table {
|
||||
margin: 1rem auto;
|
||||
font-size: 1.2rem;
|
||||
border-collapse: collapse;
|
||||
|
||||
& thead tr {
|
||||
border-bottom: solid 1px var(--black-white);
|
||||
}
|
||||
& tbody tr {
|
||||
border-top: solid color-mix(in srgb, var(--black-white) 20%, var(--back-color)) 1px;
|
||||
/* background-color: color-mix(in srgb, var(--black-white) 10%, var(--back-color)); */
|
||||
}
|
||||
& td,th {
|
||||
border-width: 0px;
|
||||
padding: .5em;
|
||||
}
|
||||
}
|
||||
& blockquote {
|
||||
position: relative;
|
||||
font-style: italic;
|
||||
width: fit-content;
|
||||
max-width: 100%;
|
||||
margin: 1em auto;
|
||||
border-top: 1px solid var(--font-color);
|
||||
border-bottom: 1px solid var(--font-color);
|
||||
|
||||
& p::before {
|
||||
content: '';
|
||||
mask-image: url('data:image/svg+xml;utf-8,<svg version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg"><path d="m57.2 36.6-4.3 20.4h-20.5l3.8-17.9q3.3-16 10.4-23.5 7.2-7.5 16.8-8.6l-1.6 7.9q-11.7 3.2-15.7 21.7zm-31.8 0-4.3 20.4h-20.5l3.8-17.9q3.3-16 10.4-23.5 7.2-7.5 16.8-8.6l-1.6 7.9q-11.7 3.2-15.7 21.7z"/></svg>');
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
position: absolute;
|
||||
background-color: var(--font-color);
|
||||
top: -.4em;
|
||||
left: -1em;
|
||||
}
|
||||
& p::after {
|
||||
content: '';
|
||||
mask-image: url('data:image/svg+xml;utf-8,<svg version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg"><path d="m6.8 27.4 4.3-20.4h20.5l-3.8 17.9q-3.3 16-10.4 23.5-7.17 7.5-16.8 8.6l1.6-7.9q11.7-3.2 15.7-21.7zm31.8 0 4.3-20.4h20.5l-3.8 17.9q-3.3 16-10.4 23.5-7.17 7.5-16.8 8.6l1.6-7.9q11.7-3.2 15.7-21.7z"/></svg>');
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
position: absolute;
|
||||
background-color: var(--font-color);
|
||||
bottom: -.4em;
|
||||
right: -1em;
|
||||
}
|
||||
}
|
||||
& iframe {
|
||||
display: block;
|
||||
margin: 30px auto;
|
||||
border: none;
|
||||
width: 80%;
|
||||
aspect-ratio: 16/9;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0px 6px 30px var(--frame-shadow);
|
||||
max-height: 75vh;
|
||||
transition: max-height .3s ease-in-out;
|
||||
&.hide {
|
||||
max-height: 30px;
|
||||
}
|
||||
@media(width<480px) {
|
||||
width: 100%;
|
||||
aspect-ratio: 4/3;
|
||||
box-shadow: 0px 4px 16px var(--frame-shadow);
|
||||
}
|
||||
@media(width>1280px) {
|
||||
width: 60%;
|
||||
}
|
||||
&[src*="youtube.com"]{
|
||||
aspect-ratio: 16/9;
|
||||
}
|
||||
}
|
||||
& video {
|
||||
display: block;
|
||||
margin: 30px auto;
|
||||
width: 80%;
|
||||
border-radius: 15px;
|
||||
box-shadow: 0px 6px 30px var(--frame-shadow);
|
||||
@media(width<480px) {
|
||||
width: 100%;
|
||||
}
|
||||
@media(width>1280px) {
|
||||
width: 60%;
|
||||
}
|
||||
}
|
||||
& math[display="block"] {
|
||||
margin: 1rem;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
30
src/lib/components/Markdown.ts
Normal file
30
src/lib/components/Markdown.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
export default Perser;
|
||||
|
||||
import { remark } from 'remark'
|
||||
import remarkgfm from 'remark-gfm'
|
||||
import remarkBreaks from "remark-breaks"
|
||||
import remarkmath from 'remark-math'
|
||||
import remarkRehype from 'remark-rehype'
|
||||
import rehypeslug from 'rehype-slug'
|
||||
import rehypeKatex from 'rehype-katex'
|
||||
import rehypeHighlight from 'rehype-highlight'
|
||||
import rehypeExternalLinks from 'rehype-external-links'
|
||||
import rehypeStringify from 'rehype-stringify'
|
||||
|
||||
|
||||
function Perser(mdtext: string): string {
|
||||
let md = remark()
|
||||
.use(remarkgfm) // Github Markdown
|
||||
.use(remarkBreaks) // 改行
|
||||
.use(remarkmath) // 数式
|
||||
.use(remarkRehype, {allowDangerousHtml: true})
|
||||
.use(rehypeslug) // headingにidを設定
|
||||
.use(rehypeKatex, {output:'mathml'}) // 数式
|
||||
.use(rehypeHighlight) // Syntax highlight
|
||||
.use(rehypeExternalLinks, {target:'_blank', rel:['noreferrer','noopener']}) // 外部サイトを新規タブで開く
|
||||
.use(rehypeStringify, {allowDangerousHtml: true})
|
||||
.processSync(mdtext)
|
||||
.toString()
|
||||
|
||||
return md
|
||||
}
|
120
src/lib/components/rainbow.css
Normal file
120
src/lib/components/rainbow.css
Normal file
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
|
||||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2006, Ivan Sagalaev.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Style with support for rainbow parens
|
||||
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
background: #474949;
|
||||
color: #d1d9e1;
|
||||
}
|
||||
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #969896;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-literal,
|
||||
.hljs-type {
|
||||
color: #cc99cc;
|
||||
}
|
||||
|
||||
.hljs-number,
|
||||
.hljs-selector-attr,
|
||||
.hljs-selector-pseudo {
|
||||
color: #f99157;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-doctag,
|
||||
.hljs-regexp {
|
||||
color: #8abeb7;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-name,
|
||||
.hljs-section,
|
||||
.hljs-built_in {
|
||||
color: #b5bd68;
|
||||
}
|
||||
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-selector-id,
|
||||
.hljs-title.class_,
|
||||
.hljs-class .hljs-title {
|
||||
color: #ffcc66;
|
||||
}
|
||||
|
||||
.hljs-section,
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-subst,
|
||||
.hljs-meta,
|
||||
.hljs-link {
|
||||
color: #f99157;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
color: #dc322f;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
color: #68dc2e
|
||||
}
|
||||
|
||||
.hljs-formula {
|
||||
background: #eee8d5;
|
||||
}
|
||||
|
||||
.hljs-attr,
|
||||
.hljs-attribute {
|
||||
color: #81a2be;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
26
src/lib/server/LoadPost.ts
Normal file
26
src/lib/server/LoadPost.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
export default getpost;
|
||||
|
||||
import { POST_DIR } from '$env/static/private';
|
||||
import Parser from './MetaParser';
|
||||
import fs from 'node:fs';
|
||||
|
||||
|
||||
async function getpost(id:string) {
|
||||
const md = fs.readFileSync(`${POST_DIR}/Posts/${id}.md`, 'utf8');
|
||||
|
||||
let fm_line = md.split('\n');
|
||||
|
||||
let line_no:number[] = []
|
||||
fm_line.forEach((i,n)=>{
|
||||
if(i=='---'){line_no.push(n)}
|
||||
})
|
||||
|
||||
let a = line_no[0]
|
||||
|
||||
let md_text = fm_line.slice(line_no[1]+1).join('\n');
|
||||
let fm_text = fm_line.slice(line_no[0]+1, line_no[1]).join('\n');
|
||||
|
||||
let metadata = Parser(fm_text);
|
||||
|
||||
return {metadata: metadata, post: md_text}
|
||||
}
|
34
src/lib/server/MetaParser.ts
Normal file
34
src/lib/server/MetaParser.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
export default parser;
|
||||
|
||||
import yaml from "yaml"
|
||||
import { parse } from '@twemoji/parser';
|
||||
import { error } from '@sveltejs/kit';
|
||||
|
||||
function parser(fm_text:string) {
|
||||
|
||||
let persed = yaml.parse(fm_text);
|
||||
|
||||
let fms = (fm:unknown) => {
|
||||
if (typeof fm === 'object' && fm !== null){
|
||||
let title = 'title' in fm && typeof fm.title === 'string' ? fm.title : ''
|
||||
let description = 'description' in fm && typeof fm.description === 'string'? fm.description : ''
|
||||
let thumbnail = 'thumbnail' in fm && typeof fm.thumbnail === 'string' ? fm.thumbnail : ''
|
||||
let emoji = 'emoji' in fm && typeof fm.emoji === 'string' ? fm.emoji : ''
|
||||
let date_str = 'date' in fm && typeof fm.date === 'string' ? fm.date : ''
|
||||
let category = 'category' in fm && typeof fm.category === 'string' ? fm.category : 'other'
|
||||
let tags = 'tags' in fm && Array.isArray(fm.tags) ? fm.tags : []
|
||||
let index = 'index' in fm && typeof fm.index === 'boolean' ? fm.index : true
|
||||
let published = 'published' in fm && typeof fm.published === 'boolean' ? fm.published : false
|
||||
|
||||
emoji = emoji? parse(emoji)[0].url:''
|
||||
|
||||
let date:Date = new Date(date_str)
|
||||
|
||||
return {title, description,thumbnail,emoji,date,category,tags,index,published}
|
||||
} else {
|
||||
error(500,{message:'Invalid frontmatter'})
|
||||
}
|
||||
}
|
||||
|
||||
return fms(persed)
|
||||
}
|
68
src/lib/server/Metadatas.ts
Normal file
68
src/lib/server/Metadatas.ts
Normal file
|
@ -0,0 +1,68 @@
|
|||
export default Metadatas;
|
||||
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import Posts from './PostList';
|
||||
import Load from './LoadPost';
|
||||
|
||||
import { dev } from '$app/environment';
|
||||
|
||||
async function Metadatas() {
|
||||
|
||||
const cache_dir = '/tmp/day.moris.blog/';
|
||||
const cache_file = `${cache_dir}metadata.json`;
|
||||
|
||||
async function build() {
|
||||
const posts = await Posts();
|
||||
|
||||
const metadataList = await Promise.all(posts.map(async (file)=>{
|
||||
const postId = path.basename(file, '.md')
|
||||
const metadata = (await Load(postId)).metadata
|
||||
return {postId, metadata}
|
||||
}))
|
||||
|
||||
const sorted = metadataList
|
||||
.sort((a,b)=>{
|
||||
return b.metadata.date.getTime() - a.metadata.date.getTime()
|
||||
})
|
||||
.filter((m)=> dev||m.metadata.published)
|
||||
|
||||
return sorted
|
||||
}
|
||||
|
||||
async function makeCache() {
|
||||
let data = await build()
|
||||
let cache_data = {
|
||||
cached_time: Date.now(),
|
||||
dev,
|
||||
data
|
||||
}
|
||||
|
||||
if (!fs.existsSync(cache_dir)) {
|
||||
fs.mkdirSync(cache_dir), {recursive: true}
|
||||
}
|
||||
|
||||
fs.writeFileSync(cache_file, JSON.stringify(cache_data, null, 2), 'utf8')
|
||||
return data
|
||||
}
|
||||
|
||||
|
||||
if (fs.existsSync(cache_file)) {
|
||||
const cache = JSON.parse(fs.readFileSync(cache_file, 'utf8'), (key,value)=>{
|
||||
if(key=='date'){
|
||||
return (new Date(value));
|
||||
}
|
||||
return value
|
||||
})
|
||||
|
||||
if (Boolean(cache.dev)!=dev || Date.now()-cache.cached_time>5*60000) {
|
||||
const data = await makeCache()
|
||||
return data
|
||||
} else {
|
||||
return cache.data
|
||||
}
|
||||
} else {
|
||||
const data = await makeCache()
|
||||
return data
|
||||
}
|
||||
}
|
15
src/lib/server/PostList.ts
Normal file
15
src/lib/server/PostList.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
export default postList;
|
||||
|
||||
import fs from 'node:fs';
|
||||
import Path from 'node:path';
|
||||
|
||||
import { POST_DIR } from '$env/static/private';
|
||||
|
||||
async function postList() {
|
||||
|
||||
const files = fs.readdirSync(`${POST_DIR}/Posts`);
|
||||
|
||||
const posts = files.filter((content)=> Path.extname(content)=='.md' && content!='README.md')
|
||||
|
||||
return posts
|
||||
}
|
121
src/routes/(DefaultStyle)/+layout.svelte
Normal file
121
src/routes/(DefaultStyle)/+layout.svelte
Normal file
|
@ -0,0 +1,121 @@
|
|||
<script lang="ts">
|
||||
import "../../app.css";
|
||||
import Header from "./header.svelte";
|
||||
import Footer from "./footer.svelte";
|
||||
import { onMount } from 'svelte';
|
||||
import { dev } from '$app/environment'
|
||||
|
||||
let { children } = $props();
|
||||
|
||||
let scrollObserver = $state(true);
|
||||
|
||||
onMount(()=>{
|
||||
let observer = new IntersectionObserver(
|
||||
(entries)=>{scrollObserver = entries[0].isIntersecting},
|
||||
{rootMargin: "25px",threshold: 0}
|
||||
);
|
||||
observer.observe(document.getElementById('scroll')!)
|
||||
});
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<meta name="theme-color" content="#a1cc66" media="(prefers-color-scheme: light)">
|
||||
<meta name="theme-color" content="teal" media="(prefers-color-scheme: dark)">
|
||||
</svelte:head>
|
||||
|
||||
<div id="root">
|
||||
<div id="scroll"></div>
|
||||
{#if dev}
|
||||
<div id='devTicker'>DEV DUILD</div>
|
||||
{/if}
|
||||
|
||||
<div class="headerContainer">
|
||||
<header class:hide={!scrollObserver}>
|
||||
<Header />
|
||||
</header>
|
||||
</div>
|
||||
|
||||
<div class="mainContainer">
|
||||
<main>
|
||||
{@render children()}
|
||||
</main>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
|
||||
<div class="u320"></div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
#root {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: var(--back-color);
|
||||
transition: background-color 1s;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
#devTicker {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
padding: 6px;
|
||||
color: yellow;
|
||||
background-color: #0008;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.headerContainer {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
height: 80px;
|
||||
z-index: 1;
|
||||
@media(width<1000px) {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
& header {
|
||||
background-color: var(--theme-color);
|
||||
height: 100%;
|
||||
transition: height .4s, transform .4s, background-color 1s;
|
||||
&.hide {
|
||||
height: 40px;
|
||||
@media(width<1000px) {
|
||||
transform: translate(0px,-50px);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mainContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
main {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
@media(width<320px) {
|
||||
.u320 {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 2;
|
||||
background: no-repeat center/25% url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAgCAAAAADC94zaAAAAiklEQVQoz62RQQ7EMAgDxxH/f3LdQ9MmNGQPq3JBwsLYRkYUZQIZv+dCFgUAQgFIKxcEoJXN0NhVG8SpD8Sd0g/1s2OlPu107cNDmz2kOGIyoeQ5Xv5KRBmN5BtUKOjaFtXrtbhEbbI+XCUqXEet/Rfitp+u6/4pHEpS/eedb5GdABwbTPzMQDVyAtNNK05J5lfeAAAAAElFTkSuQmCC);
|
||||
background-color: white;
|
||||
image-rendering: pixelated;
|
||||
color: black;
|
||||
&::after {
|
||||
content: 'This site supports screen sizes larger than 320px';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (scripting: none) {
|
||||
.headerContainer{height:40px !important;}
|
||||
}
|
||||
</style>
|
11
src/routes/(DefaultStyle)/+page.svelte
Normal file
11
src/routes/(DefaultStyle)/+page.svelte
Normal file
|
@ -0,0 +1,11 @@
|
|||
<script lang="ts">
|
||||
import { goto } from "$app/navigation";
|
||||
import { onMount } from "svelte";
|
||||
import { base } from '$app/paths'
|
||||
|
||||
onMount(() => {
|
||||
goto(`${base}/0/`)
|
||||
})
|
||||
</script>
|
||||
|
||||
To show posts, click <a href="/blog/0">here</a>
|
11
src/routes/(DefaultStyle)/[slug]/+page.server.ts
Normal file
11
src/routes/(DefaultStyle)/[slug]/+page.server.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
import Metas from '$lib/server/Metadatas';
|
||||
|
||||
export async function load({params}){
|
||||
const pageNo = Number(params.slug)
|
||||
const postList = await Metas()
|
||||
|
||||
const posts = postList.slice(pageNo*12, (pageNo+1)*12);
|
||||
const lastPage = Math.ceil(postList.length/12)-1;
|
||||
|
||||
return {posts, pageNo, lastPage}
|
||||
}
|
74
src/routes/(DefaultStyle)/[slug]/+page.svelte
Normal file
74
src/routes/(DefaultStyle)/[slug]/+page.svelte
Normal file
|
@ -0,0 +1,74 @@
|
|||
<script lang="ts">
|
||||
const { data } = $props();
|
||||
import Postgrid from './grid.svelte'
|
||||
|
||||
import { base } from '$app/paths';
|
||||
import { PUBLIC_HOSTNAME } from '$env/static/public';
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>記事一覧 | moris.day Blog</title>
|
||||
<link rel="canonical" href="https://{PUBLIC_HOSTNAME}{base}/" />
|
||||
</svelte:head>
|
||||
|
||||
|
||||
<div class='contain'>
|
||||
<div class="posts">
|
||||
{#each data.posts as post}
|
||||
<div class="post" class:unpublished={!post.metadata.published}>
|
||||
<a style='text-decoration: none;' href="../post/{post.postId}" tabindex="0">
|
||||
<Postgrid id={post.postId} {...post.metadata}></Postgrid>
|
||||
</a>
|
||||
</div>
|
||||
{/each}
|
||||
{#if data.posts.length%4}
|
||||
{#each Array(4-data.posts.length%4) as i}
|
||||
<div class="blank"></div>
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class='paging'>
|
||||
<a href={data.pageNo==0? "":`../${Number(data.pageNo)-1}`} style:visibility={data.pageNo==0? 'hidden':''}><</a>
|
||||
<span>{data.pageNo}</span><span>/</span><span>{data.lastPage}</span>
|
||||
<a href={data.pageNo==data.lastPage? "":`../${Number(data.pageNo)+1}`} style:visibility={data.pageNo==data.lastPage? 'hidden':''}>></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<style>
|
||||
.contain {
|
||||
margin: 3vw;
|
||||
}
|
||||
|
||||
.posts {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
grid-template-rows: max-content;
|
||||
gap: 25px;
|
||||
justify-content: center;
|
||||
margin: 0 auto;
|
||||
max-width: 1599px;
|
||||
}
|
||||
.post {
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 0 6px #0001;
|
||||
|
||||
&.unpublished {
|
||||
border: solid red 3px;
|
||||
}
|
||||
}
|
||||
|
||||
.paging {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
column-gap: 8px;
|
||||
margin: 20px;
|
||||
font-size: 1.5em;
|
||||
font-weight: 550;
|
||||
& a {
|
||||
color: var(--theme-color);
|
||||
}
|
||||
}
|
||||
</style>
|
117
src/routes/(DefaultStyle)/[slug]/grid.svelte
Normal file
117
src/routes/(DefaultStyle)/[slug]/grid.svelte
Normal file
|
@ -0,0 +1,117 @@
|
|||
<script lang="ts">
|
||||
export let title: string;
|
||||
export let description: string;
|
||||
export let thumbnail: string;
|
||||
export let emoji: string;
|
||||
export let date: Date;
|
||||
export let category: string;
|
||||
export let id: string;
|
||||
|
||||
let twemoji = async (url: string)=>{
|
||||
let res = await (await fetch(url)).text()
|
||||
return res
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class='grid'>
|
||||
<div class='thumbnail'>
|
||||
{#if thumbnail }
|
||||
<img src="{thumbnail}" alt='thumbnail' style='view-transition-name: {id}'/>
|
||||
{:else if emoji}
|
||||
{#await twemoji(emoji)}
|
||||
<div></div>
|
||||
{:then emojisvg}
|
||||
<div class="emoji">
|
||||
{@html emojisvg}
|
||||
</div>
|
||||
{/await}
|
||||
<!-- <div class='emoji'><img class='svg' src="{emoji}" alt="thumbnail" style='view-transition-name: {id}'/></div> -->
|
||||
{:else}
|
||||
<img src='data:image/svg+xml,{encodeURIComponent('<svg fill="#aaa" version="1.1" viewBox="0 -960 96 96" xmlns="http://www.w3.org/2000/svg"><path d="m41-903q-0.8 0-1.4-0.6t-0.6-1.4v-14q0-0.8 0.6-1.4t1.4-0.6h14q0.8 0 1.4 0.6t0.6 1.4v14q0 0.8-0.6 1.4t-1.4 0.6zm0-2h14v-14h-14zm1-2h12l-3.8-5-3 4-2.25-3zm-1 2v-14z"/></svg>')}' alt="fallback"/>
|
||||
{/if}
|
||||
|
||||
<div class="tag date">{date.toLocaleDateString('sv-SE')}</div>
|
||||
<div class="tag category">{category}</div>
|
||||
</div>
|
||||
<div class='label'>
|
||||
<div class='title'>{title}</div>
|
||||
<div class='description'>{description}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.grid {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
background-color: var(--grid-color);
|
||||
transition: background-color 1s;
|
||||
&:hover {
|
||||
img {
|
||||
transform: scale(1.03);
|
||||
}
|
||||
.title{
|
||||
text-decoration-line: underline;
|
||||
text-decoration-color: var(--font-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.thumbnail {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
aspect-ratio: 1/0.6;
|
||||
width: 100%;
|
||||
max-height: 200px;
|
||||
|
||||
& img {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
object-fit: contain;
|
||||
margin: 0 auto;
|
||||
transition: transform .3s ease-out;
|
||||
}
|
||||
& div.emoji {
|
||||
height: 70%;
|
||||
aspect-ratio: 1/1;
|
||||
}
|
||||
|
||||
& .tag{
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
padding:2px;
|
||||
color: var(--font-color);
|
||||
background-color: var(--back-color);
|
||||
border-radius: 3px;
|
||||
font-size: 0.85em;
|
||||
}
|
||||
& .date {
|
||||
right:5px;
|
||||
}
|
||||
& .category {
|
||||
left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.label {
|
||||
flex-grow: 1;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
color: var(--font-color);
|
||||
|
||||
& .title {
|
||||
font-size: 1.17em;
|
||||
font-weight: bold;
|
||||
margin: 4px 8px;
|
||||
}
|
||||
|
||||
& .description {
|
||||
margin:8px;
|
||||
font-size: .9em;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
</style>
|
10
src/routes/(DefaultStyle)/about/+page.server.ts
Normal file
10
src/routes/(DefaultStyle)/about/+page.server.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
import fs from 'node:fs';
|
||||
import Perser from '$lib/components/Markdown'
|
||||
|
||||
export async function load(){
|
||||
const profile_md = fs.readFileSync(`${process.cwd()}/src/routes/(DefaultStyle)/about/profile.md`, 'utf-8')
|
||||
|
||||
let persed = Perser(profile_md)
|
||||
|
||||
return {md: persed}
|
||||
}
|
26
src/routes/(DefaultStyle)/about/+page.svelte
Normal file
26
src/routes/(DefaultStyle)/about/+page.svelte
Normal file
|
@ -0,0 +1,26 @@
|
|||
<script lang="ts">
|
||||
const { data } = $props();
|
||||
|
||||
import '$lib/components/rainbow.css';
|
||||
import '$lib/components/Markdown.css';
|
||||
</script>
|
||||
|
||||
|
||||
<svelte:head>
|
||||
<title>About | moris.day Blog</title>
|
||||
</svelte:head>
|
||||
|
||||
<div id="profile">
|
||||
<article class='markdown'>
|
||||
{@html data.md}
|
||||
</article>
|
||||
</div>
|
||||
|
||||
|
||||
<style>
|
||||
#profile {
|
||||
margin: auto;
|
||||
padding: 24px;
|
||||
max-width: 720px;
|
||||
}
|
||||
</style>
|
9
src/routes/(DefaultStyle)/about/profile.md
Normal file
9
src/routes/(DefaultStyle)/about/profile.md
Normal file
|
@ -0,0 +1,9 @@
|
|||
## プロフィール
|
||||

|
||||
moris
|
||||
|
||||
|
||||
## ライセンス
|
||||
このブログのコンテンツは全てCC-BY-4.0の下で提供されます。
|
||||
|
||||
このブログのソースコードは[Gitea](https://git.moris.day/moris/moris-blog)で公開されており、MITライセンスの下で使用、改変、再頒布などを行うことができます。
|
17
src/routes/(DefaultStyle)/category/+page.server.ts
Normal file
17
src/routes/(DefaultStyle)/category/+page.server.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import Metadatas from "$lib/server/Metadatas";
|
||||
|
||||
export async function load() {
|
||||
let metalist = await Metadatas()
|
||||
|
||||
let cats: string[] = []
|
||||
|
||||
for (let meta of metalist){
|
||||
let cat = meta.metadata.category;
|
||||
|
||||
if (!cats.includes(cat)) {
|
||||
cats.push(cat)
|
||||
}
|
||||
}
|
||||
|
||||
return {cats}
|
||||
}
|
9
src/routes/(DefaultStyle)/category/+page.svelte
Normal file
9
src/routes/(DefaultStyle)/category/+page.svelte
Normal file
|
@ -0,0 +1,9 @@
|
|||
<script lang="ts">
|
||||
const { data } = $props();
|
||||
</script>
|
||||
|
||||
{#each data.cats as cat}
|
||||
<div>
|
||||
<a href="{cat}">{cat}</a>
|
||||
</div>
|
||||
{/each}
|
11
src/routes/(DefaultStyle)/category/[slug]/+page.server.ts
Normal file
11
src/routes/(DefaultStyle)/category/[slug]/+page.server.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
import Metadatas from "$lib/server/Metadatas";
|
||||
|
||||
export async function load({params}) {
|
||||
const cat = params.slug
|
||||
|
||||
const metalist = await Metadatas()
|
||||
|
||||
const result = metalist.filter((meta)=>meta.metadata.category == cat).map((meta)=>meta.postId)
|
||||
|
||||
return {posts: result}
|
||||
}
|
8
src/routes/(DefaultStyle)/category/[slug]/+page.svelte
Normal file
8
src/routes/(DefaultStyle)/category/[slug]/+page.svelte
Normal file
|
@ -0,0 +1,8 @@
|
|||
<script lang="ts">
|
||||
import { base } from '$app/paths'
|
||||
const { data } = $props();
|
||||
</script>
|
||||
|
||||
{#each data.posts as post}
|
||||
<div><a href="{base}/post/{post}">{post}</a></div>
|
||||
{/each}
|
77
src/routes/(DefaultStyle)/footer.svelte
Normal file
77
src/routes/(DefaultStyle)/footer.svelte
Normal file
|
@ -0,0 +1,77 @@
|
|||
<script lang="ts">
|
||||
import { base } from '$app/paths'
|
||||
</script>
|
||||
|
||||
<footer>
|
||||
<div id="footercontents">
|
||||
<div id="ftitle">
|
||||
<svg class="title" version="1.1" viewBox="0 0 300 64" xmlns="http://www.w3.org/2000/svg" fill="white"><path d="m10 45.6v-26.3h3.8v6c1.2-2.56 2.3-4.3 3.34-5.3 2.57-2.4 5-1.5 6.2 0 1.24 1.64 1.17 3.7 1.17 5.65 0.723-2.5 2.13-4.6 4.1-6.26 1.2-0.92 3.72-1.66 5.56 0.54 0.8 0.96 1.2 2.86 1.2 5.72v20h-3.8v-17.9c0-2.8-0.137-3.7-0.7-4.26-1.26-1.27-2.9 0.6-3.5 1.46-0.92 1.24-1.86 3.3-2.8 6.2v14.6h-3.65v-18c0-2.3-0.225-3.7-0.68-4.1-2.2-2-4.5 1.84-6.4 6.85v15.2zm41.4 0.73c-3.7 0-6.7-1.3-9-3.9-2.24-2.6-3.4-5.95-3.4-10s1.1-7.31 3.4-9.9 5.2-3.9 9-3.9c3.7 0 6.7 1.3 9 3.9s3.4 5.9 3.4 9.9-1.1 7.3-3.4 10c-2.24 2.6-5.2 3.9-9 3.9zm0-3.65c2.3 0 4.2-0.9 5.53-2.73 1.4-1.8 2.1-4.32 2.1-7.5 0-3.2-0.685-5.7-2.1-7.5-1.37-1.8-3.2-2.73-5.53-2.73-2.33 0-4.2 0.9-5.6 2.73-1.37 1.8-2.1 4.3-2.1 7.5 0 3.2 0.69 5.7 2.1 7.5 1.37 1.8 3.2 2.7 5.6 2.7zm20 2.9v-26.3h4.35v5.74c2.44-4 5.8-6.5 10.5-6.5 1.6 0 3.15 0.243 4.7 0.73v9.5h-4.2v-6c-5.3-1-8.7 3.5-11 7.53v15.3zm34 0v-22.6h-7.24v-3.65h11.6v22.6h7.27v3.65zm-0.724-36c0-1 0.34-1.73 1-2.2s1.3-0.73 1.9-0.73c0.6 0 1.24 0.24 1.92 0.73 0.67 0.49 1 1.2 1 2.2 0 0.97-0.335 1.7-1 2.2-0.67 0.49-1.3 0.73-1.9 0.73-0.6 0-1.22-0.24-1.9-0.73-0.675-0.49-1-1.2-1-2.2zm22.4 34.4v-4.6c4.5 2.9 9.3 3.1 10.5 3.1 2.35 0 6.2-0.5 6.2-3.74-0.22-2.7-3.4-3.4-5.5-4.3l-3-1.2c-3.24-1.3-5.3-2.45-6.1-3.5-1.75-2.2-2.1-6.5 1.2-9.24 3.26-2.7 10.8-2.6 16-0.9v4c-2.9-1.04-5.6-1.55-8.1-1.55-0.5 0-5.9 0.078-5.9 3.4 0 1.5 0.81 2.4 5.7 4.2l2.94 1.1c2.7 1 4.6 2.1 5.7 3.2 2.3 2.4 2.44 7.1-0.98 10-3 2.5-10.4 3.34-18.6 0.07zm39.1 2.5c-1 0-1.94-0.38-2.7-1.13-0.75-0.75-1.12-1.65-1.1-2.7 0-1.1 0.37-2 1.12-2.7 0.76-0.75 1.66-1.13 2.7-1.13s1.92 0.376 2.66 1.13c0.763 0.737 1.14 1.64 1.14 2.7 0 1.05-0.373 1.95-1.12 2.7s-1.64 1.13-2.7 1.13zm35.5-7c-3.63 6-10.7 9.3-15.8 3.8-3.37-3.7-3.3-11.8-0.864-16.8 2.9-6.1 7.53-7.76 11.8-7.76 1.63 0.016 3.25 0.215 4.86 0.376v-11.7h4.37v38h-4.37zm0-5.2v-11.3c-1.54-0.41-3-0.61-4.3-0.61-4.67 0-9.37 3.6-9.4 11.6 0 7.36 4 7.9 4.8 7.9 2.5 0 6-2.6 8.9-7.65zm28.4 5.2c-3.5 5.8-8.4 6.6-9.9 6.6-0.7 0-8.5-0.253-8.5-11.5 0-2.65 0.58-9.68 6.36-13.8 3.55-2.6 7.93-2.14 12-1.72h4.37v18.6c0 3.17 0.327 5.74 1 7.7h-4.53c-0.343-1.44-0.615-3.4-0.82-5.9zm0-5.2v-11.3c-5.57-1.5-8.75-0.11-11 2.5-1.8 2.1-2.66 4.9-2.66 8.5 0 7.36 4 7.9 4.8 7.9 2.5 0 6-2.6 8.9-7.65zm21.2 10-12-25.2h4.8l9.6 19.7 8-19.7h4.4l-10.1 24.4c-2.14 5.16-4.16 8.6-6.1 10.3-4 3.53-9.8 2.46-11 2.2v-3.86c1.62 0.5 4.53 1 7.17-0.26 2.8-1.6 4.16-4.7 5.3-7.55z"/><line class="underline" x1="268" y1="50" x2="290" y2="50" stroke="white" stroke-width="3"/><style>.underline {animation: 1.5s step-end infinite underline;}@keyframes underline {0% {visibility: visible;}50% {visibility: hidden;}}</style></svg>
|
||||
</div>
|
||||
<div id='footlink'>
|
||||
<dl>
|
||||
<dt>Site Map</dt>
|
||||
<dd><a href="https://moris.day">Top Page</a></dd>
|
||||
<dd><a href="{base}/about">About me</a></dd>
|
||||
<dd><a href="{base}/post">Blog</a></dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>Links</dt>
|
||||
<dd><a target="_blank" href="https://mi.moris.day/@moris">Misskey</a></dd>
|
||||
<dd><a target="_blank" href="https://mi.moris.day/@moris">Gitea</a></dd>
|
||||
<dd><a target="_blank" href="https://github.com/cocoyayann">Github</a></dd>
|
||||
<dd><a target="_blank" href="https://twitter.com/cocoyayan">Twitter</a></dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin:8px auto;width:fit-content;font-size:0.8em;">
|
||||
Copyright 2024 moris.
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<style>
|
||||
footer {
|
||||
font-family: "Source Code Pro", "Monaco", "Consolas", monospace;
|
||||
height: fit-content;
|
||||
background-color: var(--theme-color);
|
||||
transition: background-color 1s;
|
||||
color: white;
|
||||
|
||||
& a {
|
||||
color: white;
|
||||
}
|
||||
& dd {
|
||||
margin: 12px 0 0 24px;
|
||||
}
|
||||
& dt {
|
||||
font-size: 1.25em;
|
||||
}
|
||||
|
||||
& #footercontents {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
height: 85%;
|
||||
margin: 25px;
|
||||
@media(width < 720px) {
|
||||
flex-direction: column;
|
||||
row-gap: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
& #ftitle {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
& .title {
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
& #footlink {
|
||||
width:80%;
|
||||
max-width: 600px;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
27
src/routes/(DefaultStyle)/header.svelte
Normal file
27
src/routes/(DefaultStyle)/header.svelte
Normal file
|
@ -0,0 +1,27 @@
|
|||
<script lang="ts">
|
||||
import { base } from '$app/paths'
|
||||
</script>
|
||||
|
||||
<div class="title">
|
||||
<a href="{base}/0" aria-label="blog home">
|
||||
<svg version="1.1" viewBox="0 0 256 64" xmlns="http://www.w3.org/2000/svg"><path fill="white" d="m0 45.6v-26.3h3.8v6c1.2-2.56 2.3-4.3 3.34-5.3 2.57-2.4 5-1.5 6.2 0 1.24 1.64 1.17 3.7 1.17 5.65 0.723-2.5 2.13-4.6 4.1-6.26 1.2-0.92 3.72-1.66 5.56 0.54 0.8 0.96 1.2 2.86 1.2 5.72v20h-3.8v-17.9c0-2.8-0.137-3.7-0.7-4.26-1.26-1.27-2.9 0.6-3.5 1.46-0.92 1.24-1.86 3.3-2.8 6.2v14.6h-3.65v-18c0-2.3-0.225-3.7-0.68-4.1-2.2-2-4.5 1.84-6.4 6.85v15.2zm41.4 0.73c-3.7 0-6.7-1.3-9-3.9-2.24-2.6-3.4-5.95-3.4-10s1.1-7.31 3.4-9.9 5.2-3.9 9-3.9c3.7 0 6.7 1.3 9 3.9s3.4 5.9 3.4 9.9-1.1 7.3-3.4 10c-2.24 2.6-5.2 3.9-9 3.9zm0-3.65c2.3 0 4.2-0.9 5.53-2.73 1.4-1.8 2.1-4.32 2.1-7.5 0-3.2-0.685-5.7-2.1-7.5-1.37-1.8-3.2-2.73-5.53-2.73-2.33 0-4.2 0.9-5.6 2.73-1.37 1.8-2.1 4.3-2.1 7.5 0 3.2 0.69 5.7 2.1 7.5 1.37 1.8 3.2 2.7 5.6 2.7zm20 2.9v-26.3h4.35v5.74c2.44-4 5.8-6.5 10.5-6.5 1.6 0 3.15 0.243 4.7 0.73v9.5h-4.2v-6c-5.3-1-8.7 3.5-11 7.53v15.3zm34 0v-22.6h-7.24v-3.65h11.6v22.6h7.27v3.65zm-0.724-36c0-1 0.34-1.73 1-2.2s1.3-0.73 1.9-0.73c0.6 0 1.24 0.24 1.92 0.73 0.67 0.49 1 1.2 1 2.2 0 0.97-0.335 1.7-1 2.2-0.67 0.49-1.3 0.73-1.9 0.73-0.6 0-1.22-0.24-1.9-0.73-0.675-0.49-1-1.2-1-2.2zm22.4 34.4v-4.6c4.5 2.9 9.3 3.1 10.5 3.1 2.35 0 6.2-0.5 6.2-3.74-0.22-2.7-3.4-3.4-5.5-4.3l-3-1.2c-3.24-1.3-5.3-2.45-6.1-3.5-1.75-2.2-2.1-6.5 1.2-9.24 3.26-2.7 10.8-2.6 16-0.9v4c-2.9-1.04-5.6-1.55-8.1-1.55-0.5 0-5.9 0.078-5.9 3.4 0 1.5 0.81 2.4 5.7 4.2l2.94 1.1c2.7 1 4.6 2.1 5.7 3.2 2.3 2.4 2.44 7.1-0.98 10-3 2.5-10.4 3.34-18.6 0.07zm39.1 2.5c-1 0-1.94-0.38-2.7-1.13-0.75-0.75-1.12-1.65-1.1-2.7 0-1.1 0.37-2 1.12-2.7 0.76-0.75 1.66-1.13 2.7-1.13s1.92 0.376 2.66 1.13c0.763 0.737 1.14 1.64 1.14 2.7 0 1.05-0.373 1.95-1.12 2.7s-1.64 1.13-2.7 1.13zm35.5-7c-3.63 6-10.7 9.3-15.8 3.8-3.37-3.7-3.3-11.8-0.864-16.8 2.9-6.1 7.53-7.76 11.8-7.76 1.63 0.016 3.25 0.215 4.86 0.376v-11.7h4.37v38h-4.37zm0-5.2v-11.3c-1.54-0.41-3-0.61-4.3-0.61-4.67 0-9.37 3.6-9.4 11.6 0 7.36 4 7.9 4.8 7.9 2.5 0 6-2.6 8.9-7.65zm28.4 5.2c-3.5 5.8-8.4 6.6-9.9 6.6-0.7 0-8.5-0.253-8.5-11.5 0-2.65 0.58-9.68 6.36-13.8 3.55-2.6 7.93-2.14 12-1.72h4.37v18.6c0 3.17 0.327 5.74 1 7.7h-4.53c-0.343-1.44-0.615-3.4-0.82-5.9zm0-5.2v-11.3c-5.57-1.5-8.75-0.11-11 2.5-1.8 2.1-2.66 4.9-2.66 8.5 0 7.36 4 7.9 4.8 7.9 2.5 0 6-2.6 8.9-7.65zm21.2 10-12-25.2h4.8l9.6 19.7 8-19.7h4.4l-10.1 24.4c-2.14 5.16-4.16 8.6-6.1 10.3-4 3.53-9.8 2.46-11 2.2v-3.86c1.62 0.5 4.53 1 7.17-0.26 2.8-1.6 4.16-4.7 5.3-7.55z"/></svg>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
||||
<style>
|
||||
.title {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
a {
|
||||
display: block;
|
||||
height: 75%;
|
||||
}
|
||||
svg {
|
||||
height: 100%
|
||||
}
|
||||
}
|
||||
</style>
|
9
src/routes/(DefaultStyle)/post/+page.server.ts
Normal file
9
src/routes/(DefaultStyle)/post/+page.server.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
import Metas from '$lib/server/Metadatas';
|
||||
|
||||
export async function load(){
|
||||
const postList = await Metas()
|
||||
|
||||
let id = postList[0].postId
|
||||
|
||||
return {id}
|
||||
}
|
15
src/routes/(DefaultStyle)/post/+page.svelte
Normal file
15
src/routes/(DefaultStyle)/post/+page.svelte
Normal file
|
@ -0,0 +1,15 @@
|
|||
<script lang="ts">
|
||||
const { data } = $props();
|
||||
|
||||
import { goto } from "$app/navigation";
|
||||
import { onMount } from "svelte";
|
||||
import { base } from '$app/paths'
|
||||
|
||||
onMount(() => {
|
||||
goto(`${base}/post/${data.id}`)
|
||||
})
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<meta http-equiv="refresh" content="0; URL={data.id}" />
|
||||
</svelte:head>
|
28
src/routes/(DefaultStyle)/post/[slug]/+page.server.ts
Normal file
28
src/routes/(DefaultStyle)/post/[slug]/+page.server.ts
Normal file
|
@ -0,0 +1,28 @@
|
|||
import Post from '$lib/server/LoadPost';
|
||||
import { remark } from 'remark'
|
||||
import Perser from '$lib/components/Markdown'
|
||||
import GithubSlugger from 'github-slugger';
|
||||
|
||||
export async function load({params}) {
|
||||
|
||||
const md = await Post(params.slug);
|
||||
|
||||
let persed = Perser(md.post)
|
||||
|
||||
let mdast = remark().parse(md.post)
|
||||
let headers = mdast.children.filter((i) => i.type=='heading').map((i)=>{
|
||||
let title = i.children[0].value
|
||||
return {"depth": i.depth, "title": title}
|
||||
})
|
||||
|
||||
const slugs = new GithubSlugger()
|
||||
|
||||
let slugged = headers.map((x)=>x.depth ?slugs.slug(x.title):'').filter((x)=>x!='')
|
||||
|
||||
return {
|
||||
id: params.slug,
|
||||
metadata: md.metadata,
|
||||
post: persed,
|
||||
heading: slugged,
|
||||
}
|
||||
}
|
311
src/routes/(DefaultStyle)/post/[slug]/+page.svelte
Normal file
311
src/routes/(DefaultStyle)/post/[slug]/+page.svelte
Normal file
|
@ -0,0 +1,311 @@
|
|||
<script lang="ts">
|
||||
const { data } = $props();
|
||||
|
||||
import Toc from './toc.svelte'
|
||||
import Share from './share.svelte'
|
||||
import Profile from './profile.svelte'
|
||||
import { base } from '$app/paths';
|
||||
import { PUBLIC_HOSTNAME, PUBLIC_POST_REPO } from '$env/static/public';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
import '$lib/components/rainbow.css';
|
||||
import '$lib/components/Markdown.css';
|
||||
|
||||
const baseURL = `https://${PUBLIC_HOSTNAME}${base}`
|
||||
|
||||
onMount(()=>{
|
||||
let toggleHide = function(e:MessageEvent){
|
||||
if (e.data.message === 'toggleHide') {
|
||||
let iframes = document.querySelectorAll('.markdown iframe')
|
||||
|
||||
for ( let i = 0; i < iframes.length; i++ ){
|
||||
let frame = iframes[i]
|
||||
|
||||
if (frame instanceof HTMLIFrameElement && new URL(frame.src).origin === window.origin && frame.contentWindow?.name == e.data.id){
|
||||
iframes[i].classList.toggle('hide')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
window.addEventListener('message', toggleHide)
|
||||
|
||||
|
||||
document.getElementById('blog')?.addEventListener('click',(e:MouseEvent)=>{
|
||||
if (e.target instanceof HTMLElement && e.target.matches('pre')) {
|
||||
let code = e.target.textContent || '';
|
||||
navigator.clipboard.writeText(code)
|
||||
}
|
||||
})
|
||||
|
||||
// リスナ解除
|
||||
return ()=>{window.removeEventListener('message', toggleHide)}
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
<svelte:head>
|
||||
<title>{data.metadata.title} | moris.day Blog</title>
|
||||
|
||||
<meta property="og:type" content="article">
|
||||
<meta property="og:title" content="{data.metadata.title}">
|
||||
<meta property="og:url" content="{baseURL}/post/{data.id}">
|
||||
<meta property="og:description" content="{data.metadata.description}">
|
||||
{#if data.metadata.thumbnail}
|
||||
<meta property="og:image" content="{data.metadata.thumbnail}">
|
||||
{/if}
|
||||
|
||||
{#if !data.metadata.index}
|
||||
<meta name="robots" content="noindex">
|
||||
{/if}
|
||||
</svelte:head>
|
||||
|
||||
|
||||
<div id='blog'>
|
||||
<article>
|
||||
<h1 class="title">{data.metadata.title}</h1>
|
||||
|
||||
<div class="meta">
|
||||
<div class="category">
|
||||
<span class="txt">Category:</span>
|
||||
<a class="tag" href='/blog/category/{data.metadata.category}'>{data.metadata.category}</a>
|
||||
</div>
|
||||
|
||||
{#if data.metadata.tags.length }
|
||||
<div class="divider"></div>
|
||||
|
||||
<div class="tags">
|
||||
<span class="txt">Tags:</span>
|
||||
{#each data.metadata.tags as tag}
|
||||
<a class='tag' href='/blog/tag/{tag}'>{tag}</a>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="date">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M480-120q-138 0-240.5-91.5T122-440h82q14 104 92.5 172T480-200q117 0 198.5-81.5T760-480q0-117-81.5-198.5T480-760q-69 0-129 32t-101 88h110v80H120v-240h80v94q51-64 124.5-99T480-840q75 0 140.5 28.5t114 77q48.5 48.5 77 114T840-480q0 75-28.5 140.5t-77 114q-48.5 48.5-114 77T480-120Zm112-192L440-464v-216h80v184l128 128-56 56Z"/></svg>
|
||||
<span>{data.metadata.date.toLocaleDateString('sv-SE')}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if data.metadata.thumbnail}
|
||||
<img class="thumbnail" alt="thumbnail" src="{data.metadata.thumbnail}" style='view-transition-name: {data.id}'>
|
||||
{:else if data.metadata.emoji}
|
||||
<div class='thumbnail emoji'><img class="emoji" alt="thumbnail" src="{data.metadata.emoji}" style='view-transition-name: {data.id}'></div>
|
||||
{/if}
|
||||
|
||||
<div class='markdown'>
|
||||
{@html data.post}
|
||||
</div>
|
||||
|
||||
<div class="data">
|
||||
{#if PUBLIC_POST_REPO}
|
||||
<div><a target="_blank" href="{PUBLIC_POST_REPO}/commits/branch/main/Posts/{data.id}.md">History</a></div>
|
||||
<div class="spacer"></div>
|
||||
{/if}
|
||||
<div><a target="_blank" href="raw.md">Raw file</a></div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<aside>
|
||||
<div id='side'>
|
||||
<div>
|
||||
<Profile></Profile>
|
||||
</div>
|
||||
<div>
|
||||
<Share share={{url:`${baseURL}/post/${data.id}`, title:data.metadata.title}} />
|
||||
</div>
|
||||
{#if data.heading.length!=0}
|
||||
<div id='toc'>
|
||||
<Toc toclist={data.heading}></Toc>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="mi-posts js">
|
||||
<!-- <iframe src="https://mi.moris.day/embed/user-timeline/9w7bhjzt2b5z0001?maxHeight=320&rounded=false&border=false" title="moris's posts" loading="lazy" style="border:none; width:100%; height:100%;"></iframe> -->
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
|
||||
|
||||
<style>
|
||||
#blog {
|
||||
display: flex;
|
||||
margin: 25px 2.5%;
|
||||
gap: 20px;
|
||||
}
|
||||
aside {
|
||||
min-width: 280px;
|
||||
max-width: 320px;
|
||||
|
||||
@media (width<1000px) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
& #side {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
row-gap: 20px;
|
||||
position: sticky;
|
||||
top: 70px;
|
||||
}
|
||||
& #side>* {
|
||||
background-color: var(--grid-color);
|
||||
transition: background-color 1s;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 0 6px #1111;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
& .mi-posts {
|
||||
height: 320px;
|
||||
@media(prefers-color-scheme: dark) {
|
||||
border: solid #444 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
article {
|
||||
min-width: 0;
|
||||
max-width: 60rem;
|
||||
margin: 0 auto;
|
||||
flex-grow: 1;
|
||||
padding: 0 20px;
|
||||
border-radius: 8px;
|
||||
@media(width<480px){
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
& .title {
|
||||
font-size: 2em;
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
padding: 5px;
|
||||
border-bottom: 1px solid;
|
||||
@media(width<480px) {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
}
|
||||
& .thumbnail {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
max-height: 50vh;
|
||||
}
|
||||
& img.thumbnail {
|
||||
height: 35vh;
|
||||
max-width: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
& .emoji.thumbnail {
|
||||
width: 30%;
|
||||
max-width: 30vh;
|
||||
aspect-ratio: 1;
|
||||
@media(width<480px) {
|
||||
width: 50%;
|
||||
}
|
||||
& img {
|
||||
margin: 15%;
|
||||
}
|
||||
}
|
||||
& .markdown {
|
||||
margin: 25px 0;
|
||||
@media (width<480px) {
|
||||
margin: 8px;
|
||||
}
|
||||
}
|
||||
& .data {
|
||||
display: flex;
|
||||
padding: 8px;
|
||||
border-top: solid 1px;
|
||||
font-weight: 200;
|
||||
font-size: 1.2em;
|
||||
& .spacer {
|
||||
width: 1px;
|
||||
background-color: var(--font-color);
|
||||
box-sizing: border-box;
|
||||
margin: 2px 6px;
|
||||
}
|
||||
& a {
|
||||
margin: 4px;
|
||||
color: var(--font-color);
|
||||
text-decoration-thickness: 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.meta {
|
||||
display: grid;
|
||||
grid-template-rows: auto auto;
|
||||
grid-template-columns: auto auto 1fr auto;
|
||||
gap: 8px;
|
||||
font-size: 0.95em;
|
||||
margin: 8px;
|
||||
white-space: nowrap;
|
||||
|
||||
@media(width<1000px) {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
& .category {
|
||||
grid-row: 1;
|
||||
grid-column: 1;
|
||||
}
|
||||
|
||||
& .tags {
|
||||
grid-row: 1;
|
||||
grid-column: 3;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
@media(width<1000px) {
|
||||
grid-row: 2;
|
||||
grid-column: 1 / 5;
|
||||
}
|
||||
@media(width<480px){
|
||||
display: inline-block;
|
||||
grid-row: 1;
|
||||
grid-column: 3;
|
||||
}
|
||||
}
|
||||
|
||||
& .tag {
|
||||
display: inline-block;
|
||||
background-color: var(--theme-color);
|
||||
color: var(--font-color);
|
||||
border-radius: 3px;
|
||||
padding: 0 4px 1px 4px;
|
||||
margin: 3px;
|
||||
}
|
||||
|
||||
& .divider {
|
||||
display: inline-block;
|
||||
width: 1px;
|
||||
margin: 3px 0;
|
||||
background-color: var(--font-color);
|
||||
grid-row: 1;
|
||||
grid-column: 2;
|
||||
@media(480px<width<1000px){
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
& .date{
|
||||
display: flex;
|
||||
grid-row: 1;
|
||||
grid-column: 4;
|
||||
vertical-align: middle;
|
||||
align-items: center;
|
||||
@media(width<480px){
|
||||
display: inline-block;
|
||||
grid-row: 2;
|
||||
grid-column: 1 / 5;
|
||||
}
|
||||
}
|
||||
& .date svg{
|
||||
height: 1rem;
|
||||
fill: var(--font-color);
|
||||
vertical-align: middle;
|
||||
}
|
||||
@media(width<480px) {
|
||||
& .txt {display: none;}
|
||||
}
|
||||
}
|
||||
</style>
|
49
src/routes/(DefaultStyle)/post/[slug]/profile.svelte
Normal file
49
src/routes/(DefaultStyle)/post/[slug]/profile.svelte
Normal file
|
@ -0,0 +1,49 @@
|
|||
<div class="profile" aria-label="プロフィール">
|
||||
<div>
|
||||
<div class="space topspace"></div>
|
||||
<div class="icon">
|
||||
<img src="https://moris.day/files/assets/moris_icon_200px.avif" width="200" height="200" alt="moris icon">
|
||||
</div>
|
||||
<div class="space bottomspace"></div>
|
||||
<div style="position:relative; text-align:center; font-family:monospace;font-size:1.2em; font-weight:350; width:fit-content; margin:auto;"><span>moris</span><img src="https://cdn.jsdelivr.net/gh/jdecked/twemoji@latest/assets/svg/1f9ea.svg" alt="test tube" style="position:absolute; left:100%; aspect-ratio:1; height:100%; padding:3%; box-sizing:border-box;"></div>
|
||||
</div>
|
||||
|
||||
<div class="discription">
|
||||
<span>有機化学好きの大学生<br>電子工作やプログラムもいじります<br>誤字 文句 その他連絡→<a href="https://mi.moris.day/@moris" target="_blank">Misskey(Fediverse)</a></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.profile {
|
||||
position: relative;
|
||||
}
|
||||
.topspace {
|
||||
height: 55px;
|
||||
background-color: color-mix(in srgb, var(--theme-color) 25%, var(--back-color));
|
||||
}
|
||||
.bottomspace {
|
||||
height: 38px;
|
||||
}
|
||||
.icon {
|
||||
position: absolute;
|
||||
padding: 4px;
|
||||
border-radius: 50%;
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
top: 14px; /*calc(55px - 35px - 6px);*/
|
||||
left: calc(50% - 41px); /*calc(50% - 35px - 6px);*/
|
||||
background-color: var(--grid-color);
|
||||
|
||||
& img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
.discription {
|
||||
padding: 8px;
|
||||
font-size: 0.9em;
|
||||
text-align: center;
|
||||
line-height: 1.8;
|
||||
}
|
||||
</style>
|
9
src/routes/(DefaultStyle)/post/[slug]/raw.md/+server.ts
Normal file
9
src/routes/(DefaultStyle)/post/[slug]/raw.md/+server.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
export const prerender = true
|
||||
|
||||
import fs from 'node:fs';
|
||||
import { POST_DIR } from '$env/static/private';
|
||||
|
||||
export async function GET({params}) {
|
||||
const raw = fs.readFileSync(`${POST_DIR}/Posts/${params.slug}.md`,{encoding:'utf-8'})
|
||||
return new Response(raw);
|
||||
};
|
92
src/routes/(DefaultStyle)/post/[slug]/share.svelte
Normal file
92
src/routes/(DefaultStyle)/post/[slug]/share.svelte
Normal file
|
@ -0,0 +1,92 @@
|
|||
<script lang="ts">
|
||||
type shareobj = {
|
||||
url: string,
|
||||
title: string
|
||||
}
|
||||
|
||||
export let share: shareobj;
|
||||
|
||||
import { base } from '$app/paths'
|
||||
|
||||
let copyed = false;
|
||||
|
||||
function copylink() {
|
||||
navigator.clipboard.writeText(share.url);
|
||||
copyed = true;
|
||||
setTimeout(() => (copyed = false), 1000);
|
||||
}
|
||||
</script>
|
||||
|
||||
<div style="margin:4px 0 0 8px;color:#aaaa;font-size:0.85em">Share</div>
|
||||
<div id="share">
|
||||
<button class="link js" type="button" on:click={copylink} aria-label="urlをコピー" title="copy url">
|
||||
{#if copyed}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="m620-163-170-170 56-56 114 114 226-226 56 56zm220-397h-80v-200h-80v120h-400v-120h-80v560h240v80h-240c-44 0-80-35.6-80-80v-560c0-44 35.6-80 80-80h167c15-47.5 62.7-80 113-80 55.7 0 99.9 35 114 80h166c44 0 80 35.6 80 80zm-360-200c22.8 0 40-17.2 40-40 0-22.8-17.2-40-40-40-22.8 0-40 17.2-40 40 0 22.8 17.2 40 40 40z"/></svg>
|
||||
{:else}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="m200-120c-44 0-80-35.6-80-80v-560c0-44 35.6-80 80-80h167c15-47.5 62.7-80 113-80 55.7 0 100 35 114 80h166c44 0 80 35.6 80 80v560c0 44-35.6 80-80 80zm0-80h560v-560h-80v120h-400v-120h-80zm280-560c22.8 0 40-17.2 40-40 0-22.8-17.2-40-40-40-22.8 0-40 17.2-40 40 0 22.8 17.2 40 40 40z"/></svg>
|
||||
{/if}
|
||||
</button>
|
||||
<div class="misskey">
|
||||
<a href="https://misskey-hub.net/share?url={share.url}&text={share.title}+-+moris+Blog" target="_blank" aria-label="misskeyで共有">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 136 136"><path d="m16.5 20c-9 0-16.5 7.5-16.5 16.5v62c0 9 7.5 16.5 16.5 16.5 9 0 16.5-7.5 16.5-16.5v-12c0-3 2.6-2 4 0 2.4 4 7.4 7.6 13.3 7.5s10.9-3.5 13.3-7.5c1.4-2 4-3 4 0v12c0 9 7.5 16.5 16.5 16.5 9 0 16.5-9 16.5-16.5v-62c0-9-7.5-16.5-16.5-16.5-5 0-9.4 2-13 6l-16.5 19.5c-2.45 3.13-5.96 2.92-8.4 0l-16.5-19.5c-3.4-4-7.7-6-13-6zm105.5 0c-8 0-14 6-14 14 0 8 6 14 14 14 8 0 14-6 14-14 0-8-6-14-14-14m0 31c-8 0-14 6 -14 14v35c0 8 6 14 14 14 8 0 14-6 14-14v-35c0-8-6-14-14-14"/></svg>
|
||||
</a>
|
||||
</div>
|
||||
<div class="threads">
|
||||
<a href="https://www.threads.net/intent/post?text={share.title}+-+moris+Blog%0A{share.url}" target="_blank" aria-label="threadsで共有">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1100 1100"><path d="m558 1050c-229 0-444-129-446-499v-0.7c1.4-172 56-496 446-499h0.6c231 1.6 377 122 430 315l-85 23.7c-46-165-162-249-346-251-284 2.1-356 208-358 411 2.8 325 179 410 358 411 109-0.8 182-26 242-85 83.6-82 81-212-22.7-273-34.2 240-253 237-344 177-92-60-97-184-17.6-252 82-71 221-57 275-48-25-150-195-129-244-55l-73-49c93-138 393-152 409 130 196 83 203 303 80 432-82 88-172 112-304 112zm11-486c-173 9.7-151 171-6 163 51-2.7 117-22.6 129-155-41-3.7-82-10-123-8z"/></svg>
|
||||
</a>
|
||||
</div>
|
||||
<div class="twitter">
|
||||
<a href="https://twitter.com/share?url={share.url}&text={share.title}+-+moris+Blog%0A" target="_blank" aria-label="twitterで共有">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 248 248"><path d="M 222,73 C 222,205 87,257 1,201 28,204 54,196 76,180 54,180 35,166 29,145 37,147 44,146 52,144 28,139 11,118 11,94 18,98 26,100 34,100 12,85 5,56 18,33 44,65 81,84 122,86 111,38 172,2 208,40 219,38 230,34 240,28 236,40 228,50 218,56 227,56 238,52 247,48Z"/></svg>
|
||||
</a>
|
||||
</div>
|
||||
<div class="rss">
|
||||
<a href="{base}/feed.rss" target="_blank" aria-label="rss配信">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M200-120q-33 0-56.5-23.5T120-200q0-33 23.5-56.5T200-280q33 0 56.5 23.5T280-200q0 33-23.5 56.5T200-120Zm480 0q0-117-44-218.5T516-516q-76-76-177.5-120T120-680v-120q142 0 265 53t216 146q93 93 146 216t53 265H680Zm-240 0q0-67-25-124.5T346-346q-44-44-101.5-69T120-440v-120q92 0 171.5 34.5T431-431q60 60 94.5 139.5T560-120H440Z"/></svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
#share {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
height: 36px;
|
||||
padding: 5px;
|
||||
|
||||
& > * {
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
border-radius: 3px;
|
||||
&:hover {
|
||||
background-color: #0001;
|
||||
}
|
||||
}
|
||||
}
|
||||
button {
|
||||
all: unset;
|
||||
}
|
||||
svg {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
fill: #aaaa;
|
||||
transition: fill 0.2s;
|
||||
}
|
||||
|
||||
.link svg:hover {
|
||||
fill: hsl(0, 25%, 30%);
|
||||
}
|
||||
.misskey svg:hover {
|
||||
fill: hsl(75, 99%, 40%);
|
||||
}
|
||||
.threads svg:hover {
|
||||
fill: black;
|
||||
}
|
||||
.twitter svg:hover {
|
||||
fill: hsl(203, 100%, 65%);
|
||||
}
|
||||
.rss svg:hover {
|
||||
fill: orange;
|
||||
}
|
||||
</style>
|
46
src/routes/(DefaultStyle)/post/[slug]/toc.svelte
Normal file
46
src/routes/(DefaultStyle)/post/[slug]/toc.svelte
Normal file
|
@ -0,0 +1,46 @@
|
|||
<script lang="ts">
|
||||
export let toclist: string[];
|
||||
</script>
|
||||
|
||||
|
||||
<nav>
|
||||
<div style="margin:4px 0 0 8px;color:#aaaa;font-size:0.85em;">目次</div>
|
||||
<ul>
|
||||
{#each toclist as toc}
|
||||
<li><a href='#{toc}'>{toc}</a></li>
|
||||
{/each}
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
|
||||
<style>
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 5px;
|
||||
font-size: .9rem;
|
||||
max-height: 180px;
|
||||
overflow: auto;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: #aaa #444;
|
||||
}
|
||||
li {
|
||||
padding: 4px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
li:hover {
|
||||
background-color: #0002;
|
||||
}
|
||||
a {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
color: var(--font-color);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
&::before {
|
||||
content: '・';
|
||||
color: var(--font-color);
|
||||
}
|
||||
}
|
||||
</style>
|
17
src/routes/(DefaultStyle)/tag/+page.server.ts
Normal file
17
src/routes/(DefaultStyle)/tag/+page.server.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import Metadatas from "$lib/server/Metadatas";
|
||||
|
||||
export async function load() {
|
||||
let metalist = await Metadatas()
|
||||
|
||||
let tags: string[] = []
|
||||
|
||||
for (let meta of metalist){
|
||||
for (let tag of meta.metadata.tags) {
|
||||
if (!tags.includes(tag)) {
|
||||
tags.push(tag)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {tags}
|
||||
}
|
9
src/routes/(DefaultStyle)/tag/+page.svelte
Normal file
9
src/routes/(DefaultStyle)/tag/+page.svelte
Normal file
|
@ -0,0 +1,9 @@
|
|||
<script lang="ts">
|
||||
const { data } = $props();
|
||||
</script>
|
||||
|
||||
{#each data.tags as tag}
|
||||
<div>
|
||||
<a href="{tag}">{tag}</a>
|
||||
</div>
|
||||
{/each}
|
11
src/routes/(DefaultStyle)/tag/[slug]/+page.server.ts
Normal file
11
src/routes/(DefaultStyle)/tag/[slug]/+page.server.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
import Metadatas from "$lib/server/Metadatas";
|
||||
|
||||
export async function load({params}) {
|
||||
const tag = params.slug
|
||||
|
||||
const metalist = await Metadatas()
|
||||
|
||||
const result = metalist.filter((meta)=>meta.metadata.tags.includes(tag)).map((meta)=>meta.postId)
|
||||
|
||||
return {posts: result}
|
||||
}
|
8
src/routes/(DefaultStyle)/tag/[slug]/+page.svelte
Normal file
8
src/routes/(DefaultStyle)/tag/[slug]/+page.svelte
Normal file
|
@ -0,0 +1,8 @@
|
|||
<script lang="ts">
|
||||
import { base } from '$app/paths'
|
||||
const { data } = $props();
|
||||
</script>
|
||||
|
||||
{#each data.posts as post}
|
||||
<div><a href="{base}/post/{post}">{post}</a></div>
|
||||
{/each}
|
2
src/routes/+layout.ts
Normal file
2
src/routes/+layout.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
export const prerender = true;
|
||||
export const trailingSlash = 'always';
|
1
src/routes/code/+layout.ts
Normal file
1
src/routes/code/+layout.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export const csr = false
|
12
src/routes/code/+page.server.ts
Normal file
12
src/routes/code/+page.server.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { POST_DIR } from '$env/static/private';
|
||||
import Path from 'node:path';
|
||||
import fs from 'node:fs';
|
||||
|
||||
export async function load({}) {
|
||||
|
||||
const files = fs.readdirSync(`${POST_DIR}/Codes`);
|
||||
|
||||
const codes = files.filter((content)=> Path.extname(content)=='.html')
|
||||
|
||||
return {codes}
|
||||
}
|
10
src/routes/code/+page.svelte
Normal file
10
src/routes/code/+page.svelte
Normal file
|
@ -0,0 +1,10 @@
|
|||
<script lang="ts">
|
||||
const { data } = $props();
|
||||
import { base } from '$app/paths';
|
||||
</script>
|
||||
|
||||
<ul>
|
||||
{#each data.codes as code}
|
||||
<li><a href="{base}/code/{code}">{code}</a></li>
|
||||
{/each}
|
||||
</ul>
|
75
src/routes/code/[slug]/+layout.svelte
Normal file
75
src/routes/code/[slug]/+layout.svelte
Normal file
|
@ -0,0 +1,75 @@
|
|||
<script lang="ts">
|
||||
let { children } = $props();
|
||||
|
||||
import './app.css'
|
||||
|
||||
function toggleFullScreen() {
|
||||
if (document.fullscreenElement) {
|
||||
document.exitFullscreen();
|
||||
} else {
|
||||
document.querySelector("body")?.requestFullscreen();
|
||||
}
|
||||
}
|
||||
|
||||
function hideContent() {
|
||||
let uuid = crypto.randomUUID()
|
||||
window.name = uuid
|
||||
window.parent.postMessage({"id": uuid, 'message': 'toggleHide'}, '*');
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<meta name="robots" content="noindex">
|
||||
</svelte:head>
|
||||
|
||||
<div id='window'>
|
||||
<div class="menubar">
|
||||
<button style="background-color: rgb(255 95 87)" aria-label="reload" onclick={()=>{location.reload()}}></button>
|
||||
<button style="background-color: rgb(255 188 46)" aria-label="close" onclick={hideContent}></button>
|
||||
<button style="background-color: rgb(40 200 64)" aria-label="fullscreen" onclick={toggleFullScreen}></button>
|
||||
</div>
|
||||
<div class="code">
|
||||
{@render children()}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
#window {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
border: solid var(--border-color) 1px;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0px 8px 40px var(--shadow-color);
|
||||
background-color: var(--back-color);
|
||||
font-family: sans-serif;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.menubar {
|
||||
display: flex;
|
||||
height: 28px;
|
||||
padding: 0 4px;
|
||||
border-radius: 12px 12px 0 0;
|
||||
background-color: var(--head-color);
|
||||
border-bottom: solid var(--divider-color) 1px;
|
||||
|
||||
& >* {
|
||||
all: unset;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
margin: 8px 4px;
|
||||
border-radius: 50%;
|
||||
background-color: gray;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.code {
|
||||
height: calc(100% - 28px);
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
</style>
|
10
src/routes/code/[slug]/+page.server.ts
Normal file
10
src/routes/code/[slug]/+page.server.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
import { POST_DIR } from '$env/static/private';
|
||||
import fs from 'node:fs';
|
||||
|
||||
export async function load({params}) {
|
||||
const code = params.slug.replace(/\.html$/, "");
|
||||
|
||||
const html = fs.readFileSync(`${POST_DIR}/Codes/${code}.html`, 'utf-8');
|
||||
|
||||
return {html}
|
||||
}
|
5
src/routes/code/[slug]/+page.svelte
Normal file
5
src/routes/code/[slug]/+page.svelte
Normal file
|
@ -0,0 +1,5 @@
|
|||
<script lang="ts">
|
||||
const { data } = $props();
|
||||
</script>
|
||||
|
||||
<div>{@html data.html}</div>
|
35
src/routes/code/[slug]/app.css
Normal file
35
src/routes/code/[slug]/app.css
Normal file
|
@ -0,0 +1,35 @@
|
|||
:root {
|
||||
height: 100%;
|
||||
background-color: var(--white-black);
|
||||
|
||||
--back-color: white; /*rgb(240 238 245)*/
|
||||
--head-color: rgb(245, 245, 245); /*rgb(244 243 250)*/
|
||||
--divider-color: rgb(220 220 220);
|
||||
--border-color: #bbb;
|
||||
--shadow-color: #0009;
|
||||
--white-black: #fff;
|
||||
--font-color: #222;
|
||||
|
||||
@media(prefers-color-scheme: dark){
|
||||
--back-color: rgb(43 48 55);
|
||||
--head-color: rgb(58 60 66);
|
||||
--divider-color: #222;
|
||||
--border-color: #555;
|
||||
--shadow-color: #000;
|
||||
--white-black: #000;
|
||||
--font-color: #f5f5f5;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
background-color: var(--white-black);
|
||||
color: var(--font-color);
|
||||
}
|
||||
|
||||
body:fullscreen {
|
||||
padding: 10%;
|
||||
background-image: url(https://moris.day/files/img/BigSur.avif);
|
||||
background-size: cover;
|
||||
}
|
46
src/routes/feed.rss/+server.ts
Normal file
46
src/routes/feed.rss/+server.ts
Normal file
|
@ -0,0 +1,46 @@
|
|||
export const prerender = true
|
||||
|
||||
import path from 'node:path';
|
||||
|
||||
import Metadatas from '$lib/server/Metadatas';
|
||||
import { PUBLIC_HOSTNAME } from '$env/static/public';
|
||||
|
||||
/** @type {import('./$types').RequestHandler} */
|
||||
export async function GET() {
|
||||
|
||||
let items = ""
|
||||
let i = 0
|
||||
|
||||
const metalist = await Metadatas()
|
||||
|
||||
for (let post of metalist){
|
||||
|
||||
let meta = post.metadata
|
||||
let link = `https://${PUBLIC_HOSTNAME}/blog/post/${path.basename(post.postId, '.md')}`
|
||||
|
||||
i++
|
||||
items += `
|
||||
<item>
|
||||
<title>${meta.title}</title>
|
||||
<description>${meta.description}</description>
|
||||
<link>${link}</link>
|
||||
<pubDate>${meta.date.toUTCString()}</pubDate>
|
||||
<guid>${link}</guid>
|
||||
</item>`
|
||||
|
||||
if (i==15) {break}
|
||||
}
|
||||
|
||||
let rss = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0">
|
||||
<channel>
|
||||
<title>moris.day blog RSSfeed</title>
|
||||
<description>工作とか化学とかプログラミングとか</description>
|
||||
<link>https://moris.day/blog</link>
|
||||
<pubDate>${(new Date()).toUTCString()}</pubDate>
|
||||
${items}
|
||||
</channel>
|
||||
</rss>`
|
||||
|
||||
return new Response(rss);
|
||||
};
|
17
svelte.config.js
Normal file
17
svelte.config.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
import adapter from '@sveltejs/adapter-static';
|
||||
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
preprocess: vitePreprocess(),
|
||||
|
||||
kit: {
|
||||
adapter: adapter(),
|
||||
paths: {
|
||||
base: "/blog",
|
||||
relative: false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default config;
|
19
tsconfig.json
Normal file
19
tsconfig.json
Normal file
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"extends": "./.svelte-kit/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"checkJs": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"skipLibCheck": true,
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"moduleResolution": "bundler"
|
||||
}
|
||||
// Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
|
||||
// except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
|
||||
//
|
||||
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
|
||||
// from the referenced tsconfig.json - TypeScript does not merge them in
|
||||
}
|
9
vite.config.ts
Normal file
9
vite.config.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
import { sveltekit } from '@sveltejs/kit/vite';
|
||||
import { defineConfig } from 'vite';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [sveltekit()],
|
||||
server: {
|
||||
port: 5273
|
||||
}
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue