diff --git a/frontend/package-lock.json b/frontend/package-lock.json index c3960c3..d0d2f64 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -41,8 +41,10 @@ "@types/uuid": "^10.0.0", "@vueuse/core": "^13.3.0", "codemirror": "^6.0.1", + "colors-named": "^1.0.2", + "colors-named-hex": "^1.0.2", + "hsl-matcher": "^1.2.4", "pinia": "^3.0.2", - "pinia-plugin-persistedstate": "^4.3.0", "sass": "^1.89.1", "uuid": "^11.1.0", "vue": "^3.5.16", @@ -1415,7 +1417,10 @@ "version": "3.17.4", "resolved": "https://registry.npmmirror.com/@nuxt/kit/-/kit-3.17.4.tgz", "integrity": "sha512-l+hY8sy2XFfg3PigZj+PTu6+KIJzmbACTRimn1ew/gtCz+F38f6KTF4sMRTN5CUxiB8TRENgEonASmkAWfpO9Q==", + "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "c12": "^3.0.4", "consola": "^3.4.2", @@ -1448,7 +1453,10 @@ "version": "7.0.4", "resolved": "https://registry.npmmirror.com/ignore/-/ignore-7.0.4.tgz", "integrity": "sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A==", + "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">= 4" } @@ -2033,6 +2041,7 @@ "version": "1.0.7", "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.7.tgz", "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", + "dev": true, "license": "MIT" }, "node_modules/@types/json-schema": { @@ -2608,6 +2617,7 @@ "version": "8.14.1", "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.14.1.tgz", "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "dev": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -2751,7 +2761,10 @@ "version": "3.0.4", "resolved": "https://registry.npmmirror.com/c12/-/c12-3.0.4.tgz", "integrity": "sha512-t5FaZTYbbCtvxuZq9xxIruYydrAGsJ+8UdP0pZzMiK2xl/gNiSOy0OxhLzHUEEb0m1QXYqfzfvyIFEmz/g9lqg==", + "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "chokidar": "^4.0.3", "confbox": "^0.2.2", @@ -2821,7 +2834,10 @@ "version": "0.1.6", "resolved": "https://registry.npmmirror.com/citty/-/citty-0.1.6.tgz", "integrity": "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==", + "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "consola": "^3.2.3" } @@ -2861,6 +2877,30 @@ "dev": true, "license": "MIT" }, + "node_modules/colors-named": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/colors-named/-/colors-named-1.0.2.tgz", + "integrity": "sha512-2ANq2r393PV9njYUD66UdfBcxR1slMqRA3QRTWgCx49JoCJ+kOhyfbQYxKJbPZQIhZUcNjVOs5AlyY1WwXec3w==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + } + }, + "node_modules/colors-named-hex": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/colors-named-hex/-/colors-named-hex-1.0.2.tgz", + "integrity": "sha512-k6kq1e1pUCQvSVwIaGFq2l0LrkAPQZWyeuZn1Z8nOiYSEZiKoFj4qx690h2Kd34DFl9Me0gKS6MUwAMBJj8nuA==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz", @@ -2872,13 +2912,17 @@ "version": "0.2.2", "resolved": "https://registry.npmmirror.com/confbox/-/confbox-0.2.2.tgz", "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", + "dev": true, "license": "MIT" }, "node_modules/consola": { "version": "3.4.2", "resolved": "https://registry.npmmirror.com/consola/-/consola-3.4.2.tgz", "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": "^14.18.0 || >=16.10.0" } @@ -2970,23 +3014,23 @@ "dev": true, "license": "MIT" }, - "node_modules/deep-pick-omit": { - "version": "1.2.1", - "resolved": "https://registry.npmmirror.com/deep-pick-omit/-/deep-pick-omit-1.2.1.tgz", - "integrity": "sha512-2J6Kc/m3irCeqVG42T+SaUMesaK7oGWaedGnQQK/+O0gYc+2SP5bKh/KKTE7d7SJ+GCA9UUE1GRzh6oDe0EnGw==", - "license": "MIT" - }, "node_modules/defu": { "version": "6.1.4", "resolved": "https://registry.npmmirror.com/defu/-/defu-6.1.4.tgz", "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", - "license": "MIT" + "dev": true, + "license": "MIT", + "optional": true, + "peer": true }, "node_modules/destr": { "version": "2.0.5", "resolved": "https://registry.npmmirror.com/destr/-/destr-2.0.5.tgz", "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==", - "license": "MIT" + "dev": true, + "license": "MIT", + "optional": true, + "peer": true }, "node_modules/detect-libc": { "version": "1.0.3", @@ -3005,7 +3049,10 @@ "version": "16.5.0", "resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-16.5.0.tgz", "integrity": "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==", + "dev": true, "license": "BSD-2-Clause", + "optional": true, + "peer": true, "engines": { "node": ">=12" }, @@ -3029,7 +3076,10 @@ "version": "0.1.0", "resolved": "https://registry.npmmirror.com/errx/-/errx-0.1.0.tgz", "integrity": "sha512-fZmsRiDNv07K6s2KkKFTiD2aIvECa7++PKyD5NC32tpRw46qZA3sOz+aM+/V9V0GDHxVTKLziveV4JhzBHDp9Q==", - "license": "MIT" + "dev": true, + "license": "MIT", + "optional": true, + "peer": true }, "node_modules/esbuild": { "version": "0.25.2", @@ -3272,6 +3322,7 @@ "version": "1.0.5", "resolved": "https://registry.npmmirror.com/exsolve/-/exsolve-1.0.5.tgz", "integrity": "sha512-pz5dvkYYKQ1AHVrgOzBKWeP4u4FRb3a6DNK2ucr0OoNwYIU4QWsJ+NM36LLzORT+z845MzKHHhpXiUF5nvQoJg==", + "dev": true, "license": "MIT" }, "node_modules/fast-deep-equal": { @@ -3418,7 +3469,10 @@ "version": "2.0.0", "resolved": "https://registry.npmmirror.com/giget/-/giget-2.0.0.tgz", "integrity": "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==", + "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "citty": "^0.1.6", "consola": "^3.4.0", @@ -3490,6 +3544,18 @@ "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", "license": "MIT" }, + "node_modules/hsl-matcher": { + "version": "1.2.4", + "resolved": "https://registry.npmmirror.com/hsl-matcher/-/hsl-matcher-1.2.4.tgz", + "integrity": "sha512-tS7XnJS33Egirm+6cI+Z/kH/aVZt94uxGlJxOZlGql2/yqbAzPg3zHHnTnVN4cVpoJnEYEGq+LE3iXbuUIe8BA==", + "license": "MIT", + "engines": { + "node": ">=16.0.0" + }, + "funding": { + "url": "https://jaywcjlove.github.io/#/sponsor" + } + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmmirror.com/ignore/-/ignore-5.3.2.tgz", @@ -3602,7 +3668,10 @@ "version": "2.4.2", "resolved": "https://registry.npmmirror.com/jiti/-/jiti-2.4.2.tgz", "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "dev": true, "license": "MIT", + "optional": true, + "peer": true, "bin": { "jiti": "lib/jiti-cli.mjs" } @@ -3611,7 +3680,10 @@ "version": "9.0.1", "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-9.0.1.tgz", "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", - "license": "MIT" + "dev": true, + "license": "MIT", + "optional": true, + "peer": true }, "node_modules/js-yaml": { "version": "4.1.0", @@ -3661,7 +3733,10 @@ "version": "2.0.6", "resolved": "https://registry.npmmirror.com/klona/-/klona-2.0.6.tgz", "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", + "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">= 8" } @@ -3670,7 +3745,10 @@ "version": "1.2.0", "resolved": "https://registry.npmmirror.com/knitwork/-/knitwork-1.2.0.tgz", "integrity": "sha512-xYSH7AvuQ6nXkq42x0v5S8/Iry+cfulBz/DJQzhIyESdLD7425jXsPy4vn5cCXU+HhRN2kVw51Vd1K6/By4BQg==", - "license": "MIT" + "dev": true, + "license": "MIT", + "optional": true, + "peer": true }, "node_modules/levn": { "version": "0.4.1", @@ -3690,6 +3768,7 @@ "version": "1.1.1", "resolved": "https://registry.npmmirror.com/local-pkg/-/local-pkg-1.1.1.tgz", "integrity": "sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==", + "dev": true, "license": "MIT", "dependencies": { "mlly": "^1.7.4", @@ -3789,6 +3868,7 @@ "version": "1.7.4", "resolved": "https://registry.npmmirror.com/mlly/-/mlly-1.7.4.tgz", "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==", + "dev": true, "license": "MIT", "dependencies": { "acorn": "^8.14.0", @@ -3801,12 +3881,14 @@ "version": "0.1.8", "resolved": "https://registry.npmmirror.com/confbox/-/confbox-0.1.8.tgz", "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "dev": true, "license": "MIT" }, "node_modules/mlly/node_modules/pkg-types": { "version": "1.3.1", "resolved": "https://registry.npmmirror.com/pkg-types/-/pkg-types-1.3.1.tgz", "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "dev": true, "license": "MIT", "dependencies": { "confbox": "^0.1.8", @@ -3864,7 +3946,10 @@ "version": "1.6.6", "resolved": "https://registry.npmmirror.com/node-fetch-native/-/node-fetch-native-1.6.6.tgz", "integrity": "sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ==", - "license": "MIT" + "dev": true, + "license": "MIT", + "optional": true, + "peer": true }, "node_modules/normalize-path": { "version": "3.0.0", @@ -3893,7 +3978,10 @@ "version": "0.6.0", "resolved": "https://registry.npmmirror.com/nypm/-/nypm-0.6.0.tgz", "integrity": "sha512-mn8wBFV9G9+UFHIrq+pZ2r2zL4aPau/by3kJb3cM7+5tQHMt6HGQB8FDIeKFYp8o0D2pnH6nVsO88N4AmUxIWg==", + "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "citty": "^0.1.6", "consola": "^3.4.0", @@ -3912,7 +4000,10 @@ "version": "2.0.11", "resolved": "https://registry.npmmirror.com/ohash/-/ohash-2.0.11.tgz", "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", - "license": "MIT" + "dev": true, + "license": "MIT", + "optional": true, + "peer": true }, "node_modules/optionator": { "version": "0.9.4", @@ -4008,6 +4099,7 @@ "version": "2.0.3", "resolved": "https://registry.npmmirror.com/pathe/-/pathe-2.0.3.tgz", "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, "license": "MIT" }, "node_modules/perfect-debounce": { @@ -4056,34 +4148,11 @@ } } }, - "node_modules/pinia-plugin-persistedstate": { - "version": "4.3.0", - "resolved": "https://registry.npmmirror.com/pinia-plugin-persistedstate/-/pinia-plugin-persistedstate-4.3.0.tgz", - "integrity": "sha512-x9wxpHj6iFDj5ITQJ3rj6+KesEqyRk/vqcE3WE+VGfetleV9Zufqwa9qJ6AkA5wmRSQEp7BTA1us/MDVTRHFFw==", - "license": "MIT", - "dependencies": { - "@nuxt/kit": "^3.17.2", - "deep-pick-omit": "^1.2.1", - "defu": "^6.1.4", - "destr": "^2.0.5" - }, - "peerDependencies": { - "@pinia/nuxt": ">=0.10.0", - "pinia": ">=3.0.0" - }, - "peerDependenciesMeta": { - "@pinia/nuxt": { - "optional": true - }, - "pinia": { - "optional": true - } - } - }, "node_modules/pkg-types": { "version": "2.1.0", "resolved": "https://registry.npmmirror.com/pkg-types/-/pkg-types-2.1.0.tgz", "integrity": "sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==", + "dev": true, "license": "MIT", "dependencies": { "confbox": "^0.2.1", @@ -4157,6 +4226,7 @@ "version": "0.2.10", "resolved": "https://registry.npmmirror.com/quansync/-/quansync-0.2.10.tgz", "integrity": "sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==", + "dev": true, "funding": [ { "type": "individual", @@ -4194,7 +4264,10 @@ "version": "2.1.2", "resolved": "https://registry.npmmirror.com/rc9/-/rc9-2.1.2.tgz", "integrity": "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==", + "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" @@ -4328,12 +4401,16 @@ "version": "1.3.0", "resolved": "https://registry.npmmirror.com/scule/-/scule-1.3.0.tgz", "integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==", - "license": "MIT" + "dev": true, + "license": "MIT", + "optional": true, + "peer": true }, "node_modules/semver": { "version": "7.7.2", "resolved": "https://registry.npmmirror.com/semver/-/semver-7.7.2.tgz", "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -4387,7 +4464,10 @@ "version": "3.9.0", "resolved": "https://registry.npmmirror.com/std-env/-/std-env-3.9.0.tgz", "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==", - "license": "MIT" + "dev": true, + "license": "MIT", + "optional": true, + "peer": true }, "node_modules/strip-json-comments": { "version": "3.1.1", @@ -4406,7 +4486,10 @@ "version": "3.0.0", "resolved": "https://registry.npmmirror.com/strip-literal/-/strip-literal-3.0.0.tgz", "integrity": "sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==", + "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "js-tokens": "^9.0.1" }, @@ -4449,12 +4532,16 @@ "version": "0.3.2", "resolved": "https://registry.npmmirror.com/tinyexec/-/tinyexec-0.3.2.tgz", "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", - "license": "MIT" + "dev": true, + "license": "MIT", + "optional": true, + "peer": true }, "node_modules/tinyglobby": { "version": "0.2.14", "resolved": "https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.14.tgz", "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "dev": true, "license": "MIT", "dependencies": { "fdir": "^6.4.4", @@ -4471,6 +4558,7 @@ "version": "6.4.4", "resolved": "https://registry.npmmirror.com/fdir/-/fdir-6.4.4.tgz", "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", + "dev": true, "license": "MIT", "peerDependencies": { "picomatch": "^3 || ^4" @@ -4485,6 +4573,7 @@ "version": "4.0.2", "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.2.tgz", "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -4573,13 +4662,17 @@ "version": "1.6.1", "resolved": "https://registry.npmmirror.com/ufo/-/ufo-1.6.1.tgz", "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", + "dev": true, "license": "MIT" }, "node_modules/unctx": { "version": "2.4.1", "resolved": "https://registry.npmmirror.com/unctx/-/unctx-2.4.1.tgz", "integrity": "sha512-AbaYw0Nm4mK4qjhns67C+kgxR2YWiwlDBPzxrN8h8C6VtAdCgditAY5Dezu3IJy4XVqAnbrXt9oQJvsn3fyozg==", + "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "acorn": "^8.14.0", "estree-walker": "^3.0.3", @@ -4591,7 +4684,10 @@ "version": "3.0.3", "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-3.0.3.tgz", "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/estree": "^1.0.0" } @@ -4607,7 +4703,10 @@ "version": "5.0.1", "resolved": "https://registry.npmmirror.com/unimport/-/unimport-5.0.1.tgz", "integrity": "sha512-1YWzPj6wYhtwHE+9LxRlyqP4DiRrhGfJxdtH475im8ktyZXO3jHj/3PZ97zDdvkYoovFdi0K4SKl3a7l92v3sQ==", + "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "acorn": "^8.14.1", "escape-string-regexp": "^5.0.0", @@ -4632,7 +4731,10 @@ "version": "5.0.0", "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=12" }, @@ -4644,7 +4746,10 @@ "version": "3.0.3", "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-3.0.3.tgz", "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/estree": "^1.0.0" } @@ -4653,7 +4758,10 @@ "version": "4.0.2", "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.2.tgz", "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=12" }, @@ -4665,6 +4773,7 @@ "version": "2.3.5", "resolved": "https://registry.npmmirror.com/unplugin/-/unplugin-2.3.5.tgz", "integrity": "sha512-RyWSb5AHmGtjjNQ6gIlA67sHOsWpsbWpwDokLwTcejVdOjEkJZh7QKu14J00gDDVSh8kGH4KYC/TNBceXFZhtw==", + "dev": true, "license": "MIT", "dependencies": { "acorn": "^8.14.1", @@ -4679,6 +4788,7 @@ "version": "0.2.4", "resolved": "https://registry.npmmirror.com/unplugin-utils/-/unplugin-utils-0.2.4.tgz", "integrity": "sha512-8U/MtpkPkkk3Atewj1+RcKIjb5WBimZ/WSLhhR3w6SsIj8XJuKTacSP8g+2JhfSGw0Cb125Y+2zA/IzJZDVbhA==", + "dev": true, "license": "MIT", "dependencies": { "pathe": "^2.0.2", @@ -4695,6 +4805,7 @@ "version": "4.0.2", "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.2.tgz", "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -4794,6 +4905,7 @@ "version": "4.0.2", "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.2.tgz", "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -4806,7 +4918,10 @@ "version": "2.0.0", "resolved": "https://registry.npmmirror.com/untyped/-/untyped-2.0.0.tgz", "integrity": "sha512-nwNCjxJTjNuLCgFr42fEak5OcLuB3ecca+9ksPFNvtfYSLpjf+iJqSIaSnIile6ZPbKYxI5k2AfXqeopGudK/g==", + "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "citty": "^0.1.6", "defu": "^6.1.4", @@ -5078,6 +5193,7 @@ "version": "0.6.2", "resolved": "https://registry.npmmirror.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", + "dev": true, "license": "MIT" }, "node_modules/which": { diff --git a/frontend/package.json b/frontend/package.json index b134cb0..03020b4 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -45,8 +45,10 @@ "@types/uuid": "^10.0.0", "@vueuse/core": "^13.3.0", "codemirror": "^6.0.1", + "colors-named": "^1.0.2", + "colors-named-hex": "^1.0.2", + "hsl-matcher": "^1.2.4", "pinia": "^3.0.2", - "pinia-plugin-persistedstate": "^4.3.0", "sass": "^1.89.1", "uuid": "^11.1.0", "vue": "^3.5.16", diff --git a/frontend/src/main.ts b/frontend/src/main.ts index 4f73a34..77b2e1b 100644 --- a/frontend/src/main.ts +++ b/frontend/src/main.ts @@ -4,10 +4,7 @@ import '@/assets/styles/index.css'; import {createPinia} from 'pinia'; import i18n from './i18n'; import router from './router'; -import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' - const pinia = createPinia() -pinia.use(piniaPluginPersistedstate) const app = createApp(App); app.use(pinia) app.use(i18n); diff --git a/frontend/src/views/editor/extensions/basicSetup.ts b/frontend/src/views/editor/extensions/basicSetup.ts index d2fefb2..9bd58ab 100644 --- a/frontend/src/views/editor/extensions/basicSetup.ts +++ b/frontend/src/views/editor/extensions/basicSetup.ts @@ -24,9 +24,11 @@ import {defaultKeymap, history, historyKeymap,} from '@codemirror/commands'; import {highlightSelectionMatches} from '@codemirror/search'; import {autocompletion, closeBrackets, closeBracketsKeymap, completionKeymap} from '@codemirror/autocomplete'; import {lintKeymap} from '@codemirror/lint'; -import { vscodeSearch, customSearchKeymap, searchVisibilityField } from '../plugins/vscodeSearch'; +import { vscodeSearch, customSearchKeymap, searchVisibilityField } from './vscodeSearch'; + +import { hyperLink } from './hyperlink'; +import { color } from './colorSelector'; -import { hyperLink } from '../plugins/hyperlink'; // 基本编辑器设置,包含常用扩展 export const createBasicSetup = (): Extension[] => { return [ @@ -35,6 +37,7 @@ export const createBasicSetup = (): Extension[] => { searchVisibilityField, hyperLink, + color, // 基础UI lineNumbers(), @@ -67,7 +70,7 @@ export const createBasicSetup = (): Extension[] => { // 键盘映射 keymap.of([ - ...customSearchKeymap as KeyBinding[], + ...customSearchKeymap, ...closeBracketsKeymap, ...defaultKeymap, ...historyKeymap, diff --git a/frontend/src/views/editor/extensions/colorSelector/index.ts b/frontend/src/views/editor/extensions/colorSelector/index.ts new file mode 100644 index 0000000..28983f6 --- /dev/null +++ b/frontend/src/views/editor/extensions/colorSelector/index.ts @@ -0,0 +1,301 @@ +import { ViewPlugin, EditorView, ViewUpdate, WidgetType, Decoration, DecorationSet } from '@codemirror/view'; +import { Extension, Range } from '@codemirror/state'; +import { syntaxTree } from '@codemirror/language'; +import colors from 'colors-named'; +import hexs from 'colors-named-hex'; +import hslMatcher, { hlsStringToRGB, RGBAColor } from 'hsl-matcher'; +import { toFullHex, rgbToHex, hexToRgb, RGBToHSL } from './utils'; + +export enum ColorType { + rgb = 'RGB', + hex = 'HEX', + named = 'NAMED', + hsl = 'HSL', +} + +export interface ColorState { + from: number; + to: number; + alpha: string; + colorType: ColorType; +} + +const colorState = new WeakMap(); + +type GetArrayElementType = T extends readonly (infer U)[] ? U : never; + +function colorDecorations(view: EditorView) { + const widgets: Array> = []; + for (const range of view.visibleRanges) { + syntaxTree(view.state).iterate({ + from: range.from, + to: range.to, + enter: ({ type, from, to }) => { + const callExp: string = view.state.doc.sliceString(from, to); + /** + * ``` + * rgb(0 107 128, .5); ❌ ❌ ❌ + * rgb( 0 107 128 ); ✅ ✅ ✅ + * RGB( 0 107 128 ); ✅ ✅ ✅ + * Rgb( 0 107 128 ); ✅ ✅ ✅ + * rgb( 0 107 128 / ); ❌ ❌ ❌ + * rgb( 0 107 128 / 60%); ✅ ✅ ✅ + * rgb(0,107,128 / 60%); ❌ ❌ ❌ + * rgb( 255, 255, 255 ) ✅ ✅ ✅ + * rgba( 255, 255, 255 ) ✅ ✅ ✅ + * rgba( 255, 255 , 255, ) ❌ ❌ ❌ + * rgba( 255, 255 , 255, .5 ) ✅ ✅ ✅ + * rgba( 255 255 255 / 0.5 ); ✅ ✅ ✅ + * rgba( 255 255 255 0.5 ); ❌ ❌ ❌ + * rgba( 255 255 255 / ); ❌ ❌ ❌ + * ``` + */ + if (type.name === 'CallExpression' && callExp.startsWith('rgb')) { + const match = + /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,?\s*(\d{1,3})\s*(,\s*\d*\.\d*\s*)?\)/i.exec(callExp) || + /rgba?\(\s*(\d{1,3})\s*(\d{1,3})\s*(\d{1,3})\s*(\/?\s*\d+%)?(\/\s*\d+\.\d\s*)?\)/i.exec(callExp); + if (!match) return; + const [_, r, g, b, a] = match; + const hex = rgbToHex(Number(r), Number(g), Number(b)); + const widget = Decoration.widget({ + widget: new ColorWidget({ + colorType: ColorType.rgb, + color: hex, + colorRaw: callExp, + from, + to, + alpha: a ? a.replace(/(\/|,)/g, '') : '', + }), + side: 0, + }); + widgets.push(widget.range(from)); + } else if (type.name === 'CallExpression' && hslMatcher(callExp)) { + /** + * # valid + * hsl(240, 100%, 50%) // ✅ comma separated + * hsl(240, 100%, 50%, 0.1) // ✅ comma separated with opacity + * hsl(240, 100%, 50%, 10%) // ✅ comma separated with % opacity + * hsl(240,100%,50%,0.1) // ✅ comma separated without spaces + * hsl(180deg, 100%, 50%, 0.1) // ✅ hue with 'deg' + * hsl(3.14rad, 100%, 50%, 0.1) // ✅ hue with 'rad' + * hsl(200grad, 100%, 50%, 0.1) // ✅ hue with 'grad' + * hsl(0.5turn, 100%, 50%, 0.1) // ✅ hue with 'turn' + * hsl(-240, -100%, -50%, -0.1) // ✅ negative values + * hsl(+240, +100%, +50%, +0.1) // ✅ explicit positive sign + * hsl(240.5, 99.99%, 49.999%, 0.9999) // ✅ non-integer values + * hsl(.9, .99%, .999%, .9999) // ✅ fraction w/o leading zero + * hsl(0240, 0100%, 0050%, 01) // ✅ leading zeros + * hsl(240.0, 100.00%, 50.000%, 1.0000) // ✅ trailing decimal zeros + * hsl(2400, 1000%, 1000%, 10) // ✅ out of range values + * hsl(-2400.01deg, -1000.5%, -1000.05%, -100) // ✅ combination of above + * hsl(2.40e+2, 1.00e+2%, 5.00e+1%, 1E-3) // ✅ scientific notation + * hsl(240 100% 50%) // ✅ space separated (CSS Color Level 4) + * hsl(240 100% 50% / 0.1) // ✅ space separated with opacity + * hsla(240, 100%, 50%) // ✅ hsla() alias + * hsla(240, 100%, 50%, 0.1) // ✅ hsla() with opacity + * HSL(240Deg, 100%, 50%) // ✅ case insensitive + */ + const match = hlsStringToRGB(callExp) as RGBAColor; + if (!match) return; + const { r, g, b } = match; + const hex = rgbToHex(Number(r), Number(g), Number(b)); + const widget = Decoration.widget({ + widget: new ColorWidget({ + colorType: ColorType.hsl, + color: hex, + colorRaw: callExp, + from, + to, + alpha: match.a ? match.a.toString() : '', + }), + side: 0, + }); + widgets.push(widget.range(from)); + } else if (type.name === 'ColorLiteral') { + const [color, alpha] = toFullHex(callExp); + const widget = Decoration.widget({ + widget: new ColorWidget({ + colorType: ColorType.hex, + color, + colorRaw: callExp, + from, + to, + alpha, + }), + side: 0, + }); + widgets.push(widget.range(from)); + } else if (type.name === 'ValueName') { + const name = callExp as unknown as GetArrayElementType; + if (colors.includes(name)) { + const widget = Decoration.widget({ + widget: new ColorWidget({ + colorType: ColorType.named, + color: hexs[colors.indexOf(name)], + colorRaw: callExp, + from, + to, + alpha: '', + }), + side: 0, + }); + widgets.push(widget.range(from)); + } + } + }, + }); + } + return Decoration.set(widgets); +} + +class ColorWidget extends WidgetType { + private readonly state: ColorState; + private readonly color: string; + private readonly colorRaw: string; + + constructor({ + color, + colorRaw, + ...state + }: ColorState & { + color: string; + colorRaw: string; + }) { + super(); + this.state = state; + this.color = color; + this.colorRaw = colorRaw; + } + eq(other: ColorWidget) { + return ( + other.state.colorType === this.state.colorType && + other.color === this.color && + other.state.from === this.state.from && + other.state.to === this.state.to && + other.state.alpha === this.state.alpha + ); + } + toDOM() { + const picker = document.createElement('input'); + colorState.set(picker, this.state); + picker.type = 'color'; + picker.value = this.color; + picker.dataset['color'] = this.color; + picker.dataset['colorraw'] = this.colorRaw; + const wrapper = document.createElement('span'); + wrapper.appendChild(picker); + wrapper.dataset['color'] = this.color; + wrapper.style.backgroundColor = this.colorRaw; + return wrapper; + } + ignoreEvent() { + return false; + } +} + +export const colorView = (showPicker: boolean = true) => + ViewPlugin.fromClass( + class ColorView { + decorations: DecorationSet; + constructor(view: EditorView) { + this.decorations = colorDecorations(view); + } + update(update: ViewUpdate) { + if (update.docChanged || update.viewportChanged) { + this.decorations = colorDecorations(update.view); + } + const readOnly = update.view.contentDOM.ariaReadOnly === 'true'; + const editable = update.view.contentDOM.contentEditable === 'true'; + + const canBeEdited = readOnly === false && editable; + this.changePicker(update.view, canBeEdited); + } + changePicker(view: EditorView, canBeEdited: boolean) { + const doms = view.contentDOM.querySelectorAll('input[type=color]'); + doms.forEach((inp) => { + if (!showPicker) { + inp.setAttribute('disabled', ''); + } else { + canBeEdited ? inp.removeAttribute('disabled') : inp.setAttribute('disabled', ''); + } + }); + } + }, + { + decorations: (v) => v.decorations, + eventHandlers: { + change: (e, view) => { + const target = e.target as HTMLInputElement; + if ( + target.nodeName !== 'INPUT' || + !target.parentElement || + (!target.dataset.color && !target.dataset.colorraw) + ) + return false; + const data = colorState.get(target)!; + const value = target.value; + const rgb = hexToRgb(value); + const colorraw = target.dataset.colorraw; + const slash = (target.dataset.colorraw || '').indexOf('/') > 4; + const comma = (target.dataset.colorraw || '').indexOf(',') > 4; + let converted = target.value; + if (data.colorType === ColorType.rgb) { + let funName = colorraw?.match(/^(rgba?)/) ? colorraw?.match(/^(rgba?)/)![0] : undefined; + if (comma) { + converted = rgb + ? `${funName}(${rgb.r}, ${rgb.g}, ${rgb.b}${data.alpha ? ', ' + data.alpha.trim() : ''})` + : value; + } else if (slash) { + converted = rgb + ? `${funName}(${rgb.r} ${rgb.g} ${rgb.b}${data.alpha ? ' / ' + data.alpha.trim() : ''})` + : value; + } else { + converted = rgb ? `${funName}(${rgb.r} ${rgb.g} ${rgb.b})` : value; + } + } else if (data.colorType === ColorType.hsl) { + const rgb = hexToRgb(value); + if (rgb) { + const { h, s, l } = RGBToHSL(rgb?.r, rgb?.g, rgb?.b); + converted = `hsl(${h}deg ${s}% ${l}%${data.alpha ? ' / ' + data.alpha : ''})`; + } + } + view.dispatch({ + changes: { + from: data.from, + to: data.to, + insert: converted, + }, + }); + return true; + }, + }, + }, + ); + +export const colorTheme = EditorView.baseTheme({ + 'span[data-color]': { + width: '12px', + height: '12px', + display: 'inline-block', + borderRadius: '2px', + marginRight: '0.5ch', + outline: '1px solid #00000040', + overflow: 'hidden', + verticalAlign: 'middle', + marginTop: '-2px', + }, + 'span[data-color] input[type="color"]': { + background: 'transparent', + display: 'block', + border: 'none', + outline: '0', + paddingLeft: '24px', + height: '12px', + }, + 'span[data-color] input[type="color"]::-webkit-color-swatch': { + border: 'none', + paddingLeft: '24px', + }, +}); + +export const color: Extension = [colorView(), colorTheme]; \ No newline at end of file diff --git a/frontend/src/views/editor/extensions/colorSelector/utils.ts b/frontend/src/views/editor/extensions/colorSelector/utils.ts new file mode 100644 index 0000000..fbd1fc2 --- /dev/null +++ b/frontend/src/views/editor/extensions/colorSelector/utils.ts @@ -0,0 +1,64 @@ +export function toFullHex(color: string): string[] { + if (color.length === 4) { + // 3-char hex + return [`#${color[1].repeat(2)}${color[2].repeat(2)}${color[3].repeat(2)}`, '']; + } + + if (color.length === 5) { + // 4-char hex (alpha) + return [`#${color[1].repeat(2)}${color[2].repeat(2)}${color[3].repeat(2)}`, color[4].repeat(2)]; + } + + if (color.length === 9) { + // 8-char hex (alpha) + return [`#${color.slice(1, -2)}`, color.slice(-2)]; + } + + return [color, '']; +} +/** https://stackoverflow.com/a/5624139/1334703 */ +export function rgbToHex(r: number, g: number, b: number) { + return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1); +} + +/** https://stackoverflow.com/a/5624139/1334703 */ +export function hexToRgb(hex: string) { + const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); + return result + ? { + r: parseInt(result[1], 16), + g: parseInt(result[2], 16), + b: parseInt(result[3], 16), + } + : null; +} + +/** https://css-tricks.com/converting-color-spaces-in-javascript/#aa-rgb-to-hsl */ +export function RGBToHSL(r: number, g: number, b: number) { + (r /= 255), (g /= 255), (b /= 255); + const max = Math.max(r, g, b), + min = Math.min(r, g, b); + let h = 0, + s, + l = (max + min) / 2; + + if (max == min) { + h = s = 0; // achromatic + } else { + const d = max - min; + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); + switch (max) { + case r: + h = (g - b) / d + (g < b ? 6 : 0); + break; + case g: + h = (b - r) / d + 2; + break; + case b: + h = (r - g) / d + 4; + break; + } + h /= 6; + } + return { h: Math.floor(h * 360), s: Math.floor(s * 100), l: Math.floor(l * 100) }; +} \ No newline at end of file diff --git a/frontend/src/views/editor/plugins/hyperlink/index.ts b/frontend/src/views/editor/extensions/hyperlink/index.ts similarity index 100% rename from frontend/src/views/editor/plugins/hyperlink/index.ts rename to frontend/src/views/editor/extensions/hyperlink/index.ts diff --git a/frontend/src/views/editor/plugins/vscodeSearch/FindReplaceControl.ts b/frontend/src/views/editor/extensions/vscodeSearch/FindReplaceControl.ts similarity index 95% rename from frontend/src/views/editor/plugins/vscodeSearch/FindReplaceControl.ts rename to frontend/src/views/editor/extensions/vscodeSearch/FindReplaceControl.ts index 8b362cf..1c9a622 100644 --- a/frontend/src/views/editor/plugins/vscodeSearch/FindReplaceControl.ts +++ b/frontend/src/views/editor/extensions/vscodeSearch/FindReplaceControl.ts @@ -127,8 +127,8 @@ export class CustomSearchPanel { if (query.regexp) { try { - this.regexCursor = new RegExpCursor(state.doc, query.search) - this.searchCursor = undefined; + this.regexCursor = new RegExpCursor(state.doc, query.search) + this.searchCursor = undefined; } catch (error) { // 如果正则表达式无效,清空匹配结果并显示错误状态 console.warn("Invalid regular expression:", query.search, error); @@ -168,17 +168,17 @@ export class CustomSearchPanel { } else if (this.regexCursor) { try { - const matchWord = this.regexpWordTest(state.charCategorizer(state.selection.main.head)) + const matchWord = this.regexpWordTest(state.charCategorizer(state.selection.main.head)) - while (!this.regexCursor.done) { - this.regexCursor.next(); + while (!this.regexCursor.done) { + this.regexCursor.next(); - if (!this.regexCursor.done) { - const { from, to, match } = this.regexCursor.value; + if (!this.regexCursor.done) { + const { from, to, match } = this.regexCursor.value; - if (!query.wholeWord || matchWord(from, to, match)) { - this.matches.push({ from, to }); - } + if (!query.wholeWord || matchWord(from, to, match)) { + this.matches.push({ from, to }); + } } } } catch (error) { @@ -222,19 +222,19 @@ export class CustomSearchPanel { commit() { try { - const newQuery = new SearchQuery({ - search: this.searchField.value, - replace: this.replaceField.value, - caseSensitive: this.matchCase, - regexp: this.useRegex, - wholeWord: this.matchWord, - }) + const newQuery = new SearchQuery({ + search: this.searchField.value, + replace: this.replaceField.value, + caseSensitive: this.matchCase, + regexp: this.useRegex, + wholeWord: this.matchWord, + }) - let query = getSearchQuery(this.view.state) - if (!newQuery.eq(query)) { - this.view.dispatch({ - effects: setSearchQuery.of(newQuery) - }) + let query = getSearchQuery(this.view.state) + if (!newQuery.eq(query)) { + this.view.dispatch({ + effects: setSearchQuery.of(newQuery) + }) } } catch (error) { // 如果创建SearchQuery时出错(通常是无效的正则表达式),记录错误但不中断程序 @@ -367,7 +367,7 @@ export class CustomSearchPanel { }); // 重新查找匹配项 - this.findMatchesAndSelectClosest(this.view.state); + this.findMatchesAndSelectClosest(this.view.state); } } } @@ -392,7 +392,7 @@ export class CustomSearchPanel { }); // 重新查找匹配项 - this.findMatchesAndSelectClosest(this.view.state); + this.findMatchesAndSelectClosest(this.view.state); } } @@ -592,7 +592,7 @@ export class CustomSearchPanel { if (visible) { // 使用 setTimeout 确保DOM已经渲染 setTimeout(() => { - this.searchField.focus(); + this.searchField.focus(); this.searchField.select(); }, 0); } diff --git a/frontend/src/views/editor/plugins/vscodeSearch/commands.ts b/frontend/src/views/editor/extensions/vscodeSearch/commands.ts similarity index 100% rename from frontend/src/views/editor/plugins/vscodeSearch/commands.ts rename to frontend/src/views/editor/extensions/vscodeSearch/commands.ts diff --git a/frontend/src/views/editor/plugins/vscodeSearch/index.ts b/frontend/src/views/editor/extensions/vscodeSearch/index.ts similarity index 100% rename from frontend/src/views/editor/plugins/vscodeSearch/index.ts rename to frontend/src/views/editor/extensions/vscodeSearch/index.ts diff --git a/frontend/src/views/editor/plugins/vscodeSearch/keymap.ts b/frontend/src/views/editor/extensions/vscodeSearch/keymap.ts similarity index 98% rename from frontend/src/views/editor/plugins/vscodeSearch/keymap.ts rename to frontend/src/views/editor/extensions/vscodeSearch/keymap.ts index 7aa6161..33c4529 100644 --- a/frontend/src/views/editor/plugins/vscodeSearch/keymap.ts +++ b/frontend/src/views/editor/extensions/vscodeSearch/keymap.ts @@ -72,10 +72,10 @@ export const customSearchKeymap: KeyBinding[] = [ key: "ArrowLeft", run: searchMoveCursorLeft, scope: 'search' - }, - { + }, + { key: "ArrowRight", run: searchMoveCursorRight, scope: 'search' - }, + }, ]; \ No newline at end of file diff --git a/frontend/src/views/editor/plugins/vscodeSearch/plugin.ts b/frontend/src/views/editor/extensions/vscodeSearch/plugin.ts similarity index 100% rename from frontend/src/views/editor/plugins/vscodeSearch/plugin.ts rename to frontend/src/views/editor/extensions/vscodeSearch/plugin.ts diff --git a/frontend/src/views/editor/plugins/vscodeSearch/state.ts b/frontend/src/views/editor/extensions/vscodeSearch/state.ts similarity index 100% rename from frontend/src/views/editor/plugins/vscodeSearch/state.ts rename to frontend/src/views/editor/extensions/vscodeSearch/state.ts diff --git a/frontend/src/views/editor/plugins/vscodeSearch/theme.ts b/frontend/src/views/editor/extensions/vscodeSearch/theme.ts similarity index 100% rename from frontend/src/views/editor/plugins/vscodeSearch/theme.ts rename to frontend/src/views/editor/extensions/vscodeSearch/theme.ts diff --git a/frontend/src/views/editor/plugins/vscodeSearch/utility.ts b/frontend/src/views/editor/extensions/vscodeSearch/utility.ts similarity index 100% rename from frontend/src/views/editor/plugins/vscodeSearch/utility.ts rename to frontend/src/views/editor/extensions/vscodeSearch/utility.ts