From b0af4e78c0e1b2abf78690da6eb2201cf12dda3a Mon Sep 17 00:00:00 2001 From: Pyrofab Date: Thu, 21 Mar 2024 22:35:11 +0100 Subject: [PATCH 01/68] Set up svelte project for highly dynamic pages and widgets --- .editorconfig | 3 + .gitignore | 1 - README.md | 21 +- _config.yml | 2 + jekyll_plugins/build_sprinkles.rb | 15 + svelte_sprinkles/.gitignore | 24 + svelte_sprinkles/blabber-parlour.html | 14 + svelte_sprinkles/index.html | 15 + svelte_sprinkles/package-lock.json | 1775 +++++++++++++++++ svelte_sprinkles/package.json | 22 + svelte_sprinkles/public/vite.svg | 1 + svelte_sprinkles/src/assets/svelte.svg | 1 + svelte_sprinkles/src/lib/Counter.svelte | 10 + .../src/sprinkles/parlour/Parlour.svelte | 47 + .../src/sprinkles/parlour/main.ts | 8 + .../src/sprinkles/parlour/parlour.css | 79 + svelte_sprinkles/src/vite-env.d.ts | 2 + svelte_sprinkles/svelte.config.js | 7 + svelte_sprinkles/tsconfig.json | 20 + svelte_sprinkles/tsconfig.node.json | 10 + svelte_sprinkles/vite.config.ts | 25 + 21 files changed, 2099 insertions(+), 3 deletions(-) create mode 100644 jekyll_plugins/build_sprinkles.rb create mode 100644 svelte_sprinkles/.gitignore create mode 100644 svelte_sprinkles/blabber-parlour.html create mode 100644 svelte_sprinkles/index.html create mode 100644 svelte_sprinkles/package-lock.json create mode 100644 svelte_sprinkles/package.json create mode 100644 svelte_sprinkles/public/vite.svg create mode 100644 svelte_sprinkles/src/assets/svelte.svg create mode 100644 svelte_sprinkles/src/lib/Counter.svelte create mode 100644 svelte_sprinkles/src/sprinkles/parlour/Parlour.svelte create mode 100644 svelte_sprinkles/src/sprinkles/parlour/main.ts create mode 100644 svelte_sprinkles/src/sprinkles/parlour/parlour.css create mode 100644 svelte_sprinkles/src/vite-env.d.ts create mode 100644 svelte_sprinkles/svelte.config.js create mode 100644 svelte_sprinkles/tsconfig.json create mode 100644 svelte_sprinkles/tsconfig.node.json create mode 100644 svelte_sprinkles/vite.config.ts diff --git a/.editorconfig b/.editorconfig index f1891840..e845b06b 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,2 +1,5 @@ [{*.js,*.mjs}] ij_javascript_spaces_within_object_literal_braces = true + +[*.ts] +ij_typescript_spaces_within_object_literal_braces = true diff --git a/.gitignore b/.gitignore index 29a9402a..56f8c5be 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,5 @@ System Volume Information/ #bootstrap.css node_modules/ -package-lock.json currentsetting.htm _site/ diff --git a/README.md b/README.md index 880a638c..3fcc72e8 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,11 @@ To run the site locally, follow these steps: > Fetching dependency metadata from https://rubygems.org/.. > Resolving dependencies... ``` -4. Start the site (from the root of this repository): +4. Setup NPM in the [svelte_sprinkles](./svelte_sprinkles) directory: + ```bash + $ npm --prefix svelte_sprinkles install + ``` +5. Start the site (from the root of this repository): ```bash $ bundle exec jekyll serve > Configuration file: /Users/octocat/ladysnake.github.io/_config.yml @@ -31,4 +35,17 @@ To run the site locally, follow these steps: > Server address: http://127.0.0.1:4000/ > Server running... press ctrl-c to stop. ``` -5. Preview your copy of the site in your web browser at http://localhost:4000. +6. Preview your copy of the site in your web browser at http://localhost:4000. + +## Dynamic Content + +### Build-time + +This website makes use of a number of [custom Jekyll plugins](./jekyll_plugins), most notably to +dynamically generate crafting recipe widgets based on the JSON data available in our mod repositories. + +### Runtime + +Some pages like the Blabber dialogue editor use sprinkles of dynamic content in the form of [Svelte components](./svelte_sprinkles). +These sprinkles are automatically built each time you run `jekyll build` or `jekyll serve`. +When working on those sprinkles, one can open a separate terminal and use the `npm run watch` command in the `svelte_sprinkles` directory. diff --git a/_config.yml b/_config.yml index f4ff7281..327ada74 100644 --- a/_config.yml +++ b/_config.yml @@ -5,6 +5,8 @@ markdown: kramdown sass: style: compressed exclude: [] +keep_files: + - scripts/sprinkles # note that the source attribute is hardcoded by github pages collections: mods: diff --git a/jekyll_plugins/build_sprinkles.rb b/jekyll_plugins/build_sprinkles.rb new file mode 100644 index 00000000..95c50a04 --- /dev/null +++ b/jekyll_plugins/build_sprinkles.rb @@ -0,0 +1,15 @@ +require 'open3' + +Jekyll::Hooks.register :site, :after_init do + cmd = 'npm run build' + stdout, stderr, status = Open3.capture3(cmd, chdir: 'svelte_sprinkles') + + if status.success? + puts "Successfully built Svelte sprinkles" + else + puts "Failed to build Svelte sprinkles" + puts "stdout: #{stdout}" + puts "stderr: #{stderr}" + raise "Svelte Sprinkles build failed" + end +end diff --git a/svelte_sprinkles/.gitignore b/svelte_sprinkles/.gitignore new file mode 100644 index 00000000..a547bf36 --- /dev/null +++ b/svelte_sprinkles/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/svelte_sprinkles/blabber-parlour.html b/svelte_sprinkles/blabber-parlour.html new file mode 100644 index 00000000..cbb6fe81 --- /dev/null +++ b/svelte_sprinkles/blabber-parlour.html @@ -0,0 +1,14 @@ + + + + + + + + Blabber Dialogue Generator + + +
+ + + diff --git a/svelte_sprinkles/index.html b/svelte_sprinkles/index.html new file mode 100644 index 00000000..e2b7bf01 --- /dev/null +++ b/svelte_sprinkles/index.html @@ -0,0 +1,15 @@ + + + + + + + + Vite + Svelte + TS + + + + + diff --git a/svelte_sprinkles/package-lock.json b/svelte_sprinkles/package-lock.json new file mode 100644 index 00000000..8b0c8850 --- /dev/null +++ b/svelte_sprinkles/package-lock.json @@ -0,0 +1,1775 @@ +{ + "name": "ladysnake-svelte-sprinkles", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "ladysnake-svelte-sprinkles", + "version": "0.0.0", + "devDependencies": { + "@sveltejs/vite-plugin-svelte": "^3.0.2", + "@tsconfig/svelte": "^5.0.2", + "svelte": "^4.2.12", + "svelte-check": "^3.6.7", + "tslib": "^2.6.2", + "typescript": "^5.2.2", + "vite": "^5.2.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.0.tgz", + "integrity": "sha512-5ZYPOuaAqEH/W3gYsRkxQATBW3Ii1MfaT4EQstTnLKViLi2gLSQmlmtTpGucNP3sXEpOiI5tdGhjdE111ekyEg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.13.0.tgz", + "integrity": "sha512-BSbaCmn8ZadK3UAQdlauSvtaJjhlDEjS5hEVVIN3A4bbl3X+otyf/kOJV08bYiRxfejP3DXFzO2jz3G20107+Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.13.0.tgz", + "integrity": "sha512-Ovf2evVaP6sW5Ut0GHyUSOqA6tVKfrTHddtmxGQc1CTQa1Cw3/KMCDEEICZBbyppcwnhMwcDce9ZRxdWRpVd6g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.13.0.tgz", + "integrity": "sha512-U+Jcxm89UTK592vZ2J9st9ajRv/hrwHdnvyuJpa5A2ngGSVHypigidkQJP+YiGL6JODiUeMzkqQzbCG3At81Gg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.13.0.tgz", + "integrity": "sha512-8wZidaUJUTIR5T4vRS22VkSMOVooG0F4N+JSwQXWSRiC6yfEsFMLTYRFHvby5mFFuExHa/yAp9juSphQQJAijQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.13.0.tgz", + "integrity": "sha512-Iu0Kno1vrD7zHQDxOmvweqLkAzjxEVqNhUIXBsZ8hu8Oak7/5VTPrxOEZXYC1nmrBVJp0ZcL2E7lSuuOVaE3+w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.13.0.tgz", + "integrity": "sha512-C31QrW47llgVyrRjIwiOwsHFcaIwmkKi3PCroQY5aVq4H0A5v/vVVAtFsI1nfBngtoRpeREvZOkIhmRwUKkAdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.13.0.tgz", + "integrity": "sha512-Oq90dtMHvthFOPMl7pt7KmxzX7E71AfyIhh+cPhLY9oko97Zf2C9tt/XJD4RgxhaGeAraAXDtqxvKE1y/j35lA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.13.0.tgz", + "integrity": "sha512-yUD/8wMffnTKuiIsl6xU+4IA8UNhQ/f1sAnQebmE/lyQ8abjsVyDkyRkWop0kdMhKMprpNIhPmYlCxgHrPoXoA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.13.0.tgz", + "integrity": "sha512-9RyNqoFNdF0vu/qqX63fKotBh43fJQeYC98hCaf89DYQpv+xu0D8QFSOS0biA7cGuqJFOc1bJ+m2rhhsKcw1hw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.13.0.tgz", + "integrity": "sha512-46ue8ymtm/5PUU6pCvjlic0z82qWkxv54GTJZgHrQUuZnVH+tvvSP0LsozIDsCBFO4VjJ13N68wqrKSeScUKdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.13.0.tgz", + "integrity": "sha512-P5/MqLdLSlqxbeuJ3YDeX37srC8mCflSyTrUsgbU1c/U9j6l2g2GiIdYaGD9QjdMQPMSgYm7hgg0551wHyIluw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.13.0.tgz", + "integrity": "sha512-UKXUQNbO3DOhzLRwHSpa0HnhhCgNODvfoPWv2FCXme8N/ANFfhIPMGuOT+QuKd16+B5yxZ0HdpNlqPvTMS1qfw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sveltejs/vite-plugin-svelte": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-3.0.2.tgz", + "integrity": "sha512-MpmF/cju2HqUls50WyTHQBZUV3ovV/Uk8k66AN2gwHogNAG8wnW8xtZDhzNBsFJJuvmq1qnzA5kE7YfMJNFv2Q==", + "dev": true, + "dependencies": { + "@sveltejs/vite-plugin-svelte-inspector": "^2.0.0", + "debug": "^4.3.4", + "deepmerge": "^4.3.1", + "kleur": "^4.1.5", + "magic-string": "^0.30.5", + "svelte-hmr": "^0.15.3", + "vitefu": "^0.2.5" + }, + "engines": { + "node": "^18.0.0 || >=20" + }, + "peerDependencies": { + "svelte": "^4.0.0 || ^5.0.0-next.0", + "vite": "^5.0.0" + } + }, + "node_modules/@sveltejs/vite-plugin-svelte-inspector": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-2.0.0.tgz", + "integrity": "sha512-gjr9ZFg1BSlIpfZ4PRewigrvYmHWbDrq2uvvPB1AmTWKuM+dI1JXQSUu2pIrYLb/QncyiIGkFDFKTwJ0XqQZZg==", + "dev": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.0.0 || >=20" + }, + "peerDependencies": { + "@sveltejs/vite-plugin-svelte": "^3.0.0", + "svelte": "^4.0.0 || ^5.0.0-next.0", + "vite": "^5.0.0" + } + }, + "node_modules/@tsconfig/svelte": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/svelte/-/svelte-5.0.2.tgz", + "integrity": "sha512-BRbo1fOtyVbhfLyuCWw6wAWp+U8UQle+ZXu84MYYWzYSEB28dyfnRBIE99eoG+qdAC0po6L2ScIEivcT07UaMA==", + "dev": true + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true + }, + "node_modules/@types/pug": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz", + "integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/axobject-query": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.0.0.tgz", + "integrity": "sha512-+60uv1hiVFhHZeO+Lz0RYzsVHy5Wr1ayX0mwda9KPDVLNJgZ1T9Ny7VmFbLDzxsH0D87I86vgj3gFrjTJUYznw==", + "dev": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/code-red": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", + "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15", + "@types/estree": "^1.0.1", + "acorn": "^8.10.0", + "estree-walker": "^3.0.3", + "periscopic": "^3.1.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/es6-promise": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", + "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==", + "dev": true + }, + "node_modules/esbuild": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-reference": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", + "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", + "dev": true, + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/locate-character": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", + "dev": true + }, + "node_modules/magic-string": { + "version": "0.30.8", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", + "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/periscopic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", + "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^3.0.0", + "is-reference": "^3.0.0" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/rollup": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.13.0.tgz", + "integrity": "sha512-3YegKemjoQnYKmsBlOHfMLVPPA5xLkQ8MHLLSw/fBrFaVkEayL51DilPpNNLq1exr98F2B1TzrV0FUlN3gWRPg==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.13.0", + "@rollup/rollup-android-arm64": "4.13.0", + "@rollup/rollup-darwin-arm64": "4.13.0", + "@rollup/rollup-darwin-x64": "4.13.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.13.0", + "@rollup/rollup-linux-arm64-gnu": "4.13.0", + "@rollup/rollup-linux-arm64-musl": "4.13.0", + "@rollup/rollup-linux-riscv64-gnu": "4.13.0", + "@rollup/rollup-linux-x64-gnu": "4.13.0", + "@rollup/rollup-linux-x64-musl": "4.13.0", + "@rollup/rollup-win32-arm64-msvc": "4.13.0", + "@rollup/rollup-win32-ia32-msvc": "4.13.0", + "@rollup/rollup-win32-x64-msvc": "4.13.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dev": true, + "dependencies": { + "mri": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sander": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/sander/-/sander-0.5.1.tgz", + "integrity": "sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==", + "dev": true, + "dependencies": { + "es6-promise": "^3.1.2", + "graceful-fs": "^4.1.3", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.2" + } + }, + "node_modules/sorcery": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.11.0.tgz", + "integrity": "sha512-J69LQ22xrQB1cIFJhPfgtLuI6BpWRiWu1Y3vSsIwK/eAScqJxd/+CJlUuHQRdX2C9NGFamq+KqNywGgaThwfHw==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.14", + "buffer-crc32": "^0.2.5", + "minimist": "^1.2.0", + "sander": "^0.5.0" + }, + "bin": { + "sorcery": "bin/sorcery" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/svelte": { + "version": "4.2.12", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.12.tgz", + "integrity": "sha512-d8+wsh5TfPwqVzbm4/HCXC783/KPHV60NvwitJnyTA5lWn1elhXMNWhXGCJ7PwPa8qFUnyJNIyuIRt2mT0WMug==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.1", + "@jridgewell/sourcemap-codec": "^1.4.15", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/estree": "^1.0.1", + "acorn": "^8.9.0", + "aria-query": "^5.3.0", + "axobject-query": "^4.0.0", + "code-red": "^1.0.3", + "css-tree": "^2.3.1", + "estree-walker": "^3.0.3", + "is-reference": "^3.0.1", + "locate-character": "^3.0.0", + "magic-string": "^0.30.4", + "periscopic": "^3.1.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/svelte-check": { + "version": "3.6.8", + "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.6.8.tgz", + "integrity": "sha512-rhXU7YCDtL+lq2gCqfJDXKTxJfSsCgcd08d7VWBFxTw6IWIbMWSaASbAOD3N0VV9TYSSLUqEBiratLd8WxAJJA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.17", + "chokidar": "^3.4.1", + "fast-glob": "^3.2.7", + "import-fresh": "^3.2.1", + "picocolors": "^1.0.0", + "sade": "^1.7.4", + "svelte-preprocess": "^5.1.3", + "typescript": "^5.0.3" + }, + "bin": { + "svelte-check": "bin/svelte-check" + }, + "peerDependencies": { + "svelte": "^3.55.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0" + } + }, + "node_modules/svelte-hmr": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.3.tgz", + "integrity": "sha512-41snaPswvSf8TJUhlkoJBekRrABDXDMdpNpT2tfHIv4JuhgvHqLMhEPGtaQn0BmbNSTkuz2Ed20DF2eHw0SmBQ==", + "dev": true, + "engines": { + "node": "^12.20 || ^14.13.1 || >= 16" + }, + "peerDependencies": { + "svelte": "^3.19.0 || ^4.0.0" + } + }, + "node_modules/svelte-preprocess": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.1.3.tgz", + "integrity": "sha512-xxAkmxGHT+J/GourS5mVJeOXZzne1FR5ljeOUAMXUkfEhkLEllRreXpbl3dIYJlcJRfL1LO1uIAPpBpBfiqGPw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@types/pug": "^2.0.6", + "detect-indent": "^6.1.0", + "magic-string": "^0.30.5", + "sorcery": "^0.11.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">= 16.0.0", + "pnpm": "^8.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.10.2", + "coffeescript": "^2.5.1", + "less": "^3.11.3 || ^4.0.0", + "postcss": "^7 || ^8", + "postcss-load-config": "^2.1.0 || ^3.0.0 || ^4.0.0 || ^5.0.0", + "pug": "^3.0.0", + "sass": "^1.26.8", + "stylus": "^0.55.0", + "sugarss": "^2.0.0 || ^3.0.0 || ^4.0.0", + "svelte": "^3.23.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0", + "typescript": ">=3.9.5 || ^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "coffeescript": { + "optional": true + }, + "less": { + "optional": true + }, + "postcss": { + "optional": true + }, + "postcss-load-config": { + "optional": true + }, + "pug": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, + "node_modules/typescript": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz", + "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/vite": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.2.tgz", + "integrity": "sha512-FWZbz0oSdLq5snUI0b6sULbz58iXFXdvkZfZWR/F0ZJuKTSPO7v72QPXt6KqYeMFb0yytNp6kZosxJ96Nr/wDQ==", + "dev": true, + "dependencies": { + "esbuild": "^0.20.1", + "postcss": "^8.4.36", + "rollup": "^4.13.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vitefu": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz", + "integrity": "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==", + "dev": true, + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + } + } +} diff --git a/svelte_sprinkles/package.json b/svelte_sprinkles/package.json new file mode 100644 index 00000000..4900a877 --- /dev/null +++ b/svelte_sprinkles/package.json @@ -0,0 +1,22 @@ +{ + "name": "ladysnake-svelte-sprinkles", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "watch": "vite build --watch", + "preview": "vite preview", + "check": "svelte-check --tsconfig ./tsconfig.json" + }, + "devDependencies": { + "@sveltejs/vite-plugin-svelte": "^3.0.2", + "@tsconfig/svelte": "^5.0.2", + "svelte": "^4.2.12", + "svelte-check": "^3.6.7", + "tslib": "^2.6.2", + "typescript": "^5.2.2", + "vite": "^5.2.0" + } +} diff --git a/svelte_sprinkles/public/vite.svg b/svelte_sprinkles/public/vite.svg new file mode 100644 index 00000000..e7b8dfb1 --- /dev/null +++ b/svelte_sprinkles/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/svelte_sprinkles/src/assets/svelte.svg b/svelte_sprinkles/src/assets/svelte.svg new file mode 100644 index 00000000..c5e08481 --- /dev/null +++ b/svelte_sprinkles/src/assets/svelte.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/svelte_sprinkles/src/lib/Counter.svelte b/svelte_sprinkles/src/lib/Counter.svelte new file mode 100644 index 00000000..979b4dfc --- /dev/null +++ b/svelte_sprinkles/src/lib/Counter.svelte @@ -0,0 +1,10 @@ + + + diff --git a/svelte_sprinkles/src/sprinkles/parlour/Parlour.svelte b/svelte_sprinkles/src/sprinkles/parlour/Parlour.svelte new file mode 100644 index 00000000..f2c7f83f --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/parlour/Parlour.svelte @@ -0,0 +1,47 @@ + + +
+
+ + + + + + +
+

Vite + Svelte

+ +
+ +
+ +

+ Check out SvelteKit, the official Svelte app framework powered by Vite! +

+ +

+ Click on the Vite and Svelte logos to learn more +

+
+ + diff --git a/svelte_sprinkles/src/sprinkles/parlour/main.ts b/svelte_sprinkles/src/sprinkles/parlour/main.ts new file mode 100644 index 00000000..95ac8b24 --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/parlour/main.ts @@ -0,0 +1,8 @@ +import './parlour.css' +import App from './Parlour.svelte' + +const app = new App({ + target: document.getElementById('blabber-parlour')!, +}) + +export default app diff --git a/svelte_sprinkles/src/sprinkles/parlour/parlour.css b/svelte_sprinkles/src/sprinkles/parlour/parlour.css new file mode 100644 index 00000000..26d51461 --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/parlour/parlour.css @@ -0,0 +1,79 @@ +:root { + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + 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; +} + +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; +} + +.card { + padding: 2em; +} + +#blabber-parlour { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +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; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/svelte_sprinkles/src/vite-env.d.ts b/svelte_sprinkles/src/vite-env.d.ts new file mode 100644 index 00000000..4078e747 --- /dev/null +++ b/svelte_sprinkles/src/vite-env.d.ts @@ -0,0 +1,2 @@ +/// +/// diff --git a/svelte_sprinkles/svelte.config.js b/svelte_sprinkles/svelte.config.js new file mode 100644 index 00000000..b0683fd2 --- /dev/null +++ b/svelte_sprinkles/svelte.config.js @@ -0,0 +1,7 @@ +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' + +export default { + // Consult https://svelte.dev/docs#compile-time-svelte-preprocess + // for more information about preprocessors + preprocess: vitePreprocess(), +} diff --git a/svelte_sprinkles/tsconfig.json b/svelte_sprinkles/tsconfig.json new file mode 100644 index 00000000..5fb548f2 --- /dev/null +++ b/svelte_sprinkles/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "@tsconfig/svelte/tsconfig.json", + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "resolveJsonModule": true, + /** + * Typecheck JS in `.svelte` and `.js` files by default. + * Disable checkJs if you'd like to use dynamic types in JS. + * Note that setting allowJs false does not prevent the use + * of JS in `.svelte` files. + */ + "allowJs": true, + "checkJs": true, + "isolatedModules": true + }, + "include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/svelte_sprinkles/tsconfig.node.json b/svelte_sprinkles/tsconfig.node.json new file mode 100644 index 00000000..d02c37df --- /dev/null +++ b/svelte_sprinkles/tsconfig.node.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "strict": true + }, + "include": ["vite.config.ts"] +} diff --git a/svelte_sprinkles/vite.config.ts b/svelte_sprinkles/vite.config.ts new file mode 100644 index 00000000..6a359657 --- /dev/null +++ b/svelte_sprinkles/vite.config.ts @@ -0,0 +1,25 @@ +import {ConfigEnv, defineConfig, UserConfig} from 'vite' +import {svelte} from '@sveltejs/vite-plugin-svelte' + +// https://vitejs.dev/config/ +// Vite+Jekyll setup derived from https://github.com/FabricMC/fabricmc.net/blob/b88f4f058064087405e351849a04931b27c89925/scripts/vite.config.js +export default defineConfig(({ mode }: ConfigEnv) => ({ + // Web build + plugins: [svelte()], + build: { + sourcemap: mode === "development", + // Build directly into the Jekyll output directory + outDir: "../_site/scripts/sprinkles", + emptyOutDir: true, + rollupOptions: { + input: { + 'blabber-parlour': './src/sprinkles/parlour/main.ts' + }, + output: { + entryFileNames: `[name].js`, + chunkFileNames: `[name].[hash].js`, + assetFileNames: `[name].[ext]` + } + } + } +}) as UserConfig); From 3a193c8e00f3d544174b42040a2ca1e0ccebe65a Mon Sep 17 00:00:00 2001 From: Pyrofab Date: Fri, 22 Mar 2024 16:55:21 +0100 Subject: [PATCH 02/68] Convert dialogue creation form to Svelte --- .editorconfig | 7 + public/tools/parlour.html | 33 +++ svelte_sprinkles/blabber-parlour.html | 14 +- svelte_sprinkles/public/vite.svg | 1 - .../src/assets/ExternalLink.svelte | 1 + .../src/assets/OcticonDownload.svelte | 5 + .../src/assets/OcticonUpload.svelte | 5 + svelte_sprinkles/src/assets/svelte.svg | 1 - .../src/sprinkles/parlour/BlabberDialogue.ts | 88 ++++++ .../src/sprinkles/parlour/Footer.svelte | 102 +++++++ .../src/sprinkles/parlour/Parlour.svelte | 47 +-- .../sprinkles/parlour/dialogueDataStore.ts | 36 +++ .../dialogueio/DialogueImportExport.svelte | 124 ++++++++ .../sprinkles/parlour/landing/Landing.svelte | 16 ++ .../parlour/landing/NewDialogueForm.svelte | 272 ++++++++++++++++++ .../src/sprinkles/parlour/localStorageKeys.ts | 1 + .../src/sprinkles/parlour/parlour.css | 79 +---- .../src/sprinkles/parlour/validation.ts | 17 ++ svelte_sprinkles/vite.config.ts | 2 + 19 files changed, 728 insertions(+), 123 deletions(-) create mode 100644 public/tools/parlour.html delete mode 100644 svelte_sprinkles/public/vite.svg create mode 100644 svelte_sprinkles/src/assets/ExternalLink.svelte create mode 100644 svelte_sprinkles/src/assets/OcticonDownload.svelte create mode 100644 svelte_sprinkles/src/assets/OcticonUpload.svelte delete mode 100644 svelte_sprinkles/src/assets/svelte.svg create mode 100644 svelte_sprinkles/src/sprinkles/parlour/BlabberDialogue.ts create mode 100644 svelte_sprinkles/src/sprinkles/parlour/Footer.svelte create mode 100644 svelte_sprinkles/src/sprinkles/parlour/dialogueDataStore.ts create mode 100644 svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueImportExport.svelte create mode 100644 svelte_sprinkles/src/sprinkles/parlour/landing/Landing.svelte create mode 100644 svelte_sprinkles/src/sprinkles/parlour/landing/NewDialogueForm.svelte create mode 100644 svelte_sprinkles/src/sprinkles/parlour/localStorageKeys.ts create mode 100644 svelte_sprinkles/src/sprinkles/parlour/validation.ts diff --git a/.editorconfig b/.editorconfig index e845b06b..54e02e9d 100644 --- a/.editorconfig +++ b/.editorconfig @@ -3,3 +3,10 @@ ij_javascript_spaces_within_object_literal_braces = true [*.ts] ij_typescript_spaces_within_object_literal_braces = true + +[*.html] +indent_size = 2 + +[*.svelte] +indent_size = 2 +ij_typescript_spaces_within_object_literal_braces = true diff --git a/public/tools/parlour.html b/public/tools/parlour.html new file mode 100644 index 00000000..3d5c34e3 --- /dev/null +++ b/public/tools/parlour.html @@ -0,0 +1,33 @@ +--- +layout: default +no_anchor_headings: true +title: Blabber Dialogue Editor +og: +img: /img/blabber.png +img_alt: blabber logo +desc: Online editor for blabber dialogues +--- + + +{% include wip.liquid message="Conditional choices (added in Blabber 1.0) are not yet available in this editor." %} + + +
+ + diff --git a/svelte_sprinkles/blabber-parlour.html b/svelte_sprinkles/blabber-parlour.html index cbb6fe81..86260fb3 100644 --- a/svelte_sprinkles/blabber-parlour.html +++ b/svelte_sprinkles/blabber-parlour.html @@ -2,13 +2,17 @@ - - - + + + + + Blabber Dialogue Generator -
- +
+
+ +
diff --git a/svelte_sprinkles/public/vite.svg b/svelte_sprinkles/public/vite.svg deleted file mode 100644 index e7b8dfb1..00000000 --- a/svelte_sprinkles/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/svelte_sprinkles/src/assets/ExternalLink.svelte b/svelte_sprinkles/src/assets/ExternalLink.svelte new file mode 100644 index 00000000..a1c3b334 --- /dev/null +++ b/svelte_sprinkles/src/assets/ExternalLink.svelte @@ -0,0 +1 @@ + diff --git a/svelte_sprinkles/src/assets/OcticonDownload.svelte b/svelte_sprinkles/src/assets/OcticonDownload.svelte new file mode 100644 index 00000000..8ef2c773 --- /dev/null +++ b/svelte_sprinkles/src/assets/OcticonDownload.svelte @@ -0,0 +1,5 @@ + diff --git a/svelte_sprinkles/src/assets/OcticonUpload.svelte b/svelte_sprinkles/src/assets/OcticonUpload.svelte new file mode 100644 index 00000000..9c265997 --- /dev/null +++ b/svelte_sprinkles/src/assets/OcticonUpload.svelte @@ -0,0 +1,5 @@ + diff --git a/svelte_sprinkles/src/assets/svelte.svg b/svelte_sprinkles/src/assets/svelte.svg deleted file mode 100644 index c5e08481..00000000 --- a/svelte_sprinkles/src/assets/svelte.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/svelte_sprinkles/src/sprinkles/parlour/BlabberDialogue.ts b/svelte_sprinkles/src/sprinkles/parlour/BlabberDialogue.ts new file mode 100644 index 00000000..b3a9ca61 --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/parlour/BlabberDialogue.ts @@ -0,0 +1,88 @@ +export interface McText { + readonly value: string | object; + readonly translate?: string; +} + +export interface DialogueAction { + readonly type?: string; + readonly value?: string; +} + +export interface DialogueChoice { + readonly text?: McText; + readonly next?: string; +} + +export interface DialogueState { + readonly type?: string; + readonly text?: McText; + readonly action?: DialogueAction; + readonly choices?: DialogueChoice[]; +} + +export interface DialogueLayout { + readonly type?: string; +} + +export interface DialogueData { + readonly states?: Record; + readonly start_at?: string; + readonly unskippable?: boolean; + readonly layout?: DialogueLayout; +} + +export default class BlabberDialogue { + readonly data: DialogueData; + + /** + * Constructs a new dialogue with no data + */ + constructor(data: DialogueData = {}) { + this.data = data; + } + + get startAt(): string | undefined { + return this.data.start_at; + } + + get unskippable(): boolean { + return !!this.data.unskippable; + } + + get layout(): string | undefined { + return this.data.layout?.type; + } + + get states(): string[] { + return Object.keys(this.data.states ?? {}); + } + + stateData(key: string): DialogueState | undefined { + return this.data.states?.[key]; + } + + withStartAt(state?: string) { + return new BlabberDialogue({ ...this.data, start_at: state }); + } + + withUnskippability(unskippable: boolean) { + return new BlabberDialogue({ ...this.data, unskippable }); + } + + withLayout(layout: string) { + return new BlabberDialogue({ ...this.data, layout: { type: layout } }); + } + + isLoaded(): boolean { + return this.data.states !== null; + } + + prune() { + return new BlabberDialogue({ + ...this.data, + states: Object.fromEntries(Object.entries(this.data.states ?? {}).map(([key, { action, ...state }]) => { + return [key, action?.type === '' ? { ...state } : { action, ...state }]; + })), + }); + } +} diff --git a/svelte_sprinkles/src/sprinkles/parlour/Footer.svelte b/svelte_sprinkles/src/sprinkles/parlour/Footer.svelte new file mode 100644 index 00000000..8b7820e1 --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/parlour/Footer.svelte @@ -0,0 +1,102 @@ + + \ No newline at end of file diff --git a/svelte_sprinkles/src/sprinkles/parlour/Parlour.svelte b/svelte_sprinkles/src/sprinkles/parlour/Parlour.svelte index f2c7f83f..6abc0bae 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/Parlour.svelte +++ b/svelte_sprinkles/src/sprinkles/parlour/Parlour.svelte @@ -1,47 +1,16 @@
- -

Vite + Svelte

- -
- -
- -

- Check out SvelteKit, the official Svelte app framework powered by Vite! -

- -

- Click on the Vite and Svelte logos to learn more -

+ {#if (!$dialogueFilename)} + + {:else} +

{$dialogueFilename}

+ + {/if}
diff --git a/svelte_sprinkles/src/sprinkles/parlour/dialogueDataStore.ts b/svelte_sprinkles/src/sprinkles/parlour/dialogueDataStore.ts new file mode 100644 index 00000000..b0dca260 --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/parlour/dialogueDataStore.ts @@ -0,0 +1,36 @@ +import {writable, get, derived, type Writable} from 'svelte/store'; +import BlabberDialogue from './BlabberDialogue'; + +function createDialogueData() { + let store = writable(new BlabberDialogue()); + const { subscribe, set, update } = store; + + function unload(): void { + set(new BlabberDialogue()); + } + + return { + subscribe, + set, + update, + unload, + }; +} + +export const dialogueData = createDialogueData(); +export const dialogueStart: Writable = { + ...(derived(dialogueData,(d) => d.startAt)), + set: (startAt: string) => dialogueData.update((d) => d.withStartAt(startAt)), + update: (fn: (startAt: string | undefined) => string) => dialogueData.update((d) => d.withStartAt(fn(d.startAt))) +} +export const dialogueUnskippable: Writable = { + ...(derived(dialogueData,(d) => d.unskippable)), + set: (unskippable: boolean) => dialogueData.update((d) => d.withUnskippability(unskippable)), + update: (fn: (unskippable: boolean) => boolean) => dialogueData.update((d) => d.withUnskippability(fn(d.unskippable))) +} +export const dialogueLayout: Writable = { + ...(derived(dialogueData,(d) => d.layout)), + set: (layout: string) => dialogueData.update((d) => d.withLayout(layout)), + update: (fn: (layout: string | undefined) => string) => dialogueData.update((d) => d.withLayout(fn(d.layout))) +} +export const dialogueFilename = writable(); diff --git a/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueImportExport.svelte b/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueImportExport.svelte new file mode 100644 index 00000000..0c88a027 --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueImportExport.svelte @@ -0,0 +1,124 @@ +
+ + + Or drop a dialogue file in this area to import +
+ + Drop a dialogue file here to import +
+

{info}

+

{warning}

+

{error}

+
+ + + + diff --git a/svelte_sprinkles/src/sprinkles/parlour/landing/Landing.svelte b/svelte_sprinkles/src/sprinkles/parlour/landing/Landing.svelte new file mode 100644 index 00000000..e1cc4e7a --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/parlour/landing/Landing.svelte @@ -0,0 +1,16 @@ +
+ + + +
+ + + + diff --git a/svelte_sprinkles/src/sprinkles/parlour/landing/NewDialogueForm.svelte b/svelte_sprinkles/src/sprinkles/parlour/landing/NewDialogueForm.svelte new file mode 100644 index 00000000..04cfd9e2 --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/parlour/landing/NewDialogueForm.svelte @@ -0,0 +1,272 @@ + + +
+

Create a dialogue

+
+ +
+
+ Which format should this editor use for texts? + + + + + + + + + + + + +
+
+ What layout do you want your dialogue to use for regular states? + + + + + + + + +
+
+ + +
+
+ + validateIdentifierField(e.currentTarget)} + /> +
+
+ + validateIdentifierField(e.currentTarget)} + /> +
+ +
+ + diff --git a/svelte_sprinkles/src/sprinkles/parlour/localStorageKeys.ts b/svelte_sprinkles/src/sprinkles/parlour/localStorageKeys.ts new file mode 100644 index 00000000..b4f56bf7 --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/parlour/localStorageKeys.ts @@ -0,0 +1 @@ +export const EDITOR_TEXT_FORMAT_KEY = 'blabber-editor-text-format'; diff --git a/svelte_sprinkles/src/sprinkles/parlour/parlour.css b/svelte_sprinkles/src/sprinkles/parlour/parlour.css index 26d51461..e219ea58 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/parlour.css +++ b/svelte_sprinkles/src/sprinkles/parlour/parlour.css @@ -1,79 +1,4 @@ -:root { - font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; - line-height: 1.5; - 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; -} - -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; -} - -.card { - padding: 2em; -} - #blabber-parlour { - max-width: 1280px; - margin: 0 auto; - padding: 2rem; - text-align: center; -} - -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; -} - -@media (prefers-color-scheme: light) { - :root { - color: #213547; - background-color: #ffffff; - } - a:hover { - color: #747bff; - } - button { - background-color: #f9f9f9; - } + display: flex; + justify-content: center; } diff --git a/svelte_sprinkles/src/sprinkles/parlour/validation.ts b/svelte_sprinkles/src/sprinkles/parlour/validation.ts new file mode 100644 index 00000000..02353570 --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/parlour/validation.ts @@ -0,0 +1,17 @@ +import type BlabberDialogue from "./BlabberDialogue"; + +export function validateIdentifierField(element: HTMLInputElement, dialogue?: BlabberDialogue, acceptEmpty?: boolean) { + if (!(acceptEmpty || element.value)) { + element.setCustomValidity('Please enter a valid non-namespaced identifier'); + } else if (element.validity.patternMismatch) { + element.setCustomValidity('Must be a valid non-namespaced identifier (lowercase letters, numbers and dashes/underscores only)'); + } else if (dialogue && dialogue.data.states && element.value in dialogue.data.states) { + element.setCustomValidity('A state with that name already exists'); + } else { + element.setCustomValidity(''); + element.reportValidity(); + return true; + } + element.reportValidity(); + return false; +} diff --git a/svelte_sprinkles/vite.config.ts b/svelte_sprinkles/vite.config.ts index 6a359657..43460be9 100644 --- a/svelte_sprinkles/vite.config.ts +++ b/svelte_sprinkles/vite.config.ts @@ -6,11 +6,13 @@ import {svelte} from '@sveltejs/vite-plugin-svelte' export default defineConfig(({ mode }: ConfigEnv) => ({ // Web build plugins: [svelte()], + publicDir: '../_site', build: { sourcemap: mode === "development", // Build directly into the Jekyll output directory outDir: "../_site/scripts/sprinkles", emptyOutDir: true, + copyPublicDir: false, rollupOptions: { input: { 'blabber-parlour': './src/sprinkles/parlour/main.ts' From 06d648f47079e376ee16056bfd4793dca949eebf Mon Sep 17 00:00:00 2001 From: Pyrofab Date: Fri, 22 Mar 2024 16:58:57 +0100 Subject: [PATCH 03/68] Always enable sourcemap generation in sprinkles We are not hiding anything here --- svelte_sprinkles/vite.config.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/svelte_sprinkles/vite.config.ts b/svelte_sprinkles/vite.config.ts index 43460be9..37e34d4e 100644 --- a/svelte_sprinkles/vite.config.ts +++ b/svelte_sprinkles/vite.config.ts @@ -3,12 +3,12 @@ import {svelte} from '@sveltejs/vite-plugin-svelte' // https://vitejs.dev/config/ // Vite+Jekyll setup derived from https://github.com/FabricMC/fabricmc.net/blob/b88f4f058064087405e351849a04931b27c89925/scripts/vite.config.js -export default defineConfig(({ mode }: ConfigEnv) => ({ +export default defineConfig(() => ({ // Web build plugins: [svelte()], publicDir: '../_site', build: { - sourcemap: mode === "development", + sourcemap: true, // Build directly into the Jekyll output directory outDir: "../_site/scripts/sprinkles", emptyOutDir: true, From 7554a45310fc5413792f29ecdd50c5d1dfeb7683 Mon Sep 17 00:00:00 2001 From: Pyrofab Date: Fri, 22 Mar 2024 18:54:25 +0100 Subject: [PATCH 04/68] Convert dialogue import code to Svelte --- svelte_sprinkles/package-lock.json | 15 ++ svelte_sprinkles/package.json | 4 + .../src/assets/GraphOutline.svelte | 8 ++ .../src/assets/ViewDashboardOutline.svelte | 8 ++ .../src/sprinkles/parlour/BlabberDialogue.ts | 9 +- .../src/sprinkles/parlour/Footer.svelte | 111 +++------------ .../dialogueio/DialogueImportExport.svelte | 128 +++++++++++++++++- .../sprinkles/parlour/landing/Landing.svelte | 4 +- .../src/sprinkles/parlour/validation.ts | 65 +++++++++ 9 files changed, 248 insertions(+), 104 deletions(-) create mode 100644 svelte_sprinkles/src/assets/GraphOutline.svelte create mode 100644 svelte_sprinkles/src/assets/ViewDashboardOutline.svelte diff --git a/svelte_sprinkles/package-lock.json b/svelte_sprinkles/package-lock.json index 8b0c8850..81ee029c 100644 --- a/svelte_sprinkles/package-lock.json +++ b/svelte_sprinkles/package-lock.json @@ -7,9 +7,13 @@ "": { "name": "ladysnake-svelte-sprinkles", "version": "0.0.0", + "dependencies": { + "file-saver": "^2.0.5" + }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^3.0.2", "@tsconfig/svelte": "^5.0.2", + "@types/file-saver": "^2.0.7", "svelte": "^4.2.12", "svelte-check": "^3.6.7", "tslib": "^2.6.2", @@ -701,6 +705,12 @@ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, + "node_modules/@types/file-saver": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.7.tgz", + "integrity": "sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==", + "dev": true + }, "node_modules/@types/pug": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz", @@ -986,6 +996,11 @@ "reusify": "^1.0.4" } }, + "node_modules/file-saver": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz", + "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==" + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", diff --git a/svelte_sprinkles/package.json b/svelte_sprinkles/package.json index 4900a877..68190004 100644 --- a/svelte_sprinkles/package.json +++ b/svelte_sprinkles/package.json @@ -13,10 +13,14 @@ "devDependencies": { "@sveltejs/vite-plugin-svelte": "^3.0.2", "@tsconfig/svelte": "^5.0.2", + "@types/file-saver": "^2.0.7", "svelte": "^4.2.12", "svelte-check": "^3.6.7", "tslib": "^2.6.2", "typescript": "^5.2.2", "vite": "^5.2.0" + }, + "dependencies": { + "file-saver": "^2.0.5" } } diff --git a/svelte_sprinkles/src/assets/GraphOutline.svelte b/svelte_sprinkles/src/assets/GraphOutline.svelte new file mode 100644 index 00000000..6ccbff3a --- /dev/null +++ b/svelte_sprinkles/src/assets/GraphOutline.svelte @@ -0,0 +1,8 @@ + + {alt} + + + + \ No newline at end of file diff --git a/svelte_sprinkles/src/assets/ViewDashboardOutline.svelte b/svelte_sprinkles/src/assets/ViewDashboardOutline.svelte new file mode 100644 index 00000000..fbc8dbc0 --- /dev/null +++ b/svelte_sprinkles/src/assets/ViewDashboardOutline.svelte @@ -0,0 +1,8 @@ + + {alt} + + + + \ No newline at end of file diff --git a/svelte_sprinkles/src/sprinkles/parlour/BlabberDialogue.ts b/svelte_sprinkles/src/sprinkles/parlour/BlabberDialogue.ts index b3a9ca61..11818de0 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/BlabberDialogue.ts +++ b/svelte_sprinkles/src/sprinkles/parlour/BlabberDialogue.ts @@ -53,8 +53,8 @@ export default class BlabberDialogue { return this.data.layout?.type; } - get states(): string[] { - return Object.keys(this.data.states ?? {}); + get states(): [string, DialogueState][] { + return Object.entries(this.data.states ?? {}); } stateData(key: string): DialogueState | undefined { @@ -77,6 +77,11 @@ export default class BlabberDialogue { return this.data.states !== null; } + saveToWindow() { + const newState = {...(window.history.state ?? {}), data: this.data}; + window.history.replaceState(newState, ''); + } + prune() { return new BlabberDialogue({ ...this.data, diff --git a/svelte_sprinkles/src/sprinkles/parlour/Footer.svelte b/svelte_sprinkles/src/sprinkles/parlour/Footer.svelte index 8b7820e1..6f9fa257 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/Footer.svelte +++ b/svelte_sprinkles/src/sprinkles/parlour/Footer.svelte @@ -1,102 +1,23 @@ \ No newline at end of file + + + + diff --git a/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueImportExport.svelte b/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueImportExport.svelte index 0c88a027..9acb62e3 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueImportExport.svelte +++ b/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueImportExport.svelte @@ -1,11 +1,19 @@ -
- +
+ - Or drop a dialogue file in this area to import -
+ + {#if !importOnly} + + {/if} +
0} class:hovered={draggingInDropZone > 0} + on:dragover|preventDefault> Drop a dialogue file here to import
@@ -16,16 +24,124 @@ diff --git a/svelte_sprinkles/src/sprinkles/parlour/Parlour.svelte b/svelte_sprinkles/src/sprinkles/parlour/Parlour.svelte index 6abc0bae..56eff4e2 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/Parlour.svelte +++ b/svelte_sprinkles/src/sprinkles/parlour/Parlour.svelte @@ -1,16 +1,40 @@
{#if (!$dialogueFilename)} {:else} -

{$dialogueFilename}

- + {#if mainView} + + {:else} +

{$dialogueFilename}

+ + {/if} +
{/if}
diff --git a/svelte_sprinkles/src/sprinkles/parlour/dialogueDataStore.ts b/svelte_sprinkles/src/sprinkles/parlour/dialogueDataStore.ts index b0dca260..d3da40dd 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/dialogueDataStore.ts +++ b/svelte_sprinkles/src/sprinkles/parlour/dialogueDataStore.ts @@ -1,4 +1,4 @@ -import {writable, get, derived, type Writable} from 'svelte/store'; +import {writable, derived, type Writable} from 'svelte/store'; import BlabberDialogue from './BlabberDialogue'; function createDialogueData() { @@ -23,6 +23,7 @@ export const dialogueStart: Writable = { set: (startAt: string) => dialogueData.update((d) => d.withStartAt(startAt)), update: (fn: (startAt: string | undefined) => string) => dialogueData.update((d) => d.withStartAt(fn(d.startAt))) } +export const dialogueStateKeys = derived(dialogueData,(d) => Object.keys(d.states)); export const dialogueUnskippable: Writable = { ...(derived(dialogueData,(d) => d.unskippable)), set: (unskippable: boolean) => dialogueData.update((d) => d.withUnskippability(unskippable)), diff --git a/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueImportExport.svelte b/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueImportExport.svelte index 28ab7406..3fbb0f9e 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueImportExport.svelte +++ b/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueImportExport.svelte @@ -1,36 +1,44 @@ -
+
{#if !importOnly} {/if} -
0} class:hovered={draggingInDropZone > 0} - on:dragover|preventDefault> - +
0} + class:hovered={draggingInDropZone > 0} + on:dragover|preventDefault + > + Drop a dialogue file here to import
-

{info}

-

{warning}

-

{error}

+

{info}

+

{warning}

+

{error}

+
+
+ +

Global Properties

+
+ +
+
+ + diff --git a/svelte_sprinkles/src/sprinkles/parlour/editor/DialogueStateList.svelte b/svelte_sprinkles/src/sprinkles/parlour/editor/DialogueStateList.svelte new file mode 100644 index 00000000..8383a01d --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/parlour/editor/DialogueStateList.svelte @@ -0,0 +1,24 @@ + + +
+

Dialogue States

+ +
+ + \ No newline at end of file diff --git a/svelte_sprinkles/src/sprinkles/parlour/editor/MainEditor.svelte b/svelte_sprinkles/src/sprinkles/parlour/editor/MainEditor.svelte new file mode 100644 index 00000000..db79b774 --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/parlour/editor/MainEditor.svelte @@ -0,0 +1,22 @@ + + +
+ +
+ + {#if selectedState} + + {/if} +
+
+ + \ No newline at end of file diff --git a/svelte_sprinkles/src/sprinkles/parlour/editor/NewDialogueState.svelte b/svelte_sprinkles/src/sprinkles/parlour/editor/NewDialogueState.svelte new file mode 100644 index 00000000..efe38068 --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/parlour/editor/NewDialogueState.svelte @@ -0,0 +1,56 @@ + +
+ + validateIdentifierField(e.currentTarget, $dialogueData, true)} + /> + +

+
+ \ No newline at end of file diff --git a/svelte_sprinkles/src/sprinkles/parlour/editor/state/DialogueStateProperties.svelte b/svelte_sprinkles/src/sprinkles/parlour/editor/state/DialogueStateProperties.svelte new file mode 100644 index 00000000..5731f1c0 --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/parlour/editor/state/DialogueStateProperties.svelte @@ -0,0 +1,38 @@ + +
+ + + + + + diff --git a/svelte_sprinkles/src/sprinkles/parlour/editor/state/DialogueStateView.svelte b/svelte_sprinkles/src/sprinkles/parlour/editor/state/DialogueStateView.svelte new file mode 100644 index 00000000..fed30f7c --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/parlour/editor/state/DialogueStateView.svelte @@ -0,0 +1,39 @@ + +
+

State Properties: {state}

+ + +
+

+ Available Choices + +

+
+
+ + + + + + + + + + + +
TextNext StateSortRemove
+
+
+
+
+ \ No newline at end of file diff --git a/svelte_sprinkles/src/sprinkles/parlour/editor/state/StateActionInput.svelte b/svelte_sprinkles/src/sprinkles/parlour/editor/state/StateActionInput.svelte new file mode 100644 index 00000000..96fdb71f --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/parlour/editor/state/StateActionInput.svelte @@ -0,0 +1,107 @@ + + + + +
+ + +
+ + diff --git a/svelte_sprinkles/src/sprinkles/parlour/editor/state/StateTextInput.svelte b/svelte_sprinkles/src/sprinkles/parlour/editor/state/StateTextInput.svelte new file mode 100644 index 00000000..d75c4918 --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/parlour/editor/state/StateTextInput.svelte @@ -0,0 +1,38 @@ + + + + + + diff --git a/svelte_sprinkles/src/sprinkles/parlour/editor/state/type/ConfirmDialogueLayout.svelte b/svelte_sprinkles/src/sprinkles/parlour/editor/state/type/ConfirmDialogueLayout.svelte new file mode 100644 index 00000000..8db276db --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/parlour/editor/state/type/ConfirmDialogueLayout.svelte @@ -0,0 +1,14 @@ + + + Title + + Second option + + First option + + diff --git a/svelte_sprinkles/src/sprinkles/parlour/editor/state/type/DefaultDialogueLayout.svelte b/svelte_sprinkles/src/sprinkles/parlour/editor/state/type/DefaultDialogueLayout.svelte new file mode 100644 index 00000000..fde920ec --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/parlour/editor/state/type/DefaultDialogueLayout.svelte @@ -0,0 +1,14 @@ + + + This is the title + This is the first option + This is the second option + This is the selected option + Hover or press [W]/[S] to select a choice, then click or press [E] to confirm it + + diff --git a/svelte_sprinkles/src/sprinkles/parlour/editor/state/type/EndDialogueLayout.svelte b/svelte_sprinkles/src/sprinkles/parlour/editor/state/type/EndDialogueLayout.svelte new file mode 100644 index 00000000..b9ba791e --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/parlour/editor/state/type/EndDialogueLayout.svelte @@ -0,0 +1,17 @@ + + + + + + + + + + + + diff --git a/svelte_sprinkles/src/sprinkles/parlour/editor/state/type/StateTypeInput.svelte b/svelte_sprinkles/src/sprinkles/parlour/editor/state/type/StateTypeInput.svelte new file mode 100644 index 00000000..07c10922 --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/parlour/editor/state/type/StateTypeInput.svelte @@ -0,0 +1,100 @@ + + +
+ Type + + + + + + +
+ + diff --git a/svelte_sprinkles/src/sprinkles/parlour/landing/Landing.svelte b/svelte_sprinkles/src/sprinkles/parlour/landing/Landing.svelte index b65f12e3..a1f79c5d 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/landing/Landing.svelte +++ b/svelte_sprinkles/src/sprinkles/parlour/landing/Landing.svelte @@ -1,18 +1,27 @@
- - + + +
Or drop a dialogue file in this area to import +
diff --git a/svelte_sprinkles/src/sprinkles/parlour/landing/NewDialogueForm.svelte b/svelte_sprinkles/src/sprinkles/parlour/landing/NewDialogueForm.svelte index 04cfd9e2..526ba1fb 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/landing/NewDialogueForm.svelte +++ b/svelte_sprinkles/src/sprinkles/parlour/landing/NewDialogueForm.svelte @@ -1,5 +1,4 @@ @@ -108,8 +106,8 @@ bind:group={textFormat} /> + href="https://minecraft.wiki/w/Raw_JSON_text_format">the wiki page , or a generator )
@@ -136,7 +134,7 @@
- +
diff --git a/svelte_sprinkles/src/sprinkles/parlour/validation.ts b/svelte_sprinkles/src/sprinkles/parlour/validation.ts index 235b3dad..67914bb9 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/validation.ts +++ b/svelte_sprinkles/src/sprinkles/parlour/validation.ts @@ -21,7 +21,7 @@ function validateStructure(dialogue: BlabberDialogue, logWarning: (msg: string) const waitList: Set = new Set(); const unvalidated: Set = new Set(); - for (const [state, { type, choices }] of dialogue.states) { + for (const [state, { type, choices }] of Object.entries(dialogue.states)) { if (type === 'end_dialogue') { waitList.add(state); } else if (!choices) { diff --git a/svelte_sprinkles/vite.config.ts b/svelte_sprinkles/vite.config.ts index 37e34d4e..4579fa77 100644 --- a/svelte_sprinkles/vite.config.ts +++ b/svelte_sprinkles/vite.config.ts @@ -1,11 +1,21 @@ import {ConfigEnv, defineConfig, UserConfig} from 'vite' import {svelte} from '@sveltejs/vite-plugin-svelte' +import {inlineSvg} from "@svelte-put/preprocess-inline-svg/vite"; // https://vitejs.dev/config/ // Vite+Jekyll setup derived from https://github.com/FabricMC/fabricmc.net/blob/b88f4f058064087405e351849a04931b27c89925/scripts/vite.config.js export default defineConfig(() => ({ // Web build - plugins: [svelte()], + plugins: [ + inlineSvg([ + { + directories: '../public/_includes/svg' + } + ], { + inlineSrcAttributeName: 'inline-src', + }), + svelte() + ], publicDir: '../_site', build: { sourcemap: true, @@ -15,7 +25,7 @@ export default defineConfig(() => ({ copyPublicDir: false, rollupOptions: { input: { - 'blabber-parlour': './src/sprinkles/parlour/main.ts' + 'blabber-parlour': './src/sprinkles/parlour/main.ts' }, output: { entryFileNames: `[name].js`, From 2ee66cd38b754181085acf1d3ba5ece52ac33748 Mon Sep 17 00:00:00 2001 From: Pyrofab Date: Sun, 24 Mar 2024 12:51:08 +0100 Subject: [PATCH 07/68] Implement dialogue text input --- svelte_sprinkles/src/lib/Counter.svelte | 10 ---- svelte_sprinkles/src/lib/McText.ts | 28 +++++++++++ svelte_sprinkles/src/lib/McTextInput.svelte | 44 +++++++++++++++++ .../src/sprinkles/parlour/BlabberDialogue.ts | 10 +--- .../sprinkles/parlour/dialogueDataStore.ts | 2 + .../dialogueio/DialogueImportExport.svelte | 4 ++ .../editor/DialogueGlobalProperties.svelte | 20 ++++++-- .../editor/state/StateActionInput.svelte | 4 +- .../editor/state/StateTextInput.svelte | 47 +++++++++++-------- .../parlour/landing/NewDialogueForm.svelte | 19 +++++--- 10 files changed, 136 insertions(+), 52 deletions(-) delete mode 100644 svelte_sprinkles/src/lib/Counter.svelte create mode 100644 svelte_sprinkles/src/lib/McText.ts create mode 100644 svelte_sprinkles/src/lib/McTextInput.svelte diff --git a/svelte_sprinkles/src/lib/Counter.svelte b/svelte_sprinkles/src/lib/Counter.svelte deleted file mode 100644 index 979b4dfc..00000000 --- a/svelte_sprinkles/src/lib/Counter.svelte +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/svelte_sprinkles/src/lib/McText.ts b/svelte_sprinkles/src/lib/McText.ts new file mode 100644 index 00000000..98f776f2 --- /dev/null +++ b/svelte_sprinkles/src/lib/McText.ts @@ -0,0 +1,28 @@ +export interface McTextRaw { + readonly value: string | object; +} + +export interface McTextTranslatable { + readonly translate?: string; +} + +export type McText = string | McTextTranslatable | McTextRaw; + +export enum McTextType { + PLAIN = 'plain', + TRANSLATION_KEY = 'translation_key', + JSON = 'json', +} + +export function parseMcTextType(value: string) { + switch (value) { + case 'literal': + return McTextType.PLAIN; + case 'translate': + return McTextType.TRANSLATION_KEY; + case 'json': + return McTextType.JSON; + default: + return McTextType.PLAIN; + } +} diff --git a/svelte_sprinkles/src/lib/McTextInput.svelte b/svelte_sprinkles/src/lib/McTextInput.svelte new file mode 100644 index 00000000..508f200a --- /dev/null +++ b/svelte_sprinkles/src/lib/McTextInput.svelte @@ -0,0 +1,44 @@ + + { + value = exportDialogueText(e.currentTarget.value); + dispatch('change', value); + }} +/> diff --git a/svelte_sprinkles/src/sprinkles/parlour/BlabberDialogue.ts b/svelte_sprinkles/src/sprinkles/parlour/BlabberDialogue.ts index 5d687e76..3bbc8177 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/BlabberDialogue.ts +++ b/svelte_sprinkles/src/sprinkles/parlour/BlabberDialogue.ts @@ -1,12 +1,4 @@ -export interface McTextRaw { - readonly value: string | object; -} - -export interface McTextTranslatable { - readonly translate?: string; -} - -export type McText = string | McTextTranslatable | McTextRaw; +import type {McText} from "../../lib/McText"; export interface DialogueAction { readonly type?: string; diff --git a/svelte_sprinkles/src/sprinkles/parlour/dialogueDataStore.ts b/svelte_sprinkles/src/sprinkles/parlour/dialogueDataStore.ts index d3da40dd..9bc46608 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/dialogueDataStore.ts +++ b/svelte_sprinkles/src/sprinkles/parlour/dialogueDataStore.ts @@ -1,5 +1,6 @@ import {writable, derived, type Writable} from 'svelte/store'; import BlabberDialogue from './BlabberDialogue'; +import {McTextType} from "../../lib/McText"; function createDialogueData() { let store = writable(new BlabberDialogue()); @@ -35,3 +36,4 @@ export const dialogueLayout: Writable = { update: (fn: (layout: string | undefined) => string) => dialogueData.update((d) => d.withLayout(fn(d.layout))) } export const dialogueFilename = writable(); +export const dialogueTextFormat = writable(McTextType.PLAIN); diff --git a/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueImportExport.svelte b/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueImportExport.svelte index 3fbb0f9e..91ddf67d 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueImportExport.svelte +++ b/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueImportExport.svelte @@ -217,6 +217,10 @@ display: flex; align-items: center; } + + &:focus-visible + label { + outline: auto; + } } .dialogue-io-log { diff --git a/svelte_sprinkles/src/sprinkles/parlour/editor/DialogueGlobalProperties.svelte b/svelte_sprinkles/src/sprinkles/parlour/editor/DialogueGlobalProperties.svelte index b7cd4231..dab88524 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/editor/DialogueGlobalProperties.svelte +++ b/svelte_sprinkles/src/sprinkles/parlour/editor/DialogueGlobalProperties.svelte @@ -1,6 +1,12 @@ @@ -45,12 +51,16 @@ - + - + + diff --git a/svelte_sprinkles/src/sprinkles/parlour/editor/state/StateActionInput.svelte b/svelte_sprinkles/src/sprinkles/parlour/editor/state/StateActionInput.svelte index 96fdb71f..777ff244 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/editor/state/StateActionInput.svelte +++ b/svelte_sprinkles/src/sprinkles/parlour/editor/state/StateActionInput.svelte @@ -19,7 +19,7 @@ - updateText(e.detail)} /> diff --git a/svelte_sprinkles/src/sprinkles/parlour/landing/NewDialogueForm.svelte b/svelte_sprinkles/src/sprinkles/parlour/landing/NewDialogueForm.svelte index 526ba1fb..e9f6a088 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/landing/NewDialogueForm.svelte +++ b/svelte_sprinkles/src/sprinkles/parlour/landing/NewDialogueForm.svelte @@ -2,7 +2,8 @@ import {EDITOR_TEXT_FORMAT_KEY} from "../localStorageKeys"; import {validateIdentifierField} from "../validation"; import BlabberDialogue from "../BlabberDialogue"; - import {dialogueData, dialogueFilename} from "../dialogueDataStore"; + import {dialogueData, dialogueFilename, dialogueTextFormat} from "../dialogueDataStore"; + import {parseMcTextType} from "../../../lib/McText.js"; let filename: string | undefined; let textFormat: string | null = localStorage.getItem(EDITOR_TEXT_FORMAT_KEY); @@ -42,6 +43,7 @@ } return; } + $dialogueTextFormat = parseMcTextType(textFormat); $dialogueFilename = filename; $dialogueData = new BlabberDialogue({ states: { @@ -82,7 +84,7 @@ id="literal-text" type="radio" name="text-format" - value="literal" + value="plain" bind:group={textFormat} /> @@ -92,7 +94,7 @@ id="translation-keys" type="radio" name="text-format" - value="translate" + value="translation_key" bind:group={textFormat} /> @@ -105,9 +107,14 @@ value="json" bind:group={textFormat} /> - +
From 73bc3565c37e5e65047d116f38ee4e21a3b114f6 Mon Sep 17 00:00:00 2001 From: Pyrofab Date: Sun, 24 Mar 2024 13:50:20 +0100 Subject: [PATCH 08/68] Pass dialogue state data through context --- .../parlour/editor/MainEditor.svelte | 2 +- .../editor/state/DialogueStateChoices.svelte | 32 +++++++++ .../state/DialogueStateProperties.svelte | 8 +-- .../editor/state/DialogueStateView.svelte | 65 +++++++++++-------- .../editor/state/StateActionInput.svelte | 20 +++--- .../editor/state/StateTextInput.svelte | 18 ++--- .../editor/state/type/StateTypeInput.svelte | 25 ++++--- 7 files changed, 105 insertions(+), 65 deletions(-) create mode 100644 svelte_sprinkles/src/sprinkles/parlour/editor/state/DialogueStateChoices.svelte diff --git a/svelte_sprinkles/src/sprinkles/parlour/editor/MainEditor.svelte b/svelte_sprinkles/src/sprinkles/parlour/editor/MainEditor.svelte index db79b774..2bf18f4d 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/editor/MainEditor.svelte +++ b/svelte_sprinkles/src/sprinkles/parlour/editor/MainEditor.svelte @@ -12,7 +12,7 @@
{#if selectedState} - + {/if}
diff --git a/svelte_sprinkles/src/sprinkles/parlour/editor/state/DialogueStateChoices.svelte b/svelte_sprinkles/src/sprinkles/parlour/editor/state/DialogueStateChoices.svelte new file mode 100644 index 00000000..1cd665f9 --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/parlour/editor/state/DialogueStateChoices.svelte @@ -0,0 +1,32 @@ + + +
+

+ Available Choices + + + +

+
+
+ + + + + + + + + + + +
TextNext StateSortRemove
+
+
+
diff --git a/svelte_sprinkles/src/sprinkles/parlour/editor/state/DialogueStateProperties.svelte b/svelte_sprinkles/src/sprinkles/parlour/editor/state/DialogueStateProperties.svelte index 5731f1c0..145a2d39 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/editor/state/DialogueStateProperties.svelte +++ b/svelte_sprinkles/src/sprinkles/parlour/editor/state/DialogueStateProperties.svelte @@ -2,13 +2,11 @@ import StateTypeInput from "./type/StateTypeInput.svelte"; import StateActionInput from "./StateActionInput.svelte"; import StateTextInput from "./StateTextInput.svelte"; - - export let state: string;
- - - + + + \ No newline at end of file + diff --git a/svelte_sprinkles/src/sprinkles/parlour/editor/state/StateActionInput.svelte b/svelte_sprinkles/src/sprinkles/parlour/editor/state/StateActionInput.svelte index 777ff244..46f8c56d 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/editor/state/StateActionInput.svelte +++ b/svelte_sprinkles/src/sprinkles/parlour/editor/state/StateActionInput.svelte @@ -18,24 +18,24 @@ } diff --git a/svelte_sprinkles/src/sprinkles/parlour/editor/state/type/StateTypeInput.svelte b/svelte_sprinkles/src/sprinkles/parlour/editor/state/type/StateTypeInput.svelte index 07c10922..d1489313 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/editor/state/type/StateTypeInput.svelte +++ b/svelte_sprinkles/src/sprinkles/parlour/editor/state/type/StateTypeInput.svelte @@ -1,20 +1,19 @@
From d87640435eeb84ee3f12ab0ea6ed7572d39bd3b2 Mon Sep 17 00:00:00 2001 From: Pyrofab Date: Sun, 24 Mar 2024 17:45:36 +0100 Subject: [PATCH 09/68] Implement dialogue choice editing table --- svelte_sprinkles/src/lib/EditableTable.svelte | 66 +++++++++++++ .../editor/state/DialogueStateChoices.svelte | 93 +++++++++++++++---- .../editor/state/DialogueStateView.svelte | 4 +- .../src/sprinkles/parlour/validation.ts | 2 +- 4 files changed, 144 insertions(+), 21 deletions(-) create mode 100644 svelte_sprinkles/src/lib/EditableTable.svelte diff --git a/svelte_sprinkles/src/lib/EditableTable.svelte b/svelte_sprinkles/src/lib/EditableTable.svelte new file mode 100644 index 00000000..02e789db --- /dev/null +++ b/svelte_sprinkles/src/lib/EditableTable.svelte @@ -0,0 +1,66 @@ + + +
+ + + + + + + + + + + {#each $items as item, index} + + + + + + {/each} + +
TextNext StateSortRemove
+ + + + +
+
diff --git a/svelte_sprinkles/src/sprinkles/parlour/editor/state/DialogueStateChoices.svelte b/svelte_sprinkles/src/sprinkles/parlour/editor/state/DialogueStateChoices.svelte index 1cd665f9..7acd51a9 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/editor/state/DialogueStateChoices.svelte +++ b/svelte_sprinkles/src/sprinkles/parlour/editor/state/DialogueStateChoices.svelte @@ -1,32 +1,87 @@ -
-

+
+

Available Choices - -

-
- - - - - - - - - - - -
TextNext StateSortRemove
-
+ + + updateText(index, e.detail)}/> + + +
diff --git a/svelte_sprinkles/src/sprinkles/parlour/editor/state/DialogueStateView.svelte b/svelte_sprinkles/src/sprinkles/parlour/editor/state/DialogueStateView.svelte index bfe81713..e574d705 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/editor/state/DialogueStateView.svelte +++ b/svelte_sprinkles/src/sprinkles/parlour/editor/state/DialogueStateView.svelte @@ -38,7 +38,9 @@

State Properties: {selectedState}

- + {#if $stateData.type !== 'end_dialogue'} + + {/if}
\ No newline at end of file diff --git a/svelte_sprinkles/src/sprinkles/parlour/graph/DialogueGraphView.svelte b/svelte_sprinkles/src/sprinkles/parlour/graph/DialogueGraphView.svelte index 3d185ded..2ca3175f 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/graph/DialogueGraphView.svelte +++ b/svelte_sprinkles/src/sprinkles/parlour/graph/DialogueGraphView.svelte @@ -1,9 +1,113 @@ - + -
+ +{#await Promise.all([import('vis-data'), import('vis-network')]) } + Loading... +{:then [{DataSet}, {Network}]} +

Import a dialogue or create some states in the table view to get started

+{/await} diff --git a/svelte_sprinkles/src/sprinkles/parlour/graph/color-transform.ts b/svelte_sprinkles/src/sprinkles/parlour/graph/color-transform.ts new file mode 100644 index 00000000..c680f76d --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/parlour/graph/color-transform.ts @@ -0,0 +1,44 @@ +export function hsvToRgb(obj: { h: number, s: number, v: number }): number; +export function hsvToRgb(h: number, s: number, v: number): number; + +export function hsvToRgb(h: number | { h: number, s: number, v: number }, s?: number, v?: number) { + let r: number, g: number, b: number, i: number, f: number, p: number, q: number, t: number; + if (typeof h === 'object') { + s = h.s; v = h.v; h = h.h; + } else { + s = s as number; + v = v as number; + } + i = Math.floor(h * 6); + f = h * 6 - i; + p = v * (1 - s); + q = v * (1 - f * s); + t = v * (1 - (1 - f) * s); + switch (i % 6) { + case 0: + r = v; g = t; b = p; + break; + case 1: + r = q; g = v; b = p; + break; + case 2: + r = p; g = v; b = t; + break; + case 3: + r = p; g = q; b = v; + break; + case 4: + r = t; g = p; b = v; + break; + case 5: + r = v; g = p; b = q; + break; + default: + throw Error('Modulo went wrong'); + } + return Math.round(r * 255) << 16 | Math.round(g * 255) << 8 | Math.round(b * 255); +} + +export function hsvToRgbString(h: number, s: number, v: number) { + return `#${hsvToRgb(h, s, v).toString(16)}`; +} diff --git a/svelte_sprinkles/vite.config.ts b/svelte_sprinkles/vite.config.ts index 4faa31d6..7a103807 100644 --- a/svelte_sprinkles/vite.config.ts +++ b/svelte_sprinkles/vite.config.ts @@ -31,8 +31,8 @@ export default defineConfig(() => ({ output: { entryFileNames: `[name].js`, chunkFileNames: `[name].[hash].js`, - assetFileNames: `[name].[ext]` - } + assetFileNames: `[name].[ext]`, + }, } } }) as UserConfig); From 5c28fd74f4c578bde99adc7698dc869cf53954f9 Mon Sep 17 00:00:00 2001 From: Pyrofab Date: Mon, 25 Mar 2024 15:37:15 +0100 Subject: [PATCH 15/68] Convert dark mode toggle to a Svelte widget, add transition --- public/_includes/header.liquid | 20 +- public/{img => _includes/svg}/darkmode_0.svg | 0 public/{img => _includes/svg}/darkmode_1.svg | 0 public/_layouts/default.liquid | 24 +- public/_sass/parts/breadcrumb.scss | 28 +- public/_sass/parts/buttons.scss | 267 ++++++------ public/_sass/parts/site-header.scss | 396 +++++++++--------- public/css/style.scss | 383 +++++++++++------ public/scripts/darkmode.js | 1 - svelte_sprinkles/src/lib/darkModeStore.ts | 17 +- .../sprinkles/darkmode/DarkModeToggle.svelte | 50 +++ .../src/sprinkles/darkmode/main.ts | 7 + svelte_sprinkles/vite.config.ts | 3 +- 13 files changed, 698 insertions(+), 498 deletions(-) rename public/{img => _includes/svg}/darkmode_0.svg (100%) rename public/{img => _includes/svg}/darkmode_1.svg (100%) create mode 100644 svelte_sprinkles/src/sprinkles/darkmode/DarkModeToggle.svelte create mode 100644 svelte_sprinkles/src/sprinkles/darkmode/main.ts diff --git a/public/_includes/header.liquid b/public/_includes/header.liquid index 2f0644cf..02ffa8f5 100644 --- a/public/_includes/header.liquid +++ b/public/_includes/header.liquid @@ -1,13 +1,13 @@ -{% capture full_title %}{% if page.title %}{{page.title}} - {% endif %}Ladysnake 🐍{% endcapture %} -{% if page.og.img %}{% assign og_img = page.og.img %}{% endif %} -{% if page.og.img_alt %}{% assign og_img_alt = page.og.img_alt %}{% endif %} -{% if page.og.desc %}{% assign meta_desc = page.og.desc %}{% elsif page.slug %}{% endif %} +{%- capture full_title %}{% if page.title %}{{page.title}} - {% endif %}Ladysnake 🐍{% endcapture -%} +{%- if page.og.img %}{% assign og_img = page.og.img %}{% endif -%} +{%- if page.og.img_alt %}{% assign og_img_alt = page.og.img_alt %}{% endif -%} +{%- if page.og.desc %}{% assign meta_desc = page.og.desc %}{% elsif page.slug %}{% endif -%} -{% if layout.header_preprocessor %}{% include {{ layout.header_preprocessor }} %}{% endif %} +{%- if layout.header_preprocessor %}{% include {{ layout.header_preprocessor }} %}{% endif -%} -{% unless og_img %}{% assign og_img = "/img/colored-ladysnake-icon.png" %}{% endunless %} -{% unless og_img_alt %}{% assign og_img_alt = "Ladysnake Logo" %}{% endunless %} -{% unless meta_desc %}{% assign meta_desc = "Home of a small group of developers called Ladysnake" %}{% endunless %} +{%- unless og_img %}{% assign og_img = "/img/colored-ladysnake-icon.png" %}{% endunless -%} +{%- unless og_img_alt %}{% assign og_img_alt = "Ladysnake Logo" %}{% endunless -%} +{%- unless meta_desc %}{% assign meta_desc = "Home of a small group of developers called Ladysnake" %}{% endunless -%} @@ -31,6 +31,10 @@ + + + + diff --git a/public/img/darkmode_0.svg b/public/_includes/svg/darkmode_0.svg similarity index 100% rename from public/img/darkmode_0.svg rename to public/_includes/svg/darkmode_0.svg diff --git a/public/img/darkmode_1.svg b/public/_includes/svg/darkmode_1.svg similarity index 100% rename from public/img/darkmode_1.svg rename to public/_includes/svg/darkmode_1.svg diff --git a/public/_layouts/default.liquid b/public/_layouts/default.liquid index bad7545d..7807134b 100644 --- a/public/_layouts/default.liquid +++ b/public/_layouts/default.liquid @@ -2,16 +2,24 @@ {% include header.liquid %} - - - + +
- +
@@ -35,7 +43,7 @@
diff --git a/public/_includes/svg/darkmode_1.svg b/public/_includes/svg/darkmode-disable.svg similarity index 100% rename from public/_includes/svg/darkmode_1.svg rename to public/_includes/svg/darkmode-disable.svg diff --git a/public/_includes/svg/darkmode_0.svg b/public/_includes/svg/darkmode-enable.svg similarity index 100% rename from public/_includes/svg/darkmode_0.svg rename to public/_includes/svg/darkmode-enable.svg diff --git a/public/_sass/parts/hover-effects.scss b/public/_sass/parts/hover-effects.scss index 147de505..57ba2b4e 100644 --- a/public/_sass/parts/hover-effects.scss +++ b/public/_sass/parts/hover-effects.scss @@ -1,6 +1,14 @@ @import "../mixins"; -.hovered-alt { +.dark-mode-alt { + transition: opacity var(--dark-mode-transition-duration) var(--dark-mode-transition-function); + @include darkMode { + opacity: 100; + } + opacity: 0; +} + +.hovered-alt, .dark-mode-hovered-alt, .light-mode-hovered-alt { transition: opacity 100ms ease-in-out; @supports (-webkit-hyphens:none) { // ?????? Safari weird blur when updating opacity transition: none; @@ -49,6 +57,18 @@ opacity: 100%; } + @include lightMode(&) { + .light-mode-hovered-alt { + opacity: 100; + } + } + + @include darkMode { + .dark-mode-hovered-alt { + opacity: 100; + } + } + svg { fill: var(--accent-text-color); } diff --git a/public/hissiemotes.json b/public/hissiemotes.json index e3a67386..0cbdd598 100644 --- a/public/hissiemotes.json +++ b/public/hissiemotes.json @@ -33,7 +33,7 @@ "illuminations": "https://ladysnake.github.io/img/illuminations.png", "impersonate": "https://ladysnake.github.io/img/impersonate.png", "nomadbooks": "https://ladysnake.github.io/img/nomadbooks.png", - "requiem": "https://ladysnake.github.io/img/requiem_icon_0.png", + "requiem": "https://ladysnake.github.io/img/requiem.png", "beem": "https://ladysnake.github.io/img/beem.png", "hissie": "https://ladysnake.github.io/img/pfp/hissie.png", "comcubehush": "https://ladysnake.github.io/hissie/emotes/comcubehush.png", diff --git a/public/img/requiem_icon_0.png b/public/img/requiem_icon_0.png deleted file mode 100644 index 68d723253684a928db488c950fadb756edc5a59d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6843 zcmdU!XHXOE+x8bIqjj`YsmPhh0RRA%x|*^c z06_T9-$6=vli8{|Ho1|1tkv{10e}E*0O0Kh0O0H<^>!TqfC>WuI71J2G*j`#i?Y~pt}_SX+DFRpg5xTEbg z0AFClP0g)08mh|ow;+vCHvyTunz0uEK;83q-0F8LwYf=>c&lrwkYLFu85x=V3C3@x ze4k2PSyA6_ZX0c7K`%$&YjsPPR{sObHvYPBoJN=Jaf7C0k~GiYb$~#7k{G?lh7Z1n zF^`fkyV za+r(Lc17kvlu`ill#_WAWwf87IViLel@(Eqo? zgjdv!17+1F<&DF=*BH9L^$lb6L1WZk2jWKEzVmFTN|DMCt@(6H4eX26C|L?v1>6vy z9$WkU1s~h`Xv04M3Bb|?fd~9sv_>yrzots8BERTNFEVCfpTUXuswoPnzB!ZrT8(v` z$dE5P1el*YG%3z-xa&13d}F8e94P|PFIEqaTMbV8<(>Ynd z_xj6pwvk_80Z*l}a)9r}4^DsS0c42O|E#nk2z*HO?!CmOxk}Wi{6P0jT)fdGmLY;? zyj+_Wo#9v?vK5y4`ITBxRo-g@OtzOcp$`!X2fo+Jim1y=MaP2FM%IgMxmSiA5fMyu zAG}xwiUVdiNbRKJU5RUzXouWcsWiTou}0R`7NaXc`XkFtP{wwBlnH|nXVelXx(aF~ z(Bw5^eouyIG^k%VSG0+A&WI)t>S6Q_Pa2_rb4l&i=ze*n7%pouPh&!=vbu|I#ga=sG|u^&cqk4NHPC(L@g$8*b8*6qr=H3b zfWQt|m<+8|v6I@r_fQ~KK(rQN&+F{rl4v|Cujs#do(Flje3>2``T&xE-Z4jOeQz7j zVncC?{T$de1{>RW>!l4cX7q`ACAI4`4X`r8V3Avmbt(~Q@}e{vm8k-vO}}qHud!?z zsA0@v?EU=vV;{HkSd1O&z_wtzER55n`RkCb)sje}0NQe!xBmFkx}jTbP*&a9ThgCy zp8;`}vJG_UHgEAFEN2WZZ@zTjqx{JF>GKyp9733x0(wWwcrhb@v%>BfFx;5cl9TeV zhTO&#r!LG&0%eZNsCXeqoLZk7w-WCKrGD~i{0lpd^{QyBM>4&!wB1eiHcr|6qD1SB z*)<~Y`WgJY3^LKLq@Dj}DZt2jhQrU*q&|M>&||LgIe}LHVr<#UDbeNgO*t zX}X@U*tYSNKW6ZeZoeN^@2}#SDhjDrqxhhbT;URA&`3;+9*?NLiA!P^5)G_c!g=>; zxY*#v;$~c-@=6hs+|XD3F3@GKu*X4${h~SJxa=G>Fh z0cReEwuZh4>&I%N`zKf`;v7!^qloq=A)zQ~P1-ymC`pM!6$rs4h?@Pht%vUBLe3&} z>?JhfAjrxYRGXWsT-j6xuZGV6H?C?F1%{d@^&(1kX1u8kcqA?IU*I64 zGn!C4F}t$-9aL7Qeu<=G#VIlv)|iN!DW;OlXwx`6)`ic1pIFoNb-;0#C1rwsvEr^? zEg1Me}NxGVmn6{^so%7@YR6mW*uLv zUI?PzROGM{DVJXVs)XFIMA~s{A9>m@K2)8^<7|k%Pk-?Txe?hgSQB4l5dRcj^ci%X zz%6}Tn-2-a2}6;CkqrZNu_{I7;Ml=Xa~x9X%zEzo+%g(*sIOzsHVOR6#yDNAC0R(4 zq{qWH!Gd8-ty(k(LY^|M6^^yf1aB}SquD;<^G__!+6?Vs8zyj{+8*Z?-m5f%yPG;Z ztP>w+OOxW(qkYd|hHo_BWmSPyPSd$sM>gNVcx!H4GU1sOro%VwP}oD2JAbUDlZEE0 zv)nWhE7r6P9&>@`jHmGFki1Sl7~ON# z2444vlohzSO#DD*q@JCIoZ2fLxg16zri6;9jV45CCg`!5$L9*tLr0ys4|joL?%kaM z&~JfVl9U;3B;iQ9e!Y@ehJcCq5CheYhkN+lBGACcDA4kS52Ew>K-aI@9{T+?J$s7< z?h`TkU^oy7NfA1qZxH}TW?}f7Yr3iCD_}*KPT#j2T~ozc(%r8f?}p^mJG575)MkM(W?B*0Sf(PkjsCpUy;e<7Ua*sLb$VHiEs*Wr-YL2R;uW`+u8u+6Uo_#FP;Q}6oK zz}AO^d}{>&FReApmRvUP4j|8;E37?8m3>gr>nc9%6z2U zNjOb;RmOR1$+|woFxkIotbyj}qPkV_w#oI=qOzak)av7=W*g~8PSazz$@DJDFNL5* z*ZA@VyTQz&Y~)n;0`+|;s$d#k?7a=mNU!cm>QnQY zp_<`J>Y$vagV(K*DW;`&gEqB^kC4?3isaKLKY~8j;h(T`E^x{I5EsH#oT;L{FEpE# z9ot37G!OH&%6qX@!+clC=W+r$(>d~OM@q(XY4$3>S3e7THN8zUvV9il+e>{sZCTu? zmT7l4Sn5irFfS#rvjWMR^;I=853Vq=69<17=oi$0v)nvF=p!fdc&EOOFH*iuP&B>F zX{>DbSnsO`7tdGijKwN<;Qk}ov0g?cM$bnW;q`H+3YaF8;W5SpUSBjOAa1)`9L-do z!qQmh+V^N4|FX>#aZzEQN#7P{sIL78FwB3{}l%T-Jn}A;uGj?>*dE>1SSR zqc{6?DgbUJGwo6HXO}}ZX>(3F9%@0-ZTrF+H5xs~*G|FMpRD_SqmvcrI)5%5o*71u z(UfRSraINKR^F?VqmQ_S1_?J>9OY}yswZ0LQIt%1Yp&DW8kG`!`8bLMlJXBh{aUON zaAhrOm05(q!j;=~RVg%gH}!a-uOZYqk((ZZu0GXuR#i)O@o4YPP?Tx7$mc zvhy7+NYdJR@Ewu$gvbl}gboC_PLZ+f(D;wqBsGNqV?Z-R!6Vi%5_d(@puoc2F5t-d4V^u|;T^)f~?E>HFAYHCaw|t6osG(IP7mNAonNg+Jt$QUm0TJO_`Ix&pWQyN3-B zr$G({*0O@VDWOPP?6muy7%Fmgx_9)Kk)BeQ13%a5+4pG!Rg{k3@8z#K)j@{Z1*HZw z1027%1dTtv&~q?jX(kFDnROM-NG+TJNkZt( z8GfnGgm_nl1%#`!?rk`RCns7xdd#j-DT&zZcqQj?>SQ3|T@i!4+;Fus#T^xa_2en! zY9Y2}l8iV1ieo()HIocKhy;%_rsg!}8<>YB-N_9~sb6O}R+&HL#JnZq7j1&|HFI>z z>%^O_D(g*6ix0c_c#0+qdI;`&C`e`xxx9mUQeU1}2X((^dXm%eeK;h`qE;01;k%%l z-q#F_c=mv^M~oBo)rqEi`5Pvw`mC95ia9$8CEJn(qbND_KwANVSyx6;nPveQAnu3vAm zT*sSeJ_v3TY4kG1Cp3uaHOaB-?qKtDnEA#}+GfQn6K%X^_ia|%g|t@} z2}m*g=-CHVbH4>As>VI@S{}YV*pwB%U&%v-M2oimmw(5DbK7%~7i?8QTi=}e)f?y8 zA6h(f@UuKhTO`)zvSSQ^hsfxed>F2PZO2bVK5=d#5((*@B85dZ?WA?h(-?c84hfk< ztPvVme3UOmOL1Gm-Epo5*t*?xcIl@$YJ?w^x}3$z)sti3F^sUk!k_t8nC`_<4_7}g znnMIbr-^1S!dOBU*xToX$b3xy$eNTC?46^mWF8cU`jo`XvTKuf_hbA~hfnD6``5M3 z-ECL<1GS#MYF~LGL~>}JZ^eHr@#t)kF_}QTYDlmhFW^6rI$w2~-%bi`O8b1&_m9}Z ziv9dCaQ>qdrob_n=m;hm-fgBPK&GLs<(tk}$s>K4u6ttG(o*@61{Ad4eBHP4BcN`D zhB+c`b3EQB_jVczLRK2k!EjY zV&CRS4C}eDyVBkJg-5pPu;<@3`}^x`*GgMmoW3;it0SZ7D@$8RTt}K=1jrz!&F?5c zwwZB~qfno7xx;?6oN-dw{XC_7YLO<>pQ#n<)3Gxm_aA-Nm8s*!gnXJb`&}k>UR(OM zWZ?*>hMo`Ddf^TX{$K>F&kGMCY|r=DW3YXz-d`TQ)2 z;p=pZ%bjRUfp<7hG}h7kx5lc@rcL2x4!59@WkWk(eyTsW>nRJe)312XvUSqfuBwvB zW^pGRs|zf0(Hz|RBkg2ovVymCJx0%Z|H?ecg;X%6&%Wz*JO}S>e}Qc>wL?Q*QxW4I zm7OrYp@C(v#55_ET&JV-@}K0rx7N50x|{mr*LQ)(INhElmTV#L>D$>~&?4J-jy9xs zgl0Tnu(*Z3;Xwi(u`U1|4qY3M5t^OziQM@aW8T!%xlL1;-R@B;V{kn1E_Qbs1KJyT zcYy8A(ea_N+9+YyMuMdhaOEK7QF4~0?6INgd_l2wgxN=4|9mft@bEde#BbYq7KPJ|xsLT)pvFs(3WU*?qpFSW?8sxX!P*g}SNkJ&qslB8M zIue5dONv5wvyqn}6;(}TMqzmWt$0b?j;ll7-fmY4epnaV#$no#2U$$|?7V1E-r5?F zJ~uyHUhQ(NDQ708gLi+;m4vyNR;V+BuQwU(Q-^7znvXtD#;r^p^5V4Q4=aAvmzk%m z1mC4WZj~Na4zNSG?Dp4sE^i(7=;9A&*A9Awu)N)rc6ARtqS}hKW8sL~Xma<2wn~ms z*RwK>%`|T0Z1{tyus@gra%cD7zb`n_!pgk@`=km2^nCI0U+$uVq=R5WiM}@a_KfVn z1+LTNv)Jw3L>0=eKeb|k=@$)ENY^XZQi0`KxhkYcg%TQPk7H1yAVJJuR`i(77Yw?Q z;9mlJVvuszqZfo$@fx(qNBqOf<6V7HtHLc3l%dlGVElD7i171Qx>vYI?pZ`oHtm!0 z6q+M`SzY_5%um+L}MyQ{JaPdYCvWC^ZXqWov8w6F6sRda+M99>An$61kY?ZZzw_q6}wZv=&Q~3ZrC`td5B*nrH_VD? z`VDh#x;A;k#1C7xA#ZJY+<%z{dK)b0wV_8+)Bmr*%t(T4>oEv$3W2W=HH2SNTssh4G*#j`;z!?epxK_|E|5a zanz{m(W(iYYR^XyLFCtK&ma8wmiax+BHc${Eabs|KYo65cpUrU)|K#C&x8aEQOKu= z$x?`2Lo)qeQnkPtfGVBnVewQ#vI8(j+&08KrE=L2(y(NEc zlthamq3md38v(}YKmT{Y-xbJS&>#n`)PZyA*qi8~w~CRsjg_}8$lBBPMgXG1qGAHV z(gGr)`l6yBQ4x@s7@x2(NLcud$!*^M2XJ+>akTUQp8(darkModeSetting === null ? undefined : darkModeSetting === 'true'); subscribe((value) => { - if (value) { + if (value !== undefined) { localStorage.setItem('dark-mode', '' + value); } else { localStorage.removeItem('dark-mode'); } }); + subscribe((value) => { + if (value === undefined) { + document.body.classList.remove("light-mode"); + document.body.classList.remove("dark-mode"); + } else if (value) { + document.body.classList.remove("light-mode"); + document.body.classList.add("dark-mode"); + } else { + document.body.classList.remove("dark-mode"); + document.body.classList.add("light-mode"); + } + }); + document.body.classList.remove("uninitialized-dark-mode"); return { subscribe, set, update } as const; } diff --git a/svelte_sprinkles/src/sprinkles/darkmode/DarkModeToggle.svelte b/svelte_sprinkles/src/sprinkles/darkmode/DarkModeToggle.svelte index 2f0e1d41..406efe17 100644 --- a/svelte_sprinkles/src/sprinkles/darkmode/DarkModeToggle.svelte +++ b/svelte_sprinkles/src/sprinkles/darkmode/DarkModeToggle.svelte @@ -1,8 +1,7 @@ + diff --git a/svelte_sprinkles/src/sprinkles/settings/Settings.svelte b/svelte_sprinkles/src/sprinkles/settings/Settings.svelte new file mode 100644 index 00000000..8583b81c --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/settings/Settings.svelte @@ -0,0 +1,86 @@ + +
+ + + + +
+ + +
+ + diff --git a/svelte_sprinkles/src/sprinkles/settings/main.ts b/svelte_sprinkles/src/sprinkles/settings/main.ts new file mode 100644 index 00000000..7aa0644a --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/settings/main.ts @@ -0,0 +1,7 @@ +import App from './Settings.svelte'; + +const app = new App({ + target: document.getElementById('ladysnake-settings')!, +}); + +export default app; diff --git a/svelte_sprinkles/vite.config.ts b/svelte_sprinkles/vite.config.ts index 45d2b132..b51cfa83 100644 --- a/svelte_sprinkles/vite.config.ts +++ b/svelte_sprinkles/vite.config.ts @@ -28,6 +28,7 @@ export default defineConfig(() => ({ input: { 'blabber-parlour': './src/sprinkles/parlour/main.ts', 'darkmode-toggle': './src/sprinkles/darkmode/main.ts', + 'ladysnake-settings': './src/sprinkles/settings/main.ts', }, output: { entryFileNames: `[name].js`, From 7d4996b0ab8c3821c0928f5bc1f3795daca673ee Mon Sep 17 00:00:00 2001 From: Pyrofab Date: Tue, 26 Mar 2024 20:31:06 +0100 Subject: [PATCH 20/68] Prevent infinite reloading in case of broken build --- public/tools/parlour.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/public/tools/parlour.html b/public/tools/parlour.html index ae02667f..add386c9 100644 --- a/public/tools/parlour.html +++ b/public/tools/parlour.html @@ -33,7 +33,9 @@ From 78a671f5510985cb6b7fa8701cd1199cdb088450 Mon Sep 17 00:00:00 2001 From: Pyrofab Date: Tue, 26 Mar 2024 21:08:56 +0100 Subject: [PATCH 21/68] Improve settings page style slightly --- .../src/sprinkles/settings/Settings.svelte | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/svelte_sprinkles/src/sprinkles/settings/Settings.svelte b/svelte_sprinkles/src/sprinkles/settings/Settings.svelte index 8583b81c..30eefd12 100644 --- a/svelte_sprinkles/src/sprinkles/settings/Settings.svelte +++ b/svelte_sprinkles/src/sprinkles/settings/Settings.svelte @@ -23,15 +23,15 @@
updateNext(index, e.currentTarget.value)}> - {#each $dialogueStateKeys as state} - - {/each} - +
+ c[choiceIdKey]}> + + Text + Next State + + + + focusNewChoice(node, item)} + on:change={(e) => updateText(index, e.detail)} + /> + + +

+ + diff --git a/svelte_sprinkles/src/sprinkles/parlour/editor/state/dialogue-state-choices.css b/svelte_sprinkles/src/sprinkles/parlour/editor/state/dialogue-state-choices.css new file mode 100644 index 00000000..090137ed --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/parlour/editor/state/dialogue-state-choices.css @@ -0,0 +1,95 @@ +@supports(grid-template-columns: subgrid) { + .dialogue-choice-editor { + & table { + display: grid; + grid-template-columns: [start text-start] 1fr [text-end next-start] max-content [next-end sort-start sort-up-start] max-content [sort-up-end] max-content [sort-end remove-start] max-content [remove-end]; + column-gap: 0.5em; + border: 1px solid var(--accent-background-color); + border-radius: 0.5em; + } + + & thead { + display: grid; + grid-template-columns: subgrid; + grid-column: start / end; + } + + & tbody { + display: grid; + grid-template-columns: subgrid; + grid-column: start / end; + } + + & tr { + display: grid; + grid-template-columns: subgrid; + grid-column: start / end; + padding: 0.2em; + } + + & tbody tr:nth-of-type(2n + 1) { + background-color: var(--accent-background-color); + } + + & td, & th { + justify-content: center; + min-width: 5em; + } + + & th { + padding: 0.5em; + } + + & .col-text { + grid-column: text-start / text-end; + } + + & .col-next { + grid-column: next-start / next-end; + } + + & .col-next { + grid-column: next-start / next-end; + } + + & .col-sort { + grid-column: sort-start / sort-end; + display: flex; + gap: 0.2em; + + & button:hover, & button:focus-visible { + background-color: var(--color-info); + color: var(--base-background-color); + } + + & button:disabled { + display: none; + } + } + + & td:hover, & td:focus-within { + text-decoration: underline; + } + + & td button, & td select, & td input { + width: 100%; + height: 100%; + background-color: transparent; + border-radius: 0.5em; + border: 1px solid transparent; + + &:hover { + border-color: var(--base-text-color); + } + } + + & .col-remove { + grid-column: remove-start / remove-end; + + & button:hover, & button:focus-visible { + background-color: var(--color-danger); + color: var(--base-background-color); + } + } + } +} diff --git a/svelte_sprinkles/src/sprinkles/parlour/graph/DialogueGraphView.svelte b/svelte_sprinkles/src/sprinkles/parlour/graph/DialogueGraphView.svelte index 827f3626..cc47b433 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/graph/DialogueGraphView.svelte +++ b/svelte_sprinkles/src/sprinkles/parlour/graph/DialogueGraphView.svelte @@ -107,7 +107,7 @@ Loading...

{:then [{DataSet}, {Network}]} -
+

Import a dialogue or create some states in the table view to get started

diff --git a/svelte_sprinkles/src/sprinkles/parlour/validation.ts b/svelte_sprinkles/src/sprinkles/parlour/validation.ts index ffd7f015..abb452f8 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/validation.ts +++ b/svelte_sprinkles/src/sprinkles/parlour/validation.ts @@ -28,11 +28,16 @@ function validateStructure(dialogue: BlabberDialogue, logWarning: (msg: string) logError(`${state} has no available choices but is not an end state`); } else { unvalidated.add(state); - for (const {next} of choices) { + let missingText = false; + for (const {next, text} of choices) { + if (!text || (typeof text === "string" && !text.length)) missingText = true; if (!next) continue; if (!ancestors[next]) ancestors[next] = new Set(); ancestors[next].add(state); } + if (missingText) { + logError(`${state} has one or more choices with no text`); + } } } From deeb876017ee04665e47b925792e6952dc0d64c7 Mon Sep 17 00:00:00 2001 From: Pyrofab Date: Fri, 29 Mar 2024 23:07:32 +0100 Subject: [PATCH 28/68] Redo darkmode toggle as vanilla JS+CSS --- public/_includes/header.liquid | 1 - public/_layouts/default.liquid | 9 ++++- public/_sass/parts/buttons.scss | 15 ++++++++ public/_sass/parts/hover-effects.scss | 5 ++- public/css/style.scss | 4 ++ .../sprinkles/darkmode/DarkModeToggle.svelte | 38 ------------------- .../src/sprinkles/darkmode/main.ts | 16 ++++---- 7 files changed, 40 insertions(+), 48 deletions(-) delete mode 100644 svelte_sprinkles/src/sprinkles/darkmode/DarkModeToggle.svelte diff --git a/public/_includes/header.liquid b/public/_includes/header.liquid index 02ffa8f5..13ba3cc0 100644 --- a/public/_includes/header.liquid +++ b/public/_includes/header.liquid @@ -33,7 +33,6 @@ - diff --git a/public/_layouts/default.liquid b/public/_layouts/default.liquid index 821e399f..a3d5c32a 100644 --- a/public/_layouts/default.liquid +++ b/public/_layouts/default.liquid @@ -19,7 +19,14 @@ Ladysnake Logo -
+ diff --git a/public/_sass/parts/buttons.scss b/public/_sass/parts/buttons.scss index 421bdd16..6673afb1 100644 --- a/public/_sass/parts/buttons.scss +++ b/public/_sass/parts/buttons.scss @@ -1,5 +1,20 @@ @import "../mixins"; +#darkmode-toggle { + display: inline-grid; + + span { + grid-column: 1; + grid-row: 1; + } + + svg { + height: 25px; + vertical-align: middle; + cursor: pointer; + } +} + .styled-checkbox { opacity: 0; width: 0; diff --git a/public/_sass/parts/hover-effects.scss b/public/_sass/parts/hover-effects.scss index 57ba2b4e..37dfd427 100644 --- a/public/_sass/parts/hover-effects.scss +++ b/public/_sass/parts/hover-effects.scss @@ -1,11 +1,14 @@ @import "../mixins"; .dark-mode-alt { - transition: opacity var(--dark-mode-transition-duration) var(--dark-mode-transition-function); + transition: opacity var(--dark-mode-transition-duration) var(--dark-mode-transition-function), + visibility var(--dark-mode-transition-duration); @include darkMode { + visibility: visible; opacity: 100; } opacity: 0; + visibility: hidden; } .hovered-alt, .dark-mode-hovered-alt, .light-mode-hovered-alt { diff --git a/public/css/style.scss b/public/css/style.scss index e3710360..b51b78d0 100644 --- a/public/css/style.scss +++ b/public/css/style.scss @@ -155,6 +155,10 @@ body { max-width: 100%; } +.hidden { + display: none !important; +} + li a span svg.download-icon { float: right; fill: currentColor; diff --git a/svelte_sprinkles/src/sprinkles/darkmode/DarkModeToggle.svelte b/svelte_sprinkles/src/sprinkles/darkmode/DarkModeToggle.svelte deleted file mode 100644 index 406efe17..00000000 --- a/svelte_sprinkles/src/sprinkles/darkmode/DarkModeToggle.svelte +++ /dev/null @@ -1,38 +0,0 @@ - - - - - diff --git a/svelte_sprinkles/src/sprinkles/darkmode/main.ts b/svelte_sprinkles/src/sprinkles/darkmode/main.ts index 2ff68d5b..d6200534 100644 --- a/svelte_sprinkles/src/sprinkles/darkmode/main.ts +++ b/svelte_sprinkles/src/sprinkles/darkmode/main.ts @@ -1,7 +1,9 @@ -import App from './DarkModeToggle.svelte' - -const app = new App({ - target: document.getElementById('darkmode-toggle')!, -}); - -export default app +const darkmodeToggle = document.getElementById('darkmode-toggle'); +if (darkmodeToggle) { + darkmodeToggle.addEventListener('click', async () => { + // Better avoid loading all of Svelte just for a button, at least wait until someone clicks it + const { darkModeEnabled } = await import('../../lib/darkMode'); + darkModeEnabled.update((v) => !v) + }); + darkmodeToggle.classList.remove('hidden'); +} From f33f22e87f3851148556dab09171f2a342d4d058 Mon Sep 17 00:00:00 2001 From: Pyrofab Date: Fri, 29 Mar 2024 23:09:19 +0100 Subject: [PATCH 29/68] Fix button styling --- public/_sass/parts/buttons.scss | 4 +++- svelte_sprinkles/src/sprinkles/parlour/Footer.svelte | 4 ---- .../parlour/dialogueio/DialogueImportExport.svelte | 6 ------ 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/public/_sass/parts/buttons.scss b/public/_sass/parts/buttons.scss index 6673afb1..3b6d1685 100644 --- a/public/_sass/parts/buttons.scss +++ b/public/_sass/parts/buttons.scss @@ -50,7 +50,9 @@ } .btn { - display: inline-block; + display: inline-flex; + align-items: center; + margin: 0; user-select: none; border-radius: 0; text-transform: uppercase; diff --git a/svelte_sprinkles/src/sprinkles/parlour/Footer.svelte b/svelte_sprinkles/src/sprinkles/parlour/Footer.svelte index 6f736a67..e664acf1 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/Footer.svelte +++ b/svelte_sprinkles/src/sprinkles/parlour/Footer.svelte @@ -21,10 +21,6 @@
\ No newline at end of file + diff --git a/svelte_sprinkles/src/sprinkles/parlour/landing/NewDialogueForm.svelte b/svelte_sprinkles/src/sprinkles/parlour/landing/NewDialogueForm.svelte index c899f7e0..f4d55b89 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/landing/NewDialogueForm.svelte +++ b/svelte_sprinkles/src/sprinkles/parlour/landing/NewDialogueForm.svelte @@ -1,8 +1,7 @@ + + + +
+
+ + validateIdentifier(e.currentTarget)} + /> + +

+ {#if predicateLocationMatch} + This will look for the file data/{predicateLocationMatch[1]}/predicates/{predicateLocationMatch[2]}.json + in your mod or datapack. + {:else} + This will look for a file in the data/<namespace>/predicates/ directory of the corresponding mod or datapack. + {/if} + More information on predicates +

+
+
+ When condition is not met: +
+ + +
+ {#if !hideChoice} +
+ + +
+ {/if} +
+
+ + +
+
+
+ + diff --git a/svelte_sprinkles/src/sprinkles/parlour/editor/state/DialogueStateChoices.svelte b/svelte_sprinkles/src/sprinkles/parlour/editor/state/choice/DialogueStateChoices.svelte similarity index 64% rename from svelte_sprinkles/src/sprinkles/parlour/editor/state/DialogueStateChoices.svelte rename to svelte_sprinkles/src/sprinkles/parlour/editor/state/choice/DialogueStateChoices.svelte index 9505e1dd..851280ac 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/editor/state/DialogueStateChoices.svelte +++ b/svelte_sprinkles/src/sprinkles/parlour/editor/state/choice/DialogueStateChoices.svelte @@ -1,18 +1,19 @@ diff --git a/public/_layouts/wiki.liquid b/public/_layouts/wiki.liquid index d8ea900c..8bfd3bcb 100644 --- a/public/_layouts/wiki.liquid +++ b/public/_layouts/wiki.liquid @@ -32,8 +32,4 @@ header_preprocessor: mod_header_preprocessor.liquid
- + diff --git a/public/_sass/colors.scss b/public/_sass/colors.scss new file mode 100644 index 00000000..0bd41ae4 --- /dev/null +++ b/public/_sass/colors.scss @@ -0,0 +1,180 @@ +/* COLORS */ + +@property --color-blue { + syntax: ""; + inherits: true; + initial-value: #0969da; +} + +@property --color-info { + syntax: ""; + inherits: true; + initial-value: #0969da; +} + +@property --color-purple { + syntax: ""; + inherits: true; + initial-value: #8250df; +} + +@property --color-important { + syntax: ""; + inherits: true; + initial-value: #8250df; +} + +@property --color-orange { + syntax: ""; + inherits: true; + initial-value: #e67e22; +} + +@property --color-warning { + syntax: ""; + inherits: true; + initial-value: #e67e22; +} + +@property --color-red { + syntax: ""; + inherits: true; + initial-value: #e74c3c; +} + +@property --color-danger { + syntax: ""; + inherits: true; + initial-value: #e74c3c; +} + +@property --base-text-color { + syntax: ""; + inherits: true; + initial-value: #2c3e50; +} + +@property --accent-text-color { + syntax: ""; + inherits: true; + initial-value: #2d3436; +} + +@property --base-background-color { + syntax: ""; + inherits: true; + initial-value: #171717; +} + +@property --accent-background-color { + syntax: ""; + inherits: true; + initial-value: #343434; +} + +@property --anchor-color { + syntax: ""; + inherits: true; + initial-value: #8ab4f8; +} + +@property --anchor-hover-color { + syntax: ""; + inherits: true; + initial-value: #e9ebee; +} + +@property --button-background { + syntax: ""; + inherits: true; + initial-value: #dfe6e9; +} + +@property --button-outline { + syntax: ""; + inherits: true; + initial-value: #636e72; +} + +@property --button-hover-outline { + syntax: ""; + inherits: true; + initial-value: #2d3436; +} + +@property --button-selected-outline { + syntax: ""; + inherits: true; + initial-value: #0984e3; +} + +@property --dark-mode-transition-duration { + syntax: "
diff --git a/public/_sass/parts/dialogs.scss b/public/_sass/parts/dialogs.scss index 0ea53a89..1b5369a9 100644 --- a/public/_sass/parts/dialogs.scss +++ b/public/_sass/parts/dialogs.scss @@ -10,3 +10,20 @@ dialog { border-radius: 1em; padding: 1em; } + +.dialog-danger { + border: 0.5em solid var(--color-danger); +} + +.dialog-form { + display: flex; + flex-direction: column; + gap: 1em; +} + +.dialog-exit { + display: flex; + justify-content: end; + gap: 1em; + margin: 0 1em; +} diff --git a/public/_sass/parts/globals.scss b/public/_sass/parts/globals.scss index 87a19bc7..303bf96e 100644 --- a/public/_sass/parts/globals.scss +++ b/public/_sass/parts/globals.scss @@ -2,7 +2,9 @@ // THIS IS GLOBAL html { - scrollbar-gutter: stable both-edges; + // TODO add both-edges once https://bugzilla.mozilla.org/show_bug.cgi?id=1874091 is fixed + // then set the desktop width on .container to calc(97.5% + 20px) + scrollbar-gutter: stable; } body { @@ -44,6 +46,6 @@ body { @include desktop { // Account for scrollbar width (assuming stable both-edges) // Note: a typical scrollbar takes 15px - width: calc(97.5% + 20px); + width: calc(97.5% + 15px); } } diff --git a/public/_sass/parts/toc.scss b/public/_sass/parts/toc.scss index dd71e69c..6386bd55 100644 --- a/public/_sass/parts/toc.scss +++ b/public/_sass/parts/toc.scss @@ -54,10 +54,12 @@ padding-bottom: 0.2em; border-bottom: 1px solid var(--button-background); } +} - ul { - list-style: none; - } +.toc-list, .toc-subgroup { + list-style: none; + padding: 0; + margin: 0; } .toc { @@ -145,12 +147,6 @@ } } - ul { - list-style: none; - padding: 0; - margin: 0; - } - a { padding: 0.4rem 1rem; text-overflow: ellipsis; @@ -158,6 +154,7 @@ display: inline-block; overflow: hidden; vertical-align: middle; + transition-duration: 0s; &:hover, &:focus-visible { background-color: var(--accent-background-color); @@ -184,4 +181,4 @@ main { flex-grow: 1 -} \ No newline at end of file +} diff --git a/svelte_sprinkles/src/lib/ConfirmDialogue.svelte b/svelte_sprinkles/src/lib/ConfirmDialogue.svelte new file mode 100644 index 00000000..bcb05f9b --- /dev/null +++ b/svelte_sprinkles/src/lib/ConfirmDialogue.svelte @@ -0,0 +1,38 @@ + + + sendResult(false)} class:dialog-danger={danger}> +
sendResult(true)}> + {#if arg !== undefined} + + {/if} +
+ + +
+ +
+ + diff --git a/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueImportExport.svelte b/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueImportExport.svelte index 8cfc0339..05a45288 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueImportExport.svelte +++ b/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueImportExport.svelte @@ -19,7 +19,7 @@ {#if !importOnly} - @@ -181,16 +181,6 @@ draggingInDropZone--; } } - - function isEmpty(obj: object) { - for (const prop in obj) { - if (Object.hasOwn(obj, prop)) { - return false; - } - } - - return true; - } diff --git a/svelte_sprinkles/src/sprinkles/parlour/editor/DialogueStateList.svelte b/svelte_sprinkles/src/sprinkles/parlour/editor/DialogueStateList.svelte index 8ca50f6c..71e047dd 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/editor/DialogueStateList.svelte +++ b/svelte_sprinkles/src/sprinkles/parlour/editor/DialogueStateList.svelte @@ -1,31 +1,87 @@

Dialogue States

+ +
\ No newline at end of file + diff --git a/svelte_sprinkles/src/sprinkles/parlour/editor/MainEditor.svelte b/svelte_sprinkles/src/sprinkles/parlour/editor/MainEditor.svelte index bbc2848f..01f021e7 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/editor/MainEditor.svelte +++ b/svelte_sprinkles/src/sprinkles/parlour/editor/MainEditor.svelte @@ -18,6 +18,13 @@ } let selectedState: string | undefined = loadSelectedState() ?? $dialogueStart; + + $: { + if (!(selectedState && selectedState in $dialogueData.states)) { + selectedState = $dialogueStart; + } + } + let mainView = true; let GraphView: Promise; @@ -31,7 +38,7 @@
- {#if selectedState} + {#if selectedState && $dialogueData.states[selectedState]} {/if}
diff --git a/svelte_sprinkles/src/sprinkles/parlour/editor/NewDialogueState.svelte b/svelte_sprinkles/src/sprinkles/parlour/editor/NewDialogueState.svelte index 575fa2a9..7d85d5e2 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/editor/NewDialogueState.svelte +++ b/svelte_sprinkles/src/sprinkles/parlour/editor/NewDialogueState.svelte @@ -47,6 +47,7 @@ diff --git a/svelte_sprinkles/src/sprinkles/parlour/model/BlabberDialogue.ts b/svelte_sprinkles/src/sprinkles/parlour/model/BlabberDialogue.ts index 9805d056..2cc107a8 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/model/BlabberDialogue.ts +++ b/svelte_sprinkles/src/sprinkles/parlour/model/BlabberDialogue.ts @@ -75,10 +75,16 @@ export default class BlabberDialogue { } withAddedState(newState: string) { - return this.withUpdatedState(newState, () => ({ + let updated = this.withUpdatedState(newState, () => ({ text: '', choices: [], })); + if (Object.keys(this.states).length === 0) { + // We just added our only state + return updated.withStartAt(newState); + } else { + return updated; + } } withUpdatedState(key: string, updater: (state: DialogueState) => DialogueState) { @@ -95,6 +101,43 @@ export default class BlabberDialogue { return this.data.states !== null; } + /** + * Finds all states that have choices which reference a given state + */ + findReferences(state: string) { + const references = []; + for (const [key, other] of Object.entries(this.states)) { + if (key !== state) { + for (let i = 0; i < (other?.choices ?? []).length; i++) { + const { next } = (other?.choices ?? [])[i]; + if (next === state) { + references.push({ state: key, choice: i }); + } + } + } + } + return references; + } + + withoutState(stateToDelete: string) { + const newStates: Record = {}; + + for (const [existingKey, { choices, ...existingState }] of Object.entries(this.states)) { + if (existingKey === stateToDelete) continue; + + newStates[existingKey] = { + ...existingState, + choices: choices?.filter((c) => c.next !== stateToDelete) + }; + } + + return new BlabberDialogue({ + ...this.data, + states: newStates, + start_at: stateToDelete === this.startAt ? undefined : this.startAt, + }, this.filename); + } + saveToWindow() { const newState = { ...(window.history.state ?? {}), diff --git a/svelte_sprinkles/src/sprinkles/parlour/parlour.css b/svelte_sprinkles/src/sprinkles/parlour/parlour.css index d5c78d0b..661b66f2 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/parlour.css +++ b/svelte_sprinkles/src/sprinkles/parlour/parlour.css @@ -12,3 +12,8 @@ outline: 1px solid var(--button-outline); } } + +.choice-index { + font-family: monospace; + color: var(--accent-text-color); +} From 55040cc356b1a1a8a220067393c8380c74e019d7 Mon Sep 17 00:00:00 2001 From: Pyrofab Date: Sun, 7 Apr 2024 17:03:27 +0200 Subject: [PATCH 60/68] Refactor dialogue IO into several components and helpers Also make footer icons more consistent (octicon set, 24px) --- public/_includes/svg/octicon-browser-24.svg | 1 + .../_includes/svg/octicon-code-square-24.svg | 1 + public/_includes/svg/octicon-download-24.svg | 1 + public/_includes/svg/octicon-trashcan-24.svg | 1 + public/_includes/svg/octicon-upload-24.svg | 1 + public/_sass/parts/buttons.scss | 4 + svelte_sprinkles/src/lib/fileDrop.ts | 59 ++++ svelte_sprinkles/src/lib/htmlLogger.ts | 38 +++ .../src/sprinkles/parlour/Footer.svelte | 28 +- .../dialogueio/DialogueDropZone.svelte | 64 ++++ .../dialogueio/DialogueFileExport.svelte | 13 + .../dialogueio/DialogueFileInput.svelte | 47 +++ .../dialogueio/DialogueImportExport.svelte | 291 ------------------ .../dialogueio/DialogueResetButton.svelte | 15 + .../parlour/dialogueio/LogDisplay.svelte | 32 ++ .../parlour/dialogueio/dialogueIo.ts | 75 +++++ .../parlour/editor/MainEditor.svelte | 5 - .../sprinkles/parlour/landing/Landing.svelte | 35 ++- .../src/sprinkles/parlour/parlour.css | 11 + 19 files changed, 413 insertions(+), 309 deletions(-) create mode 100644 public/_includes/svg/octicon-browser-24.svg create mode 100644 public/_includes/svg/octicon-code-square-24.svg create mode 100644 public/_includes/svg/octicon-download-24.svg create mode 100644 public/_includes/svg/octicon-trashcan-24.svg create mode 100644 public/_includes/svg/octicon-upload-24.svg create mode 100644 svelte_sprinkles/src/lib/fileDrop.ts create mode 100644 svelte_sprinkles/src/lib/htmlLogger.ts create mode 100644 svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueDropZone.svelte create mode 100644 svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueFileExport.svelte create mode 100644 svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueFileInput.svelte delete mode 100644 svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueImportExport.svelte create mode 100644 svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueResetButton.svelte create mode 100644 svelte_sprinkles/src/sprinkles/parlour/dialogueio/LogDisplay.svelte create mode 100644 svelte_sprinkles/src/sprinkles/parlour/dialogueio/dialogueIo.ts diff --git a/public/_includes/svg/octicon-browser-24.svg b/public/_includes/svg/octicon-browser-24.svg new file mode 100644 index 00000000..8f9c7f4f --- /dev/null +++ b/public/_includes/svg/octicon-browser-24.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/_includes/svg/octicon-code-square-24.svg b/public/_includes/svg/octicon-code-square-24.svg new file mode 100644 index 00000000..08eb31d3 --- /dev/null +++ b/public/_includes/svg/octicon-code-square-24.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/_includes/svg/octicon-download-24.svg b/public/_includes/svg/octicon-download-24.svg new file mode 100644 index 00000000..d4a20a95 --- /dev/null +++ b/public/_includes/svg/octicon-download-24.svg @@ -0,0 +1 @@ + diff --git a/public/_includes/svg/octicon-trashcan-24.svg b/public/_includes/svg/octicon-trashcan-24.svg new file mode 100644 index 00000000..eb4b716a --- /dev/null +++ b/public/_includes/svg/octicon-trashcan-24.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/_includes/svg/octicon-upload-24.svg b/public/_includes/svg/octicon-upload-24.svg new file mode 100644 index 00000000..eae19b34 --- /dev/null +++ b/public/_includes/svg/octicon-upload-24.svg @@ -0,0 +1 @@ + diff --git a/public/_sass/parts/buttons.scss b/public/_sass/parts/buttons.scss index 7df5d2ce..08ae5a15 100644 --- a/public/_sass/parts/buttons.scss +++ b/public/_sass/parts/buttons.scss @@ -106,6 +106,10 @@ } } +.btn-icon { + margin-right: 1rem; +} + a.btn-primary { color: var(--bright-text-color); } diff --git a/svelte_sprinkles/src/lib/fileDrop.ts b/svelte_sprinkles/src/lib/fileDrop.ts new file mode 100644 index 00000000..ae25f264 --- /dev/null +++ b/svelte_sprinkles/src/lib/fileDrop.ts @@ -0,0 +1,59 @@ +import type {Action, ActionReturn} from "svelte/action"; + +export const setupFileDrop: Action void> = (node: HTMLElement, loadFile: (file: File) => void): ActionReturn<(file: File) => void> => { + let draggingInWindow = 0; + let draggingInDropZone = 0; + + function onDrop(e: DragEvent) { + e.preventDefault(); + try { + if (e.dataTransfer?.items && e.dataTransfer.items.length) { + // If dropped items aren't files, reject them + if (e.dataTransfer.items[0].kind === 'file') { + loadFile(e.dataTransfer.items[0].getAsFile()!); + } + } else if (e.dataTransfer?.files.length) { + // Use DataTransfer interface to access the file(s) + loadFile(e.dataTransfer.files[0]); + } + } finally { + node.classList.remove('active', 'hovered'); + draggingInWindow = 0; + draggingInDropZone = 0; + } + } + + function onDragEnter(e: DragEvent) { + if (!(draggingInWindow++)) { + node.classList.add('active'); + } + if ((e.target as HTMLElement).classList.contains('drop-zone') && !(draggingInDropZone++)) { + node.classList.add('hovered'); + } + } + + function onDragLeave(e: DragEvent) { + if (!(--draggingInWindow)) { + node.classList.remove('active'); + } + if ((e.target as HTMLElement).classList.contains('drop-zone') && !(--draggingInDropZone)) { + node.classList.remove('hovered'); + } + } + + function onDragOver(e: DragEvent) { + e.preventDefault(); + } + + node.addEventListener('dragover', onDragOver); + node.addEventListener('drop', onDrop); + document.body.addEventListener('dragenter', onDragEnter); + document.body.addEventListener('dragleave', onDragLeave); + + return { + destroy() { + document.body.removeEventListener('dragenter', onDragEnter); + document.body.removeEventListener('dragleave', onDragLeave); + } + } +} diff --git a/svelte_sprinkles/src/lib/htmlLogger.ts b/svelte_sprinkles/src/lib/htmlLogger.ts new file mode 100644 index 00000000..36fa479a --- /dev/null +++ b/svelte_sprinkles/src/lib/htmlLogger.ts @@ -0,0 +1,38 @@ +import {type Readable, writable} from "svelte/store"; + +export interface Logs { + readonly info: string; + readonly warning: string; + readonly error: string; +} + +export interface HtmlLogger extends Readable { + logInfo: (text: string) => void; + logWarning: (text: string) => void; + logError: (text: string) => void; + clearLogs: () => void; +} + +export function createHtmlLogger(): HtmlLogger { + const empty: Logs = { + info: '', + warning: '', + error: '', + }; + const { subscribe, set, update } = writable(empty); + return { + subscribe, + logInfo(info) { + update((oldLogs) => ({...oldLogs, info})); + }, + logWarning(warning) { + update((oldLogs) => ({...oldLogs, warning})); + }, + logError(error) { + update((oldLogs) => ({...oldLogs, error})); + }, + clearLogs() { + set(empty) + } + } +} diff --git a/svelte_sprinkles/src/sprinkles/parlour/Footer.svelte b/svelte_sprinkles/src/sprinkles/parlour/Footer.svelte index e664acf1..09a8566a 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/Footer.svelte +++ b/svelte_sprinkles/src/sprinkles/parlour/Footer.svelte @@ -1,23 +1,39 @@ \ No newline at end of file diff --git a/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueFileExport.svelte b/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueFileExport.svelte new file mode 100644 index 00000000..5ee77113 --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueFileExport.svelte @@ -0,0 +1,13 @@ + + + diff --git a/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueFileInput.svelte b/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueFileInput.svelte new file mode 100644 index 00000000..ae07b5d7 --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueFileInput.svelte @@ -0,0 +1,47 @@ + + + + + + diff --git a/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueImportExport.svelte b/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueImportExport.svelte deleted file mode 100644 index 05a45288..00000000 --- a/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueImportExport.svelte +++ /dev/null @@ -1,291 +0,0 @@ - -
- {#if !importOnly} - - {/if} - - - - {#if !importOnly} - - {/if} -
0} - class:hovered={draggingInDropZone > 0} - on:dragover|preventDefault - > - - Drop a dialogue file here to import -
-
-

{info}

-

{warning}

-

{error}

- - - - diff --git a/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueResetButton.svelte b/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueResetButton.svelte new file mode 100644 index 00000000..68136e05 --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/parlour/dialogueio/DialogueResetButton.svelte @@ -0,0 +1,15 @@ + + diff --git a/svelte_sprinkles/src/sprinkles/parlour/dialogueio/LogDisplay.svelte b/svelte_sprinkles/src/sprinkles/parlour/dialogueio/LogDisplay.svelte new file mode 100644 index 00000000..3daa957d --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/parlour/dialogueio/LogDisplay.svelte @@ -0,0 +1,32 @@ + + +

{info}

+

{warning}

+

{error}

+ + \ No newline at end of file diff --git a/svelte_sprinkles/src/sprinkles/parlour/dialogueio/dialogueIo.ts b/svelte_sprinkles/src/sprinkles/parlour/dialogueio/dialogueIo.ts new file mode 100644 index 00000000..d08a6ac6 --- /dev/null +++ b/svelte_sprinkles/src/sprinkles/parlour/dialogueio/dialogueIo.ts @@ -0,0 +1,75 @@ +import type {HtmlLogger} from "../../../lib/htmlLogger"; +import {choiceIdKey, genChoiceId} from "../model/DialogueChoice"; +import {dialogueData, dialogueFilename} from "../dialogueDataStore"; +import BlabberDialogue, {StateType} from "../model/BlabberDialogue"; +import {get} from "svelte/store"; +import type {EventDispatcher} from "svelte"; +import {validateDialogue} from "../validation/DialogueValidator"; +import {saveAs} from "file-saver"; + +export function loadDialogueFile(file: File, ioLogger: HtmlLogger, dispatch: EventDispatcher<{ load: BlabberDialogue }>) { + if (!file.type.startsWith('application/json')) { + ioLogger.logError(`${file.name} is not a valid JSON file`); + return; + } + const reader = new FileReader(); + reader.addEventListener('load', () => { + try { + ioLogger.clearLogs(); + if (typeof reader.result !== 'string') { + ioLogger.logError(`Could not parse ${file.name}`); + return; + } + const d = JSON.parse(reader.result, function (key, value) { + if (key === 'choices') { + for (const choice of value) { + choice[choiceIdKey] = genChoiceId(); + } + } + return value; + }); + if (!d.states) { + ioLogger.logError(`${file.name} is missing dialogue state data`); + } else { + // You can go back to the previous dialogue after loading a new one! + if (get(dialogueData).isLoaded()) window.history.pushState(null, ''); + + let filename = file.name.endsWith('.json') ? file.name.substring(0, file.name.length - 5) : file.name; + const importedDialogue = new BlabberDialogue(d, filename); + dialogueData.set(importedDialogue); + dispatch('load', importedDialogue); + ioLogger.logInfo(`Loaded dialogue from ${file.name}`); + } + } catch (err: any) { + console.error(err); + ioLogger.logError(`Failed to read ${file.name}: ${err.message}`); + } + }); + reader.readAsText(file); +} + +export function exportDialogue(dialogue: BlabberDialogue, filename: string | undefined, ioLogger: HtmlLogger) { + ioLogger.clearLogs(); + if (validateDialogue(dialogue, ioLogger.logWarning, ioLogger.logError)) { + saveAs(new Blob( + [JSON.stringify( + dialogue.data, + function (key, value) { + if (key === 'action' && typeof value === 'object' && value.type === '') { + return undefined; + } else if (key === 'condition' && typeof value === 'object' && !value.predicate) { + return undefined; + } else if (key === choiceIdKey) { + return undefined; + } else if (key === 'choices' && this.type === StateType.END_DIALOGUE) { + return undefined; + } else { + return value; + } + }, + 2, + )], + { type: 'application/json' }), + filename + '.json'); + } +} diff --git a/svelte_sprinkles/src/sprinkles/parlour/editor/MainEditor.svelte b/svelte_sprinkles/src/sprinkles/parlour/editor/MainEditor.svelte index 01f021e7..8a0ebe13 100644 --- a/svelte_sprinkles/src/sprinkles/parlour/editor/MainEditor.svelte +++ b/svelte_sprinkles/src/sprinkles/parlour/editor/MainEditor.svelte @@ -53,9 +53,4 @@