diff --git a/.github/codecov.yml b/.github/codecov.yml index 6baab5b2..2660d914 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -5,11 +5,15 @@ coverage: # basic target: 0% threshold: 10% - # advanced settings - branches: + # advanced settings + branches: - master - dev - feature/projects if_ci_failed: error #success, failure, error, ignore - informational: false - only_pulls: false \ No newline at end of file + informational: true + only_pulls: false + patch: + default: + informational: true +comment: false diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3917362a..fee645eb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,8 +3,10 @@ name: Build/release on: push: branches: - - dev - master + pull_request: + branches: + - dev jobs: Build: diff --git a/.gitignore b/.gitignore index 2bfa9e76..ec5245f9 100644 --- a/.gitignore +++ b/.gitignore @@ -129,4 +129,3 @@ tsconfig.electron.prod.json tsconfig.svelte.prod.json __pycache__ - diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..3d51b577 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "blix-plugins/ripple"] + path = blix-plugins/ripple + url = https://github.com/BlixEditor/ripple +[submodule "blix-plugins/blink"] + path = blix-plugins/blink + url = https://github.com/BlixEditor/blink diff --git a/__mocks__/hello-plugin/README.md b/__mocks__/hello-plugin/README.md deleted file mode 100644 index 850c215d..00000000 --- a/__mocks__/hello-plugin/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Hello Plugin - -> This is an example plugin for Blix. \ No newline at end of file diff --git a/__mocks__/hello-plugin/package.json b/__mocks__/hello-plugin/package.json deleted file mode 100644 index 84b2bc65..00000000 --- a/__mocks__/hello-plugin/package.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "name": "hello-plugin", - "displayName": "Hello Plugin", - "description": "A plugin that says hello", - "version": "0.0.1", - - "author": "Rec1dite", - "repository": "", - - "contributes": { - "commands": [ - { - "command": "hello-plugin.hello", - "title": "Hello" - } - ], - "nodes": [ - { - "id": "hello", - "name": "Hello", - "interface" : { - "inputs": { - "numA": "int" - }, - "outputs": { - "numOut": "int" - } - } - } - ] - }, - - "main": "src/main.js", - "renderer": "src/renderer.js", - - "devDependencies": { - "@types/node": "^12.0.0", - "typescript": "^3.4.5" - }, - - "comments": [ "This property will be completely ignored" ] -} \ No newline at end of file diff --git a/__mocks__/hello-plugin/src/main.js b/__mocks__/hello-plugin/src/main.js deleted file mode 100644 index 19b805e9..00000000 --- a/__mocks__/hello-plugin/src/main.js +++ /dev/null @@ -1,75 +0,0 @@ -// Here we define node UIs and callbacks -const nodes = { - "hello": (context) => { - // Use context.nodeBuilder to construct the node UI - - // console.log("Bogus nodes"); - } -} - - - -// Here we define commands (that are made available in the command palette) and their callbacks -const commands = { - "addBrightnessNode": (context) => { - // TODO: Work this out - // E.g. Could get context.command.inputs for instance for additional values - - context.setDescription("import a picture"); - - context.setIcon("testing/image.jpg"); - - context.addCommand(() => { - console.log("Add Brightness Node"); - }) - - context.setDisplayName("Add Brightness Node"); - - return context.create(); - }, - "import": (context) => { - // TODO: Work this out - // E.g. Could get context.command.inputs for instance for additional values - - context.setDescription("import a picture"); - - context.setIcon("testing/image.jpg"); - - context.setDisplayName("Import Project"); - - context.addCommand(() => { - console.log("Import project"); - }) - - return context.create(); - }, - "export": (context) => { - // TODO: Work this out - // E.g. Could get context.command.inputs for instance for additional values - - context.setDescription("import a picture"); - - context.setIcon("testing/image.jpg"); - - context.setDisplayName("Export project"); - - context.addCommand(() => { - console.log("Export picture"); - }) - - return context.create(); - } -} - -// Here we define custom tiles for the UI -const tiles = { - "helloTile": (context) => { - // Use context.tileBuilder to construct the tile UI - } -} - -module.exports = { - nodes, - commands, - tiles -}; \ No newline at end of file diff --git a/__mocks__/svelvet.js b/__mocks__/svelvet.js deleted file mode 100644 index 6a49dc9e..00000000 --- a/__mocks__/svelvet.js +++ /dev/null @@ -1,26 +0,0 @@ -const Slider = jest.fn(); -const generateInput = jest.fn((initialData) => { - const subscribers = new Set(); - let value = null; - - return { - value: initialData.value, - subscribe: (callback) => { - subscribers.add(callback); - return () => subscribers.delete(callback); - }, - set: (newValue) => { - value = newValue; - subscribers.forEach((callback) => callback(value)); - }, - }; -}); -const generateOutput = jest.fn(); -const Anchor = jest.fn(); - -module.exports = { - Slider, - generateInput, - generateOutput, - Anchor, -}; diff --git a/blix-plugins/blink b/blix-plugins/blink new file mode 160000 index 00000000..3b1b3d8d --- /dev/null +++ b/blix-plugins/blink @@ -0,0 +1 @@ +Subproject commit 3b1b3d8dc7d8c9b5254c7a39478ea4282005279f diff --git a/blix-plugins/blink/.gitignore b/blix-plugins/blink/.gitignore deleted file mode 100644 index b512c09d..00000000 --- a/blix-plugins/blink/.gitignore +++ /dev/null @@ -1 +0,0 @@ -node_modules \ No newline at end of file diff --git a/blix-plugins/blink/README.md b/blix-plugins/blink/README.md deleted file mode 100644 index 373c8815..00000000 --- a/blix-plugins/blink/README.md +++ /dev/null @@ -1,34 +0,0 @@ -# Blink - -> Blink is a non-destructive image editing plugin for Blix. - -### Features -- Layering -- Blending -- Filters -- Shapes -- Painting -- Resizing -- Text Overlays - - -### How to Use - -To use the Math Plugin within the Blix photo editor, follow these steps: - - -### Contributions - -If you are interested in contributing to Blink's development or creating your own plugins for Blix, please refer to our developer documentation. - - -### Feedback and Support - -We highly value your feedback and are dedicated to continuously improving Blix and its plugins. If you encounter any issues, have suggestions for improvement, or need assistance, please don't hesitate to reach out to our support team. We are here to help you make the most out of your photo editing experience with Blix. - - -### License - -The Math Plugin is released under the [GNU GENERAL PUBLIC LICENSE] license. Please review the license file for more information regarding the terms of use and redistribution. - -Enjoy using the Math Plugin in Blix, and have fun exploring the possibilities of mathematical transformations in your photo editing projects! \ No newline at end of file diff --git a/blix-plugins/blink/global.d.ts b/blix-plugins/blink/global.d.ts deleted file mode 100644 index 308db084..00000000 --- a/blix-plugins/blink/global.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -/// - -declare global { - interface Window { - api: any; - } -} - -export {}; diff --git a/blix-plugins/blink/package-lock.json b/blix-plugins/blink/package-lock.json deleted file mode 100644 index db860b08..00000000 --- a/blix-plugins/blink/package-lock.json +++ /dev/null @@ -1,2902 +0,0 @@ -{ - "name": "blink", - "version": "0.0.1", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "blink", - "version": "0.0.1", - "devDependencies": { - "@rollup/plugin-commonjs": "^24.0.0", - "@rollup/plugin-node-resolve": "^15.1.0", - "@rollup/plugin-terser": "^0.4.0", - "@rollup/plugin-typescript": "^11.1.3", - "@tsconfig/svelte": "^5.0.0", - "@types/node": "^12.0.0", - "concurrently": "^8.2.1", - "pixi-filters": "^5.2.1", - "pixi-viewport": "^5.0.2", - "pixi.js": "^7.2.4", - "rollup": "^3.15.0", - "rollup-plugin-css-only": "^4.3.0", - "rollup-plugin-livereload": "^2.0.5", - "rollup-plugin-node-polyfills": "^0.2.1", - "rollup-plugin-svelte": "^7.1.2", - "svelte": "^3.55.0", - "svelte-check": "^3.5.0", - "svelte-preprocess": "^5.0.4", - "tsc-watch": "^6.0.4", - "tslib": "^2.6.1", - "typescript": "^4.9.0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz", - "integrity": "sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==", - "dev": true, - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", - "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "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.19", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", - "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", - "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/@pixi/accessibility": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/accessibility/-/accessibility-7.2.4.tgz", - "integrity": "sha512-EVjuqUqv9FeYFXCv0S0qj1hgCtbAMNBPCbOGEtiMogpM++/IySxBZvcOYg3rRgo9inwt2s4Bi7kUiqMPD8hItw==", - "dev": true, - "peerDependencies": { - "@pixi/core": "7.2.4", - "@pixi/display": "7.2.4", - "@pixi/events": "7.2.4" - } - }, - "node_modules/@pixi/app": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/app/-/app-7.2.4.tgz", - "integrity": "sha512-eJ2jpu5P28ip07nLItw6sETXn45P4KR/leMJ6zPHRlhT1m8t5zTsWr3jK4Uj8LF2E+6KlPNzLQh5Alf/unn/aQ==", - "dev": true, - "peerDependencies": { - "@pixi/core": "7.2.4", - "@pixi/display": "7.2.4" - } - }, - "node_modules/@pixi/assets": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/assets/-/assets-7.2.4.tgz", - "integrity": "sha512-7199re3wvMAlVqXLaCyAr8IkJSXqkeVAxcYyB2rBu4Id5m2hhlGX1dQsdMBiCXLwu6/LLVqDvJggSNVQBzL6ZQ==", - "dev": true, - "dependencies": { - "@types/css-font-loading-module": "^0.0.7" - }, - "peerDependencies": { - "@pixi/core": "7.2.4", - "@pixi/utils": "7.2.4" - } - }, - "node_modules/@pixi/color": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/color/-/color-7.2.4.tgz", - "integrity": "sha512-B/+9JRcXe2uE8wQfsueFRPZVayF2VEMRB7XGeRAsWCryOX19nmWhv0Nt3nOU2rvzI0niz9XgugJXsB6vVmDFSg==", - "dev": true, - "dependencies": { - "colord": "^2.9.3" - } - }, - "node_modules/@pixi/compressed-textures": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/compressed-textures/-/compressed-textures-7.2.4.tgz", - "integrity": "sha512-atnWyw/ot/Wg69qhgskKiuTYCZx15IxV35sa0KyXMthyjyvDLCIvOn0nczM6wCBy9H96SjJbfgynVWhVrip6qw==", - "dev": true, - "peerDependencies": { - "@pixi/assets": "7.2.4", - "@pixi/core": "7.2.4" - } - }, - "node_modules/@pixi/constants": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/constants/-/constants-7.2.4.tgz", - "integrity": "sha512-hKuHBWR6N4Q0Sf5MGF3/9l+POg/G5rqhueHfzofiuelnKg7aBs3BVjjZ+6hZbd6M++vOUmxYelEX/NEFBxrheA==", - "dev": true - }, - "node_modules/@pixi/core": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/core/-/core-7.2.4.tgz", - "integrity": "sha512-0XtvrfxHlS2T+beBBSpo7GI8+QLyyTqMVQpNmPqB4woYxzrOEJ9JaUFBaBfCvycLeUkfVih1u6HAbtF+2d1EjQ==", - "dev": true, - "dependencies": { - "@pixi/color": "7.2.4", - "@pixi/constants": "7.2.4", - "@pixi/extensions": "7.2.4", - "@pixi/math": "7.2.4", - "@pixi/runner": "7.2.4", - "@pixi/settings": "7.2.4", - "@pixi/ticker": "7.2.4", - "@pixi/utils": "7.2.4", - "@types/offscreencanvas": "^2019.6.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/pixijs" - } - }, - "node_modules/@pixi/display": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/display/-/display-7.2.4.tgz", - "integrity": "sha512-w5tqb8cWEO5qIDaO9GEqRvxYhL0iMk0Wsngw23bbLm1gLEQmrFkB2tpJlRAqd7H82C3DrDDeWvkrrxW6+m4apg==", - "dev": true, - "peerDependencies": { - "@pixi/core": "7.2.4" - } - }, - "node_modules/@pixi/events": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/events/-/events-7.2.4.tgz", - "integrity": "sha512-/JtmoB98fzIU8giN9xvlRvmvOi6u4MaD2DnKNOMHkQ1MBraj3pmrXM9fZ0JbNzi+324GraAAY76QidgHjIYoYQ==", - "dev": true, - "peerDependencies": { - "@pixi/core": "7.2.4", - "@pixi/display": "7.2.4" - } - }, - "node_modules/@pixi/extensions": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/extensions/-/extensions-7.2.4.tgz", - "integrity": "sha512-Mnqv9scbL1ARD3QFKfOWs2aSVJJfP1dL8g5UiqGImYO3rZbz/9QCzXOeMVIZ5n3iaRyKMNhFFr84/zUja2H7Dw==", - "dev": true - }, - "node_modules/@pixi/extract": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/extract/-/extract-7.2.4.tgz", - "integrity": "sha512-wlXZg+J2L/1jQhRi5nZQP/cXshovhjksjss91eAKMvY5aGxNAQovCP4xotJ/XJjfTvPMpeRzHPFYzm3PrOPQ7g==", - "dev": true, - "peerDependencies": { - "@pixi/core": "7.2.4" - } - }, - "node_modules/@pixi/filter-adjustment": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@pixi/filter-adjustment/-/filter-adjustment-5.1.1.tgz", - "integrity": "sha512-AUHe03rmqXwV1ylAHq62t19AolPWOOYomCcL+Qycb1tf+LbM8FWpGXC6wmU1PkUrhgNc958uM9TrA9nRpplViA==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-advanced-bloom": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@pixi/filter-advanced-bloom/-/filter-advanced-bloom-5.1.1.tgz", - "integrity": "sha512-C5AWmkWKvoYvJ+600qS7rC81E1X1clvrQLw4QE4IiFec5j1b07KhKE78w/BSRYMrBVa0cQ/ju0J1f7XoQYJfdQ==", - "dev": true, - "dependencies": { - "@pixi/filter-kawase-blur": "5.1.1" - }, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-alpha": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/filter-alpha/-/filter-alpha-7.2.4.tgz", - "integrity": "sha512-UTUMSGyktUr+I9vmigqJo9iUhb0nwGyqTTME2xBWZvVGCnl5z+/wHxvIBBCe5pNZ66IM15pGXQ4cDcfqCuP2kA==", - "dev": true, - "peerDependencies": { - "@pixi/core": "7.2.4" - } - }, - "node_modules/@pixi/filter-ascii": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@pixi/filter-ascii/-/filter-ascii-5.1.1.tgz", - "integrity": "sha512-uGfpd7aYZuiEzkBH8asL/2j7L/7k/jCZRURjAU9c0unWlkagwIjvUwoPMsdzPNMh2DNQzCG1FPWseSbRFjUNow==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-bevel": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@pixi/filter-bevel/-/filter-bevel-5.1.1.tgz", - "integrity": "sha512-UGik6YEW+fnzVu1DV8ctbxS7eClJQzqaM2sPYI0MopaEE2mW35yjAcg9py9Kwx27BX8FniVRqtJOyKEw1A3mBA==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-bloom": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@pixi/filter-bloom/-/filter-bloom-5.1.1.tgz", - "integrity": "sha512-4/i+tMxAQdgezahxsVCqzkAyBAH4TxtuY/zo1wuCJybEqkKFIzOJ76Y4R/lJevEHS9CGpCTrvjRpup0Hze8k0Q==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X", - "@pixi/filter-alpha": "^7.0.0-X", - "@pixi/filter-blur": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-blur": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/filter-blur/-/filter-blur-7.2.4.tgz", - "integrity": "sha512-aLyXIoxy14bTansCPtbY8x7Sdn2OrrqkF/pcKiRXHJGGhi7wPacvB/NcmYJdnI/n2ExQ6V5Njuj/nfrsejVwcA==", - "dev": true, - "peerDependencies": { - "@pixi/core": "7.2.4" - } - }, - "node_modules/@pixi/filter-bulge-pinch": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@pixi/filter-bulge-pinch/-/filter-bulge-pinch-5.1.1.tgz", - "integrity": "sha512-80I3g813td7Fnzi7IJSiR3z8gZlKblk6WN+5z6WnscQROcNEpck6lgWS/Lf/IdeHB/FtUKJCbx7RzxkUhiRTvA==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-color-gradient": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@pixi/filter-color-gradient/-/filter-color-gradient-5.2.0.tgz", - "integrity": "sha512-po3JBEKgfowqhAh2D75Ii1bhNl1gA8Agt+ESIMnSbrTVIkemno8zOVlVmP7xaf8+PKYnX7JWH5buTnnDfA7Hnw==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-color-map": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@pixi/filter-color-map/-/filter-color-map-5.1.1.tgz", - "integrity": "sha512-WvDKvweXkg/t9t40thFlN1d/kUrWXGsxpRpFPNmkrZF6hNxdRjqgfg4wxUOev7uZwHIjcZtTfoLRKhJjF+1uqw==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-color-matrix": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/filter-color-matrix/-/filter-color-matrix-7.2.4.tgz", - "integrity": "sha512-DFtayybYXoUh73eHUFRK5REbi1t3FZuVUnaQTj+euHKF9L7EaYc3Q9wctpx1WPRcwkqEX50M4SNFhxpA7Pxtaw==", - "dev": true, - "peerDependencies": { - "@pixi/core": "7.2.4" - } - }, - "node_modules/@pixi/filter-color-overlay": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@pixi/filter-color-overlay/-/filter-color-overlay-5.1.1.tgz", - "integrity": "sha512-u8xuWsUePQ1NFBqpxDAFEujW4kImFIIvlp4D2xbRZqJ0RRbeeKEW31Sk4cxl1yFJKWIq0XLyT/TAepT9iIlEXg==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-color-replace": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@pixi/filter-color-replace/-/filter-color-replace-5.1.1.tgz", - "integrity": "sha512-t+FEEnuqvlU1cKMSe8939tIGCNJsqpyc7o5BzIunMxsZsHjMQWzZtWQKls+FSdSlFyk2TWYSXWAxtj2VBzBZBg==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-convolution": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@pixi/filter-convolution/-/filter-convolution-5.1.1.tgz", - "integrity": "sha512-68NNa7lXBFlRgP/ac/L/0bKk/9QvU8urh7CEeOnR9WJxjymglbAa0nM69TBlhg++Fus3t7Mz/jc/GIfPJ/VL6Q==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-cross-hatch": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@pixi/filter-cross-hatch/-/filter-cross-hatch-5.1.1.tgz", - "integrity": "sha512-g1hPHZYmGBpZtGojOtUOBWH6tqhtQGDo5xAp3o3gwmn2QnY087ZiYWFHF5ml+nTL62fEJ78uIpODscz4Y04e8w==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-crt": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@pixi/filter-crt/-/filter-crt-5.1.1.tgz", - "integrity": "sha512-w+rRbR7eTsPf18QPB68Wiyx8laC+v7fYb3hRVhnq/j6yRUJKQgg4HK5KLP9jfUJ9FJvxy4bzLSDQulvxbOMJZg==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-displacement": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/filter-displacement/-/filter-displacement-7.2.4.tgz", - "integrity": "sha512-Simq3IBJKt7+Gvk4kK7OFkfoeYUMhNhIyATCdeT+Jkdkq5WV7pYnH5hqO0YW7eAHrgjV13yn6t4H/GC4+6LhEA==", - "dev": true, - "peerDependencies": { - "@pixi/core": "7.2.4" - } - }, - "node_modules/@pixi/filter-dot": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@pixi/filter-dot/-/filter-dot-5.1.1.tgz", - "integrity": "sha512-w3g6bumHzZgv9ktzegEWQS7OWuHH0QG76sbg/hZBy5K01dyuGAe1uUUnzVN5hZuFTD6q77T2UPlifhNI5j4ixg==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-drop-shadow": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@pixi/filter-drop-shadow/-/filter-drop-shadow-5.2.0.tgz", - "integrity": "sha512-cYS2KDER7cwCu0V4VNSxTHGvzmNcEXdC9j3031YBOkUAE3+p17LMS/TAt6XeMfJV7KaPuusvXy2NFgGkv3RDbw==", - "dev": true, - "dependencies": { - "@pixi/filter-kawase-blur": "5.1.1" - }, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-emboss": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@pixi/filter-emboss/-/filter-emboss-5.1.1.tgz", - "integrity": "sha512-AoAFVzrMcCXldU+27hvJ95tcKNOVLnanlq1z838l2SzYGgso+ICbLauUz+o2PL/znudUJE6oky+I6WJzeavDsQ==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-fxaa": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/filter-fxaa/-/filter-fxaa-7.2.4.tgz", - "integrity": "sha512-qzKjdL+Ih18uGTJLg8tT/H+YCsTeGkw2uF7lyKnw/lxGLJQhLWIhM95M9qSNgxbXyW1vp7SbG81a9aAEz2HAhA==", - "dev": true, - "peerDependencies": { - "@pixi/core": "7.2.4" - } - }, - "node_modules/@pixi/filter-glitch": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@pixi/filter-glitch/-/filter-glitch-5.1.1.tgz", - "integrity": "sha512-pl6jOQlzQGg6NwqCwlgioYhlwue2OSRBGByDzh6Y6Y/qxMBuzQi7W56GunhQW79Kpvj9ynDLAGxomvZsrX88qg==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-glow": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/@pixi/filter-glow/-/filter-glow-5.2.1.tgz", - "integrity": "sha512-94I4XePDF9yqqA6KQuhPSphEHPJ2lXfqJLn0Bes8VVdwft0Ianj1wALqjoSUeBWqiJbhjBEXGDNkRZhPHvY3Xg==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-godray": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@pixi/filter-godray/-/filter-godray-5.1.1.tgz", - "integrity": "sha512-JCvNiKBF/01VyaBYzeusULg+h6kmBaYg0NruHwe/FaJMWCRIPOUBHMQIUavJR0JGE5s6bEIR8kRtdpf3RHiwqw==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-grayscale": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@pixi/filter-grayscale/-/filter-grayscale-5.1.1.tgz", - "integrity": "sha512-tRyggOhTdAQlQpgH/IzjCbORICua/Gm0JkKGOcdDQOHqt4bTVvAehQ59e2+A6A1yA8pevu2L/C25qQhsPgNW9w==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-hsl-adjustment": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@pixi/filter-hsl-adjustment/-/filter-hsl-adjustment-5.2.0.tgz", - "integrity": "sha512-BjmiKIJQuWNqMUjVUpqkM+HaInQzl7dCvYWj8wx9lSAwjzdOCRVVLbRLdO2TwGdwGIHjR3AylMxY1HZK3P4cLA==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-kawase-blur": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@pixi/filter-kawase-blur/-/filter-kawase-blur-5.1.1.tgz", - "integrity": "sha512-nPnJ1ChBFP+4pgFCwC0RJgHAJCetiHcQU3INH7zCdq88cFABmVmhN+wCKRNg4H7lF1EJjaXgFDkTrTreOD/bnw==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-motion-blur": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@pixi/filter-motion-blur/-/filter-motion-blur-5.1.1.tgz", - "integrity": "sha512-I94s3pW2GutjCyXiKQ/dI4Vl9JKne+Q8QgGRn1mrk0Uwg6DDO/OQI3jqv01S+SCTU3LZqhR/p8AQyxeDmOhr2w==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-multi-color-replace": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@pixi/filter-multi-color-replace/-/filter-multi-color-replace-5.1.1.tgz", - "integrity": "sha512-P1shsJXEOpJGe9FdCUgCMi/nius86lBfb6cDIFM4oXdZfzuBUfWjZfUm7uofOvK7IWSrlXYrYoqp75H0XrLZ8A==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-noise": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/filter-noise/-/filter-noise-7.2.4.tgz", - "integrity": "sha512-QAU9Ybj2ZQrWM9ZEjTTC0iLnQcuyNoZNRinxSbg1G0yacpmsSb9wvV5ltIZ66+hfY+90+u2Nudt/v9g6pvOdGg==", - "dev": true, - "peerDependencies": { - "@pixi/core": "7.2.4" - } - }, - "node_modules/@pixi/filter-old-film": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@pixi/filter-old-film/-/filter-old-film-5.1.1.tgz", - "integrity": "sha512-Jgq3eLbcQW48o+YxLe8+T4vsQrvBnKrZAHS3cu3yc2aBLaiVIj8EfYP3vpOPjkQlZ7JVRZNdELpYA6KCR+abXw==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-outline": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@pixi/filter-outline/-/filter-outline-5.2.0.tgz", - "integrity": "sha512-xKfAouhZNKl6A0RvxT5i+2/ean7r16dE/QswwIkbWvr2hhHlp4p9U6XsqdgUERCDxK+IZibMAumbWs4DGxOUeQ==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-pixelate": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@pixi/filter-pixelate/-/filter-pixelate-5.1.1.tgz", - "integrity": "sha512-qTs0Sv10aIbMFW//BPlhcFh1ByyKiVmvXfytYTTXNLrlK5DU3H3x8Pgy5Vy4lacS9VtOO69/CQ1QObBFCHnEBQ==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-radial-blur": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@pixi/filter-radial-blur/-/filter-radial-blur-5.1.1.tgz", - "integrity": "sha512-q6RreUM+RO25HZaxc6ceEOSi6chadv8vrCOvupNLSY+1lvXue0KyFK6vxMcMInNdqRGYWSyJ+ql3RyHMTr93aw==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-reflection": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@pixi/filter-reflection/-/filter-reflection-5.1.1.tgz", - "integrity": "sha512-ksmfrRfBqXZ+rEFuA0l2tf4k+yzTU8VcNMuhW7U+ggkWOP2OEHga+oOlJg6TnHjOEbxudCpag5Us6e9aCeKpEw==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-rgb-split": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@pixi/filter-rgb-split/-/filter-rgb-split-5.1.1.tgz", - "integrity": "sha512-DEeAYoPU2lbUTeNYK8e6q89jqtLeUYSkEdFK/a9IyxYkvJP2CPk+nVXIe48v3wORUf5DdP20k6yQzqoPZyP3ww==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-shockwave": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@pixi/filter-shockwave/-/filter-shockwave-5.1.1.tgz", - "integrity": "sha512-ovzOdAC2LCyWdxJC5PW97wSzHTNfjmKq4c/61cIO4sZp+9DB6n3b/6Rrad2jU346UATtM6K2XkmPY5p7SrRRXA==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-simple-lightmap": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@pixi/filter-simple-lightmap/-/filter-simple-lightmap-5.1.1.tgz", - "integrity": "sha512-S3cHUgbVvUgeef93f3trdL50+162Nyqa7DBYufkGw0dPjPecXyjTH47GJzxDqQPooRwHWWUG9W5EYC+XEwlV9w==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-tilt-shift": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@pixi/filter-tilt-shift/-/filter-tilt-shift-5.2.0.tgz", - "integrity": "sha512-bCQE/BTGsqu8EhRMyiGg+9/FXsPBYxjfODbGTWWQNsXtbFVqZXvg1vEjUZQXvuso1v/Fh/BtZ3u+t2kFfWpBXA==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-twist": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@pixi/filter-twist/-/filter-twist-5.1.1.tgz", - "integrity": "sha512-ZUxLmSHu7ZcP1OYmO9EsKgWDV/Ophf622N7YVei4opBrj/gBMuQZNvFIfnsm4l8yhqAwwzndSTVLNehq1A2ONw==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/filter-zoom-blur": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@pixi/filter-zoom-blur/-/filter-zoom-blur-5.1.1.tgz", - "integrity": "sha512-0n10xOqACC2vm9Lpsq37Y/edDvp/B7xsBdkuWxeCI7Ta7J22fsJ8IHG1iUyxgdZGa+SCPcKiFoTrYEUu5PLCpA==", - "dev": true, - "peerDependencies": { - "@pixi/core": "^7.0.0-X" - } - }, - "node_modules/@pixi/graphics": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-7.2.4.tgz", - "integrity": "sha512-3A2EumTjWJgXlDLOyuBrl9b6v1Za/E+/IjOGUIX843HH4NYaf1a2sfDfljx6r3oiDvy+VhuBFmgynRcV5IyA0Q==", - "dev": true, - "peerDependencies": { - "@pixi/core": "7.2.4", - "@pixi/display": "7.2.4", - "@pixi/sprite": "7.2.4" - } - }, - "node_modules/@pixi/math": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/math/-/math-7.2.4.tgz", - "integrity": "sha512-LJB+mozyEPllxa0EssFZrKNfVwysfaBun4b2dJKQQInp0DafgbA0j7A+WVg0oe51KhFULTJMpDqbLn/ITFc41A==", - "dev": true - }, - "node_modules/@pixi/mesh": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/mesh/-/mesh-7.2.4.tgz", - "integrity": "sha512-wiALIqcRKib2BqeH9kOA5fOKWN352nqAspgbDa8gA7OyWzmNwqIedIlElixd0oLFOrIN5jOZAdzeKnoYQlt9Aw==", - "dev": true, - "peerDependencies": { - "@pixi/core": "7.2.4", - "@pixi/display": "7.2.4" - } - }, - "node_modules/@pixi/mesh-extras": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/mesh-extras/-/mesh-extras-7.2.4.tgz", - "integrity": "sha512-Lxqq/1E2EmDgjZX8KzjhBy3VvITIQ00arr2ikyHYF1d0XtQTKEYpr8VKzhchqZ5/9DuyTDbDMYGhcxoNXQmZrQ==", - "dev": true, - "peerDependencies": { - "@pixi/core": "7.2.4", - "@pixi/mesh": "7.2.4" - } - }, - "node_modules/@pixi/mixin-cache-as-bitmap": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/mixin-cache-as-bitmap/-/mixin-cache-as-bitmap-7.2.4.tgz", - "integrity": "sha512-95L/9nzfLHw6GoeqqRl/RjSloKvRt0xrc2inCmjMZvMsFUEtHN2F8IWd1k5vcv0S+83NCreFkJg6nJm1m5AZqg==", - "dev": true, - "peerDependencies": { - "@pixi/core": "7.2.4", - "@pixi/display": "7.2.4", - "@pixi/sprite": "7.2.4" - } - }, - "node_modules/@pixi/mixin-get-child-by-name": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/mixin-get-child-by-name/-/mixin-get-child-by-name-7.2.4.tgz", - "integrity": "sha512-9g17KgSBEEhkinnKk4dqmxagzHOCPSTvGB6lOopBq4yyXmr/2WVv+QGjuzE0O+p80szQeBJjPBQxzrfBILaSRw==", - "dev": true, - "peerDependencies": { - "@pixi/display": "7.2.4" - } - }, - "node_modules/@pixi/mixin-get-global-position": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/mixin-get-global-position/-/mixin-get-global-position-7.2.4.tgz", - "integrity": "sha512-UrAUF2BXCeWtFgR2m+er41Ky7zShT7r228cZkB6ZfYwMeThhwqG5mH68UeCyP6p68JMpT1gjI2DPfeSRY3ecnA==", - "dev": true, - "peerDependencies": { - "@pixi/core": "7.2.4", - "@pixi/display": "7.2.4" - } - }, - "node_modules/@pixi/particle-container": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/particle-container/-/particle-container-7.2.4.tgz", - "integrity": "sha512-tpSzilZGFtAoi8XhzL0TecLPNRQAbY8nWV9XNGXJDw+nxXp18GCe8L6eEmnHLlAug67BRHl65DtrdvTknPX+4g==", - "dev": true, - "peerDependencies": { - "@pixi/core": "7.2.4", - "@pixi/display": "7.2.4", - "@pixi/sprite": "7.2.4" - } - }, - "node_modules/@pixi/prepare": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/prepare/-/prepare-7.2.4.tgz", - "integrity": "sha512-Yff5Sh4kTLdKc5VkkM44LW9gpj7Izw8ns3P1TzWxqeGjzPZ3folr/tQujGL+Qw+8A9VESp+hX9MSIHyw+jpyrg==", - "dev": true, - "peerDependencies": { - "@pixi/core": "7.2.4", - "@pixi/display": "7.2.4", - "@pixi/graphics": "7.2.4", - "@pixi/text": "7.2.4" - } - }, - "node_modules/@pixi/runner": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-7.2.4.tgz", - "integrity": "sha512-YtyqPk1LA+0guEFKSFx6t/YSvbEQwajFwi4Ft8iDhioa6VK2MmTir1GjWwy7JQYLcDmYSAcQjnmFtVTZohyYSw==", - "dev": true - }, - "node_modules/@pixi/settings": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-7.2.4.tgz", - "integrity": "sha512-ZPKRar9EwibijGmH8EViu4Greq1I/O7V/xQx2rNqN23XA7g09Qo6yfaeQpufu5xl8+/lZrjuHtQSnuY7OgG1CA==", - "dev": true, - "dependencies": { - "@pixi/constants": "7.2.4", - "@types/css-font-loading-module": "^0.0.7", - "ismobilejs": "^1.1.0" - } - }, - "node_modules/@pixi/sprite": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-7.2.4.tgz", - "integrity": "sha512-DhR1B+/d0eXpxHIesJMXcVPrKFwQ+zRA1LvEIFfzewqfaRN3X6PMIuoKX8SIb6tl+Hq8Ba9Pe28zI7d2rmRzrA==", - "dev": true, - "peerDependencies": { - "@pixi/core": "7.2.4", - "@pixi/display": "7.2.4" - } - }, - "node_modules/@pixi/sprite-animated": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/sprite-animated/-/sprite-animated-7.2.4.tgz", - "integrity": "sha512-9eRriPSC0QVS7U9zQlrG3uEI5+h3fi+mqofXy+yjk1sGCmXSIJME5p2wg2mzxoJk3qkSMagQA9QHtL26Fti8Iw==", - "dev": true, - "peerDependencies": { - "@pixi/core": "7.2.4", - "@pixi/sprite": "7.2.4" - } - }, - "node_modules/@pixi/sprite-tiling": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/sprite-tiling/-/sprite-tiling-7.2.4.tgz", - "integrity": "sha512-nGfxQoACRx49dUN0oW1vFm3141M+7gkAbzoNJym2Pljd2dpLME9fb5E6Lyahu0yWMaPRhhGorn6z9VIGmTF3Jw==", - "dev": true, - "peerDependencies": { - "@pixi/core": "7.2.4", - "@pixi/display": "7.2.4", - "@pixi/sprite": "7.2.4" - } - }, - "node_modules/@pixi/spritesheet": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/spritesheet/-/spritesheet-7.2.4.tgz", - "integrity": "sha512-LNmlavyiMQeCF0U4S+yhzxUYmPmat6EpLjLnkGukQTZV5CZkxDCVgXM9uKoRF2DvNydj4yuwZ6+JjK8QssHI8Q==", - "dev": true, - "peerDependencies": { - "@pixi/assets": "7.2.4", - "@pixi/core": "7.2.4" - } - }, - "node_modules/@pixi/text": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/text/-/text-7.2.4.tgz", - "integrity": "sha512-DGu7ktpe+zHhqR2sG9NsJt4mgvSObv5EqXTtUxD4Z0li1gmqF7uktpLyn5I6vSg1TTEL4TECClRDClVDGiykWw==", - "dev": true, - "peerDependencies": { - "@pixi/core": "7.2.4", - "@pixi/sprite": "7.2.4" - } - }, - "node_modules/@pixi/text-bitmap": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/text-bitmap/-/text-bitmap-7.2.4.tgz", - "integrity": "sha512-3u2CP4VN+muCaq/jtj7gn0hb3DET/X2S04zTBcgc2WVGufJc62yz+UDzS9jC+ellotVdt9c8U74++vpz3zJGfw==", - "dev": true, - "peerDependencies": { - "@pixi/assets": "7.2.4", - "@pixi/core": "7.2.4", - "@pixi/display": "7.2.4", - "@pixi/mesh": "7.2.4", - "@pixi/text": "7.2.4" - } - }, - "node_modules/@pixi/text-html": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/text-html/-/text-html-7.2.4.tgz", - "integrity": "sha512-0NfLAE/w51ZtatxVqLvDS62iO0VLKsSdctqTAVv4Zlgdk9TKJmX1WUucHJboTvbm2SbDjNDGfZ6qXM5nAslIDQ==", - "dev": true, - "peerDependencies": { - "@pixi/core": "7.2.4", - "@pixi/display": "7.2.4", - "@pixi/sprite": "7.2.4", - "@pixi/text": "7.2.4" - } - }, - "node_modules/@pixi/ticker": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-7.2.4.tgz", - "integrity": "sha512-hQQHIHvGeFsP4GNezZqjzuhUgNQEVgCH9+qU05UX1Mc5UHC9l6OJnY4VTVhhcHxZjA6RnyaY+1zBxCnoXuazpg==", - "dev": true, - "dependencies": { - "@pixi/extensions": "7.2.4", - "@pixi/settings": "7.2.4", - "@pixi/utils": "7.2.4" - } - }, - "node_modules/@pixi/utils": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-7.2.4.tgz", - "integrity": "sha512-VUGQHBOINIS4ePzoqafwxaGPVRTa3oM/mEutIIHbNGI3b+QvSO+1Dnk40M0zcH6Bo+MxQZbOZK5X/wO9oU5+LQ==", - "dev": true, - "dependencies": { - "@pixi/color": "7.2.4", - "@pixi/constants": "7.2.4", - "@pixi/settings": "7.2.4", - "@types/earcut": "^2.1.0", - "earcut": "^2.2.4", - "eventemitter3": "^4.0.0", - "url": "^0.11.0" - } - }, - "node_modules/@rollup/plugin-commonjs": { - "version": "24.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-24.1.0.tgz", - "integrity": "sha512-eSL45hjhCWI0jCCXcNtLVqM5N1JlBGvlFfY0m6oOYnLCJ6N0qEXoZql4sY2MOUArzhH4SA/qBpTxvvZp2Sc+DQ==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "commondir": "^1.0.1", - "estree-walker": "^2.0.2", - "glob": "^8.0.3", - "is-reference": "1.2.1", - "magic-string": "^0.27.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^2.68.0||^3.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-node-resolve": { - "version": "15.2.1", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.1.tgz", - "integrity": "sha512-nsbUg588+GDSu8/NS8T4UAshO6xeaOfINNuXeVHcKV02LJtoRaM1SiOacClw4kws1SFiNhdLGxlbMY9ga/zs/w==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "@types/resolve": "1.20.2", - "deepmerge": "^4.2.2", - "is-builtin-module": "^3.2.1", - "is-module": "^1.0.0", - "resolve": "^1.22.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^2.78.0||^3.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-terser": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.3.tgz", - "integrity": "sha512-EF0oejTMtkyhrkwCdg0HJ0IpkcaVg1MMSf2olHb2Jp+1mnLM04OhjpJWGma4HobiDTF0WCyViWuvadyE9ch2XA==", - "dev": true, - "dependencies": { - "serialize-javascript": "^6.0.1", - "smob": "^1.0.0", - "terser": "^5.17.4" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^2.x || ^3.x" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-typescript": { - "version": "11.1.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.3.tgz", - "integrity": "sha512-8o6cNgN44kQBcpsUJTbTXMTtb87oR1O0zgP3Dxm71hrNgparap3VujgofEilTYJo+ivf2ke6uy3/E5QEaiRlDA==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "resolve": "^1.22.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^2.14.0||^3.0.0", - "tslib": "*", - "typescript": ">=3.7.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - }, - "tslib": { - "optional": true - } - } - }, - "node_modules/@rollup/pluginutils": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.4.tgz", - "integrity": "sha512-0KJnIoRI8A+a1dqOYLxH8vBf8bphDmty5QvIm2hqm7oFCFYKCAZWWd2hXgMibaPsNDhI0AtpYfQZJG47pt/k4g==", - "dev": true, - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "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/css-font-loading-module": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/@types/css-font-loading-module/-/css-font-loading-module-0.0.7.tgz", - "integrity": "sha512-nl09VhutdjINdWyXxHWN/w9zlNCfr60JUqJbd24YXUuCwgeL0TpFSdElCwb6cxfB6ybE19Gjj4g0jsgkXxKv1Q==", - "dev": true - }, - "node_modules/@types/earcut": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@types/earcut/-/earcut-2.1.1.tgz", - "integrity": "sha512-w8oigUCDjElRHRRrMvn/spybSMyX8MTkKA5Dv+tS1IE/TgmNZPqUYtvYBXGY8cieSE66gm+szeK+bnbxC2xHTQ==", - "dev": true - }, - "node_modules/@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", - "dev": true - }, - "node_modules/@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "dev": true - }, - "node_modules/@types/offscreencanvas": { - "version": "2019.7.1", - "resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.1.tgz", - "integrity": "sha512-+HSrJgjBW77ALieQdMJvXhRZUIRN1597L+BKvsyeiIlHHERnqjcuOLyodK3auJ3Y3zRezNKtKAhuQWYJfEgFHQ==", - "dev": true - }, - "node_modules/@types/pug": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.6.tgz", - "integrity": "sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg==", - "dev": true - }, - "node_modules/@types/resolve": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", - "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", - "dev": true - }, - "node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "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/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.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "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/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chalk/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "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" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/colord": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", - "dev": true - }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true - }, - "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/concurrently": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.1.tgz", - "integrity": "sha512-nVraf3aXOpIcNud5pB9M82p1tynmZkrSGQ1p6X/VY8cJ+2LMVqAgXsJxYYefACSHbTYlm92O1xuhdGTjwoEvbQ==", - "dev": true, - "dependencies": { - "chalk": "^4.1.2", - "date-fns": "^2.30.0", - "lodash": "^4.17.21", - "rxjs": "^7.8.1", - "shell-quote": "^1.8.1", - "spawn-command": "0.0.2", - "supports-color": "^8.1.1", - "tree-kill": "^1.2.2", - "yargs": "^17.7.2" - }, - "bin": { - "conc": "dist/bin/concurrently.js", - "concurrently": "dist/bin/concurrently.js" - }, - "engines": { - "node": "^14.13.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/date-fns": { - "version": "2.30.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", - "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.21.0" - }, - "engines": { - "node": ">=0.11" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/date-fns" - } - }, - "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/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/duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "dev": true - }, - "node_modules/earcut": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz", - "integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==", - "dev": true - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "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/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true - }, - "node_modules/event-stream": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", - "integrity": "sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==", - "dev": true, - "dependencies": { - "duplexer": "~0.1.1", - "from": "~0", - "map-stream": "~0.1.0", - "pause-stream": "0.0.11", - "split": "0.3", - "stream-combiner": "~0.0.4", - "through": "~2.3.1" - } - }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", - "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.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "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/from": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==", - "dev": true - }, - "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/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "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/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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-builtin-module": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", - "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", - "dev": true, - "dependencies": { - "builtin-modules": "^3.3.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-core-module": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", - "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "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-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", - "dev": true - }, - "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": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", - "dev": true, - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/ismobilejs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ismobilejs/-/ismobilejs-1.1.1.tgz", - "integrity": "sha512-VaFW53yt8QO61k2WJui0dHf4SlL8lxBofUuUmwBo0ljPk0Drz2TiuDW4jo3wDcv41qy/SxrJ+VAzJ/qYqsmzRw==", - "dev": true - }, - "node_modules/livereload": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/livereload/-/livereload-0.9.3.tgz", - "integrity": "sha512-q7Z71n3i4X0R9xthAryBdNGVGAO2R5X+/xXpmKeuPMrteg+W2U8VusTKV3YiJbXZwKsOlFlHe+go6uSNjfxrZw==", - "dev": true, - "dependencies": { - "chokidar": "^3.5.0", - "livereload-js": "^3.3.1", - "opts": ">= 1.2.0", - "ws": "^7.4.3" - }, - "bin": { - "livereload": "bin/livereload.js" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/livereload-js": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-3.4.1.tgz", - "integrity": "sha512-5MP0uUeVCec89ZbNOT/i97Mc+q3SxXmiUGhRFOTmhrGPn//uWVQdCvcLJDy64MSBR5MidFdOR7B9viumoavy6g==", - "dev": true - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/magic-string": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", - "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.13" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/map-stream": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", - "integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==", - "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": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "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/node-cleanup": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/node-cleanup/-/node-cleanup-2.1.2.tgz", - "integrity": "sha512-qN8v/s2PAJwGUtr1/hYTpNKlD6Y9rc4p8KSmJXyGdYGZsDGKXrGThikLFP9OCHFeLeEpQzPwiAtdIvBLqm//Hw==", - "dev": true - }, - "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/object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/opts": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/opts/-/opts-2.0.2.tgz", - "integrity": "sha512-k41FwbcLnlgnFh69f4qdUfvDQ+5vaSDnVPFI/y5XuhKRq97EnVVneO9F1ESVCdiVu4fCS2L8usX3mU331hB7pg==", - "dev": true - }, - "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/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/pause-stream": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", - "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", - "dev": true, - "dependencies": { - "through": "~2.3" - } - }, - "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/pixi-filters": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/pixi-filters/-/pixi-filters-5.2.1.tgz", - "integrity": "sha512-lsRakKJfK0iH+aCCVePQcSb477hFiS20CR2p4u7xS6RO7q5qh5GhAyGqWdgYZlUT5WLSW0kxAV+FddYLs9z9Sg==", - "dev": true, - "dependencies": { - "@pixi/filter-adjustment": "5.1.1", - "@pixi/filter-advanced-bloom": "5.1.1", - "@pixi/filter-ascii": "5.1.1", - "@pixi/filter-bevel": "5.1.1", - "@pixi/filter-bloom": "5.1.1", - "@pixi/filter-bulge-pinch": "5.1.1", - "@pixi/filter-color-gradient": "5.2.0", - "@pixi/filter-color-map": "5.1.1", - "@pixi/filter-color-overlay": "5.1.1", - "@pixi/filter-color-replace": "5.1.1", - "@pixi/filter-convolution": "5.1.1", - "@pixi/filter-cross-hatch": "5.1.1", - "@pixi/filter-crt": "5.1.1", - "@pixi/filter-dot": "5.1.1", - "@pixi/filter-drop-shadow": "5.2.0", - "@pixi/filter-emboss": "5.1.1", - "@pixi/filter-glitch": "5.1.1", - "@pixi/filter-glow": "5.2.1", - "@pixi/filter-godray": "5.1.1", - "@pixi/filter-grayscale": "5.1.1", - "@pixi/filter-hsl-adjustment": "5.2.0", - "@pixi/filter-kawase-blur": "5.1.1", - "@pixi/filter-motion-blur": "5.1.1", - "@pixi/filter-multi-color-replace": "5.1.1", - "@pixi/filter-old-film": "5.1.1", - "@pixi/filter-outline": "5.2.0", - "@pixi/filter-pixelate": "5.1.1", - "@pixi/filter-radial-blur": "5.1.1", - "@pixi/filter-reflection": "5.1.1", - "@pixi/filter-rgb-split": "5.1.1", - "@pixi/filter-shockwave": "5.1.1", - "@pixi/filter-simple-lightmap": "5.1.1", - "@pixi/filter-tilt-shift": "5.2.0", - "@pixi/filter-twist": "5.1.1", - "@pixi/filter-zoom-blur": "5.1.1" - } - }, - "node_modules/pixi-viewport": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/pixi-viewport/-/pixi-viewport-5.0.2.tgz", - "integrity": "sha512-U77KnCTl81xEgxEQRFEuI7MYVySWwCVkA41EnM8KiOYwgVOwdBUa7318O+u61IOnTwnoYLzaihy/kpoONKU13Q==", - "dev": true - }, - "node_modules/pixi.js": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/pixi.js/-/pixi.js-7.2.4.tgz", - "integrity": "sha512-nBH60meoLnHxoMFz17HoMxXS4uJpG5jwIdL+Gx2S11TzWgP3iKF+/WLOTrkSdyuQoQSdIBxVqpnYii0Wiox15A==", - "dev": true, - "dependencies": { - "@pixi/accessibility": "7.2.4", - "@pixi/app": "7.2.4", - "@pixi/assets": "7.2.4", - "@pixi/compressed-textures": "7.2.4", - "@pixi/core": "7.2.4", - "@pixi/display": "7.2.4", - "@pixi/events": "7.2.4", - "@pixi/extensions": "7.2.4", - "@pixi/extract": "7.2.4", - "@pixi/filter-alpha": "7.2.4", - "@pixi/filter-blur": "7.2.4", - "@pixi/filter-color-matrix": "7.2.4", - "@pixi/filter-displacement": "7.2.4", - "@pixi/filter-fxaa": "7.2.4", - "@pixi/filter-noise": "7.2.4", - "@pixi/graphics": "7.2.4", - "@pixi/mesh": "7.2.4", - "@pixi/mesh-extras": "7.2.4", - "@pixi/mixin-cache-as-bitmap": "7.2.4", - "@pixi/mixin-get-child-by-name": "7.2.4", - "@pixi/mixin-get-global-position": "7.2.4", - "@pixi/particle-container": "7.2.4", - "@pixi/prepare": "7.2.4", - "@pixi/sprite": "7.2.4", - "@pixi/sprite-animated": "7.2.4", - "@pixi/sprite-tiling": "7.2.4", - "@pixi/spritesheet": "7.2.4", - "@pixi/text": "7.2.4", - "@pixi/text-bitmap": "7.2.4", - "@pixi/text-html": "7.2.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/pixijs" - } - }, - "node_modules/ps-tree": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz", - "integrity": "sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==", - "dev": true, - "dependencies": { - "event-stream": "=3.3.4" - }, - "bin": { - "ps-tree": "bin/ps-tree.js" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "dev": true - }, - "node_modules/qs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", - "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "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/regenerator-runtime": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", - "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==", - "dev": true - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve": { - "version": "1.22.4", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", - "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", - "dev": true, - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/resolve.exports": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", - "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "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/rimraf/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/rimraf/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/rimraf/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/rollup": { - "version": "3.29.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.0.tgz", - "integrity": "sha512-nszM8DINnx1vSS+TpbWKMkxem0CDWk3cSit/WWCBVs9/JZ1I/XLwOsiUglYuYReaeWWSsW9kge5zE5NZtf/a4w==", - "dev": true, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=14.18.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/rollup-plugin-css-only": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-css-only/-/rollup-plugin-css-only-4.3.0.tgz", - "integrity": "sha512-BsiCqJJQzZh2lQiHY5irejRoJ3I1EUFHEi5PjVqsr+EmOh54YrWVwd3YZEXnQJ2+fzlhif0YM/Kf0GuH90GAdQ==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "5" - }, - "engines": { - "node": ">=14" - }, - "peerDependencies": { - "rollup": "<4" - } - }, - "node_modules/rollup-plugin-inject": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rollup-plugin-inject/-/rollup-plugin-inject-3.0.2.tgz", - "integrity": "sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==", - "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject.", - "dev": true, - "dependencies": { - "estree-walker": "^0.6.1", - "magic-string": "^0.25.3", - "rollup-pluginutils": "^2.8.1" - } - }, - "node_modules/rollup-plugin-inject/node_modules/estree-walker": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", - "dev": true - }, - "node_modules/rollup-plugin-inject/node_modules/magic-string": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", - "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", - "dev": true, - "dependencies": { - "sourcemap-codec": "^1.4.8" - } - }, - "node_modules/rollup-plugin-livereload": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/rollup-plugin-livereload/-/rollup-plugin-livereload-2.0.5.tgz", - "integrity": "sha512-vqQZ/UQowTW7VoiKEM5ouNW90wE5/GZLfdWuR0ELxyKOJUIaj+uismPZZaICU4DnWPVjnpCDDxEqwU7pcKY/PA==", - "dev": true, - "dependencies": { - "livereload": "^0.9.1" - }, - "engines": { - "node": ">=8.3" - } - }, - "node_modules/rollup-plugin-node-polyfills": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/rollup-plugin-node-polyfills/-/rollup-plugin-node-polyfills-0.2.1.tgz", - "integrity": "sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==", - "dev": true, - "dependencies": { - "rollup-plugin-inject": "^3.0.0" - } - }, - "node_modules/rollup-plugin-svelte": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/rollup-plugin-svelte/-/rollup-plugin-svelte-7.1.6.tgz", - "integrity": "sha512-nVFRBpGWI2qUY1OcSiEEA/kjCY2+vAjO9BI8SzA7NRrh2GTunLd6w2EYmnMt/atgdg8GvcNjLsmZmbQs/u4SQA==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^4.1.0", - "resolve.exports": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "rollup": ">=2.0.0", - "svelte": ">=3.5.0" - } - }, - "node_modules/rollup-plugin-svelte/node_modules/@rollup/pluginutils": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", - "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", - "dev": true, - "dependencies": { - "estree-walker": "^2.0.1", - "picomatch": "^2.2.2" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/rollup-pluginutils": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", - "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", - "dev": true, - "dependencies": { - "estree-walker": "^0.6.1" - } - }, - "node_modules/rollup-pluginutils/node_modules/estree-walker": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", - "dev": true - }, - "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/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "dev": true, - "dependencies": { - "tslib": "^2.1.0" - } - }, - "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/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "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/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/serialize-javascript": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", - "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/smob": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/smob/-/smob-1.4.0.tgz", - "integrity": "sha512-MqR3fVulhjWuRNSMydnTlweu38UhQ0HXM4buStD/S3mc/BzX3CuM9OmhyQpmtYCvoYdl5ris6TI0ZqH355Ymqg==", - "dev": true - }, - "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": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", - "deprecated": "Please use @jridgewell/sourcemap-codec instead", - "dev": true - }, - "node_modules/spawn-command": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2.tgz", - "integrity": "sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==", - "dev": true - }, - "node_modules/split": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", - "integrity": "sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==", - "dev": true, - "dependencies": { - "through": "2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/stream-combiner": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", - "integrity": "sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==", - "dev": true, - "dependencies": { - "duplexer": "~0.1.1" - } - }, - "node_modules/string-argv": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", - "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", - "dev": true, - "engines": { - "node": ">=0.6.19" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "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/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/svelte": { - "version": "3.59.2", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.59.2.tgz", - "integrity": "sha512-vzSyuGr3eEoAtT/A6bmajosJZIUWySzY2CzB3w2pgPvnkUjGqlDnsNnA0PMO+mMAhuyMul6C2uuZzY6ELSkzyA==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/svelte-check": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.5.1.tgz", - "integrity": "sha512-+Zb4iHxAhdUtcUg/WJPRjlS1RJalIsWAe9Mz6G1zyznSs7dDkT7VUBdXc3q7Iwg49O/VrZgyJRvOJkjuBfKjFA==", - "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.0.4", - "typescript": "^5.0.3" - }, - "bin": { - "svelte-check": "bin/svelte-check" - }, - "peerDependencies": { - "svelte": "^3.55.0 || ^4.0.0-next.0 || ^4.0.0" - } - }, - "node_modules/svelte-check/node_modules/typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/svelte-preprocess": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.0.4.tgz", - "integrity": "sha512-ABia2QegosxOGsVlsSBJvoWeXy1wUKSfF7SWJdTjLAbx/Y3SrVevvvbFNQqrSJw89+lNSsM58SipmZJ5SRi5iw==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@types/pug": "^2.0.6", - "detect-indent": "^6.1.0", - "magic-string": "^0.27.0", - "sorcery": "^0.11.0", - "strip-indent": "^3.0.0" - }, - "engines": { - "node": ">= 14.10.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", - "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", - "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/terser": { - "version": "5.19.4", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.4.tgz", - "integrity": "sha512-6p1DjHeuluwxDXcuT9VR8p64klWJKo1ILiy19s6C9+0Bh2+NWTX6nD9EPppiER4ICkHDVB1RkVpin/YW2nQn/g==", - "dev": true, - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": 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/tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", - "dev": true, - "bin": { - "tree-kill": "cli.js" - } - }, - "node_modules/tsc-watch": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/tsc-watch/-/tsc-watch-6.0.4.tgz", - "integrity": "sha512-cHvbvhjO86w2aGlaHgSCeQRl+Aqw6X6XN4sQMPZKF88GoP30O+oTuh5lRIJr5pgFWrRpF1AgXnJJ2DoFEIPHyg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.3", - "node-cleanup": "^2.1.2", - "ps-tree": "^1.2.0", - "string-argv": "^0.3.1" - }, - "bin": { - "tsc-watch": "dist/lib/tsc-watch.js" - }, - "engines": { - "node": ">=12.12.0" - }, - "peerDependencies": { - "typescript": "*" - } - }, - "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": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/url": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.1.tgz", - "integrity": "sha512-rWS3H04/+mzzJkv0eZ7vEDGiQbgquI1fGfOad6zKvgYQi1SzMmhl7c/DdRGxhaWrVH6z0qWITo8rpnxK/RfEhA==", - "dev": true, - "dependencies": { - "punycode": "^1.4.1", - "qs": "^6.11.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "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 - }, - "node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "dev": true, - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "engines": { - "node": ">=12" - } - } - } -} diff --git a/blix-plugins/blink/package.json b/blix-plugins/blink/package.json deleted file mode 100644 index 5a779ff7..00000000 --- a/blix-plugins/blink/package.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "blink", - "displayName": "Blink", - "description": "Dynamic image editing for Blix", - "version": "0.0.1", - "author": "Rec1dite", - "repository": "", - "type": "module", - "scripts": { - "build": "rollup -c", - "webview": "rollup -cw", - "main": "tsc-watch src/main.cts --outDir dist", - "dev": "concurrently \"npm run webview\" \"npm run main\"", - "check": "svelte-check" - }, - "contributes": { - "commands": [], - "nodes": [] - }, - "main": "src/main.cjs", - "renderers": { - "blinkRenderer": "src/index.html" - }, - "devDependencies": { - "@rollup/plugin-commonjs": "^24.0.0", - "@rollup/plugin-node-resolve": "^15.1.0", - "@rollup/plugin-terser": "^0.4.0", - "@rollup/plugin-typescript": "^11.1.3", - "@tsconfig/svelte": "^5.0.0", - "@types/node": "^12.0.0", - "concurrently": "^8.2.1", - "pixi-filters": "^5.2.1", - "pixi-viewport": "^5.0.2", - "pixi.js": "^7.2.4", - "rollup": "^3.15.0", - "rollup-plugin-css-only": "^4.3.0", - "rollup-plugin-livereload": "^2.0.5", - "rollup-plugin-node-polyfills": "^0.2.1", - "rollup-plugin-svelte": "^7.1.2", - "svelte": "^3.55.0", - "svelte-check": "^3.5.0", - "svelte-preprocess": "^5.0.4", - "tsc-watch": "^6.0.4", - "tslib": "^2.6.1", - "typescript": "^4.9.0" - }, - "comments": [ - "This plugin will be expanded to handle more image operations." - ] -} diff --git a/blix-plugins/blink/rollup.config.js b/blix-plugins/blink/rollup.config.js deleted file mode 100644 index e628dbb6..00000000 --- a/blix-plugins/blink/rollup.config.js +++ /dev/null @@ -1,104 +0,0 @@ -import { spawn } from 'child_process'; -import svelte from 'rollup-plugin-svelte'; -import commonjs from '@rollup/plugin-commonjs'; -import terser from '@rollup/plugin-terser'; -import resolve from '@rollup/plugin-node-resolve'; -import livereload from 'rollup-plugin-livereload'; -import css from 'rollup-plugin-css-only'; -import nodePolyfills from 'rollup-plugin-node-polyfills'; -import sveltePreprocess from 'svelte-preprocess'; -import typescript from '@rollup/plugin-typescript'; - -const production = !process.env.ROLLUP_WATCH; - -function serve() { - let server; - - function toExit() { - if (server) server.kill(0); - } - - return { - writeBundle() { - if (server) return; - // server = spawn('npm', ['run', 'start', '--', '--dev'], { - // stdio: ['ignore', 'inherit', 'inherit'], - // shell: true - // }); - - process.on('SIGTERM', toExit); - process.on('exit', toExit); - } - }; -} - -export default { - input: 'webview/app.ts', - output: { - sourcemap: true, - format: 'iife', - name: 'app', - file: 'dist/bundle.js' - }, - plugins: [ - svelte({ - preprocess: sveltePreprocess({ sourceMap: !production }), - compilerOptions: { - // enable run-time checks when not in production - dev: !production - } - }), - // we'll extract any component CSS out into - // a separate file - better for performance - css({ output: 'bundle.css' }), - - // If you have external dependencies installed from - // npm, you'll most likely need these plugins. In - // some cases you'll need additional configuration - - // consult the documentation for details: - // https://github.com/rollup/plugins/tree/master/packages/commonjs - resolve({ - browser: true, - dedupe: ['svelte'], - preferBuiltins: false, - exportConditions: ['svelte'] - }), - - typescript({ - tsconfig: './tsconfig.json', - sourceMap: !production, - inlineSources: !production, - // compilerOptions: { - // noUnusedLocals: false - // } - }), - - // Important to allow node modules to be imported in .svelte files - nodePolyfills(), - commonjs({ - include: 'node_modules/**', - }), - - serve({ - // open: true, // Open browser automatically - // verbose: true, - // contentBase: ['src', 'dist'], - - // host: 'localhost', - // port: 3000, - }), - - // Watch the `dist` directory and refresh the - // browser on changes when not in production - !production && livereload({ - watch: 'dist' - }), - - // If we're building for production (npm run build - // instead of npm run dev), minify - production && terser() - ], - watch: { - clearScreen: false - } -}; \ No newline at end of file diff --git a/blix-plugins/blink/src/global.css b/blix-plugins/blink/src/global.css deleted file mode 100644 index cda76288..00000000 --- a/blix-plugins/blink/src/global.css +++ /dev/null @@ -1,5 +0,0 @@ -body { - font-family: 'Arial'; - padding: 0px; - margin: 0px; -} \ No newline at end of file diff --git a/blix-plugins/blink/src/index.html b/blix-plugins/blink/src/index.html deleted file mode 100644 index ff372361..00000000 --- a/blix-plugins/blink/src/index.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - GLFX plugin - - - - - - - - - - - - \ No newline at end of file diff --git a/blix-plugins/blink/src/main.cjs b/blix-plugins/blink/src/main.cjs deleted file mode 100644 index e4ab9539..00000000 --- a/blix-plugins/blink/src/main.cjs +++ /dev/null @@ -1,1110 +0,0 @@ -const crypto = require("crypto"); - -function getUUID() { - return crypto.randomBytes(16).toString("base64url"); -} - -function colorHexToAlpha(str) { - if (str.length <= 7) return 1.0; - return parseInt("0x" + str.slice(7, 9))/255.0; -} -function colorHexToNumber(str) { - return parseInt(str.slice(0, 7).replace("#", "0x")); -} - -function chooseInput(input, uiInput, inputKey) { - if (input[inputKey] != null) { - return input[inputKey]; - } - return inputKey.includes("color") ? colorHexToNumber(uiInput[inputKey]) : uiInput[inputKey]; -} - -function toTitleCase(str) { - return str.charAt(0).toUpperCase() + str.slice(1); -} - -function addTransformInput(ui, props = ["position", "rotation", "scale", "origin"]) { - const propInputs = [ - ...(props.includes("position") ? ["position X", "position Y"] : []), - ...(props.includes("rotation") ? ["rotation"] : []), - ...(props.includes("scale") ? ["scale X", "scale Y"] : []) - ]; - for (let numInp of propInputs) { - // for (let numInp of ["position X", "position Y", "rotation", "scale X", "scale Y"]) { - ui.addNumberInput( - { - componentId: numInp.replace(" ", ""), - label: numInp[0].toUpperCase() + numInp.slice(1), - defaultValue: (numInp.includes("scale") ? 1 : 0), - triggerUpdate: true, - }, - numInp.includes("scale") ? { step: 0.025 } : - numInp === "rotation" ? { step: 0.2 } : - { step: 1 } - ); - } - if (props.includes("origin")) { - ui.addOriginPicker( - { - componentId: "origin", - label: "", - defaultValue: "mm", - triggerUpdate: true, - }, - {} - ); - } - return (uiInput) => ({ - ...(props.includes("position") ? { position: { x: uiInput?.positionX, y: uiInput?.positionY } } : {}), - ...(props.includes("rotation") ? { rotation: uiInput?.rotation } : {}), - ...(props.includes("scale") ? { scale: { x: uiInput?.scaleX, y: uiInput?.scaleY }, } : {}), - ...(props.includes("origin") ? { origin: uiInput?.origin } : {}), - }); -} - -function addState(ui) { - ui.addBuffer({ - componentId: "state", - label: "State Buffer", - defaultValue: { id: null }, - triggerUpdate: true, - }, {} - ); -} - -function addTweakability(ui) { - ui.addTweakDial("tweaks", {}); - // ui.addDiffDial("diffs", {}); -} - -function createBlinkNode(type, title, desc, params) { - return (context) => { - const nodeBuilder = context.instantiate("Blink/Filters", type); - nodeBuilder.setTitle(title); - nodeBuilder.setDescription(desc); - - const ui = nodeBuilder.createUIBuilder(); - for (let param of params) { - if(param.id.includes("color") || param.id.includes("Color")) { - ui.addColorPicker({ - componentId: param.id, - label: toTitleCase(param.id), - defaultValue: "#000000", - triggerUpdate: true, - }, {}) - - } - else{ - ui.addSlider( - { - componentId: param.id, - label: toTitleCase(param.id), - defaultValue: 0, - triggerUpdate: true, - }, - { min: param.min ?? -1, max: param.max ?? 1, step: param.step ?? 0.05 } - ); - } - } - nodeBuilder.define(async (input, uiInput, from) => { - - const canvas = input["clump"]; - - if (!canvas.content.filters) canvas.content.filters = []; - canvas.content.filters.push({ - class: "filter", - type: type, - params: params.map((param) => chooseInput(input, uiInput, param.id)), - }); - - return { "res": canvas }; - }); - - nodeBuilder.setUI(ui); - nodeBuilder.addInput("Blink clump", "clump", "Clump"); - // for (let param of params) { - // nodeBuilder.addInput("number", type, toTitleCase(param.id)); - // } - nodeBuilder.addOutput("Blink clump", "res", "Result"); - }; -} - -const blinkNodes = { - "blur": [ - "Blur", - "Applies a blur to the image", - [{ id: "blur", min: 0, max: 100, step: 0.1 }, { id: "quality", min: 1, max: 10, step: 0.01 }] - ], - "noise": [ - "Noise", - "Applies a noise filter to the image", - [{ id: "noise", min: 0, max: 1, step: 0.01 }, { id: "seed", min: 0.01, max: 0.99, step: 0.01 }] - ], - "bloom": [ - "Bloom", - "Applies a Guassian blur to the image", - [{ id: "strength", min: 0, max: 20, step: 0.1 }] - ], - "grayscale": [ - "Gray Scale", - "Applies a grayscale filter to the image", - [] - ], - "bevel": [ - "Bevel", - "Bevel Filter", - [ - { id: "rotation", min: 0, max: 360, step: 1.0 }, - { id: "thickness", min: 0, max: 100, step: 0.1 }, - { id: "lightColor" }, - { id: "lightAlpha", min: 0, max: 1, step: 0.01 }, - { id: "shadowColor" }, - { id: "shadowAlpha", min: 0, max: 1, step: 0.01 }, - ] - ], - "outline": [ - "Outline", - "Applies an outline filter to the image", - [ - { id: "thickness", min: 0, max: 100, step: 0.1 }, - { id: "color" }, - { id: "alpha", min: 0, max: 1, step: 0.01 }, - ] - ], - "dot": [ - "Dot", - "This filter applies a dotscreen effect making display objects appear to be made out of halftone dots like an old printer", - [{ id: "scale", min: 0.3, max: 1, step: 0.01 }, { id: "angle", min: 0, max: 5, step: 0.01 }] - ], - "crt": [ - "CRT", - "Applies a CRT effect to the image", - [ - { id: "curvature", min: 0, max: 100, step: 0.1 }, - { id: "lineWidth", min: 0, max: 5, step: 0.01 }, - { id: "lineContrast", min: 0, max: 1, step: 0.01 }, - { id: "noise", min: 0, max: 1, step: 0.01 }, - { id: "noiseSize", min: 1, max: 10, step: 0.01 }, - { id: "vignetting", min: 0, max: 1, step: 0.01 }, - { id: "vignettingAlpha", min: 0, max: 1, step: 0.01 }, - { id: "vignettingBlur", min: 0, max: 1, step: 0.01 }, - { id: "seed", min: 0, max: 1, step: 0.01 }, - ] - ], - "emboss": [ - "Emboss", - "An RGB Split Filter.", - [{ id: "strength", min: 0, max: 20, step: 0.1 }] - ], - "bulge": [ - "Bulge / Pinch", - "Bulges or pinches the image in a circle.", - [ - { id: "radius", min: 0, max: 1000, step: 1.0 }, - { id: "strength", min: -1, max: 1, step: 0.01 }, - { id: "center.x", min: 0, max: 1, step: 0.01 }, - { id: "center.y", min: 0, max: 1, step: 0.01 }, - ] - ], - "zoomblur": [ - "ZoomBlur", - "The ZoomFilter applies a Zoom blur to an object.", - [ - { id: "strength", min: 0, max: 0.5, step: 0.01 }, - { id: "innerRadius", min: 0, max: 1000, step: 1.0 }, - { id: "center.x", min: 0, max: 2000, step: 1.0 }, - { id: "center.y", min: 0, max: 2000, step: 1.0 }, - ] - ], - "brightnessContrast": [ - "Brightness / Contrast", - "Adjusts the brightness and contrast of the image.", - [ - { id: "brightness", min: 0, max: 10, step: 0.1 }, - { id: "contrast", min: 0, max: 10, step: 0.1 }, - ] - ], - "saturationGamma": [ - "Saturation / Gamma", - "Adjusts the saturation and gamma of the image.", - [ - { id: "saturation", min: 0, max: 10, step: 0.1 }, - { id: "gamma", min: 0, max: 10, step: 0.1 }, - ] - ], - "colorChannel": [ - "Color-channel", - "Shifts the color channel and alpha of the image.", - [ - { id: "red", min: 0, max: 10, step: 0.1 }, - { id: "green", min: 0, max: 10, step: 0.1 }, - { id: "blue", min: 0, max: 10, step: 0.1 }, - { id: "alpha", min: 0, max: 10, step: 0.1 }, - ] - ], -}; - -Object.keys(blinkNodes).forEach((key) => { - blinkNodes[key] = createBlinkNode(key, ...blinkNodes[key]); -}); - -//========== NODES ==========// -const nodes = { - ...blinkNodes, - - "inputImage": (context) => { - const nodeBuilder = context.instantiate(String.raw`Blink/Input`, "inputImage"); - nodeBuilder.setTitle("Blink Image"); - nodeBuilder.setDescription("Input a Blink Sprite Image"); - - const ui = nodeBuilder.createUIBuilder(); - ui.addCachePicker({ - componentId: "imagePicker", - label: "Pick an image", - defaultValue: "", - triggerUpdate: true, - }, {}); - // ui.addCachePicker({ - // componentId: "cachePicker", - // label: "Pick an cache item", - // defaultValue: "", - // triggerUpdate: true, - // }, {}); - addTransformInput(ui); - addState(ui); - addTweakability(ui); - - nodeBuilder.setUIInitializer((x) => { - return { - state: { - id: getUUID(), - } - }; - }); - - nodeBuilder.define(async (input, uiInput, from) => { - let src = uiInput["imagePicker"]; - - const canvas = { - assets: { - [uiInput["state"]["id"]]: { - class: "asset", - type: "image", - data: uiInput["imagePicker"] - // data: uiInput["cachePicker"], - } - }, - content: { - class: "clump", - nodeUUID: uiInput["tweaks"].nodeUUID, - changes: uiInput["diffs"]?.uiInputs ?? [], - transform: { - position: { x: uiInput["positionX"], y: uiInput["positionY"] }, - rotation: uiInput["rotation"], - scale: { x: uiInput["scaleX"], y: uiInput["scaleY"] }, - }, - elements: [ - { - class: "atom", - type: "image", - assetId: uiInput["state"]["id"], - } - ] - } - } - - return { res: canvas }; - }); - - nodeBuilder.setUI(ui); - nodeBuilder.addInput("Blink matrix", "transform", "Transform"); - nodeBuilder.addOutput("Blink clump", "res", "Result"); - }, - "inputShape": (context) => { - const nodeBuilder = context.instantiate("Blink/Input", "inputShape"); - nodeBuilder.setTitle("Blink Shape"); - nodeBuilder.setDescription("Input a Blink Shape"); - - const ui = nodeBuilder.createUIBuilder(); - ui.addDropdown({ - componentId: "shape", - label: "Shape", - defaultValue: "rectangle", - triggerUpdate: true, - }, { - options: { - "Rectangle": "rectangle", - "Ellipse": "ellipse", - "Triangle": "triangle", - } - }) - for (let numInp of ["width", "height"]) { - ui.addNumberInput( - { - componentId: numInp.replace(" ", ""), - label: numInp[0].toUpperCase() + numInp.slice(1), - defaultValue: 100, - triggerUpdate: true, - }, - { min: 0 } - ); - } - const getTransform = addTransformInput(ui, ["position", "rotation"]); - - ui.addColorPicker({ - componentId: "fill", - label: "Fill", - defaultValue: "#000000", - triggerUpdate: true, - }, {}); - ui.addColorPicker({ - componentId: "stroke", - label: "Stroke", - defaultValue: "#00000000", - triggerUpdate: true, - }, {}); - ui.addSlider({ - componentId: "strokeWidth", - label: "Stroke Width", - defaultValue: 0, - triggerUpdate: true, - }, { min: 0, max: 100, set: 0.1 }); - - addTweakability(ui); - - nodeBuilder.define(async (input, uiInput, from) => { - const canvas = { - assets: {}, - content: { - class: "clump", - nodeUUID: uiInput["tweaks"].nodeUUID, - changes: uiInput["diffs"]?.uiInputs ?? [], - transform: getTransform(uiInput), - elements: [ - { - class: "atom", - type: "shape", - shape: uiInput["shape"], - bounds: { w: uiInput["width"], h: uiInput["height"] }, - - fill: colorHexToNumber(uiInput["fill"]), - fillAlpha: colorHexToAlpha(uiInput["fill"]), - stroke: colorHexToNumber(uiInput["stroke"]), - strokeAlpha: colorHexToAlpha(uiInput["stroke"]), - strokeWidth: uiInput["strokeWidth"], - } - ] - } - } - - return { res: canvas }; - }); - - nodeBuilder.setUI(ui); - - nodeBuilder.addInput("Blink matrix", "transform", "Transform"); - nodeBuilder.addOutput("Blink clump", "res", "Result"); - }, - "curve": (context) => { - const nodeBuilder = context.instantiate("Blink/Input", "curve"); - nodeBuilder.setTitle("Blink Curve"); - nodeBuilder.setDescription("Draw a custom curve"); - - const ui = nodeBuilder.createUIBuilder(); - ui.addDropdown({ - componentId: "drawMode", - label: "Draw Mode", - defaultValue: "normal", - triggerUpdate: true, - }, { - options: { - "Normal": "normal", - } - }) - const getTransform = addTransformInput(ui, ["position", "rotation", "scale"]); - - ui.addColorPicker({ - componentId: "fill", - label: "Fill", - defaultValue: "#00000000", - triggerUpdate: true, - }, {}); - ui.addColorPicker({ - componentId: "stroke", - label: "Stroke", - defaultValue: "#000000", - triggerUpdate: true, - }, {}); - ui.addSlider({ - componentId: "strokeWidth", - label: "Stroke Width", - defaultValue: 1, - triggerUpdate: true, - }, { min: 0, max: 100, set: 0.1 }); - - ui.addBuffer({ - componentId: "curve", - label: "Curve Buffer", - defaultValue: { id: "", path: [] }, - triggerUpdate: true, - }, {} - ); - - addTweakability(ui); - - nodeBuilder.setUIInitializer((x) => { - return { - curve: { - id: getUUID(), - path: [ - { - control1: { x: 50, y: 10 }, - control2: { x: 10, y: 300 }, - point: { x: 0, y: 0 }, - }, - { - control1: { x: 50, y: 10 }, - control2: { x: 10, y: 300 }, - point: { x: 400, y: 400 }, - }, - { - control1: { x: 400, y: 500 }, - control2: { x: 10, y: 500 }, - point: { x: 50, y: 10 }, - }, - ] - } - }; - }); - - nodeBuilder.define(async (input, uiInput, from) => { - const canvas = { - assets: { - [uiInput["curve"]["id"]]: { - class: "asset", - type: "curve", - data: uiInput["curve"].path - } - }, - content: { - class: "clump", - nodeUUID: uiInput["tweaks"].nodeUUID, - changes: uiInput["diffs"]?.uiInputs ?? [], - transform: getTransform(uiInput), - elements: [ - { - class: "atom", - type: "curve", - assetId: uiInput["curve"].id, - - fill: colorHexToNumber(uiInput["fill"]), - fillAlpha: colorHexToAlpha(uiInput["fill"]), - stroke: colorHexToNumber(uiInput["stroke"]), - strokeAlpha: colorHexToAlpha(uiInput["stroke"]), - strokeWidth: uiInput["strokeWidth"], - } - ] - } - } - - return { res: canvas }; - }); - - nodeBuilder.setUI(ui); - - nodeBuilder.addInput("Blink matrix", "transform", "Transform"); - nodeBuilder.addOutput("Blink clump", "res", "Result"); - }, - "inputText": (context) => { - const nodeBuilder = context.instantiate("Blink/Input", "inputText"); - nodeBuilder.setTitle("Blink Text"); - nodeBuilder.setDescription("Input a Blink Text element"); - - const ui = nodeBuilder.createUIBuilder(); - ui.addTextInput({ - componentId: "text", - label: "Text", - defaultValue: "input text", - triggerUpdate: true, - }, { multiline: true }); - - ui.addDropdown({ - componentId: "fontFamily", - label: "Family", - defaultValue: "Arial", - triggerUpdate: true, - }, { - options: { - "Arial": "Arial", - "Consolas": "Consolas", - "Courier New": "Courier New", - "Georgia": "Georgia", - "Helvetica": "Helvetica", - "Impact": "Impact", - "Times New Roman": "Times New Roman", - "Trebuchet MS": "Trebuchet MS", - "Verdana": "Verdana", - } - }); - - ui.addNumberInput({ - componentId: "fontSize", - label: "Size", - defaultValue: 24, - triggerUpdate: true, - }, { step: 0.2, min: 0 }); - - ui.addDropdown({ - componentId: "fontStyle", - label: "Style", - defaultValue: "normal", - triggerUpdate: true, - }, { - options: { - "Normal": "normal", - "Italic": "italic", - } - }); - ui.addDropdown({ - componentId: "fontWeight", - label: "Weight", - defaultValue: "normal", - triggerUpdate: true, - }, { - options: { - "Normal": "normal", - "Bold": "bold", - } - }); - ui.addDropdown({ - componentId: "textAlign", - label: "Align", - defaultValue: "center", - triggerUpdate: true, - }, { - options: { - "Left": "left", - "Center": "center", - "Right": "right" - } - }); - const getTransform = addTransformInput(ui, ["position", "rotation"]); - - ui.addColorPicker({ - componentId: "fill", - label: "Fill", - defaultValue: "#000000", - triggerUpdate: true, - }, {}); - ui.addColorPicker({ - componentId: "stroke", - label: "Stroke", - defaultValue: "#00000000", - triggerUpdate: true, - }, {}); - ui.addSlider({ - componentId: "strokeWidth", - label: "Stroke Width", - defaultValue: 0, - triggerUpdate: true, - }, { min: 0, max: 100, set: 0.1 }); - - addTweakability(ui); - - nodeBuilder.define(async (input, uiInput, from) => { - const canvas = { - assets: {}, - content: { - class: "clump", - nodeUUID: uiInput["tweaks"].nodeUUID, - changes: uiInput["diffs"]?.uiInputs ?? [], - transform: getTransform(uiInput), - elements: [ - { - class: "atom", - type: "text", - - text: uiInput["text"], - - fill: colorHexToNumber(uiInput["fill"]), - stroke: colorHexToNumber(uiInput["stroke"]), - strokeWidth: uiInput["strokeWidth"], - alpha: colorHexToAlpha(uiInput["fill"]), - - fontSize: uiInput["fontSize"], - fontFamily: uiInput["fontFamily"], - fontStyle: uiInput["fontStyle"], - fontWeight: uiInput["fontWeight"], - textAlign: uiInput["textAlign"], - textBaseline: "alphabetic" - } - ] - } - } - - return { res: canvas }; - }); - - nodeBuilder.setUI(ui); - - nodeBuilder.addInput("Blink matrix", "transform", "Transform"); - nodeBuilder.addOutput("Blink clump", "res", "Result"); - }, - "matrix": (context) => { - const nodeBuilder = context.instantiate("Blink/Input", "matrix"); - nodeBuilder.setTitle("Matrix"); - nodeBuilder.setDescription("Construct a Blink matrix"); - - const ui = nodeBuilder.createUIBuilder(); - ui.addMatrixInput( - { - componentId: "matrix", - label: "Input matrix", - defaultValue: [], - triggerUpdate: true, - }, - { rows: 3, cols: 3, step: 1 } - ); - - nodeBuilder.define(async (input, uiInput, from) => { - return { - "res": uiInput["matrix"] - } - }); - - nodeBuilder.setUI(ui); - nodeBuilder.addInput("vec2", "translation", "Translation"); - nodeBuilder.addInput("number", "rotation", "Rotation"); - nodeBuilder.addInput("vec2", "scale", "Scale"); - nodeBuilder.addOutput("Blink matrix", "res", "Result"); - }, - "layer": (context) => { - const nodeBuilder = context.instantiate("Blink/Utils", "layer"); - nodeBuilder.setTitle("Layer"); - nodeBuilder.setDescription("Layer two or more Blink clumps. Clumps inputted at the beginning are placed on top in the canvas."); - - const ui = nodeBuilder.createUIBuilder(); - const getTransform = addTransformInput(ui); - ui.addSlider( - { - componentId: "opacity", - label: "Opacity", - defaultValue: 1, - triggerUpdate: true, - }, - { min: 0, max: 1, step: 0.01 } - ); - addTweakability(ui); - - nodeBuilder.define(async (input, uiInput, from) => { - // Apply filter to outermost clump - const clumps = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(n => input[`clump${n}`]).filter(c => c != null); - - // Construct assets union - const assets = {}; - clumps.forEach(c => { - Object.keys(c.assets).forEach(k => { - assets[k] = c.assets[k]; - }); - }); - - // Construct parent clump - const parent = { - class: "clump", - nodeUUID: uiInput["tweaks"].nodeUUID, - changes: uiInput["diffs"]?.uiInputs ?? [], - transform: getTransform(uiInput), - opacity: uiInput["opacity"], - elements: clumps.map(c => c.content) - } - - return { "res": { assets, content: parent } }; - }); - - nodeBuilder.setUI(ui); - nodeBuilder.addInput("Blink clump", "clump1", "Clump 1"); - nodeBuilder.addInput("Blink clump", "clump2", "Clump 2"); - nodeBuilder.addInput("Blink clump", "clump3", "Clump 3"); - nodeBuilder.addInput("Blink clump", "clump4", "Clump 4"); - nodeBuilder.addInput("Blink clump", "clump5", "Clump 5"); - nodeBuilder.addOutput("Blink clump", "res", "Result"); - }, - "repeat": (context) => { - const nodeBuilder = context.instantiate("Blink/Utils", "repeat"); - nodeBuilder.setTitle("Repeat"); - nodeBuilder.setDescription("Repeat a clump element multiple times with an offset"); - - const ui = nodeBuilder.createUIBuilder(); - ui.addSlider( - { - componentId: "repeat", - label: "Repeat", - defaultValue: 1, - triggerUpdate: true, - }, - { min: 0, max: 50, step: 1 } - ); - ui.addNumberInput( - { - componentId: "offsetX", - label: "Offset X", - defaultValue: 0, - triggerUpdate: true, - }, { step: 1 } - ); - ui.addNumberInput( - { - componentId: "offsetY", - label: "Offset Y", - defaultValue: 0, - triggerUpdate: true, - }, { step: 1 } - ); - ui.addNumberInput( - { - componentId: "offsetRot", - label: "Rotation Offset", - defaultValue: 0, - triggerUpdate: true, - }, { step: 1 } - ); - const getTransform = addTransformInput(ui, ["position"]); - ui.addSlider( - { - componentId: "opacity", - label: "Opacity", - defaultValue: 1, - triggerUpdate: true, - }, - { min: 0, max: 1, step: 0.01 } - ); - addTweakability(ui); - - nodeBuilder.define(async (input, uiInput, from) => { - const clump = input["clump"]; - - if (clump == null) return { "res": null }; - - const assets = clump.assets; - - // Construct parent clump - const parent = { - class: "clump", - nodeUUID: uiInput["tweaks"].nodeUUID, - changes: uiInput["diffs"]?.uiInputs ?? [], - transform: getTransform(uiInput), - opacity: uiInput["opacity"], - elements: Array.from({ length: uiInput["repeat"] }, (_, i) => ({ - ...clump.content, - transform: { - ...clump.content.transform, - position: { - x: clump.content.transform.position.x + i * uiInput["offsetX"], - y: clump.content.transform.position.y + i * uiInput["offsetY"], - }, - rotation: clump.content.transform.rotation + i * uiInput["offsetRot"], - } - })), - } - - return { "res": { assets, content: parent } }; - }); - - nodeBuilder.setUI(ui); - nodeBuilder.addInput("Blink clump", "clump", "Clump"); - nodeBuilder.addOutput("Blink clump", "res", "Result"); - }, - "particle": (context) => { - const nodeBuilder = context.instantiate("Blink/Utils", "particle"); - nodeBuilder.setTitle("Particle"); - nodeBuilder.setDescription("Scatter a clump randomly within a fixed region"); - - const ui = nodeBuilder.createUIBuilder(); - ui.addSlider( - { - componentId: "count", - label: "Count", - defaultValue: 1, - triggerUpdate: true, - }, - { min: 0, max: 50, step: 1 } - ); - ui.addNumberInput( - { - componentId: "boundW", - label: "Bounds W", - defaultValue: 400, - triggerUpdate: true, - }, { min: 0, step: 1 } - ); - ui.addNumberInput( - { - componentId: "boundH", - label: "Bounds H", - defaultValue: 400, - triggerUpdate: true, - }, { min: 0, step: 1 } - ); - ui.addNumberInput( - { - componentId: "boundRot", - label: "Rotation Bound", - defaultValue: 0, - triggerUpdate: true, - }, { step: 1 } - ); - const getTransform = addTransformInput(ui, ["position", "rotation", "scale"]); - ui.addSlider( - { - componentId: "opacity", - label: "Opacity", - defaultValue: 1, - triggerUpdate: true, - }, - { min: 0, max: 1, step: 0.01 } - ); - ui.addSlider( - { - componentId: "seed", - label: "Seed", - defaultValue: 1, - triggerUpdate: true, - }, - { min: 0, max: 1000, step: 1 } - ); - addTweakability(ui); - - - nodeBuilder.define(async (input, uiInput, from) => { - const clump = input["clump"]; - - if (clump == null) return { "res": null }; - - const assets = clump.assets; - - let seed = uiInput["seed"]; - function random() { - var x = Math.sin(seed++) * 10000; - return x - Math.floor(x); - } - - // Construct parent clump - const parent = { - class: "clump", - nodeUUID: uiInput["tweaks"].nodeUUID, - changes: uiInput["diffs"]?.uiInputs ?? [], - transform: getTransform(uiInput), - opacity: uiInput["opacity"], - elements: Array.from({ length: uiInput["count"] }, (_, i) => ({ - ...clump.content, - transform: { - ...clump.content.transform, - position: { - x: clump.content.transform.position.x + (2*random()-1) * uiInput["boundW"], - y: clump.content.transform.position.y + (2*random()-1) * uiInput["boundH"], - }, - rotation: clump.content.transform.rotation + (2*random()-1) * uiInput["boundRot"], - } - })), - } - - return { "res": { assets, content: parent } }; - }); - - nodeBuilder.setUI(ui); - nodeBuilder.addInput("Blink clump", "clump", "Clump"); - nodeBuilder.addOutput("Blink clump", "res", "Result"); - }, - "filter": (context) => { - const nodeBuilder = context.instantiate("Blink/Utils", "filter"); - nodeBuilder.setTitle("Filter"); - nodeBuilder.setDescription("Construct a Blink matrix"); - - const ui = nodeBuilder.createUIBuilder(); - ui.addDropdown({ - componentId: "filter", - label: "Filter", - defaultValue: "blur", - triggerUpdate: true, - }, { - options: { - "Blur": "blur", - "Noise": "noise", - "Bloom": "bloom", - "Grayscale": "grayscale", - "Bevel": "bevel", - "Outline": "outline", - "Dot": "dot", - "Crt": "crt", - "Emboss": "emboss", - "Bulge": "bulge", - "Glitch": "glitch", - "Zoomblur": "zoomblur", - "Twist": "twist", - } - }) - .addSlider( - { - componentId: "strength", - label: "Strength", - defaultValue: 10, - triggerUpdate: true, - }, - { min: 0, max: 100, set: 0.1 } - ) - .addSlider( - { - componentId: "amount", - label: "Amount", - defaultValue: 10, - triggerUpdate: true, - }, - { min: 0, max: 100, set: 0.1 } - ); - - nodeBuilder.define(async (input, uiInput, from) => { - // Apply filter to outermost clump - const canvas = input["clump"]; - - if (!canvas.content.filters) canvas.content.filters = []; - canvas.content.filters.push({ - class: "filter", - type: uiInput["filter"], - params: [uiInput["strength"], uiInput["amount"]], - }); - - return { "res": canvas }; - }); - - nodeBuilder.setUI(ui); - nodeBuilder.addInput("Blink clump", "clump", "Clump"); - nodeBuilder.addOutput("Blink clump", "res", "Result"); - }, - "mask": (context) => { - const nodeBuilder = context.instantiate("Blink/Utils", "mask"); - nodeBuilder.setTitle("Mask"); - nodeBuilder.setDescription("Mask a Blink clump with another clump"); - - const ui = nodeBuilder.createUIBuilder(); - ui.addRadio({ - componentId: "maskEnabled", - label: "Enabled", - defaultValue: "enabled", - triggerUpdate: true, - }, { - options: { - "Enabled": "enabled", - "Disabled": "disabled", - } - }) - - nodeBuilder.define(async (input, uiInput, from) => { - // Apply mask to outermost clump - const canvas = input["clump"]; - if (uiInput["maskEnabled"] === "enabled" && input["mask"] != null) { - canvas.content.mask = input["mask"].content; - } - - return { "res": canvas }; - }); - - nodeBuilder.setUI(ui); - nodeBuilder.addInput("Blink clump", "clump", "Clump"); - nodeBuilder.addInput("Blink clump", "mask", "Mask"); - nodeBuilder.addOutput("Blink clump", "res", "Result"); - }, - "canvasConfig": (context) => { - const nodeBuilder = context.instantiate("Blink/Utils", "canvasConfig"); - nodeBuilder.setTitle("Canvas Config"); - nodeBuilder.setDescription("Configure the Blink canvas"); - - const ui = nodeBuilder.createUIBuilder(); - ui.addTextInput({ - componentId: "exportName", - label: "Export Name", - defaultValue: "Blink Export", - triggerUpdate: true, - }, {}); - - ui.addNumberInput( - { - componentId: "canvasW", - label: "Canvas Width", - defaultValue: 1920, - triggerUpdate: true, - }, - { min: 0, step: 1 } - ); - ui.addNumberInput( - { - componentId: "canvasH", - label: "Canvas Height", - defaultValue: 1080, - triggerUpdate: true, - }, - { min: 0, step: 1 } - ); - ui.addColorPicker({ - componentId: "canvasColor", - label: "Canvas Background", - defaultValue: "#ffffffff", - triggerUpdate: true, - }, {}) - - nodeBuilder.define(async (input, uiInput, from) => { - // Apply mask to outermost clump - const canvas = { - ...input["clump"], - config: { - canvasDims: { w: uiInput["canvasW"], h: uiInput["canvasH"] }, - canvasColor: colorHexToNumber(uiInput["canvasColor"]), - canvasAlpha: colorHexToAlpha(uiInput["canvasColor"]), - - exportName: uiInput["exportName"] - } - } - - return { "canvas": canvas }; - }); - - nodeBuilder.setUI(ui); - nodeBuilder.addInput("Blink clump", "clump", "Clump"); - nodeBuilder.addOutput("Blink canvas", "canvas", "Canvas"); - } -}; -const commands = {}; -const tiles = {}; - -function init(context) { - - const configurator = (data) => { - return { - displayType: "webview", - props: { - renderer: `${context.pluginId}/blinkRenderer`, - media: null - }, - contentProp: "media" - }; - } - - const clumpTypeBuilder = context.createTypeclassBuilder("Blink clump"); - clumpTypeBuilder.setDisplayConfigurator(configurator); - - // clumpTypeBuilder.setToConverters({ - // "image": (value) => ({}) - // }); - // clumpTypeBuilder.setFromConverters({ - // "image": (value) => ({}) - // }); - - const canvasTypeBuilder = context.createTypeclassBuilder("Blink canvas"); - canvasTypeBuilder.setDisplayConfigurator(configurator); -} - -module.exports = { - nodes, - commands, - tiles, - init -}; \ No newline at end of file diff --git a/blix-plugins/blink/src/media/bird.png b/blix-plugins/blink/src/media/bird.png deleted file mode 100644 index 72e46e3d..00000000 Binary files a/blix-plugins/blink/src/media/bird.png and /dev/null differ diff --git a/blix-plugins/blink/src/media/blueArrow.png b/blix-plugins/blink/src/media/blueArrow.png deleted file mode 100644 index b6a5b189..00000000 Binary files a/blix-plugins/blink/src/media/blueArrow.png and /dev/null differ diff --git a/blix-plugins/blink/src/media/jake.png b/blix-plugins/blink/src/media/jake.png deleted file mode 100644 index 4efab718..00000000 Binary files a/blix-plugins/blink/src/media/jake.png and /dev/null differ diff --git a/blix-plugins/blink/src/media/lighthouse.jpg b/blix-plugins/blink/src/media/lighthouse.jpg deleted file mode 100644 index 9c1a8da3..00000000 Binary files a/blix-plugins/blink/src/media/lighthouse.jpg and /dev/null differ diff --git a/blix-plugins/blink/src/media/perspective.jpg b/blix-plugins/blink/src/media/perspective.jpg deleted file mode 100644 index 99cd097b..00000000 Binary files a/blix-plugins/blink/src/media/perspective.jpg and /dev/null differ diff --git a/blix-plugins/blink/src/media/pineRiver.png b/blix-plugins/blink/src/media/pineRiver.png deleted file mode 100644 index adae60eb..00000000 Binary files a/blix-plugins/blink/src/media/pineRiver.png and /dev/null differ diff --git a/blix-plugins/blink/src/media/trail.jpg b/blix-plugins/blink/src/media/trail.jpg deleted file mode 100644 index 961e0a9a..00000000 Binary files a/blix-plugins/blink/src/media/trail.jpg and /dev/null differ diff --git a/blix-plugins/blink/src/tsconfig.json b/blix-plugins/blink/src/tsconfig.json deleted file mode 100644 index f1e824ce..00000000 --- a/blix-plugins/blink/src/tsconfig.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "compilerOptions": { - "module": "CommonJS", - "target": "es5", - "declaration": true, - "outDir": ".", - "strict": true, - "esModuleInterop": true, - "rootDir": "..", - }, - "include": ["main.cts"], - "exclude": [] -} diff --git a/blix-plugins/blink/svelte.config.js b/blix-plugins/blink/svelte.config.js deleted file mode 100644 index 137dd0d6..00000000 --- a/blix-plugins/blink/svelte.config.js +++ /dev/null @@ -1,5 +0,0 @@ -import sveltePreprocess from 'svelte-preprocess'; - -export default { - preprocess: sveltePreprocess({ sourceMap: true }), -} \ No newline at end of file diff --git a/blix-plugins/blink/tsconfig.json b/blix-plugins/blink/tsconfig.json deleted file mode 100644 index c7ca23af..00000000 --- a/blix-plugins/blink/tsconfig.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "extends": "@tsconfig/svelte/tsconfig.json", - "compilerOptions": { - "baseUrl": ".", - "target": "es2017", - "moduleResolution": "node", - - /** - Svelte Preprocess cannot figure out whether you have a value or a type, so tell TypeScript - to enforce using `import type` instead of `import` for Types. - */ - // "verbatimModuleSyntax": true, - - "types": ["node", "svelte", "jest"], - /** - To have warnings/errors of the Svelte compiler at the correct position, - enable source maps by default. - */ - "sourceMap": true, - - "strict": false, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - }, - - "include": ["webview/**/*", "global.d.ts"], - "exclude": ["node_modules"], -} diff --git a/blix-plugins/blink/webview/App.svelte b/blix-plugins/blink/webview/App.svelte deleted file mode 100644 index 3121cc8e..00000000 --- a/blix-plugins/blink/webview/App.svelte +++ /dev/null @@ -1,293 +0,0 @@ - - - -
- - -
- -
- {#if showDebug} - - {/if} - -
- -
-
- - \ No newline at end of file diff --git a/blix-plugins/blink/webview/Debug.svelte b/blix-plugins/blink/webview/Debug.svelte deleted file mode 100644 index 5c71eb83..00000000 --- a/blix-plugins/blink/webview/Debug.svelte +++ /dev/null @@ -1,67 +0,0 @@ - - - -{#if data != null} - - {#if data["assets"]} -
- {#each Object.keys(data.assets) as assetId} - {#if data.assets[assetId].type === "image"} - - {/if} - {/each} -
- - - - {:else if data["class"] === "clump"} - CLUMP [{Math.round(data.transform.position.x)}, {Math.round( - data.transform.position.y - )}] - {#if data?.filters} - <{#each data.filters as filter}{filter.type}{/each}> - {/if} - - MASK: {data.mask} - -
    - {#each data.elements as element} -
  • - {/each} -
-
- - {:else if data["class"] === "atom"} - ATOM {data["type"]}: {#if data["type"] === "image"} - image({data.src}) - {:else if data["type"] === "shape"} - shape({data.shape}, {JSON.stringify( - data.bounds - )}) - {:else if data["type"] === "text"} - text({data.text}) - {:else if data["type"] === "paint"} - paint({data.uuid}) - {:else if data["type"] === "blob"} - blob() - {/if} - {/if} -
-{/if} - - diff --git a/blix-plugins/blink/webview/app.ts b/blix-plugins/blink/webview/app.ts deleted file mode 100644 index b0ac35b1..00000000 --- a/blix-plugins/blink/webview/app.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { writable } from 'svelte/store'; -import App from './App.svelte'; -import { type BlinkCanvas } from './types'; - -const media = writable({ - assets: {}, - content: null -}); - -let sender = (message: string, data: any) => {}; - -const send = (message: string, data: any) => { - sender(message, data); -} - -const app = new App({ - target: document.body, - props: { media, send }, -}); - -// Assert window.api is loaded - -window.addEventListener("DOMContentLoaded", () => { - window.api.on("mediaChanged", (newMedia: any) => { - if (newMedia.assets && newMedia.content) { - media.set(newMedia); - } - }); - - // To send a message back to main renderer - sender = (message: string, data: any) => { - window.api.send(message, data); - } -}); - - -// window.cache.write("test", new Blob([])); - -export { app }; \ No newline at end of file diff --git a/blix-plugins/blink/webview/atom.ts b/blix-plugins/blink/webview/atom.ts deleted file mode 100644 index d58b68b2..00000000 --- a/blix-plugins/blink/webview/atom.ts +++ /dev/null @@ -1,142 +0,0 @@ -import * as PIXI from 'pixi.js'; -import type { Asset, Atom, CurveAsset, CurveAtom, CurvePoint, ImageAtom, PaintAtom, ShapeAtom, TextAtom } from "./types"; -import { diffAtom, diffCurveAtom, diffImageAtom, diffPaintAtom, diffShapeAtom, diffTextAtom } from './diff'; -import { type HierarchyAtom, randomId } from './render'; - -export function renderAtom(assets: { [key: string]: Asset }, prevAssets: { [key: string]: Asset } | undefined, atom: Atom, prevAtom: HierarchyAtom | undefined, textures: { [key: string]: PIXI.Texture }): { - pixiAtom: PIXI.Container, - changed: boolean // Whether the pixiClump is a different PIXI object than before -} { - console.log(">>>---------------------------------"); - if (!atom) return null; - - const atomsDiffer = diffAtom(atom, prevAtom); - - switch (atom.type) { - case "image": - const imageDiff = atomsDiffer || prevAssets == null || diffImageAtom(atom, prevAtom as ImageAtom, assets, prevAssets); - if (!imageDiff) { - return { pixiAtom: prevAtom.container, changed: false }; - } - - if (assets[atom.assetId] && assets[atom.assetId].type === "image") { - const textureId = assets[atom.assetId].data as string; - const sprite = PIXI.Sprite.from(textures[textureId]); - - sprite.anchor.x = 0.5; - sprite.anchor.y = 0.5; - - sprite.name = `ImageSprite(${randomId()})`; - // console.log("DESTROY PREV ATOM"); - prevAtom?.container?.destroy(); - return { pixiAtom: sprite, changed: true }; - } - - return { pixiAtom: null, changed: true }; - - case "shape": - const shapeDiff = atomsDiffer || diffShapeAtom(atom, prevAtom as ShapeAtom); - if (!shapeDiff) { - return { pixiAtom: prevAtom.container, changed: false }; - } - - const shapeContainer = new PIXI.Container(); - const shape = new PIXI.Graphics(); - // shape.lineStyle(1, 0xf43e5c, 0.5); - shape.beginFill(atom.fill, atom.fillAlpha); - shape.lineStyle(atom.strokeWidth, atom.stroke, atom.strokeAlpha); - const halfBounds = { w: atom.bounds.w / 2, h: atom.bounds.h / 2 }; - - switch (atom.shape) { - case "rectangle": - shape.drawRect(-halfBounds.w, -halfBounds.h, atom.bounds.w, atom.bounds.h); - break; - case "ellipse": - shape.drawEllipse(0, 0, halfBounds.w, halfBounds.h); - break; - case "triangle": - shape.drawPolygon([-halfBounds.w, halfBounds.h, halfBounds.w, halfBounds.h, 0, -halfBounds.h]); - break; - } - shape.endFill(); - - shapeContainer.addChild(shape); - shapeContainer.name = `ShapeContainer(${randomId()})`; - - return { pixiAtom: shapeContainer, changed: true }; - - case "text": - const textDiff = atomsDiffer || diffTextAtom(atom, prevAtom as TextAtom); - if (!textDiff) { - return { pixiAtom: prevAtom.container, changed: false }; - } - - const textContainer = new PIXI.Container(); - const text = new PIXI.Text(atom.text, { - fill: atom.fill, - stroke: atom.stroke, - strokeThickness: atom.strokeWidth, - - fontFamily: atom.fontFamily, - fontSize: atom.fontSize, - fontStyle: atom.fontStyle, - fontWeight: atom.fontWeight, - - align: atom.textAlign, - textBaseline: atom.textBaseline, - }); - - textContainer.addChild(text); - textContainer.name = `TextContainer(${randomId()})`; - - textContainer.alpha = atom.alpha; - - return { pixiAtom: textContainer, changed: true }; - - case "paint": - const paintDiff = atomsDiffer || diffPaintAtom(atom, prevAtom as PaintAtom); - if (!paintDiff) { - return { pixiAtom: prevAtom.container, changed: false }; - } - - return { pixiAtom: null, changed: true }; - - case "curve": - const curveDiff = atomsDiffer || diffCurveAtom(atom, prevAtom as CurveAtom, assets, prevAssets); - if (!curveDiff) { - return { pixiAtom: prevAtom.container, changed: false }; - } - - const curveContainer = new PIXI.Container(); - const curve = new PIXI.Graphics(); - - curve.beginFill(atom.fill, atom.fillAlpha); - curve.lineStyle(atom.strokeWidth, atom.stroke, atom.strokeAlpha); - - if (assets[atom.assetId] && assets[atom.assetId].type === "curve") { - const path = assets[atom.assetId].data as CurvePoint[]; - - if (path.length > 0) { - curve.moveTo(path[0].point.x, path[0].point.y); - - for (let i = 1; i < path.length; i++) { - curve.bezierCurveTo( - path[i].control1.x, - path[i].control1.y, - path[i].control2.x, - path[i].control2.y, - path[i].point.x, - path[i].point.y - ); - } - } - } - - curve.endFill(); - - curveContainer.addChild(curve); - curveContainer.name = `CurveContainer(${randomId()})`; - - return { pixiAtom: curveContainer, changed: true }; - } -} \ No newline at end of file diff --git a/blix-plugins/blink/webview/diff.ts b/blix-plugins/blink/webview/diff.ts deleted file mode 100644 index f99274ab..00000000 --- a/blix-plugins/blink/webview/diff.ts +++ /dev/null @@ -1,175 +0,0 @@ -import type { HierarchyAtom, HierarchyClump } from "./render"; -import type { - Asset, - Atom, - BlinkCanvasConfig, - Clump, - CurveAtom, - Filter, - ImageAtom, - PaintAtom, - ShapeAtom, - TextAtom, - Transform, -} from "./types"; - -export type ClumpDiff = "name" | "transform" | "opacity" | "filters" | "mask"; - -export function diffClump(h1: Clump, h2: HierarchyClump) { - const diffs = new Set(); - if (h1 == null && h2 == null) return new Set([]); // Vacuous case - if (h1 == null || h2 == null) - return new Set(["name", "transform", "opacity", "filters", "mask"]); - - // Diff name - if (h1.name !== h2.name) { - diffs.add("name"); - } - - // Diff transform - if (h1.transform == null && h2.transform == null) { - diffs.add("transform"); - } else if (diffTransform(h1.transform, h2.transform).length > 0) { - diffs.add("transform"); - } - - // Diff opacity - if (h1.opacity !== h2.opacity) { - diffs.add("opacity"); - } - - // Diff filters - if (diffFilters(h1.filters, h2.filters)) { - diffs.add("filters"); - } - - // Diff mask - if (diffClump(h1.mask, h2.mask as HierarchyClump).size > 0) { - diffs.add("mask"); - } - - return diffs; -} - -function diffTransform(t1: Transform, t2: Transform) { - const diffs = []; - if (t1?.position?.x !== t2?.position?.x || t1?.position?.y !== t2?.position?.y) - diffs.push("position"); - if (t1?.rotation !== t2?.rotation) diffs?.push("rotation"); - if (t1?.scale?.x !== t2?.scale?.x || t1?.scale?.y !== t2?.scale?.y) diffs?.push("scale"); - if (t1?.origin !== t2?.origin) diffs?.push("origin"); - return diffs; -} - -// Returns true if the filters differ in some way -function diffFilters(f1s: Filter[], f2s: Filter[]) { - if (f1s == null && f2s == null) return false; - if (f1s == null || f2s == null) return true; - - const maxLen = Math.max(f1s.length, f2s.length); - - for (let f = 0; f < maxLen; f++) { - // Diff filter - if (f1s[f] && f2s[f]) { - // Diff types - if (f1s[f].type !== f2s[f].type) return true; - - // Diff params - const maxParamsLen = Math.max(f1s[f].params.length, f2s[f].params.length); - for (let p = 0; p < maxParamsLen; p++) { - if (f1s[f].params[p] !== f2s[f].params[p]) { - return true; - } - } - } else { - return true; - } - } - - return false; -} - -// Returns true if the atoms differ in some way -export function diffAtom(a1: Atom, a2: HierarchyAtom) { - if (a1 == null && a2 == null) return false; - if (a1 == null || a2 == null) return true; - - if (a1.type !== a2.type) return true; - return false; -} - -// TODO: Pass in `assets` later on, so that we can diff on asset.data instead of assetId -// TODO: For now this just returns a boolean, but later on we'll return a more fine-grained diff -export function diffImageAtom(a1: ImageAtom, a2: ImageAtom, assets1: { [key: string]: Asset }, assets2: { [key: string]: Asset } ) { - if (a1.assetId !== a2.assetId) return true; - if (assets1[a1.assetId].type !== assets2[a2.assetId].type) return true; - if (assets1[a1.assetId].data !== assets2[a2.assetId].data) return true; - return false; -} - -export function diffCurveAtom(a1: CurveAtom, a2: CurveAtom, assets1: { [key: string]: Asset }, assets2: { [key: string]: Asset }) { - if (a1.assetId !== a2.assetId) return true; - if (assets1[a1.assetId].type !== assets2[a2.assetId].type) return true; - if (assets1[a1.assetId].data !== assets2[a2.assetId].data) return true; - - if (a1.fill !== a2.fill) return true; - if (a1.fillAlpha !== a2.fillAlpha) return true; - if (a1.stroke !== a2.stroke) return true; - if (a1.strokeAlpha !== a2.strokeAlpha) return true; - if (a1.strokeWidth !== a2.strokeWidth) return true; - return false; -} - -export function diffShapeAtom(a1: ShapeAtom, a2: ShapeAtom) { - if (a1.shape !== a2.shape) return true; - if (a1.bounds?.w !== a2.bounds?.w || a1.bounds?.h !== a2.bounds?.h) return true; - if (a1.fill !== a2.fill) return true; - if (a1.fillAlpha !== a2.fillAlpha) return true; - if (a1.stroke !== a2.stroke) return true; - if (a1.strokeAlpha !== a2.strokeAlpha) return true; - if (a1.strokeWidth !== a2.strokeWidth) return true; - return false; -} - -export function diffTextAtom(a1: TextAtom, a2: TextAtom) { - if (a1.text !== a2.text) return true; - if (a1.fill !== a2.fill) return true; - if (a1.stroke !== a2.stroke) return true; - if (a1.strokeWidth !== a2.strokeWidth) return true; - if (a1.fontSize !== a2.fontSize) return true; - if (a1.fontFamily !== a2.fontFamily) return true; - if (a1.fontStyle !== a2.fontStyle) return true; - if (a1.fontWeight !== a2.fontWeight) return true; - if (a1.textAlign !== a2.textAlign) return true; - if (a1.textBaseline !== a2.textBaseline) return true; - return false; -} - -export function diffPaintAtom(a1: PaintAtom, a2: PaintAtom) { - if (a1.uuid !== a2.uuid) return true; - return false; -} - -export type CanvasConfigDiff = "canvasBlock" | "exportName"; - -export function diffCanvasConfig(c1: BlinkCanvasConfig, c2: BlinkCanvasConfig) { - const diffs = new Set(); - if (c1 == null && c2 == null) return new Set([]); // Vacuous case - if (c1 == null || c2 == null) - return new Set(["canvasBlock", "exportName"]); - - if ( - c1.canvasDims.w !== c2.canvasDims.w || - c1.canvasDims.h !== c2.canvasDims.h || - c1.canvasColor !== c2.canvasColor || - c1.canvasAlpha !== c2.canvasAlpha - ) { - diffs.add("canvasBlock"); - } - - if (c1.exportName !== c2.exportName) { - diffs.add("exportName"); - } - - return diffs; -} \ No newline at end of file diff --git a/blix-plugins/blink/webview/filter.ts b/blix-plugins/blink/webview/filter.ts deleted file mode 100644 index e8fbe7e1..00000000 --- a/blix-plugins/blink/webview/filter.ts +++ /dev/null @@ -1,41 +0,0 @@ -import * as PIXI from 'pixi.js'; -import { type Filter, getPixiFilter } from './types'; -import { randomId } from './render'; - -const paddedFilters = new Set(["blur", "outline", "twist"]); - -// Apply a series of filters and flatten the result to a sprite. -// This is done so that the filters are applied evenly regardless of scaling. -export function applyFilters(blink: PIXI.Application, content: PIXI.Container, filters: Filter[]) { - // `renderPadding` is necessary for filters like - // blur that spread beyond the bounds of the sprite - const renderPadding = filters.some(v => paddedFilters.has(v.type)) ? 100 : 0; - - // Normalize offset to fit within renderTexture - const { x: bx, y: by, width: bw, height: bh } = content.getLocalBounds(); - content.transform.position.x = -bx + renderPadding; - content.transform.position.y = -by + renderPadding; - - // Apply filters - content.filters = filters.map(getPixiFilter); - - // Render to texture - const renderTexture = PIXI.RenderTexture.create({ - width: bw + 2 * renderPadding, - height: bh + 2 * renderPadding, - }); - console.log("RENDER TEXTURE", renderTexture); - blink.renderer.render(content, { renderTexture: renderTexture }); - - content.filters = null; - content.transform.setFromMatrix(new PIXI.Matrix()); - - // Create flattened sprite - const renderSprite = new PIXI.Sprite(renderTexture); - renderSprite.name = `FilterSprite(${randomId()})` - // renderSprite.anchor.x = 0.5; - // renderSprite.anchor.y = 0.5; - renderSprite.setTransform(bx - renderPadding, by - renderPadding); - - return renderSprite; -} \ No newline at end of file diff --git a/blix-plugins/blink/webview/render.ts b/blix-plugins/blink/webview/render.ts deleted file mode 100644 index 07b92ea0..00000000 --- a/blix-plugins/blink/webview/render.ts +++ /dev/null @@ -1,506 +0,0 @@ -import * as PIXI from "pixi.js"; -import { - getPixiFilter, - type Atom, - type Clump, - type BlinkCanvas, - type WindowWithApis, -} from "./types"; -import { Viewport } from "pixi-viewport"; -import { createBoundingBox } from "./select"; -import { renderAtom } from "./atom"; -import { applyFilters } from "./filter"; -import { diffClump } from "./diff"; -import { tick } from "svelte"; - -export function randomId() { - return Math.random().toString(36).slice(2, 6); -} - -// let prevMedia = null; // TODO: Replace with DiffDial - -// Utility type to override properties of T with properties of R -type Override = { [P in Exclude]: T[P] } & R; - -type HierarchyData = { container: PIXI.Container }; - -export type HierarchyCanvas = Override; -export type HierarchyClump = Override & - HierarchyData; -export type HierarchyAtom = Atom & HierarchyData; -// type Clumps = { [key: string]: PIXI.Container }; - -type SelectionState = { - uuid: string, // NodeUUID of selected clump - container: PIXI.Container, - dragging: boolean, - prevMousePos: PIXI.Point -}; - -const MAX_CHILDREN_IN_CLUMP = 50; - -let selection: SelectionState = null; - -let oldSceneStructure = ""; -let sceneStructure = "_"; - -let boundingBox: PIXI.Container = null; -let scene: PIXI.Container; - -let hierarchy: HierarchyCanvas | undefined = undefined; - -const textures: { [key: string]: PIXI.Texture } = {} - -export async function renderScene( - blink: PIXI.Application, - canvas: BlinkCanvas, - viewport: Viewport, - send: (message: string, data: any) => void -): Promise<{ success: boolean; scene: PIXI.Container }> { - console.log("===================================="); - - if (!canvas || !canvas.content) return { success: false, scene: null }; - if (!scene) { - scene = new PIXI.Container(); - scene.name = "Blink Scene"; - viewport.addChild(scene); - } - - if (!boundingBox) { - //===== CREATE BOUNDING BOX =====// - boundingBox = new PIXI.Container(); - boundingBox.name = "boundingBox"; - - window.addEventListener("keydown", (e: KeyboardEvent) => { - if (e.key === "Escape") { - selection = null; - } - }); - - blink.stage.addChild(boundingBox); - - blink.ticker.add(() => { - if (boundingBox.children) { - boundingBox.removeChildren(); - } - - if (selection?.uuid) { - boundingBox.addChild(createBoundingBox(selection.container.transform.localTransform, selection.container.getLocalBounds(), viewport, selection.container.transform.pivot)); - // boundingBox.addChild(createBoundingBox(selection.container.transform.worldTransform, selection.container.getBounds(), viewport)); - } - }); - } - - //===== PRELOAD IMAGE ASSETS =====// - const imgPromises = []; - for (let assetId in canvas.assets) { - if (canvas.assets[assetId].type === "image") { - const cacheId = canvas.assets[assetId].data as string; - if (textures[cacheId] != null) continue; - - // Get cache object - imgPromises.push(new Promise(async (resolve, reject) => { - const blob: Blob = await (window as WindowWithApis).cache.get(cacheId); - const url = window.URL.createObjectURL(blob); - console.log("BLOB", blob); - console.log("URL", url); - - // To get a list of all available loadParsers: - // console.log("PARSERS", PIXI.Assets.loader.parsers); - - // Also make note of: - // PIXI.Assets.add(cacheId, url); - // await PIXI.Assets.loader.load(url); - - // NOTE: - // There is currently a bug with Pixi.js v5.2.4 where Blob URLs fail to load - // on the first frame, and awaiting the load() function has no effect. - // See: [https://github.com/pixijs/pixijs/issues/9568] - - // This issue has been fixed in Pixi.js v5.3.1 - // See: [https://github.com/pixijs/pixijs/pull/9634] - // However, v5.3.1 is currently incompatible with the pixi-viewport plugin, - // So we'll have to use the below setTimeout() temp fix until pixi-viewport is upgraded. - - // PREFERABLE IMPLEMENTATION AFTER UPGRADE: - // const asset = await PIXI.Assets.load({ src: url }); - // textures[cacheId] = url; - - textures[cacheId] = PIXI.Texture.from(url); - resolve(); - })); - } - } - - // Construct clump hierarchy - await Promise.all(imgPromises); - if (imgPromises.length > 0) { - await new Promise((resolve, reject) => setTimeout(resolve, 50)); - } - - // Reset selection - // selection = null; - - const { pixiClump, changed } = renderClump( - blink, - 0, - canvas.content, - hierarchy?.content, - canvas, - hierarchy, - viewport, - send - ); - - // Update hierarchy - hierarchy = { - assets: canvas.assets, - config: undefined, - content: { - ...canvas.content, - container: pixiClump, - } as HierarchyClump, - }; - - if (hierarchy.content.container != null && changed) { - scene.addChild(hierarchy.content.container); - } - - return { success: true, scene }; -} - -export function renderCanvas(blink: PIXI.Application, root: Clump) {} - -function renderClump( - blink: PIXI.Application, - index: number, - clump: Clump, - prevClump: HierarchyClump | undefined, - canvas: BlinkCanvas, - prevCanvas: BlinkCanvas, - viewport: Viewport, - send: (message: string, data: any) => void -): { - pixiClump: PIXI.Container; - changed: boolean; // Whether the pixiClump is a different PIXI object than before -} { - if (!clump) { - console.log("------------------------------------"); - return { pixiClump: null, changed: prevClump != null }; - } - console.log("PREVCLUMP EXISTS", prevClump?.container != null) - - //========== DIFF CLUMP VS HIERARCHY ==========// - const diffs = diffClump(clump, prevClump); - - //========== CREATE CHILD ELEMENTS ==========// - let childChanged = false; - const children: { changed: boolean, child: PIXI.Container }[] = []; - const hierarchyElements = []; - - if (clump.elements) { - for (let i = 0; i < MAX_CHILDREN_IN_CLUMP; i++) { - const child = clump.elements[i]; - const prevChild = prevClump?.elements != null && prevClump.elements[i]; - - if (child == null) { - //===== REMOVED CHILD =====// - if (prevChild) { - console.log("----> DELETED CHILD", i); - childChanged = true; - children.push({ changed: true, child: null }); - } - } - else if (child.class === "clump") { - //===== CHILD CLUMP =====// - const { pixiClump, changed } = renderClump( - blink, - i, - child as HierarchyClump, - (prevChild?.class === "clump" ? prevChild : undefined) as HierarchyClump, - canvas, - prevCanvas, - viewport, - send - ); - - // Construct hierarchy clump - const hierarchyClump = child as HierarchyClump; - hierarchyClump.container = pixiClump; - hierarchyElements.push(hierarchyClump); - - childChanged ||= changed; - - if (pixiClump != null) { - children.push({ changed, child: pixiClump }); - // content.addChild(pixiClump); - } - - } else if (child.class === "atom") { - //===== CHILD ATOM =====// - const { pixiAtom, changed } = renderAtom( - canvas.assets, - prevCanvas?.assets, - child, - (prevChild?.class === "atom" ? prevChild : undefined) as HierarchyAtom, - textures - ); - - // Construct hierarchy atom - const hierarchyAtom = child as HierarchyAtom; - hierarchyAtom.container = pixiAtom; - hierarchyElements.push(hierarchyAtom); - - childChanged ||= changed; - - if (pixiAtom != null) { - children.push({ changed, child: pixiAtom }); - // content.addChild(pixiAtom); - } - } - } - console.log("-> CHILDREN", children); - } - - //========== OBTAIN CLUMP CONTAINER ==========// - let resClump: PIXI.Container; - let content: PIXI.Container; - const newContainer = prevClump?.container == null; - - // Create resClump - if (newContainer) { - resClump = new PIXI.Container(); - resClump.name = `Clump[${index}](${randomId()})`; - // resClump.sortableChildren = true; - addInteractivity(resClump, clump, viewport, send); - - } else { resClump = prevClump.container; } - - // Add content - const prevContent = findChild(resClump, "content"); - if (prevContent == null) { - content = new PIXI.Container(); - content.name = `content(${randomId()})`; - content.sortableChildren = true; - - resClump.addChild(content); - } else { content = prevContent as PIXI.Container; } - content.visible = true; - - console.log(`==> ${newContainer ? "" : "NO "}NEW RESCLUMP (${resClump.name.split("(")[1].slice(0, 4)})`); - - if (childChanged || newContainer || diffs.has("filters")) { - //========== BUILD CONTENT ==========// - - //Add children to content - if (true || newContainer) { - content.removeChildren(); - for (let i = 0; i < children.length; i++) { - if (children[i].child == null) continue; - children[i].child.zIndex = children.length - i; - console.log("=====> ADD CHILD", i, children[i].child.name); - content.addChild(children[i].child); - } - } else { - // TODO: Fix this so it only replaces changed children / removes excess - // Above is a temp fix that removes all children and adds everything back - - for (let i = 0; i < children.length; i++) { - children[i].child.zIndex = children.length - i; - // Only update if child changed - if (children[i].changed) { - console.log("=====> UPDATE CHILD", i, children[i].child.name); - // content.children[i] = children[i].child; - content.removeChildAt(i); - content.addChildAt(children[i].child, i); - // content.addChild(children[i].child); - } - } - - // Remove redundant surplus children - // content.children.splice(children.length, content.children.length - children.length); - // for (let i = content.children.length-1; i >= children.length; i--) { - // console.log("=====> REMOVE CHILD", i, content.children[i].name); - // content.removeChildAt(i); - // } - } - - content.sortChildren(); - - if ((diffs.has("filters") || childChanged) && clump.filters && clump.filters.length > 0) - { - //===== FILTERS =====// - console.log("APPLY FILTER", content.name); - const filterSprite = applyFilters(blink, content, clump.filters); - // resClump.addChildAt(content, 0); - if (resClump.children.length > 1) { - resClump.removeChildAt(1); - } - resClump.addChildAt(filterSprite, 1); - } - else - { - //===== ADD CONTENT WITHOUT FLATTENING =====// - if (childChanged) { - console.log("RESCLUMP CHILDREN", resClump.children); - } - } - } - - let appliedFilter = false; - for (let i = 0; i < resClump.children.length; i++) { - if (resClump.children[i].name.includes("FilterSprite")) { - appliedFilter = true; - break; - } - } - if (findChild(resClump, "FilterSprite") != null) { - // If we've applied a filter (potentially in a previous step), hide the content - content.visible = false; - } - - // Get bounds before applying transform - const clumpBounds = resClump.getBounds(); - // TODO: Optimize with resClump._bounds.getRectangle() on children, - // to avoid recalculating all the way down the hierarchy - // Also: Look into .getLocalBounds() instead - - //========== APPLY CLUMP PROPERTIES ==========// - if (diffs.has("transform")) { - console.log("UPDATE TRANSFORM", resClump.name.split("(")[1].slice(0, 4)); - let transMatrix = PIXI.Matrix.IDENTITY; - if (clump.transform) { - const { position: pos, rotation: rot, scale: scl } = clump.transform; - - if (scl) transMatrix.scale(scl.x, scl.y); - if (rot) transMatrix.rotate((rot * Math.PI) / 180); - if (pos) transMatrix.translate(pos.x, pos.y); - } - - resClump.transform.setFromMatrix(transMatrix); - // const matTransform = resClumpContent.transform.worldTransform; - } - - if (diffs.has("opacity")) { - if (clump.opacity) { - resClump.alpha = Math.min(1, Math.max(0, clump.opacity)); - } - } - - if (diffs.has("mask")) { - const mask = clump.mask != null ? renderClump( - blink, - 0, - clump.mask, - undefined, - canvas, - undefined, - viewport, - () => {} - ).pixiClump : null; - - if (mask) { - const { x: bx, y: by, width: bw, height: bh } = mask.getLocalBounds(); - const renderPadding = 0; - mask.transform.position.x = -bx + renderPadding; - mask.transform.position.y = -by + renderPadding; - - // Render to texture - const renderTexture = PIXI.RenderTexture.create({ width: bw + 2 * renderPadding, height: bh + 2 * renderPadding, }); - blink.renderer.render(mask, { renderTexture: renderTexture }); - - mask.transform.setFromMatrix(new PIXI.Matrix()); - - // Create flattened sprite - const renderSprite = new PIXI.Sprite(renderTexture); - renderSprite.name = `FilterSprite(${randomId()})` - // renderSprite.anchor.x = 0.5; - // renderSprite.anchor.y = 0.5; - renderSprite.setTransform(bx - renderPadding, by - renderPadding); - - // TODO: Add a separate child container to the clump to - // be used specifically for masking - resClump.addChild(renderSprite); - resClump.mask = renderSprite; - } - else { - resClump.mask = null; - } - } - - resClump.sortChildren(); - - if (prevClump != null) { - prevClump.container = resClump; - } - - console.log("------------------------------------"); - return { - pixiClump: resClump, - changed: childChanged || diffs.size > 0, - }; -} - - -function addInteractivity(container: PIXI.Container, clump: Clump, viewport: Viewport, send: (message: string, data: any) => void) { - container.eventMode = "dynamic"; - - container.on("mousedown", (event) => { - event.stopPropagation(); - - // Create new selection - selection = { - uuid: clump.nodeUUID, - container, - dragging: true, - prevMousePos: viewport.toWorld(event.global) - }; - }); - - viewport.on("mouseup", (event) => { - if (selection?.uuid === clump.nodeUUID) { - event.stopPropagation(); - if (selection.dragging) { - send("tweak", { - nodeUUID: clump.nodeUUID, - inputs: { - positionX: container.transform.position.x, - positionY: container.transform.position.y - }, - }); - selection.dragging = false; - console.log("MOUSE UP", selection); - } - } - }); - - viewport.on("mousemove", (event) => { - if (selection?.uuid === clump.nodeUUID && selection?.dragging) { - // boundingBox.removeChildren(); - // boundingBox.addChild(createBoundingBox(container.transform.worldTransform, container.getBounds(), viewport)); - - const pos = viewport.toWorld(event.global); - // const pos = viewport.worldTransform.apply(event.global); - const shift = new PIXI.Point( - pos.x - selection.prevMousePos.x, - pos.y - selection.prevMousePos.y - ); - selection.prevMousePos = pos; - - container.transform.position.x += shift.x; - container.transform.position.y += shift.y; - } - }); - - // To get global mouse position at any point: - // console.log("MOUSE", blink.renderer.plugins.interaction.pointer.global); -} - -function findChild(container: PIXI.Container, namePrefix: string): PIXI.DisplayObject | null { - for (let i = 0; i < container.children.length; i++) { - if (container.children[i].name.includes(namePrefix)) { - return container.children[i]; - } - } - return null; -} \ No newline at end of file diff --git a/blix-plugins/blink/webview/select.ts b/blix-plugins/blink/webview/select.ts deleted file mode 100644 index 2794838c..00000000 --- a/blix-plugins/blink/webview/select.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { type Viewport } from "pixi-viewport"; -import * as PIXI from "pixi.js"; -import { OriginPoint } from "./types"; - -const BOX_CORNER_DOT_SIZE = 5; -const BOX_EDGE_DOT_SIZE = 4; -const BOX_LINE_WIDTH = 2; - -export function createBoundingBox(transMatrix: PIXI.Matrix, bounds: PIXI.Rectangle, viewport: Viewport, origin: PIXI.Point) { - - //===== COMPUTE CORNERS =====// - const tl = transMatrix.apply(new PIXI.Point(bounds.x, bounds.y)); - const tr = transMatrix.apply(new PIXI.Point(bounds.x + bounds.width, bounds.y)); - const bl = transMatrix.apply(new PIXI.Point(bounds.x, bounds.y + bounds.height)); - const br = transMatrix.apply(new PIXI.Point(bounds.x + bounds.width, bounds.y + bounds.height)); - - const corners = [tl, tr, br, bl]; - - for (let c = 0; c < 4; c++) { - corners[c] = viewport.toScreen(corners[c]); - // corners[c] = viewport.toWorld(corners[c]); - } - - const boxWidth = corners[1].x - corners[0].x; - const boxHeight = corners[3].y - corners[0].y; - - //===== CONSTRUCT BOX LINES =====// - const boxLines = new PIXI.Graphics(); - boxLines.beginFill(0xf43e5c, 1); - - for (let c = 0; c < 4; c++) { - const c2 = (c + 1) % 4; - - boxLines.lineStyle(BOX_LINE_WIDTH, 0xf43e5c, 0.5); - boxLines.moveTo(corners[c].x, corners[c].y); - boxLines.lineTo(corners[c2].x, corners[c2].y); - boxLines.lineStyle(); - } - - //===== CONSTRUCT BOX DOTS =====// - const boxDots: PIXI.Graphics[] = []; - const cursorsCorner = ["nwse-resize", "nesw-resize", "nwse-resize", "nesw-resize"]; - const cursorsEdge = ["ew-resize", "ns-resize", "ew-resize", "ns-resize"]; - - for (let c = 0; c < 4; c++) { - const c2 = (c + 1) % 4; - - const boxDot1 = new PIXI.Graphics(); - - boxDot1.interactive = true; - boxDot1.beginFill(0xf43e5c, 1); - boxDot1.cursor = cursorsCorner[c]; - boxDot1.drawCircle(corners[c].x, corners[c].y, BOX_CORNER_DOT_SIZE); - boxDots.push(boxDot1); - - const boxDot2 = new PIXI.Graphics(); - boxDot2.interactive = true; - boxDot2.beginFill(0xf43e5c, 1); - boxDot2.cursor = cursorsEdge[c2]; - boxDot2.drawCircle((corners[c].x + corners[c2].x) / 2, (corners[c].y + corners[c2].y) / 2, BOX_EDGE_DOT_SIZE); - boxDots.push(boxDot2); - } - - const originDot = new PIXI.Graphics(); - originDot.lineStyle(1, 0xf43e5c, 1); - // TODO: Swap 0.5 for origin point - originDot.drawCircle(corners[0].x + 0.5*boxWidth, corners[0].y + 0.5*boxHeight, 0.5 * BOX_CORNER_DOT_SIZE); - - //===== BUILD BOX =====// - const box = new PIXI.Container(); - box.addChild(boxLines); - for (const boxDot of boxDots) { - box.addChild(boxDot); - } - box.addChild(originDot); - - box.zIndex = 1000; - - return box; -} diff --git a/blix-plugins/blink/webview/types.ts b/blix-plugins/blink/webview/types.ts deleted file mode 100644 index cb05a02e..00000000 --- a/blix-plugins/blink/webview/types.ts +++ /dev/null @@ -1,297 +0,0 @@ -import * as PIXI from "pixi.js"; -import { - KawaseBlurFilter, - BloomFilter, - GrayscaleFilter, - BevelFilter, - OutlineFilter, - DotFilter, - CRTFilter, - EmbossFilter, - BulgePinchFilter, - GlitchFilter, - ZoomBlurFilter, - TwistFilter, - AdjustmentFilter -} from "pixi-filters" - -export type WindowWithApis = Window & typeof globalThis & { - api: { - send: (channel: string, data: any) => {}; - on: (channel: string, func: (..._: any) => any) => {}; - }; - - cache: { - write: (content: Blob, metadata?: any) => Promise; - get: (id: string) => Promise; - delete: (id: string) => Promise; - }; -}; - - -export type BlinkCanvas = { - assets: { [key: string]: Asset }; - config?: BlinkCanvasConfig; - content: Clump | null; -} - -export type BlinkCanvasConfig = { - canvasDims: { w: number, h: number }; - canvasColor: number; - canvasAlpha: number; - - exportName: string; -}; - -export type Asset = { class: "asset" } & (ImageAsset | CurveAsset); - -export type ImageAsset = { - type: "image"; - data: string; -} - -export type CurveAsset = { - type: "curve" - data: CurvePoint[]; -} - -export type CurvePoint = { - control1: Vec2; - control2: Vec2; - point: Vec2; -} - -export type Vec2 = { x: number, y: number }; - -export type Clump = { - class: "clump"; - name?: string; - nodeUUID: string; - transform: Transform; - opacity?: number; - elements: (Clump | Atom)[]; - filters?: Filter[]; - mask?: Clump; -}; - -export type Transform = { - position: Vec2; - rotation: number; - scale: Vec2; - origin: OriginPoint; -} - -export type OriginPoint = "tl" | "tm" | "tr" | "ml" | "mm" | "mr" | "bl" | "bm" | "br"; - -export type Filter = { - class: "filter"; - type: "blur" | "noise" | "bloom" | "grayscale" | "bevel" | "outline" | "dot" | "crt" | "emboss" | "bulge" | "glitch" | "zoomblur" | "twist" | "brightnessContrast" | "saturationGamma" | "colorChannel"; - params: any[] -}; - -export function getPixiFilter(filter: Filter) { - try { - switch (filter.type) { - case "blur": return new PIXI.BlurFilter(...filter.params); - case "noise": return new PIXI.NoiseFilter(...filter.params); - case "bloom": return new BloomFilter(...filter.params); - case "grayscale": return new GrayscaleFilter(); - case "bevel": return new BevelFilter( - { - rotation: filter.params[0], - thickness: filter.params[1], - lightColor: filter.params[2], - lightAlpha: filter.params[3], - shadowColor: filter.params[4], - shadowAlpha: filter.params[5], - } - ); - case "outline": return new OutlineFilter(...filter.params); - case "dot": return new DotFilter(...filter.params); - case "crt": return new CRTFilter( - { - curvature: filter.params[0], - lineWidth: filter.params[1], - lineContrast: filter.params[2], - noise: filter.params[3], - noiseSize: filter.params[4], - vignetting: filter.params[5], - vignettingAlpha: filter.params[6], - vignettingBlur: filter.params[7], - seed: filter.params[8], - } - ); - case "emboss": return new EmbossFilter(...filter.params); - case "bulge": return new BulgePinchFilter( - { - radius: filter.params[0], - strength: filter.params[1], - center: new PIXI.Point(filter.params[2], filter.params[3]), - } - ); - case "glitch": return new GlitchFilter(...filter.params); - case "zoomblur": return new ZoomBlurFilter( - { - strength: filter.params[0], - innerRadius: filter.params[1], - center: [filter.params[2], filter.params[3]], - } - ); - case "twist": return new TwistFilter( - { - angle: filter.params[0], - radius: filter.params[1], - offset: new PIXI.Point(filter.params[2], filter.params[3]), - } - ); - case "brightnessContrast": return new AdjustmentFilter( - { - brightness: filter.params[0], - contrast: filter.params[1], - } - ); - case "saturationGamma": return new AdjustmentFilter( - { - saturation: filter.params[0], - gamma: filter.params[1], - } - ); - case "colorChannel": return new AdjustmentFilter( - { - red: filter.params[0], - green: filter.params[1], - blue: filter.params[2], - alpha: filter.params[3], - } - ); - } - } catch { - return new PIXI.Filter(); - } -} - -// A single indivisible unit of a clump (E.g. image, shape, text etc.) -export type Atom = { class: "atom", nodeUUID: string } & (ImageAtom | ShapeAtom | TextAtom | PaintAtom | CurveAtom); -export type ImageAtom = { - type: "image"; - assetId: string; -}; - -export type CurveAtom = { - type: "curve"; - assetId: string; - fill: number; - fillAlpha: number; - stroke: number; - strokeAlpha: number; - strokeWidth: number; -} - -export type ShapeAtom = { - type: "shape"; - shape: "rectangle" | "ellipse" | "triangle"; - - bounds: { w: number, h: number }; - fill: number; - fillAlpha: number; - stroke: number; - strokeAlpha: number; - strokeWidth: number; -}; -export type TextAtom = { - type: "text"; - text: string; - - fill: number; - stroke: number; - alpha: number; - strokeWidth: number; - fontSize: number; - fontFamily: string; - fontStyle: "normal" | "italic"; - fontWeight: "normal" | "bold"; - textAlign: "left" | "center" | "right"; - textBaseline: "top" | "hanging" | "middle" | "alphabetic" | "ideographic" | "bottom"; -}; -export type PaintAtom = { - type: "paint"; - uuid: string; -}; - -export const canvas1: BlinkCanvas = { - assets: { - "1": { - class: "asset", - type: "image", - data: "media/bird.png", - }, - "2": { - class: "asset", - type: "image", - data: "media/blueArrow.png", - } - }, - content: { - class: "clump", - name: "root", - nodeUUID: "a", - transform: { position: { x: 0, y: 0 }, rotation: 0, scale: { x: 1, y: 1 } }, - filters: [ - { class: "filter", type: "blur", params: [100, 25] }, - // { class: "filter", type: "noise", params: [10] }, - // { class: "filter", type: "color", params: [] }, - ], - elements: [ - { - class: "atom", - type: "image", - assetId: "1", - nodeUUID: "b", - }, - { - class: "clump", - nodeUUID: "", - name: "clump1", - transform: { position: { x: 500, y: 500 }, rotation: 0, scale: { x: 1, y: 1 } }, - elements: [ - { - class: "atom", - type: "shape", - shape: "rectangle", - nodeUUID: "c", - - bounds: { w: 100, h: 100 }, - fill: 0xff0000, - fillAlpha: 1, - stroke: 0x00ff00, - strokeAlpha: 1, - strokeWidth: 5, - }, - { - class: "atom", - type: "text", - text: "Hello World", - nodeUUID: "d", - - fill: 0x0000ff, - stroke: 0x00ff00, - alpha: 1, - strokeWidth: 5, - fontSize: 20, - fontFamily: "Arial", - fontStyle: "italic", - fontWeight: "bold", - textAlign: "center", - textBaseline: "middle", - }, - { - class: "atom", - type: "image", - assetId: "2", - nodeUUID: "e", - }, - ], - }, - ], - } -}; diff --git a/blix-plugins/glfx-plugin/src/main.cjs b/blix-plugins/glfx-plugin/src/main.cjs index 9cbdbba9..05d97fd8 100644 --- a/blix-plugins/glfx-plugin/src/main.cjs +++ b/blix-plugins/glfx-plugin/src/main.cjs @@ -45,9 +45,9 @@ function createGLFXNode(type, title, desc, params) { nodeBuilder.setUI(ui); nodeBuilder.addInput("GLFX image", "img", "GLFX image"); - for (let param of params) { - nodeBuilder.addInput("number", param.id, toTitleCase(param.id)); - } + // for (let param of params) { + // nodeBuilder.addInput("number", param.id, toTitleCase(param.id)); + // } nodeBuilder.addOutput("GLFX image", "res", "Result"); }; } diff --git a/blix-plugins/input-plugin/src/main.js b/blix-plugins/input-plugin/src/main.js index cfc9c1da..d51bec2f 100644 --- a/blix-plugins/input-plugin/src/main.js +++ b/blix-plugins/input-plugin/src/main.js @@ -23,6 +23,30 @@ const nodes = { nodeBuilder.addOutput("number", "res", "Result"); }, + "string": (context) => { + const nodeBuilder = context.instantiate("Input", "string"); + nodeBuilder.setTitle("String"); + nodeBuilder.setDescription("Returns a single string output"); + + nodeBuilder.define((input, uiInput, from) => { + return { "res": uiInput["value"] }; + }); + + const ui = nodeBuilder.createUIBuilder(); + ui + .addTextInput( + { + componentId: "value", + label: "Input string", + defaultValue: "Hello world", + triggerUpdate: true, + }, + { multiline: true } + ); + nodeBuilder.setUI(ui); + + nodeBuilder.addOutput("string", "res", "Result"); + }, // "image": (context) => { // const nodeBuilder = context.instantiate("Input", "image"); // nodeBuilder.setTitle("Image"); diff --git a/blix-plugins/ripple b/blix-plugins/ripple new file mode 160000 index 00000000..7a14961b --- /dev/null +++ b/blix-plugins/ripple @@ -0,0 +1 @@ +Subproject commit 7a14961b657bbab5b438ebabba9c7cdeaa7b13d3 diff --git a/blix-plugins/threlte-plugin/.gitignore b/blix-plugins/threlte-plugin/.gitignore deleted file mode 100644 index b512c09d..00000000 --- a/blix-plugins/threlte-plugin/.gitignore +++ /dev/null @@ -1 +0,0 @@ -node_modules \ No newline at end of file diff --git a/blix-plugins/threlte-plugin/README.md b/blix-plugins/threlte-plugin/README.md deleted file mode 100644 index 7fced4b9..00000000 --- a/blix-plugins/threlte-plugin/README.md +++ /dev/null @@ -1,41 +0,0 @@ -# Math Plugin - -The Math Plugin is an essential component of Blix, our AI photo editor. It offers a wide range of basic arithmetic operations, enabling users to perform mathematical manipulations on images within the photo editing graph. -Features - -The Math Plugin provides some of the following key features: - - Addition: Perform addition operations on numerical values. - Subtraction: Perform subtraction operations on numerical values. - Multiplication: Perform multiplication operations on numerical values. - Division: Perform division operations on numerical values. - Exponentiation: Apply exponentiation operations to numerical values. - Absolute Value: Calculate the absolute value of a numerical value. - Minimum: Determine the minimum value between two numerical values. - Maximum: Determine the maximum value between two numerical values. - -How to Use - -To use the Math Plugin within the Blix photo editor, follow these steps: - - Open the Blix photo editor and create a new project. - Access the editing graph or workspace. - Locate the Math Plugin nodes within the available nodes. - Drag and drop the Math Plugin node into the graph. - Connect the input and output nodes to the desired locations in the graph. - Manipulate the node through the provided components. - Observe the effects on the image. - -Please note that the Math Plugin can be used in combination with other nodes and plugins within the photo editing graph to achieve complex and customized effects. - -Plugin Development - -If you are interested in developing additional functionalities for the Math Plugin or creating your own plugins for Blix, please refer to our developer documentation. It provides comprehensive guidelines and resources to help you extend the capabilities of our photo editor. -Feedback and Support - -We highly value your feedback and are dedicated to continuously improving Blix and its plugins. If you encounter any issues, have suggestions for improvement, or need assistance, please don't hesitate to reach out to our support team. We are here to help you make the most out of your photo editing experience with Blix. -License - -The Math Plugin is released under the [GNU GENERAL PUBLIC LICENSE] license. Please review the license file for more information regarding the terms of use and redistribution. - -Enjoy using the Math Plugin in Blix, and have fun exploring the possibilities of mathematical transformations in your photo editing projects! \ No newline at end of file diff --git a/blix-plugins/threlte-plugin/package-lock.json b/blix-plugins/threlte-plugin/package-lock.json deleted file mode 100644 index 0726358a..00000000 --- a/blix-plugins/threlte-plugin/package-lock.json +++ /dev/null @@ -1,1205 +0,0 @@ -{ - "name": "glfx-plugin", - "version": "0.0.1", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "glfx-plugin", - "version": "0.0.1", - "devDependencies": { - "@rollup/plugin-commonjs": "^24.0.0", - "@rollup/plugin-node-resolve": "^15.0.0", - "@rollup/plugin-terser": "^0.4.0", - "@threlte/core": "^6.0.2", - "@threlte/extras": "^5.0.4", - "@types/node": "^12.0.0", - "rollup": "^3.15.0", - "rollup-plugin-css-only": "^4.3.0", - "rollup-plugin-livereload": "^2.0.0", - "rollup-plugin-svelte": "^7.1.2", - "svelte": "^3.55.0", - "three": "^0.155.0", - "typescript": "^3.4.5" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", - "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "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.18", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", - "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - } - }, - "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, - "node_modules/@rollup/plugin-commonjs": { - "version": "24.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-24.1.0.tgz", - "integrity": "sha512-eSL45hjhCWI0jCCXcNtLVqM5N1JlBGvlFfY0m6oOYnLCJ6N0qEXoZql4sY2MOUArzhH4SA/qBpTxvvZp2Sc+DQ==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "commondir": "^1.0.1", - "estree-walker": "^2.0.2", - "glob": "^8.0.3", - "is-reference": "1.2.1", - "magic-string": "^0.27.0" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^2.68.0||^3.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-node-resolve": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.1.0.tgz", - "integrity": "sha512-xeZHCgsiZ9pzYVgAo9580eCGqwh/XCEUM9q6iQfGNocjgkufHAqC3exA+45URvhiYV8sBF9RlBai650eNs7AsA==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^5.0.1", - "@types/resolve": "1.20.2", - "deepmerge": "^4.2.2", - "is-builtin-module": "^3.2.1", - "is-module": "^1.0.0", - "resolve": "^1.22.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^2.78.0||^3.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/plugin-terser": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.3.tgz", - "integrity": "sha512-EF0oejTMtkyhrkwCdg0HJ0IpkcaVg1MMSf2olHb2Jp+1mnLM04OhjpJWGma4HobiDTF0WCyViWuvadyE9ch2XA==", - "dev": true, - "dependencies": { - "serialize-javascript": "^6.0.1", - "smob": "^1.0.0", - "terser": "^5.17.4" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^2.x || ^3.x" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/pluginutils": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", - "integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==", - "dev": true, - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@threlte/core": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@threlte/core/-/core-6.0.2.tgz", - "integrity": "sha512-xEgCvOlQAKTKxpOhShvzP1IX/ME1pAv2yLBTdTAyqkxVGm/R/hzR5J7KhrEGrC6ixTXUhYwTZey7cHk5oOzAAQ==", - "dev": true, - "dependencies": { - "svelte": "^4.1.1", - "three": "^0.153.0" - } - }, - "node_modules/@threlte/core/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/@threlte/core/node_modules/is-reference": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.1.tgz", - "integrity": "sha512-baJJdQLiYaJdvFbJqXrcGv3WU3QCzBlUcI5QhbesIm6/xPsvmO+2CDoi/GMOFBQEQm+PXkwOPrp9KK5ozZsp2w==", - "dev": true, - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/@threlte/core/node_modules/magic-string": { - "version": "0.30.2", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.2.tgz", - "integrity": "sha512-lNZdu7pewtq/ZvWUp9Wpf/x7WzMTsR26TWV03BRZrXFsv+BI6dy8RAiKgm1uM/kyR0rCfUcqvOlXKG66KhIGug==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@threlte/core/node_modules/svelte": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.1.2.tgz", - "integrity": "sha512-/evA8U6CgOHe5ZD1C1W3va9iJG7mWflcCdghBORJaAhD2JzrVERJty/2gl0pIPrJYBGZwZycH6onYf+64XXF9g==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.1", - "@jridgewell/sourcemap-codec": "^1.4.15", - "@jridgewell/trace-mapping": "^0.3.18", - "acorn": "^8.9.0", - "aria-query": "^5.3.0", - "axobject-query": "^3.2.1", - "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.0", - "periscopic": "^3.1.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/@threlte/core/node_modules/three": { - "version": "0.153.0", - "resolved": "https://registry.npmjs.org/three/-/three-0.153.0.tgz", - "integrity": "sha512-OCP2/uQR6GcDpSLnJt/3a4mdS0kNWcbfUXIwLoEMgLzEUIVIYsSDwskpmOii/AkDM+BBwrl6+CKgrjX9+E2aWg==", - "dev": true - }, - "node_modules/@threlte/extras": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@threlte/extras/-/extras-5.0.4.tgz", - "integrity": "sha512-IDmmDJBrFbFiGpgf8NB49yfSCKdVxkJRwg2kte7kj4wxrk6Nn1bdR2FTy+ReWJ9g4fE85n4XkkLJmereIZv4AA==", - "dev": true, - "dependencies": { - "lodash-es": "^4.17.21", - "svelte": "^4.1.1", - "three": "^0.153.0", - "troika-three-text": "^0.47.2" - } - }, - "node_modules/@threlte/extras/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/@threlte/extras/node_modules/is-reference": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.1.tgz", - "integrity": "sha512-baJJdQLiYaJdvFbJqXrcGv3WU3QCzBlUcI5QhbesIm6/xPsvmO+2CDoi/GMOFBQEQm+PXkwOPrp9KK5ozZsp2w==", - "dev": true, - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/@threlte/extras/node_modules/magic-string": { - "version": "0.30.2", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.2.tgz", - "integrity": "sha512-lNZdu7pewtq/ZvWUp9Wpf/x7WzMTsR26TWV03BRZrXFsv+BI6dy8RAiKgm1uM/kyR0rCfUcqvOlXKG66KhIGug==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@threlte/extras/node_modules/svelte": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.1.2.tgz", - "integrity": "sha512-/evA8U6CgOHe5ZD1C1W3va9iJG7mWflcCdghBORJaAhD2JzrVERJty/2gl0pIPrJYBGZwZycH6onYf+64XXF9g==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.1", - "@jridgewell/sourcemap-codec": "^1.4.15", - "@jridgewell/trace-mapping": "^0.3.18", - "acorn": "^8.9.0", - "aria-query": "^5.3.0", - "axobject-query": "^3.2.1", - "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.0", - "periscopic": "^3.1.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/@threlte/extras/node_modules/three": { - "version": "0.153.0", - "resolved": "https://registry.npmjs.org/three/-/three-0.153.0.tgz", - "integrity": "sha512-OCP2/uQR6GcDpSLnJt/3a4mdS0kNWcbfUXIwLoEMgLzEUIVIYsSDwskpmOii/AkDM+BBwrl6+CKgrjX9+E2aWg==", - "dev": true - }, - "node_modules/@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", - "dev": true - }, - "node_modules/@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "dev": true - }, - "node_modules/@types/resolve": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", - "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", - "dev": true - }, - "node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", - "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": "3.2.1", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", - "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", - "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/bidi-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", - "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", - "dev": true, - "dependencies": { - "require-from-string": "^2.0.2" - } - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "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-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/builtin-modules": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", - "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "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" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/code-red": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.3.tgz", - "integrity": "sha512-kVwJELqiILQyG5aeuyKFbdsI1fmQy1Cmf7dQ8eGmVuJoaRVdwey7WaMknr2ZFeVSYSKT0rExsa8EGw0aoI/1QQ==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.14", - "@types/estree": "^1.0.0", - "acorn": "^8.8.2", - "estree-walker": "^3.0.3", - "periscopic": "^3.1.0" - } - }, - "node_modules/code-red/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/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "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/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/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true - }, - "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.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "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/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "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-builtin-module": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", - "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", - "dev": true, - "dependencies": { - "builtin-modules": "^3.3.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-core-module": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", - "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==", - "dev": true - }, - "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": "1.2.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", - "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", - "dev": true, - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/livereload": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/livereload/-/livereload-0.9.3.tgz", - "integrity": "sha512-q7Z71n3i4X0R9xthAryBdNGVGAO2R5X+/xXpmKeuPMrteg+W2U8VusTKV3YiJbXZwKsOlFlHe+go6uSNjfxrZw==", - "dev": true, - "dependencies": { - "chokidar": "^3.5.0", - "livereload-js": "^3.3.1", - "opts": ">= 1.2.0", - "ws": "^7.4.3" - }, - "bin": { - "livereload": "bin/livereload.js" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/livereload-js": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-3.4.1.tgz", - "integrity": "sha512-5MP0uUeVCec89ZbNOT/i97Mc+q3SxXmiUGhRFOTmhrGPn//uWVQdCvcLJDy64MSBR5MidFdOR7B9viumoavy6g==", - "dev": true - }, - "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/lodash-es": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", - "dev": true - }, - "node_modules/magic-string": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz", - "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.13" - }, - "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/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "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/opts": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/opts/-/opts-2.0.2.tgz", - "integrity": "sha512-k41FwbcLnlgnFh69f4qdUfvDQ+5vaSDnVPFI/y5XuhKRq97EnVVneO9F1ESVCdiVu4fCS2L8usX3mU331hB7pg==", - "dev": true - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "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/periscopic/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/periscopic/node_modules/is-reference": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.1.tgz", - "integrity": "sha512-baJJdQLiYaJdvFbJqXrcGv3WU3QCzBlUcI5QhbesIm6/xPsvmO+2CDoi/GMOFBQEQm+PXkwOPrp9KK5ozZsp2w==", - "dev": true, - "dependencies": { - "@types/estree": "*" - } - }, - "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/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "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/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", - "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", - "dev": true, - "dependencies": { - "is-core-module": "^2.11.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve.exports": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", - "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/rollup": { - "version": "3.27.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.27.0.tgz", - "integrity": "sha512-aOltLCrYZ0FhJDm7fCqwTjIUEVjWjcydKBV/Zeid6Mn8BWgDCUBBWT5beM5ieForYNo/1ZHuGJdka26kvQ3Gzg==", - "dev": true, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=14.18.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/rollup-plugin-css-only": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-css-only/-/rollup-plugin-css-only-4.3.0.tgz", - "integrity": "sha512-BsiCqJJQzZh2lQiHY5irejRoJ3I1EUFHEi5PjVqsr+EmOh54YrWVwd3YZEXnQJ2+fzlhif0YM/Kf0GuH90GAdQ==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "5" - }, - "engines": { - "node": ">=14" - }, - "peerDependencies": { - "rollup": "<4" - } - }, - "node_modules/rollup-plugin-livereload": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/rollup-plugin-livereload/-/rollup-plugin-livereload-2.0.5.tgz", - "integrity": "sha512-vqQZ/UQowTW7VoiKEM5ouNW90wE5/GZLfdWuR0ELxyKOJUIaj+uismPZZaICU4DnWPVjnpCDDxEqwU7pcKY/PA==", - "dev": true, - "dependencies": { - "livereload": "^0.9.1" - }, - "engines": { - "node": ">=8.3" - } - }, - "node_modules/rollup-plugin-svelte": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/rollup-plugin-svelte/-/rollup-plugin-svelte-7.1.6.tgz", - "integrity": "sha512-nVFRBpGWI2qUY1OcSiEEA/kjCY2+vAjO9BI8SzA7NRrh2GTunLd6w2EYmnMt/atgdg8GvcNjLsmZmbQs/u4SQA==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^4.1.0", - "resolve.exports": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "rollup": ">=2.0.0", - "svelte": ">=3.5.0" - } - }, - "node_modules/rollup-plugin-svelte/node_modules/@rollup/pluginutils": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", - "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", - "dev": true, - "dependencies": { - "estree-walker": "^2.0.1", - "picomatch": "^2.2.2" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "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/serialize-javascript": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", - "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/smob": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/smob/-/smob-1.4.0.tgz", - "integrity": "sha512-MqR3fVulhjWuRNSMydnTlweu38UhQ0HXM4buStD/S3mc/BzX3CuM9OmhyQpmtYCvoYdl5ris6TI0ZqH355Ymqg==", - "dev": true - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/svelte": { - "version": "3.59.2", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.59.2.tgz", - "integrity": "sha512-vzSyuGr3eEoAtT/A6bmajosJZIUWySzY2CzB3w2pgPvnkUjGqlDnsNnA0PMO+mMAhuyMul6C2uuZzY6ELSkzyA==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/terser": { - "version": "5.19.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.19.2.tgz", - "integrity": "sha512-qC5+dmecKJA4cpYxRa5aVkKehYsQKc+AHeKl0Oe62aYjBL8ZA33tTljktDHJSaxxMnbI5ZYw+o/S2DxxLu8OfA==", - "dev": true, - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/three": { - "version": "0.155.0", - "resolved": "https://registry.npmjs.org/three/-/three-0.155.0.tgz", - "integrity": "sha512-sNgCYmDijnIqkD/bMfk+1pHg3YzsxW7V2ChpuP6HCQ8NiZr3RufsXQr8M3SSUMjW4hG+sUk7YbyuY0DncaDTJQ==", - "dev": 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/troika-three-text": { - "version": "0.47.2", - "resolved": "https://registry.npmjs.org/troika-three-text/-/troika-three-text-0.47.2.tgz", - "integrity": "sha512-qylT0F+U7xGs+/PEf3ujBdJMYWbn0Qci0kLqI5BJG2kW1wdg4T1XSxneypnF05DxFqJhEzuaOR9S2SjiyknMng==", - "dev": true, - "dependencies": { - "bidi-js": "^1.0.2", - "troika-three-utils": "^0.47.2", - "troika-worker-utils": "^0.47.2", - "webgl-sdf-generator": "1.1.1" - }, - "peerDependencies": { - "three": ">=0.125.0" - } - }, - "node_modules/troika-three-utils": { - "version": "0.47.2", - "resolved": "https://registry.npmjs.org/troika-three-utils/-/troika-three-utils-0.47.2.tgz", - "integrity": "sha512-/28plhCxfKtH7MSxEGx8e3b/OXU5A0xlwl+Sbdp0H8FXUHKZDoksduEKmjQayXYtxAyuUiCRunYIv/8Vi7aiyg==", - "dev": true, - "peerDependencies": { - "three": ">=0.125.0" - } - }, - "node_modules/troika-worker-utils": { - "version": "0.47.2", - "resolved": "https://registry.npmjs.org/troika-worker-utils/-/troika-worker-utils-0.47.2.tgz", - "integrity": "sha512-mzss4MeyzUkYBppn4x5cdAqrhBHFEuVmMMgLMTyFV23x6GvQMyo+/R5E5Lsbrt7WSt5RfvewjcwD1DChRTA9lA==", - "dev": true - }, - "node_modules/typescript": { - "version": "3.9.10", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", - "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/webgl-sdf-generator": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/webgl-sdf-generator/-/webgl-sdf-generator-1.1.1.tgz", - "integrity": "sha512-9Z0JcMTFxeE+b2x1LJTdnaT8rT8aEp7MVxkNwoycNmJWwPdzoXzMh0BjJSh/AEFP+KPYZUli814h8bJZFIZ2jA==", - "dev": 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 - }, - "node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "dev": true, - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - } - } -} diff --git a/blix-plugins/threlte-plugin/package.json b/blix-plugins/threlte-plugin/package.json deleted file mode 100644 index b706d5ed..00000000 --- a/blix-plugins/threlte-plugin/package.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "thelte-plugin", - "displayName": "Threlte Plugin", - "description": "", - "version": "0.0.1", - "author": "Rec1dite", - "repository": "", - "type": "module", - "scripts": { - "build": "rollup -c", - "dev": "rollup -c -w" - }, - "contributes": { - "commands": [], - "nodes": [] - }, - "main": "src/main.cjs", - "renderers": { "main": "src/index.html" }, - "devDependencies": { - "@rollup/plugin-commonjs": "^24.0.0", - "@rollup/plugin-node-resolve": "^15.0.0", - "@rollup/plugin-terser": "^0.4.0", - "@threlte/core": "^6.0.2", - "@threlte/extras": "^5.0.4", - "@types/node": "^12.0.0", - "rollup": "^3.15.0", - "rollup-plugin-css-only": "^4.3.0", - "rollup-plugin-livereload": "^2.0.0", - "rollup-plugin-svelte": "^7.1.2", - "svelte": "^3.55.0", - "three": "^0.155.0", - "typescript": "^3.4.5" - }, - "comments": [ - "This plugin will be expanded to handle more image operations." - ] -} diff --git a/blix-plugins/threlte-plugin/rollup.config.js b/blix-plugins/threlte-plugin/rollup.config.js deleted file mode 100644 index 95710837..00000000 --- a/blix-plugins/threlte-plugin/rollup.config.js +++ /dev/null @@ -1,78 +0,0 @@ -import { spawn } from 'child_process'; -import svelte from 'rollup-plugin-svelte'; -import commonjs from '@rollup/plugin-commonjs'; -import terser from '@rollup/plugin-terser'; -import resolve from '@rollup/plugin-node-resolve'; -import livereload from 'rollup-plugin-livereload'; -import css from 'rollup-plugin-css-only'; - -const production = !process.env.ROLLUP_WATCH; - -function serve() { - let server; - - function toExit() { - if (server) server.kill(0); - } - - return { - writeBundle() { - if (server) return; - // server = spawn('npm', ['run', 'start', '--', '--dev'], { - // stdio: ['ignore', 'inherit', 'inherit'], - // shell: true - // }); - - process.on('SIGTERM', toExit); - process.on('exit', toExit); - } - }; -} - -export default { - input: 'webview/app.js', - output: { - sourcemap: true, - format: 'iife', - name: 'app', - file: 'dist/bundle.js' - }, - plugins: [ - svelte({ - compilerOptions: { - // enable run-time checks when not in production - dev: !production - } - }), - // we'll extract any component CSS out into - // a separate file - better for performance - css({ output: 'bundle.css' }), - - // If you have external dependencies installed from - // npm, you'll most likely need these plugins. In - // some cases you'll need additional configuration - - // consult the documentation for details: - // https://github.com/rollup/plugins/tree/master/packages/commonjs - resolve({ - browser: true, - dedupe: ['svelte'], - exportConditions: ['svelte'] - }), - commonjs(), - - // In dev mode, call `npm run start` once - // the bundle has been generated - !production && serve(), - - // Watch the `public` directory and refresh the - // browser on changes when not in production - !production && livereload('public'), - - // If we're building for production (npm run build - // instead of npm run dev), minify - production && terser() - ], - watch: { - clearScreen: false - } -}; \ No newline at end of file diff --git a/blix-plugins/threlte-plugin/src/global.css b/blix-plugins/threlte-plugin/src/global.css deleted file mode 100644 index ca357ffc..00000000 --- a/blix-plugins/threlte-plugin/src/global.css +++ /dev/null @@ -1,4 +0,0 @@ -body { - margin: 0px; - font-family: 'Arial'; -} \ No newline at end of file diff --git a/blix-plugins/threlte-plugin/src/index.html b/blix-plugins/threlte-plugin/src/index.html deleted file mode 100644 index f0ea34dd..00000000 --- a/blix-plugins/threlte-plugin/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - Threlte plugin - - - - - - - \ No newline at end of file diff --git a/blix-plugins/threlte-plugin/src/main.cjs b/blix-plugins/threlte-plugin/src/main.cjs deleted file mode 100644 index 55f291b3..00000000 --- a/blix-plugins/threlte-plugin/src/main.cjs +++ /dev/null @@ -1,109 +0,0 @@ -// Use UI input if anchor not defined -function chooseInput(input, uiInput, inputKey) { - if (input[inputKey]) { - return input[inputKey]; - } - return uiInput[inputKey]; -} - -function toTitleCase(str) { - return str.charAt(0).toUpperCase() + str.slice(1); -} - -function createThrelteNode(type, title, desc, params) { - return (context) => { - const nodeBuilder = context.instantiate("Threlte", type); - nodeBuilder.setTitle(title); - nodeBuilder.setDescription(desc); - - const ui = nodeBuilder.createUIBuilder(); - for (let param of params) { - ui.addSlider( - { - componentId: param.id, - label: toTitleCase(param.id), - defaultValue: 0, - triggerUpdate: true, - }, - { min: param.min ?? -1, max: param.max ?? 1, step: param.step ?? 0.05 } - ); - } - - nodeBuilder.define(async (input, uiInput, from) => { - return { - "res": { - src: input["img"]?.src, - ops: [ - ...(input["img"]?.ops || []), - { - type, - args: params.map((param) => chooseInput(input, uiInput, param.id)) - } - ] - } - } - }); - - nodeBuilder.setUI(ui); - nodeBuilder.addInput("GLFX image", "img", "GLFX image"); - for (let param of params) { - nodeBuilder.addOutput("number", type, toTitleCase(param.id)); - } - nodeBuilder.addOutput("GLFX image", "res", "Result"); - }; -} - -const glfxNodes = { - "addPrimitive": [ - "Add Primitive", - "Add a 3D primitive", - [] - ], -}; - -// Object.keys(glfxNodes).forEach((key) => { -// glfxNodes[key] = createGLFXNode(key, ...glfxNodes[key]); -// }); - -const nodes = { - // ...glfxNodes, - - // "inputGLFXImage": (context) => { - // const nodeBuilder = context.instantiate("Input/Other", "inputGLFXImage"); - // nodeBuilder.setTitle("Input GLFX image"); - // nodeBuilder.setDescription("Provides an image input and returns a single image output"); - - // nodeBuilder.define(async (input, uiInput, from) => { - // return { "res": { src: uiInput["imagePicker"] } }; - // }); - - // const ui = nodeBuilder.createUIBuilder(); - // ui.addFilePicker({ - // componentId: "imagePicker", - // label: "Pick an image", - // defaultValue: "", - // triggerUpdate: true, - // }, {}); - // // ui.addCachePicker({ - // // componentId: "cacheid", - // // label: "Pick an image", - // // defaultValue: "", - // // triggerUpdate: true, - // // }, {}) - - // nodeBuilder.setUI(ui); - - // nodeBuilder.addOutput("GLFX image", "res", "Result"); - // }, -} - -const commands = {} -const tiles = {} - -const types = {} - -module.exports = { - nodes, - commands, - tiles -}; \ No newline at end of file diff --git a/blix-plugins/threlte-plugin/webview/App.svelte b/blix-plugins/threlte-plugin/webview/App.svelte deleted file mode 100644 index 0b18c9a0..00000000 --- a/blix-plugins/threlte-plugin/webview/App.svelte +++ /dev/null @@ -1,38 +0,0 @@ - - -
- - - -
- - - Media: {JSON.stringify($media)} - - - \ No newline at end of file diff --git a/blix-plugins/threlte-plugin/webview/Scene.svelte b/blix-plugins/threlte-plugin/webview/Scene.svelte deleted file mode 100644 index 90a88c55..00000000 --- a/blix-plugins/threlte-plugin/webview/Scene.svelte +++ /dev/null @@ -1,62 +0,0 @@ - - - { - ref.lookAt(0, 1, 0) - }} -/> - - - - scale.set(1.5)} - on:pointerleave={() => scale.set(1)} - castShadow -> - - - - - - - - - - - - - diff --git a/blix-plugins/threlte-plugin/webview/app.js b/blix-plugins/threlte-plugin/webview/app.js deleted file mode 100644 index 7c746eeb..00000000 --- a/blix-plugins/threlte-plugin/webview/app.js +++ /dev/null @@ -1,25 +0,0 @@ -const { writable } = require('svelte/store'); -const App = require('./App.svelte').default; - -const media = writable({}); - -const app = new App({ - target: document.body, - props: { media }, -}); - -module.exports.default = app; -// module.exports.dispatchMessage = (message) => { notifyMessageSubscribers(message); return "asdfHello"; }; - -// window.api.on("testMessage", (data) => { -// console.log(`Received ${data} from main process`); -// }); - -window.addEventListener("DOMContentLoaded", () => { - window.api.on("mediaChanged", (newMedia) => { - media.set(newMedia); - - // To send a message back - // window.api.send("backTestMessage", "Hello from app.js"); - }); -}); \ No newline at end of file diff --git a/jest.config.json b/jest.config.json index 181f591f..9d358ce4 100644 --- a/jest.config.json +++ b/jest.config.json @@ -15,7 +15,7 @@ ], "^.+\\.js$": "babel-jest" }, - "coveragePathIgnorePatterns": ["blix-plugins","node_modules","src/electron/lib/plugins/PluginManager"], + "coveragePathIgnorePatterns": ["blix-plugins","node_modules","src/electron/lib/plugins/PluginManager","src/electron/lib/ai/AiManagerv2","src/electron/lib/ai/Model","src/electron/lib/ai/Chat"], "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$", "moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node", "svelte"], "coverageDirectory": "coverage", diff --git a/package-lock.json b/package-lock.json index 6eeefaa4..63197129 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "blix", - "version": "1.2.0", + "version": "1.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "blix", - "version": "1.2.0", + "version": "1.3.0", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -101,6 +101,7 @@ "svelte-preprocess": "^5.0.3", "svelte-splitpanes": "^0.7.13", "tailwindcss": "^3.3.2", + "tailwindcss-palette-generator": "^0.4.5", "terser": "^5.17.1", "ts-jest": "^29.1.0", "tslib": "^2.5.0", @@ -6221,6 +6222,12 @@ "node": ">=10" } }, + "node_modules/chroma-js": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz", + "integrity": "sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A==", + "dev": true + }, "node_modules/chromium-pickle-js": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz", @@ -15906,6 +15913,21 @@ "node": ">=14.0.0" } }, + "node_modules/tailwindcss-palette-generator": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/tailwindcss-palette-generator/-/tailwindcss-palette-generator-0.4.5.tgz", + "integrity": "sha512-rIswqij1dU8zCUyfCVjGQ4VRXekqsRey28cU3H8lJX3kTYDg55M3B0UIo1alLXpd6anfWVjB+zHx3cY3ueokaA==", + "dev": true, + "dependencies": { + "chroma-js": "^2.4.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "tailwindcss": ">=3.0.0 || insiders" + } + }, "node_modules/tar": { "version": "6.1.15", "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz", diff --git a/package.json b/package.json index fa39f48b..d287a831 100644 --- a/package.json +++ b/package.json @@ -163,6 +163,7 @@ "svelte-preprocess": "^5.0.3", "svelte-splitpanes": "^0.7.13", "tailwindcss": "^3.3.2", + "tailwindcss-palette-generator": "^0.4.5", "terser": "^5.17.1", "ts-jest": "^29.1.0", "tslib": "^2.5.0", diff --git a/src/electron/lib/Blix.ts b/src/electron/lib/Blix.ts index b7945d87..60cd0f46 100644 --- a/src/electron/lib/Blix.ts +++ b/src/electron/lib/Blix.ts @@ -89,7 +89,8 @@ export class Blix { this._mediaManager = new MediaManager( this._typeclassRegistry, this._graphInterpreter, - this._graphManager + this._graphManager, + this.projectManager ); this.toolbox.addInstance(createOutputNode(this._mediaManager)); diff --git a/src/electron/lib/ai/AiLang.ts b/src/electron/lib/ai/AiLang.ts index b0e701e9..1f1f1544 100644 --- a/src/electron/lib/ai/AiLang.ts +++ b/src/electron/lib/ai/AiLang.ts @@ -969,6 +969,12 @@ export class BlypescriptPlugin { } else if (componentType === "DiffDial") { nodeParam.aiCanUse = false; nodeParam.types.push("diffDial"); + } else if (componentType === "OriginPicker") { + nodeParam.aiCanUse = false; + nodeParam.types.push("originPicker"); + } else if (componentType === "MatrixInput") { + nodeParam.aiCanUse = false; + nodeParam.types.push("matrixInput"); } else if (componentType === "CachePicker") { nodeParam.aiCanUse = false; nodeParam.types.push("cache"); @@ -1023,7 +1029,7 @@ export class BlypescriptToolbox { public toString(): string { const pluginStrings = this.plugins.map((plugin) => plugin.toString()); - let str = "// Graph edge connection wrapper type\nE = { value: T } | null;\n\n"; + let str = "// Graph edge connection wrapper\ntype E = { value: T } | null;\n\n"; str += pluginStrings.join("\n\n"); return str; } diff --git a/src/electron/lib/ai/AiManagerv2.ts b/src/electron/lib/ai/AiManagerv2.ts index f44462b9..d03f994e 100644 --- a/src/electron/lib/ai/AiManagerv2.ts +++ b/src/electron/lib/ai/AiManagerv2.ts @@ -39,14 +39,14 @@ type PromptOptions = { verbose?: boolean; }; -export const genericErrorResponse = "Oops, that wasn't supposed to happen😅"; +export const genericErrorResponse = "I struggled to understand that, can you try again?"; export class AiManager { private graphExporter: CoreGraphExporter; private readonly chats: Chat[] = []; private blypescriptInterpreter: BlypescriptInterpreter; private blypescriptToolbox: BlypescriptToolbox; - private agentIterationLimit = 3; + private agentIterationLimit = 2; constructor( private readonly toolbox: ToolboxRegistry, @@ -95,7 +95,7 @@ export class AiManager { chat.addMessages(messages); - const llm = Model.create({ model: model || "GPT-3.5", apiKey, temperature: 0 }); + const llm = Model.create({ model: model || "GPT-3.5", apiKey, temperature: 0.05 }); for (let i = 0; i < this.agentIterationLimit; i++) { const response = await llm.generate(chat); diff --git a/src/electron/lib/ai/Model.ts b/src/electron/lib/ai/Model.ts index 5ad78475..71c74573 100644 --- a/src/electron/lib/ai/Model.ts +++ b/src/electron/lib/ai/Model.ts @@ -89,6 +89,9 @@ export class OpenAiModel extends Model { } else if (error.message.toLocaleLowerCase().includes("provide your api")) { response.error = "invalid_api_key"; response.message = "Open AI API key hasn't been provided."; + } else if (error.code === "context_length_exceeded") { + response.error = "context_length_exceeded"; + response.message = "The context length has been exceeded."; } logger.error(error.code); diff --git a/src/electron/lib/ai/prompt.ts b/src/electron/lib/ai/prompt.ts index e0ef87b9..8c524a20 100644 --- a/src/electron/lib/ai/prompt.ts +++ b/src/electron/lib/ai/prompt.ts @@ -93,9 +93,9 @@ User: Brighten up the image and add some noise AI: \`\`\`typescript graph() { - const glfxInput = input.GLFXImage(); - const brightness = glfx.brightnessContrast(glfxInput['res'], mull, null, 0.4, 0); - const noise = glfx.noise(brightness['res'], null, 0.5); + const glfxInput = glfx.GLFXImage(); + const brightness = glfx.brightnessContrast(glfxInput['res'], 0.4, 0); + const noise = glfx.noise(brightness['res'], 0.5); const output = blix.output(noise['res'], 'output'); } \`\`\` @@ -105,8 +105,8 @@ graph() { Current Graph: \`\`\`typescript graph() { - const glfxInput = input.GLFXImage(); - const brightness = glfx.brightnessContrast(glfxInput['res'], mull, null, 0.4, 0); + const glfxInput = glfx.GLFXImage(); + const brightness = glfx.brightnessContrast(glfxInput['res'], 0.4, 0); const output = blix.output(brightness['res'], 'output'); } \`\`\` @@ -116,9 +116,9 @@ User: Add a yellow tint AI: \`\`\`typescript graph() { - const glfxInput = input.GLFXImage(); - const brightness = glfx.brightnessContrast(glfxInput['res'], mull, null, 0.4, 0); - const sepia = glfx.sepia(brightness['res'], mull, 0.5); + const glfxInput = glfx.GLFXImage(); + const brightness = glfx.brightnessContrast(glfxInput['res'], 0.4, 0); + const sepia = glfx.sepia(brightness['res'], 0.5); const output = blix.output(sepia['res'], 'output'); } \`\`\` diff --git a/src/electron/lib/api/apis/ProjectApi.ts b/src/electron/lib/api/apis/ProjectApi.ts index 3210aa33..52f53028 100644 --- a/src/electron/lib/api/apis/ProjectApi.ts +++ b/src/electron/lib/api/apis/ProjectApi.ts @@ -7,6 +7,7 @@ import { CoreGraphUpdateEvent, CoreGraphUpdateParticipant, } from "../../core-graph/CoreGraphInteractors"; +import { type CacheUUID } from "../../../../shared/types/cache"; export class ProjectApi implements ElectronMainApi { constructor(private readonly blix: Blix) {} @@ -57,7 +58,20 @@ export class ProjectApi implements ElectronMainApi { // } async closeProject(uuid: UUID, graphs?: UUID[]) { + const cacheUUIDs = this.blix.projectManager.getProject(uuid)?.getCacheIds() || []; const res = await this.blix.projectManager.removeProject(this.blix, uuid); - if (res === -1 && graphs) this.blix.graphManager.deleteGraphs(graphs); + + if (res === -1 && graphs) { + this.blix.cacheManager.deleteAssets(cacheUUIDs); + this.blix.graphManager.deleteGraphs(graphs); + } + } + + async addCacheObjects(projectUUID: UUID, cacheUUIDs: UUID[]): Promise> { + return this.blix.projectManager.addCacheObjects(projectUUID, cacheUUIDs); + } + + async removeCacheObjects(projectUUID: UUID, cacheUUIDs: UUID[]): Promise> { + return this.blix.projectManager.removeCacheObjects(projectUUID, cacheUUIDs); } } diff --git a/src/electron/lib/cache/CacheManager.ts b/src/electron/lib/cache/CacheManager.ts index 0a486822..6aa64d4d 100644 --- a/src/electron/lib/cache/CacheManager.ts +++ b/src/electron/lib/cache/CacheManager.ts @@ -1,24 +1,22 @@ // Blix caching system primarily for large binary objects import { - type SubsidiaryUUID, - type CacheUUID, - type CacheSubsidiary, + CACHE_MESSAGE_ID_SIZE, type CacheObject, type CacheRequest, + type CacheResponse, + type CacheUUID, type CacheUpdateNotification, type CacheWriteResponse, - type CacheResponse, - CACHE_MESSAGE_ID_SIZE, } from "../../../shared/types/cache"; import WebSocket, { WebSocketServer } from "ws"; // import { Server } from "socket.io"; import { randomBytes } from "crypto"; -import logger from "../../utils/logger"; import { app, ipcMain } from "electron"; -import { showSaveDialog } from "../../utils/dialog"; -import { join } from "path"; import { writeFile } from "fs/promises"; +import { join } from "path"; +import { showSaveDialog } from "../../utils/dialog"; +import logger from "../../utils/logger"; // The main interface which this manager must expose is: // - get(cacheUUID: CacheUUID): CacheObject @@ -91,14 +89,13 @@ export class CacheManager { JSON.stringify({ success: true, messageId: data.messageId } as CacheResponse) ); - this.notifyListeners(); + // this.notifyListeners(); break; case "cache-delete-all": this.deleteAssets(Object.keys(this.cache)); socket.send( JSON.stringify({ success: true, messageId: data.messageId } as CacheResponse) ); - this.notifyListeners(); break; case "cache-subscribe": this.listeners.add(socket); @@ -207,10 +204,15 @@ export class CacheManager { return this.cache[cacheUUID]; } + getUUIDs(): CacheUUID[] { + return Object.keys(this.cache); + } + deleteAssets(cacheUUID: CacheUUID[]) { for (const uuid of cacheUUID) { delete this.cache[uuid]; } + this.notifyListeners(); } async export(ids: CacheUUID[]) { diff --git a/src/electron/lib/core-graph/CoreGraph.ts b/src/electron/lib/core-graph/CoreGraph.ts index ead93d92..0037cb00 100644 --- a/src/electron/lib/core-graph/CoreGraph.ts +++ b/src/electron/lib/core-graph/CoreGraph.ts @@ -68,7 +68,8 @@ export class CoreGraph extends UniqueEntity { this.uiInputs = {}; this.uiPositions = {}; this.metadata = { - displayName: "Graph", + displayName: `Graph`, + timestamp: Date.now(), }; // this.nodeList = []; } @@ -217,8 +218,14 @@ export class CoreGraph extends UniqueEntity { inputValues = { ...inputValues, ...filledDialInputs }; // Handle the UI input initializer - const initializedInputs = nodeInstance.uiInitializer(inputValues); - const uiChanges = Object.keys(initializedInputs); + let initializedInputs = {}; + let uiChanges: string[] = []; + try { + initializedInputs = nodeInstance.uiInitializer(inputValues); + uiChanges = Object.keys(initializedInputs); + } catch (error) { + logger.error("Failed to execute UI initializer: ", error); + } let uiInputsInitialized = false; @@ -236,7 +243,6 @@ export class CoreGraph extends UniqueEntity { uiInputsInitialized = true; } - // console.log(uiInputsInitialized) const anchors: AiAnchors = node.returnAnchors(); // Add position of node to graph this.uiPositions[node.uuid] = pos; @@ -253,6 +259,7 @@ export class CoreGraph extends UniqueEntity { }, } satisfies QueryResponse; } catch (error) { + logger.error("Error initializing node: ", error); return { status: "error", message: error as string } satisfies QueryResponse; } @@ -637,10 +644,11 @@ export class CoreGraph extends UniqueEntity { } satisfies QueryResponse; } - const { displayName } = updatedMetadata; + const { displayName, timestamp } = updatedMetadata; const newMetadata: GraphMetadata = { displayName: displayName ? displayName : this.metadata.displayName, + timestamp: timestamp ? timestamp : this.metadata.timestamp, }; this.metadata = newMetadata; diff --git a/src/electron/lib/core-graph/CoreGraphInterpreter.ts b/src/electron/lib/core-graph/CoreGraphInterpreter.ts index 910b682e..a6d07ac7 100644 --- a/src/electron/lib/core-graph/CoreGraphInterpreter.ts +++ b/src/electron/lib/core-graph/CoreGraphInterpreter.ts @@ -40,6 +40,7 @@ export class CoreGraphInterpreter { // } // }); try { + if (!graph.getNodes[node]) return; const res = this.traverse( graph, graph.getNodes[node], diff --git a/src/electron/lib/core-graph/CoreGraphManager.ts b/src/electron/lib/core-graph/CoreGraphManager.ts index c2177d61..2b77ca9a 100644 --- a/src/electron/lib/core-graph/CoreGraphManager.ts +++ b/src/electron/lib/core-graph/CoreGraphManager.ts @@ -320,15 +320,20 @@ export class CoreGraphManager { return this._subscribers[graphUUID]; } - deleteGraphs(uuids: UUID[]): boolean[] { + deleteGraphs(graphUUIDs: UUID[]): boolean[] { const flags: boolean[] = []; - uuids.forEach((uuid) => { - if (uuid in this._graphs) { - delete this._graphs[uuid]; - delete this._subscribers[uuid]; - delete this._events[uuid]; - this._mainWindow?.apis.graphClientApi.graphRemoved(uuid); + graphUUIDs.forEach((graphId) => { + if (graphId in this._graphs) { + const outputNodes = Object.keys(this._graphs[graphId].getOutputNodes); + outputNodes.forEach((node) => { + delete this._outputIds[node]; + }); + delete this._graphs[graphId]; + delete this._subscribers[graphId]; + delete this._events[graphId]; + this._mainWindow?.apis.graphClientApi.graphRemoved(graphId); + this._mainWindow?.apis.mediaClientApi.outputNodesChanged(); flags.push(true); } else { flags.push(false); diff --git a/src/electron/lib/media/MediaManager.ts b/src/electron/lib/media/MediaManager.ts index 65b5fc19..86cb1bc2 100644 --- a/src/electron/lib/media/MediaManager.ts +++ b/src/electron/lib/media/MediaManager.ts @@ -11,12 +11,14 @@ import { } from "../../../shared/types/media"; import { CoreGraphManager } from "../core-graph/CoreGraphManager"; import { TypeclassRegistry } from "../registries/TypeclassRegistry"; +import { ProjectManager } from "../../lib/projects/ProjectManager"; export class MediaManager { private media: { [key: MediaOutputId]: MediaOutput }; private _typeclassRegistry: TypeclassRegistry; private _graphInterpreter: CoreGraphInterpreter; private _graphManager: CoreGraphManager; + private projectManager: ProjectManager; // Subscribers that are listening on the MediaManager private _subscribers: { [key: MediaOutputId]: { [key: UUID]: MediaSubscriber } }; @@ -24,18 +26,26 @@ export class MediaManager { constructor( typeclassRegistry: TypeclassRegistry, graphInterpreter: CoreGraphInterpreter, - graphManager: CoreGraphManager + graphManager: CoreGraphManager, + projectManager: ProjectManager ) { this._typeclassRegistry = typeclassRegistry; this._subscribers = {}; this._graphInterpreter = graphInterpreter; this._graphManager = graphManager; + this.projectManager = projectManager; this.media = {}; } updateMedia(mediaOutput: MediaOutput) { this.media[mediaOutput.outputId] = mediaOutput; + const projectId = this.projectManager.getProjectIdByGraphId(mediaOutput.graphUUID); + + if (projectId) { + this.projectManager.addMediaOutputs(projectId, [mediaOutput.outputNodeUUID]); + } + this.onMediaUpdated(mediaOutput.outputId); } diff --git a/src/electron/lib/projects/CoreProject.ts b/src/electron/lib/projects/CoreProject.ts index e2175755..4f2aef8b 100644 --- a/src/electron/lib/projects/CoreProject.ts +++ b/src/electron/lib/projects/CoreProject.ts @@ -4,6 +4,7 @@ import type { UUID } from "../../../shared/utils/UniqueEntity"; import type { PathLike } from "fs"; import type { GraphToJSON } from "../../lib/core-graph/CoreGraphExporter"; import { layoutTemplate } from "../../../frontend/lib/Project"; +import { type IpcResponse } from "../../lib/api/MainApi"; // Encapsulates the backend state for one of the open Blix projects export class CoreProject extends UniqueEntity { private _name: string; @@ -15,6 +16,8 @@ export class CoreProject extends UniqueEntity { private _location: PathLike; // Location in user local storage to sync to private _saved: boolean; // Flag used to check if project has been saved since last changes private _layout: LayoutPanel; + private _cache: UUID[]; + private _mediaIds: UUID[]; constructor(name: string) { super(); @@ -23,6 +26,8 @@ export class CoreProject extends UniqueEntity { this._location = "" as PathLike; this._saved = false; this._layout = layoutTemplate; + this._cache = []; + this._mediaIds = []; } public rename(name: string): boolean { @@ -94,6 +99,8 @@ export class CoreProject extends UniqueEntity { id: this.uuid, saved: this._saved, graphs: [...this._graphs], + cache: [...this._cache], + mediaOutputIds: [...this._mediaIds], }; return project; @@ -106,6 +113,50 @@ export class CoreProject extends UniqueEntity { public set saved(flag: boolean) { this._saved = flag; } + + public addCacheObjects(cacheUUIDs: UUID[]): IpcResponse { + try { + this._cache = [...this._cache, ...cacheUUIDs]; + return { success: true, data: "Asset successfully added" }; + } catch (e: any) { + return { success: false, data: e }; + } + } + + public removeCacheObjects(cacheUUIDs: UUID[]): IpcResponse { + try { + this._cache = this._cache.filter((id) => !cacheUUIDs.includes(id)); + return { success: true, data: "Asset successfully removed" }; + } catch (e: any) { + return { success: false, data: e }; + } + } + + public addMediaOutputs(mediaOutputIds: UUID[]): IpcResponse { + try { + mediaOutputIds.forEach((id) => { + if (!this._mediaIds.includes(id)) { + this._mediaIds.push(id); + } + }); + return { success: true, data: "Media output successfully added" }; + } catch (e: any) { + return { success: false, data: e }; + } + } + + public removeMediaOutputs(mediaOutputIds: UUID[]): IpcResponse { + try { + this._mediaIds = this._mediaIds.filter((id) => !mediaOutputIds.includes(id)); + return { success: true, data: "Media output successfully removed" }; + } catch (e: any) { + return { success: false, data: e }; + } + } + + public getCacheIds() { + return [...this._cache]; + } } export interface ProjectFile { diff --git a/src/electron/lib/projects/ProjectCommands.ts b/src/electron/lib/projects/ProjectCommands.ts index 995afdf6..3df7a88b 100644 --- a/src/electron/lib/projects/ProjectCommands.ts +++ b/src/electron/lib/projects/ProjectCommands.ts @@ -329,6 +329,9 @@ export async function openProject(ctx: CommandContext, path?: string): Promise { + if (project.name.includes("Untitled-")) { + const slice = parseInt(project.name.slice(9), 10); + + if (!isNaN(slice) && slice >= index) { + index = slice + 1; + } + } + }); + + name = `Untitled-${index}`; + } + const project = new CoreProject(name); this._projects[project.uuid] = project; this.onProjectCreated(project.uuid); @@ -57,6 +71,18 @@ export class ProjectManager { return this._projects[id]; } + public getProjectIdByGraphId(graphId: UUID): UUID | null { + let projectId: UUID | null = null; + + Object.values(this._projects).forEach((project) => { + if (project.graphs.includes(graphId)) { + projectId = project.uuid; + } + }); + + return projectId; + } + public async removeProject(blix: Blix, uuid: UUID, forceRemove = false) { const project = this._projects[uuid]; if (!project) forceRemove = true; // Project does not exist, just obliterate the tab @@ -203,6 +229,30 @@ export class ProjectManager { this._projects[projectId].saved = newState; this.onProjectChanged(projectId); } + + public addCacheObjects(projectUUID: UUID, cacheUUIDs: UUID[]): IpcResponse { + const res = this._projects[projectUUID].addCacheObjects(cacheUUIDs); + this.onProjectChanged(projectUUID); + return res; + } + + public removeCacheObjects(projectUUID: UUID, cacheUUIDs: UUID[]): IpcResponse { + const res = this._projects[projectUUID].removeCacheObjects(cacheUUIDs); + this.onProjectChanged(projectUUID); + return res; + } + + public addMediaOutputs(projectUUID: UUID, mediaOutputs: UUID[]): IpcResponse { + const res = this._projects[projectUUID].addMediaOutputs(mediaOutputs); + this.onProjectChanged(projectUUID); + return res; + } + + public removeMediaOutputs(projectUUID: UUID, mediaOutputs: UUID[]): IpcResponse { + const res = this._projects[projectUUID].removeMediaOutputs(mediaOutputs); + this.onProjectChanged(projectUUID); + return res; + } } const recentProjectsSchema = z.object({ diff --git a/src/electron/utils/settings.ts b/src/electron/utils/settings.ts index 7d72d236..5696fd47 100644 --- a/src/electron/utils/settings.ts +++ b/src/electron/utils/settings.ts @@ -13,6 +13,7 @@ export interface Settings { prompts: string[]; model: string; keyboardShortcuts: KeyboardShortcut[]; + accentColor: string; } type DotUnionKeys = T extends object @@ -42,6 +43,7 @@ export const settings = new ElectronStore({ prompts: [], model: "GPT-3.5", keyboardShortcuts: [], + accentColor: "f43e5c", }, }); diff --git a/src/frontend/lib/PanelNode.ts b/src/frontend/lib/PanelNode.ts index d0798c87..83715ab5 100644 --- a/src/frontend/lib/PanelNode.ts +++ b/src/frontend/lib/PanelNode.ts @@ -5,149 +5,148 @@ import { writable } from "svelte/store"; /* eslint-disable no-console */ export abstract class PanelNode { static panelCounter = 0; + parent: PanelGroup | null; + index: number; + // Helps Svelte with keying, cannot contain '_' character because it is used + // for string splitting in Graph.svelte + id: string; + size?: number; - constructor(id = -1) { + constructor() { this.parent = null; this.index = -1; - if (id !== -1) { - this.id = id; - } else { - this.id = PanelNode.panelCounter++; - } + this.id = PanelNode.generateUniqueId(); } - parent: PanelGroup | null; - index: number; - id: number; // Unique ID for each panel, helps Svelte with keying - // IMPORTANT: If id is replaced with a string at some point, - // that string _cannot_ contain the "_" character because - // we use that to do string splitting in Graph.svelte - size?: number; + static generateUniqueId() { + const timestamp = Date.now().toString(36); + const randomNumber = Math.random().toString(36).substring(2, 8); + const uniqueId = timestamp + randomNumber; + return uniqueId; + } } // Always has a minimum of two children, or self-destructs export class PanelGroup extends PanelNode { static groupCounter = 0; + name: string; + panels: PanelNode[] = []; + // A custom name can optionally be provided - constructor(name = "", id = -1) { - super(id); - this.parent = null; + constructor(name = "") { + super(); + if (name !== "") { this.name = name; } else { this.name = `pg_${PanelGroup.groupCounter}`; } + PanelGroup.groupCounter++; } - name: string; - panels: PanelNode[] = []; /** - * Removes a panel to from the panelgroup at index i. Existing panelGroup will be pruned if only one panel exists. - * @param i The index to remove the panel from - * @returns void - * */ + * Removes a panel at a designated index in the PanelGroup. If the PanelGroup + * has only one child, it will be replaced by the child. + * + * @param index The index of the panel to be removed + */ + removePanel(index: number) { + if (index < 0 || index >= this.panels.length) { + return; + } - // Nukes the current panelgroup and replaces it with its first child if possible - removePanel(i: number) { - if (i > this.panels.length) console.warn("PanelGroup.removePanel: Index out of bounds : ", i); - this.panels.splice(i, 1); + this.panels.splice(index, 1); - // If length 1, dissolve and replace with child + // Nukes the current PanelGroup and replaces it with its first child if (this.panels.length === 1) { - if (this.parent != null) { - this.parent.setPanel(this.panels[0], this.index); // Replaces - } + this.parent?.setPanel(this.panels[0], this.index); } + // If empty, dissolve (Shouldn't ever happen anyway) if (this.panels.length === 0) { - if (this.parent != null) { - this.parent.removePanel(this.index); - } + this.parent?.removePanel(this.index); } + + this.updatePanelIndexes(); this.updateParent(this); } /** - * Replaces a panel at the designated index in the panelgroup. + * Replaces a panel at the designated index in the PanelGroup. + * * @param panel The panel to be used to replace the existing panel - * @param i The index of the panel to be replaced - * @returns void - * */ - - setPanel(panel: PanelNode, i: number) { - if (i > this.panels.length) { - console.warn("PanelGroup.setPanel: Index out of bounds : ", i); + * @param index The index of the panel to be replaced + */ + setPanel(panel: PanelNode, index: number) { + if (index < 0 || index >= this.panels.length) { return; } - const tempId = this.panels[i].id; - this.panels[i] = panel; + + this.panels[index] = panel; panel.parent = this; - panel.index = i; - panel.id = tempId; + panel.index = index; } /** - * Inserts a panel to the panelgroup at index i + * Inserts a panel at the designated index in the PanelGroup. If the index is + * not provided, the panel will be added to the end of the PanelGroup. + * * @param content The type of the panel to be added - * @param i The index to place the panel at - * @returns void - * */ + * @param index The index to place the panel at + */ + addPanel(content: PanelType, index?: number) { + index = index ?? this.panels.length; + + if (index < 0 || index > this.panels.length) { + return; + } - addPanel(content: PanelType, i: number) { const newLeaf = new PanelLeaf(content); - if (i > this.panels.length) console.warn("PanelGroup.addPanel: Index out of bounds : ", i); - this.panels.splice(i, 0, newLeaf); + + this.panels.splice(index, 0, newLeaf); newLeaf.parent = this; - newLeaf.index = i; + newLeaf.index = index; this.updateParent(this); } /** - * Inserts a panelgroup to the current panelgroup at index i - * @param panelGroup The panelgroup to be added - * @param i The index to place the panelgroup at - * @returns void - * */ - - addPanelGroup(panelGroup: PanelGroup, i: number) { - this.panels.splice(i, 0, panelGroup); + * Inserts a PanelGroup at the designated index in the PanelGroup. If the + * index is not provided, thee PanelGroup will be added to the end of the + * PanelGroup. + * + * @param panelGroup The PanelGroup to be added + * @param index The index to place the PanelGroup at + */ + addPanelGroup(panelGroup: PanelGroup, index?: number) { + index = index ?? this.panels.length; + + if (index < 0 || index > this.panels.length) { + return; + } + + this.panels.splice(index, 0, panelGroup); panelGroup.parent = this; - panelGroup.index = i; + panelGroup.index = index; } - /** - * Returns the panel at the designated index - * @param i The index of the panel to be returned - * @returns PanelNode - * */ - getPanel(i: number): PanelNode { - return this.panels[i]; + getPanel(index: number): PanelNode { + return this.panels[index]; } - /** - * Updates the parent of the current panelgroup - * @param _current The current panel group to be used - * @returns void - * */ - updateParent(_current: PanelGroup) { let current = _current; + while (current.parent != null) { current = current.parent; } + current = current; } - /** - * Prints the panelgroup and its children - * @param indent The indentation level to be used - * @returns string - */ - - // Print tree for debug + /** Print tree for debug */ public print(indent = 0): string { let res; if (this.parent) { @@ -170,28 +169,24 @@ export class PanelGroup extends PanelNode { return res; } - /** - * Recursively sets the parent of the panelgroup and its children - * @returns void - * */ + updatePanelIndexes() { + this.panels.forEach((panel, index) => { + panel.index = index; + }); + } + /** Recursively sets the parent of the PanelGroup and its children */ recurseParent() { - for (let p = 0; p < this.panels.length; p++) { - const panel = this.panels[p]; + this.panels.forEach((panel, index) => { panel.parent = this; - panel.index = p; + panel.index = index; if (panel instanceof PanelGroup) { panel.recurseParent(); } - } + }); } - /** - * Saves the layout of the panelgroup and its children - * @returns LayoutPanel - * */ - public saveLayout(): LayoutPanel { const p: LayoutPanel = { panels: [], @@ -217,13 +212,14 @@ export class PanelLeaf extends PanelNode { this.parent = null; } } + /** * This store house the last panel clicked by the user. */ class FocusedPanelStore { - private readonly store = writable(-1); + private readonly store = writable(""); - public focusOnPanel(id: number) { + public focusOnPanel(id: string) { this.store.set(id); } diff --git a/src/frontend/lib/Project.ts b/src/frontend/lib/Project.ts index d1d40fcf..af10cd99 100644 --- a/src/frontend/lib/Project.ts +++ b/src/frontend/lib/Project.ts @@ -1,6 +1,8 @@ import type { UUID } from "../../shared/utils/UniqueEntity"; import { PanelGroup } from "./PanelNode"; import type { LayoutPanel } from "../../shared/types/index"; +import type { Writable } from "svelte/store"; +import type { GraphUUID } from "../../shared/ui/UIGraph"; export interface UIProject { readonly id: UUID; @@ -8,35 +10,35 @@ export interface UIProject { readonly saved: boolean; readonly layout: PanelGroup; readonly graphs: UUID[]; + readonly focusedGraph: Writable; + readonly focusedPanel: Writable; + readonly cache: UUID[]; + readonly mediaOutputIds: UUID[]; } let groupTest = 0; /** * Constructs a PanelGroup from a LayoutPanel + * * @param layout The layout to construct from * @returns The constructed PanelGroup */ - export function constructLayout(layout: LayoutPanel): PanelGroup { const group = new PanelGroup((groupTest++).toString()); - if (layout.panels) { - for (const panel of layout.panels) { - if (panel.panels) { - group.addPanelGroup(constructLayout(panel), panel.panels.length); - } else { - if (panel.content) { - group.addPanel(panel.content, layout.panels.length); - } + + layout.panels?.forEach((panel) => { + if (panel.panels) { + group.addPanelGroup(constructLayout(panel)); + } else { + if (panel.content) { + group.addPanel(panel.content); } } - return group; - } + }); + return group; } -/** - * A layout template for the UI - */ export const layoutTemplate: LayoutPanel = { panels: [ diff --git a/src/frontend/lib/stores/BlixStore.ts b/src/frontend/lib/stores/BlixStore.ts index 86124963..302229d3 100644 --- a/src/frontend/lib/stores/BlixStore.ts +++ b/src/frontend/lib/stores/BlixStore.ts @@ -1,9 +1,11 @@ -import { writable } from "svelte/store"; +/* eslint-disable @typescript-eslint/naming-convention */ +import { derived, writable } from "svelte/store"; import { commandStore } from "./CommandStore"; import { toolboxStore } from "./ToolboxStore"; import { tileStore } from "./TileStore"; import { shortcutsRegistry } from "./ShortcutStore"; import type { KeyboardShortcut } from "@shared/types"; +import getPalette from "tailwindcss-palette-generator"; const blixStoreDefaults = { blixReady: false, @@ -24,9 +26,24 @@ const blixStoreDefaults = { percentDownloaded: 0, version: "", }, + theme: { + primary: { + "50": "#ffb7c5", + "100": "#ffaab9", + "200": "#ff90a0", + "300": "#ff7589", + "400": "#ff5b72", + "500": "#f43e5c", + "600": "#d71a47", + "700": "#bb0033", + "800": "#9e0020", + "900": "#82000e", + }, + }, }; export type BlixStoreState = typeof blixStoreDefaults; +export type ColorPalette = { primary: Record }; export class BlixStore { store = writable(blixStoreDefaults); @@ -35,6 +52,57 @@ export class BlixStore { this.store.update((s) => ({ ...s, ...state })); } + /** + * Sets the accent color of Blix. Defaults to the best color in the known + * universe. + * + * @param color Hex color code + * @param shade Shade at which pallette will be generated + */ + public setPrimaryColor(color = "f43e5c", shade?: number) { + let palette: ColorPalette; + + if (shade) { + palette = getPalette({ + color, + name: "primary", + shade, + }) as ColorPalette; + } else { + palette = getPalette(color) as ColorPalette; + } + + const primaryColors: Record = {}; + + for (const [key, value] of Object.entries(palette.primary)) { + if (key === "DEFAULT") continue; + + const hex = value.replace("#", ""); + + const r = parseInt(hex.substring(0, 2), 16); + const g = parseInt(hex.substring(2, 4), 16); + const b = parseInt(hex.substring(4, 6), 16); + + const primary = `--color-primary-${key}`; + const rgb = `${r}, ${g}, ${b}`; + + document.documentElement.style.setProperty(primary, rgb); + primaryColors[key] = value; + } + + this.store.update((state) => { + // @ts-expect-error + state.theme.primary = primaryColors; + return state; + }); + } + + public primaryColor() { + return derived(this.store, ($store) => { + return $store.theme.primary["500"] as `#${string}`; + }); + } + public get subscribe() { return this.store.subscribe; } @@ -46,6 +114,10 @@ export class BlixStore { export const blixStore = new BlixStore(); +// ================================================================== +// Utilities +// ================================================================== + export async function setInitialStores() { // BLix store const res = await window.apis.utilApi.getInfo(); diff --git a/src/frontend/lib/stores/CacheStore.ts b/src/frontend/lib/stores/CacheStore.ts index 69450969..56c2f66a 100644 --- a/src/frontend/lib/stores/CacheStore.ts +++ b/src/frontend/lib/stores/CacheStore.ts @@ -1,15 +1,13 @@ import { - type SubsidiaryUUID, - type CacheUUID, - type CacheObject, - type CacheUpdateNotification, + CACHE_MESSAGE_ID_SIZE, type CacheMetadata, type CacheRequest, - type CacheWriteResponse, - CACHE_MESSAGE_ID_SIZE, type CacheResponse, + type CacheUUID, + type CacheUpdateNotification, + type CacheWriteResponse, } from "@shared/types/cache"; -import { derived, get, writable, type Writable } from "svelte/store"; +import { writable } from "svelte/store"; // type CacheObjects = { // [key: CacheUUID]: CacheObject; @@ -60,7 +58,6 @@ class CacheStore { } else { // Handle response const messageId = payload.messageId; - if (this.lobby[messageId] != null) { this.lobby[messageId](payload); delete this.lobby[messageId]; @@ -113,7 +110,7 @@ class CacheStore { const metadataPayload = JSON.stringify({ type: "cache-write-metadata", id: writeResp.id, - messageId, + messageId: metadataMessageId, metadata, } as CacheRequest); (await this.sendCachePayload(metadataMessageId, metadataPayload)) as CacheResponse; diff --git a/src/frontend/lib/stores/GraphStore.ts b/src/frontend/lib/stores/GraphStore.ts index 0e0db4ef..c0793307 100644 --- a/src/frontend/lib/stores/GraphStore.ts +++ b/src/frontend/lib/stores/GraphStore.ts @@ -10,6 +10,7 @@ import { constructUIValueStore, type GraphMetadata, NodeStylingStore, + GraphEdge, } from "@shared/ui/UIGraph"; import { writable, get, derived, type Writable, type Readable } from "svelte/store"; import { toolboxStore } from "./ToolboxStore"; @@ -288,31 +289,135 @@ export class GraphStore { }); } + public discernNodeLayers(nodes: GraphNodeUUID[]) { + // Get all edges between chosen nodes + const edges: GraphEdge[] = Object.values(get(this.graphStore).edges).filter( + (e) => nodes.includes(e.nodeUUIDFrom) && nodes.includes(e.nodeUUIDTo) + ); + + // Construct edge mapping { [toNode]: fromNode[] } + const edgeMap: { [key: GraphNodeUUID]: { fromNode: GraphNodeUUID; toAnchor: string }[] } = {}; + edges.forEach((edge) => { + if (edgeMap[edge.nodeUUIDTo] == null) { + edgeMap[edge.nodeUUIDTo] = []; + } + edgeMap[edge.nodeUUIDTo].push({ fromNode: edge.nodeUUIDFrom, toAnchor: edge.anchorIdTo }); + }); + // Sort edgeMap according to anchor order in node + // TODO: OPTIMIZE THIS! + Object.keys(edgeMap).forEach((nodeTo) => { + const signature = this.getNode(nodeTo).signature; + edgeMap[nodeTo] = edgeMap[nodeTo].sort((a, b) => { + const indexA = toolboxStore.getAnchorOrderedIndex(signature, a.toAnchor); + const indexB = toolboxStore.getAnchorOrderedIndex(signature, b.toAnchor); + return indexA - indexB; + }); + }); + + // Find output nodes + const fromNodes = new Set(edges.map((e) => e.nodeUUIDFrom)); + const outputNodes = new Set(nodes.filter((n) => !fromNodes.has(n))); + + // Setup for depth-first search + const layersByOutput: { [key: GraphNodeUUID]: { [key: GraphNodeUUID]: number } } = {}; // { [outputNode]: { [node]: layerNo } } + + function dfs(node: GraphNodeUUID, layers: { [key: GraphNodeUUID]: number }, d: number) { + if (edgeMap[node] == null) return d; + + let maxD = d; + edgeMap[node].forEach(({ fromNode }) => { + if (!layers[fromNode] || layers[fromNode] < d + 1) { + layers[fromNode] = d + 1; + maxD = Math.max(maxD, dfs(fromNode, layers, d + 1)); + } + }); + + return maxD; + } + + // Traverse for layers + const maxDs: { [key: GraphNodeUUID]: number } = {}; // { [outputNode]: maxD } + let maxMaxD = 0; + + outputNodes.forEach((out) => { + layersByOutput[out] = { [out]: 0 }; + + maxDs[out] = dfs(out, layersByOutput[out], 0); + maxMaxD = Math.max(maxMaxD, maxDs[out]); + }); + + // Zip merge columns + const merged: { [key: number]: Set } = {}; + + outputNodes.forEach((out) => { + for (const [n, l] of Object.entries(layersByOutput[out])) { + const i = maxMaxD - (maxDs[out] - l); + + if (merged[i] == null) { + merged[i] = new Set(); + } + + if (!merged[i].has(n)) { + merged[i].add(n); + } + } + }); + + return { layers: merged, numLayers: maxMaxD + 1, edgeMap }; + } + public gravityDisplace(nodes: GraphNodeUUID[], duration: number) { const start = performance.now(); - const nodesSet = new Set(nodes); const FORCE = 3; const NUDGE_DISTANCE = 10; - // ===== NUDGE NODES RANDOMLY ===== // + const X_SNAP_POS = 500; + const X_SNAP_FORCE = 0.2; + const Y_SPLAYING_FORCE = 400; + + const CENTER_FORCE = 0.02; + + const EDGE_TIGHTEN_FORCE = 0.1; + + const NODE_FORCE = 15; + + // ===== DISCERN + APPLY NODE LAYERS ===== // + const { layers, numLayers, edgeMap } = this.discernNodeLayers(nodes); + + // Obtain center x pos + let centerX = 0; + let numNodes = 0; nodes.forEach((node) => { const nodePos = this.getNode(node)?.styling?.pos; if (!nodePos) return; - nodePos.update((pos) => { - return { - x: pos.x + NUDGE_DISTANCE * 2 * (Math.random() - 0.5), - y: pos.y + NUDGE_DISTANCE * 2 * (Math.random() - 0.5), - }; - }); + + centerX += get(nodePos).x; + numNodes++; }); + centerX /= numNodes; + + // Apply initial (layered) placement + for (const [layer, layerNodes] of Object.entries(layers)) { + layerNodes.forEach((node) => { + const nodePos = this.getNode(node)?.styling?.pos; + if (!nodePos) return; + + nodePos.update((pos) => { + return { + x: centerX + X_SNAP_POS * (numLayers / 2 - parseFloat(layer)), + y: pos.y + NUDGE_DISTANCE * 2 * (Math.random() - 0.5), // Random nudge + }; + }); + }); + } // Notify the system of the new node positions const registerPositionUpdate = async () => { await this.updateUIPositions(); - return; // TODO }; + // ========== MAIN LOOP ========== // const tickGravityDisplace = () => { const now = performance.now(); if (now - start > duration * 1000) { @@ -321,113 +426,124 @@ export class GraphStore { return; } + // ===== INITIALIZE FORCES ===== // const forces: { [key: GraphNodeUUID]: { x: number; y: number } } = {}; - // ===== COMPUTE CENTER OF MASS ===== // - const centerMass = { x: 0, y: 0 }; - const CENTER_FORCE = 0.02; - let numNodes = 0; + nodes.forEach((node) => { + forces[node] = { x: 0, y: 0 }; + }); + + // ===== COMPUTE VERTICAL CENTER OF MASS ===== // + let centerMassV = 0; nodes.forEach((node) => { const nodePos = this.getNode(node)?.styling?.pos; if (!nodePos) return; const nodePosVal = get(nodePos); - centerMass.x += nodePosVal.x; - centerMass.y += nodePosVal.y; - numNodes++; + centerMassV += nodePosVal.y; }); - centerMass.x /= numNodes; - centerMass.y /= numNodes; - - nodes.forEach((node) => { - if (!forces[node]) forces[node] = { x: 0, y: 0 }; - }); - - // ===== ADD EDGE DIRECTION REPULSION FORCES ===== // - - const totalDirForce = 0; - // let totalDirForce = 0; - // const dirForces: { [key: GraphNodeUUID]: number } = {}; - // const DIRECTION_FORCE = 5; - // const MAX_DIRECTION_FORCE = 800; + centerMassV /= numNodes; - // const edges = get(this.graphStore).edges; - // Object.keys(edges).forEach((edge) => { - // const edgeObj = edges[edge]; - - // // Add leftward force - // if (nodesSet.has(edgeObj.nodeUUIDFrom)) { - // dirForces[edgeObj.nodeUUIDFrom] = -DIRECTION_FORCE; - // } - - // // Add rightward force - // if (nodesSet.has(edgeObj.nodeUUIDTo)) { - // dirForces[edgeObj.nodeUUIDTo] = DIRECTION_FORCE; - // } - // }); - - // nodes.forEach((node) => { - // if (!dirForces[node]) dirForces[node] = 0; - - // dirForces[node] = Math.max( - // Math.min(dirForces[node], MAX_DIRECTION_FORCE), - // -MAX_DIRECTION_FORCE - // ); - // totalDirForce += dirForces[node]; - - // forces[node].x += dirForces[node]; - // }); - // totalDirForce /= numNodes; - - // ===== ADD CENTER OF MASS ATTRACTION FORCE + COUNTERBALANCE DIRECTION FORCE ===== // + // ===== COMPUTE HORIZONTAL SNAPPING + APPLY CENTER OF MASS ===== // nodes.forEach((node) => { const nodePos = this.getNode(node)?.styling?.pos; if (!nodePos) return; const nodePosVal = get(nodePos); + const snapPoint = Math.round(nodePosVal.x / (0.5 * X_SNAP_POS)) * (0.5 * X_SNAP_POS); + const diff = snapPoint - nodePosVal.x; - const diff = { x: centerMass.x - nodePosVal.x, y: centerMass.y - nodePosVal.y }; - const dist = Math.sqrt(diff.x * diff.x + diff.y * diff.y); - const forceMag = dist * CENTER_FORCE; + // TODO: Check if snap point is a different layer from layerNodes + // then update layerNodes if necessary - if (diff.x !== 0 || diff.y !== 0) { - forces[node].x += (diff.x / dist) * forceMag - totalDirForce; - forces[node].y += (diff.y / dist) * forceMag; - } + // forces[node].x += diff * X_SNAP_FORCE; + forces[node].y += (centerMassV - nodePosVal.y) * CENTER_FORCE; }); - // ===== ADD INTER-NODE REPULSION FORCES ===== // - const NODE_FORCE = 3; - const VERTICAL_SQUASH = 0.75; - nodes.forEach((node) => { - const nodePos = this.getNode(node)?.styling?.pos; - if (!nodePos) return; + // ===== ADD EDGE TIGHTENING FORCES ===== // + for (const layer in layers) { + if (!layers.hasOwnProperty(layer) || parseInt(layer, 10) === numLayers) continue; - const nodePosVal = get(nodePos); - const nodeForce = { x: 0, y: 0 }; + layers[layer].forEach((node) => { + if (edgeMap[node] == null) return; - nodes.forEach((otherNode) => { - if (node === otherNode) return; + const nodePos = this.getNode(node)?.styling?.pos; + if (!nodePos) return; - const otherNodePos = this.getNode(otherNode)?.styling?.pos; - if (!otherNodePos) return; + const nodePosVal = get(nodePos); - const otherNodePosVal = get(otherNodePos); - const diff = { - x: nodePosVal.x - otherNodePosVal.x, - y: nodePosVal.y - otherNodePosVal.y, - }; - const dist = Math.sqrt(diff.x * diff.x + diff.y * diff.y); + edgeMap[node].forEach(({ fromNode }, i) => { + const fromNodePos = this.getNode(fromNode)?.styling?.pos; + if (!fromNodePos) return; - if (diff.x !== 0) nodeForce.x += (NODE_FORCE * diff.x) / dist; + const fromNodePosVal = get(fromNodePos); + const diff = { + x: nodePosVal.x - X_SNAP_POS - fromNodePosVal.x, + y: + nodePosVal.y + (i - edgeMap[node].length / 2) * Y_SPLAYING_FORCE - fromNodePosVal.y, + }; - if (diff.y !== 0) nodeForce.y += (NODE_FORCE * diff.y * VERTICAL_SQUASH) / dist; + // forces[fromNode].x += EDGE_TIGHTEN_FORCE * diff.x; + forces[fromNode].y += EDGE_TIGHTEN_FORCE * diff.y; // Math.sign(diffY) * diffY; + }); }); + } - forces[node].x += nodeForce.x; - forces[node].y += nodeForce.y; + // ===== ADD INTER-NODE REPULSION FORCES WITHIN LAYER ===== // + for (const layerNodes of Object.values(layers)) { + layerNodes.forEach((node) => { + const nodePos = this.getNode(node)?.styling?.pos; + const nodeHeight = this.getNode(node)?.styling?.height; + + if (!nodePos || !nodeHeight) return; + + const nodePosVal = get(nodePos); + const nodeHeightVal = get(nodeHeight); + + layerNodes.forEach((otherNode) => { + if (node === otherNode) return; + + const otherNodePos = this.getNode(otherNode)?.styling?.pos; + const otherNodeHeight = this.getNode(otherNode)?.styling?.height; + if (!otherNodePos || !otherNodeHeight) return; + + const otherNodePosVal = get(otherNodePos); + const otherNodeHeightVal = get(otherNodeHeight); + const diff = { + x: nodePosVal.x - otherNodePosVal.x, + y: nodePosVal.y - otherNodePosVal.y, + }; + + let multiplier = NODE_FORCE; + + // Check nodes not overlapping + if ( + nodePosVal.y > otherNodePosVal.y + ? nodePosVal.y < otherNodePosVal.y + nodeHeightVal + : nodePosVal.y + nodeHeightVal > otherNodePosVal.y + ) { + multiplier *= 4; + } + + // const dist = diff.x * diff.x + diff.y * diff.y; + // forces[node].x += 1000000 * NODE_FORCE * Math.sign(diff.x) / dist; + // forces[node].y += 1000000 * NODE_FORCE * Math.sign(diff.y) / dist; + + // Applied force is simply a linear constant to counterbalance center force + forces[node].y += NODE_FORCE * Math.sign(diff.y); + }); + }); + } + + // ===== COMPUTE GLOBAL COUNTERBALANCE ===== // + const counterbalance = { x: 0, y: 0 }; + nodes.forEach((node) => { + counterbalance.x += forces[node].x; + counterbalance.y += forces[node].y; }); + counterbalance.x /= nodes.length; + counterbalance.y /= nodes.length; // ===== APPLY FORCES ===== // nodes.forEach((node) => { @@ -436,8 +552,8 @@ export class GraphStore { nodePos.update((pos) => { return { - x: pos.x + forces[node].x * FORCE, - y: pos.y + forces[node].y * FORCE, + x: pos.x + (forces[node].x - counterbalance.x) * FORCE, + y: pos.y + (forces[node].y - counterbalance.y) * FORCE, }; }); }); @@ -566,11 +682,3 @@ class GraphMall { // export const graphMall = writable(new GraphMall()); export const graphMall = new GraphMall(); - -/** - * Writable store used to house the panel that house the last used graph. - */ -export const focusedGraphStore = writable<{ panelId: number; graphUUID: GraphUUID }>({ - panelId: -1, - graphUUID: "", -}); diff --git a/src/frontend/lib/stores/MediaStore.ts b/src/frontend/lib/stores/MediaStore.ts index 7cdeb0e4..3701d0f9 100644 --- a/src/frontend/lib/stores/MediaStore.ts +++ b/src/frontend/lib/stores/MediaStore.ts @@ -19,11 +19,21 @@ class MediaStore { } public async outputNodesChanged() { - const projectGraphIds = get(projectsStore.activeProjectGraphIds); - const mediaOutputs = await window.apis.graphApi.getMediaOutputs(projectGraphIds); + // const projectGraphIds = get(projectsStore.activeProjectGraphIds); + const $projectStore = get(projectsStore); + const projectsGraphIds = Object.values($projectStore.projects).flatMap( + (project) => project.graphs + ); + const mediaOutputs = await window.apis.graphApi.getMediaOutputs(projectsGraphIds); this.outputIds.set(mediaOutputs); } + public getMediaOutputListReactive() { + return derived(this.outputIds, (store) => { + return store; + }); + } + // Stop listening for graph changes // public stopMediaReactive(graphUUID: GraphUUID, outputNodeUUID: GraphNodeUUID) { public async stopMediaReactive(mediaId: MediaOutputId) { @@ -99,5 +109,4 @@ class MediaStore { } export const mediaStore = new MediaStore(); - export const nodeIdLastClicked = writable(""); diff --git a/src/frontend/lib/stores/ProjectStore.ts b/src/frontend/lib/stores/ProjectStore.ts index 7e8d3121..905c0f32 100644 --- a/src/frontend/lib/stores/ProjectStore.ts +++ b/src/frontend/lib/stores/ProjectStore.ts @@ -1,10 +1,12 @@ -import { writable, derived, type Readable, get } from "svelte/store"; +import type { SharedProject } from "@shared/types"; +import type { GraphUUID } from "@shared/ui/UIGraph"; import { type UUID } from "@shared/utils/UniqueEntity"; +import { derived, get, writable, type Readable } from "svelte/store"; import { constructLayout, layoutTemplate, type UIProject } from "../Project"; -import type { SharedProject } from "@shared/types"; import { graphMall } from "./GraphStore"; import { cacheStore } from "./CacheStore"; import { mediaStore } from "./MediaStore"; +import { type CacheUUID, type CacheMetadata } from "@shared/types/cache"; type ProjectsStoreState = { projects: UIProject[]; @@ -38,7 +40,7 @@ class ProjectsStore { * and UI has show the new state. */ public handleProjectCreated(projectState: SharedProject, setAsActive = false): void { - const { id, name, saved, layout, graphs } = projectState; + const { id, name, saved, layout, graphs, cache, mediaOutputIds } = projectState; const project: UIProject = { id, @@ -46,6 +48,10 @@ class ProjectsStore { saved: saved ?? false, layout: layout ? constructLayout(layout) : constructLayout(layoutTemplate), graphs: graphs ? graphs : [], + focusedGraph: writable(""), + focusedPanel: writable(""), + cache: cache ? cache : [], + mediaOutputIds: mediaOutputIds ? mediaOutputIds : [], }; this.store.update((state) => { @@ -70,16 +76,18 @@ class ProjectsStore { if (index < 0) return state; const project = state.projects[index]; - const { id, name, saved, layout, graphs } = changedState; - + const { id, name, saved, layout, graphs, cache, mediaOutputIds } = changedState; const newProject: UIProject = { id, name: name ? name : project.name, saved: saved ?? project.saved, layout: layout ? constructLayout(layout) : project.layout, graphs: graphs ? graphs : project.graphs, + focusedGraph: project.focusedGraph, + focusedPanel: project.focusedPanel, + cache: cache ?? project.cache, + mediaOutputIds: mediaOutputIds ?? project.mediaOutputIds, }; - state.projects[index] = newProject; if (state.activeProject?.id === newProject.id) { @@ -121,13 +129,7 @@ class ProjectsStore { */ public async closeProject(projectId: UUID): Promise { const project = get(this.store).projects.find((p) => p.id === projectId); - // if (project) await window.apis.graphApi.deleteGraphs(project.graphs); await window.apis.projectApi.closeProject(projectId, project?.graphs); - - // Clear all stores once removed - await cacheStore.deleteAllAssets(); - await mediaStore.deleteAllMedia(); - await graphMall.clearAllGraphs(); } /** @@ -145,6 +147,10 @@ class ProjectsStore { } } + public getActiveProjectId(): UUID | null { + return get(this.store).activeProject?.id || null; + } + public async handleProjectSaving(projectId: UUID) { const project = get(this.store).projects.find((p) => p.id === projectId); if (!project) return; @@ -183,6 +189,29 @@ class ProjectsStore { }); } + public getReactiveProjectCacheMap(projectId: UUID): Readable> { + return derived([this.store, cacheStore], ([$projectStore, $cacheStore]) => { + const cacheIds = $projectStore.projects.find((p) => p.id === projectId)?.cache || []; + const cacheObjects = new Map(); + + cacheIds.forEach((id) => { + const cacheMetadata = $cacheStore[id]; + + if (cacheMetadata) { + cacheObjects.set(id, cacheMetadata); + } + }); + + return cacheObjects; + }); + } + + public getReactiveActiveProjectCacheIds(): Readable { + return derived(this.store, ($store) => { + return $store.activeProject?.cache || []; + }); + } + public get subscribe() { return this.store.subscribe; } diff --git a/src/frontend/lib/stores/ShortcutStore.ts b/src/frontend/lib/stores/ShortcutStore.ts index e4b2d369..900090e4 100644 --- a/src/frontend/lib/stores/ShortcutStore.ts +++ b/src/frontend/lib/stores/ShortcutStore.ts @@ -57,6 +57,11 @@ const defaultShortcuts: Omit[] = [ title: "Create New Project", value: ["meta+[KeyN]", "ctrl+[KeyN]"], }, + { + id: "blix.projects.openProject", + title: "Open Project", + value: ["meta+[KeyO]", "ctrl+[KeyO]"], + }, { id: "blix.settings.toggle", title: "Toggle Settings", @@ -84,6 +89,33 @@ const defaultShortcuts: Omit[] = [ }, ]; +const shortcutIconFilterMap: ReadonlyMap = new Map< + string | RegExp, + string +>([ + ["Comma", ","], + ["Equal", "="], + ["Minus", "-"], + ["Period", "."], + ["Backslash", "\\"], + ["Backspace", "⌫"], + ["meta", "⌘"], + ["alt", "⌥"], + ["ctrl", "⌃"], + ["shift", "⇧"], + ["ArrowDown", "↓"], + ["ArrowUp", "↑"], + ["ArrowLeft", "←"], + ["ArrowRight", "→"], + ["BracketRight", "]"], + ["BracketLeft", "["], + ["Digit", ""], + ["Key", ""], + ["[", ""], + ["]", ""], + [/\+/g, " "], +]); + export type ShortcutAction = `${string}.${string}`; // Actions must be nested at least one layer deep export type ShortcutString = string; @@ -275,6 +307,28 @@ class ShortcutStore { }); } + public getFormattedShortcutsForActionReactive( + action: ShortcutAction + ): Readable { + return derived(this.shortcuts, ($shortcuts) => { + const shortcut = $shortcuts.get(action); + + if (!shortcut) { + return []; + } + + const hotkeys = shortcut.value.map((combo) => { + for (const [key, value] of shortcutIconFilterMap.entries()) { + combo = combo.replace(key, value); + } + + return combo; + }); + + return hotkeys; + }); + } + public getShortcutsReactive(): Readable { return derived(this.shortcuts, ($shortcuts) => { return Array.from($shortcuts.values()); @@ -287,31 +341,7 @@ class ShortcutStore { shortcuts.forEach((shortcut) => { shortcut.value = shortcut.value.map((combo) => { - const map = new Map([ - ["Comma", ","], - ["Equal", "="], - ["Minus", "-"], - ["Period", "."], - ["Backslash", "\\"], - ["Backspace", "⌫"], - ["meta", "⌘"], - ["alt", "⌥"], - ["ctrl", "⌃"], - ["shift", "⇧"], - ["ArrowDown", "↓"], - ["ArrowUp", "↑"], - ["ArrowLeft", "←"], - ["ArrowRight", "→"], - ["BracketRight", "]"], - ["BracketLeft", "["], - ["Digit", ""], - ["Key", ""], - ["[", ""], - ["]", ""], - [/\+/g, " "], - ]); - - for (const [key, value] of map.entries()) { + for (const [key, value] of shortcutIconFilterMap.entries()) { combo = combo.replace(key, value); } diff --git a/src/frontend/lib/stores/ToolboxStore.ts b/src/frontend/lib/stores/ToolboxStore.ts index d70539f3..f86a63fd 100644 --- a/src/frontend/lib/stores/ToolboxStore.ts +++ b/src/frontend/lib/stores/ToolboxStore.ts @@ -36,6 +36,18 @@ class ToolboxStore { public getNode(signature: NodeSignature) { return get(this.store)[signature]; } + + public getAnchorOrderedIndex(signature: NodeSignature, anchorId: string) { + const node = this.getNode(signature); + if (!node) return -1; + + for (let i = 0; i < node.inputs.length; i++) { + if (node.inputs[i].id === anchorId) { + return i; + } + } + return -1; + } } // export const graphMall = writable(new GraphMall()); diff --git a/src/frontend/ui/base/App.svelte b/src/frontend/ui/base/App.svelte index f5b0840c..242c3f03 100644 --- a/src/frontend/ui/base/App.svelte +++ b/src/frontend/ui/base/App.svelte @@ -13,9 +13,9 @@ import Shortcuts from "../../ui/utils/Shortcuts.svelte"; import { settingsStore } from "../../lib/stores/SettingsStore"; import { confetti } from "@neoconfetti/svelte"; + import { projectsStore } from "../../lib/stores/ProjectStore"; const testing = false; - let showSettings = false; let showSplash = true; @@ -34,6 +34,10 @@ onMount(async () => { await initAPIs(); }); + + // projectsStore.subscribe((state) => { + // console.log(state); + // }); @@ -63,6 +67,9 @@ +
+ +
{:else}
@@ -70,10 +77,6 @@
{/if} -
- -
- @@ -83,6 +86,22 @@ @tailwind components; @tailwind utilities; + :root { + --navbar-height: 2rem; + + --color-primary-50: 255, 241, 242; + --color-primary-100: 255, 228, 230; + --color-primary-200: 254, 205, 211; + --color-primary-300: 253, 164, 174; + --color-primary-400: 251, 113, 132; + --color-primary-500: 244, 62, 92; + --color-primary-600: 225, 29, 71; + --color-primary-700: 190, 18, 59; + --color-primary-800: 159, 18, 56; + --color-primary-900: 136, 19, 54; + --color-primary-950: 76, 5, 25; + } + body { padding: 0px; } @@ -94,9 +113,6 @@ display: flex; position: relative; } - :root { - --navbar-height: 2rem; - } div.navbar { width: 100%; diff --git a/src/frontend/ui/base/ProjectBar.svelte b/src/frontend/ui/base/ProjectBar.svelte index df5c4837..7e4e171f 100644 --- a/src/frontend/ui/base/ProjectBar.svelte +++ b/src/frontend/ui/base/ProjectBar.svelte @@ -4,6 +4,7 @@ import { onMount, tick } from "svelte"; import { fade } from "svelte/transition"; import { commandStore } from "../../lib/stores/CommandStore"; + import { blixStore } from "../../lib/stores/BlixStore"; function createProject() { projectsStore.createProject(); @@ -46,7 +47,7 @@ {#if !project.saved}
{/if} @@ -58,13 +59,13 @@ viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" - class="ml-auto h-4 w-4 shrink-0 rounded-md stroke-zinc-500 p-[0.1em] hover:bg-zinc-600 hover:stroke-rose-500/70" + class="ml-auto h-4 w-4 shrink-0 rounded-md stroke-zinc-500 p-[0.1em] hover:bg-zinc-600 hover:stroke-primary-500/70" >
{/each} - {#if $projectsStore.projects.length === 0} + {#if !$blixStore.production}
Banner - AI Photo Editor
-
+ The Everything Editor
+


Recent projects


@@ -46,30 +46,30 @@ {#each projects as project (project.path)}
  • - + {handlePath(project.path)} - + - {project.lastEdited} + {project.lastEdited.slice(0, project.lastEdited.lastIndexOf(":"))}
  • {/each} {/await} -



    +
    diff --git a/src/frontend/ui/base/layout/Layout.svelte b/src/frontend/ui/base/layout/Layout.svelte index 50643b41..5041d8f4 100644 --- a/src/frontend/ui/base/layout/Layout.svelte +++ b/src/frontend/ui/base/layout/Layout.svelte @@ -1,23 +1,59 @@ -
    - {#if $projectsStore.activeProject} - {#key $projectsStore.activeProject.id} - - {/key} - {:else} -
    -
    -

    No projects!

    -

    Create a project to begin creating

    +{#if $projectsStore.activeProject} + {#each $projectsStore.projects || [] as project (project.id)} +
    + +
    + {/each} +{:else} +
    +
    +
    +

    Open a project

    + {#each $openProjectHotkeys as hotkey} + + {hotkey} + + {/each} +
    +
    +

    Create a new project

    + {#each $newProjectHotkeys as hotkey} + + {hotkey} + + {/each}
    - {/if} -
    +
    +{/if} + + diff --git a/src/frontend/ui/base/layout/PanelBlipVane.svelte b/src/frontend/ui/base/layout/PanelBlipVane.svelte index cbfbc35b..e07106ed 100644 --- a/src/frontend/ui/base/layout/PanelBlipVane.svelte +++ b/src/frontend/ui/base/layout/PanelBlipVane.svelte @@ -32,8 +32,6 @@ let panelWidth: number; let panelHeight: number; - - $: console.log(panelWidth, panelHeight); {#if icon !== null} diff --git a/src/frontend/ui/base/palette/Palette.svelte b/src/frontend/ui/base/palette/Palette.svelte index dc5c5115..f0ee6084 100644 --- a/src/frontend/ui/base/palette/Palette.svelte +++ b/src/frontend/ui/base/palette/Palette.svelte @@ -1,10 +1,10 @@ + +
    + +
    + + diff --git a/src/frontend/ui/base/settings/utils/Dropdown.svelte b/src/frontend/ui/base/settings/utils/Dropdown.svelte index a2d07f34..ae404bb4 100644 --- a/src/frontend/ui/base/settings/utils/Dropdown.svelte +++ b/src/frontend/ui/base/settings/utils/Dropdown.svelte @@ -19,7 +19,7 @@