This commit is contained in:
monoid 2023-01-05 18:18:07 +09:00
commit b7da837654
2010 changed files with 17830 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
collected_docs.json
db.sqlite
.env

6
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,6 @@
{
"recommendations": [
"denoland.vscode-deno",
"sastan.twind-intellisense"
]
}

8
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,8 @@
{
"deno.enable": true,
"deno.lint": true,
"editor.defaultFormatter": "denoland.vscode-deno",
"[css]": {
"editor.defaultFormatter": "vscode.css-language-features"
}
}

26
README.md Normal file
View File

@ -0,0 +1,26 @@
# Simple FS server
### Feature
- [x] Simple file server
- [x] Serve static files
- [ ] Search files
- [ ] Preview files
- [ ] Plugin system
- [ ] Support for multiple languages
- [ ] Support for multiple themes
- [ ] Upload files
- [ ] Authentication
- [ ] Sort files
- [ ] Download files
- [ ] DESCRIPTION.md for index
### Usage
Start the project:
```
deno task start
```
This will watch the project directory and restart as necessary.

12
components/Button.tsx Normal file
View File

@ -0,0 +1,12 @@
import { JSX } from "preact";
import { IS_BROWSER } from "$fresh/runtime.ts";
export function Button(props: JSX.HTMLAttributes<HTMLButtonElement>) {
return (
<button
{...props}
disabled={!IS_BROWSER || props.disabled}
class="px-2 py-1 border(gray-100 2) hover:bg-gray-200"
/>
);
}

10
deno.json Normal file
View File

@ -0,0 +1,10 @@
{
"tasks": {
"start": "deno run -A --watch=static/,routes/ dev.ts"
},
"importMap": "./import_map.json",
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "preact"
}
}

348
deno.lock Normal file
View File

@ -0,0 +1,348 @@
{
"version": "2",
"remote": {
"https://cdn.jsdelivr.net/npm/@types/marked@latest/index.d.ts": "0b2fcecb260110d36514d4a845e10d98d19ae62f19ff18a5fc0181c31e1be8ef",
"https://cdn.jsdelivr.net/npm/marked@latest/lib/marked.esm.js": "154e8c60ec6efac64e967cd0a48d5dae2dd158eeb6e808bd83776cb8f7edac82",
"https://deno.land/std@0.140.0/_util/assert.ts": "e94f2eb37cebd7f199952e242c77654e43333c1ac4c5c700e929ea3aa5489f74",
"https://deno.land/std@0.140.0/_util/os.ts": "3b4c6e27febd119d36a416d7a97bd3b0251b77c88942c8f16ee5953ea13e2e49",
"https://deno.land/std@0.140.0/fs/_util.ts": "0fb24eb4bfebc2c194fb1afdb42b9c3dda12e368f43e8f2321f84fc77d42cb0f",
"https://deno.land/std@0.140.0/fs/ensure_dir.ts": "9dc109c27df4098b9fc12d949612ae5c9c7169507660dcf9ad90631833209d9d",
"https://deno.land/std@0.140.0/fs/expand_glob.ts": "0c10130d67c9b02164b03df8e43c6d6defbf8e395cb69d09e84a8586e6d72ac3",
"https://deno.land/std@0.140.0/fs/walk.ts": "117403ccd21fd322febe56ba06053b1ad5064c802170f19b1ea43214088fe95f",
"https://deno.land/std@0.140.0/path/_constants.ts": "df1db3ffa6dd6d1252cc9617e5d72165cd2483df90e93833e13580687b6083c3",
"https://deno.land/std@0.140.0/path/_interface.ts": "ee3b431a336b80cf445441109d089b70d87d5e248f4f90ff906820889ecf8d09",
"https://deno.land/std@0.140.0/path/_util.ts": "c1e9686d0164e29f7d880b2158971d805b6e0efc3110d0b3e24e4b8af2190d2b",
"https://deno.land/std@0.140.0/path/common.ts": "bee563630abd2d97f99d83c96c2fa0cca7cee103e8cb4e7699ec4d5db7bd2633",
"https://deno.land/std@0.140.0/path/glob.ts": "cb5255638de1048973c3e69e420c77dc04f75755524cb3b2e160fe9277d939ee",
"https://deno.land/std@0.140.0/path/mod.ts": "d3e68d0abb393fb0bf94a6d07c46ec31dc755b544b13144dee931d8d5f06a52d",
"https://deno.land/std@0.140.0/path/posix.ts": "293cdaec3ecccec0a9cc2b534302dfe308adb6f10861fa183275d6695faace44",
"https://deno.land/std@0.140.0/path/separator.ts": "fe1816cb765a8068afb3e8f13ad272351c85cbc739af56dacfc7d93d710fe0f9",
"https://deno.land/std@0.140.0/path/win32.ts": "31811536855e19ba37a999cd8d1b62078235548d67902ece4aa6b814596dd757",
"https://deno.land/std@0.150.0/_util/assert.ts": "e94f2eb37cebd7f199952e242c77654e43333c1ac4c5c700e929ea3aa5489f74",
"https://deno.land/std@0.150.0/_util/os.ts": "3b4c6e27febd119d36a416d7a97bd3b0251b77c88942c8f16ee5953ea13e2e49",
"https://deno.land/std@0.150.0/async/abortable.ts": "87aa7230be8360c24ad437212311c9e8d4328854baec27b4c7abb26e85515c06",
"https://deno.land/std@0.150.0/async/deadline.ts": "48ac998d7564969f3e6ec6b6f9bf0217ebd00239b1b2292feba61272d5dd58d0",
"https://deno.land/std@0.150.0/async/debounce.ts": "564273ef242bcfcda19a439132f940db8694173abffc159ea34f07d18fc42620",
"https://deno.land/std@0.150.0/async/deferred.ts": "bc18e28108252c9f67dfca2bbc4587c3cbf3aeb6e155f8c864ca8ecff992b98a",
"https://deno.land/std@0.150.0/async/delay.ts": "cbbdf1c87d1aed8edc7bae13592fb3e27e3106e0748f089c263390d4f49e5f6c",
"https://deno.land/std@0.150.0/async/mod.ts": "9852cd8ed897ab2d41a8fbee611d574e97898327db5c19d9d58e41126473f02c",
"https://deno.land/std@0.150.0/async/mux_async_iterator.ts": "5b4aca6781ad0f2e19ccdf1d1a1c092ccd3e00d52050d9c27c772658c8367256",
"https://deno.land/std@0.150.0/async/pool.ts": "ef9eb97b388543acbf0ac32647121e4dbe629236899586c4d4311a8770fbb239",
"https://deno.land/std@0.150.0/async/tee.ts": "bcfae0017ebb718cf4eef9e2420e8675d91cb1bcc0ed9b668681af6e6caad846",
"https://deno.land/std@0.150.0/flags/mod.ts": "594472736e24b2f2afd3451cf7ccd58a21706ce91006478a544fdfa056c69697",
"https://deno.land/std@0.150.0/fs/_util.ts": "2cf50bfb1081c2d5f2efec10ac19abbc2baf478e51cd1b057d0da2f30585b6ba",
"https://deno.land/std@0.150.0/fs/walk.ts": "6ce8d87fbaeda23383e979599ad27f3f94b3e5ff0c0cd976b5fc5c2aa0df7d92",
"https://deno.land/std@0.150.0/http/http_status.ts": "897575a7d6bc2b9123f6a38ecbc0f03d95a532c5d92029315dc9f508e12526b8",
"https://deno.land/std@0.150.0/http/server.ts": "0b0a9f3abfcfecead944b31ee9098a0c11a59b0495bf873ee200eb80e7441483",
"https://deno.land/std@0.150.0/media_types/_util.ts": "ce9b4fc4ba1c447dafab619055e20fd88236ca6bdd7834a21f98bd193c3fbfa1",
"https://deno.land/std@0.150.0/media_types/mod.ts": "2d4b6f32a087029272dc59e0a55ae3cc4d1b27b794ccf528e94b1925795b3118",
"https://deno.land/std@0.150.0/media_types/vendor/mime-db.v1.52.0.ts": "724cee25fa40f1a52d3937d6b4fbbfdd7791ff55e1b7ac08d9319d5632c7f5af",
"https://deno.land/std@0.150.0/path/_constants.ts": "df1db3ffa6dd6d1252cc9617e5d72165cd2483df90e93833e13580687b6083c3",
"https://deno.land/std@0.150.0/path/_interface.ts": "ee3b431a336b80cf445441109d089b70d87d5e248f4f90ff906820889ecf8d09",
"https://deno.land/std@0.150.0/path/_util.ts": "c1e9686d0164e29f7d880b2158971d805b6e0efc3110d0b3e24e4b8af2190d2b",
"https://deno.land/std@0.150.0/path/common.ts": "bee563630abd2d97f99d83c96c2fa0cca7cee103e8cb4e7699ec4d5db7bd2633",
"https://deno.land/std@0.150.0/path/glob.ts": "cb5255638de1048973c3e69e420c77dc04f75755524cb3b2e160fe9277d939ee",
"https://deno.land/std@0.150.0/path/mod.ts": "4945b430b759b0b3d98f2a278542cbcf95e0ad2bd8eaaed3c67322b306b2b346",
"https://deno.land/std@0.150.0/path/posix.ts": "c1f7afe274290ea0b51da07ee205653b2964bd74909a82deb07b69a6cc383aaa",
"https://deno.land/std@0.150.0/path/separator.ts": "fe1816cb765a8068afb3e8f13ad272351c85cbc739af56dacfc7d93d710fe0f9",
"https://deno.land/std@0.150.0/path/win32.ts": "bd7549042e37879c68ff2f8576a25950abbfca1d696d41d82c7bca0b7e6f452c",
"https://deno.land/std@0.150.0/semver/mod.ts": "4a5195fa81b4aede8875a386550a1119f01fb58d74aea899b2cfb136c05a7310",
"https://deno.land/std@0.152.0/async/abortable.ts": "87aa7230be8360c24ad437212311c9e8d4328854baec27b4c7abb26e85515c06",
"https://deno.land/std@0.152.0/async/deadline.ts": "48ac998d7564969f3e6ec6b6f9bf0217ebd00239b1b2292feba61272d5dd58d0",
"https://deno.land/std@0.152.0/async/debounce.ts": "564273ef242bcfcda19a439132f940db8694173abffc159ea34f07d18fc42620",
"https://deno.land/std@0.152.0/async/deferred.ts": "bc18e28108252c9f67dfca2bbc4587c3cbf3aeb6e155f8c864ca8ecff992b98a",
"https://deno.land/std@0.152.0/async/delay.ts": "cbbdf1c87d1aed8edc7bae13592fb3e27e3106e0748f089c263390d4f49e5f6c",
"https://deno.land/std@0.152.0/async/mod.ts": "dd0a8ed4f3984ffabe2fcca7c9f466b7932d57b1864ffee148a5d5388316db6b",
"https://deno.land/std@0.152.0/async/mux_async_iterator.ts": "5b4aca6781ad0f2e19ccdf1d1a1c092ccd3e00d52050d9c27c772658c8367256",
"https://deno.land/std@0.152.0/async/pool.ts": "ef9eb97b388543acbf0ac32647121e4dbe629236899586c4d4311a8770fbb239",
"https://deno.land/std@0.152.0/async/tee.ts": "bcfae0017ebb718cf4eef9e2420e8675d91cb1bcc0ed9b668681af6e6caad846",
"https://deno.land/std@0.152.0/http/server.ts": "0b0a9f3abfcfecead944b31ee9098a0c11a59b0495bf873ee200eb80e7441483",
"https://deno.land/std@0.161.0/encoding/base64.ts": "c57868ca7fa2fbe919f57f88a623ad34e3d970d675bdc1ff3a9d02bba7409db2",
"https://deno.land/std@0.161.0/encoding/base64url.ts": "a5f82a9fa703bd85a5eb8e7c1296bc6529e601ebd9642cc2b5eaa6b38fa9e05a",
"https://deno.land/std@0.170.0/_util/asserts.ts": "d0844e9b62510f89ce1f9878b046f6a57bf88f208a10304aab50efcb48365272",
"https://deno.land/std@0.170.0/_util/os.ts": "8a33345f74990e627b9dfe2de9b040004b08ea5146c7c9e8fe9a29070d193934",
"https://deno.land/std@0.170.0/async/abortable.ts": "80b2ac399f142cc528f95a037a7d0e653296352d95c681e284533765961de409",
"https://deno.land/std@0.170.0/async/deadline.ts": "2c2deb53c7c28ca1dda7a3ad81e70508b1ebc25db52559de6b8636c9278fd41f",
"https://deno.land/std@0.170.0/async/debounce.ts": "60301ffb37e730cd2d6f9dadfd0ecb2a38857681bd7aaf6b0a106b06e5210a98",
"https://deno.land/std@0.170.0/async/deferred.ts": "77d3f84255c3627f1cc88699d8472b664d7635990d5358c4351623e098e917d6",
"https://deno.land/std@0.170.0/async/delay.ts": "5a9bfba8de38840308a7a33786a0155a7f6c1f7a859558ddcec5fe06e16daf57",
"https://deno.land/std@0.170.0/async/mod.ts": "7809ad4bb223e40f5fdc043e5c7ca04e0e25eed35c32c3c32e28697c553fa6d9",
"https://deno.land/std@0.170.0/async/mux_async_iterator.ts": "770a0ff26c59f8bbbda6b703a2235f04e379f73238e8d66a087edc68c2a2c35f",
"https://deno.land/std@0.170.0/async/pool.ts": "6854d8cd675a74c73391c82005cbbe4cc58183bddcd1fbbd7c2bcda42b61cf69",
"https://deno.land/std@0.170.0/async/retry.ts": "e8e5173623915bbc0ddc537698fa418cf875456c347eda1ed453528645b42e67",
"https://deno.land/std@0.170.0/async/tee.ts": "3a47cc4e9a940904fd4341f0224907e199121c80b831faa5ec2b054c6d2eff5e",
"https://deno.land/std@0.170.0/bytes/bytes_list.ts": "aba5e2369e77d426b10af1de0dcc4531acecec27f9b9056f4f7bfbf8ac147ab4",
"https://deno.land/std@0.170.0/bytes/concat.ts": "97a1274e117510ffffc9499c4debb9541e408732bab2e0ca624869ae13103c10",
"https://deno.land/std@0.170.0/bytes/copy.ts": "d14a58f188a997ee0d2ba696d0c82a42f4fb4b6705e90a4238b77d7644dae24c",
"https://deno.land/std@0.170.0/collections/_utils.ts": "fd759867be7a0047a1fa89ec89f7b58ebe3f2f7f089a8f4e416eb30c5d764868",
"https://deno.land/std@0.170.0/collections/deep_merge.ts": "0303cca7697646c5464ecb3337d494602056babae4f09baf6619f1043ba7eb6d",
"https://deno.land/std@0.170.0/collections/filter_values.ts": "3f19ad44dce3a5e2430c47759d0068d6cef44a186a554da1c28ef27448bf7dfc",
"https://deno.land/std@0.170.0/collections/without_all.ts": "d0adc99202b5b23d38fc7733410f84ae0b1af5fbf2ca2ce7cf184ffe36b599be",
"https://deno.land/std@0.170.0/crypto/_fnv/fnv32.ts": "aa9bddead8c6345087d3abd4ef35fb9655622afc333fc41fff382b36e64280b5",
"https://deno.land/std@0.170.0/crypto/_fnv/fnv64.ts": "625d7e7505b6cb2e9801b5fd6ed0a89256bac12b2bbb3e4664b85a88b0ec5bef",
"https://deno.land/std@0.170.0/crypto/_fnv/index.ts": "a8f6a361b4c6d54e5e89c16098f99b6962a1dd6ad1307dbc97fa1ecac5d7060a",
"https://deno.land/std@0.170.0/crypto/_fnv/util.ts": "4848313bed7f00f55be3cb080aa0583fc007812ba965b03e4009665bde614ce3",
"https://deno.land/std@0.170.0/crypto/_util.ts": "4a8cb74e7273d2400aa6da582ec58078cf8d54bc66530592048cbd7cc4152621",
"https://deno.land/std@0.170.0/crypto/_wasm/lib/deno_std_wasm_crypto.generated.mjs": "71c1ac20f32fdbdc9b31a14917779c7fa392dbc8b050059cbb2c35b400b975b1",
"https://deno.land/std@0.170.0/crypto/_wasm/mod.ts": "b49ec171049bbbaaed3c5a5a71dfcb3d09f880607c8d9c517638d0443bd0f874",
"https://deno.land/std@0.170.0/crypto/keystack.ts": "ee8ee58ca876f619cef56f40127405f77f9738f50a459b6ba44234b3a2cb6cc8",
"https://deno.land/std@0.170.0/crypto/mod.ts": "f953406904aa4257a6c76c40eb74b47d8dad83af8a77f33a4639cbac6d311baf",
"https://deno.land/std@0.170.0/crypto/timing_safe_equal.ts": "3784958e40a5fe10429a68b75cc5f8d34356bf0bc2eb93c80c3033e2a6f17821",
"https://deno.land/std@0.170.0/crypto/util.ts": "93fc9dbaa62421538ad60ee65337cbf1d8a0298fac3c4f70b37e5627e7e129eb",
"https://deno.land/std@0.170.0/datetime/to_imf.ts": "bdb0704a986a9bb48fba220722b3d4681e4b8c9c162562ee545ef2eb90b6edcd",
"https://deno.land/std@0.170.0/dotenv/load.ts": "b083f766a5ab0a955aa339d46bc9499979e202e5365ccde5b6d0875d8411cc4a",
"https://deno.land/std@0.170.0/dotenv/mod.ts": "c6a7804fe59ae566cb2bebc11829f717d840cd498a339131ffeafb9fbbea94e6",
"https://deno.land/std@0.170.0/encoding/_yaml/dumper/dumper.ts": "5bd334372608a1aec7a2343705930889d4048f57a2c4d398f1d6d75996ecd0d3",
"https://deno.land/std@0.170.0/encoding/_yaml/dumper/dumper_state.ts": "3c1bc8519c1832f0f136856881b97f0b42f64b7968767dbc36b8b0b6cae963dc",
"https://deno.land/std@0.170.0/encoding/_yaml/error.ts": "6ca899f6d86c6979bce6d7c3a6a8e2a360b09d8b0f55d2e649bd1233604fb7c9",
"https://deno.land/std@0.170.0/encoding/_yaml/loader/loader.ts": "db200890459e9490b21d8ce657d9566327e1d1d20ed493393a1f04a51516436c",
"https://deno.land/std@0.170.0/encoding/_yaml/loader/loader_state.ts": "59124e56d864274ce4043dca8bf63e937c6e960e4ad120465e424b38f3469b2d",
"https://deno.land/std@0.170.0/encoding/_yaml/mark.ts": "7f67f43755b2602fefe52012eb3ab627880da97edd0f6c00f916ceb2ddb1b5d1",
"https://deno.land/std@0.170.0/encoding/_yaml/parse.ts": "f0c9b19957b78003e268cea886451d9eb5a71645308c1e64db05efb669ffb114",
"https://deno.land/std@0.170.0/encoding/_yaml/schema.ts": "db295ea6079fce9c38f4ee2ff1233c65db598b35b379551e445b558534b2e1fd",
"https://deno.land/std@0.170.0/encoding/_yaml/schema/core.ts": "bcb47a389d596369fbfccf73a6b221ac3ca5440149b4f6df1e707f2efc6854ef",
"https://deno.land/std@0.170.0/encoding/_yaml/schema/default.ts": "8b6bd9cb1cab07a3397e1cc3843edba6ad40d1bd15687c1f56cd977da834d984",
"https://deno.land/std@0.170.0/encoding/_yaml/schema/extended.ts": "e8b8976bcfda4c339709fba75787168fbc780458e52b9729386284d33f57e21a",
"https://deno.land/std@0.170.0/encoding/_yaml/schema/failsafe.ts": "7254a9ca0dff8f30377098622812e55c4535aaf352fecb4ec51939e596bd74e7",
"https://deno.land/std@0.170.0/encoding/_yaml/schema/json.ts": "2205d0d3d3377de56f92ac0f4a82bf561ea0d7b86eb195c9f0c32c7c7871d78f",
"https://deno.land/std@0.170.0/encoding/_yaml/schema/mod.ts": "6769df6082aceee9849f71168f4353ba4f92e4a2a5a429a422debac13a593d4e",
"https://deno.land/std@0.170.0/encoding/_yaml/state.ts": "374b8dc170417beccb364e543b25eef73576196f4a526836bb3a621b87a204a3",
"https://deno.land/std@0.170.0/encoding/_yaml/stringify.ts": "ec15035c1928f96f4e42c0a0e9f3082512e294fd6b8ff6a0403a3ee9282f69aa",
"https://deno.land/std@0.170.0/encoding/_yaml/type.ts": "95ad0cdbab49343b1527ebc7762c477726c34702438375be6781b44e03e9fcfc",
"https://deno.land/std@0.170.0/encoding/_yaml/type/binary.ts": "04c00f4e5c491c0c09e894dfd4e2ce312d5cf4bb2a9eb04c4a05d3a6fb17bfbe",
"https://deno.land/std@0.170.0/encoding/_yaml/type/bool.ts": "95c030531adc3d66a59979dc25c2fcdeb1f58ae40a91d6f9e9a537af0fd2b5a4",
"https://deno.land/std@0.170.0/encoding/_yaml/type/float.ts": "60e26783fd0e4472bd222e028323ff68e0c5ff37a9871298c676335d8574cf87",
"https://deno.land/std@0.170.0/encoding/_yaml/type/function.ts": "b5642dda5ef8d47c0325a2b89a022cbce3be45ba21f8c4f9202364d967c6b3e5",
"https://deno.land/std@0.170.0/encoding/_yaml/type/int.ts": "166cdd73d9473373e0e65e9f65d5fd8e96cbd303b58535e2ff2e049bb73dbefb",
"https://deno.land/std@0.170.0/encoding/_yaml/type/map.ts": "78bf5447d2e3f79d59bf7cb63a76ca7797854a0d8e2154c6fd35775c4e5c8c61",
"https://deno.land/std@0.170.0/encoding/_yaml/type/merge.ts": "094b272e6087c6aef39cd9617fa6603ec934e507faad6c276d293e2734f9b083",
"https://deno.land/std@0.170.0/encoding/_yaml/type/mod.ts": "b2f267dc0b0296cf8f6109aa129e2cf6d1e1f8c59f8903f0330c18749eca2d3c",
"https://deno.land/std@0.170.0/encoding/_yaml/type/nil.ts": "1988843acab56e99e883cd047c40cc7fb799b6d335f541f022ae3b914abcbe35",
"https://deno.land/std@0.170.0/encoding/_yaml/type/omap.ts": "fd3f2f9a8ae634996da84d021353ac8bf4b41e714f2711159d756d0e2f3aabd1",
"https://deno.land/std@0.170.0/encoding/_yaml/type/pairs.ts": "90736f87b6e39a144205a235d8851f7bebf6bb3835fd03742c30253d5ecd7ec5",
"https://deno.land/std@0.170.0/encoding/_yaml/type/regexp.ts": "a9e70491fa7ede8689b933d81142aa7635a253733a4df626bd479c55cb64222e",
"https://deno.land/std@0.170.0/encoding/_yaml/type/seq.ts": "135f37a1b6dcb3688bc0dad0c9dc3a04370b1fc94267960586ea23877ffd3088",
"https://deno.land/std@0.170.0/encoding/_yaml/type/set.ts": "2937ac0e1ce8c121a4009e74568e341e2a380fdb5f41f16050ce2ca7537b2bd8",
"https://deno.land/std@0.170.0/encoding/_yaml/type/str.ts": "6420d3a0099d9fbc35861241b7dad65b800ff3909efe71ab71c895326187ab8d",
"https://deno.land/std@0.170.0/encoding/_yaml/type/timestamp.ts": "3db0667dd9bdc3b3f0e8596fff023e87bc9fca230a545bb67d0bf3b732c1c656",
"https://deno.land/std@0.170.0/encoding/_yaml/type/undefined.ts": "5b595082d064cf50a3345f5fdda8c02beb0768e9d97d4bd4c53ac81a9f94e185",
"https://deno.land/std@0.170.0/encoding/_yaml/utils.ts": "c7e6bf055b08fffe700c7cbdfa2939cab7b9676ff75b6dc98d72d41b3b173d37",
"https://deno.land/std@0.170.0/encoding/base64.ts": "8605e018e49211efc767686f6f687827d7f5fd5217163e981d8d693105640d7a",
"https://deno.land/std@0.170.0/encoding/base64url.ts": "0283b12fcd306c11e3cf26fc022fecc800c6acc19704ea8bdb3908898fcd06d6",
"https://deno.land/std@0.170.0/encoding/hex.ts": "b51e99b684486a3ad2406807a8be953f5ef8bac95af202774a759f9fcf0d87a6",
"https://deno.land/std@0.170.0/encoding/yaml.ts": "42baa442cb37a7e1f5d1aa5256ba988d139fe7bb2940151d8ed689be0ea67ce9",
"https://deno.land/std@0.170.0/flags/mod.ts": "4f50ec6383c02684db35de38b3ffb2cd5b9fcfcc0b1147055d1980c49e82521c",
"https://deno.land/std@0.170.0/fmt/colors.ts": "03ad95e543d2808bc43c17a3dd29d25b43d0f16287fe562a0be89bf632454a12",
"https://deno.land/std@0.170.0/http/cookie.ts": "581464551b3d91739f699fbd6a429e6e8701ae252cf295efcda7379e8410d204",
"https://deno.land/std@0.170.0/http/file_server.ts": "c26eee517f9fe8a398556f3ba9a65accfa9a85af37e583ae537a4d5126a51dd7",
"https://deno.land/std@0.170.0/http/http_status.ts": "ed24048cc0d06066c944da59b0301da3ae2f990564bb4ad79bb52a09cf8e9b30",
"https://deno.land/std@0.170.0/http/server.ts": "1b93c76cd415d7b6ad0ae36c17ccb9149b23f4dff018f7d5aa1ab5c36637eb45",
"https://deno.land/std@0.170.0/http/util.ts": "759a2b57b44b722d2033d0dfe077f7e9a257f431db6d0319b78dcfebed0adb1e",
"https://deno.land/std@0.170.0/io/buf_reader.ts": "6c0eb067040a9931be2d24de50f56e67b10e3ff69d5344575df06caddf551417",
"https://deno.land/std@0.170.0/io/buf_writer.ts": "b1ee5325cec3386596c67b1c7510bfc7e42b2f505060fe2e9d6536cdefdbb30c",
"https://deno.land/std@0.170.0/io/buffer.ts": "04e4d9a7bffffeddd75df7da795001871857d83f8e7772e6a3eee9d174f33d38",
"https://deno.land/std@0.170.0/io/read_delim.ts": "6bff17d31730eeab402633ee53701ac16e7b575a343c432acf7bd61bd649fd05",
"https://deno.land/std@0.170.0/io/read_lines.ts": "51e2841394effe1473f588de2a87d62b1c2deb63ce869115506324e228f9e67b",
"https://deno.land/std@0.170.0/io/read_string_delim.ts": "70b20eebd853269252d4a833834a2677b711f216842709d11005ba291d822a0a",
"https://deno.land/std@0.170.0/io/types.d.ts": "790d3a3fa6b7f298d4cfbcf8bfd9d4be595c1b1acaa3eebb3009177df98bf93c",
"https://deno.land/std@0.170.0/media_types/_db.ts": "981fb4a1ad1dad6bc896208e9d01929bea31b875b9a400ad145a5e802996b3ea",
"https://deno.land/std@0.170.0/media_types/_util.ts": "839abd68a8c67f89e3fd8900b89b8d4725368b488f72f067fcf8051e77e3a38d",
"https://deno.land/std@0.170.0/media_types/content_type.ts": "ecf5e4965195b7c19a0de7b251ae920cfb40897205c5529d829d357bf2218900",
"https://deno.land/std@0.170.0/media_types/format_media_type.ts": "e5f906e7b0509d47c81b3533ebb96783e57683cc0fcb03ea4e3420c641a80538",
"https://deno.land/std@0.170.0/media_types/get_charset.ts": "74aee42562808172c3ce2892a7e668f537bf565f2deebd2655a7d5c5b2779857",
"https://deno.land/std@0.170.0/media_types/parse_media_type.ts": "f40f0b98e7e6883bc2ea0f83482c48e2583a2a9785426dfc665f494f0ca3f17b",
"https://deno.land/std@0.170.0/media_types/type_by_extension.ts": "5bd760bb9518ba0cf4e40cc5b9d04dc84b0c562d9b04ac2cbd4050a4b47c9a6d",
"https://deno.land/std@0.170.0/media_types/vendor/mime-db.v1.52.0.ts": "724cee25fa40f1a52d3937d6b4fbbfdd7791ff55e1b7ac08d9319d5632c7f5af",
"https://deno.land/std@0.170.0/path/_constants.ts": "df1db3ffa6dd6d1252cc9617e5d72165cd2483df90e93833e13580687b6083c3",
"https://deno.land/std@0.170.0/path/_interface.ts": "ee3b431a336b80cf445441109d089b70d87d5e248f4f90ff906820889ecf8d09",
"https://deno.land/std@0.170.0/path/_util.ts": "d16be2a16e1204b65f9d0dfc54a9bc472cafe5f4a190b3c8471ec2016ccd1677",
"https://deno.land/std@0.170.0/path/common.ts": "bee563630abd2d97f99d83c96c2fa0cca7cee103e8cb4e7699ec4d5db7bd2633",
"https://deno.land/std@0.170.0/path/glob.ts": "81cc6c72be002cd546c7a22d1f263f82f63f37fe0035d9726aa96fc8f6e4afa1",
"https://deno.land/std@0.170.0/path/mod.ts": "cf7cec7ac11b7048bb66af8ae03513e66595c279c65cfa12bfc07d9599608b78",
"https://deno.land/std@0.170.0/path/posix.ts": "b859684bc4d80edfd4cad0a82371b50c716330bed51143d6dcdbe59e6278b30c",
"https://deno.land/std@0.170.0/path/separator.ts": "fe1816cb765a8068afb3e8f13ad272351c85cbc739af56dacfc7d93d710fe0f9",
"https://deno.land/std@0.170.0/path/win32.ts": "7cebd2bda6657371adc00061a1d23fdd87bcdf64b4843bb148b0b24c11b40f69",
"https://deno.land/std@0.170.0/version.ts": "eb6935c9beaac221b235d011ba5b127ceb5d3addf329cc01e05806af07ba93e1",
"https://deno.land/x/bcrypt@v0.4.1/mod.ts": "ff09bdae282583cf5f7d87efe37ddcecef7f14f6d12e8b8066a3058db8c6c2f7",
"https://deno.land/x/bcrypt@v0.4.1/src/bcrypt/base64.ts": "b8266450a4f1eb6960f60f2f7986afc4dde6b45bd2d7ee7ba10789e67e17b9f7",
"https://deno.land/x/bcrypt@v0.4.1/src/bcrypt/bcrypt.ts": "ec221648cc6453ea5e3803bc817c01157dada06aa6f7a0ba6b9f87aae32b21e2",
"https://deno.land/x/bcrypt@v0.4.1/src/main.ts": "08d201b289c8d9c46f8839c69cd6625b213863db29775c7a200afc3b540e64f8",
"https://deno.land/x/bcrypt@v0.4.1/src/worker.ts": "5a73bdfee9c9e622f47c9733d374b627dce52fb3ec1e74c8226698b3fc57ffac",
"https://deno.land/x/cliffy@v0.25.6/_utils/distance.ts": "02af166952c7c358ac83beae397aa2fbca4ad630aecfcd38d92edb1ea429f004",
"https://deno.land/x/cliffy@v0.25.6/ansi/ansi.ts": "7f43d07d31dd7c24b721bb434c39cbb5132029fa4be3dd8938873065f65e5810",
"https://deno.land/x/cliffy@v0.25.6/ansi/ansi_escapes.ts": "885f61f343223f27b8ec69cc138a54bea30542924eacd0f290cd84edcf691387",
"https://deno.land/x/cliffy@v0.25.6/ansi/chain.ts": "31fb9fcbf72fed9f3eb9b9487270d2042ccd46a612d07dd5271b1a80ae2140a0",
"https://deno.land/x/cliffy@v0.25.6/ansi/colors.ts": "5f71993af5bd1aa0a795b15f41692d556d7c89584a601fed75997df844b832c9",
"https://deno.land/x/cliffy@v0.25.6/ansi/cursor_position.ts": "d537491e31d9c254b208277448eff92ff7f55978c4928dea363df92c0df0813f",
"https://deno.land/x/cliffy@v0.25.6/ansi/deps.ts": "0f35cb7e91868ce81561f6a77426ea8bc55dc15e13f84c7352f211023af79053",
"https://deno.land/x/cliffy@v0.25.6/ansi/mod.ts": "bb4e6588e6704949766205709463c8c33b30fec66c0b1846bc84a3db04a4e075",
"https://deno.land/x/cliffy@v0.25.6/ansi/tty.ts": "8fb064c17ead6cdf00c2d3bc87a9fd17b1167f2daa575c42b516f38bdb604673",
"https://deno.land/x/cliffy@v0.25.6/command/_errors.ts": "a9bd23dc816b32ec96c9b8f3057218241778d8c40333b43341138191450965e5",
"https://deno.land/x/cliffy@v0.25.6/command/_utils.ts": "9ab3d69fabab6c335b881b8a5229cbd5db0c68f630a1c307aff988b6396d9baf",
"https://deno.land/x/cliffy@v0.25.6/command/command.ts": "6ecc7c20e764246c021d92b12eea2226d08cb9688dffb5ac9b33277dbf16a2b0",
"https://deno.land/x/cliffy@v0.25.6/command/completions/_bash_completions_generator.ts": "43b4abb543d4dc60233620d51e69d82d3b7c44e274e723681e0dce2a124f69f9",
"https://deno.land/x/cliffy@v0.25.6/command/completions/_fish_completions_generator.ts": "d0289985f5cf0bd288c05273bfa286b24c27feb40822eb7fd9d7fee64e6580e8",
"https://deno.land/x/cliffy@v0.25.6/command/completions/_zsh_completions_generator.ts": "14461eb274954fea4953ee75938821f721da7da607dc49bcc7db1e3f33a207bd",
"https://deno.land/x/cliffy@v0.25.6/command/completions/bash.ts": "053aa2006ec327ccecacb00ba28e5eb836300e5c1bec1b3cfaee9ddcf8189756",
"https://deno.land/x/cliffy@v0.25.6/command/completions/complete.ts": "58df61caa5e6220ff2768636a69337923ad9d4b8c1932aeb27165081c4d07d8b",
"https://deno.land/x/cliffy@v0.25.6/command/completions/fish.ts": "9938beaa6458c6cf9e2eeda46a09e8cd362d4f8c6c9efe87d3cd8ca7477402a5",
"https://deno.land/x/cliffy@v0.25.6/command/completions/mod.ts": "aeef7ec8e319bb157c39a4bab8030c9fe8fa327b4c1e94c9c1025077b45b40c0",
"https://deno.land/x/cliffy@v0.25.6/command/completions/zsh.ts": "8b04ab244a0b582f7927d405e17b38602428eeb347a9968a657e7ea9f40e721a",
"https://deno.land/x/cliffy@v0.25.6/command/deprecated.ts": "bbe6670f1d645b773d04b725b8b8e7814c862c9f1afba460c4d599ffe9d4983c",
"https://deno.land/x/cliffy@v0.25.6/command/deps.ts": "bdf4eb349a6aa09beea1d2004edb232d5c91b252eff59f735ddd8b2be1f5915d",
"https://deno.land/x/cliffy@v0.25.6/command/help/_help_generator.ts": "10d0192727b97354e5fedca28418df94d9bee09253f3afe5196e1285c5e987cc",
"https://deno.land/x/cliffy@v0.25.6/command/help/mod.ts": "09d74d3eb42d21285407cda688074c29595d9c927b69aedf9d05ff3f215820d3",
"https://deno.land/x/cliffy@v0.25.6/command/mod.ts": "d0a32df6b14028e43bb2d41fa87d24bc00f9662a44e5a177b3db02f93e473209",
"https://deno.land/x/cliffy@v0.25.6/command/type.ts": "24e88e3085e1574662b856ccce70d589959648817135d4469fab67b9cce1b364",
"https://deno.land/x/cliffy@v0.25.6/command/types.ts": "ae02eec0ed7a769f7dba2dd5d3a931a61724b3021271b1b565cf189d9adfd4a0",
"https://deno.land/x/cliffy@v0.25.6/command/types/action_list.ts": "33c98d449617c7a563a535c9ceb3741bde9f6363353fd492f90a74570c611c27",
"https://deno.land/x/cliffy@v0.25.6/command/types/boolean.ts": "3879ec16092b4b5b1a0acb8675f8c9250c0b8a972e1e4c7adfba8335bd2263ed",
"https://deno.land/x/cliffy@v0.25.6/command/types/child_command.ts": "f1fca390c7fbfa7a713ca15ef55c2c7656bcbb394d50e8ef54085bdf6dc22559",
"https://deno.land/x/cliffy@v0.25.6/command/types/command.ts": "325d0382e383b725fd8d0ef34ebaeae082c5b76a1f6f2e843fee5dbb1a4fe3ac",
"https://deno.land/x/cliffy@v0.25.6/command/types/enum.ts": "2178345972adf7129a47e5f02856ca3e6852a91442a1c78307dffb8a6a3c6c9f",
"https://deno.land/x/cliffy@v0.25.6/command/types/file.ts": "8618f16ac9015c8589cbd946b3de1988cc4899b90ea251f3325c93c46745140e",
"https://deno.land/x/cliffy@v0.25.6/command/types/integer.ts": "29864725fd48738579d18123d7ee78fed37515e6dc62146c7544c98a82f1778d",
"https://deno.land/x/cliffy@v0.25.6/command/types/number.ts": "aeba96e6f470309317a16b308c82e0e4138a830ec79c9877e4622c682012bc1f",
"https://deno.land/x/cliffy@v0.25.6/command/types/string.ts": "e4dadb08a11795474871c7967beab954593813bb53d9f69ea5f9b734e43dc0e0",
"https://deno.land/x/cliffy@v0.25.6/command/upgrade/mod.ts": "17e2df3b620905583256684415e6c4a31e8de5c59066eb6d6c9c133919292dc4",
"https://deno.land/x/cliffy@v0.25.6/command/upgrade/provider.ts": "c6e8e0b8dc91359ece92f73061a218a8384790c29bc48feece9e81f5048611e7",
"https://deno.land/x/cliffy@v0.25.6/command/upgrade/provider/deno_land.ts": "24f8d82e38c51e09be989f30f8ad21f9dd41ac1bb1973b443a13883e8ba06d6d",
"https://deno.land/x/cliffy@v0.25.6/command/upgrade/provider/github.ts": "666f43d7ee687d90da42f1ab105c27f8f953db452f9a6bb88e68852cc813ad08",
"https://deno.land/x/cliffy@v0.25.6/command/upgrade/provider/nest_land.ts": "0e07936cea04fa41ac9297f32d87f39152ea873970c54cb5b4934b12fee1885e",
"https://deno.land/x/cliffy@v0.25.6/command/upgrade/upgrade_command.ts": "3640a287d914190241ea1e636774b1b4b0e1828fa75119971dd5304784061e05",
"https://deno.land/x/cliffy@v0.25.6/flags/_errors.ts": "f1fbb6bfa009e7950508c9d491cfb4a5551027d9f453389606adb3f2327d048f",
"https://deno.land/x/cliffy@v0.25.6/flags/_utils.ts": "340d3ecab43cde9489187e1f176504d2c58485df6652d1cdd907c0e9c3ce4cc2",
"https://deno.land/x/cliffy@v0.25.6/flags/_validate_flags.ts": "16eb5837986c6f6f7620817820161a78d66ce92d690e3697068726bbef067452",
"https://deno.land/x/cliffy@v0.25.6/flags/deprecated.ts": "a72a35de3cc7314e5ebea605ca23d08385b218ef171c32a3f135fb4318b08126",
"https://deno.land/x/cliffy@v0.25.6/flags/flags.ts": "68a9dfcacc4983a84c07ba19b66e5e9fccd04389fad215210c60fb414cc62576",
"https://deno.land/x/cliffy@v0.25.6/flags/mod.ts": "b21c2c135cd2437cc16245c5f168a626091631d6d4907ad10db61c96c93bdb25",
"https://deno.land/x/cliffy@v0.25.6/flags/types.ts": "7452ea5296758fb7af89930349ce40d8eb9a43b24b3f5759283e1cb5113075fd",
"https://deno.land/x/cliffy@v0.25.6/flags/types/boolean.ts": "b21be165b49b8517372361642cffaeaa4f4bb69637994a9762ceba642fe39676",
"https://deno.land/x/cliffy@v0.25.6/flags/types/integer.ts": "b60d4d590f309ddddf066782d43e4dc3799f0e7d08e5ede7dc62a5ee94b9a6d9",
"https://deno.land/x/cliffy@v0.25.6/flags/types/number.ts": "610936e2d29de7c8c304b65489a75ebae17b005c6122c24e791fbed12444d51e",
"https://deno.land/x/cliffy@v0.25.6/flags/types/string.ts": "e89b6a5ce322f65a894edecdc48b44956ec246a1d881f03e97bbda90dd8638c5",
"https://deno.land/x/cliffy@v0.25.6/keycode/key_code.ts": "3e73a82b9132334038cb629393149e906509e7c121fbab5d9016237c0401cc1f",
"https://deno.land/x/cliffy@v0.25.6/keycode/key_codes.ts": "917f0a2da0dbace08cf29bcfdaaa2257da9fe7e705fff8867d86ed69dfb08cfe",
"https://deno.land/x/cliffy@v0.25.6/keycode/mod.ts": "292d2f295316c6e0da6955042a7b31ab2968ff09f2300541d00f05ed6c2aa2d4",
"https://deno.land/x/cliffy@v0.25.6/mod.ts": "e3515ccf6bd4e4ac89322034e07e2332ed71901e4467ee5bc9d72851893e167b",
"https://deno.land/x/cliffy@v0.25.6/prompt/_generic_input.ts": "727d9820eed3b174b4ddf6e2057bc5c9be88a21ee074c0f92b1e0a1b38db3366",
"https://deno.land/x/cliffy@v0.25.6/prompt/_generic_list.ts": "3dc8015738fad5937fe03ab450429ac05ca663cf2b4ae873747d819d243197dc",
"https://deno.land/x/cliffy@v0.25.6/prompt/_generic_prompt.ts": "c46a1adb7e6e6a030b1e887f062017cb941714e5d6d893989e1d88d4465a9b27",
"https://deno.land/x/cliffy@v0.25.6/prompt/_generic_suggestions.ts": "57d20659914685dbe7caae1d79dc9e1dec94333af5788c1f14c05dc81e2e48c3",
"https://deno.land/x/cliffy@v0.25.6/prompt/_utils.ts": "676cca30762656ed1a9bcb21a7254244278a23ffc591750e98a501644b6d2df3",
"https://deno.land/x/cliffy@v0.25.6/prompt/checkbox.ts": "4e00e94efcd7a9917101f719564b3bf98a7aee0986bb004a4a75125081538b9d",
"https://deno.land/x/cliffy@v0.25.6/prompt/confirm.ts": "9de9fd0e51f939bac0c6a5758bf6c9aa438d5916de196761091d689c6f950cf0",
"https://deno.land/x/cliffy@v0.25.6/prompt/deps.ts": "5d82eafac455b78cf797341d23a8009dc5fdd19e66a47fee4783c0fe3f60770f",
"https://deno.land/x/cliffy@v0.25.6/prompt/figures.ts": "26af0fbfe21497220e4b887bb550fab997498cde14703b98e78faf370fbb4b94",
"https://deno.land/x/cliffy@v0.25.6/prompt/input.ts": "8a98b6b2fbfc273785fdaaecc2e976aaf2d1402387045d73fc7d3fbe75023ea5",
"https://deno.land/x/cliffy@v0.25.6/prompt/list.ts": "4214e85d8755c1937de456583506a6335e346f041d9eba9230e7578bf3bd9dcc",
"https://deno.land/x/cliffy@v0.25.6/prompt/mod.ts": "195aed14d10d279914eaa28c696dec404d576ca424c097a5bc2b4a7a13b66c89",
"https://deno.land/x/cliffy@v0.25.6/prompt/number.ts": "65766e272f4fb96d35b3e6f54673987f81119315b2e843ae60516b064eb5ac04",
"https://deno.land/x/cliffy@v0.25.6/prompt/prompt.ts": "0e7f6a1d43475ee33fb25f7d50749b2f07fc0bcddd9579f3f9af12d05b4a4412",
"https://deno.land/x/cliffy@v0.25.6/prompt/secret.ts": "4d513925deca97a7ca5110f2fb6290186ce6deb4de93a9ce841737f196e27177",
"https://deno.land/x/cliffy@v0.25.6/prompt/select.ts": "3e58d118e79933036df69b30fb5aa63101dccee1f044d1a0010f32ad909806d5",
"https://deno.land/x/cliffy@v0.25.6/prompt/toggle.ts": "16a8aa3f4f22db7d4705cd263569d547b6540c53b057e64a4c4028b610dd1920",
"https://deno.land/x/cliffy@v0.25.6/table/border.ts": "2514abae4e4f51eda60a5f8c927ba24efd464a590027e900926b38f68e01253c",
"https://deno.land/x/cliffy@v0.25.6/table/cell.ts": "1d787d8006ac8302020d18ec39f8d7f1113612c20801b973e3839de9c3f8b7b3",
"https://deno.land/x/cliffy@v0.25.6/table/deps.ts": "5b05fa56c1a5e2af34f2103fd199e5f87f0507549963019563eae519271819d2",
"https://deno.land/x/cliffy@v0.25.6/table/layout.ts": "46bf10ae5430cf4fbb92f23d588230e9c6336edbdb154e5c9581290562b169f4",
"https://deno.land/x/cliffy@v0.25.6/table/mod.ts": "e74f69f38810ee6139a71132783765feb94436a6619c07474ada45b465189834",
"https://deno.land/x/cliffy@v0.25.6/table/row.ts": "5f519ba7488d2ef76cbbf50527f10f7957bfd668ce5b9169abbc44ec88302645",
"https://deno.land/x/cliffy@v0.25.6/table/table.ts": "ec204c9d08bb3ff1939c5ac7412a4c9ed7d00925d4fc92aff9bfe07bd269258d",
"https://deno.land/x/cliffy@v0.25.6/table/utils.ts": "187bb7dcbcfb16199a5d906113f584740901dfca1007400cba0df7dcd341bc29",
"https://deno.land/x/code_block_writer@11.0.3/mod.ts": "2c3448060e47c9d08604c8f40dee34343f553f33edcdfebbf648442be33205e5",
"https://deno.land/x/code_block_writer@11.0.3/utils/string_utils.ts": "60cb4ec8bd335bf241ef785ccec51e809d576ff8e8d29da43d2273b69ce2a6ff",
"https://deno.land/x/denoflate@1.2.1/mod.ts": "f5628e44b80b3d80ed525afa2ba0f12408e3849db817d47a883b801f9ce69dd6",
"https://deno.land/x/denoflate@1.2.1/pkg/denoflate.js": "b9f9ad9457d3f12f28b1fb35c555f57443427f74decb403113d67364e4f2caf4",
"https://deno.land/x/denoflate@1.2.1/pkg/denoflate_bg.wasm.js": "d581956245407a2115a3d7e8d85a9641c032940a8e810acbd59ca86afd34d44d",
"https://deno.land/x/djwt@v2.8/algorithm.ts": "fa4c7354ab9f4808d38104fdc6f21c8270f65f109ed84136d4fe31a4504426d4",
"https://deno.land/x/djwt@v2.8/deps.ts": "261b7b6bfe2602329d8f9de2938c2a898cd6dfa746b3454ae415df2c53e6ae4d",
"https://deno.land/x/djwt@v2.8/mod.ts": "7abba8518688e88648882a95161b42391ac6043c142b1ab491b36f712189e1e1",
"https://deno.land/x/djwt@v2.8/signature.ts": "a5649368a4b433b2810e7d47f53661fe3b0f7fe1778cb49234ceae3d6e861185",
"https://deno.land/x/djwt@v2.8/util.ts": "0d78272bd23a4656ceabe137d496fcca37cf3de36212477642aa5d85a880d87a",
"https://deno.land/x/esbuild@v0.14.51/mod.d.ts": "c142324d0383c39de0d7660cd207a7f7f52c7198a13d7d3281c0d636a070f441",
"https://deno.land/x/esbuild@v0.14.51/mod.js": "7432566c71fac77637822dc230319c7392a2d2fef51204c9d12c956d7093c279",
"https://deno.land/x/esbuild@v0.14.51/wasm.d.ts": "c142324d0383c39de0d7660cd207a7f7f52c7198a13d7d3281c0d636a070f441",
"https://deno.land/x/esbuild@v0.14.51/wasm.js": "afc1b6927543b664af60ce452c4929e5dc2bb9a0f4ed47b446a6431847c7598e",
"https://deno.land/x/esbuild_deno_loader@0.5.2/deps.ts": "bf83c27b7787b2f245fa0bc0b99f5041aa949c000a81c016cfe828d06b476d37",
"https://deno.land/x/esbuild_deno_loader@0.5.2/mod.ts": "bc111a68f323dbdb6edec68dd558ab732b27866d2ef304708872d763387b65d7",
"https://deno.land/x/esbuild_deno_loader@0.5.2/src/deno.ts": "0e83ccabbe2b004389288e38df2031b79eb347df2d139fce9394d8e88a11f259",
"https://deno.land/x/esbuild_deno_loader@0.5.2/src/native_loader.ts": "343854a566cf510cf25144f7c09fc0c1097780a31830305142a075d12bb697ba",
"https://deno.land/x/esbuild_deno_loader@0.5.2/src/portable_loader.ts": "35b6c526eed8c2c781a3256b23c30aa7cce69c0ef1d583c15528663287ba18a3",
"https://deno.land/x/esbuild_deno_loader@0.5.2/src/shared.ts": "b64749cd8c0f6252a11498bd8758ef1220003e46b2c9b68e16da63fd7e92b13a",
"https://deno.land/x/fresh@1.1.2/dev.ts": "a66c7d64be35bcd6a8e12eec9c27ae335044c70363a241f2e36ee776db468622",
"https://deno.land/x/fresh@1.1.2/plugins/twind.ts": "c0570d6010e29ba24ee5f43b9d3f1fe735f7fac76d9a3e680c9896373d669876",
"https://deno.land/x/fresh@1.1.2/plugins/twind/shared.ts": "023e0ffcd66668753b5049edab0de46e6d66194fb6026c679034b9bbf04ad6f3",
"https://deno.land/x/fresh@1.1.2/runtime.ts": "b02ec1e2e32cf73a33d262b7c9dcab9468ce16cd89fd424196c71003698a4ab0",
"https://deno.land/x/fresh@1.1.2/server.ts": "f379c9aad24471a71e58fb887fa57e5cc27ad9df035987eb260541c78df38e84",
"https://deno.land/x/fresh@1.1.2/src/dev/deps.ts": "de5470828c17839c0b52c328e6709f3477740b9800deaf724d6569b64b1d3872",
"https://deno.land/x/fresh@1.1.2/src/dev/error.ts": "21a38d240c00279662e6adde41367f1da0ae7e2836d993f818ea94aabab53e7b",
"https://deno.land/x/fresh@1.1.2/src/dev/mod.ts": "f5836b2eccd0efd7c0a726a121f174a974daefc22058f759f07d4df56c46e978",
"https://deno.land/x/fresh@1.1.2/src/runtime/csp.ts": "9ee900e9b0b786057b1009da5976298c202d1b86d1f1e4d2510bde5f06530ac9",
"https://deno.land/x/fresh@1.1.2/src/runtime/head.ts": "0f9932874497ab6e57ed1ba01d549e843523df4a5d36ef97460e7a43e3132fdc",
"https://deno.land/x/fresh@1.1.2/src/runtime/utils.ts": "8320a874a44bdd5905c7d4b87a0e7a14a6c50a2ed133800e72ae57341e4d4faa",
"https://deno.land/x/fresh@1.1.2/src/server/bundle.ts": "f529a54ea5e078b9bd94c64c2ad345a3ba763b39c25b6e61f90629bdfa39c2ff",
"https://deno.land/x/fresh@1.1.2/src/server/constants.ts": "ad10dda1bc20c25c2926f6a8cfd79ef4368d70b4b03a645f65c04b3fa7d93a8c",
"https://deno.land/x/fresh@1.1.2/src/server/context.ts": "b385b982de2e5ee6e543dd56aad0e88f8f8fe5d9497909cf16caaf23b4d88b62",
"https://deno.land/x/fresh@1.1.2/src/server/default_error_page.ts": "1155ac98b3729bf2e51be730af507e431db0ee43ac84c86f1c022a831b310106",
"https://deno.land/x/fresh@1.1.2/src/server/deps.ts": "1c4e05b7d6e4eecc0012c9ec30ee587d8f533ab67c2bcb59048ed5f76841a770",
"https://deno.land/x/fresh@1.1.2/src/server/htmlescape.ts": "834ac7d0caa9fc38dffd9b8613fb47aeecd4f22d5d70c51d4b20a310c085835c",
"https://deno.land/x/fresh@1.1.2/src/server/mod.ts": "72d213444334dd2e94c757a0eee0fc486c0919399ea9184d07ad042f34edd00d",
"https://deno.land/x/fresh@1.1.2/src/server/render.ts": "6f50707bd1f6e33ed84bb71ae3b0996d202b953cefc4285f5356524c7b21f01f",
"https://deno.land/x/fresh@1.1.2/src/server/types.ts": "dde992ab4ee635df71a7fc96fe4cd85943c1a9286ea8eb586563d5f5ca154955",
"https://deno.land/x/fuse@v6.4.1/dist/fuse.esm.min.js": "02034c3e0a1d7f4d207ecd104c9cde1bab116d474dc60c2a019e9d4353455ff4",
"https://deno.land/x/importmap@0.2.1/_util.ts": "ada9a9618b537e6c0316c048a898352396c882b9f2de38aba18fd3f2950ede89",
"https://deno.land/x/importmap@0.2.1/mod.ts": "ae3d1cd7eabd18c01a4960d57db471126b020f23b37ef14e1359bbb949227ade",
"https://deno.land/x/marked@1.0.1/mod.ts": "25a04e7c3512622293d84b7287711b990562ce41e44f7fb55af9ca1586e57b15",
"https://deno.land/x/rutt@0.0.13/mod.ts": "af981cfb95131152bf50fc9140fc00cb3efb6563df2eded1d408361d8577df20",
"https://deno.land/x/sqlite@v3.7.0/build/sqlite.d.ts": "12908ced1670f96d5dc39aebb0d659630136fa6523881e4712cfb20b122dd324",
"https://deno.land/x/sqlite@v3.7.0/build/sqlite.js": "cc55fef9cd124b2acb624899a5fad413834f4701bcfc21ac275844b822466292",
"https://deno.land/x/sqlite@v3.7.0/build/vfs.js": "08533cc78fb29b9d9bd62f6bb93e5ef333407013fed185776808f11223ba0e70",
"https://deno.land/x/sqlite@v3.7.0/mod.ts": "e09fc79d8065fe222578114b109b1fd60077bff1bb75448532077f784f4d6a83",
"https://deno.land/x/sqlite@v3.7.0/src/constants.ts": "90f3be047ec0a89bcb5d6fc30db121685fc82cb00b1c476124ff47a4b0472aa9",
"https://deno.land/x/sqlite@v3.7.0/src/db.ts": "87e3d222d00dd2e2827816a47976c6359996ab39e69c7f87855ea414585839c6",
"https://deno.land/x/sqlite@v3.7.0/src/error.ts": "f7a15cb00d7c3797da1aefee3cf86d23e0ae92e73f0ba3165496c3816ab9503a",
"https://deno.land/x/sqlite@v3.7.0/src/function.ts": "e4c83b8ec64bf88bafad2407376b0c6a3b54e777593c70336fb40d43a79865f2",
"https://deno.land/x/sqlite@v3.7.0/src/query.ts": "69895232360b4254a8834e3bbea30bc3752cf691dba862f4a393e7a41a2e30eb",
"https://deno.land/x/sqlite@v3.7.0/src/wasm.ts": "e79d0baa6e42423257fb3c7cc98091c54399254867e0f34a09b5bdef37bd9487",
"https://deno.land/x/ts_morph@16.0.0/common/DenoRuntime.ts": "537800e840d0994f9055164e11bf33eadf96419246af0d3c453793c3ae67bdb3",
"https://deno.land/x/ts_morph@16.0.0/common/mod.ts": "01985d2ee7da8d1caee318a9d07664774fbee4e31602bc2bb6bb62c3489555ed",
"https://deno.land/x/ts_morph@16.0.0/common/ts_morph_common.d.ts": "39f2ddefd4995e4344236c44c2bf296069149f45ef6f00440b56e7b32cb2b3bd",
"https://deno.land/x/ts_morph@16.0.0/common/ts_morph_common.js": "7d908bf4f416aa96de956dc11ecc83b585bed297e16418d496ca04a3481067e0",
"https://deno.land/x/ts_morph@16.0.0/common/typescript.d.ts": "df7dd83543f14081ca74918d5a80ff60f634f465746cf2aff8924b28bcc3b152",
"https://deno.land/x/ts_morph@16.0.0/common/typescript.js": "5c59651248a4c41b25fa7beee8e0d0d0fab5f439fa72d478e65abd8241aa533c",
"https://deno.land/x/ts_morph@16.0.0/mod.ts": "adba9b82f24865d15d2c78ef6074b9a7457011719056c9928c800f130a617c93",
"https://deno.land/x/ts_morph@16.0.0/ts_morph.d.ts": "38668b0e3780282a56a805425494490b0045d1928bd040c47a94095749dab8c3",
"https://deno.land/x/ts_morph@16.0.0/ts_morph.js": "9fc0f3d6a3997c2df023fabc4e529d2117d214ffd4fd04247ca2f56c4e9cd470",
"https://esm.sh/*preact-render-to-string@5.2.4": "0a65784d053ac491a6d2397ad38c14d2fa172240734b374d354fe38a74be873d",
"https://esm.sh/preact@10.11.0": "e888b244446037c56f1881173fb51d1f5fa7aae5599e6c5154619346a6a5094e",
"https://esm.sh/preact@10.11.0/hooks": "2b8ec155eb8b87501663f074acff1d55a9114fa7d88f0b39da06c940af1ff736",
"https://esm.sh/preact@10.11.0/jsx-runtime": "5c123264f19799ab243211132dded45f6d42d594b5c78dd585f947d07bf20eae",
"https://esm.sh/stable/preact@10.11.0/deno/hooks.js": "48b7674c1f0c2a0f8a0f758b786f5bc15ba0f7a4f3a356ecc783848f1e4a1c55",
"https://esm.sh/stable/preact@10.11.0/deno/jsx-runtime.js": "b5a8e96758c20b5dea05802c6f6962b8a95bfdbd476eb4ea51cf3234f6e09271",
"https://esm.sh/stable/preact@10.11.0/deno/preact.js": "071b515099e5dff2fe56768be62644e32fab702b194171357ccc4d7d1210144a",
"https://esm.sh/twind@0.16.17": "f5bf049b0104a59c2b4651c2e09cbf9f6cd3a3110bf7b0808355e56f40bd161c",
"https://esm.sh/twind@0.16.17/sheets": "e0951fd922dd174f4ecf30e499cc044f019c0a36431e2d0aa3e7df4b10f2187c",
"https://esm.sh/v87/csstype@3.1.0/index.d.ts": "ba7617784f6b9aeac5e20c5eea869bbc3ef31b905f59c796b0fd401dae17c111",
"https://esm.sh/v87/style-vendorizer@2.2.3/deno/style-vendorizer.js": "bacdb96f034bbdae11a8d90427a6d49270d28d5939f02dbf0e7d0e52491ff9e3",
"https://esm.sh/v87/twind@0.16.17/deno/sheets.js": "f75586c3a778278f99ca9e6761e8c8a2089c66d6a503bb25e3bba38597fe1e30",
"https://esm.sh/v87/twind@0.16.17/deno/twind.js": "b9bf5d268c9d1c240a6d4485f034508924923eef88d37618cbad999e8ff80593",
"https://esm.sh/v87/twind@0.16.17/sheets/sheets.d.ts": "3948858f36c53a1d9031dc6d57bd0f28204ea85745e6a90fbbaac6b8d9386b32",
"https://esm.sh/v87/twind@0.16.17/twind.d.ts": "af3f5da08497bb6641ccf6cf71d0343e9759c4521cc21b2f71e3f774ed26e3c1",
"https://esm.sh/v99/preact-render-to-string@5.2.4/X-ZS8q/deno/preact-render-to-string.js": "75aad97b00d5ad63383de7f729a3f1fea59e69a9b876db5551d9c746ed372f82",
"https://esm.sh/v99/preact-render-to-string@5.2.4/X-ZS8q/src/index.d.ts": "b1d73703252c8570fdf2952475805f5808ba3511fefbd93a3e7bd8406de7dcd0",
"https://esm.sh/v99/preact@10.11.0/hooks/src/index.d.ts": "5c29febb624fc25d71cb0e125848c9b711e233337a08f7eacfade38fd4c14cc3",
"https://esm.sh/v99/preact@10.11.0/jsx-runtime/src/index.d.ts": "e153460ed2b3fe2ad8b93696ecd48fbf73cd628b0b0ea6692b71804a3af69dfd",
"https://esm.sh/v99/preact@10.11.0/src/index.d.ts": "1a5c331227be54be6515b0c92a469d352834fa413963ae84a39a05a3177111f6",
"https://esm.sh/v99/preact@10.11.0/src/jsx.d.ts": "c423715fd7992b2e1446fea11d2d04e8adbd66c1edca1ce5e85f90e0d26a2eb2"
},
"npm": {
"specifiers": { "elasticlunr": "elasticlunr@0.9.5" },
"packages": {
"elasticlunr@0.9.5": {
"integrity": "sha512-5YM9LFQgVYfuLNEoqMqVWIBuF2UNCA+xu/jz1TyryLN/wmBcQSb+GNAwvLKvEpGESwgGN8XA1nbLAt6rKlyHYQ==",
"dependencies": {}
}
}
}
}

5
dev.ts Normal file
View File

@ -0,0 +1,5 @@
#!/usr/bin/env -S deno run -A --watch=static/,routes/
import dev from "$fresh/dev.ts";
await dev(import.meta.url, "./main.ts");

50
fresh.gen.ts Normal file
View File

@ -0,0 +1,50 @@
// DO NOT EDIT. This file is generated by fresh.
// This file SHOULD be checked into source version control.
// This file is automatically updated during development when running `dev.ts`.
import config from "./deno.json" assert { type: "json" };
import * as $0 from "./routes/_404.tsx";
import * as $1 from "./routes/_middleware.ts";
import * as $2 from "./routes/api/doc.ts";
import * as $3 from "./routes/api/login.ts";
import * as $4 from "./routes/api/logout.ts";
import * as $5 from "./routes/dir/[...path].tsx";
import * as $6 from "./routes/doc/index.tsx";
import * as $7 from "./routes/fs/[...path].ts";
import * as $8 from "./routes/index.tsx";
import * as $9 from "./routes/login.tsx";
import * as $$0 from "./islands/ContentRenderer.tsx";
import * as $$1 from "./islands/Counter.tsx";
import * as $$2 from "./islands/DirList.tsx";
import * as $$3 from "./islands/DocSearch.tsx";
import * as $$4 from "./islands/FileViewer.tsx";
import * as $$5 from "./islands/MarkdownRenderer.tsx";
import * as $$6 from "./islands/UpList.tsx";
const manifest = {
routes: {
"./routes/_404.tsx": $0,
"./routes/_middleware.ts": $1,
"./routes/api/doc.ts": $2,
"./routes/api/login.ts": $3,
"./routes/api/logout.ts": $4,
"./routes/dir/[...path].tsx": $5,
"./routes/doc/index.tsx": $6,
"./routes/fs/[...path].ts": $7,
"./routes/index.tsx": $8,
"./routes/login.tsx": $9,
},
islands: {
"./islands/ContentRenderer.tsx": $$0,
"./islands/Counter.tsx": $$1,
"./islands/DirList.tsx": $$2,
"./islands/DocSearch.tsx": $$3,
"./islands/FileViewer.tsx": $$4,
"./islands/MarkdownRenderer.tsx": $$5,
"./islands/UpList.tsx": $$6,
},
baseUrl: import.meta.url,
config,
};
export default manifest;

18
import_map.json Normal file
View File

@ -0,0 +1,18 @@
{
"imports": {
"$fresh/": "https://deno.land/x/fresh@1.1.2/",
"preact": "https://esm.sh/preact@10.11.0",
"preact/": "https://esm.sh/preact@10.11.0/",
"preact-render-to-string": "https://esm.sh/*preact-render-to-string@5.2.4",
"@preact/signals": "https://esm.sh/*@preact/signals@1.0.3",
"@preact/signals-core": "https://esm.sh/*@preact/signals-core@1.0.1",
"twind": "https://esm.sh/twind@0.16.17",
"twind/": "https://esm.sh/twind@0.16.17/",
"http/": "https://deno.land/std@0.170.0/http/",
"media_types/": "https://deno.land/std@0.170.0/media_types/",
"path/": "https://deno.land/std@0.170.0/path/",
"bcrypt": "https://deno.land/x/bcrypt@v0.4.1/mod.ts",
"sqlite": "https://deno.land/x/sqlite@v3.7.0/mod.ts",
"djwt": "https://deno.land/x/djwt@v2.8/mod.ts"
}
}

View File

@ -0,0 +1,65 @@
import { extname } from "path/posix.ts";
import MarkdownRenderer from "./MarkdownRenderer.tsx";
import { useEffect, useState } from "preact/hooks";
const TypeToExt = {
"image": new Set([".png", ".jpg", ".jpeg", ".gif", ".svg"]),
"video": new Set([".mp4", ".webm", ".ogg"]),
"audio": new Set([".mp3", ".wav", ".flac"]),
"md": new Set([".md"]),
"text": new Set([".txt"]),
"code": new Set([".json", ".js", ".ts", ".css", ".tsx", ".jsx"]),
}
function extToType(ext: string) {
for (const [type, exts] of Object.entries(TypeToExt)) {
if (exts.has(ext)) {
return type;
}
}
return "unknown";
}
function FetchAndRender(props: {src: string, type: string}){
const src = props.src;
const ext = extname(src);
const [content, setContent] = useState("");
useEffect(() => {
fetch(src).then(res => res.text()).then(setContent);
}, [src]);
switch (props.type) {
case "text":
return <div style={{ whiteSpace: "pre-wrap" }}>{content}</div>;
case "md":
return <MarkdownRenderer text={content} />;
case "code":
return <pre style={{ whiteSpace: "pre-wrap" }}><code lang={ext.slice(1)}>{content}</code></pre>;
//case "csv":
// return <CsvRenderer content={content} />;
default:
return <>error: invalid type: {props.type} content: {content}</>;
}
}
export function RenderView(props: {src: string}) {
const src = props.src;
const type = extToType(extname(src));
switch (type) {
case "text":
case "md":
case "code":
return <FetchAndRender src={src} type={type}></FetchAndRender>
//case "csv":
// return <CsvRenderer content={content} />;
case "image":
return <img style={{ width: "100%" }} src={src} />;
case "video":
return <video style={{ width: "100%" }} controls src={src} />;
case "audio":
return <audio style={{ width: "100%" }} controls src={src} />;
default:
return <>error: invalid type: {type} src: {src}</>;
}
}
export default RenderView;

17
islands/Counter.tsx Normal file
View File

@ -0,0 +1,17 @@
import { useState } from "preact/hooks";
import { Button } from "../components/Button.tsx";
interface CounterProps {
start: number;
}
export default function Counter(props: CounterProps) {
const [count, setCount] = useState(props.start);
return (
<div class="flex gap-2 w-full">
<p class="flex-grow-1 font-bold text-xl">{count}</p>
<Button onClick={() => setCount(count - 1)}>-1</Button>
<Button onClick={() => setCount(count + 1)}>+1</Button>
</div>
);
}

93
islands/DirList.tsx Normal file
View File

@ -0,0 +1,93 @@
import { Head, asset } from "$fresh/runtime.ts";
import { useState } from "preact/hooks";
import { extname, join } from "path/posix.ts";
import { ComponentChild } from "preact";
import UpList from "./UpList.tsx";
import {extToIcon} from "../src/media.ts";
function ListItem(props:{
href: string,
icon: string,
children: ComponentChild
}) {
return (
<li class="p-1 hover:bg-gray-400 transition-colors">
<a class="flex gap-2" href={props.href}>
<img src={asset(props.icon)}/><p class="">{props.children}</p></a>
</li>
);
}
export interface EntryInfo{
name: string;
isFile: boolean;
isDirectory: boolean;
isSymlink: boolean;
size: number;
lastModified?: Date;
}
interface DirListProps {
path: string;
files: EntryInfo[];
}
export function DirList(props: DirListProps) {
const data = props;
const [files, setFiles] = useState(data.files);
return (<div>
<UpList path={data.path}></UpList>
<ul class="border-2 rounded-md">
<li class="p-1 flex gap-2">
<button class="flex" onClick={sortDir}>
<img src={asset("/icon/sort-down.svg")}/> Sort Directory
</button>
<button class="flex" onClick={sortAlpha}>
<img src={asset("/icon/sort-alpha-down.svg")} /> Sort Alphabet
</button>
</li>
<ListItem key=".." href={`/dir/${join(data.path,"..")}`}
icon="/icon/back.svg"
>...</ListItem>
{files.map((file) => (
<ListItem key={file.name} href={`/dir/${join(data.path,file.name)}`}
icon={file.isDirectory ? "/icon/folder.svg": extToIcon(extname(file.name))}
>{file.name}</ListItem>
))}
</ul>
</div>)
function sortDir() {
// sort by directory first then by index
const sorted_files = files.map((x,i)=>
([x,i] as [EntryInfo, number]))
.sort(
([a, ai],[b,bi]) => {
if (a.isDirectory && !b.isDirectory) {
return -1;
} else if (!a.isDirectory && b.isDirectory) {
return 1;
} else {
return ai - bi;
}
});
setFiles(sorted_files.map(([x,_])=>x));
}
function sortAlpha() {
// sort by alphabet first then by index
const sorted_files = files.map((x,i)=>
([x,i] as [EntryInfo, number]))
.sort(
([a, ai],[b,bi]) => {
const ret = a.name.localeCompare(b.name);
if (ret === 0) {
return ai - bi;
} else {
return ret;
}
});
setFiles(sorted_files.map(([x,_])=>x));
}
}
export default DirList;

44
islands/DocSearch.tsx Normal file
View File

@ -0,0 +1,44 @@
import { Doc } from "../src/collect.ts";
import { useEffect, useState } from "preact/hooks";
import { Index } from "../src/client_search.ts";
function SearchBar(props:{
search?: string;
onSearch?: (search: string) => void;
}){
const [search, setSearch] = useState(props.search ?? "");
return (
<div class="flex items-center justify-center">
<input type="text" class="w-1/2 px-4 py-2 border-2 rounded-lg" placeholder="Search..."
//onChange={(event)=>{}}
onKeyUp={(event)=>{
if (event.currentTarget.value === search) return;
setSearch(event.currentTarget.value);
props.onSearch?.(event.currentTarget.value);
}}>{search}</input>
</div>
)
}
export default function DocSearch(props: {
docs: Doc[]
}){
const [docs, setDocs] = useState(props.docs);
const index = Index.createIndex(props.docs);
return (
<>
<SearchBar onSearch={(s)=>{
setDocs(index.search(s));
}}></SearchBar>
<h1 class="text-2xl font-bold">Doc</h1>
<ul class="mt-4">
{docs.map((doc) => (
<li class="mt-2">
<a href={`/dir/${doc.path}`}> {doc.path}</a>
</li>
))}
</ul>
</>
)
}

17
islands/FileViewer.tsx Normal file
View File

@ -0,0 +1,17 @@
import RenderView from "./ContentRenderer.tsx";
import UpList from "./UpList.tsx";
import { extname } from "path/mod.ts";
export default function FileViewer(props: { path: string }) {
const { path } = props;
const srcPath = `/fs/${path}`;
return (
<div class="p-4 mx-auto max-w-screen-md">
<UpList path={path} />
<a href={srcPath}>Direct link</a>
<div class="p-2 border-2 rounded-lg">
<RenderView src={srcPath}/>
</div>
</div>
)
}

View File

@ -0,0 +1,13 @@
import { marked } from "https://deno.land/x/marked@1.0.1/mod.ts";
export function MarkdownRenderer(props: { text: string | undefined }) {
let text = props.text;
if (text === undefined) {
text = "";
}
const index = text.indexOf('\n---', 3);
const c = text.slice(index + 4, text.length);
return <div class="markdown-body" dangerouslySetInnerHTML={{ __html: marked.parse(c) }} />;
}
export default MarkdownRenderer;

39
islands/UpList.tsx Normal file
View File

@ -0,0 +1,39 @@
import { Head, asset } from "$fresh/runtime.ts";
import { join } from "path/posix.ts";
import { ComponentChild } from "preact";
function stairs(path: string){
if (path === ".") return [];
const uplist = path.split("/");
let current = ".";
const stairs = [];
for (const up of uplist){
current = join(current, up);
stairs.push([current, up]);
}
return stairs;
}
export default function UpList(props:{path: string}) {
const data = props;
const uplist = stairs(data.path);
return (<div>
<h1 class={"text-2xl flex flex-wrap"}>
<a href="/dir/" class="flex flex-wrap p-2 hover:bg-gray-400 rounded-sm">
<img src={asset("/icon/house.svg")}/>
<span class="ml-1">Home</span></a>
{
uplist.map(([cur, up], i) => (
<>
<span class="p-2">/</span>
<a class="flex flex-wrap p-2 hover:bg-gray-400 rounded-sm" href={`/dir/${cur}`}>
<img src={asset("/icon/folder.svg")} />
<span class="ml-1">{up}</span>
</a>
</>
))
}</h1>
</div>)
}

16
keyout.ts Normal file
View File

@ -0,0 +1,16 @@
import { Command } from "https://deno.land/x/cliffy@v0.25.6/mod.ts";
import { fromFileUrl, join } from "path/mod.ts";
import { prepareSecretKey } from "./util/secret.ts";
export const key_out_cmd = new Command();
key_out_cmd.name("keyout")
.description("Output the secret key.")
.action(async () => {
const key = await prepareSecretKey();
const out = await crypto.subtle.exportKey("jwk", key);
console.log(JSON.stringify(out));
});
if ( import.meta.main ){
await key_out_cmd.parse(Deno.args);
}

86
main.ts Normal file
View File

@ -0,0 +1,86 @@
/// <reference no-default-lib="true" />
/// <reference lib="dom" />
/// <reference lib="dom.iterable" />
/// <reference lib="dom.asynciterable" />
/// <reference lib="deno.ns" />
import { PluginRenderResult, Plugin, ServerContext, Manifest, StartOptions } from "$fresh/server.ts";
import manifest from "./fresh.gen.ts";
import twindPlugin from "$fresh/plugins/twind.ts";
import twindConfig from "./twind.config.ts";
import "https://deno.land/std@0.170.0/dotenv/load.ts";
import { Command } from "https://deno.land/x/cliffy@v0.25.6/mod.ts";
import { fromFileUrl, join } from "path/mod.ts";
import { prepareSecretKey } from "./util/secret.ts";
import { serve } from "http/server.ts";
const github_markdown= await Deno.readTextFile(join(fromFileUrl(import.meta.url), "..", "static", "github-markdown.css"))
const CSSPlugin: Plugin = {
name:"css plugin",
// deno-lint-ignore require-await
render(ctx): PluginRenderResult{
ctx.render();
return {
styles: [{
cssText: github_markdown,
}]
}
}
};
await prepareSecretKey();
async function startServer(manifest: Manifest, options: StartOptions = {}){
const ctx = await ServerContext.fromManifest(manifest, options);
options.port ??= 8000;
if (options.experimentalDenoServe === true) {
// @ts-ignore as `Deno.serve` is still unstable.
await Deno.serve(ctx.handler() as Deno.ServeHandler, options);
} else {
await serve(ctx.handler(), options);
}
}
async function start({port = 8000, hostname = "localhost"}: {port?: number, hostname?: string}){
await startServer(manifest, { plugins: [twindPlugin(twindConfig), CSSPlugin],
port: port,
hostname: hostname,
});
}
if (import.meta.main){
const cmd = new Command();
cmd.name("fs-server")
.description("A simple file server that supports search, upload, and download.")
.version("0.0.1")
.globalOption("-d, --debug", "Enable debug mode.")
.command("start", "Start the server.")
.option("-p, --port <port:number>", "The port to listen on.",
{ default: 8000 })
.option("--auth", "Enable authentication.")
.arguments("[hostname:string]")
.action(async ({debug, port, auth }, hostname) => {
hostname ??= "localhost";
if (auth){
Deno.env.set("AUTH_REQUIRED", "true");
}
if (debug){
console.log("Debug mode enabled.");
}
await start({
port: port,
hostname: hostname,
});
}
)
//.command("user")
;
await cmd.parse(Deno.args);
}
else {
await start({});
}

24
routes/_404.tsx Normal file
View File

@ -0,0 +1,24 @@
import { Head } from "$fresh/runtime.ts";
export default function Page404() {
return (
<>
<Head>
<title>Simple file server - 404 Not Found</title>
</Head>
<div class="p-4 mx-auto max-w-screen-md">
<img
src="/logo.svg"
class="w-32 h-32"
alt="the fresh logo: a sliced lemon dripping with juice"
/>
<p class="my-6 text-4xl">
404 Not Found.
</p>
<a href="/dir/">Go To CWD</a>
<hr></hr>
<a href="/login">Login</a> | <a href="/api/logout">Logout</a>
</div>
</>
);
}

20
routes/_middleware.ts Normal file
View File

@ -0,0 +1,20 @@
import { MiddlewareHandlerContext } from "$fresh/server.ts";
import { getCookies } from "http/cookie.ts";
import { decode, verify } from "djwt";
import { prepareSecretKey } from "../util/secret.ts";
const secret_key = await prepareSecretKey();
export const handler =
async (req: Request , ctx: MiddlewareHandlerContext<Record<string, unknown>>) => {
const cookies = getCookies(req.headers);
const jwt = cookies["auth"];
try{
const payload = await verify(jwt, secret_key);
ctx.state["login"] = payload;
}
catch (e){
ctx.state["login"] = null;
}
return await ctx.next();
}

0
routes/api/doc.ts Normal file
View File

65
routes/api/login.ts Normal file
View File

@ -0,0 +1,65 @@
import { HandlerContext } from "$fresh/server.ts";
import { setCookie } from "http/cookie.ts";
import { Status } from "http/http_status.ts";
import { connectDB } from "../../src/user/db.ts";
import { getUser, verifyUser } from "../../src/user/user.ts";
import { create as createJWT } from "djwt";
import { prepareSecretKey } from "../../util/secret.ts";
const SECRET_KEY = await prepareSecretKey();
async function POST(req: Request, ctx: HandlerContext): Promise<Response> {
const url = new URL(req.url);
const form = await req.formData();
const username = form.get("username");
const password = form.get("password");
if (username && password){
const DB = connectDB();
const user = await getUser(DB, username.toString());
if (user){
if (await verifyUser(user, password.toString())){
const headers = new Headers();
const jwt = await createJWT({alg:"HS512", typ: "JWT"},{
username: user.name
}, SECRET_KEY);
setCookie(headers, {
name: "auth",
value: jwt,
httpOnly: true,
sameSite: "Strict",
maxAge: 60 * 60 * 24 * 7,
domain: url.hostname,
path: "/",
secure: url.protocol === "https:"
});
headers.set("Location", "/");
return new Response(null,{
status: Status.SeeOther, // See Other
headers: headers
});
}
}
}
return new Response(`<!DOCTYPE html><html>
<head> <title> Login Failed </title> </head>
<body>
<h1> Login Failed </h1>
<p> <a href="/"> Back to Home </a> </p>
<script>
document.location.href = "/login";
</script>
</body>
</html>`, {
headers:{
"Content-Type": "text/html"
},
status: Status.Forbidden,
});
}
export const handler = {
POST
};

17
routes/api/logout.ts Normal file
View File

@ -0,0 +1,17 @@
import { Handlers } from "$fresh/server.ts";
import { deleteCookie } from "http/cookie.ts";
import { Status } from "http/http_status.ts";
export const handler: Handlers = {
GET(req) {
const url = new URL(req.url);
const headers = new Headers(req.headers);
deleteCookie(headers, "auth", { path: "/", domain: url.hostname });
headers.set("location", "/");
return new Response(null, {
status: Status.Found,
headers,
});
},
};

83
routes/dir/[...path].tsx Normal file
View File

@ -0,0 +1,83 @@
import { PageProps, Handlers, HandlerContext } from "$fresh/server.ts";
import { Head, asset } from "$fresh/runtime.ts";
import {removePrefixFromPathname} from "../../util/util.ts";
import { join } from "path/posix.ts";
import DirList, { EntryInfo } from "../../islands/DirList.tsx";
import FileViewer from "../../islands/FileViewer.tsx";
type DirProps = {
type: "dir";
path: string;
stat: Deno.FileInfo;
files: EntryInfo[];
}
type FileProps = {
type: "file";
path: string;
stat: Deno.FileInfo;
}
type DirOrFileProps = DirProps | FileProps;
async function GET(req: Request, ctx: HandlerContext): Promise<Response>{
const authRequired = Deno.env.get("AUTH_REQUIRED") === "true";
if (authRequired) {
const login = ctx.state["login"];
if (!login) {
return new Response(null, {
status: 401,
headers: {
"content-type": "text/plain",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
"Access-Control-Allow-Headers": "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"
}
});
}
}
const url = new URL(req.url);
const path = removePrefixFromPathname(url.pathname, "/dir");
const stat = await Deno.stat(path);
if (stat.isDirectory){
const filesIter = await Deno.readDir(path);
const files: EntryInfo[] = []
for await (const file of filesIter){
const fileStat = await Deno.stat(join(path, file.name));
files.push({
...file,
lastModified: fileStat.mtime ? new Date(fileStat.mtime) : undefined,
size: fileStat.size
});
}
return await ctx.render({
type: "dir",
stat,
files
, path
})
}
else{
return await ctx.render({
type: "file",
stat, path
});
}
}
export const handler: Handlers = {
GET
}
export default function DirLists(props: PageProps<DirOrFileProps>) {
const data = props.data;
return (<>
<Head>
<title>Simple file server : {data.path}</title>
</Head>
<div class="p-4 mx-auto max-w-screen-md">
{data.type === "dir" ? (<DirList path={data.path} files={data.files}></DirList>) :
(<FileViewer path={data.path}></FileViewer>)}
</div>
</>
);
}

28
routes/doc/index.tsx Normal file
View File

@ -0,0 +1,28 @@
import { Head } from "$fresh/runtime.ts";
import { PageProps, Handlers, HandlerContext } from "$fresh/server.ts";
import DocSearch from "../../islands/DocSearch.tsx";
import { Doc } from "../../src/collect.ts";
import { docCollector } from "../../src/store/doc.ts";
async function GET(req: Request, ctx: HandlerContext): Promise<Response> {
const docs = docCollector.getDocs();
return await ctx.render({docs});
}
export const handler: Handlers = {
GET,
}
export default function Docs(props: PageProps<{docs:Doc[]}>) {
const {docs} = props.data;
return (
<>
<Head>
<title>Simple file server - Doc</title>
</Head>
<div class="p-4 mx-auto max-w-screen-md">
<DocSearch docs={docs}></DocSearch>
</div>
</>
);
}

74
routes/fs/[...path].ts Normal file
View File

@ -0,0 +1,74 @@
import { HandlerContext, Handlers } from "$fresh/server.ts";
import { serveFile } from "http/file_server.ts";
import {removePrefixFromPathname} from "../../util/util.ts";
export async function GET(req: Request, ctx: HandlerContext): Promise<Response> {
const url = new URL(req.url);
const path = removePrefixFromPathname(url.pathname, "/fs");
// if auth is required, check if the user is logged in.
// if not, return a 401.
const authRequired = Deno.env.get("AUTH_REQUIRED") === "true";
if (authRequired) {
const login = ctx.state["login"];
if (!login) {
return new Response(null, {
status: 401,
headers: {
"content-type": "text/plain",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
"Access-Control-Allow-Headers": "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"
}
});
}
}
try{
const fileInfo = await Deno.stat(path);
if (fileInfo.isDirectory) {
// if index.html exists, serve it.
// otherwise, serve a directory listing.
const indexPath = path + "/index.html";
try {
await Deno.stat(indexPath);
const res = await serveFile(req, indexPath)
return res;
} catch (e) {
if (e instanceof Deno.errors.NotFound) {
const list: Deno.DirEntry[] = []
for await (const entry of Deno.readDir(path)){
list.push(entry);
}
return new Response(JSON.stringify(
list
), {
headers: { "content-type": "application/json",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
"Access-Control-Allow-Headers": "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"},
status: 200,
});
}
}
}
const res = await serveFile(req, path, {
fileInfo
});
return res;
}
catch (e) {
if (e instanceof Deno.errors.NotFound) {
return new Response("Not Found", {
status: 404,
});
}
throw e;
}
}
export const handler: Handlers = {
GET
}

24
routes/index.tsx Normal file
View File

@ -0,0 +1,24 @@
import { Head } from "$fresh/runtime.ts";
export default function Home() {
return (
<>
<Head>
<title>Simple file server</title>
</Head>
<div class="p-4 mx-auto max-w-screen-md">
<img
src="/logo.svg"
class="w-32 h-32"
alt="the fresh logo: a sliced lemon dripping with juice"
/>
<p class="my-6">
This is a simple file server. It serves files from the <code>CWD</code>.
</p>
<a href="/dir/">Go To CWD</a>
<hr></hr>
<a href="/login">Login</a> | <a href="/api/logout">Logout</a>
</div>
</>
);
}

38
routes/login.tsx Normal file
View File

@ -0,0 +1,38 @@
import { Head } from "$fresh/runtime.ts";
export default function Login() {
return (
<>
<Head>
<title>Simple file server - Login</title>
</Head>
<div class="">
<div class="p-4 absolute top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%]
flex flex-col items-center border-gray-500 border-2 rounded-md
sm:max-w-screen-sm max-w-screen-md">
<img
src="/logo.svg"
class="w-32 h-32"
alt="the fresh logo: a sliced lemon dripping with juice"
/>
<form action="/api/login" method="POST" class="flex flex-col gap-2 items-stretch">
<div class="flex gap-2 flex-wrap">
<div class="basis-40 flex items-center flex-1">
<label for="username" class="w-20">Username</label>
<input type="text" name="username" id="username"
class="border-b-2 focus:border-green-500 transition-colors flex-1" />
</div>
<div class="flex items-center flex-1">
<label for="password" class="w-20">Password</label>
<input type="password" name="password" id="password"
class="border-b-2 focus:border-green-500 transition-colors flex-1" />
</div>
</div>
<button type="submit" class="bg-gray-400 p-2 rounded
m-auto">Login</button>
</form>
</div>
</div>
</>
);
}

85
search.ts Normal file
View File

@ -0,0 +1,85 @@
import { Command } from "https://deno.land/x/cliffy@v0.25.6/mod.ts";
import { Index } from "./src/client_search.ts";
import { Doc, DocCollector, loadDocuments } from "./src/collect.ts";
export async function collectDocuments(path: string, out: string){
const collector = new DocCollector({ summaryOnly: true, dropContent: true });
await collector.walkDir(path);
const docs = collector.getDocs();
await Deno.writeTextFile(out, JSON.stringify(docs));
}
export async function watchDocuments(doc: string , options?:{
abort?: AbortSignal,
}){
const doc_dump = await loadDocuments(doc);
const collector = new DocCollector({ summaryOnly: true, dropContent: true });
collector.setDocs(doc_dump);
const index = Index.createIndex(doc_dump);
async function update(){
index.setDocs(collector.getDocs());
await Deno.writeTextFile(doc, JSON.stringify(collector.getDocs()));
}
collector.watchDir(".", {
async onAdd(doc){
console.log("onAdd :", doc.path);
await update();
},
async onRemove(path){
console.log("onRemove :", path);
await update();
},
async onChange(doc){
console.log("onModify :", doc.path);
await update();
},
abort: options?.abort,
});
return index;
}
export const search = new Command();
search.name("search")
.description("Search for a document.")
.command("collect", "Collect a document.")
.description("Collect documents and index documents.")
.arguments("<path:string>")
.option("-o, --out <path:string>", "out file to write the index to.", {default: "collected_docs.json"})
.action(async ({out} ,path: string) => {
console.log("collecting", path);
await collectDocuments(path, out);
})
.command("search", "Search for a document.")
.description("Search for a document.")
.arguments("<query:string>")
.option("-d, --docs <path:string>", "collected document file to search", {default: "collected_docs.json"})
.action(async ({docs}, query: string) => {
console.log("searching", query);
const doc_dump = await loadDocuments(docs);
const results = Index.createIndex(doc_dump).search(query);
console.log(results);
})
.command("interact", "watch the index and search for a document.")
.description("watch the index and search for a document.")
.option("-d, --doc <path:string>", "doc file to read the docs from.", {default: "collected_docs.json"})
.action(async ({doc}) => {
console.log("interacting");
const index = await watchDocuments(doc);
// interact
while (true){
const query = await prompt("query: ");
if (query === null){
continue;
}
if (query === ":exit"){
break;
}
const results = index.search(query);
console.log(results);
}
});
if ( import.meta.main ){
await search.parse(Deno.args);
}

31
src/client_search.ts Normal file
View File

@ -0,0 +1,31 @@
//// @deno-types="https://deno.land/x/fuse@v6.4.1/dist/fuse.d.ts"
import Fuse from 'https://deno.land/x/fuse@v6.4.1/dist/fuse.esm.min.js';
import { Doc } from "./collect.ts";
export class Index{
private index: Fuse;
private constructor(index: Fuse){
this.index = index;
}
public setDocs(docs: Doc[]){
this.index.setCollection(docs);
}
public search(query: string): Doc[]{
return this.index.search(query, {limit: 10}).map((
result) =>
result.item as Doc);
}
public static createIndex(docs: Doc[]){
const index = new Fuse(docs,{
keys: ["attributes.title", "attributes.japanese_title", "attributes.tags", "attributes.rjcode", "attributes.author", "path"],
includeScore: true,
includeMatches: true,
})
return new Index(index);
}
}

210
src/collect.ts Normal file
View File

@ -0,0 +1,210 @@
import {join, extname, relative, basename} from "path/mod.ts";
import { readMarkdownDoc } from "./readDoc.ts";
import { Index } from "./client_search.ts";
export interface Doc{
path: string;
content: string;
attributes: {
title?: string;
japanese_title?: string;
tags?: string[];
rjcode?: string;
author?: string;
};
}
export async function loadDocuments(path: string): Promise<Doc[]>{
const doc_json = await Deno.readTextFile(path);
return JSON.parse(doc_json) as Doc[];
}
export interface DocCollectorOptions{
summaryOnly?: boolean;
dropContent?: boolean;
}
export class DocCollector {
private doc_map: Map<string,Doc>;
private options: DocCollectorOptions;
constructor(options: DocCollectorOptions = {}){
this.doc_map = new Map();
this.options = options;
}
public getDocs(): Doc[]{
return [...this.doc_map.values()];
}
public setDoc(doc: Doc){
if (this.options.dropContent){
doc.content = "";
}
this.doc_map.set(doc.path,doc);
}
public setDocs(docs: Doc[]){
for (const doc of docs){
this.setDoc(doc);
}
}
public removeDoc(path: string){
this.doc_map.delete(path);
}
public async walkDir(path: string){
const dir = Deno.readDir(path);
const fileList = [];
for await (const entry of dir){
fileList.push(entry);
}
if (fileList.some((entry) => entry.name === "SUMMARY.md")){
const {content, metadata} = await readMarkdownDoc(join(path, "SUMMARY.md"));
this.setDoc({
path: join(path, "SUMMARY.md"),
content: content,
attributes: metadata,
});
}
else {
for (const entry of fileList){
if (entry.isDirectory){
await this.walkDir(join(path, entry.name));
}
else if (entry.isFile && !this.options.summaryOnly){
const doc = await this.readDoc(join(path, entry.name));
this.setDoc(doc);
}
}
}
}
public async readDoc(path: string): Promise<Doc>{
const ext = extname(path);
if (ext === ".md"){
return await this.readMarkdown(path);
}
else if (ext === ".html" || ext === ".htm" || ext === ".xhtml"){
return await this.readHTML(path);
}
else if (ext === ".txt"){
return await this.readText(path);
}
else {
return {
path: path,
content: "",
attributes: {}
}
}
}
public async readHTML(path: string): Promise<Doc>{
const content = await Deno.readTextFile(path);
return {
path: path,
content: content,
attributes: {},
}
}
public async readText(path: string): Promise<Doc>{
const content = await Deno.readTextFile(path);
return {
path: path,
content: content,
attributes: {},
}
}
public async readMarkdown(path: string): Promise<Doc>{
const {content, metadata} = await readMarkdownDoc(path);
return {
path: path,
content: content,
attributes: metadata,
}
}
async watchDir(path: string, {
onRemove = (_path: string) => {},
onAdd = (_doc: Doc) => {},
onChange = (_doc: Doc) => {},
abort = undefined,
}:{
onRemove?: (path: string) => void | Promise<void>,
onAdd?: (doc: Doc) => void | Promise<void>,
onChange?: (doc: Doc) => void | Promise<void>,
abort?: AbortSignal,
}){
const watcher = Deno.watchFs(path);
if (abort){
abort.addEventListener("abort", () => {
watcher.close();
});
}
for await (const event of watcher){
if (event.kind === "access" || event.kind === "other" || event.kind === "any"){
continue;
}
if (event.paths.length === 0){
continue;
}
for (const path of event.paths){
const relpath = relative(Deno.cwd(), path);
const filename = basename(relpath);
if (filename === "SUMMARY.md"){
if( event.kind === "remove"){
this.doc_map.delete(relpath);
await onRemove(relpath);
}
else if (event.kind === "create" || event.kind === "modify"){
const {content, metadata} = await readMarkdownDoc(relpath);
const doc = {
path: relpath,
content: content,
attributes: metadata,
};
this.setDoc(doc);
if (event.kind === "create"){
await onAdd(doc);
}
else if (event.kind === "modify"){
await onChange(doc);
}
}
}
}
}
}
makeIndex(options? : {
onUpdate?: (() => void) | (() => Promise<void>),
abort?: AbortSignal,
watch?: boolean,
}){
const opt = options ?? {};
const index = Index.createIndex(this.getDocs());
if (!opt.watch){
return index;
}
const update = async () => {
index.setDocs(this.getDocs());
if (opt.onUpdate){
await opt.onUpdate();
}
}
this.watchDir(".", {
async onAdd(_doc){
await update();
},
async onRemove(_path){
await update();
},
async onChange(_doc){
await update();
},
abort: opt.abort,
});
return index;
}
}

60
src/media.ts Normal file
View File

@ -0,0 +1,60 @@
const ICON_MAP: Record<string, string> = {
".pdf": "file-pdf",
".zip": "file-zip",
".rar": "file-zip",
".7z": "file-zip",
".tar": "file-zip",
".gz": "file-zip",
".bz2": "file-zip",
".xz": "file-zip",
".doc": "file-word",
".docx": "file-word",
".xls": "file-excel",
".xlsx": "file-excel",
".ppt": "file-ppt",
".pptx": "file-ppt",
".txt": "file-text",
".md": "filetype-md",
".html": "filetype-html",
".ts": "file-code",
".tsx": "filetype-tsx",
".js": "filetype-js",
".json": "filetype-json",
".jsx": "filetype-jsx",
".css": "filetype-css",
".scss": "filetype-scss",
".csv": "filetype-csv",
".xml": "filetype-xml",
".svg": "filetype-svg",
".mp3": "file-music",
".wav": "file-music",
".ogg": "file-music",
".flac": "file-music",
".mp4": "file-play",
".mkv": "file-play",
".avi": "file-play",
".mov": "file-play",
".wmv": "file-play",
".webm": "file-play",
".mpg": "file-play",
".mpeg": "file-play",
".flv": "file-play",
".m4v": "file-play",
".m4a": "file-play",
".aac": "file-play",
".jpg": "file-image",
".jpeg": "file-image",
".png": "file-image",
".gif": "file-image",
".bmp": "file-image",
".ico": "file-image",
".tiff": "file-image",
".tif": "file-image",
".webp": "file-image",
".psd": "file-image",
}
export function extToIcon(s: string): string{
return `/icon/${(ICON_MAP[s] ?? "file")}.svg`;
}

36
src/readDoc.ts Normal file
View File

@ -0,0 +1,36 @@
import {parse as parseYaml, stringify} from "https://deno.land/std@0.170.0/encoding/yaml.ts";
function trimSubstring(str: string, start: number, end: number) {
while (str[start] === ' ' || str[start] === '\t' || str[start] === '\r' || str[start] === '\n') {
start++;
}
return str.substring(start, end);
}
interface Doc {
metadata: Record<string, string | string[]>;
content: string;
}
export function parse(content: string): Doc {
if(!content.startsWith('---')){
return {
metadata: {},
content: content,
}
}
const index = content.indexOf('\n---', 3);
const meta = content.substring(3, index);
const c = trimSubstring(content, index + 4, content.length);
const metadata = parseYaml(meta) as Record<string, string | string[]>;
return {
metadata: metadata,
content: c,
}
}
export async function readMarkdownDoc(path: string): Promise<Doc> {
const doc = await Deno.readTextFile(path);
return parse(doc);
}

40
src/store/doc.ts Normal file
View File

@ -0,0 +1,40 @@
import { Doc, DocCollector } from "../collect.ts";
export const docCollector = new DocCollector(
{
dropContent: true,
summaryOnly: true,
});
async function prepareDocs() {
const docPath = Deno.env.get("COLLECT_DOC_PATH");
if (!docPath) {
await docCollector.walkDir(".");
return docCollector.makeIndex({
watch: true
});
}
try {
const doc_dump = await Deno.readTextFile(docPath);
const docs = JSON.parse(doc_dump) as Doc[];
docCollector.setDocs(docs);
} catch (error) {
if (error instanceof Deno.errors.NotFound) {
await docCollector.walkDir(".");
await Deno.writeTextFile(docPath, JSON.stringify(docCollector.getDocs()));
}
else {
throw error;
}
}
return docCollector.makeIndex({
watch: true,
onUpdate: async () => {
await Deno.writeTextFile(docPath, JSON.stringify(docCollector.getDocs()));
}
});
}
export const docIndex = await prepareDocs();

13
src/user/db.ts Normal file
View File

@ -0,0 +1,13 @@
import {DB} from 'sqlite';
import {createSchema} from './user.ts';
export function connectDB(): DB {
let DB_path = Deno.env.get("DB_PATH");
if (DB_path === undefined){
Deno.env.set("DB_PATH", "./db.sqlite");
DB_path = "./db.sqlite";
}
let db = new DB(DB_path);
createSchema(db);
return db;
}

65
src/user/user.ts Normal file
View File

@ -0,0 +1,65 @@
import {genSalt, hash, compare} from "bcrypt";
import { DB } from "sqlite";
interface User{
name: string;
salted_password: string;
salt: string;
}
export async function createUser(name: string, password: string){
const salt = await genSalt(10);
const salted_password = await hash(password, salt);
const user: User = {
name: name,
salted_password: salted_password,
salt: salt
}
return user;
}
export async function verifyUser(user: User, password: string){
return await compare(password, user.salted_password);
}
export async function getAllUsers(db :DB): Promise<User[]>{
const users = await db.query<[string, string, string]>
("SELECT name, salted_password, salt FROM users");
return users.map(([name, salted_password, salt])=>({
name,
salted_password,
salt,
}));
}
export async function getUser(db: DB, name: string): Promise<User | undefined>{
const users = await db.query<[string, string, string]>
("SELECT name, salted_password, salt FROM users WHERE name = ?", [name]);
if (users === undefined || users.length === 0){
return undefined;
}
const user = users[0];
return {
name: user[0],
salted_password: user[1],
salt: user[2],
}
}
export async function addUser(db: DB, user: User){
await db.query("INSERT INTO users (name, salted_password, salt) VALUES (?, ?, ?)",
[user.name, user.salted_password, user.salt]);
}
export async function updateUser(db: DB, user: User){
await db.query("UPDATE users SET salted_password = ?, salt = ? WHERE name = ?",
[user.salted_password, user.salt, user.name]);
}
export async function deleteUser(db: DB, name: string){
await db.query("DELETE FROM users WHERE name = ?", [name]);
}
export async function createSchema(db: DB){
await db.query("CREATE TABLE IF NOT EXISTS users (name TEXT PRIMARY KEY, salted_password TEXT, salt TEXT)");
}

BIN
static/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

1036
static/github-markdown.css Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-0-circle-fill" viewBox="0 0 16 16">
<path d="M8 4.951c-1.008 0-1.629 1.09-1.629 2.895v.31c0 1.81.627 2.895 1.629 2.895s1.623-1.09 1.623-2.895v-.31c0-1.8-.621-2.895-1.623-2.895Z"/>
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0Zm-8.012 4.158c1.858 0 2.96-1.582 2.96-3.99V7.84c0-2.426-1.079-3.996-2.936-3.996-1.864 0-2.965 1.588-2.965 3.996v.328c0 2.42 1.09 3.99 2.941 3.99Z"/>
</svg>

After

Width:  |  Height:  |  Size: 479 B

4
static/icon/0-circle.svg Normal file
View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-0-circle" viewBox="0 0 16 16">
<path d="M7.988 12.158c-1.851 0-2.941-1.57-2.941-3.99V7.84c0-2.408 1.101-3.996 2.965-3.996 1.857 0 2.935 1.57 2.935 3.996v.328c0 2.408-1.101 3.99-2.959 3.99ZM8 4.951c-1.008 0-1.629 1.09-1.629 2.895v.31c0 1.81.627 2.895 1.629 2.895s1.623-1.09 1.623-2.895v-.31c0-1.8-.621-2.895-1.623-2.895Z"/>
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0ZM1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8Z"/>
</svg>

After

Width:  |  Height:  |  Size: 511 B

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-0-square-fill" viewBox="0 0 16 16">
<path d="M8 4.951c-1.008 0-1.629 1.09-1.629 2.895v.31c0 1.81.627 2.895 1.629 2.895s1.623-1.09 1.623-2.895v-.31c0-1.8-.621-2.895-1.623-2.895Z"/>
<path d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2Zm5.988 12.158c-1.851 0-2.941-1.57-2.941-3.99V7.84c0-2.408 1.101-3.996 2.965-3.996 1.857 0 2.935 1.57 2.935 3.996v.328c0 2.408-1.101 3.99-2.959 3.99Z"/>
</svg>

After

Width:  |  Height:  |  Size: 518 B

4
static/icon/0-square.svg Normal file
View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-0-square" viewBox="0 0 16 16">
<path d="M7.988 12.158c-1.851 0-2.941-1.57-2.941-3.99V7.84c0-2.408 1.101-3.996 2.965-3.996 1.857 0 2.935 1.57 2.935 3.996v.328c0 2.408-1.101 3.99-2.959 3.99ZM8 4.951c-1.008 0-1.629 1.09-1.629 2.895v.31c0 1.81.627 2.895 1.629 2.895s1.623-1.09 1.623-2.895v-.31c0-1.8-.621-2.895-1.623-2.895Z"/>
<path d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2Zm15 0a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V2Z"/>
</svg>

After

Width:  |  Height:  |  Size: 585 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-1-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0ZM9.283 4.002H7.971L6.072 5.385v1.271l1.834-1.318h.065V12h1.312V4.002Z"/>
</svg>

After

Width:  |  Height:  |  Size: 257 B

3
static/icon/1-circle.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-1-circle" viewBox="0 0 16 16">
<path d="M1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8Zm15 0A8 8 0 1 1 0 8a8 8 0 0 1 16 0ZM9.283 4.002V12H7.971V5.338h-.065L6.072 6.656V5.385l1.899-1.383h1.312Z"/>
</svg>

After

Width:  |  Height:  |  Size: 287 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-1-square-fill" viewBox="0 0 16 16">
<path d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2Zm7.283 4.002V12H7.971V5.338h-.065L6.072 6.656V5.385l1.899-1.383h1.312Z"/>
</svg>

After

Width:  |  Height:  |  Size: 294 B

4
static/icon/1-square.svg Normal file
View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-1-square" viewBox="0 0 16 16">
<path d="M9.283 4.002V12H7.971V5.338h-.065L6.072 6.656V5.385l1.899-1.383h1.312Z"/>
<path d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2Zm15 0a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V2Z"/>
</svg>

After

Width:  |  Height:  |  Size: 376 B

3
static/icon/123.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-123" viewBox="0 0 16 16">
<path d="M2.873 11.297V4.142H1.699L0 5.379v1.137l1.64-1.18h.06v5.961h1.174Zm3.213-5.09v-.063c0-.618.44-1.169 1.196-1.169.676 0 1.174.44 1.174 1.106 0 .624-.42 1.101-.807 1.526L4.99 10.553v.744h4.78v-.99H6.643v-.069L8.41 8.252c.65-.724 1.237-1.332 1.237-2.27C9.646 4.849 8.723 4 7.308 4c-1.573 0-2.36 1.064-2.36 2.15v.057h1.138Zm6.559 1.883h.786c.823 0 1.374.481 1.379 1.179.01.707-.55 1.216-1.421 1.21-.77-.005-1.326-.419-1.379-.953h-1.095c.042 1.053.938 1.918 2.464 1.918 1.478 0 2.642-.839 2.62-2.144-.02-1.143-.922-1.651-1.551-1.714v-.063c.535-.09 1.347-.66 1.326-1.678-.026-1.053-.933-1.855-2.359-1.845-1.5.005-2.317.88-2.348 1.898h1.116c.032-.498.498-.944 1.206-.944.703 0 1.206.435 1.206 1.07.005.64-.504 1.106-1.2 1.106h-.75v.96Z"/>
</svg>

After

Width:  |  Height:  |  Size: 870 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-2-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0ZM6.646 6.24c0-.691.493-1.306 1.336-1.306.756 0 1.313.492 1.313 1.236 0 .697-.469 1.23-.902 1.705l-2.971 3.293V12h5.344v-1.107H7.268v-.077l1.974-2.22.096-.107c.688-.763 1.287-1.428 1.287-2.43 0-1.266-1.031-2.215-2.613-2.215-1.758 0-2.637 1.19-2.637 2.402v.065h1.271v-.07Z"/>
</svg>

After

Width:  |  Height:  |  Size: 458 B

3
static/icon/2-circle.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-2-circle" viewBox="0 0 16 16">
<path d="M1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8Zm15 0A8 8 0 1 1 0 8a8 8 0 0 1 16 0ZM6.646 6.24v.07H5.375v-.064c0-1.213.879-2.402 2.637-2.402 1.582 0 2.613.949 2.613 2.215 0 1.002-.6 1.667-1.287 2.43l-.096.107-1.974 2.22v.077h3.498V12H5.422v-.832l2.97-3.293c.434-.475.903-1.008.903-1.705 0-.744-.557-1.236-1.313-1.236-.843 0-1.336.615-1.336 1.306Z"/>
</svg>

After

Width:  |  Height:  |  Size: 480 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-2-square-fill" viewBox="0 0 16 16">
<path d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2Zm4.646 6.24v.07H5.375v-.064c0-1.213.879-2.402 2.637-2.402 1.582 0 2.613.949 2.613 2.215 0 1.002-.6 1.667-1.287 2.43l-.096.107-1.974 2.22v.077h3.498V12H5.422v-.832l2.97-3.293c.434-.475.903-1.008.903-1.705 0-.744-.557-1.236-1.313-1.236-.843 0-1.336.615-1.336 1.306Z"/>
</svg>

After

Width:  |  Height:  |  Size: 487 B

4
static/icon/2-square.svg Normal file
View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-2-square" viewBox="0 0 16 16">
<path d="M6.646 6.24v.07H5.375v-.064c0-1.213.879-2.402 2.637-2.402 1.582 0 2.613.949 2.613 2.215 0 1.002-.6 1.667-1.287 2.43l-.096.107-1.974 2.22v.077h3.498V12H5.422v-.832l2.97-3.293c.434-.475.903-1.008.903-1.705 0-.744-.557-1.236-1.313-1.236-.843 0-1.336.615-1.336 1.306Z"/>
<path d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2Zm15 0a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V2Z"/>
</svg>

After

Width:  |  Height:  |  Size: 569 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-3-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0Zm-8.082.414c.92 0 1.535.54 1.541 1.318.012.791-.615 1.36-1.588 1.354-.861-.006-1.482-.469-1.54-1.066H5.104c.047 1.177 1.05 2.144 2.754 2.144 1.653 0 2.954-.937 2.93-2.396-.023-1.278-1.031-1.846-1.734-1.916v-.07c.597-.1 1.505-.739 1.482-1.876-.03-1.177-1.043-2.074-2.637-2.062-1.675.006-2.59.984-2.625 2.12h1.248c.036-.556.557-1.054 1.348-1.054.785 0 1.348.486 1.348 1.195.006.715-.563 1.237-1.342 1.237h-.838v1.072h.879Z"/>
</svg>

After

Width:  |  Height:  |  Size: 608 B

4
static/icon/3-circle.svg Normal file
View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-3-circle" viewBox="0 0 16 16">
<path d="M7.918 8.414h-.879V7.342h.838c.78 0 1.348-.522 1.342-1.237 0-.709-.563-1.195-1.348-1.195-.79 0-1.312.498-1.348 1.055H5.275c.036-1.137.95-2.115 2.625-2.121 1.594-.012 2.608.885 2.637 2.062.023 1.137-.885 1.776-1.482 1.875v.07c.703.07 1.71.64 1.734 1.917.024 1.459-1.277 2.396-2.93 2.396-1.705 0-2.707-.967-2.754-2.144H6.33c.059.597.68 1.06 1.541 1.066.973.006 1.6-.563 1.588-1.354-.006-.779-.621-1.318-1.541-1.318Z"/>
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0ZM1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8Z"/>
</svg>

After

Width:  |  Height:  |  Size: 645 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-3-square-fill" viewBox="0 0 16 16">
<path d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2Zm5.918 8.414h-.879V7.342h.838c.78 0 1.348-.522 1.342-1.237 0-.709-.563-1.195-1.348-1.195-.79 0-1.312.498-1.348 1.055H5.275c.036-1.137.95-2.115 2.625-2.121 1.594-.012 2.608.885 2.637 2.062.023 1.137-.885 1.776-1.482 1.875v.07c.703.07 1.71.64 1.734 1.917.024 1.459-1.277 2.396-2.93 2.396-1.705 0-2.707-.967-2.754-2.144H6.33c.059.597.68 1.06 1.541 1.066.973.006 1.6-.563 1.588-1.354-.006-.779-.621-1.318-1.541-1.318Z"/>
</svg>

After

Width:  |  Height:  |  Size: 637 B

4
static/icon/3-square.svg Normal file
View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-3-square" viewBox="0 0 16 16">
<path d="M7.918 8.414h-.879V7.342h.838c.78 0 1.348-.522 1.342-1.237 0-.709-.563-1.195-1.348-1.195-.79 0-1.312.498-1.348 1.055H5.275c.036-1.137.95-2.115 2.625-2.121 1.594-.012 2.608.885 2.637 2.062.023 1.137-.885 1.776-1.482 1.875v.07c.703.07 1.71.64 1.734 1.917.024 1.459-1.277 2.396-2.93 2.396-1.705 0-2.707-.967-2.754-2.144H6.33c.059.597.68 1.06 1.541 1.066.973.006 1.6-.563 1.588-1.354-.006-.779-.621-1.318-1.541-1.318Z"/>
<path d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2Zm15 0a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V2Z"/>
</svg>

After

Width:  |  Height:  |  Size: 719 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-4-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0ZM7.519 5.057c-.886 1.418-1.772 2.838-2.542 4.265v1.12H8.85V12h1.26v-1.559h1.007V9.334H10.11V4.002H8.176c-.218.352-.438.703-.657 1.055ZM6.225 9.281v.053H8.85V5.063h-.065c-.867 1.33-1.787 2.806-2.56 4.218Z"/>
</svg>

After

Width:  |  Height:  |  Size: 391 B

4
static/icon/4-circle.svg Normal file
View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-4-circle" viewBox="0 0 16 16">
<path d="M7.519 5.057c.22-.352.439-.703.657-1.055h1.933v5.332h1.008v1.107H10.11V12H8.85v-1.559H4.978V9.322c.77-1.427 1.656-2.847 2.542-4.265ZM6.225 9.281v.053H8.85V5.063h-.065c-.867 1.33-1.787 2.806-2.56 4.218Z"/>
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0ZM1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8Z"/>
</svg>

After

Width:  |  Height:  |  Size: 433 B

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-4-square-fill" viewBox="0 0 16 16">
<path d="M6.225 9.281v.053H8.85V5.063h-.065c-.867 1.33-1.787 2.806-2.56 4.218Z"/>
<path d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2Zm5.519 5.057c.22-.352.439-.703.657-1.055h1.933v5.332h1.008v1.107H10.11V12H8.85v-1.559H4.978V9.322c.77-1.427 1.656-2.847 2.542-4.265Z"/>
</svg>

After

Width:  |  Height:  |  Size: 440 B

4
static/icon/4-square.svg Normal file
View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-4-square" viewBox="0 0 16 16">
<path d="M7.519 5.057c.22-.352.439-.703.657-1.055h1.933v5.332h1.008v1.107H10.11V12H8.85v-1.559H4.978V9.322c.77-1.427 1.656-2.847 2.542-4.265ZM6.225 9.281v.053H8.85V5.063h-.065c-.867 1.33-1.787 2.806-2.56 4.218Z"/>
<path d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2Zm15 0a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V2Z"/>
</svg>

After

Width:  |  Height:  |  Size: 507 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-5-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0Zm-8.006 4.158c1.74 0 2.924-1.119 2.924-2.806 0-1.641-1.178-2.584-2.56-2.584-.897 0-1.442.421-1.612.68h-.064l.193-2.344h3.621V4.002H5.791L5.445 8.63h1.149c.193-.358.668-.809 1.435-.809.85 0 1.582.604 1.582 1.57 0 1.085-.779 1.682-1.57 1.682-.697 0-1.389-.31-1.53-1.031H5.276c.065 1.213 1.149 2.115 2.72 2.115Z"/>
</svg>

After

Width:  |  Height:  |  Size: 496 B

3
static/icon/5-circle.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-5-circle" viewBox="0 0 16 16">
<path d="M1 8a7 7 0 1 1 14 0A7 7 0 0 1 1 8Zm15 0A8 8 0 1 0 0 8a8 8 0 0 0 16 0Zm-8.006 4.158c-1.57 0-2.654-.902-2.719-2.115h1.237c.14.72.832 1.031 1.529 1.031.791 0 1.57-.597 1.57-1.681 0-.967-.732-1.57-1.582-1.57-.767 0-1.242.45-1.435.808H5.445L5.791 4h4.705v1.103H6.875l-.193 2.343h.064c.17-.258.715-.68 1.611-.68 1.383 0 2.561.944 2.561 2.585 0 1.687-1.184 2.806-2.924 2.806Z"/>
</svg>

After

Width:  |  Height:  |  Size: 516 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-5-square-fill" viewBox="0 0 16 16">
<path d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2Zm5.994 12.158c-1.57 0-2.654-.902-2.719-2.115h1.237c.14.72.832 1.031 1.529 1.031.791 0 1.57-.597 1.57-1.681 0-.967-.732-1.57-1.582-1.57-.767 0-1.242.45-1.435.808H5.445L5.791 4h4.705v1.103H6.875l-.193 2.343h.064c.17-.258.715-.68 1.611-.68 1.383 0 2.561.944 2.561 2.585 0 1.687-1.184 2.806-2.924 2.806Z"/>
</svg>

After

Width:  |  Height:  |  Size: 523 B

4
static/icon/5-square.svg Normal file
View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-5-square" viewBox="0 0 16 16">
<path d="M7.994 12.158c-1.57 0-2.654-.902-2.719-2.115h1.237c.14.72.832 1.031 1.529 1.031.791 0 1.57-.597 1.57-1.681 0-.967-.732-1.57-1.582-1.57-.767 0-1.242.45-1.435.808H5.445L5.791 4h4.705v1.103H6.875l-.193 2.343h.064c.17-.258.715-.68 1.611-.68 1.383 0 2.561.944 2.561 2.585 0 1.687-1.184 2.806-2.924 2.806Z"/>
<path d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2Zm15 0a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V2Z"/>
</svg>

After

Width:  |  Height:  |  Size: 605 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-6-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0ZM8.21 3.855c-1.868 0-3.116 1.395-3.116 4.407 0 1.183.228 2.039.597 2.642.569.926 1.477 1.254 2.409 1.254 1.629 0 2.847-1.013 2.847-2.783 0-1.676-1.254-2.555-2.508-2.555-1.125 0-1.752.61-1.98 1.155h-.082c-.012-1.946.727-3.036 1.805-3.036.802 0 1.213.457 1.312.815h1.29c-.06-.908-.962-1.899-2.573-1.899Zm-.099 4.008c-.92 0-1.564.65-1.564 1.576 0 1.032.703 1.635 1.558 1.635.868 0 1.553-.533 1.553-1.629 0-1.06-.744-1.582-1.547-1.582Z"/>
</svg>

After

Width:  |  Height:  |  Size: 619 B

3
static/icon/6-circle.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-6-circle" viewBox="0 0 16 16">
<path d="M1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8Zm15 0A8 8 0 1 1 0 8a8 8 0 0 1 16 0ZM8.21 3.855c1.612 0 2.515.99 2.573 1.899H9.494c-.1-.358-.51-.815-1.312-.815-1.078 0-1.817 1.09-1.805 3.036h.082c.229-.545.855-1.155 1.98-1.155 1.254 0 2.508.88 2.508 2.555 0 1.77-1.218 2.783-2.847 2.783-.932 0-1.84-.328-2.409-1.254-.369-.603-.597-1.459-.597-2.642 0-3.012 1.248-4.407 3.117-4.407Zm-.099 4.008c-.92 0-1.564.65-1.564 1.576 0 1.032.703 1.635 1.558 1.635.868 0 1.553-.533 1.553-1.629 0-1.06-.744-1.582-1.547-1.582Z"/>
</svg>

After

Width:  |  Height:  |  Size: 643 B

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-6-square-fill" viewBox="0 0 16 16">
<path d="M8.111 7.863c-.92 0-1.564.65-1.564 1.576 0 1.032.703 1.635 1.558 1.635.868 0 1.553-.533 1.553-1.629 0-1.06-.744-1.582-1.547-1.582Z"/>
<path d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2Zm6.21 3.855c1.612 0 2.515.99 2.573 1.899H9.494c-.1-.358-.51-.815-1.312-.815-1.078 0-1.817 1.09-1.805 3.036h.082c.229-.545.855-1.155 1.98-1.155 1.254 0 2.508.88 2.508 2.555 0 1.77-1.218 2.783-2.847 2.783-.932 0-1.84-.328-2.409-1.254-.369-.603-.597-1.459-.597-2.642 0-3.012 1.248-4.407 3.117-4.407Z"/>
</svg>

After

Width:  |  Height:  |  Size: 665 B

4
static/icon/6-square.svg Normal file
View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-6-square" viewBox="0 0 16 16">
<path d="M8.21 3.855c1.612 0 2.515.99 2.573 1.899H9.494c-.1-.358-.51-.815-1.312-.815-1.078 0-1.817 1.09-1.805 3.036h.082c.229-.545.855-1.155 1.98-1.155 1.254 0 2.508.88 2.508 2.555 0 1.77-1.218 2.783-2.847 2.783-.932 0-1.84-.328-2.409-1.254-.369-.603-.597-1.459-.597-2.642 0-3.012 1.248-4.407 3.117-4.407Zm-.099 4.008c-.92 0-1.564.65-1.564 1.576 0 1.032.703 1.635 1.558 1.635.868 0 1.553-.533 1.553-1.629 0-1.06-.744-1.582-1.547-1.582Z"/>
<path d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2Zm15 0a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V2Z"/>
</svg>

After

Width:  |  Height:  |  Size: 732 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-7-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0ZM5.37 5.11h3.972v.07L6.025 12H7.42l3.258-6.85V4.002H5.369v1.107Z"/>
</svg>

After

Width:  |  Height:  |  Size: 252 B

3
static/icon/7-circle.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-7-circle" viewBox="0 0 16 16">
<path d="M1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8Zm15 0A8 8 0 1 1 0 8a8 8 0 0 1 16 0ZM5.37 5.11V4.001h5.308V5.15L7.42 12H6.025l3.317-6.82v-.07H5.369Z"/>
</svg>

After

Width:  |  Height:  |  Size: 281 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-7-square-fill" viewBox="0 0 16 16">
<path d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2Zm3.37 5.11V4.001h5.308V5.15L7.42 12H6.025l3.317-6.82v-.07H5.369Z"/>
</svg>

After

Width:  |  Height:  |  Size: 288 B

4
static/icon/7-square.svg Normal file
View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-7-square" viewBox="0 0 16 16">
<path d="M5.37 5.11V4.001h5.308V5.15L7.42 12H6.025l3.317-6.82v-.07H5.369Z"/>
<path d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2Zm15 0a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V2Z"/>
</svg>

After

Width:  |  Height:  |  Size: 370 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-8-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0Zm-5.03 1.803c0-1.248-.943-1.84-1.646-1.992v-.065c.598-.187 1.336-.72 1.336-1.781 0-1.225-1.084-2.121-2.654-2.121-1.57 0-2.66.896-2.66 2.12 0 1.044.709 1.589 1.33 1.782v.065c-.697.152-1.647.732-1.647 2.003 0 1.39 1.19 2.344 2.953 2.344 1.77 0 2.989-.96 2.989-2.355Zm-4.347-3.71c0 .739.586 1.255 1.383 1.255s1.377-.516 1.377-1.254c0-.733-.58-1.23-1.377-1.23s-1.383.497-1.383 1.23Zm-.281 3.645c0 .838.72 1.412 1.664 1.412.943 0 1.658-.574 1.658-1.412 0-.843-.715-1.424-1.658-1.424-.944 0-1.664.58-1.664 1.424Z"/>
</svg>

After

Width:  |  Height:  |  Size: 694 B

3
static/icon/8-circle.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-8-circle" viewBox="0 0 16 16">
<path d="M1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8Zm15 0A8 8 0 1 1 0 8a8 8 0 0 1 16 0Zm-5.03 1.803c0 1.394-1.218 2.355-2.988 2.355-1.763 0-2.953-.955-2.953-2.344 0-1.271.95-1.851 1.647-2.003v-.065c-.621-.193-1.33-.738-1.33-1.781 0-1.225 1.09-2.121 2.66-2.121s2.654.896 2.654 2.12c0 1.061-.738 1.595-1.336 1.782v.065c.703.152 1.647.744 1.647 1.992Zm-4.347-3.71c0 .739.586 1.255 1.383 1.255s1.377-.516 1.377-1.254c0-.733-.58-1.23-1.377-1.23s-1.383.497-1.383 1.23Zm-.281 3.645c0 .838.72 1.412 1.664 1.412.943 0 1.658-.574 1.658-1.412 0-.843-.715-1.424-1.658-1.424-.944 0-1.664.58-1.664 1.424Z"/>
</svg>

After

Width:  |  Height:  |  Size: 720 B

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-8-square-fill" viewBox="0 0 16 16">
<path d="M6.623 6.094c0 .738.586 1.254 1.383 1.254s1.377-.516 1.377-1.254c0-.733-.58-1.23-1.377-1.23s-1.383.497-1.383 1.23Zm-.281 3.644c0 .838.72 1.412 1.664 1.412.943 0 1.658-.574 1.658-1.412 0-.843-.715-1.424-1.658-1.424-.944 0-1.664.58-1.664 1.424Z"/>
<path d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2Zm8.97 9.803c0 1.394-1.218 2.355-2.988 2.355-1.763 0-2.953-.955-2.953-2.344 0-1.271.95-1.851 1.647-2.003v-.065c-.621-.193-1.33-.738-1.33-1.781 0-1.225 1.09-2.121 2.66-2.121s2.654.896 2.654 2.12c0 1.061-.738 1.595-1.336 1.782v.065c.703.152 1.647.744 1.647 1.992Z"/>
</svg>

After

Width:  |  Height:  |  Size: 741 B

4
static/icon/8-square.svg Normal file
View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-8-square" viewBox="0 0 16 16">
<path d="M10.97 9.803c0 1.394-1.218 2.355-2.988 2.355-1.763 0-2.953-.955-2.953-2.344 0-1.271.95-1.851 1.647-2.003v-.065c-.621-.193-1.33-.738-1.33-1.781 0-1.225 1.09-2.121 2.66-2.121s2.654.896 2.654 2.12c0 1.061-.738 1.595-1.336 1.782v.065c.703.152 1.647.744 1.647 1.992Zm-4.347-3.71c0 .739.586 1.255 1.383 1.255s1.377-.516 1.377-1.254c0-.733-.58-1.23-1.377-1.23s-1.383.497-1.383 1.23Zm-.281 3.645c0 .838.72 1.412 1.664 1.412.943 0 1.658-.574 1.658-1.412 0-.843-.715-1.424-1.658-1.424-.944 0-1.664.58-1.664 1.424Z"/>
<path d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2Zm15 0a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V2Z"/>
</svg>

After

Width:  |  Height:  |  Size: 809 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-9-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0Zm-8.223 4.146c2.104 0 3.123-1.464 3.123-4.3 0-3.147-1.459-4.014-2.97-4.014-1.63 0-2.871 1.02-2.871 2.73 0 1.706 1.171 2.667 2.566 2.667 1.06 0 1.7-.557 1.934-1.184h.076c.047 1.67-.475 3.023-1.834 3.023-.71 0-1.149-.363-1.248-.72H5.258c.094.908.926 1.798 2.52 1.798Zm.118-3.972c.808 0 1.535-.528 1.535-1.594s-.668-1.676-1.56-1.676c-.838 0-1.517.616-1.517 1.659 0 1.072.708 1.61 1.54 1.61Z"/>
</svg>

After

Width:  |  Height:  |  Size: 575 B

3
static/icon/9-circle.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-9-circle" viewBox="0 0 16 16">
<path d="M1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8Zm15 0A8 8 0 1 1 0 8a8 8 0 0 1 16 0Zm-8.223 4.146c-1.593 0-2.425-.89-2.52-1.798h1.296c.1.357.539.72 1.248.72 1.36 0 1.88-1.353 1.834-3.023h-.076c-.235.627-.873 1.184-1.934 1.184-1.395 0-2.566-.961-2.566-2.666 0-1.711 1.242-2.731 2.87-2.731 1.512 0 2.971.867 2.971 4.014 0 2.836-1.02 4.3-3.123 4.3Zm.118-3.972c.808 0 1.535-.528 1.535-1.594s-.668-1.676-1.56-1.676c-.838 0-1.517.616-1.517 1.659 0 1.072.708 1.61 1.54 1.61Z"/>
</svg>

After

Width:  |  Height:  |  Size: 600 B

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-9-square-fill" viewBox="0 0 16 16">
<path d="M7.895 8.174c.808 0 1.535-.528 1.535-1.594s-.668-1.676-1.56-1.676c-.838 0-1.517.616-1.517 1.659 0 1.072.708 1.61 1.54 1.61Z"/>
<path d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2Zm5.777 12.146c-1.593 0-2.425-.89-2.52-1.798h1.296c.1.357.539.72 1.248.72 1.36 0 1.88-1.353 1.834-3.023h-.076c-.235.627-.873 1.184-1.934 1.184-1.395 0-2.566-.961-2.566-2.666 0-1.711 1.242-2.731 2.87-2.731 1.512 0 2.971.867 2.971 4.014 0 2.836-1.02 4.3-3.123 4.3Z"/>
</svg>

After

Width:  |  Height:  |  Size: 623 B

4
static/icon/9-square.svg Normal file
View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-9-square" viewBox="0 0 16 16">
<path d="M7.777 12.146c-1.593 0-2.425-.89-2.52-1.798h1.296c.1.357.539.72 1.248.72 1.36 0 1.88-1.353 1.834-3.023h-.076c-.235.627-.873 1.184-1.934 1.184-1.395 0-2.566-.961-2.566-2.666 0-1.711 1.242-2.731 2.87-2.731 1.512 0 2.971.867 2.971 4.014 0 2.836-1.02 4.3-3.123 4.3Zm.118-3.972c.808 0 1.535-.528 1.535-1.594s-.668-1.676-1.56-1.676c-.838 0-1.517.616-1.517 1.659 0 1.072.708 1.61 1.54 1.61Z"/>
<path d="M0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2Zm15 0a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V2Z"/>
</svg>

After

Width:  |  Height:  |  Size: 689 B

3
static/icon/activity.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-activity" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M6 2a.5.5 0 0 1 .47.33L10 12.036l1.53-4.208A.5.5 0 0 1 12 7.5h3.5a.5.5 0 0 1 0 1h-3.15l-1.88 5.17a.5.5 0 0 1-.94 0L6 3.964 4.47 8.171A.5.5 0 0 1 4 8.5H.5a.5.5 0 0 1 0-1h3.15l1.88-5.17A.5.5 0 0 1 6 2Z"/>
</svg>

After

Width:  |  Height:  |  Size: 367 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-airplane-engines-fill" viewBox="0 0 16 16">
<path d="M8 0c-.787 0-1.292.592-1.572 1.151A4.347 4.347 0 0 0 6 3v3.691l-2 1V7.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.191l-1.17.585A1.5 1.5 0 0 0 0 10.618V12a.5.5 0 0 0 .582.493l1.631-.272.313.937a.5.5 0 0 0 .948 0l.405-1.214 2.21-.369.375 2.253-1.318 1.318A.5.5 0 0 0 5.5 16h5a.5.5 0 0 0 .354-.854l-1.318-1.318.375-2.253 2.21.369.405 1.214a.5.5 0 0 0 .948 0l.313-.937 1.63.272A.5.5 0 0 0 16 12v-1.382a1.5 1.5 0 0 0-.83-1.342L14 8.691V7.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v.191l-2-1V3c0-.568-.14-1.271-.428-1.849C9.292.591 8.787 0 8 0Z"/>
</svg>

After

Width:  |  Height:  |  Size: 690 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-airplane-engines" viewBox="0 0 16 16">
<path d="M8 0c-.787 0-1.292.592-1.572 1.151A4.347 4.347 0 0 0 6 3v3.691l-2 1V7.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.191l-1.17.585A1.5 1.5 0 0 0 0 10.618V12a.5.5 0 0 0 .582.493l1.631-.272.313.937a.5.5 0 0 0 .948 0l.405-1.214 2.21-.369.375 2.253-1.318 1.318A.5.5 0 0 0 5.5 16h5a.5.5 0 0 0 .354-.854l-1.318-1.318.375-2.253 2.21.369.405 1.214a.5.5 0 0 0 .948 0l.313-.937 1.63.272A.5.5 0 0 0 16 12v-1.382a1.5 1.5 0 0 0-.83-1.342L14 8.691V7.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v.191l-2-1V3c0-.568-.14-1.271-.428-1.849C9.292.591 8.787 0 8 0ZM7 3c0-.432.11-.979.322-1.401C7.542 1.159 7.787 1 8 1c.213 0 .458.158.678.599C8.889 2.02 9 2.569 9 3v4a.5.5 0 0 0 .276.447l5.448 2.724a.5.5 0 0 1 .276.447v.792l-5.418-.903a.5.5 0 0 0-.575.41l-.5 3a.5.5 0 0 0 .14.437l.646.646H6.707l.647-.646a.5.5 0 0 0 .14-.436l-.5-3a.5.5 0 0 0-.576-.411L1 11.41v-.792a.5.5 0 0 1 .276-.447l5.448-2.724A.5.5 0 0 0 7 7V3Z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-airplane-fill" viewBox="0 0 16 16">
<path d="M6.428 1.151C6.708.591 7.213 0 8 0s1.292.592 1.572 1.151C9.861 1.73 10 2.431 10 3v3.691l5.17 2.585a1.5 1.5 0 0 1 .83 1.342V12a.5.5 0 0 1-.582.493l-5.507-.918-.375 2.253 1.318 1.318A.5.5 0 0 1 10.5 16h-5a.5.5 0 0 1-.354-.854l1.319-1.318-.376-2.253-5.507.918A.5.5 0 0 1 0 12v-1.382a1.5 1.5 0 0 1 .83-1.342L6 6.691V3c0-.568.14-1.271.428-1.849Z"/>
</svg>

After

Width:  |  Height:  |  Size: 493 B

3
static/icon/airplane.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-airplane" viewBox="0 0 16 16">
<path d="M6.428 1.151C6.708.591 7.213 0 8 0s1.292.592 1.572 1.151C9.861 1.73 10 2.431 10 3v3.691l5.17 2.585a1.5 1.5 0 0 1 .83 1.342V12a.5.5 0 0 1-.582.493l-5.507-.918-.375 2.253 1.318 1.318A.5.5 0 0 1 10.5 16h-5a.5.5 0 0 1-.354-.854l1.319-1.318-.376-2.253-5.507.918A.5.5 0 0 1 0 12v-1.382a1.5 1.5 0 0 1 .83-1.342L6 6.691V3c0-.568.14-1.271.428-1.849Zm.894.448C7.111 2.02 7 2.569 7 3v4a.5.5 0 0 1-.276.447l-5.448 2.724a.5.5 0 0 0-.276.447v.792l5.418-.903a.5.5 0 0 1 .575.41l.5 3a.5.5 0 0 1-.14.437L6.708 15h2.586l-.647-.646a.5.5 0 0 1-.14-.436l.5-3a.5.5 0 0 1 .576-.411L15 11.41v-.792a.5.5 0 0 0-.276-.447L9.276 7.447A.5.5 0 0 1 9 7V3c0-.432-.11-.979-.322-1.401C8.458 1.159 8.213 1 8 1c-.213 0-.458.158-.678.599Z"/>
</svg>

After

Width:  |  Height:  |  Size: 849 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-alarm-fill" viewBox="0 0 16 16">
<path d="M6 .5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1H9v1.07a7.001 7.001 0 0 1 3.274 12.474l.601.602a.5.5 0 0 1-.707.708l-.746-.746A6.97 6.97 0 0 1 8 16a6.97 6.97 0 0 1-3.422-.892l-.746.746a.5.5 0 0 1-.707-.708l.602-.602A7.001 7.001 0 0 1 7 2.07V1h-.5A.5.5 0 0 1 6 .5zm2.5 5a.5.5 0 0 0-1 0v3.362l-1.429 2.38a.5.5 0 1 0 .858.515l1.5-2.5A.5.5 0 0 0 8.5 9V5.5zM.86 5.387A2.5 2.5 0 1 1 4.387 1.86 8.035 8.035 0 0 0 .86 5.387zM11.613 1.86a2.5 2.5 0 1 1 3.527 3.527 8.035 8.035 0 0 0-3.527-3.527z"/>
</svg>

After

Width:  |  Height:  |  Size: 626 B

4
static/icon/alarm.svg Normal file
View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-alarm" viewBox="0 0 16 16">
<path d="M8.5 5.5a.5.5 0 0 0-1 0v3.362l-1.429 2.38a.5.5 0 1 0 .858.515l1.5-2.5A.5.5 0 0 0 8.5 9V5.5z"/>
<path d="M6.5 0a.5.5 0 0 0 0 1H7v1.07a7.001 7.001 0 0 0-3.273 12.474l-.602.602a.5.5 0 0 0 .707.708l.746-.746A6.97 6.97 0 0 0 8 16a6.97 6.97 0 0 0 3.422-.892l.746.746a.5.5 0 0 0 .707-.708l-.601-.602A7.001 7.001 0 0 0 9 2.07V1h.5a.5.5 0 0 0 0-1h-3zm1.038 3.018a6.093 6.093 0 0 1 .924 0 6 6 0 1 1-.924 0zM0 3.5c0 .753.333 1.429.86 1.887A8.035 8.035 0 0 1 4.387 1.86 2.5 2.5 0 0 0 0 3.5zM13.5 1c-.753 0-1.429.333-1.887.86a8.035 8.035 0 0 1 3.527 3.527A2.5 2.5 0 0 0 13.5 1z"/>
</svg>

After

Width:  |  Height:  |  Size: 711 B

3
static/icon/alexa.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-alexa" viewBox="0 0 16 16">
<path d="M7.996 0A7.998 7.998 0 0 0 0 8a8 8 0 0 0 6.93 7.93v-1.613a1.06 1.06 0 0 0-.717-1.008A5.602 5.602 0 0 1 2.4 7.865 5.579 5.579 0 0 1 8.054 2.4a5.599 5.599 0 0 1 5.535 5.81l-.002.046a6.116 6.116 0 0 1-.012.192l-.005.061a4.85 4.85 0 0 1-.033.284l-.01.068c-.685 4.516-6.564 7.054-6.596 7.068A7.998 7.998 0 0 0 15.992 8 7.998 7.998 0 0 0 7.996.001Z"/>
</svg>

After

Width:  |  Height:  |  Size: 487 B

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-align-bottom" viewBox="0 0 16 16">
<rect width="4" height="12" x="6" y="1" rx="1"/>
<path d="M1.5 14a.5.5 0 0 0 0 1v-1zm13 1a.5.5 0 0 0 0-1v1zm-13 0h13v-1h-13v1z"/>
</svg>

After

Width:  |  Height:  |  Size: 271 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-align-center" viewBox="0 0 16 16">
<path d="M8 1a.5.5 0 0 1 .5.5V6h-1V1.5A.5.5 0 0 1 8 1zm0 14a.5.5 0 0 1-.5-.5V10h1v4.5a.5.5 0 0 1-.5.5zM2 7a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V7z"/>
</svg>

After

Width:  |  Height:  |  Size: 315 B

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-align-end" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M14.5 1a.5.5 0 0 0-.5.5v13a.5.5 0 0 0 1 0v-13a.5.5 0 0 0-.5-.5z"/>
<path d="M13 7a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1V7z"/>
</svg>

After

Width:  |  Height:  |  Size: 318 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-align-middle" viewBox="0 0 16 16">
<path d="M6 13a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1H7a1 1 0 0 0-1 1v10zM1 8a.5.5 0 0 0 .5.5H6v-1H1.5A.5.5 0 0 0 1 8zm14 0a.5.5 0 0 1-.5.5H10v-1h4.5a.5.5 0 0 1 .5.5z"/>
</svg>

After

Width:  |  Height:  |  Size: 316 B

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-align-start" viewBox="0 0 16 16">
<path fill-rule="evenodd" d="M1.5 1a.5.5 0 0 1 .5.5v13a.5.5 0 0 1-1 0v-13a.5.5 0 0 1 .5-.5z"/>
<path d="M3 7a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v2a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V7z"/>
</svg>

After

Width:  |  Height:  |  Size: 318 B

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-align-top" viewBox="0 0 16 16">
<rect width="4" height="12" rx="1" transform="matrix(1 0 0 -1 6 15)"/>
<path d="M1.5 2a.5.5 0 0 1 0-1v1zm13-1a.5.5 0 0 1 0 1V1zm-13 0h13v1h-13V1z"/>
</svg>

After

Width:  |  Height:  |  Size: 287 B

4
static/icon/alipay.svg Normal file
View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-alipay" viewBox="0 0 16 16">
<path d="M2.541 0H13.5a2.551 2.551 0 0 1 2.54 2.563v8.297c-.006 0-.531-.046-2.978-.813-.412-.14-.916-.327-1.479-.536-.303-.113-.624-.232-.957-.353a12.98 12.98 0 0 0 1.325-3.373H8.822V4.649h3.831v-.634h-3.83V2.121H7.26c-.274 0-.274.273-.274.273v1.621H3.11v.634h3.875v1.136h-3.2v.634H9.99c-.227.789-.532 1.53-.894 2.202-2.013-.67-4.161-1.212-5.51-.878-.864.214-1.42.597-1.746.998-1.499 1.84-.424 4.633 2.741 4.633 1.872 0 3.675-1.053 5.072-2.787 2.08 1.008 6.37 2.738 6.387 2.745v.105A2.551 2.551 0 0 1 13.5 16H2.541A2.552 2.552 0 0 1 0 13.437V2.563A2.552 2.552 0 0 1 2.541 0Z"/>
<path d="M2.309 9.27c-1.22 1.073-.49 3.034 1.978 3.034 1.434 0 2.868-.925 3.994-2.406-1.602-.789-2.959-1.353-4.425-1.207-.397.04-1.14.217-1.547.58Z"/>
</svg>

After

Width:  |  Height:  |  Size: 864 B

3
static/icon/alt.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-alt" viewBox="0 0 16 16">
<path d="M1 13.5a.5.5 0 0 0 .5.5h3.797a.5.5 0 0 0 .439-.26L11 3h3.5a.5.5 0 0 0 0-1h-3.797a.5.5 0 0 0-.439.26L5 13H1.5a.5.5 0 0 0-.5.5zm10 0a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 0-1h-3a.5.5 0 0 0-.5.5z"/>
</svg>

After

Width:  |  Height:  |  Size: 326 B

3
static/icon/amd.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-amd" viewBox="0 0 16 16">
<path d="m.334 0 4.358 4.359h7.15v7.15l4.358 4.358V0H.334ZM.2 9.72l4.487-4.488v6.281h6.28L6.48 16H.2V9.72Z"/>
</svg>

After

Width:  |  Height:  |  Size: 240 B

3
static/icon/android.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-android" viewBox="0 0 16 16">
<path d="M2.76 3.061a.5.5 0 0 1 .679.2l1.283 2.352A8.94 8.94 0 0 1 8 5a8.94 8.94 0 0 1 3.278.613l1.283-2.352a.5.5 0 1 1 .878.478l-1.252 2.295C14.475 7.266 16 9.477 16 12H0c0-2.523 1.525-4.734 3.813-5.966L2.56 3.74a.5.5 0 0 1 .2-.678ZM5 10a1 1 0 1 0 0-2 1 1 0 0 0 0 2Zm6 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z"/>
</svg>

After

Width:  |  Height:  |  Size: 438 B

3
static/icon/android2.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-android2" viewBox="0 0 16 16">
<path d="m10.213 1.471.691-1.26c.046-.083.03-.147-.048-.192-.085-.038-.15-.019-.195.058l-.7 1.27A4.832 4.832 0 0 0 8.005.941c-.688 0-1.34.135-1.956.404l-.7-1.27C5.303 0 5.239-.018 5.154.02c-.078.046-.094.11-.049.193l.691 1.259a4.25 4.25 0 0 0-1.673 1.476A3.697 3.697 0 0 0 3.5 5.02h9c0-.75-.208-1.44-.623-2.072a4.266 4.266 0 0 0-1.664-1.476ZM6.22 3.303a.367.367 0 0 1-.267.11.35.35 0 0 1-.263-.11.366.366 0 0 1-.107-.264.37.37 0 0 1 .107-.265.351.351 0 0 1 .263-.11c.103 0 .193.037.267.11a.36.36 0 0 1 .112.265.36.36 0 0 1-.112.264Zm4.101 0a.351.351 0 0 1-.262.11.366.366 0 0 1-.268-.11.358.358 0 0 1-.112-.264c0-.103.037-.191.112-.265a.367.367 0 0 1 .268-.11c.104 0 .19.037.262.11a.367.367 0 0 1 .107.265c0 .102-.035.19-.107.264ZM3.5 11.77c0 .294.104.544.311.75.208.204.46.307.76.307h.758l.01 2.182c0 .276.097.51.292.703a.961.961 0 0 0 .7.288.973.973 0 0 0 .71-.288.95.95 0 0 0 .292-.703v-2.182h1.343v2.182c0 .276.097.51.292.703a.972.972 0 0 0 .71.288.973.973 0 0 0 .71-.288.95.95 0 0 0 .292-.703v-2.182h.76c.291 0 .54-.103.749-.308.207-.205.311-.455.311-.75V5.365h-9v6.404Zm10.495-6.587a.983.983 0 0 0-.702.278.91.91 0 0 0-.293.685v4.063c0 .271.098.501.293.69a.97.97 0 0 0 .702.284c.28 0 .517-.095.712-.284a.924.924 0 0 0 .293-.69V6.146a.91.91 0 0 0-.293-.685.995.995 0 0 0-.712-.278Zm-12.702.283a.985.985 0 0 1 .712-.283c.273 0 .507.094.702.283a.913.913 0 0 1 .293.68v4.063a.932.932 0 0 1-.288.69.97.97 0 0 1-.707.284.986.986 0 0 1-.712-.284.924.924 0 0 1-.293-.69V6.146c0-.264.098-.491.293-.68Z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-app-indicator" viewBox="0 0 16 16">
<path d="M5.5 2A3.5 3.5 0 0 0 2 5.5v5A3.5 3.5 0 0 0 5.5 14h5a3.5 3.5 0 0 0 3.5-3.5V8a.5.5 0 0 1 1 0v2.5a4.5 4.5 0 0 1-4.5 4.5h-5A4.5 4.5 0 0 1 1 10.5v-5A4.5 4.5 0 0 1 5.5 1H8a.5.5 0 0 1 0 1H5.5z"/>
<path d="M16 3a3 3 0 1 1-6 0 3 3 0 0 1 6 0z"/>
</svg>

After

Width:  |  Height:  |  Size: 387 B

Some files were not shown because too many files have changed in this diff Show More