This commit is contained in:
2023-01-13 22:11:28 +08:00
parent 46fcccda35
commit d45783334d
41 changed files with 544 additions and 256 deletions

View File

@@ -24,6 +24,7 @@
}, },
"devDependencies": { "devDependencies": {
"@iconify-json/ep": "^1.1.8", "@iconify-json/ep": "^1.1.8",
"@types/node": "^18.11.18",
"@vitejs/plugin-vue": "^4.0.0", "@vitejs/plugin-vue": "^4.0.0",
"monaco-editor": "^0.34.1", "monaco-editor": "^0.34.1",
"prettier": "^2.8.2", "prettier": "^2.8.2",

15
pnpm-lock.yaml generated
View File

@@ -4,6 +4,7 @@ specifiers:
'@element-plus/icons-vue': ^2.0.10 '@element-plus/icons-vue': ^2.0.10
'@iconify-json/ep': ^1.1.8 '@iconify-json/ep': ^1.1.8
'@monaco-editor/loader': ^1.3.2 '@monaco-editor/loader': ^1.3.2
'@types/node': ^18.11.18
'@vitejs/plugin-vue': ^4.0.0 '@vitejs/plugin-vue': ^4.0.0
'@vueuse/core': ^9.10.0 '@vueuse/core': ^9.10.0
'@vueuse/integrations': ^9.10.0 '@vueuse/integrations': ^9.10.0
@@ -39,6 +40,7 @@ dependencies:
devDependencies: devDependencies:
'@iconify-json/ep': 1.1.8 '@iconify-json/ep': 1.1.8
'@types/node': 18.11.18
'@vitejs/plugin-vue': 4.0.0_vite@4.0.4+vue@3.2.45 '@vitejs/plugin-vue': 4.0.0_vite@4.0.4+vue@3.2.45
monaco-editor: 0.34.1 monaco-editor: 0.34.1
prettier: 2.8.2 prettier: 2.8.2
@@ -46,7 +48,7 @@ devDependencies:
unplugin-auto-import: 0.12.1_@vueuse+core@9.10.0 unplugin-auto-import: 0.12.1_@vueuse+core@9.10.0
unplugin-icons: 0.15.1 unplugin-icons: 0.15.1
unplugin-vue-components: 0.22.12_vue@3.2.45 unplugin-vue-components: 0.22.12_vue@3.2.45
vite: 4.0.4 vite: 4.0.4_@types+node@18.11.18
vite-plugin-vue-markdown: 0.22.2_vite@4.0.4 vite-plugin-vue-markdown: 0.22.2_vite@4.0.4
vue-tsc: 1.0.24_typescript@4.9.4 vue-tsc: 1.0.24_typescript@4.9.4
@@ -431,6 +433,10 @@ packages:
resolution: {integrity: sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==} resolution: {integrity: sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==}
dev: true dev: true
/@types/node/18.11.18:
resolution: {integrity: sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==}
dev: true
/@types/web-bluetooth/0.0.16: /@types/web-bluetooth/0.0.16:
resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==} resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==}
@@ -441,7 +447,7 @@ packages:
vite: ^4.0.0 vite: ^4.0.0
vue: ^3.2.25 vue: ^3.2.25
dependencies: dependencies:
vite: 4.0.4 vite: 4.0.4_@types+node@18.11.18
vue: 3.2.45 vue: 3.2.45
dev: true dev: true
@@ -1515,12 +1521,12 @@ packages:
'@rollup/pluginutils': 5.0.2 '@rollup/pluginutils': 5.0.2
'@types/markdown-it': 12.2.3 '@types/markdown-it': 12.2.3
markdown-it: 13.0.1 markdown-it: 13.0.1
vite: 4.0.4 vite: 4.0.4_@types+node@18.11.18
transitivePeerDependencies: transitivePeerDependencies:
- rollup - rollup
dev: true dev: true
/vite/4.0.4: /vite/4.0.4_@types+node@18.11.18:
resolution: {integrity: sha512-xevPU7M8FU0i/80DMR+YhgrzR5KS2ORy1B4xcX/cXLsvnUWvfHuqMmVU6N0YiJ4JWGRJJsLCgjEzKjG9/GKoSw==} resolution: {integrity: sha512-xevPU7M8FU0i/80DMR+YhgrzR5KS2ORy1B4xcX/cXLsvnUWvfHuqMmVU6N0YiJ4JWGRJJsLCgjEzKjG9/GKoSw==}
engines: {node: ^14.18.0 || >=16.0.0} engines: {node: ^14.18.0 || >=16.0.0}
hasBin: true hasBin: true
@@ -1545,6 +1551,7 @@ packages:
terser: terser:
optional: true optional: true
dependencies: dependencies:
'@types/node': 18.11.18
esbuild: 0.16.16 esbuild: 0.16.16
postcss: 8.4.21 postcss: 8.4.21
resolve: 1.22.1 resolve: 1.22.1

12
public/C++.svg Normal file
View File

@@ -0,0 +1,12 @@
<svg xmlns="http://www.w3.org/2000/svg" width="28.45" height="32" viewBox="0 0 256 288">
<path fill="#649AD2"
d="M255.987 84.59c-.002-4.837-1.037-9.112-3.13-12.781c-2.054-3.608-5.133-6.632-9.261-9.023c-34.08-19.651-68.195-39.242-102.264-58.913c-9.185-5.303-18.09-5.11-27.208.27c-13.565 8-81.48 46.91-101.719 58.632C4.071 67.6.015 74.984.013 84.58C0 124.101.013 163.62 0 203.141c0 4.73.993 8.923 2.993 12.537c2.056 3.717 5.177 6.824 9.401 9.269c20.24 11.722 88.164 50.63 101.726 58.631c9.121 5.382 18.027 5.575 27.215.27c34.07-19.672 68.186-39.262 102.272-58.913c4.224-2.444 7.345-5.553 9.401-9.267c1.997-3.614 2.992-7.806 2.992-12.539c0 0 0-79.018-.013-118.539" />
<path fill="#004482"
d="m128.392 143.476l-125.4 72.202c2.057 3.717 5.178 6.824 9.402 9.269c20.24 11.722 88.164 50.63 101.726 58.631c9.121 5.382 18.027 5.575 27.215.27c34.07-19.672 68.186-39.262 102.272-58.913c4.224-2.444 7.345-5.553 9.401-9.267l-124.616-72.192" />
<path fill="#1A4674"
d="M91.25 164.863c7.297 12.738 21.014 21.33 36.75 21.33c15.833 0 29.628-8.7 36.888-21.576l-36.496-21.141l-37.142 21.387" />
<path fill="#01589C"
d="M255.987 84.59c-.002-4.837-1.037-9.112-3.13-12.781l-124.465 71.667l124.616 72.192c1.997-3.614 2.99-7.806 2.992-12.539c0 0 0-79.018-.013-118.539" />
<path fill="#FFF"
d="M249.135 148.636h-9.738v9.74h-9.74v-9.74h-9.737V138.9h9.737v-9.738h9.74v9.738h9.738v9.737ZM128 58.847c31.135 0 58.358 16.74 73.17 41.709l.444.759l-37.001 21.307c-7.333-12.609-20.978-21.094-36.613-21.094c-23.38 0-42.333 18.953-42.333 42.332a42.13 42.13 0 0 0 5.583 21.003c7.297 12.738 21.014 21.33 36.75 21.33c15.659 0 29.325-8.51 36.647-21.153l.241-.423l36.947 21.406c-14.65 25.597-42.228 42.851-73.835 42.851c-31.549 0-59.084-17.185-73.754-42.707c-7.162-12.459-11.26-26.904-11.26-42.307c0-46.95 38.061-85.013 85.014-85.013Zm75.865 70.314v9.738h9.737v9.737h-9.737v9.74h-9.738v-9.74h-9.738V138.9h9.738v-9.738h9.738Z" />
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

8
public/C.svg Normal file
View File

@@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="28.45" height="32" viewBox="0 0 256 288">
<path fill="#A9B9CB"
d="M255.987 85.672c-.002-4.843-1.037-9.122-3.129-12.794c-2.055-3.612-5.134-6.638-9.262-9.032c-34.081-19.67-68.195-39.28-102.264-58.97c-9.185-5.307-18.091-5.114-27.208.27c-13.565 8.008-81.481 46.956-101.719 58.689C4.071 68.665.015 76.056.013 85.663C0 125.221.013 164.777 0 204.336c.002 4.736.993 8.932 2.993 12.55c2.056 3.72 5.177 6.83 9.401 9.278c20.239 11.733 88.164 50.678 101.726 58.688c9.121 5.387 18.027 5.579 27.215.27c34.07-19.691 68.186-39.3 102.272-58.97c4.224-2.447 7.345-5.559 9.401-9.276c1.997-3.618 2.99-7.814 2.992-12.551c0 0 0-79.094-.013-118.653" />
<path fill="#7F8B99"
d="M141.101 5.134c-9.17-5.294-18.061-5.101-27.163.269C100.395 13.39 32.59 52.237 12.385 63.94C4.064 68.757.015 76.129.013 85.711C0 125.166.013 164.62 0 204.076c.002 4.724.991 8.909 2.988 12.517c2.053 3.711 5.169 6.813 9.386 9.254a9008.51 9008.51 0 0 0 20.159 11.62L219.625 50.375c-26.178-15.074-52.363-30.136-78.524-45.241" />
<path fill="#FFF"
d="m154.456 126.968l39.839.281c0-16.599-16.802-57.249-64.973-57.249c-30.691 0-71.951 19.512-71.951 75.61c0 56.097 40.447 74.39 71.951 74.39c51.017 0 63.21-35.302 63.21-55.252l-38.007-2.173s1.017 23.075-25.406 23.075c-24.39 0-28.46-29.878-28.46-40.04c0-15.447 5.493-40.244 28.46-40.244c22.968 0 25.337 21.602 25.337 21.602" />
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

4
public/Golang.svg Normal file
View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="85.34" height="32" viewBox="0 0 512 192">
<path fill="#00ACD7"
d="m292.533 13.295l1.124.75c13.212 8.725 22.685 20.691 28.917 35.15c1.496 2.243.499 3.49-2.493 4.237l-5.063 1.296c-11.447 2.949-20.53 5.429-31.827 8.378l-6.443 1.678c-2.32.574-2.96.333-5.428-2.477l-.348-.399c-3.519-3.988-6.155-6.652-10.817-9.03l-.899-.443c-15.705-7.727-30.911-5.484-45.12 3.74c-16.952 10.968-25.677 27.172-25.428 47.364c.25 19.942 13.96 36.395 33.654 39.137c16.951 2.244 31.16-3.739 42.378-16.452c2.244-2.743 4.238-5.734 6.73-9.224h-48.11c-5.235 0-6.481-3.24-4.736-7.478l.864-2.035c3.204-7.454 8.173-18.168 11.4-24.294l.704-1.319c.862-1.494 2.612-3.513 5.977-3.513h80.224c3.603-11.415 9.449-22.201 17.246-32.407c18.198-23.931 40.135-36.396 69.8-41.63c25.427-4.488 49.359-1.995 71.046 12.713c19.694 13.461 31.909 31.66 35.15 55.59c4.237 33.654-5.485 61.075-28.668 84.508c-16.453 16.702-36.645 27.172-59.829 31.908c-6.73 1.247-13.461 1.496-19.942 2.244c-22.685-.499-43.376-6.98-60.826-21.937c-12.273-10.61-20.727-23.648-24.928-38.828a104.937 104.937 0 0 1-10.47 16.89c-17.949 23.683-41.381 38.39-71.046 42.38c-24.43 3.24-47.115-1.497-67.058-16.454c-18.447-13.96-28.917-32.407-31.66-55.34c-3.24-27.173 4.737-51.603 21.19-73.041c17.7-23.184 41.132-37.891 69.8-43.126c22.999-4.16 45.037-1.595 64.936 11.464ZM411.12 49.017l-.798.178c-23.183 5.235-38.14 19.942-43.624 43.375c-4.488 19.444 4.985 39.138 22.934 47.115c13.71 5.983 27.421 5.235 40.633-1.496c19.694-10.22 30.413-26.175 31.66-47.613c-.25-3.24-.25-5.734-.749-8.227c-4.436-24.401-26.664-38.324-50.056-33.332ZM116.416 94.564c.997 0 1.496.748 1.496 1.745l-.499 5.983c0 .997-.997 1.745-1.745 1.745l-54.344-.249c-.997 0-1.246-.748-.748-1.496l3.49-6.232c.499-.748 1.496-1.496 2.493-1.496h49.857ZM121.9 71.63c.997 0 1.496.748 1.247 1.496l-1.995 5.983c-.249.997-1.246 1.495-2.243 1.495l-117.912.25c-.997 0-1.246-.499-.748-1.247l5.235-6.73c.499-.748 1.745-1.247 2.742-1.247H121.9Zm12.963-22.934c.997 0 1.246.748.748 1.496l-4.238 6.481c-.499.748-1.745 1.496-2.493 1.496l-90.24-.25c-.998 0-1.247-.498-.749-1.246l5.235-6.73c.499-.748 1.745-1.247 2.742-1.247h88.995Z" />
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

12
public/Java.svg Normal file
View File

@@ -0,0 +1,12 @@
<svg xmlns="http://www.w3.org/2000/svg" width="23.68" height="32" viewBox="0 0 256 346">
<path fill="#5382A1"
d="M82.554 267.473s-13.198 7.675 9.393 10.272c27.369 3.122 41.356 2.675 71.517-3.034c0 0 7.93 4.972 19.003 9.279c-67.611 28.977-153.019-1.679-99.913-16.517m-8.262-37.814s-14.803 10.958 7.805 13.296c29.236 3.016 52.324 3.263 92.276-4.43c0 0 5.526 5.602 14.215 8.666c-81.747 23.904-172.798 1.885-114.296-17.532" />
<path fill="#E76F00"
d="M143.942 165.515c16.66 19.18-4.377 36.44-4.377 36.44s42.301-21.837 22.874-49.183c-18.144-25.5-32.059-38.172 43.268-81.858c0 0-118.238 29.53-61.765 94.6" />
<path fill="#5382A1"
d="M233.364 295.442s9.767 8.047-10.757 14.273c-39.026 11.823-162.432 15.393-196.714.471c-12.323-5.36 10.787-12.8 18.056-14.362c7.581-1.644 11.914-1.337 11.914-1.337c-13.705-9.655-88.583 18.957-38.034 27.15c137.853 22.356 251.292-10.066 215.535-26.195M88.9 190.48s-62.771 14.91-22.228 20.323c17.118 2.292 51.243 1.774 83.03-.89c25.978-2.19 52.063-6.85 52.063-6.85s-9.16 3.923-15.787 8.448c-63.744 16.765-186.886 8.966-151.435-8.183c29.981-14.492 54.358-12.848 54.358-12.848m112.605 62.942c64.8-33.672 34.839-66.03 13.927-61.67c-5.126 1.066-7.411 1.99-7.411 1.99s1.903-2.98 5.537-4.27c41.37-14.545 73.187 42.897-13.355 65.647c0 .001 1.003-.895 1.302-1.697" />
<path fill="#E76F00"
d="M162.439.371s35.887 35.9-34.037 91.101c-56.071 44.282-12.786 69.53-.023 98.377c-32.73-29.53-56.75-55.526-40.635-79.72C111.395 74.612 176.918 57.393 162.439.37" />
<path fill="#5382A1"
d="M95.268 344.665c62.199 3.982 157.712-2.209 159.974-31.64c0 0-4.348 11.158-51.404 20.018c-53.088 9.99-118.564 8.824-157.399 2.421c.001 0 7.95 6.58 48.83 9.201" />
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

5
public/JavaScript.svg Normal file
View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 256 256">
<path fill="#F7DF1E" d="M0 0h256v256H0V0Z" />
<path
d="m67.312 213.932l19.59-11.856c3.78 6.701 7.218 12.371 15.465 12.371c7.905 0 12.89-3.092 12.89-15.12v-81.798h24.057v82.138c0 24.917-14.606 36.259-35.916 36.259c-19.245 0-30.416-9.967-36.087-21.996m85.07-2.576l19.588-11.341c5.157 8.421 11.859 14.607 23.715 14.607c9.969 0 16.325-4.984 16.325-11.858c0-8.248-6.53-11.17-17.528-15.98l-6.013-2.58c-17.357-7.387-28.87-16.667-28.87-36.257c0-18.044 13.747-31.792 35.228-31.792c15.294 0 26.292 5.328 34.196 19.247l-18.732 12.03c-4.125-7.389-8.591-10.31-15.465-10.31c-7.046 0-11.514 4.468-11.514 10.31c0 7.217 4.468 10.14 14.778 14.608l6.014 2.577c20.45 8.765 31.963 17.7 31.963 37.804c0 21.654-17.012 33.51-39.867 33.51c-22.339 0-36.774-10.654-43.819-24.574" />
</svg>

After

Width:  |  Height:  |  Size: 868 B

16
public/Python2.svg Normal file
View File

@@ -0,0 +1,16 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32.13" height="32" viewBox="0 0 256 255">
<defs>
<linearGradient id="svgIDa" x1="12.959%" x2="79.639%" y1="12.039%" y2="78.201%">
<stop offset="0%" stop-color="#387EB8" />
<stop offset="100%" stop-color="#366994" />
</linearGradient>
<linearGradient id="svgIDb" x1="19.128%" x2="90.742%" y1="20.579%" y2="88.429%">
<stop offset="0%" stop-color="#FFE052" />
<stop offset="100%" stop-color="#FFC331" />
</linearGradient>
</defs>
<path fill="url(#svgIDa)"
d="M126.916.072c-64.832 0-60.784 28.115-60.784 28.115l.072 29.128h61.868v8.745H41.631S.145 61.355.145 126.77c0 65.417 36.21 63.097 36.21 63.097h21.61v-30.356s-1.165-36.21 35.632-36.21h61.362s34.475.557 34.475-33.319V33.97S194.67.072 126.916.072ZM92.802 19.66a11.12 11.12 0 0 1 11.13 11.13a11.12 11.12 0 0 1-11.13 11.13a11.12 11.12 0 0 1-11.13-11.13a11.12 11.12 0 0 1 11.13-11.13Z" />
<path fill="url(#svgIDb)"
d="M128.757 254.126c64.832 0 60.784-28.115 60.784-28.115l-.072-29.127H127.6v-8.745h86.441s41.486 4.705 41.486-60.712c0-65.416-36.21-63.096-36.21-63.096h-21.61v30.355s1.165 36.21-35.632 36.21h-61.362s-34.475-.557-34.475 33.32v56.013s-5.235 33.897 62.518 33.897Zm34.114-19.586a11.12 11.12 0 0 1-11.13-11.13a11.12 11.12 0 0 1 11.13-11.131a11.12 11.12 0 0 1 11.13 11.13a11.12 11.12 0 0 1-11.13 11.13Z" />
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

16
public/Python3.svg Normal file
View File

@@ -0,0 +1,16 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32.13" height="32" viewBox="0 0 256 255">
<defs>
<linearGradient id="svgIDa" x1="12.959%" x2="79.639%" y1="12.039%" y2="78.201%">
<stop offset="0%" stop-color="#387EB8" />
<stop offset="100%" stop-color="#366994" />
</linearGradient>
<linearGradient id="svgIDb" x1="19.128%" x2="90.742%" y1="20.579%" y2="88.429%">
<stop offset="0%" stop-color="#FFE052" />
<stop offset="100%" stop-color="#FFC331" />
</linearGradient>
</defs>
<path fill="url(#svgIDa)"
d="M126.916.072c-64.832 0-60.784 28.115-60.784 28.115l.072 29.128h61.868v8.745H41.631S.145 61.355.145 126.77c0 65.417 36.21 63.097 36.21 63.097h21.61v-30.356s-1.165-36.21 35.632-36.21h61.362s34.475.557 34.475-33.319V33.97S194.67.072 126.916.072ZM92.802 19.66a11.12 11.12 0 0 1 11.13 11.13a11.12 11.12 0 0 1-11.13 11.13a11.12 11.12 0 0 1-11.13-11.13a11.12 11.12 0 0 1 11.13-11.13Z" />
<path fill="url(#svgIDb)"
d="M128.757 254.126c64.832 0 60.784-28.115 60.784-28.115l-.072-29.127H127.6v-8.745h86.441s41.486 4.705 41.486-60.712c0-65.416-36.21-63.096-36.21-63.096h-21.61v30.355s1.165 36.21-35.632 36.21h-61.362s-34.475-.557-34.475 33.32v56.013s-5.235 33.897 62.518 33.897Zm34.114-19.586a11.12 11.12 0 0 1-11.13-11.13a11.12 11.12 0 0 1 11.13-11.131a11.12 11.12 0 0 1 11.13 11.13a11.12 11.12 0 0 1-11.13 11.13Z" />
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

208
public/dracula.json Normal file
View File

@@ -0,0 +1,208 @@
{
"base": "vs-dark",
"inherit": true,
"rules": [
{
"background": "282a36",
"token": ""
},
{
"foreground": "6272a4",
"token": "comment"
},
{
"foreground": "f1fa8c",
"token": "string"
},
{
"foreground": "bd93f9",
"token": "constant.numeric"
},
{
"foreground": "bd93f9",
"token": "constant.language"
},
{
"foreground": "bd93f9",
"token": "constant.character"
},
{
"foreground": "bd93f9",
"token": "constant.other"
},
{
"foreground": "ffb86c",
"token": "variable.other.readwrite.instance"
},
{
"foreground": "ff79c6",
"token": "constant.character.escaped"
},
{
"foreground": "ff79c6",
"token": "constant.character.escape"
},
{
"foreground": "ff79c6",
"token": "string source"
},
{
"foreground": "ff79c6",
"token": "string source.ruby"
},
{
"foreground": "ff79c6",
"token": "keyword"
},
{
"foreground": "ff79c6",
"token": "storage"
},
{
"foreground": "8be9fd",
"fontStyle": "italic",
"token": "storage.type"
},
{
"foreground": "50fa7b",
"fontStyle": "underline",
"token": "entity.name.class"
},
{
"foreground": "50fa7b",
"fontStyle": "italic underline",
"token": "entity.other.inherited-class"
},
{
"foreground": "50fa7b",
"token": "entity.name.function"
},
{
"foreground": "ffb86c",
"fontStyle": "italic",
"token": "variable.parameter"
},
{
"foreground": "ff79c6",
"token": "entity.name.tag"
},
{
"foreground": "50fa7b",
"token": "entity.other.attribute-name"
},
{
"foreground": "8be9fd",
"token": "support.function"
},
{
"foreground": "6be5fd",
"token": "support.constant"
},
{
"foreground": "66d9ef",
"fontStyle": " italic",
"token": "support.type"
},
{
"foreground": "66d9ef",
"fontStyle": " italic",
"token": "support.class"
},
{
"foreground": "f8f8f0",
"background": "ff79c6",
"token": "invalid"
},
{
"foreground": "f8f8f0",
"background": "bd93f9",
"token": "invalid.deprecated"
},
{
"foreground": "cfcfc2",
"token": "meta.structure.dictionary.json string.quoted.double.json"
},
{
"foreground": "6272a4",
"token": "meta.diff"
},
{
"foreground": "6272a4",
"token": "meta.diff.header"
},
{
"foreground": "ff79c6",
"token": "markup.deleted"
},
{
"foreground": "50fa7b",
"token": "markup.inserted"
},
{
"foreground": "e6db74",
"token": "markup.changed"
},
{
"foreground": "bd93f9",
"token": "constant.numeric.line-number.find-in-files - match"
},
{
"foreground": "e6db74",
"token": "entity.name.filename"
},
{
"foreground": "f83333",
"token": "message.error"
},
{
"foreground": "eeeeee",
"token": "punctuation.definition.string.begin.json - meta.structure.dictionary.value.json"
},
{
"foreground": "eeeeee",
"token": "punctuation.definition.string.end.json - meta.structure.dictionary.value.json"
},
{
"foreground": "8be9fd",
"token": "meta.structure.dictionary.json string.quoted.double.json"
},
{
"foreground": "f1fa8c",
"token": "meta.structure.dictionary.value.json string.quoted.double.json"
},
{
"foreground": "50fa7b",
"token": "meta meta meta meta meta meta meta.structure.dictionary.value string"
},
{
"foreground": "ffb86c",
"token": "meta meta meta meta meta meta.structure.dictionary.value string"
},
{
"foreground": "ff79c6",
"token": "meta meta meta meta meta.structure.dictionary.value string"
},
{
"foreground": "bd93f9",
"token": "meta meta meta meta.structure.dictionary.value string"
},
{
"foreground": "50fa7b",
"token": "meta meta meta.structure.dictionary.value string"
},
{
"foreground": "ffb86c",
"token": "meta meta.structure.dictionary.value string"
}
],
"colors": {
"editor.foreground": "#f8f8f2",
"editor.background": "#282a36",
"editor.selectionBackground": "#44475a",
"editor.lineHighlightBackground": "#44475a",
"editorCursor.foreground": "#f8f8f0",
"editorWhitespace.foreground": "#3B3A32",
"editorIndentGuide.activeBackground": "#9D550FB0",
"editor.selectionHighlightBorder": "#222218"
}
}

1
src/components.d.ts vendored
View File

@@ -43,7 +43,6 @@ declare module '@vue/runtime-core' {
IEpLoading: typeof import('~icons/ep/loading')['default'] IEpLoading: typeof import('~icons/ep/loading')['default']
IEpSelect: typeof import('~icons/ep/select')['default'] IEpSelect: typeof import('~icons/ep/select')['default']
IEpSemiSelect: typeof import('~icons/ep/semi-select')['default'] IEpSemiSelect: typeof import('~icons/ep/semi-select')['default']
IEpVideoPlay: typeof import('~icons/ep/video-play')['default']
RouterLink: typeof import('vue-router')['RouterLink'] RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView'] RouterView: typeof import('vue-router')['RouterView']
} }

View File

@@ -3,12 +3,13 @@ import { createPinia } from "pinia"
import "normalize.css" import "normalize.css"
import loader from "@monaco-editor/loader" import loader from "@monaco-editor/loader"
import storage from "utils/storage"
import { STORAGE_KEY } from "utils/constants"
import { routes } from "./routes"
import App from "./App.vue" import App from "./App.vue"
import storage from "./utils/storage" import { useLoginStore } from "~/shared/store/login"
import routes from "./routes"
import { STORAGE_KEY } from "./utils/constants"
import { useLoginStore } from "./shared/store/login"
const router = createRouter({ const router = createRouter({
history: createWebHistory(), history: createWebHistory(),
@@ -31,6 +32,11 @@ router.beforeEach((to, from, next) => {
const pinia = createPinia() const pinia = createPinia()
Promise.all([loader.init(), fetch("/dracula.json")]).then(([monaco, dark]) => {
window.monaco = monaco
dark.json().then((data) => monaco.editor.defineTheme("dark", data))
})
loader.config({ loader.config({
paths: { vs: "https://cdn.staticfile.org/monaco-editor/0.34.1/min/vs" }, paths: { vs: "https://cdn.staticfile.org/monaco-editor/0.34.1/min/vs" },
"vs/nls": { availableLanguages: { "*": "zh-cn" } }, "vs/nls": { availableLanguages: { "*": "zh-cn" } },

View File

@@ -1,8 +1,8 @@
import { useAxios } from "@vueuse/integrations/useAxios" import { useAxios } from "@vueuse/integrations/useAxios"
import http from "./../utils/http" import http from "utils/http"
import { getACRate } from "./../utils/functions" import { getACRate } from "utils/functions"
import { DIFFICULTY } from "./../utils/constants" import { DIFFICULTY } from "utils/constants"
import { Problem, SubmitCodePayload, Submission } from "./../utils/types" import { Problem, SubmitCodePayload, Submission } from "utils/types"
function filterResult(result: Problem) { function filterResult(result: Problem) {
const newResult: any = { const newResult: any = {

View File

@@ -1,11 +1,11 @@
<script lang="ts" setup> <script lang="ts" setup>
import { LANGUAGE_LABEL, SOURCES } from "../../../utils/constants" import { SOURCES } from "utils/constants"
import { Problem } from "../../../utils/types" import { Problem } from "utils/types"
import { useCodeStore } from "../../store/code" import Monaco from "~/shared/Monaco/index.vue"
import { submissionExists } from "../../api" import { useCodeStore } from "oj/store/code"
import { submissionExists } from "oj/api"
import { TabsPaneContext } from "element-plus" import { TabsPaneContext } from "element-plus"
import Monaco from "../../../shared/Monaco/index.vue"
import SubmitPanel from "./SubmitPanel.vue" import SubmitPanel from "./SubmitPanel.vue"
import TestcasePanel from "./TestcasePanel.vue" import TestcasePanel from "./TestcasePanel.vue"
@@ -54,12 +54,9 @@ function onTab(pane: TabsPaneContext) {
<el-form inline> <el-form inline>
<el-form-item label="语言" label-width="60"> <el-form-item label="语言" label-width="60">
<el-select v-model="code.language" class="language"> <el-select v-model="code.language" class="language">
<el-option <el-option v-for="item in problem.languages" :key="item" :value="item">
v-for="item in problem.languages" <img class="logo" :src="`/${item}.svg`" alt="logo" />&nbsp;&nbsp;
:key="item" <span>{{ item }}</span>
:value="item"
:label="LANGUAGE_LABEL[item]"
>
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -82,10 +79,14 @@ function onTab(pane: TabsPaneContext) {
<style scoped> <style scoped>
.language { .language {
width: 100px; width: 110px;
} }
.editor { .editor {
min-height: 200px; min-height: 200px;
} }
.logo {
width: 12px;
}
</style> </style>

View File

@@ -1,9 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import { Problem } from "../../../utils/types"
import { Flag, CloseBold, Select } from "@element-plus/icons-vue" import { Flag, CloseBold, Select } from "@element-plus/icons-vue"
import { useCodeStore } from "../../store/code" import { useCodeStore } from "oj/store/code"
import { SOURCES } from "../../../utils/constants" import { SOURCES } from "utils/constants"
import { createTestSubmission } from "../../../utils/judge" import { Problem } from "utils/types"
import { createTestSubmission } from "utils/judge"
interface Props { interface Props {
problem: Problem problem: Problem

View File

@@ -1,8 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { DIFFICULTY } from "../../../utils/constants" import { DIFFICULTY } from "utils/constants"
import { getACRate, getTagColor, parseTime } from "../../../utils/functions" import { getACRate, getTagColor, parseTime } from "utils/functions"
import { isDesktop } from "../../../utils/breakpoints" import { isDesktop } from "utils/breakpoints"
import { Problem } from "../../../utils/types" import { Problem } from "utils/types"
interface Props { interface Props {
problem: Problem problem: Problem

View File

@@ -0,0 +1,18 @@
<script setup lang="ts">
import Pagination from "~/shared/Pagination/index.vue"
const query = reactive({
page: 1,
limit: 10,
})
const total = ref(100)
</script>
<template>
<el-table max-height="calc(100vh - 171px)"></el-table>
<Pagination
:total="total"
v-model:limit="query.limit"
v-model:page="query.page"
/>
</template>
<style scoped></style>

View File

@@ -1,20 +1,13 @@
<script setup lang="ts"> <script setup lang="ts">
import party from "party-js" import party from "party-js"
import { Ref } from "vue" import { Ref } from "vue"
import { import { SOURCES, JUDGE_STATUS, SubmissionStatus } from "utils/constants"
SOURCES, import { submissionMemoryFormat, submissionTimeFormat } from "utils/functions"
JUDGE_STATUS, import { Problem, Submission, SubmitCodePayload } from "utils/types"
SubmissionStatus, import { getSubmission, submitCode } from "oj/api"
} from "../../../utils/constants" import { useCodeStore } from "oj/store/code"
import {
submissionMemoryFormat,
submissionTimeFormat,
} from "../../../utils/functions"
import { Problem, Submission, SubmitCodePayload } from "../../../utils/types"
import { getSubmission, submitCode } from "../../api"
import SubmissionResultTag from "../../components/SubmissionResultTag.vue" import SubmissionResultTag from "../../components/SubmissionResultTag.vue"
import { useCodeStore } from "../../store/code"
const problem = inject<Ref<Problem>>("problem") const problem = inject<Ref<Problem>>("problem")
const { code } = useCodeStore() const { code } = useCodeStore()
@@ -198,7 +191,12 @@ defineExpose({ submit })
<el-scrollbar v-if="msg" height="354" class="result" noresize> <el-scrollbar v-if="msg" height="354" class="result" noresize>
<div>{{ msg }}</div> <div>{{ msg }}</div>
</el-scrollbar> </el-scrollbar>
<el-table v-if="infoTable.length" height="354" :data="infoTable" stripe> <el-table
v-if="infoTable.length"
max-height="354"
:data="infoTable"
stripe
>
<el-table-column prop="test_case" label="测试用例" align="center" /> <el-table-column prop="test_case" label="测试用例" align="center" />
<el-table-column label="测试状态" width="120" align="center"> <el-table-column label="测试状态" width="120" align="center">
<template #default="scope"> <template #default="scope">

View File

@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { createTestSubmission } from "../../../utils/judge" import { createTestSubmission } from "utils/judge"
import { useCodeStore } from "../../store/code" import { useCodeStore } from "oj/store/code"
const input = ref("") const input = ref("")
const result = ref("") const result = ref("")

View File

@@ -2,8 +2,9 @@
import Editor from "./components/Editor.vue" import Editor from "./components/Editor.vue"
import ProblemContent from "./components/ProblemContent.vue" import ProblemContent from "./components/ProblemContent.vue"
import ProblemInfo from "./components/ProblemInfo.vue" import ProblemInfo from "./components/ProblemInfo.vue"
import { getProblem } from "../api" import SubmissionList from "./components/SubmissionList.vue"
import { isDesktop, isMobile } from "../../utils/breakpoints" import { getProblem } from "oj/api"
import { isDesktop, isMobile } from "utils/breakpoints"
interface Props { interface Props {
problemID: string problemID: string
@@ -32,11 +33,13 @@ provide("problem", readonly(problem))
<el-tab-pane v-if="isMobile" label="代码编辑" lazy> <el-tab-pane v-if="isMobile" label="代码编辑" lazy>
<Editor :problem="problem" /> <Editor :problem="problem" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="提交列表" lazy>
<SubmissionList />
</el-tab-pane>
<el-tab-pane label="比赛信息" v-if="props.contestID" lazy></el-tab-pane> <el-tab-pane label="比赛信息" v-if="props.contestID" lazy></el-tab-pane>
<el-tab-pane label="题目信息" lazy> <el-tab-pane label="统计信息" lazy>
<ProblemInfo :problem="problem" /> <ProblemInfo :problem="problem" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="提交列表">3</el-tab-pane>
</el-tabs> </el-tabs>
</el-col> </el-col>
<el-col v-if="isDesktop" :span="12"> <el-col v-if="isDesktop" :span="12">

View File

@@ -1,8 +1,10 @@
<script setup lang="ts"> <script setup lang="ts">
import { useUserStore } from "../../shared/store/user" import { useUserStore } from "~/shared/store/user"
import { filterEmptyValue, getTagColor } from "../../utils/functions" import { filterEmptyValue, getTagColor } from "utils/functions"
import { isDesktop } from "../../utils/breakpoints" import { isDesktop } from "utils/breakpoints"
import { getProblemList, getProblemTagList, getRandomProblemID } from "../api" import { getProblemList, getProblemTagList, getRandomProblemID } from "oj/api"
import Pagination from "~/shared/Pagination/index.vue"
const difficultyOptions = [ const difficultyOptions = [
{ label: "全部", value: "" }, { label: "全部", value: "" },
@@ -182,35 +184,15 @@ onMounted(listProblems)
/> />
<el-table-column v-if="isDesktop" prop="rate" label="通过率" width="100" /> <el-table-column v-if="isDesktop" prop="rate" label="通过率" width="100" />
</el-table> </el-table>
<el-pagination <Pagination
class="right margin"
:layout="isDesktop ? 'prev,pager,next,sizes' : 'prev,next,sizes'"
background
:total="total" :total="total"
:page-sizes="[10, 20, 30]" v-model:limit="query.limit"
:pager-count="5" v-model:page="query.page"
v-model:page-size="query.limit"
v-model:current-page="query.page"
/> />
</template> </template>
<style scoped> <style scoped>
.margin {
margin-top: 24px;
}
.right {
float: right;
}
.pointer { .pointer {
cursor: pointer; cursor: pointer;
} }
.panel {
width: 400px;
padding: 0 4px;
}
.panel-tag {
margin: 4px;
}
</style> </style>

View File

@@ -1,4 +1,4 @@
import { Code } from "../../utils/types" import { Code } from "utils/types"
export const useCodeStore = defineStore("code", () => { export const useCodeStore = defineStore("code", () => {
const code = reactive<Code>({ const code = reactive<Code>({

View File

@@ -1,55 +1,54 @@
import Home from "./oj/index.vue" export const routes = [
import Problems from "./oj/problem/list.vue"
const routes = [
{ {
path: "/", path: "/",
component: Home, component: () => import("~/shared/layout/default.vue"),
children: [ children: [
{ path: "", component: Problems }, { path: "", component: () => import("oj/problem/list.vue") },
{ path: "/learn/:step*", component: () => import("./learn/index.vue") },
{ {
path: "problem/:problemID", path: "problem/:problemID",
component: () => import("./oj/problem/detail.vue"), component: () => import("oj/problem/detail.vue"),
props: true, props: true,
name: "ProblemDetail", name: "ProblemDetail",
}, },
{ {
path: "status", path: "status",
component: () => import("./oj/status/list.vue"), component: () => import("oj/status/list.vue"),
meta: { requiresAuth: true },
}, },
{ {
path: "status/:statusID", path: "status/:statusID",
component: () => import("./oj/status/detail.vue"), component: () => import("oj/status/detail.vue"),
props: true, props: true,
}, },
{ {
path: "contest", path: "contest",
component: () => import("./oj/contest/list.vue"), component: () => import("oj/contest/list.vue"),
meta: { requiresAuth: true }, meta: { requiresAuth: true },
}, },
{ {
path: "contest/:contestID", path: "contest/:contestID",
component: () => import("./oj/contest/detail.vue"), component: () => import("oj/contest/detail.vue"),
props: true, props: true,
}, },
{ {
path: "contest/:contestID/problem/:problemID", path: "contest/:contestID/problem/:problemID",
component: () => import("./oj/problem/detail.vue"), component: () => import("oj/problem/detail.vue"),
props: true, props: true,
name: "ContestProblemDetail", name: "ContestProblemDetail",
}, },
{ {
path: "rank", path: "rank",
component: () => import("./oj/rank/list.vue"), component: () => import("oj/rank/list.vue"),
},
{
path: "/admin",
component: () => import("./admin/index.vue"),
}, },
], ],
}, },
{
path: "/learn",
component: () => import("~/shared/layout/default.vue"),
children: [{ path: ":step*", component: () => import("learn/index.vue") }],
},
{
path: "/admin",
component: () => import("~/shared/layout/admin.vue"),
children: [{ path: "", component: () => import("admin/index.vue") }],
},
] ]
export default routes

View File

@@ -1,8 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { useLoginStore } from "../store/login" import { useLoginStore } from "../store/login"
import { useSignupStore } from "../../oj/store/signup" import { useSignupStore } from "~/shared/store/signup"
import { useUserStore } from "../store/user"
import { logout } from "../api" import { logout } from "../api"
import { useUserStore } from "../store/user"
const loginStore = useLoginStore() const loginStore = useLoginStore()
const signupStore = useSignupStore() const signupStore = useSignupStore()

View File

@@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { FormInstance } from "element-plus" import { FormInstance } from "element-plus"
import { useSignupStore } from "../../oj/store/signup" import { useSignupStore } from "~/shared/store/signup"
import { login } from "../api" import { login } from "../api"
import { useLoginStore } from "../store/login" import { useLoginStore } from "../store/login"
import { useUserStore } from "../store/user" import { useUserStore } from "../store/user"

View File

@@ -1,9 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import type * as Monaco from "monaco-editor" import type * as Monaco from "monaco-editor"
import loader from "@monaco-editor/loader" import { LANGUAGE_VALUE } from "utils/constants"
import { LANGUAGE_VALUE } from "../../utils/constants" import { LANGUAGE } from "utils/types"
import { LANGUAGE } from "../../utils/types" import { isMobile } from "utils/breakpoints"
import { isMobile } from "../../utils/breakpoints"
interface Props { interface Props {
value: string value: string
@@ -25,20 +24,18 @@ const emit = defineEmits<{
}>() }>()
const monacoEditorRef = ref() const monacoEditorRef = ref()
let editor: Monaco.editor.IStandaloneCodeEditor | null let editor: Monaco.editor.IStandaloneCodeEditor
onMounted(async function () { onMounted(function () {
const monaco = await loader.init() const model = window.monaco.editor.createModel(
const model = monaco.editor.createModel(
props.value, props.value,
LANGUAGE_VALUE[props.language], LANGUAGE_VALUE[props.language],
monaco.Uri.parse(`file:///root/${Date.now()}.${ext()}`) window.monaco.Uri.parse(`file:///root/${Date.now()}.${ext()}`)
) )
editor = monaco.editor.create(monacoEditorRef.value, { editor = window.monaco.editor.create(monacoEditorRef.value, {
model, model,
theme: "vs-dark", // 官方自带三种主题vs, hc-black, or vs-dark theme: "dark", // 官方自带三种主题vs, hc-black, or vs-dark
minimap: { minimap: {
enabled: false, enabled: false,
}, },
@@ -47,6 +44,15 @@ onMounted(async function () {
tabSize: 4, tabSize: 4,
fontSize: isMobile.value ? 20 : 24, // 字体大小 fontSize: isMobile.value ? 20 : 24, // 字体大小
scrollBeyondLastLine: false, scrollBeyondLastLine: false,
lineDecorationsWidth: 0,
scrollBeyondLastColumn: 0,
glyphMargin: false,
scrollbar: {
useShadows: false,
vertical: "hidden",
horizontal: "hidden",
},
overviewRulerLanes: 0,
}) })
model.onDidChangeContent(() => { model.onDidChangeContent(() => {
@@ -64,7 +70,7 @@ onMounted(async function () {
}) })
watchEffect(() => { watchEffect(() => {
monaco.editor.setModelLanguage(model, LANGUAGE_VALUE[props.language]) window.monaco.editor.setModelLanguage(model, LANGUAGE_VALUE[props.language])
}) })
watchEffect(() => { watchEffect(() => {

View File

@@ -0,0 +1,42 @@
<script setup lang="ts">
import { isDesktop } from "utils/breakpoints"
interface Props {
total: number
limit: number
page: number
}
const props = withDefaults(defineProps<Props>(), {
limit: 10,
page: 1,
})
const emit = defineEmits(["update:limit", "update:page"])
const limit = ref(props.limit)
const page = ref(props.page)
watch(limit, () => emit("update:limit", limit))
watch(page, () => emit("update:page", page))
</script>
<template>
<el-pagination
class="right margin"
:layout="isDesktop ? 'prev,pager,next,sizes' : 'prev,next,sizes'"
background
:total="props.total"
:page-sizes="[10, 20, 30]"
:pager-count="5"
v-model:page-size="limit"
v-model:current-page="page"
/>
</template>
<style scoped>
.margin {
margin-top: 24px;
}
.right {
float: right;
}
</style>

View File

@@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { useSignupStore } from "../../oj/store/signup" import { useSignupStore } from "../store/signup"
const store = useSignupStore() const store = useSignupStore()
</script> </script>

View File

@@ -36,7 +36,6 @@
import Resizer from "./Resizer.vue" import Resizer from "./Resizer.vue"
import Pane from "./Pane.vue" import Pane from "./Pane.vue"
import { computed, ref } from "vue" import { computed, ref } from "vue"
import { classNameToArray } from "element-plus/es/utils"
interface Props { interface Props {
minPercent?: number minPercent?: number

View File

@@ -1,5 +1,5 @@
import { useAxios } from "@vueuse/integrations/useAxios" import { useAxios } from "@vueuse/integrations/useAxios"
import http from "../utils/http" import http from "utils/http"
export function login(data: { username: string; password: string }) { export function login(data: { username: string; password: string }) {
return useAxios("login", { method: "post", data }, http, { return useAxios("login", { method: "post", data }, http, {

View File

@@ -0,0 +1,11 @@
<script setup lang="ts"></script>
<template>
<el-container>
<el-main>
<router-view></router-view>
</el-main>
</el-container>
</template>
<style scoped></style>

View File

@@ -1,24 +1,24 @@
<script setup lang="ts"> <script setup lang="ts">
import Login from "../shared/Login/index.vue" import Login from "../Login/index.vue"
import Signup from "../shared/Signup/index.vue" import Signup from "../Signup/index.vue"
import Header from "../shared/Header/index.vue" import Header from "../Header/index.vue"
</script> </script>
<template> <template>
<el-container> <el-container>
<el-header class="header"> <el-header class="header">
<Header /> <Header />
</el-header> </el-header>
<el-main> <el-main>
<router-view></router-view> <router-view></router-view>
</el-main> </el-main>
<Login /> <Login />
<Signup /> <Signup />
</el-container> </el-container>
</template> </template>
<style scoped> <style scoped>
.header { .header {
display: flex; display: flex;
} }
</style> </style>

View File

@@ -1,9 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import type * as Monaco from "monaco-editor" import type * as Monaco from "monaco-editor"
import loader from "@monaco-editor/loader" import { LANGUAGE_VALUE } from "utils/constants"
import { LANGUAGE_VALUE } from "../../utils/constants" import { LANGUAGE } from "utils/types"
import { LANGUAGE } from "../../utils/types" import { isMobile } from "utils/breakpoints"
import { isMobile } from "../../utils/breakpoints"
interface Props { interface Props {
value: string value: string
@@ -25,20 +24,18 @@ const emit = defineEmits<{
}>() }>()
const monacoEditorRef = ref() const monacoEditorRef = ref()
let editor: Monaco.editor.IStandaloneCodeEditor | null let editor: Monaco.editor.IStandaloneCodeEditor
onMounted(async function () { onMounted(function () {
const monaco = await loader.init() const model = window.monaco.editor.createModel(
const model = monaco.editor.createModel(
props.value, props.value,
LANGUAGE_VALUE[props.language], LANGUAGE_VALUE[props.language],
monaco.Uri.parse(`file:///root/${Date.now()}.${ext()}`) window.monaco.Uri.parse(`file:///root/${Date.now()}.${ext()}`)
) )
editor = monaco.editor.create(monacoEditorRef.value, { editor = window.monaco.editor.create(monacoEditorRef.value, {
model, model,
theme: "vs-dark", // 官方自带三种主题vs, hc-black, or vs-dark theme: "dark", // 官方自带三种主题vs, hc-black, or vs-dark
minimap: { minimap: {
enabled: false, enabled: false,
}, },
@@ -47,6 +44,15 @@ onMounted(async function () {
tabSize: 4, tabSize: 4,
fontSize: isMobile.value ? 20 : 24, // 字体大小 fontSize: isMobile.value ? 20 : 24, // 字体大小
scrollBeyondLastLine: false, scrollBeyondLastLine: false,
lineDecorationsWidth: 0,
scrollBeyondLastColumn: 0,
glyphMargin: false,
scrollbar: {
useShadows: false,
vertical: "hidden",
horizontal: "hidden",
},
overviewRulerLanes: 0,
}) })
model.onDidChangeContent(() => { model.onDidChangeContent(() => {
@@ -64,7 +70,7 @@ onMounted(async function () {
}) })
watchEffect(() => { watchEffect(() => {
monaco.editor.setModelLanguage(model, LANGUAGE_VALUE[props.language]) window.monaco.editor.setModelLanguage(model, LANGUAGE_VALUE[props.language])
}) })
watchEffect(() => { watchEffect(() => {

View File

@@ -36,7 +36,6 @@
import Resizer from "./Resizer.vue" import Resizer from "./Resizer.vue"
import Pane from "./Pane.vue" import Pane from "./Pane.vue"
import { computed, ref } from "vue" import { computed, ref } from "vue"
import { classNameToArray } from "element-plus/es/utils"
interface Props { interface Props {
minPercent?: number minPercent?: number

View File

@@ -1,9 +1,5 @@
import { import { PROBLEM_PERMISSION, STORAGE_KEY, USER_TYPE } from "utils/constants"
PROBLEM_PERMISSION, import storage from "utils/storage"
STORAGE_KEY,
USER_TYPE,
} from "../../utils/constants"
import storage from "../../utils/storage"
import { getUserInfo } from "../api" import { getUserInfo } from "../api"
export const useUserStore = defineStore("user", () => { export const useUserStore = defineStore("user", () => {

8
src/shims.d.ts vendored
View File

@@ -1,3 +1,5 @@
import type * as Monaco from "monaco-editor"
declare module "element-plus/dist/locale/zh-cn.mjs" declare module "element-plus/dist/locale/zh-cn.mjs"
declare module "*.md" { declare module "*.md" {
@@ -5,3 +7,9 @@ declare module "*.md" {
const Component: ComponentOptions const Component: ComponentOptions
export default Component export default Component
} }
declare global {
interface Window {
monaco: Monaco
}
}

View File

@@ -1,81 +0,0 @@
:root {
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
font-size: 16px;
line-height: 24px;
font-weight: 400;
color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
body {
margin: 0;
display: flex;
place-items: center;
min-width: 320px;
min-height: 100vh;
}
h1 {
font-size: 3.2em;
line-height: 1.1;
}
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: #1a1a1a;
cursor: pointer;
transition: border-color 0.25s;
}
button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
}
.card {
padding: 2em;
}
#app {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}
@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
a:hover {
color: #747bff;
}
button {
background-color: #f9f9f9;
}
}

View File

@@ -212,16 +212,6 @@ export const DEAD_RESULTS = {
}, },
} }
export const LANGUAGE_LABEL = {
C: "C",
"C++": "C++",
Java: "Java",
Python2: "Python2",
Python3: "Python",
JavaScript: "JS",
Golang: "Go",
}
export const LANGUAGE_VALUE = { export const LANGUAGE_VALUE = {
C: "c", C: "c",
"C++": "cpp", "C++": "cpp",

View File

@@ -11,7 +11,14 @@
"esModuleInterop": true, "esModuleInterop": true,
"lib": ["ESNext", "DOM"], "lib": ["ESNext", "DOM"],
"skipLibCheck": true, "skipLibCheck": true,
"noEmit": true "noEmit": true,
"paths": {
"~/*": ["./src/*"],
"utils/*": ["./src/utils/*"],
"oj/*": ["./src/oj/*"],
"admin/*": ["./src/admin/*"],
"learn/*": ["./src/learn/*"],
}
}, },
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"], "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
"references": [{ "path": "./tsconfig.node.json" }] "references": [{ "path": "./tsconfig.node.json" }]

View File

@@ -1,4 +1,5 @@
import { defineConfig } from "vite" import { defineConfig } from "vite"
import path from "path"
import Vue from "@vitejs/plugin-vue" import Vue from "@vitejs/plugin-vue"
import AutoImport from "unplugin-auto-import/vite" import AutoImport from "unplugin-auto-import/vite"
import Components from "unplugin-vue-components/vite" import Components from "unplugin-vue-components/vite"
@@ -16,6 +17,15 @@ const proxyConfig = {
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
resolve: {
alias: {
"~": path.resolve(__dirname, "./src"),
utils: path.resolve(__dirname, "./src/utils"),
oj: path.resolve(__dirname, "./src/oj"),
admin: path.resolve(__dirname, "./src/admin"),
learn: path.resolve(__dirname, "./src/learn"),
},
},
plugins: [ plugins: [
Vue({ include: [/\.vue$/, /\.md$/] }), Vue({ include: [/\.vue$/, /\.md$/] }),
AutoImport({ AutoImport({