Compare commits

...

13 commits

Author SHA1 Message Date
b316680114 breadcrumbs
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2023-08-29 20:50:09 -03:00
e3b2edd214 format 2023-08-29 11:05:34 -03:00
559f107b14 mejorar pagepicker 2023-08-29 11:05:12 -03:00
b8f3f3e2ae más styles+modo oscuro 2023-08-29 10:39:59 -03:00
5dc140a456 usar Tailwind Typography 2023-08-29 10:00:53 -03:00
b86139622c tailwind chooseworld 2023-08-28 10:51:20 -03:00
964bd059c3 dejar index en historial al cargar automaticmaente pagina 2023-08-28 10:46:21 -03:00
178b9f3c28 prettier svelte 2023-08-28 10:40:09 -03:00
fb1ca46b17 usar tailwind 2023-08-28 10:39:04 -03:00
60ceb8c63c limpiar css/incorporar tailwind 2023-08-28 10:38:39 -03:00
9f1e5bcb60 prettier, tailwind 2023-08-28 10:35:05 -03:00
3891471975 usar mejor font-family 2023-08-28 10:26:27 -03:00
0f33952aca chore: traer tailwind 2023-08-28 10:25:36 -03:00
29 changed files with 684 additions and 144 deletions

View file

@ -1,10 +1,14 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="theme-color" content="#18181b" media="(prefers-color-scheme: dark)"> <meta
<meta name="theme-color" content="#ffffff"> name="theme-color"
content="#18181b"
media="(prefers-color-scheme: dark)"
/>
<meta name="theme-color" content="#ffffff" />
<link rel="manifest" href="/manifest.webmanifest" /> <link rel="manifest" href="/manifest.webmanifest" />
<link rel="icon" href="/edit-2-outline.svg" /> <link rel="icon" href="/edit-2-outline.svg" />
<link <link
@ -15,8 +19,8 @@
/> />
<title>Schreiben</title> <title>Schreiben</title>
</head> </head>
<body> <body class="min-h-screen bg-slate-50 dark:bg-neutral-900">
<div id="app"></div> <div id="app" class="min-h-screen"></div>
<script type="module" src="/src/main.ts"></script> <script type="module" src="/src/main.ts"></script>
</body> </body>
</html> </html>

View file

@ -8,13 +8,20 @@
"build": "vite build", "build": "vite build",
"preview": "vite preview", "preview": "vite preview",
"check": "svelte-check --tsconfig ./tsconfig.json", "check": "svelte-check --tsconfig ./tsconfig.json",
"upload": "scp -CrP993 dist/* root@nulo.in:/var/www/beta.schreiben.nulo.ar/" "upload": "scp -CrP993 dist/* root@nulo.in:/var/www/beta.schreiben.nulo.ar/",
"format": "prettier --write src/"
}, },
"devDependencies": { "devDependencies": {
"@poppanator/sveltekit-svg": "^2.1.2", "@poppanator/sveltekit-svg": "^2.1.2",
"@sveltejs/vite-plugin-svelte": "^2.0.4", "@sveltejs/vite-plugin-svelte": "^2.0.4",
"@tailwindcss/typography": "^0.5.9",
"@tsconfig/svelte": "^3.0.0", "@tsconfig/svelte": "^3.0.0",
"@vitejs/plugin-basic-ssl": "^1.0.1", "@vitejs/plugin-basic-ssl": "^1.0.1",
"autoprefixer": "^10.4.15",
"postcss": "^8.4.28",
"prettier": "^3.0.2",
"prettier-plugin-svelte": "^3.0.3",
"prettier-plugin-tailwindcss": "^0.5.3",
"prosemirror-commands": "~1.3.1", "prosemirror-commands": "~1.3.1",
"prosemirror-dropcursor": "~1.6.1", "prosemirror-dropcursor": "~1.6.1",
"prosemirror-gapcursor": "~1.3.1", "prosemirror-gapcursor": "~1.3.1",
@ -29,6 +36,7 @@
"prosemirror-view": "~1.29.2", "prosemirror-view": "~1.29.2",
"svelte": "^3.58.0", "svelte": "^3.58.0",
"svelte-check": "^2.10.3", "svelte-check": "^2.10.3",
"tailwindcss": "^3.3.3",
"tslib": "^2.5.0", "tslib": "^2.5.0",
"typescript": "^4.9.5", "typescript": "^4.9.5",
"vite": "^4.2.2" "vite": "^4.2.2"

View file

@ -46,12 +46,30 @@ devDependencies:
'@sveltejs/vite-plugin-svelte': '@sveltejs/vite-plugin-svelte':
specifier: ^2.0.4 specifier: ^2.0.4
version: 2.0.4(svelte@3.58.0)(vite@4.2.2) version: 2.0.4(svelte@3.58.0)(vite@4.2.2)
'@tailwindcss/typography':
specifier: ^0.5.9
version: 0.5.9(tailwindcss@3.3.3)
'@tsconfig/svelte': '@tsconfig/svelte':
specifier: ^3.0.0 specifier: ^3.0.0
version: 3.0.0 version: 3.0.0
'@vitejs/plugin-basic-ssl': '@vitejs/plugin-basic-ssl':
specifier: ^1.0.1 specifier: ^1.0.1
version: 1.0.1(vite@4.2.2) version: 1.0.1(vite@4.2.2)
autoprefixer:
specifier: ^10.4.15
version: 10.4.15(postcss@8.4.28)
postcss:
specifier: ^8.4.28
version: 8.4.28
prettier:
specifier: ^3.0.2
version: 3.0.2
prettier-plugin-svelte:
specifier: ^3.0.3
version: 3.0.3(prettier@3.0.2)(svelte@3.58.0)
prettier-plugin-tailwindcss:
specifier: ^0.5.3
version: 0.5.3(prettier-plugin-svelte@3.0.3)(prettier@3.0.2)
prosemirror-commands: prosemirror-commands:
specifier: ~1.3.1 specifier: ~1.3.1
version: 1.3.1 version: 1.3.1
@ -93,7 +111,10 @@ devDependencies:
version: 3.58.0 version: 3.58.0
svelte-check: svelte-check:
specifier: ^2.10.3 specifier: ^2.10.3
version: 2.10.3(svelte@3.58.0) version: 2.10.3(postcss@8.4.28)(svelte@3.58.0)
tailwindcss:
specifier: ^3.3.3
version: 3.3.3
tslib: tslib:
specifier: ^2.5.0 specifier: ^2.5.0
version: 2.5.0 version: 2.5.0
@ -106,6 +127,11 @@ devDependencies:
packages: packages:
/@alloc/quick-lru@5.2.0:
resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
engines: {node: '>=10'}
dev: true
/@esbuild/android-arm64@0.17.17: /@esbuild/android-arm64@0.17.17:
resolution: {integrity: sha512-jaJ5IlmaDLFPNttv0ofcwy/cfeY4bh/n705Tgh+eLObbGtQBK3EPAu+CzL95JVE4nFAliyrnEu0d32Q5foavqg==} resolution: {integrity: sha512-jaJ5IlmaDLFPNttv0ofcwy/cfeY4bh/n705Tgh+eLObbGtQBK3EPAu+CzL95JVE4nFAliyrnEu0d32Q5foavqg==}
engines: {node: '>=12'} engines: {node: '>=12'}
@ -304,11 +330,25 @@ packages:
dev: true dev: true
optional: true optional: true
/@jridgewell/gen-mapping@0.3.3:
resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==}
engines: {node: '>=6.0.0'}
dependencies:
'@jridgewell/set-array': 1.1.2
'@jridgewell/sourcemap-codec': 1.4.15
'@jridgewell/trace-mapping': 0.3.18
dev: true
/@jridgewell/resolve-uri@3.1.0: /@jridgewell/resolve-uri@3.1.0:
resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==}
engines: {node: '>=6.0.0'} engines: {node: '>=6.0.0'}
dev: true dev: true
/@jridgewell/set-array@1.1.2:
resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==}
engines: {node: '>=6.0.0'}
dev: true
/@jridgewell/sourcemap-codec@1.4.14: /@jridgewell/sourcemap-codec@1.4.14:
resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==}
dev: true dev: true
@ -375,6 +415,18 @@ packages:
- supports-color - supports-color
dev: true dev: true
/@tailwindcss/typography@0.5.9(tailwindcss@3.3.3):
resolution: {integrity: sha512-t8Sg3DyynFysV9f4JDOVISGsjazNb48AeIYQwcL+Bsq5uf4RYL75C1giZ43KISjeDGBaTN3Kxh7Xj/vRSMJUUg==}
peerDependencies:
tailwindcss: '>=3.0.0 || insiders'
dependencies:
lodash.castarray: 4.4.0
lodash.isplainobject: 4.0.6
lodash.merge: 4.6.2
postcss-selector-parser: 6.0.10
tailwindcss: 3.3.3
dev: true
/@trysound/sax@0.2.0: /@trysound/sax@0.2.0:
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
engines: {node: '>=10.13.0'} engines: {node: '>=10.13.0'}
@ -404,6 +456,10 @@ packages:
vite: 4.2.2 vite: 4.2.2
dev: true dev: true
/any-promise@1.3.0:
resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
dev: true
/anymatch@3.1.3: /anymatch@3.1.3:
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
engines: {node: '>= 8'} engines: {node: '>= 8'}
@ -412,10 +468,30 @@ packages:
picomatch: 2.3.1 picomatch: 2.3.1
dev: true dev: true
/arg@5.0.2:
resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
dev: true
/argparse@2.0.1: /argparse@2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
dev: true dev: true
/autoprefixer@10.4.15(postcss@8.4.28):
resolution: {integrity: sha512-KCuPB8ZCIqFdA4HwKXsvz7j6gvSDNhDP7WnUjBleRkKjPdvCmHFuQ77ocavI8FT6NdvlBnE2UFr2H4Mycn8Vew==}
engines: {node: ^10 || ^12 || >=14}
hasBin: true
peerDependencies:
postcss: ^8.1.0
dependencies:
browserslist: 4.21.10
caniuse-lite: 1.0.30001524
fraction.js: 4.2.1
normalize-range: 0.1.2
picocolors: 1.0.0
postcss: 8.4.28
postcss-value-parser: 4.2.0
dev: true
/balanced-match@1.0.2: /balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
dev: true dev: true
@ -451,6 +527,17 @@ packages:
fill-range: 7.0.1 fill-range: 7.0.1
dev: true dev: true
/browserslist@4.21.10:
resolution: {integrity: sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==}
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
dependencies:
caniuse-lite: 1.0.30001524
electron-to-chromium: 1.4.503
node-releases: 2.0.13
update-browserslist-db: 1.0.11(browserslist@4.21.10)
dev: true
/buffer-crc32@0.2.13: /buffer-crc32@0.2.13:
resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==}
dev: true dev: true
@ -467,6 +554,15 @@ packages:
engines: {node: '>=6'} engines: {node: '>=6'}
dev: true dev: true
/camelcase-css@2.0.1:
resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
engines: {node: '>= 6'}
dev: true
/caniuse-lite@1.0.30001524:
resolution: {integrity: sha512-Jj917pJtYg9HSJBF95HVX3Cdr89JUyLT4IZ8SvM5aDRni95swKgYi3TgYLH5hnGfPE/U1dg6IfZ50UsIlLkwSA==}
dev: true
/chokidar@3.5.3: /chokidar@3.5.3:
resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
engines: {node: '>= 8.10.0'} engines: {node: '>= 8.10.0'}
@ -482,6 +578,11 @@ packages:
fsevents: 2.3.2 fsevents: 2.3.2
dev: true dev: true
/commander@4.1.1:
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
engines: {node: '>= 6'}
dev: true
/commander@7.2.0: /commander@7.2.0:
resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
@ -514,6 +615,12 @@ packages:
engines: {node: '>= 6'} engines: {node: '>= 6'}
dev: true dev: true
/cssesc@3.0.0:
resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
engines: {node: '>=4'}
hasBin: true
dev: true
/csso@4.2.0: /csso@4.2.0:
resolution: {integrity: sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==} resolution: {integrity: sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==}
engines: {node: '>=8.0.0'} engines: {node: '>=8.0.0'}
@ -542,6 +649,14 @@ packages:
engines: {node: '>=8'} engines: {node: '>=8'}
dev: true dev: true
/didyoumean@1.2.2:
resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
dev: true
/dlv@1.1.3:
resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
dev: true
/dom-serializer@1.4.1: /dom-serializer@1.4.1:
resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==}
dependencies: dependencies:
@ -569,6 +684,10 @@ packages:
domhandler: 4.3.1 domhandler: 4.3.1
dev: true dev: true
/electron-to-chromium@1.4.503:
resolution: {integrity: sha512-LF2IQit4B0VrUHFeQkWhZm97KuJSGF2WJqq1InpY+ECpFRkXd8yTIaTtJxsO0OKDmiBYwWqcrNaXOurn2T2wiA==}
dev: true
/entities@2.2.0: /entities@2.2.0:
resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==}
dev: true dev: true
@ -616,6 +735,11 @@ packages:
'@esbuild/win32-x64': 0.17.17 '@esbuild/win32-x64': 0.17.17
dev: true dev: true
/escalade@3.1.1:
resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
engines: {node: '>=6'}
dev: true
/eva-icons@1.1.3: /eva-icons@1.1.3:
resolution: {integrity: sha512-QBSEWNbEx1H0numXP1qgxKVCZHonRaky5ft4pGzQBcO4cy7mEja6TuJ8rc7BqX2pmkvetVQWKDH+DK/8y7GTag==} resolution: {integrity: sha512-QBSEWNbEx1H0numXP1qgxKVCZHonRaky5ft4pGzQBcO4cy7mEja6TuJ8rc7BqX2pmkvetVQWKDH+DK/8y7GTag==}
dev: false dev: false
@ -644,6 +768,10 @@ packages:
to-regex-range: 5.0.1 to-regex-range: 5.0.1
dev: true dev: true
/fraction.js@4.2.1:
resolution: {integrity: sha512-/KxoyCnPM0GwYI4NN0Iag38Tqt+od3/mLuguepLgCAKPn0ZhC544nssAW0tG2/00zXEYl9W+7hwAIpLHo6Oc7Q==}
dev: true
/fs.realpath@1.0.0: /fs.realpath@1.0.0:
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
dev: true dev: true
@ -671,6 +799,24 @@ packages:
is-glob: 4.0.3 is-glob: 4.0.3
dev: true dev: true
/glob-parent@6.0.2:
resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
engines: {node: '>=10.13.0'}
dependencies:
is-glob: 4.0.3
dev: true
/glob@7.1.6:
resolution: {integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==}
dependencies:
fs.realpath: 1.0.0
inflight: 1.0.6
inherits: 2.0.4
minimatch: 3.1.2
once: 1.4.0
path-is-absolute: 1.0.1
dev: true
/glob@7.2.3: /glob@7.2.3:
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
dependencies: dependencies:
@ -757,6 +903,11 @@ packages:
resolution: {integrity: sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw==} resolution: {integrity: sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw==}
dev: false dev: false
/jiti@1.19.3:
resolution: {integrity: sha512-5eEbBDQT/jF1xg6l36P+mWGGoH9Spuy0PCdSr2dtWRDGC6ph/w9ZCL4lmESW8f8F7MwT3XKescfP0wnZWAKL9w==}
hasBin: true
dev: true
/kleur@4.1.5: /kleur@4.1.5:
resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==}
engines: {node: '>=6'} engines: {node: '>=6'}
@ -770,12 +921,33 @@ packages:
isomorphic.js: 0.2.5 isomorphic.js: 0.2.5
dev: false dev: false
/lilconfig@2.1.0:
resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==}
engines: {node: '>=10'}
dev: true
/lines-and-columns@1.2.4:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
dev: true
/linkify-it@4.0.1: /linkify-it@4.0.1:
resolution: {integrity: sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==} resolution: {integrity: sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==}
dependencies: dependencies:
uc.micro: 1.0.6 uc.micro: 1.0.6
dev: true dev: true
/lodash.castarray@4.4.0:
resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==}
dev: true
/lodash.isplainobject@4.0.6:
resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==}
dev: true
/lodash.merge@4.6.2:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
dev: true
/magic-string@0.25.9: /magic-string@0.25.9:
resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==}
dependencies: dependencies:
@ -851,6 +1023,14 @@ packages:
/ms@2.1.2: /ms@2.1.2:
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
/mz@2.7.0:
resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
dependencies:
any-promise: 1.3.0
object-assign: 4.1.1
thenify-all: 1.6.0
dev: true
/nanoid@3.3.6: /nanoid@3.3.6:
resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
@ -870,17 +1050,36 @@ packages:
regexparam: 1.3.0 regexparam: 1.3.0
dev: false dev: false
/node-releases@2.0.13:
resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==}
dev: true
/normalize-path@3.0.0: /normalize-path@3.0.0:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dev: true dev: true
/normalize-range@0.1.2:
resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==}
engines: {node: '>=0.10.0'}
dev: true
/nth-check@2.1.1: /nth-check@2.1.1:
resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
dependencies: dependencies:
boolbase: 1.0.0 boolbase: 1.0.0
dev: true dev: true
/object-assign@4.1.1:
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
engines: {node: '>=0.10.0'}
dev: true
/object-hash@3.0.0:
resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
engines: {node: '>= 6'}
dev: true
/once@1.4.0: /once@1.4.0:
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
dependencies: dependencies:
@ -915,8 +1114,87 @@ packages:
engines: {node: '>=8.6'} engines: {node: '>=8.6'}
dev: true dev: true
/postcss@8.4.22: /pify@2.3.0:
resolution: {integrity: sha512-XseknLAfRHzVWjCEtdviapiBtfLdgyzExD50Rg2ePaucEesyh8Wv4VPdW0nbyDa1ydbrAxV19jvMT4+LFmcNUA==} resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
engines: {node: '>=0.10.0'}
dev: true
/pirates@4.0.6:
resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
engines: {node: '>= 6'}
dev: true
/postcss-import@15.1.0(postcss@8.4.28):
resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
engines: {node: '>=14.0.0'}
peerDependencies:
postcss: ^8.0.0
dependencies:
postcss: 8.4.28
postcss-value-parser: 4.2.0
read-cache: 1.0.0
resolve: 1.22.2
dev: true
/postcss-js@4.0.1(postcss@8.4.28):
resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==}
engines: {node: ^12 || ^14 || >= 16}
peerDependencies:
postcss: ^8.4.21
dependencies:
camelcase-css: 2.0.1
postcss: 8.4.28
dev: true
/postcss-load-config@4.0.1(postcss@8.4.28):
resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==}
engines: {node: '>= 14'}
peerDependencies:
postcss: '>=8.0.9'
ts-node: '>=9.0.0'
peerDependenciesMeta:
postcss:
optional: true
ts-node:
optional: true
dependencies:
lilconfig: 2.1.0
postcss: 8.4.28
yaml: 2.3.1
dev: true
/postcss-nested@6.0.1(postcss@8.4.28):
resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==}
engines: {node: '>=12.0'}
peerDependencies:
postcss: ^8.2.14
dependencies:
postcss: 8.4.28
postcss-selector-parser: 6.0.13
dev: true
/postcss-selector-parser@6.0.10:
resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==}
engines: {node: '>=4'}
dependencies:
cssesc: 3.0.0
util-deprecate: 1.0.2
dev: true
/postcss-selector-parser@6.0.13:
resolution: {integrity: sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==}
engines: {node: '>=4'}
dependencies:
cssesc: 3.0.0
util-deprecate: 1.0.2
dev: true
/postcss-value-parser@4.2.0:
resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
dev: true
/postcss@8.4.28:
resolution: {integrity: sha512-Z7V5j0cq8oEKyejIKfpD8b4eBy9cwW2JWPk0+fB1HOAMsfHbnAXLLS+PfVWlzMSLQaWttKDt607I0XHmpE67Vw==}
engines: {node: ^10 || ^12 || >=14} engines: {node: ^10 || ^12 || >=14}
dependencies: dependencies:
nanoid: 3.3.6 nanoid: 3.3.6
@ -924,6 +1202,78 @@ packages:
source-map-js: 1.0.2 source-map-js: 1.0.2
dev: true dev: true
/prettier-plugin-svelte@3.0.3(prettier@3.0.2)(svelte@3.58.0):
resolution: {integrity: sha512-dLhieh4obJEK1hnZ6koxF+tMUrZbV5YGvRpf2+OADyanjya5j0z1Llo8iGwiHmFWZVG/hLEw/AJD5chXd9r3XA==}
peerDependencies:
prettier: ^3.0.0
svelte: ^3.2.0 || ^4.0.0-next.0
dependencies:
prettier: 3.0.2
svelte: 3.58.0
dev: true
/prettier-plugin-tailwindcss@0.5.3(prettier-plugin-svelte@3.0.3)(prettier@3.0.2):
resolution: {integrity: sha512-M5K80V21yM+CTm/FEFYRv9/9LyInYbCSXpIoPAKMm8zy89IOwdiA2e4JVbcO7tvRtAQWz32zdj7/WKcsmFyAVg==}
engines: {node: '>=14.21.3'}
peerDependencies:
'@ianvs/prettier-plugin-sort-imports': '*'
'@prettier/plugin-pug': '*'
'@shopify/prettier-plugin-liquid': '*'
'@shufo/prettier-plugin-blade': '*'
'@trivago/prettier-plugin-sort-imports': '*'
prettier: ^3.0
prettier-plugin-astro: '*'
prettier-plugin-css-order: '*'
prettier-plugin-import-sort: '*'
prettier-plugin-jsdoc: '*'
prettier-plugin-marko: '*'
prettier-plugin-organize-attributes: '*'
prettier-plugin-organize-imports: '*'
prettier-plugin-style-order: '*'
prettier-plugin-svelte: '*'
prettier-plugin-twig-melody: '*'
peerDependenciesMeta:
'@ianvs/prettier-plugin-sort-imports':
optional: true
'@prettier/plugin-pug':
optional: true
'@shopify/prettier-plugin-liquid':
optional: true
'@shufo/prettier-plugin-blade':
optional: true
'@trivago/prettier-plugin-sort-imports':
optional: true
prettier-plugin-astro:
optional: true
prettier-plugin-css-order:
optional: true
prettier-plugin-import-sort:
optional: true
prettier-plugin-jsdoc:
optional: true
prettier-plugin-marko:
optional: true
prettier-plugin-organize-attributes:
optional: true
prettier-plugin-organize-imports:
optional: true
prettier-plugin-style-order:
optional: true
prettier-plugin-svelte:
optional: true
prettier-plugin-twig-melody:
optional: true
dependencies:
prettier: 3.0.2
prettier-plugin-svelte: 3.0.3(prettier@3.0.2)(svelte@3.58.0)
dev: true
/prettier@3.0.2:
resolution: {integrity: sha512-o2YR9qtniXvwEZlOKbveKfDQVyqxbEIWn48Z8m3ZJjBjcCmUy3xZGIv+7AkaeuaTr6yPXJjwv07ZWlsWbEy1rQ==}
engines: {node: '>=14'}
hasBin: true
dev: true
/prosemirror-commands@1.3.1: /prosemirror-commands@1.3.1:
resolution: {integrity: sha512-XTporPgoECkOQACVw0JTe3RZGi+fls3/byqt+tXwGTkD7qLuB4KdVrJamDMJf4kfKga3uB8hZ+kUUyZ5oWpnfg==} resolution: {integrity: sha512-XTporPgoECkOQACVw0JTe3RZGi+fls3/byqt+tXwGTkD7qLuB4KdVrJamDMJf4kfKga3uB8hZ+kUUyZ5oWpnfg==}
dependencies: dependencies:
@ -1024,6 +1374,12 @@ packages:
safe-buffer: 5.2.1 safe-buffer: 5.2.1
dev: false dev: false
/read-cache@1.0.0:
resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
dependencies:
pify: 2.3.0
dev: true
/readable-stream@3.6.2: /readable-stream@3.6.2:
resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
engines: {node: '>= 6'} engines: {node: '>= 6'}
@ -1181,12 +1537,26 @@ packages:
min-indent: 1.0.1 min-indent: 1.0.1
dev: true dev: true
/sucrase@3.34.0:
resolution: {integrity: sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==}
engines: {node: '>=8'}
hasBin: true
dependencies:
'@jridgewell/gen-mapping': 0.3.3
commander: 4.1.1
glob: 7.1.6
lines-and-columns: 1.2.4
mz: 2.7.0
pirates: 4.0.6
ts-interface-checker: 0.1.13
dev: true
/supports-preserve-symlinks-flag@1.0.0: /supports-preserve-symlinks-flag@1.0.0:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
dev: true dev: true
/svelte-check@2.10.3(svelte@3.58.0): /svelte-check@2.10.3(postcss@8.4.28)(svelte@3.58.0):
resolution: {integrity: sha512-Nt1aWHTOKFReBpmJ1vPug0aGysqPwJh2seM1OvICfM2oeyaA62mOiy5EvkXhltGfhCcIQcq2LoE0l1CwcWPjlw==} resolution: {integrity: sha512-Nt1aWHTOKFReBpmJ1vPug0aGysqPwJh2seM1OvICfM2oeyaA62mOiy5EvkXhltGfhCcIQcq2LoE0l1CwcWPjlw==}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
@ -1199,7 +1569,7 @@ packages:
picocolors: 1.0.0 picocolors: 1.0.0
sade: 1.8.1 sade: 1.8.1
svelte: 3.58.0 svelte: 3.58.0
svelte-preprocess: 4.10.7(svelte@3.58.0)(typescript@4.9.5) svelte-preprocess: 4.10.7(postcss@8.4.28)(svelte@3.58.0)(typescript@4.9.5)
typescript: 4.9.5 typescript: 4.9.5
transitivePeerDependencies: transitivePeerDependencies:
- '@babel/core' - '@babel/core'
@ -1223,7 +1593,7 @@ packages:
svelte: 3.58.0 svelte: 3.58.0
dev: true dev: true
/svelte-preprocess@4.10.7(svelte@3.58.0)(typescript@4.9.5): /svelte-preprocess@4.10.7(postcss@8.4.28)(svelte@3.58.0)(typescript@4.9.5):
resolution: {integrity: sha512-sNPBnqYD6FnmdBrUmBCaqS00RyCsCpj2BG58A1JBswNF7b0OKviwxqVrOL/CKyJrLSClrSeqQv5BXNg2RUbPOw==} resolution: {integrity: sha512-sNPBnqYD6FnmdBrUmBCaqS00RyCsCpj2BG58A1JBswNF7b0OKviwxqVrOL/CKyJrLSClrSeqQv5BXNg2RUbPOw==}
engines: {node: '>= 9.11.2'} engines: {node: '>= 9.11.2'}
requiresBuild: true requiresBuild: true
@ -1268,6 +1638,7 @@ packages:
'@types/sass': 1.45.0 '@types/sass': 1.45.0
detect-indent: 6.1.0 detect-indent: 6.1.0
magic-string: 0.25.9 magic-string: 0.25.9
postcss: 8.4.28
sorcery: 0.10.0 sorcery: 0.10.0
strip-indent: 3.0.0 strip-indent: 3.0.0
svelte: 3.58.0 svelte: 3.58.0
@ -1293,6 +1664,50 @@ packages:
stable: 0.1.8 stable: 0.1.8
dev: true dev: true
/tailwindcss@3.3.3:
resolution: {integrity: sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==}
engines: {node: '>=14.0.0'}
hasBin: true
dependencies:
'@alloc/quick-lru': 5.2.0
arg: 5.0.2
chokidar: 3.5.3
didyoumean: 1.2.2
dlv: 1.1.3
fast-glob: 3.2.12
glob-parent: 6.0.2
is-glob: 4.0.3
jiti: 1.19.3
lilconfig: 2.1.0
micromatch: 4.0.5
normalize-path: 3.0.0
object-hash: 3.0.0
picocolors: 1.0.0
postcss: 8.4.28
postcss-import: 15.1.0(postcss@8.4.28)
postcss-js: 4.0.1(postcss@8.4.28)
postcss-load-config: 4.0.1(postcss@8.4.28)
postcss-nested: 6.0.1(postcss@8.4.28)
postcss-selector-parser: 6.0.13
resolve: 1.22.2
sucrase: 3.34.0
transitivePeerDependencies:
- ts-node
dev: true
/thenify-all@1.6.0:
resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
engines: {node: '>=0.8'}
dependencies:
thenify: 3.3.1
dev: true
/thenify@3.3.1:
resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
dependencies:
any-promise: 1.3.0
dev: true
/to-regex-range@5.0.1: /to-regex-range@5.0.1:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'} engines: {node: '>=8.0'}
@ -1300,6 +1715,10 @@ packages:
is-number: 7.0.0 is-number: 7.0.0
dev: true dev: true
/ts-interface-checker@0.1.13:
resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
dev: true
/tslib@2.5.0: /tslib@2.5.0:
resolution: {integrity: sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==} resolution: {integrity: sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==}
dev: true dev: true
@ -1314,9 +1733,19 @@ packages:
resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==}
dev: true dev: true
/update-browserslist-db@1.0.11(browserslist@4.21.10):
resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==}
hasBin: true
peerDependencies:
browserslist: '>= 4.21.0'
dependencies:
browserslist: 4.21.10
escalade: 3.1.1
picocolors: 1.0.0
dev: true
/util-deprecate@1.0.2: /util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
dev: false
/vite@4.2.2: /vite@4.2.2:
resolution: {integrity: sha512-PcNtT5HeDxb3QaSqFYkEum8f5sCVe0R3WK20qxgIvNBZPXU/Obxs/+ubBMeE7nLWeCo2LDzv+8hRYSlcaSehig==} resolution: {integrity: sha512-PcNtT5HeDxb3QaSqFYkEum8f5sCVe0R3WK20qxgIvNBZPXU/Obxs/+ubBMeE7nLWeCo2LDzv+8hRYSlcaSehig==}
@ -1344,7 +1773,7 @@ packages:
optional: true optional: true
dependencies: dependencies:
esbuild: 0.17.17 esbuild: 0.17.17
postcss: 8.4.22 postcss: 8.4.28
resolve: 1.22.2 resolve: 1.22.2
rollup: 3.20.6 rollup: 3.20.6
optionalDependencies: optionalDependencies:
@ -1433,6 +1862,11 @@ packages:
- utf-8-validate - utf-8-validate
dev: false dev: false
/yaml@2.3.1:
resolution: {integrity: sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==}
engines: {node: '>= 14'}
dev: true
/yjs@13.5.52: /yjs@13.5.52:
resolution: {integrity: sha512-wTajR70VeI6uztpUk4kMcXYHSRzuUlNyJPdBG9NII0EcFf27DwGduZEm3XbP7VSzlGx5n6uenBhOPX+YuPH/tA==} resolution: {integrity: sha512-wTajR70VeI6uztpUk4kMcXYHSRzuUlNyJPdBG9NII0EcFf27DwGduZEm3XbP7VSzlGx5n6uenBhOPX+YuPH/tA==}
engines: {node: '>=16.0.0', npm: '>=8.0.0'} engines: {node: '>=16.0.0', npm: '>=8.0.0'}

6
postcss.config.js Normal file
View file

@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

3
prettier.config.cjs Normal file
View file

@ -0,0 +1,3 @@
module.exports = {
plugins: ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"],
};

View file

@ -2,7 +2,7 @@
import { setRouteToLastPagePromise, currentRoute } from "./lib/router"; import { setRouteToLastPagePromise, currentRoute } from "./lib/router";
</script> </script>
<main> <main class="min-h-screen max-w-7xl mx-auto">
{#await setRouteToLastPagePromise then} {#await setRouteToLastPagePromise then}
<svelte:component <svelte:component
this={$currentRoute.component} this={$currentRoute.component}
@ -10,10 +10,3 @@
/> />
{/await} {/await}
</main> </main>
<style>
main {
max-width: 1280px;
margin: 0 auto;
}
</style>

View file

@ -1,13 +1,30 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
:root { :root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; font-family:
line-height: 1.5; Inter,
ui-sans-serif,
system-ui,
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
Roboto,
"Helvetica Neue",
Arial,
"Noto Sans",
sans-serif,
"Apple Color Emoji",
"Segoe UI Emoji",
"Segoe UI Symbol",
"Noto Color Emoji";
font-weight: 400; font-weight: 400;
font-synthesis: none; font-synthesis: none;
text-rendering: optimizeLegibility; text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
color-scheme: dark light; color-scheme: dark light;
@ -17,25 +34,10 @@
--accent-bg: #cbd5e1; --accent-bg: #cbd5e1;
--accent-fg: #1e293b; --accent-fg: #1e293b;
} }
/*
*,
*::before,
*::after {
box-sizing: border-box;
}
body,
#app,
main {
margin: 0;
min-height: 100vh;
background: var(--background);
color: var(--foreground);
}
a { a {
color: var(--accent-fg); color: var(--accent-fg);
} } */
@media (prefers-color-scheme: dark) { @media (prefers-color-scheme: dark) {
:root { :root {
@ -46,7 +48,3 @@ a {
--accent-fg: #94a3b8; --accent-fg: #94a3b8;
} }
} }
button {
padding: 0.5em 1em;
}

View file

@ -21,8 +21,8 @@
<div class="backdrop" /> <div class="backdrop" />
<div class="content-alignment" on:click={click} on:keydown={keydown}> <div class="content-alignment" on:click={click} on:keydown={keydown}>
<div class="content"> <div class="content shadow-xl">
<h3 id="modal-title"> <h3 class="text-2xl" id="modal-title">
<slot name="title" /> <slot name="title" />
</h3> </h3>
<slot /> <slot />
@ -127,13 +127,6 @@
background: var(--background); background: var(--background);
padding: 16px 20px; padding: 16px 20px;
border-radius: 16px; border-radius: 16px;
min-width: 50%;
min-height: 50%;
--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1),
0 8px 10px -6px rgb(0 0 0 / 0.1);
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000),
var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
} }
h3 { h3 {

View file

@ -6,6 +6,7 @@
import { makeYdocStore } from "../lib/makeYdocStore"; import { makeYdocStore } from "../lib/makeYdocStore";
import { lastUpdated } from "../lib/lastUpdated"; import { lastUpdated } from "../lib/lastUpdated";
import { nanoid } from "nanoid"; import { nanoid } from "nanoid";
import PlusIcon from "eva-icons/fill/svg/plus.svg";
type Entry = { type Entry = {
id: string; id: string;
@ -52,14 +53,31 @@
const deriveEntries = makeYdocStore((_, __, ydoc) => getDocs(ydoc)); const deriveEntries = makeYdocStore((_, __, ydoc) => getDocs(ydoc));
</script> </script>
<input type="text" bind:value={filter} placeholder="Buscar..." autofocus /> <!-- https://devdojo.com/pines/docs/text-input -->
<ul> <input
<button type="button" on:click={() => onChoose(nanoid())}>Página nueva</button type="text"
bind:value={filter}
placeholder="Buscar..."
autofocus
class="h-10 w-full rounded-md rounded-b-none border border-neutral-300 bg-white px-3 py-2 text-sm placeholder:text-neutral-500 dark:border-neutral-600 dark:bg-neutral-700 placeholder:dark:text-neutral-300"
/>
<ul
class="flex flex-col rounded-b-md border border-t-0 border-neutral-300 bg-white p-2 dark:border-neutral-600 dark:bg-neutral-700"
>
<button
type="button"
class="flex items-center gap-2 rounded px-2 py-2 text-left hover:bg-neutral-200 dark:hover:bg-neutral-600"
on:click={() => onChoose(nanoid())}
> >
{#each sortedEntries as entry} <PlusIcon class="w-6 fill-current" />
Página nueva
</button>
{#each sortedEntries as entry, index (entry.id)}
<li> <li>
<button type="button" on:click={() => onChoose(entry.id)} <button
>{entry.title ?? entry.id}</button type="button"
class="flex w-full items-center gap-2 rounded px-2 py-2 text-left hover:bg-neutral-200 dark:hover:bg-neutral-600"
on:click={() => onChoose(entry.id)}>{entry.title ?? entry.id}</button
> >
</li> </li>
{/each} {/each}

View file

@ -6,11 +6,14 @@
/** @type {import("../lib/doc").WorldIdentifier} */ /** @type {import("../lib/doc").WorldIdentifier} */
export let world; export let world;
/** @type {string} */
export let className = "";
$: title = titleStore(getWorldY(world).ydoc, "page/index"); $: title = titleStore(getWorldY(world).ydoc, "page/index");
</script> </script>
<a <a
class={className}
href={inject(routes.Page, { href={inject(routes.Page, {
worldId: world.room, worldId: world.room,
pageId: "index", pageId: "index",

View file

@ -66,20 +66,18 @@
} }
</script> </script>
<div class="editor"> <div class="editor min-h-screen">
{#if view} {#if view}
<MenuBar {view} state={updatedState} /> <MenuBar {view} state={updatedState} />
{/if} {/if}
<!-- this element gets replaced with the editor itself when mounted --> <!-- this element gets replaced with the editor itself when mounted -->
<div bind:this={wrapperEl} /> <div class="prose dark:prose-invert before:prose-p:content-none after:prose-p:content-none prose-blockquote:font-normal prose-blockquote:not-italic max-w-none min-h-screen" bind:this={wrapperEl} />
{#if view} {#if view}
<BubbleMenu {view} {worldY} state={updatedState} /> <BubbleMenu {view} {worldY} state={updatedState} />
{/if} {/if}
</div> </div>
<style> <style>
.editor,
div,
:global(.ProseMirror) { :global(.ProseMirror) {
min-height: 100vh; min-height: 100vh;
} }

View file

@ -12,7 +12,7 @@
export let state: EditorState; export let state: EditorState;
</script> </script>
<div class="menubar"> <div class="menubar sticky top-0 flex py-2 px-4 z-50 items-center">
<BlockSelect {view} {state} /> <BlockSelect {view} {state} />
<!-- <UploadItem {view} {state} /> --> <!-- <UploadItem {view} {state} /> -->
<ListItem {view} {state} kind={ListKind.Unordered} /> <ListItem {view} {state} kind={ListKind.Unordered} />
@ -22,12 +22,6 @@
<style> <style>
.menubar { .menubar {
position: sticky;
top: 0px;
z-index: 69;
display: flex;
background: var(--background, white); background: var(--background, white);
border-bottom: 1px solid var(--accent-bg); border-bottom: 1px solid var(--accent-bg);
} }

View file

@ -47,10 +47,6 @@
outline: lightskyblue solid; outline: lightskyblue solid;
} }
.ProseMirror img {
max-width: 100%;
}
.ProseMirror figure { .ProseMirror figure {
margin: 0; margin: 0;
padding: 0.5em 2em; padding: 0.5em 2em;
@ -59,10 +55,3 @@
content: "Descripción: "; content: "Descripción: ";
color: #666; color: #666;
} }
.ProseMirror blockquote {
background-color: var(--transparentish);
border-left: 5px solid var(--foreground);
padding: 1.25em 1.5em;
margin: 0.5em;
}

View file

@ -26,7 +26,7 @@ import { schema } from "./schema";
const backspace = chainCommands( const backspace = chainCommands(
deleteSelection, deleteSelection,
joinBackward, joinBackward,
selectNodeBackward selectNodeBackward,
); );
const del = chainCommands(deleteSelection, joinForward, selectNodeForward); const del = chainCommands(deleteSelection, joinForward, selectNodeForward);
@ -37,7 +37,7 @@ const pcBaseKeymap = {
liftEmptyBlock, liftEmptyBlock,
// XXX: hack // XXX: hack
splitListItem(schema.nodes.list_item as any), splitListItem(schema.nodes.list_item as any),
splitBlock splitBlock,
), ),
"Mod-Enter": chainCommands(exitCode, splitBlock), "Mod-Enter": chainCommands(exitCode, splitBlock),
Backspace: backspace, Backspace: backspace,

View file

@ -38,7 +38,7 @@
}; };
</script> </script>
<select value={currentValue} on:change={onChange}> <select value={currentValue} on:change={onChange} class="relative flex items-center justify-between py-3 pl-3 pr-10 text-left bg-white dark:bg-neutral-800 border rounded-md shadow-sm cursor-default border-neutral-200/70 dark:border-neutral-700/70 text-sm">
<option value="paragraph">Párrafo</option> <option value="paragraph">Párrafo</option>
<option value="heading:1">Titulo grande</option> <option value="heading:1">Titulo grande</option>
<option value="heading:2">Titulo mediano</option> <option value="heading:2">Titulo mediano</option>

View file

@ -11,14 +11,14 @@ import type { EditorView } from "prosemirror-view";
export type Command = ( export type Command = (
state: EditorState, state: EditorState,
dispatch?: EditorView["dispatch"] dispatch?: EditorView["dispatch"],
) => boolean; ) => boolean;
// A lot of this is from https://github.com/ueberdosis/tiptap/blob/main/packages/tiptap-commands // A lot of this is from https://github.com/ueberdosis/tiptap/blob/main/packages/tiptap-commands
export function getMarkRange( export function getMarkRange(
$pos: ResolvedPos | null = null, $pos: ResolvedPos | null = null,
type: MarkType | null = null type: MarkType | null = null,
) { ) {
if (!$pos || !type) { if (!$pos || !type) {
return false; return false;
@ -122,14 +122,14 @@ export function toggleNode(
attrs: any, attrs: any,
/// es el tipo que se setea si ya es el type querido; probablemente querés /// es el tipo que se setea si ya es el type querido; probablemente querés
/// que sea el type de párrafo /// que sea el type de párrafo
alternateType: NodeType alternateType: NodeType,
): Command { ): Command {
return chainCommands(setBlockType(type, attrs), setBlockType(alternateType)); return chainCommands(setBlockType(type, attrs), setBlockType(alternateType));
} }
export function commandListener( export function commandListener(
view: EditorView, view: EditorView,
command: Command command: Command,
): (event: Event) => void { ): (event: Event) => void {
return (event) => { return (event) => {
event.preventDefault(); event.preventDefault();
@ -139,7 +139,7 @@ export function commandListener(
export default function findParentNodeClosestToPos( export default function findParentNodeClosestToPos(
$pos: ResolvedPos, $pos: ResolvedPos,
predicate: (node: ProsemirrorNode) => boolean predicate: (node: ProsemirrorNode) => boolean,
) { ) {
for (let i = $pos.depth; i > 0; i -= 1) { for (let i = $pos.depth; i > 0; i -= 1) {
const node = $pos.node(i); const node = $pos.node(i);
@ -158,7 +158,7 @@ export default function findParentNodeClosestToPos(
export function nodeIsActiveFn( export function nodeIsActiveFn(
type: NodeType, type: NodeType,
attrs?: any, attrs?: any,
checkParents: boolean = false checkParents: boolean = false,
): (state: EditorState) => boolean { ): (state: EditorState) => boolean {
return (state) => { return (state) => {
let { $from, to } = state.selection; let { $from, to } = state.selection;
@ -196,7 +196,7 @@ export interface MarkMatch {
export function getFirstMarkInSelection( export function getFirstMarkInSelection(
state: EditorState, state: EditorState,
type: MarkType type: MarkType,
): MarkMatch | null { ): MarkMatch | null {
const { to, from } = state.selection; const { to, from } = state.selection;

View file

@ -315,7 +315,7 @@ export const schema = new Schema({
if ( if (
href && href &&
/[useandom\-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict]{21}/.test( /[useandom\-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict]{21}/.test(
href href,
) )
) { ) {
return { return {

View file

@ -9,7 +9,7 @@ interface Props {
export function h( export function h(
tagName: string, tagName: string,
props: Props, props: Props,
children: (Node | string | undefined)[] children: (Node | string | undefined)[],
): HTMLElement { ): HTMLElement {
const el = document.createElement(tagName); const el = document.createElement(tagName);
if (props.class) { if (props.class) {

48
src/lib/breadcrumbs.ts Normal file
View file

@ -0,0 +1,48 @@
import { derived } from "svelte/store";
import IdbValStore from "./idbValStore";
export type PageParams = {
worldId: string;
pageId: string;
};
type WorldId = string;
type PageId = string;
class BreadcrumbsStore {
idb: IdbValStore<Map<WorldId, PageId[]>>;
idbLastWorld: IdbValStore<WorldId>;
constructor() {
this.idb = new IdbValStore("schreiben-breadcrumbs");
this.idbLastWorld = new IdbValStore("schreiben-last-world");
}
async newCrumb({ worldId, pageId }: PageParams) {
await this.idbLastWorld.set(worldId);
await this.idb.update((map) => {
if (!map) map = new Map();
let crumbs = map.get(worldId) || [];
if (crumbs.includes(pageId)) {
crumbs = crumbs.slice(0, crumbs.indexOf(pageId) + 1);
} else {
crumbs.push(pageId);
}
map.set(worldId, crumbs);
return map;
});
}
async lastWorldBreadcrumbs() {
const map = await this.idb.get();
const worldId = await this.idbLastWorld.get();
if (!worldId) return;
const breadcrumbs = map?.get(worldId);
if (!breadcrumbs) return;
return { worldId, breadcrumbs };
}
worldStore(worldId: WorldId) {
return derived(this.idb, (map) => map?.get(worldId) || []);
}
}
export default new BreadcrumbsStore();

View file

@ -25,7 +25,7 @@ export function generateNewWorld(): WorldIdentifier {
let worldYCache: { [key: string]: WorldY } = {}; let worldYCache: { [key: string]: WorldY } = {};
const credsReq = fetch( const credsReq = fetch(
"https://nulo.metered.live/api/v1/turn/credentials?apiKey=205de2914a8564e2efa19a7d7f299a95e574" "https://nulo.metered.live/api/v1/turn/credentials?apiKey=205de2914a8564e2efa19a7d7f299a95e574",
).then((res) => res.json()); ).then((res) => res.json());
export function getWorldY(world: WorldIdentifier): WorldY { export function getWorldY(world: WorldIdentifier): WorldY {

View file

@ -1,14 +1,37 @@
import { get, set } from "idb-keyval"; import { get, set, update } from "idb-keyval";
export default class IdbValStore<T> { export default class IdbValStore<T> {
name: string; name: string;
subscriptors: ((val: T) => void)[];
constructor(name: string) { constructor(name: string) {
this.name = name; this.name = name;
this.subscriptors = [];
} }
get(): Promise<T | undefined> { get(): Promise<T | undefined> {
return get<T>(this.name); return get<T>(this.name);
} }
set(val: T): Promise<void> { async set(val: T): Promise<void> {
return set(this.name, val); await set(this.name, val);
this.push(val);
}
async update(updater: (val: T | undefined) => T): Promise<void> {
let newVal: T | undefined = undefined;
await update(this.name, (val) => (newVal = updater(val)));
if (newVal === undefined) throw new Error("what the fuck");
this.push(newVal);
}
private push(val: T) {
for (const sub of this.subscriptors) sub(val);
}
subscribe(subscription: (value: T | undefined) => void): () => void {
this.subscriptors.push(subscription);
(async () => {
const val = await this.get();
if (this.subscriptors.includes(subscription)) subscription(val);
})();
return () => {
this.subscriptors = this.subscriptors.filter((s) => s !== subscription);
};
} }
} }

View file

@ -24,6 +24,6 @@ export function lastUpdated(ydoc: Doc) {
} }
return map; return map;
}, },
() => observers.forEach(({ y, observer }) => y.unobserveDeep(observer)) () => observers.forEach(({ y, observer }) => y.unobserveDeep(observer)),
)(ydoc); )(ydoc);
} }

View file

@ -6,9 +6,9 @@ export function makeYdocStore<T>(
update: Uint8Array | null, update: Uint8Array | null,
origin: any, origin: any,
ydoc: Doc, ydoc: Doc,
tr: Transaction | null tr: Transaction | null,
) => T, ) => T,
unhandler?: () => void unhandler?: () => void,
) { ) {
return (ydoc: Doc): Readable<T> => { return (ydoc: Doc): Readable<T> => {
// thanks https://github.com/relm-us/svelt-yjs/blob/main/src/types/array.ts // thanks https://github.com/relm-us/svelt-yjs/blob/main/src/types/array.ts
@ -18,7 +18,7 @@ export function makeYdocStore<T>(
update: Uint8Array | null, update: Uint8Array | null,
origin: any, origin: any,
ydoc: Doc, ydoc: Doc,
tr: Transaction | null tr: Transaction | null,
) { ) {
run(handler(update, origin, ydoc, tr)); run(handler(update, origin, ydoc, tr));
} }

View file

@ -1,6 +1,5 @@
import navaid from "navaid"; import navaid from "navaid";
import { writable } from "svelte/store"; import { writable } from "svelte/store";
import { inject } from "regexparam";
import ChooseWorld from "../views/ChooseWorld.svelte"; import ChooseWorld from "../views/ChooseWorld.svelte";
import CreateWorld from "../views/CreateWorld.svelte"; import CreateWorld from "../views/CreateWorld.svelte";
@ -9,9 +8,8 @@ import NotFound from "../views/NotFound.svelte";
import Page from "../views/Page.svelte"; import Page from "../views/Page.svelte";
import ShareWorld from "../views/ShareWorld.svelte"; import ShareWorld from "../views/ShareWorld.svelte";
import { routes } from "./routes"; import { routes } from "./routes";
import IdbValStore from "./idbValStore"; import breadcrumbs, { type PageParams } from "./breadcrumbs";
import { inject } from "regexparam";
export const lastPageStore = new IdbValStore("schreiben-last-page");
export const currentRoute = writable<{ export const currentRoute = writable<{
// XXX: in lack of a better type for Svelte components // XXX: in lack of a better type for Svelte components
@ -20,29 +18,33 @@ export const currentRoute = writable<{
}>({ component: ChooseWorld }); }>({ component: ChooseWorld });
export let router = navaid("/", () => export let router = navaid("/", () =>
currentRoute.set({ component: NotFound }) currentRoute.set({ component: NotFound }),
); );
router.on(routes.ChooseWorld, () => router.on(routes.ChooseWorld, () =>
currentRoute.set({ component: ChooseWorld }) currentRoute.set({ component: ChooseWorld }),
); );
router.on(routes.CreateWorld, () => router.on(routes.CreateWorld, () =>
currentRoute.set({ component: CreateWorld }) currentRoute.set({ component: CreateWorld }),
); );
router.on(routes.ShareWorld, (params) => router.on(routes.ShareWorld, (params) =>
currentRoute.set({ component: ShareWorld, params }) currentRoute.set({ component: ShareWorld, params }),
); );
router.on(routes.JoinWorld, (params) => router.on(routes.JoinWorld, (params) =>
currentRoute.set({ component: JoinWorld, params }) currentRoute.set({ component: JoinWorld, params }),
);
router.on(routes.Page, (params) =>
currentRoute.set({ component: Page, params })
); );
router.on(routes.Page, (params) => {
currentRoute.set({ component: Page, params });
breadcrumbs.newCrumb(params as PageParams);
});
async function setRouteToLastPage() { async function setRouteToLastPage() {
if (location.pathname === "/") { if (location.pathname === "/") {
const lastPage = await lastPageStore.get(); const lastWorldBreadcrumbs = await breadcrumbs.lastWorldBreadcrumbs();
if (lastPage) { if (lastWorldBreadcrumbs) {
router.route(inject(routes.Page, lastPage), true); const { worldId, breadcrumbs } = lastWorldBreadcrumbs;
for (const crumb of breadcrumbs) {
router.route(inject(routes.Page, { worldId, pageId: crumb }));
}
} }
} }
} }

View file

@ -27,6 +27,6 @@ export function titleStore(ydoc, id) {
return title; return title;
}, },
() => observer && y?.unobserveDeep(observer) () => observer && y?.unobserveDeep(observer),
)(ydoc); )(ydoc);
} }

View file

@ -14,7 +14,7 @@ export function loadWorlds(): Promise<WorldIdentifier[]> {
} }
export async function writeWorlds( export async function writeWorlds(
callback: (worlds: WorldIdentifier[]) => WorldIdentifier[] callback: (worlds: WorldIdentifier[]) => WorldIdentifier[],
): Promise<WorldIdentifier[]> { ): Promise<WorldIdentifier[]> {
const oldWorlds = await loadWorlds(); const oldWorlds = await loadWorlds();
const newWorlds = callback(oldWorlds); const newWorlds = callback(oldWorlds);

View file

@ -6,28 +6,26 @@
const worldsPromise = loadWorlds(); const worldsPromise = loadWorlds();
</script> </script>
<h1>Buen día.</h1> <header class="my-4 mx-8">
<h3>Elegí un mundo.</h3> <h1 class="font-bold text-3xl">Buen día.</h1>
<h3>Elegí un mundo.</h3>
</header>
{#await worldsPromise then worlds} {#await worldsPromise then worlds}
<ul> <ul class="m-4">
{#each worlds as world} {#each worlds as world}
<li> <li>
<WorldLink {world} /> <WorldLink
className="px-6 py-4 bg-slate-200 dark:bg-neutral-800 w-full block rounded-2xl dark:border-neutral-700/70 border my-4 shadow text-xl"
{world}
/>
</li> </li>
{/each} {/each}
<li><a href={routes.CreateWorld}>Crear mundo</a></li> <li>
<a
class="px-6 py-4 bg-slate-200 dark:bg-neutral-800 w-full block rounded-2xl dark:border-neutral-700/70 border my-4 shadow text-xl"
href={routes.CreateWorld}>Crear mundo</a
>
</li>
</ul> </ul>
{/await} {/await}
<style>
ul :global(a) {
background: ButtonFace;
color: ButtonText;
display: block;
padding: 1em;
margin: 0.5em;
border-radius: 15px;
}
</style>

View file

@ -1,18 +1,21 @@
<script lang="ts"> <script lang="ts">
import type { XmlFragment } from "yjs"; import type { XmlFragment } from "yjs";
import { inject } from "regexparam"; import { inject } from "regexparam";
import ChevronRight from "eva-icons/fill/svg/chevron-right.svg";
import Editor from "../editor/Editor.svelte"; import Editor from "../editor/Editor.svelte";
import { getWorldPage, getWorldY, type WorldY } from "../lib/doc"; import { getWorldPage, getWorldY, type WorldY } from "../lib/doc";
import { routes } from "../lib/routes"; import { routes } from "../lib/routes";
import { loadWorlds } from "../lib/worldStorage"; import { loadWorlds } from "../lib/worldStorage";
import { lastPageStore } from "../lib/router"; import breadcrumbs from "../lib/breadcrumbs";
export let worldId: string; export let worldId: string;
export let pageId: string; export let pageId: string;
$: pageBreadcrumbs = breadcrumbs.worldStore(worldId);
async function loadDoc( async function loadDoc(
worldId: string, worldId: string,
pageId: string pageId: string,
): Promise<{ worldY: WorldY; doc: XmlFragment }> { ): Promise<{ worldY: WorldY; doc: XmlFragment }> {
const worlds = await loadWorlds(); const worlds = await loadWorlds();
const worldIdentifier = worlds.find((w) => w.room === worldId); const worldIdentifier = worlds.find((w) => w.room === worldId);
@ -33,11 +36,6 @@
}) })
.catch((error) => (state = { error })); .catch((error) => (state = { error }));
} }
async function saveLastPage() {
await lastPageStore.set({ worldId, pageId });
}
saveLastPage();
</script> </script>
<nav> <nav>
@ -52,6 +50,28 @@
</li> </li>
</ul> </ul>
</details> </details>
<!-- https://devdojo.com/pines/docs/breadcrumbs -->
<div
class="flex justify-between rounded-md border border-neutral-200/60 px-3.5 py-1"
>
<ol
class="mb-3 inline-flex items-center space-x-1 text-xs text-neutral-500 sm:mb-0 [&_.active-breadcrumb]:font-medium [&_.active-breadcrumb]:text-neutral-600"
>
{#each $pageBreadcrumbs as crumb, index}
<li>
<a
href={inject(routes.Page, { worldId, pageId: crumb })}
class="inline-flex items-center py-1 font-normal hover:text-neutral-900 focus:outline-none"
class:active-breadcrumb={crumb === pageId}>{crumb}</a
>
</li>
{#if index !== $pageBreadcrumbs.length - 1}
<ChevronRight class="h-5 w-5 fill-current text-gray-400/70" />
{/if}
{/each}
</ol>
</div>
</nav> </nav>
{#if state === "loading"}Cargando...{:else if "doc" in state} {#if state === "loading"}Cargando...{:else if "doc" in state}

8
tailwind.config.js Normal file
View file

@ -0,0 +1,8 @@
/** @type {import('tailwindcss').Config} */
export default {
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx,svelte}"],
theme: {
extend: {},
},
plugins: [require("@tailwindcss/typography")],
};