From 0de2197998fa9f670c8167ffefcbb00f01465d5a Mon Sep 17 00:00:00 2001 From: Julian Bilcke Date: Wed, 24 Jul 2024 15:45:02 +0200 Subject: [PATCH] upgrade to openclap 0.1.1 --- package-lock.json | 1580 +++++++++++++---- package.json | 15 +- playwright.config.ts | 4 + src/components/monitor/index.tsx | 2 +- src/components/toolbars/bottom-bar/index.tsx | 2 +- .../toolbars/bottom-bar/metrics/index.tsx | 8 +- .../editors-menu/EditorsSideMenuItem.tsx | 6 +- src/components/toolbars/top-menu/index.tsx | 35 +- .../tree-browsers/stores/useEntityLibrary.ts | 6 +- .../tree-browsers/stores/useProjectLibrary.ts | 6 +- src/experiments/grading/README.md | 3 + src/experiments/grading/applyColorGrading.ts | 225 +++ .../grading/applyColorGradingDemo.ts | 121 ++ .../grading/filters/DEPRECATED_analogFilm.ts | 171 ++ src/experiments/grading/filters/analogLens.ts | 228 +++ src/experiments/grading/filters/cinematic.ts | 98 + .../grading/filters/colorMapping.ts | 53 + .../grading/filters/colorTemperature.ts | 103 ++ .../grading/filters/crossProcessing.ts | 126 ++ .../grading/filters/filmDegradation.ts | 104 ++ src/experiments/grading/filters/infrared.ts | 87 + src/experiments/grading/filters/lomography.ts | 143 ++ .../grading/filters/splitToning.ts | 143 ++ .../grading/filters/toneMapping.ts | 148 ++ .../grading/filters/vintageFilm.ts | 299 ++++ src/experiments/grading/types.ts | 22 + src/lib/utils/formatSegmentForExport.test.ts | 13 +- src/lib/utils/getTypeAndExtension.test.ts | 7 +- src/services/ui/theme.ts | 10 +- tsconfig.json | 3 +- 30 files changed, 3423 insertions(+), 348 deletions(-) create mode 100644 src/experiments/grading/README.md create mode 100644 src/experiments/grading/applyColorGrading.ts create mode 100644 src/experiments/grading/applyColorGradingDemo.ts create mode 100644 src/experiments/grading/filters/DEPRECATED_analogFilm.ts create mode 100644 src/experiments/grading/filters/analogLens.ts create mode 100644 src/experiments/grading/filters/cinematic.ts create mode 100644 src/experiments/grading/filters/colorMapping.ts create mode 100644 src/experiments/grading/filters/colorTemperature.ts create mode 100644 src/experiments/grading/filters/crossProcessing.ts create mode 100644 src/experiments/grading/filters/filmDegradation.ts create mode 100644 src/experiments/grading/filters/infrared.ts create mode 100644 src/experiments/grading/filters/lomography.ts create mode 100644 src/experiments/grading/filters/splitToning.ts create mode 100644 src/experiments/grading/filters/toneMapping.ts create mode 100644 src/experiments/grading/filters/vintageFilm.ts create mode 100644 src/experiments/grading/types.ts diff --git a/package-lock.json b/package-lock.json index ebb307a4..44c7896d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,11 +9,11 @@ "version": "0.0.5", "license": "GPL-3.0-only", "dependencies": { - "@aitube/broadway": "0.0.22", - "@aitube/clap": "0.0.30", - "@aitube/clapper-services": "0.0.35", - "@aitube/engine": "0.0.26", - "@aitube/timeline": "0.0.45", + "@aitube/broadway": "0.1.1", + "@aitube/clap": "0.1.1", + "@aitube/clapper-services": "0.1.1", + "@aitube/engine": "0.1.1", + "@aitube/timeline": "0.1.1", "@fal-ai/serverless-client": "^0.13.0", "@ffmpeg/ffmpeg": "^0.12.10", "@ffmpeg/util": "^0.12.1", @@ -58,6 +58,7 @@ "@types/dom-speech-recognition": "^0.0.4", "@xenova/transformers": "github:xenova/transformers.js#v3", "autoprefixer": "10.4.19", + "base64-arraybuffer": "^1.0.2", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "cmdk": "^0.2.1", @@ -120,6 +121,7 @@ "@types/react-dom": "^18", "@types/uuid": "^9.0.8", "@vitejs/plugin-react": "^4.3.1", + "@webgpu/types": "^0.1.44", "electron": "^31.2.1", "eslint": "^8", "eslint-config-next": "14.2.5", @@ -136,37 +138,37 @@ } }, "node_modules/@aitube/broadway": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@aitube/broadway/-/broadway-0.0.22.tgz", - "integrity": "sha512-Koliw6Hg8QWx+iHqbaSdqpPmS21/AMzI7Bw5ecrNvRoURPEzJaBHjKo+q5Xk8AESHBU2ChNg+DLfjkgV1yHgyA==", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@aitube/broadway/-/broadway-0.1.1.tgz", + "integrity": "sha512-OqWyAH48yp3XxmkC6n2r0V0bDGGIC4WD0stzZYrHneMmwI3D1TxSYj7yUCqhmYolwhAvnaYOWl43LhW6/rxrlA==", "dependencies": { "@datagica/parse-entities": "^0.3.0", "@datagica/parse-names": "^0.0.8", "indexeddb-fs": "^2.1.5" }, "peerDependencies": { - "@aitube/clap": "0.0.30", - "@aitube/colors": "0.0.9" + "@aitube/clap": "0.1.1", + "@aitube/colors": "0.1.1" } }, "node_modules/@aitube/clap": { - "version": "0.0.30", - "resolved": "https://registry.npmjs.org/@aitube/clap/-/clap-0.0.30.tgz", - "integrity": "sha512-vBIN8+heIVHYBTY0+Rzdx6SSAiALXlzrkn02SiBCCxDdWV3qPoiQPoY78OcIkVamNZenEZ5HRK/GpuA7fdoLEQ==", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@aitube/clap/-/clap-0.1.1.tgz", + "integrity": "sha512-zKo3HQTM2kIlTTsZS7Pj+nYt5hYv0hyTQnd+Zj3C4gsoHEY8ua2JdIQTsBULD8zi3s4tKueEFv03ZwtD8q2Z1w==", "dependencies": { "pure-uuid": "^1.8.1" }, "peerDependencies": { - "yaml": "^2.4.5" + "yaml": "^2.5.0" } }, "node_modules/@aitube/clapper-services": { - "version": "0.0.35", - "resolved": "https://registry.npmjs.org/@aitube/clapper-services/-/clapper-services-0.0.35.tgz", - "integrity": "sha512-qI0qj+8tKgv6vbhBvy+RKItITSIHsjdVq6NAuxjNwXYFhxgMFuZpj34gB0AcGH9ZShl7ZEGlqptU3B9pOpqa1A==", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@aitube/clapper-services/-/clapper-services-0.1.1.tgz", + "integrity": "sha512-61fEweTndBE5Smf/Z5MZcs1ikXVZXuYD3+vAK4I2nCed5zi1Os7vKkg+M/+2IJVaGKhO45NcAKY18iyOypNzIA==", "peerDependencies": { - "@aitube/clap": "0.0.30", - "@aitube/timeline": "0.0.45", + "@aitube/clap": "0.1.1", + "@aitube/timeline": "0.1.1", "@monaco-editor/react": "4.6.0", "monaco-editor": "0.50.0", "react": "*", @@ -175,32 +177,32 @@ } }, "node_modules/@aitube/colors": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/@aitube/colors/-/colors-0.0.9.tgz", - "integrity": "sha512-Svu7nI7sVfoWrvEIdG8c0c2irhRPXphsTIh9rnesqcEJGtz/VIOqQBrYBKI+htTfGX5EeM5Q/rr7zUYrfK+pfQ==", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@aitube/colors/-/colors-0.1.1.tgz", + "integrity": "sha512-nat4dbIzTpv4UmgTLRn9ulRXrazNDh6ClhLkkEV+tNMAlx22T3btMjyKCmhpZVjL/zMpvDE/rf8oJvWiuzOa5g==", "peer": true, "peerDependencies": { - "@aitube/clap": "0.0.30" + "@aitube/clap": "0.1.1" } }, "node_modules/@aitube/engine": { - "version": "0.0.26", - "resolved": "https://registry.npmjs.org/@aitube/engine/-/engine-0.0.26.tgz", - "integrity": "sha512-Wk5kfMo5T0Gr3XjQiJGJozmtQdPdq2U6Bl0SDYyeUyLBSM5eAmiLNf+mwsy8MqDpsIdGXIeJ8IJKlChEu0Uzkw==", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@aitube/engine/-/engine-0.1.1.tgz", + "integrity": "sha512-ZhmNwzuakkHWO/ZhyPXVKLXzZfFsSIvGS5awBjqqb5KKFb8gIWTi3t/wRfCeoQN2Ngdhut4jZWJhBuh5nChnSg==", "peerDependencies": { - "@aitube/clap": "0.0.30" + "@aitube/clap": "0.1.1" } }, "node_modules/@aitube/timeline": { - "version": "0.0.45", - "resolved": "https://registry.npmjs.org/@aitube/timeline/-/timeline-0.0.45.tgz", - "integrity": "sha512-5nDn4O7z72WvZeXVAzGn+HjRhKvTpZb4OAnOMmHCpQ5bwaublaVYN1JV8wurgh+KN/N1IQgUbTe2NSQuF9EWkQ==", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@aitube/timeline/-/timeline-0.1.1.tgz", + "integrity": "sha512-cUxgIqkZ1r1M7yaqk+VpJKaeN1gpFxsFMz7REkC5XZlUyt4cHeHSQT/njMFsYp0kOvKAcCUDZpW8oEyiZp45nQ==", "dependencies": { "date-fns": "^3.6.0", "react-virtualized-auto-sizer": "^1.0.24" }, "peerDependencies": { - "@aitube/clap": "0.0.30", + "@aitube/clap": "0.1.1", "@radix-ui/react-slider": "^1.1.2", "@react-spring/three": "^9.7.3", "@react-spring/types": "^9.7.3", @@ -209,8 +211,8 @@ "clsx": "^2.1.1", "react": "*", "react-dom": "*", - "tailwind-merge": "^2.3.0", - "tailwindcss": "^3.4.3", + "tailwind-merge": "^2.4.0", + "tailwindcss": "^3.4.6", "three": "^0.164.1", "zustand": "4.5.2" } @@ -254,9 +256,9 @@ } }, "node_modules/@anthropic-ai/sdk/node_modules/@types/node": { - "version": "18.19.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.41.tgz", - "integrity": "sha512-LX84pRJ+evD2e2nrgYCHObGWkiQJ1mL+meAgbvnwk/US6vmMY7S2ygBTGV2Jw91s9vUsLSXeDEkUHZIJGLrhsg==", + "version": "18.19.42", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.42.tgz", + "integrity": "sha512-d2ZFc/3lnK2YCYhos8iaNIYu9Vfhr92nHiyJHRltXWjXUBjEE+A4I58Tdbnw4VhggSW+2j5y5gTrLs4biNnubg==", "dependencies": { "undici-types": "~5.26.4" } @@ -837,9 +839,9 @@ } }, "node_modules/@aws-sdk/credential-providers": { - "version": "3.616.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.616.0.tgz", - "integrity": "sha512-uyscpYV21lr24FNFu8ZkIKzOCD/xoysRci9HmShtKBY/FixwZRlLv7aUpqH7xcLd7sgsQwa2UD/7s9PKj/DXSg==", + "version": "3.617.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.617.0.tgz", + "integrity": "sha512-ZXzdnHI7Tfsk7Y2hezlhxFHlG2VM5tTWQPZ0qZ/cYCzZxyZfsmSFr/rMi6wJGB2J6ZDbbAohEoOWrEblHVq7Cw==", "dependencies": { "@aws-sdk/client-cognito-identity": "3.616.0", "@aws-sdk/client-sso": "3.616.0", @@ -1618,6 +1620,15 @@ "statuses": "^2.0.1" } }, + "node_modules/@bundled-es-modules/tough-cookie": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/tough-cookie/-/tough-cookie-0.1.6.tgz", + "integrity": "sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==", + "dependencies": { + "@types/tough-cookie": "^4.0.5", + "tough-cookie": "^4.1.4" + } + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -2823,6 +2834,15 @@ "node": ">=14.14" } }, + "node_modules/@emnapi/runtime": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.2.0.tgz", + "integrity": "sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@emotion/is-prop-valid": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.0.tgz", @@ -2846,294 +2866,1034 @@ "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" }, - "node_modules/@esbuild/darwin-arm64": { + "node_modules/@esbuild/aix-ppc64": { "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", "cpu": [ - "arm64" + "ppc64" ], "dev": true, "optional": true, "os": [ - "darwin" + "aix" ], "engines": { "node": ">=12" } }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + "node": ">=12" } }, - "node_modules/@eslint-community/regexpp": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], "dev": true, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + "node": ">=12" } }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=12" } }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "node_modules/@eslint/eslintrc/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], "dev": true, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], "dev": true, + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=12" } }, - "node_modules/@fal-ai/serverless-client": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@fal-ai/serverless-client/-/serverless-client-0.13.0.tgz", - "integrity": "sha512-Nkb/5YXJIPQHzM79+fRb1LZ1zQLSSvNhDVL2l62sN6/H4XqAWueIOqAAvPF8ds39uSGn8nF1WQV1mt7raVMlWw==", - "dependencies": { - "@msgpack/msgpack": "^3.0.0-beta2", - "eventsource-parser": "^1.1.2", - "robot3": "^0.4.1", - "uuid-random": "^1.3.2" - }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=18.0.0" + "node": ">=12" } }, - "node_modules/@ffmpeg/ffmpeg": { - "version": "0.12.10", - "resolved": "https://registry.npmjs.org/@ffmpeg/ffmpeg/-/ffmpeg-0.12.10.tgz", - "integrity": "sha512-lVtk8PW8e+NUzGZhPTWj2P1J4/NyuCrbDD3O9IGpSeLYtUZKBqZO8CNj1WYGghep/MXoM8e1qVY1GztTkf8YYQ==", - "dependencies": { - "@ffmpeg/types": "^0.12.2" - }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=18.x" + "node": ">=12" } }, - "node_modules/@ffmpeg/types": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@ffmpeg/types/-/types-0.12.2.tgz", - "integrity": "sha512-NJtxwPoLb60/z1Klv0ueshguWQ/7mNm106qdHkB4HL49LXszjhjCCiL+ldHJGQ9ai2Igx0s4F24ghigy//ERdA==", + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=16.x" + "node": ">=12" } }, - "node_modules/@ffmpeg/util": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/@ffmpeg/util/-/util-0.12.1.tgz", - "integrity": "sha512-10jjfAKWaDyb8+nAkijcsi9wgz/y26LOc1NKJradNMyCIl6usQcBbhkjX5qhALrSBcOy6TOeksunTYa+a03qNQ==", + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=18.x" + "node": ">=12" } }, - "node_modules/@floating-ui/core": { - "version": "1.6.5", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.5.tgz", - "integrity": "sha512-8GrTWmoFhm5BsMZOTHeGD2/0FLKLQQHvO/ZmQga4tKempYRLz8aqJGqXVuQgisnMObq2YZ2SgkwctN1LOOxcqA==", - "dependencies": { - "@floating-ui/utils": "^0.2.5" + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/@floating-ui/dom": { - "version": "1.6.8", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.8.tgz", - "integrity": "sha512-kx62rP19VZ767Q653wsP1XZCGIirkE09E0QUGNYTM/ttbbQHqcGPdSfWFxUyyNLc/W6aoJRBajOSXhP6GXjC0Q==", - "dependencies": { - "@floating-ui/core": "^1.6.0", - "@floating-ui/utils": "^0.2.5" + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/@floating-ui/react-dom": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.1.tgz", - "integrity": "sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==", - "dependencies": { - "@floating-ui/dom": "^1.0.0" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/@floating-ui/utils": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.5.tgz", - "integrity": "sha512-sTcG+QZ6fdEUObICavU+aB3Mp8HY4n14wYHdxK4fXjPmv3PXZZeY5RaguJmGyeH/CJQhX3fqKUtS4qc1LoHwhQ==" + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } }, - "node_modules/@gar/promisify": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", - "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", - "dev": true + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } }, - "node_modules/@gradio/client": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@gradio/client/-/client-1.3.0.tgz", - "integrity": "sha512-hy7brBNQGmJLUQ69gOMrcp4LGHAPknFy5Jl30EF0+VEBSjv8e3f7hPAq15QPJWY9SDDie7Mmg+epx7H+V1a8og==", + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, "dependencies": { - "@types/eventsource": "^1.1.15", - "bufferutil": "^4.0.7", - "eventsource": "^2.0.2", - "fetch-event-stream": "^0.1.5", - "msw": "^2.2.1", - "semiver": "^1.1.0", - "textlinestream": "^1.1.1", - "typescript": "^5.0.0", - "ws": "^8.13.0" + "eslint-visitor-keys": "^3.3.0" }, "engines": { - "node": ">=18.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@huggingface/hub": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/@huggingface/hub/-/hub-0.15.1.tgz", - "integrity": "sha512-uHb4aFkJDoGfLeRHfFTjkI36Z8IV6Z1c+KzhMDqUSC56opyr7Mn1Nsx7Rri/C7KDwROhQfBp/fOOqqjTzn6Cgg==", + "node_modules/@eslint-community/regexpp": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, "dependencies": { - "@huggingface/tasks": "^0.10.6", - "hash-wasm": "^4.9.0" + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" }, "engines": { - "node": ">=18" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@huggingface/inference": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@huggingface/inference/-/inference-2.8.0.tgz", - "integrity": "sha512-Ti681P1qckcCAqgzmL53jBnluPuZGelmMIuXNjgAwC5+RIjF4S0SDQu6oy44ZTwekwNp2ETaZ2sXsOk+45aC4w==", + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, "dependencies": { - "@huggingface/tasks": "^0.11.2" + "type-fest": "^0.20.2" }, "engines": { - "node": ">=18" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@huggingface/inference/node_modules/@huggingface/tasks": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/@huggingface/tasks/-/tasks-0.11.3.tgz", - "integrity": "sha512-IYq4OdlySdscjkFwm6iIqP1ZgKl4OGhvQFJWI7Yxpq2V8RmXcgIjiqk/65S6Ap7i+eyCdlOC4qweVy/ICNE0JA==" + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@fal-ai/serverless-client": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@fal-ai/serverless-client/-/serverless-client-0.13.0.tgz", + "integrity": "sha512-Nkb/5YXJIPQHzM79+fRb1LZ1zQLSSvNhDVL2l62sN6/H4XqAWueIOqAAvPF8ds39uSGn8nF1WQV1mt7raVMlWw==", + "dependencies": { + "@msgpack/msgpack": "^3.0.0-beta2", + "eventsource-parser": "^1.1.2", + "robot3": "^0.4.1", + "uuid-random": "^1.3.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@ffmpeg/ffmpeg": { + "version": "0.12.10", + "resolved": "https://registry.npmjs.org/@ffmpeg/ffmpeg/-/ffmpeg-0.12.10.tgz", + "integrity": "sha512-lVtk8PW8e+NUzGZhPTWj2P1J4/NyuCrbDD3O9IGpSeLYtUZKBqZO8CNj1WYGghep/MXoM8e1qVY1GztTkf8YYQ==", + "dependencies": { + "@ffmpeg/types": "^0.12.2" + }, + "engines": { + "node": ">=18.x" + } + }, + "node_modules/@ffmpeg/types": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@ffmpeg/types/-/types-0.12.2.tgz", + "integrity": "sha512-NJtxwPoLb60/z1Klv0ueshguWQ/7mNm106qdHkB4HL49LXszjhjCCiL+ldHJGQ9ai2Igx0s4F24ghigy//ERdA==", + "engines": { + "node": ">=16.x" + } + }, + "node_modules/@ffmpeg/util": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/@ffmpeg/util/-/util-0.12.1.tgz", + "integrity": "sha512-10jjfAKWaDyb8+nAkijcsi9wgz/y26LOc1NKJradNMyCIl6usQcBbhkjX5qhALrSBcOy6TOeksunTYa+a03qNQ==", + "engines": { + "node": ">=18.x" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.5.tgz", + "integrity": "sha512-8GrTWmoFhm5BsMZOTHeGD2/0FLKLQQHvO/ZmQga4tKempYRLz8aqJGqXVuQgisnMObq2YZ2SgkwctN1LOOxcqA==", + "dependencies": { + "@floating-ui/utils": "^0.2.5" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.8.tgz", + "integrity": "sha512-kx62rP19VZ767Q653wsP1XZCGIirkE09E0QUGNYTM/ttbbQHqcGPdSfWFxUyyNLc/W6aoJRBajOSXhP6GXjC0Q==", + "dependencies": { + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.5" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.1.tgz", + "integrity": "sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==", + "dependencies": { + "@floating-ui/dom": "^1.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.5.tgz", + "integrity": "sha512-sTcG+QZ6fdEUObICavU+aB3Mp8HY4n14wYHdxK4fXjPmv3PXZZeY5RaguJmGyeH/CJQhX3fqKUtS4qc1LoHwhQ==" + }, + "node_modules/@gar/promisify": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", + "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", + "dev": true + }, + "node_modules/@gradio/client": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@gradio/client/-/client-1.4.0.tgz", + "integrity": "sha512-4QrJrUz0j75/2SpiHfhQmKmEuFcTbbuA8hpPFb+G0fvT1kd9fRPf1LhrwvsxFQaP3byZs+IeiV0dzCLveHgtfA==", + "dependencies": { + "@types/eventsource": "^1.1.15", + "bufferutil": "^4.0.7", + "eventsource": "^2.0.2", + "fetch-event-stream": "^0.1.5", + "msw": "^2.2.1", + "semiver": "^1.1.0", + "textlinestream": "^1.1.1", + "typescript": "^5.0.0", + "ws": "^8.13.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@huggingface/hub": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@huggingface/hub/-/hub-0.15.1.tgz", + "integrity": "sha512-uHb4aFkJDoGfLeRHfFTjkI36Z8IV6Z1c+KzhMDqUSC56opyr7Mn1Nsx7Rri/C7KDwROhQfBp/fOOqqjTzn6Cgg==", + "dependencies": { + "@huggingface/tasks": "^0.10.6", + "hash-wasm": "^4.9.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@huggingface/inference": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@huggingface/inference/-/inference-2.8.0.tgz", + "integrity": "sha512-Ti681P1qckcCAqgzmL53jBnluPuZGelmMIuXNjgAwC5+RIjF4S0SDQu6oy44ZTwekwNp2ETaZ2sXsOk+45aC4w==", + "dependencies": { + "@huggingface/tasks": "^0.11.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@huggingface/inference/node_modules/@huggingface/tasks": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/@huggingface/tasks/-/tasks-0.11.3.tgz", + "integrity": "sha512-IYq4OdlySdscjkFwm6iIqP1ZgKl4OGhvQFJWI7Yxpq2V8RmXcgIjiqk/65S6Ap7i+eyCdlOC4qweVy/ICNE0JA==" + }, + "node_modules/@huggingface/jinja": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@huggingface/jinja/-/jinja-0.2.2.tgz", + "integrity": "sha512-/KPde26khDUIPkTGU82jdtTW9UAuvUTumCAbFs/7giR0SxsvZC4hru51PBvpijH6BVkHcROcvZM/lpy5h1jRRA==", + "engines": { + "node": ">=18" + } + }, + "node_modules/@huggingface/tasks": { + "version": "0.10.22", + "resolved": "https://registry.npmjs.org/@huggingface/tasks/-/tasks-0.10.22.tgz", + "integrity": "sha512-sCtp+A6sq6NXoUU7NXuXWoVNNjKddk1GTQIh3cJ6illF8S4zmFoerCVRvFf19BdgICGvF+RVZiv9sGGK9KRDTg==" + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.4.tgz", + "integrity": "sha512-p0suNqXufJs9t3RqLBO6vvrgr5OhgbWp76s5gTRvdmxmuv9E1rcaqGUsl3l4mKVmXPkTkTErXediAui4x+8PSA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.0.2" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.4.tgz", + "integrity": "sha512-0l7yRObwtTi82Z6ebVI2PnHT8EB2NxBgpK2MiKJZJ7cz32R4lxd001ecMhzzsZig3Yv9oclvqqdV93jo9hy+Dw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.0.2" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.2.tgz", + "integrity": "sha512-tcK/41Rq8IKlSaKRCCAuuY3lDJjQnYIW1UXU1kxcEKrfL8WR7N6+rzNoOxoQRJWTAECuKwgAHnPvqXGN8XfkHA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "macos": ">=11", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.2.tgz", + "integrity": "sha512-Ofw+7oaWa0HiiMiKWqqaZbaYV3/UGL2wAPeLuJTx+9cXpCRdvQhCLG0IH8YGwM0yGWGLpsF4Su9vM1o6aer+Fw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "macos": ">=10.13", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.2.tgz", + "integrity": "sha512-iLWCvrKgeFoglQxdEwzu1eQV04o8YeYGFXtfWU26Zr2wWT3q3MTzC+QTCO3ZQfWd3doKHT4Pm2kRmLbupT+sZw==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.2.tgz", + "integrity": "sha512-x7kCt3N00ofFmmkkdshwj3vGPCnmiDh7Gwnd4nUwZln2YjqPxV1NlTyZOvoDWdKQVDL911487HOueBvrpflagw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.2.tgz", + "integrity": "sha512-cmhQ1J4qVhfmS6szYW7RT+gLJq9dH2i4maq+qyXayUSn9/3iY2ZeWpbAgSpSVbV2E1JUL2Gg7pwnYQ1h8rQIog==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.2.tgz", + "integrity": "sha512-E441q4Qdb+7yuyiADVi5J+44x8ctlrqn8XgkDTwr4qPJzWkaHwD489iZ4nGDgcuya4iMN3ULV6NwbhRZJ9Z7SQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.2.tgz", + "integrity": "sha512-3CAkndNpYUrlDqkCM5qhksfE+qSIREVpyoeHIU6jd48SJZViAmznoQQLAv4hVXF7xyUB9zf+G++e2v1ABjCbEQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.2.tgz", + "integrity": "sha512-VI94Q6khIHqHWNOh6LLdm9s2Ry4zdjWJwH56WoiJU7NTeDwyApdZZ8c+SADC8OH98KWNQXnE01UdJ9CSfZvwZw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.4.tgz", + "integrity": "sha512-RUgBD1c0+gCYZGCCe6mMdTiOFS0Zc/XrN0fYd6hISIKcDUbAW5NtSQW9g/powkrXYm6Vzwd6y+fqmExDuCdHNQ==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.0.2" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.4.tgz", + "integrity": "sha512-2800clwVg1ZQtxwSoTlHvtm9ObgAax7V6MTAB/hDT945Tfyy3hVkmiHpeLPCKYqYR1Gcmv1uDZ3a4OFwkdBL7Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.0.2" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.4.tgz", + "integrity": "sha512-h3RAL3siQoyzSoH36tUeS0PDmb5wINKGYzcLB5C6DIiAn2F3udeFAum+gj8IbA/82+8RGCTn7XW8WTFnqag4tQ==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.31", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.0.2" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.4.tgz", + "integrity": "sha512-GoR++s0XW9DGVi8SUGQ/U4AeIzLdNjHka6jidVwapQ/JebGVQIpi52OdyxCNVRE++n1FCLzjDovJNozif7w/Aw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.0.2" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.4.tgz", + "integrity": "sha512-nhr1yC3BlVrKDTl6cO12gTpXMl4ITBUZieehFvMntlCXFzH2bvKG76tBL2Y/OqhupZt81pR7R+Q5YhJxW0rGgQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.0.2" + } }, - "node_modules/@huggingface/jinja": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@huggingface/jinja/-/jinja-0.2.2.tgz", - "integrity": "sha512-/KPde26khDUIPkTGU82jdtTW9UAuvUTumCAbFs/7giR0SxsvZC4hru51PBvpijH6BVkHcROcvZM/lpy5h1jRRA==", + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.4.tgz", + "integrity": "sha512-uCPTku0zwqDmZEOi4ILyGdmW76tH7dm8kKlOIV1XC5cLyJ71ENAAqarOHQh0RLfpIpbV5KOpXzdU6XkJtS0daw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=18" + "musl": ">=1.2.2", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.2" } }, - "node_modules/@huggingface/tasks": { - "version": "0.10.22", - "resolved": "https://registry.npmjs.org/@huggingface/tasks/-/tasks-0.10.22.tgz", - "integrity": "sha512-sCtp+A6sq6NXoUU7NXuXWoVNNjKddk1GTQIh3cJ6illF8S4zmFoerCVRvFf19BdgICGvF+RVZiv9sGGK9KRDTg==" - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "deprecated": "Use @eslint/config-array instead", - "dev": true, + "node_modules/@img/sharp-wasm32": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.4.tgz", + "integrity": "sha512-Bmmauh4sXUsUqkleQahpdNXKvo+wa1V9KhT2pDA4VJGKwnKMJXiSTGphn0gnJrlooda0QxCtXc6RX1XAU6hMnQ==", + "cpu": [ + "wasm32" + ], + "optional": true, "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" + "@emnapi/runtime": "^1.1.1" }, "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "url": "https://opencollective.com/libvips" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "dev": true - }, - "node_modules/@img/sharp-darwin-arm64": { + "node_modules/@img/sharp-win32-ia32": { "version": "0.33.4", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.4.tgz", - "integrity": "sha512-p0suNqXufJs9t3RqLBO6vvrgr5OhgbWp76s5gTRvdmxmuv9E1rcaqGUsl3l4mKVmXPkTkTErXediAui4x+8PSA==", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.4.tgz", + "integrity": "sha512-99SJ91XzUhYHbx7uhK3+9Lf7+LjwMGQZMDlO/E/YVJ7Nc3lyDFZPGhjwiYdctoH2BOzW9+TnfqcaMKt0jHLdqw==", "cpu": [ - "arm64" + "ia32" ], "optional": true, "os": [ - "darwin" + "win32" ], "engines": { - "glibc": ">=2.26", "node": "^18.17.0 || ^20.3.0 || >=21.0.0", "npm": ">=9.6.5", "pnpm": ">=7.1.0", @@ -3141,24 +3901,21 @@ }, "funding": { "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.0.2" } }, - "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.2.tgz", - "integrity": "sha512-tcK/41Rq8IKlSaKRCCAuuY3lDJjQnYIW1UXU1kxcEKrfL8WR7N6+rzNoOxoQRJWTAECuKwgAHnPvqXGN8XfkHA==", + "node_modules/@img/sharp-win32-x64": { + "version": "0.33.4", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.4.tgz", + "integrity": "sha512-3QLocdTRVIrFNye5YocZl+KKpYKP+fksi1QhmOArgx7GyhIbQp/WrJRu176jm8IxromS7RIkzMiMINVdBtC8Aw==", "cpu": [ - "arm64" + "x64" ], "optional": true, "os": [ - "darwin" + "win32" ], "engines": { - "macos": ">=11", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", "npm": ">=9.6.5", "pnpm": ">=7.1.0", "yarn": ">=3.2.0" @@ -3418,9 +4175,9 @@ } }, "node_modules/@langchain/anthropic": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/@langchain/anthropic/-/anthropic-0.2.6.tgz", - "integrity": "sha512-mFBC944rKGy+oRKWOmCmABPj+pQ2S8FcvyFGavFgIqjWlnBk9PwMjWm8IEdWwaSEahJXuEL9xAV2StWazWdXvg==", + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/@langchain/anthropic/-/anthropic-0.2.8.tgz", + "integrity": "sha512-d2aFPdFDFApLmaCzluTH/FvFi+xPhDDRW4gYIjE4DIoTuubAYKZEkvIlrratQuzXzg5LhDPPHBctvR7nst0D6Q==", "dependencies": { "@anthropic-ai/sdk": "^0.22.0", "@langchain/core": ">=0.2.16 <0.3.0", @@ -3678,14 +4435,6 @@ "node": ">= 14" } }, - "node_modules/@mswjs/cookies": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@mswjs/cookies/-/cookies-1.1.1.tgz", - "integrity": "sha512-W68qOHEjx1iD+4VjQudlx26CPIoxmIAtK4ZCexU0/UJBG6jYhcuyzKJx+Iw8uhBIGd9eba64XgWVgo20it1qwA==", - "engines": { - "node": ">=18" - } - }, "node_modules/@mswjs/interceptors": { "version": "0.29.1", "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.29.1.tgz", @@ -4173,12 +4922,12 @@ } }, "node_modules/@playwright/test": { - "version": "1.45.2", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.45.2.tgz", - "integrity": "sha512-JxG9eq92ET75EbVi3s+4sYbcG7q72ECeZNbdBlaMkGcNbiDQ4cAi8U2QP5oKkOx+1gpaiL1LDStmzCaEM1Z6fQ==", + "version": "1.45.3", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.45.3.tgz", + "integrity": "sha512-UKF4XsBfy+u3MFWEH44hva1Q8Da28G6RFtR2+5saw+jgAFQV5yYnB1fu68Mz7fO+5GJF3wgwAIs0UelU8TxFrA==", "devOptional": true, "dependencies": { - "playwright": "1.45.2" + "playwright": "1.45.3" }, "bin": { "playwright": "cli.js" @@ -5395,9 +6144,9 @@ "integrity": "sha512-iQVztO09ZVfsletMiY+DpT/JRiBntdsdJ4uqk3UJFhrhS8mIC9ZOZbmfGSRs/kdbNPQkVyzucceDicQ/3Mlj9g==" }, "node_modules/@react-three/drei": { - "version": "9.109.0", - "resolved": "https://registry.npmjs.org/@react-three/drei/-/drei-9.109.0.tgz", - "integrity": "sha512-LlJ1k0DO5UvBdjuv6WuSP5jXb1mXsQY3VeQTfzivCsHJH9pUsbxutLL7mk84w9MI7cZytv2Qcx2nU2HBm0eNpQ==", + "version": "9.109.2", + "resolved": "https://registry.npmjs.org/@react-three/drei/-/drei-9.109.2.tgz", + "integrity": "sha512-oUbfjiyPQeQch4Mi3jZvFKigMlc97/xvazxyjPBCGa8RP8cHZJl187eZI9Ha1WwkVaX80DfgN7bYAWXS4ywxmw==", "dependencies": { "@babel/runtime": "^7.11.2", "@mediapipe/tasks-vision": "0.10.8", @@ -5749,6 +6498,32 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.19.0.tgz", + "integrity": "sha512-JlPfZ/C7yn5S5p0yKk7uhHTTnFlvTgLetl2VxqE518QgyM7C9bSfFTYvB/Q/ftkq0RIPY4ySxTz+/wKJ/dXC0w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.19.0.tgz", + "integrity": "sha512-RDxUSY8D1tWYfn00DDi5myxKgOk6RvWPxhmWexcICt/MEC6yEMr4HNCu1sXXYLw8iAsg0D44NuU+qNq7zVWCrw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, "node_modules/@rollup/rollup-darwin-arm64": { "version": "4.19.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.19.0.tgz", @@ -5762,6 +6537,175 @@ "darwin" ] }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.19.0.tgz", + "integrity": "sha512-fO28cWA1dC57qCd+D0rfLC4VPbh6EOJXrreBmFLWPGI9dpMlER2YwSPZzSGfq11XgcEpPukPTfEVFtw2q2nYJg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.19.0.tgz", + "integrity": "sha512-2Rn36Ubxdv32NUcfm0wB1tgKqkQuft00PtM23VqLuCUR4N5jcNWDoV5iBC9jeGdgS38WK66ElncprqgMUOyomw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.19.0.tgz", + "integrity": "sha512-gJuzIVdq/X1ZA2bHeCGCISe0VWqCoNT8BvkQ+BfsixXwTOndhtLUpOg0A1Fcx/+eA6ei6rMBzlOz4JzmiDw7JQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.19.0.tgz", + "integrity": "sha512-0EkX2HYPkSADo9cfeGFoQ7R0/wTKb7q6DdwI4Yn/ULFE1wuRRCHybxpl2goQrx4c/yzK3I8OlgtBu4xvted0ug==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.19.0.tgz", + "integrity": "sha512-GlIQRj9px52ISomIOEUq/IojLZqzkvRpdP3cLgIE1wUWaiU5Takwlzpz002q0Nxxr1y2ZgxC2obWxjr13lvxNQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.19.0.tgz", + "integrity": "sha512-N6cFJzssruDLUOKfEKeovCKiHcdwVYOT1Hs6dovDQ61+Y9n3Ek4zXvtghPPelt6U0AH4aDGnDLb83uiJMkWYzQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.19.0.tgz", + "integrity": "sha512-2DnD3mkS2uuam/alF+I7M84koGwvn3ZVD7uG+LEWpyzo/bq8+kKnus2EVCkcvh6PlNB8QPNFOz6fWd5N8o1CYg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.19.0.tgz", + "integrity": "sha512-D6pkaF7OpE7lzlTOFCB2m3Ngzu2ykw40Nka9WmKGUOTS3xcIieHe82slQlNq69sVB04ch73thKYIWz/Ian8DUA==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.19.0.tgz", + "integrity": "sha512-HBndjQLP8OsdJNSxpNIN0einbDmRFg9+UQeZV1eiYupIRuZsDEoeGU43NQsS34Pp166DtwQOnpcbV/zQxM+rWA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.19.0.tgz", + "integrity": "sha512-HxfbvfCKJe/RMYJJn0a12eiOI9OOtAUF4G6ozrFUK95BNyoJaSiBjIOHjZskTUffUrB84IPKkFG9H9nEvJGW6A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.19.0.tgz", + "integrity": "sha512-HxDMKIhmcguGTiP5TsLNolwBUK3nGGUEoV/BO9ldUBoMLBssvh4J0X8pf11i1fTV7WShWItB1bKAKjX4RQeYmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.19.0.tgz", + "integrity": "sha512-xItlIAZZaiG/u0wooGzRsx11rokP4qyc/79LkAOdznGRAbOFc+SfEdfUOszG1odsHNgwippUJavag/+W/Etc6Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.19.0.tgz", + "integrity": "sha512-xNo5fV5ycvCCKqiZcpB65VMR11NJB+StnxHz20jdqRAktfdfzhgjTiJ2doTDQE/7dqGaV5I7ZGqKpgph6lCIag==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@rushstack/eslint-patch": { "version": "1.10.3", "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.3.tgz", @@ -6620,9 +7564,9 @@ } }, "node_modules/@types/node": { - "version": "20.14.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", - "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", + "version": "20.14.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.12.tgz", + "integrity": "sha512-r7wNXakLeSsGT0H1AU863vS2wa5wBOK4bWMjZz2wj+8nBx+m5PeIn0k8AloSLpRuiwdRQZwarZqHE4FNArPuJQ==", "dependencies": { "undici-types": "~5.26.4" } @@ -6709,6 +7653,11 @@ "meshoptimizer": "~0.18.1" } }, + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==" + }, "node_modules/@types/uuid": { "version": "9.0.8", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", @@ -6983,6 +7932,12 @@ "url": "https://opencollective.com/vitest" } }, + "node_modules/@webgpu/types": { + "version": "0.1.44", + "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.44.tgz", + "integrity": "sha512-JDpYJN5E/asw84LTYhKyvPpxGnD+bAKPtpW9Ilurf7cZpxaTbxkQcGwOd7jgB9BPBrTYQ+32ufo4HiuomTjHNQ==", + "dev": true + }, "node_modules/@xenova/transformers": { "version": "3.0.0-alpha.0", "resolved": "git+ssh://git@github.com/xenova/transformers.js.git#c6aeb4be1bc1cdfa72e9d050f77b97dc9c8af362", @@ -7613,6 +8568,14 @@ "to-data-view": "^1.1.0" } }, + "node_modules/base64-arraybuffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", + "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -9934,14 +10897,14 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.832", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.832.tgz", - "integrity": "sha512-cTen3SB0H2SGU7x467NRe1eVcQgcuS6jckKfWJHia2eo0cHIGOqHoAxevIYZD4eRHcWjkvFzo93bi3vJ9W+1lA==" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.0.tgz", + "integrity": "sha512-Vb3xHHYnLseK8vlMJQKJYXJ++t4u1/qJ3vykuVrVjvdiOEhYyT1AuP4x03G8EnPmYvYOhe9T+dADTmthjRQMkA==" }, "node_modules/electron-winstaller": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/electron-winstaller/-/electron-winstaller-5.3.1.tgz", - "integrity": "sha512-oM8BW3a8NEqG0XW+Vx3xywhk0DyDV4T0jT0zZfWt0IczNT3jHAAvQWBorF8osQDplSsCyXXyxrsrQ8cY0Slb/A==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/electron-winstaller/-/electron-winstaller-5.4.0.tgz", + "integrity": "sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg==", "dev": true, "hasInstallScript": true, "optional": true, @@ -10087,9 +11050,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", - "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -12087,9 +13050,9 @@ } }, "node_modules/groq-sdk/node_modules/@types/node": { - "version": "18.19.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.41.tgz", - "integrity": "sha512-LX84pRJ+evD2e2nrgYCHObGWkiQJ1mL+meAgbvnwk/US6vmMY7S2ygBTGV2Jw91s9vUsLSXeDEkUHZIJGLrhsg==", + "version": "18.19.42", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.42.tgz", + "integrity": "sha512-d2ZFc/3lnK2YCYhos8iaNIYu9Vfhr92nHiyJHRltXWjXUBjEE+A4I58Tdbnw4VhggSW+2j5y5gTrLs4biNnubg==", "dependencies": { "undici-types": "~5.26.4" } @@ -14079,15 +15042,15 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/msw": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/msw/-/msw-2.3.2.tgz", - "integrity": "sha512-vDn6d6a50vxPE+HnaKQfpmZ4SVXlOjF97yD5FJcUT3v2/uZ65qvTYNL25yOmnrfCNWZ4wtAS7EbtXxygMug2Tw==", + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/msw/-/msw-2.3.4.tgz", + "integrity": "sha512-sHMlwrajgmZSA2l1o7qRSe+azm/I+x9lvVVcOxAzi4vCtH8uVPJk1K5BQYDkzGl+tt0RvM9huEXXdeGrgcc79g==", "hasInstallScript": true, "dependencies": { "@bundled-es-modules/cookie": "^2.0.0", "@bundled-es-modules/statuses": "^1.0.1", + "@bundled-es-modules/tough-cookie": "^0.1.6", "@inquirer/confirm": "^3.0.0", - "@mswjs/cookies": "^1.1.0", "@mswjs/interceptors": "^0.29.0", "@open-draft/until": "^2.1.0", "@types/cookie": "^0.6.0", @@ -14993,9 +15956,9 @@ } }, "node_modules/openai/node_modules/@types/node": { - "version": "18.19.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.41.tgz", - "integrity": "sha512-LX84pRJ+evD2e2nrgYCHObGWkiQJ1mL+meAgbvnwk/US6vmMY7S2ygBTGV2Jw91s9vUsLSXeDEkUHZIJGLrhsg==", + "version": "18.19.42", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.42.tgz", + "integrity": "sha512-d2ZFc/3lnK2YCYhos8iaNIYu9Vfhr92nHiyJHRltXWjXUBjEE+A4I58Tdbnw4VhggSW+2j5y5gTrLs4biNnubg==", "dependencies": { "undici-types": "~5.26.4" } @@ -15476,12 +16439,12 @@ "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==" }, "node_modules/playwright": { - "version": "1.45.2", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.45.2.tgz", - "integrity": "sha512-ReywF2t/0teRvNBpfIgh5e4wnrI/8Su8ssdo5XsQKpjxJj+jspm00jSoz9BTg91TT0c9HRjXO7LBNVrgYj9X0g==", + "version": "1.45.3", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.45.3.tgz", + "integrity": "sha512-QhVaS+lpluxCaioejDZ95l4Y4jSFCsBvl2UZkpeXlzxmqS+aABr5c82YmfMHrL6x27nvrvykJAFpkzT2eWdJww==", "devOptional": true, "dependencies": { - "playwright-core": "1.45.2" + "playwright-core": "1.45.3" }, "bin": { "playwright": "cli.js" @@ -15494,9 +16457,9 @@ } }, "node_modules/playwright-core": { - "version": "1.45.2", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.45.2.tgz", - "integrity": "sha512-ha175tAWb0dTK0X4orvBIqi3jGEt701SMxMhyujxNrgd8K0Uy5wMSwwcQHtyB4om7INUkfndx02XnQ2p6dvLDw==", + "version": "1.45.3", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.45.3.tgz", + "integrity": "sha512-+ym0jNbcjikaOwwSZycFbwkWgfruWvYlJfThKYAlImbxUgdWFO2oW70ojPm4OpE4t6TAo2FY/smM+hpVTtkhDA==", "devOptional": true, "bin": { "playwright-core": "cli.js" @@ -15953,8 +16916,7 @@ "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" }, "node_modules/pump": { "version": "3.0.0", @@ -15970,7 +16932,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, "engines": { "node": ">=6" } @@ -16016,8 +16977,7 @@ "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" }, "node_modules/queue-microtask": { "version": "1.2.3", @@ -16618,8 +17578,7 @@ "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, "node_modules/resedit": { "version": "2.0.2", @@ -18232,7 +19191,6 @@ "version": "4.1.4", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", - "dev": true, "dependencies": { "psl": "^1.1.33", "punycode": "^2.1.1", @@ -18247,7 +19205,6 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "dev": true, "engines": { "node": ">= 4.0.0" } @@ -18588,9 +19545,9 @@ } }, "node_modules/typescript": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", - "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -18714,7 +19671,6 @@ "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dev": true, "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -19587,9 +20543,9 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "node_modules/yaml": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", - "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz", + "integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==", "bin": { "yaml": "bin.mjs" }, diff --git a/package.json b/package.json index fc39012e..7ef17f47 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,8 @@ "format:fix": "prettier --write --ignore-path .gitignore ./src/", "lint": "next lint", "lint:fix": "next lint --fix", - "test": "npm run build && npm run test:unit:ci && npm run test:e2e", + "test": "npm run build && npm run test:unit:ci", + "test_TEMPORARY_DISABLED": "npm run build && npm run test:unit:ci && npm run test:e2e", "test:unit:ci": "vitest run", "test:unit:watch": "vitest", "test:e2e": "npx playwright test", @@ -35,11 +36,11 @@ "electron:make": "npm run build && electron-forge make" }, "dependencies": { - "@aitube/broadway": "0.0.22", - "@aitube/clap": "0.0.30", - "@aitube/clapper-services": "0.0.35", - "@aitube/engine": "0.0.26", - "@aitube/timeline": "0.0.45", + "@aitube/broadway": "0.1.1", + "@aitube/clap": "0.1.1", + "@aitube/clapper-services": "0.1.1", + "@aitube/engine": "0.1.1", + "@aitube/timeline": "0.1.1", "@fal-ai/serverless-client": "^0.13.0", "@ffmpeg/ffmpeg": "^0.12.10", "@ffmpeg/util": "^0.12.1", @@ -84,6 +85,7 @@ "@types/dom-speech-recognition": "^0.0.4", "@xenova/transformers": "github:xenova/transformers.js#v3", "autoprefixer": "10.4.19", + "base64-arraybuffer": "^1.0.2", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "cmdk": "^0.2.1", @@ -146,6 +148,7 @@ "@types/react-dom": "^18", "@types/uuid": "^9.0.8", "@vitejs/plugin-react": "^4.3.1", + "@webgpu/types": "^0.1.44", "electron": "^31.2.1", "eslint": "^8", "eslint-config-next": "14.2.5", diff --git a/playwright.config.ts b/playwright.config.ts index 9fd9763b..a21d2630 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -31,6 +31,10 @@ export default defineConfig({ trace: 'on-first-retry', }, + expect: { + timeout: 10000, + }, + /* Configure projects for major browsers */ projects: [ { diff --git a/src/components/monitor/index.tsx b/src/components/monitor/index.tsx index ab720df8..2e24ed19 100644 --- a/src/components/monitor/index.tsx +++ b/src/components/monitor/index.tsx @@ -24,7 +24,7 @@ export function Monitor() { > -
+
setFullscreen()} className={cn( diff --git a/src/components/toolbars/bottom-bar/index.tsx b/src/components/toolbars/bottom-bar/index.tsx index 42471d19..7ffcbc67 100644 --- a/src/components/toolbars/bottom-bar/index.tsx +++ b/src/components/toolbars/bottom-bar/index.tsx @@ -31,7 +31,7 @@ export function BottomToolbar() { {APP_REVISION}
- + {/* */}
diff --git a/src/components/toolbars/bottom-bar/metrics/index.tsx b/src/components/toolbars/bottom-bar/metrics/index.tsx index dfa70978..307f08ba 100644 --- a/src/components/toolbars/bottom-bar/metrics/index.tsx +++ b/src/components/toolbars/bottom-bar/metrics/index.tsx @@ -4,14 +4,8 @@ import { cn } from '@/lib/utils' export function Metrics() { const { isAvailable, isMeasuring, bytes, humanReadableString } = usePerformanceMeter({ - delayBetweenMeasures: 20, + delayBetweenMeasures: 40, }) - console.log('debug:', { - isAvailable, - isMeasuring, - bytes, - humanReadableString, - }) if (!isAvailable) { return null diff --git a/src/components/toolbars/editors-menu/EditorsSideMenuItem.tsx b/src/components/toolbars/editors-menu/EditorsSideMenuItem.tsx index 2c545383..30fb967f 100644 --- a/src/components/toolbars/editors-menu/EditorsSideMenuItem.tsx +++ b/src/components/toolbars/editors-menu/EditorsSideMenuItem.tsx @@ -61,17 +61,17 @@ export function EditorsSideMenuItem({ `transition-all duration-200 ease-out`, `items-center justify-center`, unmanaged || isActive ? '' : `cursor-pointer`, - `border-l-[3px]`, + `border-l-[2px]`, isActive ? 'fill-gray-50 text-gray-50 hover:fill-gray-50 hover:text-gray-50' - : 'hover:tefillxt-gray-200 fill-gray-400 text-gray-400 hover:text-gray-200', + : 'fill-gray-400 text-gray-400 hover:fill-gray-200 hover:text-gray-200', `group` )} style={{ // background: theme.editorMenuBgColor || theme.defaultBgColor || "#eeeeee", borderColor: isActive ? theme.defaultPrimaryColor || '#ffffff' - : '#111827', + : 'rgba(0,0,0,0)', }} onClick={handleClick} > diff --git a/src/components/toolbars/top-menu/index.tsx b/src/components/toolbars/top-menu/index.tsx index 14da127f..3aab24a9 100644 --- a/src/components/toolbars/top-menu/index.tsx +++ b/src/components/toolbars/top-menu/index.tsx @@ -1,7 +1,8 @@ import { cn } from '@aitube/timeline' +import { TbBrandDiscord } from 'react-icons/tb' +import { FaGithubAlt } from 'react-icons/fa' import { Menubar } from '@/components/ui/menubar' -import { APP_REVISION } from '@/lib/core/constants' import { useUI, useResolver } from '@/services' import { TopMenuFile } from './file' @@ -15,6 +16,11 @@ import { TopMenuAssistant } from './assistant' import { TopMenuView } from './view' import { TopMenuLogo } from './TopMenuLogo' import { TopMenuPlugins } from './plugins' +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from '@/components/ui/tooltip' export function TopMenu() { const isBusyResolving = useResolver((s) => s.isBusyResolving) @@ -43,12 +49,37 @@ export function TopMenu() {
{ // clap?.meta?.title || "Untitled" } + + +
+ + + +
+
+ + Community + +
+ + + +
+ + + +
+
+ + Code + +
) diff --git a/src/components/tree-browsers/stores/useEntityLibrary.ts b/src/components/tree-browsers/stores/useEntityLibrary.ts index 2f10c58a..69f8fd66 100644 --- a/src/components/tree-browsers/stores/useEntityLibrary.ts +++ b/src/components/tree-browsers/stores/useEntityLibrary.ts @@ -1,7 +1,7 @@ 'use client' import { create } from 'zustand' -import { ClapEntity, UUID } from '@aitube/clap' +import { ClapEntity, ClapSegmentCategory, UUID } from '@aitube/clap' import { CivitaiCollection, LibraryNodeItem, @@ -191,10 +191,10 @@ export const useEntityLibrary = create<{ icon: icons.misc, className: itemClassName, } - if (entity.category === 'character') { + if (entity.category === ClapSegmentCategory.CHARACTER) { node.icon = icons.character characters.children!.push(node) - } else if (entity.category === 'location') { + } else if (entity.category === ClapSegmentCategory.LOCATION) { node.icon = icons.location locations.children!.push(node) } else { diff --git a/src/components/tree-browsers/stores/useProjectLibrary.ts b/src/components/tree-browsers/stores/useProjectLibrary.ts index 7fbecec7..6c59a43c 100644 --- a/src/components/tree-browsers/stores/useProjectLibrary.ts +++ b/src/components/tree-browsers/stores/useProjectLibrary.ts @@ -1,7 +1,7 @@ 'use client' import { create } from 'zustand' -import { ClapEntity, UUID } from '@aitube/clap' +import { ClapEntity, ClapSegmentCategory, UUID } from '@aitube/clap' import { icons } from '@/components/icons' @@ -85,11 +85,11 @@ export const useProjectLibrary = create<{ icon: icons.misc, className: collectionClassName, } - if (entity.category === 'character') { + if (entity.category === ClapSegmentCategory.CHARACTER) { node.icon = icons.character node.nodeType = 'LIB_NODE_PROJECT_ENTITY_CHARACTER' characters.children!.push(node) - } else if (entity.category === 'location') { + } else if (entity.category === ClapSegmentCategory.LOCATION) { node.icon = icons.location node.nodeType = 'LIB_NODE_PROJECT_ENTITY_LOCATION' locations.children!.push(node) diff --git a/src/experiments/grading/README.md b/src/experiments/grading/README.md new file mode 100644 index 00000000..2b3006eb --- /dev/null +++ b/src/experiments/grading/README.md @@ -0,0 +1,3 @@ +Utilities to apply color grading to an image. + +The purpose is to be able to unify / homogeneize diff --git a/src/experiments/grading/applyColorGrading.ts b/src/experiments/grading/applyColorGrading.ts new file mode 100644 index 00000000..d10fc878 --- /dev/null +++ b/src/experiments/grading/applyColorGrading.ts @@ -0,0 +1,225 @@ +import { decode, encode } from 'base64-arraybuffer' + +import { ColorGradingFilter } from './types' + +export async function applyColorGrading({ + images, + filters, +}: { + images: Array<{ image: string; depthMap?: string }> + filters: Array<{ + filter: ColorGradingFilter + parameters?: Record + }> +}): Promise { + if (!navigator.gpu) { + throw new Error('WebGPU is not supported in this browser.') + } + + const adapter = await navigator.gpu.requestAdapter() + if (!adapter) { + throw new Error('Failed to get GPU adapter.') + } + + const device = await adapter.requestDevice() + if (!device) { + throw new Error('Failed to get GPU device.') + } + + const processedImages: string[] = [] + + for (const { image, depthMap } of images) { + const imgData = await loadImage(image) + let texture = device.createTexture({ + size: [imgData.width, imgData.height, 1], + format: 'rgba8unorm', + usage: + GPUTextureUsage.TEXTURE_BINDING | + GPUTextureUsage.COPY_DST | + GPUTextureUsage.STORAGE_BINDING, + }) + + device.queue.writeTexture( + { texture }, + imgData.data, + { bytesPerRow: imgData.width * 4 }, + { width: imgData.width, height: imgData.height } + ) + + let depthTexture: GPUTexture | null = null + if (depthMap) { + const depthImgData = await loadImage(depthMap) + depthTexture = device.createTexture({ + size: [depthImgData.width, depthImgData.height, 1], + format: 'r8unorm', + usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST, + }) + + device.queue.writeTexture( + { texture: depthTexture }, + depthImgData.data, + { bytesPerRow: depthImgData.width }, + { width: depthImgData.width, height: depthImgData.height } + ) + } + + for (const { filter, parameters } of filters) { + texture = await applyFilter( + device, + texture, + depthTexture, + filter, + parameters + ) + } + + const resultBuffer = await readTextureToBuffer(device, texture) + const base64 = encode(resultBuffer) + processedImages.push(`data:image/png;base64,${base64}`) + } + + return processedImages +} + +async function loadImage(dataUri: string): Promise { + return new Promise((resolve, reject) => { + const img = new Image() + img.onload = () => { + const canvas = document.createElement('canvas') + canvas.width = img.width + canvas.height = img.height + const ctx = canvas.getContext('2d') + if (!ctx) { + reject(new Error('Failed to get 2D context')) + return + } + ctx.drawImage(img, 0, 0) + resolve(ctx.getImageData(0, 0, img.width, img.height)) + } + img.onerror = reject + img.src = dataUri + }) +} + +async function applyFilter( + device: GPUDevice, + inputTexture: GPUTexture, + depthTexture: GPUTexture | null, + filter: ColorGradingFilter, + parameters?: Record +): Promise { + const shader = createShaderModule(device, filter.shader) + const pipeline = device.createComputePipeline({ + layout: 'auto', + compute: { module: shader, entryPoint: 'main' }, + }) + + const outputTexture = device.createTexture({ + size: [inputTexture.width, inputTexture.height, 1], + format: 'rgba8unorm', + usage: GPUTextureUsage.STORAGE_BINDING | GPUTextureUsage.COPY_SRC, + }) + + // Automatically calculate uniform buffer size and create typed array + const uniformData: number[] = [] + filter.parameters.forEach((param) => { + if (param.type === 'number') { + uniformData.push( + (parameters?.[param.name] as number) ?? param.defaultValue + ) + } else if (param.type === 'string') { + // For string parameters, we'll use the index of the value in allowedValues + const value = (parameters?.[param.name] as string) ?? param.defaultValue + const index = param.allowedValues.indexOf(value) + uniformData.push(index) + } + }) + + const uniformTypedArray = new Float32Array(uniformData) + const uniformBufferSize = uniformTypedArray.byteLength + const uniformBuffer = device.createBuffer({ + size: uniformBufferSize, + usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, + }) + + device.queue.writeBuffer(uniformBuffer, 0, uniformTypedArray) + + const sampler = device.createSampler({ + magFilter: 'linear', + minFilter: 'linear', + }) + + const bindGroupEntries: GPUBindGroupEntry[] = [ + { binding: 0, resource: inputTexture.createView() }, + { binding: 1, resource: outputTexture.createView() }, + { binding: 2, resource: { buffer: uniformBuffer } }, + { binding: 4, resource: sampler }, + ] + + if (depthTexture) { + bindGroupEntries.push({ binding: 3, resource: depthTexture.createView() }) + } else { + // Create a dummy 1x1 depth texture if no depth texture is provided + const dummyDepthTexture = device.createTexture({ + size: [1, 1], + format: 'r32float', + usage: GPUTextureUsage.TEXTURE_BINDING, + }) + bindGroupEntries.push({ + binding: 3, + resource: dummyDepthTexture.createView(), + }) + } + + const bindGroup = device.createBindGroup({ + layout: pipeline.getBindGroupLayout(0), + entries: bindGroupEntries, + }) + + const commandEncoder = device.createCommandEncoder() + const passEncoder = commandEncoder.beginComputePass() + passEncoder.setPipeline(pipeline) + passEncoder.setBindGroup(0, bindGroup) + passEncoder.dispatchWorkgroups( + Math.ceil(inputTexture.width / 8), + Math.ceil(inputTexture.height / 8) + ) + passEncoder.end() + + device.queue.submit([commandEncoder.finish()]) + + return outputTexture +} + +function createShaderModule( + device: GPUDevice, + shaderCode: string +): GPUShaderModule { + return device.createShaderModule({ code: shaderCode }) +} + +async function readTextureToBuffer( + device: GPUDevice, + texture: GPUTexture +): Promise { + const bufferSize = texture.width * texture.height * 4 + const resultBuffer = device.createBuffer({ + size: bufferSize, + usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ, + }) + + const commandEncoder = device.createCommandEncoder() + commandEncoder.copyTextureToBuffer( + { texture }, + { buffer: resultBuffer, bytesPerRow: texture.width * 4 }, + { width: texture.width, height: texture.height } + ) + + device.queue.submit([commandEncoder.finish()]) + + await resultBuffer.mapAsync(GPUMapMode.READ) + const arrayBuffer = resultBuffer.getMappedRange().slice(0) + resultBuffer.unmap() + + return arrayBuffer +} diff --git a/src/experiments/grading/applyColorGradingDemo.ts b/src/experiments/grading/applyColorGradingDemo.ts new file mode 100644 index 00000000..0e8e2dfc --- /dev/null +++ b/src/experiments/grading/applyColorGradingDemo.ts @@ -0,0 +1,121 @@ +import { applyColorGrading } from './applyColorGrading' + +import { analogLensSimulator } from './filters/analogLens' +import { cinematic } from './filters/cinematic' +import { colorTemperature } from './filters/colorTemperature' +import { crossProcessing } from './filters/crossProcessing' +import { filmDegradation } from './filters/filmDegradation' +import { infraredBlackAndWhite } from './filters/infrared' +import { lomography } from './filters/lomography' +import { splitToning } from './filters/splitToning' +import { hdrToneMapping } from './filters/toneMapping' +import { vintageFilm } from './filters/vintageFilm' + +export async function demo() { + const base64DataUriImages = await applyColorGrading({ + images: [ + { + image: 'data:image/png....', + // depthMap: "data:image/png...." // optional depth map + }, + ], + filters: [ + { + filter: analogLensSimulator, + parameters: { + chromaticAberration: 0.003, + vignetteStrength: 0.4, + vignetteRadius: 0.8, + distortion: 0.15, + bloomStrength: 0.2, + bloomRadius: 4, + dofFocusDistance: 0.6, + dofFocusRange: 0.1, + dofBlurStrength: 3, + }, + }, + + { + filter: infraredBlackAndWhite, + parameters: { + contrast: 1.3, + grain: 0.25, + glow: 0.4, + }, + }, + { + filter: filmDegradation, + parameters: { + scratchesIntensity: 0.35, + dustIntensity: 0.25, + colorFading: 0.4, + lightLeakIntensity: 0.3, + }, + }, + { + filter: crossProcessing, + parameters: { + intensity: 0.6, + contrastBoost: 0.4, + colorShift: 'Cool', + }, + }, + { + filter: lomography, + parameters: { + saturation: 1.4, + contrast: 1.3, + vignetteIntensity: 0.6, + lightLeakIntensity: 0.4, + }, + }, + { + filter: cinematic, + parameters: { + preset: 'Blade Runner', + intensity: 0.6, + contrast: 1.3, + }, + }, + { + filter: splitToning, + parameters: { + highlightColor: 'Yellow', + shadowColor: 'Blue', + balance: 0.1, + intensity: 0.5, + }, + }, + + { + filter: hdrToneMapping, + parameters: { + exposure: 0.5, + contrast: 1.2, + saturation: 1.1, + highlights: -0.2, + shadows: 0.3, + }, + }, + { + filter: colorTemperature, + parameters: { + temperature: 5500, + tint: 10, + }, + }, + { + filter: vintageFilm, + parameters: { + preset: 'Kodachrome 64', + intensity: 0.8, + grain: 0.3, + ageEffect: 0.2, + colorShift: 0.05, + contrast: 1.1, + saturation: 1.2, + }, + }, + ], + }) +} diff --git a/src/experiments/grading/filters/DEPRECATED_analogFilm.ts b/src/experiments/grading/filters/DEPRECATED_analogFilm.ts new file mode 100644 index 00000000..407ce87b --- /dev/null +++ b/src/experiments/grading/filters/DEPRECATED_analogFilm.ts @@ -0,0 +1,171 @@ +import { ColorGradingFilter } from '../types' + +export const analogFilmSimulator: ColorGradingFilter = { + name: 'Analog Film Simulator', + parameters: [ + { + name: 'preset', + description: 'Film preset', + type: 'string', + allowedValues: [ + 'Konica Centuria 200', + 'Kodak Portra 400', + 'Fujifilm Superia 1600', + ], + defaultValue: 'Konica Centuria 200', + }, + { + name: 'saturation', + description: 'Color saturation', + type: 'number', + minValue: 0, + maxValue: 2, + defaultValue: 1, + }, + { + name: 'noise', + description: 'Film grain intensity', + type: 'number', + minValue: 0, + maxValue: 1, + defaultValue: 0.2, + }, + ], + shader: ` +struct Params { + preset: u32, + saturation: f32, + noise: f32, +} + +@group(0) @binding(0) var input_texture: texture_2d; +@group(0) @binding(1) var output_texture: texture_storage_2d; +@group(0) @binding(2) var params: Params; +@group(0) @binding(3) var depth_texture: texture_2d; + +// Film preset color matrices +const konica_centuria_200 = mat3x3( + 1.0, 0.0, 0.0, + -0.1, 1.1, 0.0, + 0.0, 0.1, 0.9 +); + +const kodak_portra_400 = mat3x3( + 1.1, -0.1, 0.0, + 0.0, 1.0, 0.0, + -0.1, 0.1, 1.0 +); + +const fujifilm_superia_1600 = mat3x3( + 1.2, -0.1, -0.1, + -0.1, 1.1, 0.0, + 0.0, 0.0, 1.0 +); + +// Helper functions +fn rgb_to_hsv(rgb: vec3) -> vec3 { + let v = max(max(rgb.r, rgb.g), rgb.b); + let c = v - min(min(rgb.r, rgb.g), rgb.b); + let s = select(0.0, c / v, v != 0.0); + + var h: f32; + if (c == 0.0) { + h = 0.0; + } else if (v == rgb.r) { + h = (rgb.g - rgb.b) / c; + } else if (v == rgb.g) { + h = 2.0 + (rgb.b - rgb.r) / c; + } else { + h = 4.0 + (rgb.r - rgb.g) / c; + } + h = fract(h / 6.0); + + return vec3(h, s, v); +} + +fn hsv_to_rgb(hsv: vec3) -> vec3 { + let h = hsv.x * 6.0; + let s = hsv.y; + let v = hsv.z; + + let c = v * s; + let x = c * (1.0 - abs(fract(h / 2.0) * 2.0 - 1.0)); + let m = v - c; + + var rgb: vec3; + if (h < 1.0) { + rgb = vec3(c, x, 0.0); + } else if (h < 2.0) { + rgb = vec3(x, c, 0.0); + } else if (h < 3.0) { + rgb = vec3(0.0, c, x); + } else if (h < 4.0) { + rgb = vec3(0.0, x, c); + } else if (h < 5.0) { + rgb = vec3(x, 0.0, c); + } else { + rgb = vec3(c, 0.0, x); + } + + return rgb + vec3(m); +} + +fn apply_film_preset(color: vec3, preset: u32) -> vec3 { + switch preset { + case 0u: { return konica_centuria_200 * color; } + case 1u: { return kodak_portra_400 * color; } + case 2u: { return fujifilm_superia_1600 * color; } + default: { return color; } + } +} + +fn apply_saturation(color: vec3, saturation: f32) -> vec3 { + let luminance = dot(color, vec3(0.299, 0.587, 0.114)); + return mix(vec3(luminance), color, saturation); +} + +fn apply_contrast(color: vec3, contrast: f32) -> vec3 { + return (color - 0.5) * contrast + 0.5; +} + +fn rand(co: vec2) -> f32 { + return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453); +} + +fn apply_film_grain(color: vec3, coord: vec2, amount: f32) -> vec3 { + let noise = rand(coord) - 0.5; + return color + noise * amount; +} + +@compute @workgroup_size(8, 8) +fn main(@builtin(global_invocation_id) global_id: vec3) { + let dimensions = textureDimensions(input_texture); + let coord = vec2(global_id.xy); + + if (coord.x >= dimensions.x || coord.y >= dimensions.y) { + return; + } + + var color = textureLoad(input_texture, coord, 0).rgb; + + // Apply film preset + color = apply_film_preset(color, params.preset); + + // Convert to HSV for saturation adjustment + var hsv = rgb_to_hsv(color); + hsv.y *= params.saturation; + color = hsv_to_rgb(hsv); + + // Apply contrast + color = apply_contrast(color, 1.1); // Slight increase in contrast + + // Apply film grain + color = apply_film_grain(color, vec2(coord), params.noise); + + // Ensure color values are within [0, 1] range + color = clamp(color, vec3(0.0), vec3(1.0)); + + textureStore(output_texture, coord, vec4(color, 1.0)); +} +`, +} diff --git a/src/experiments/grading/filters/analogLens.ts b/src/experiments/grading/filters/analogLens.ts new file mode 100644 index 00000000..94cc35dc --- /dev/null +++ b/src/experiments/grading/filters/analogLens.ts @@ -0,0 +1,228 @@ +import { ColorGradingFilter } from '../types' + +export const analogLensSimulator: ColorGradingFilter = { + name: 'Analog Lens Simulator', + parameters: [ + { + name: 'chromaticAberration', + description: 'Chromatic aberration strength', + type: 'number', + minValue: 0, + maxValue: 0.05, + defaultValue: 0.002, + }, + { + name: 'vignetteStrength', + description: 'Vignette strength', + type: 'number', + minValue: 0, + maxValue: 1, + defaultValue: 0.3, + }, + { + name: 'vignetteRadius', + description: 'Vignette radius', + type: 'number', + minValue: 0, + maxValue: 1, + defaultValue: 0.75, + }, + { + name: 'distortion', + description: 'Lens distortion', + type: 'number', + minValue: -1, + maxValue: 1, + defaultValue: 0.1, + }, + { + name: 'bloomStrength', + description: 'Bloom strength', + type: 'number', + minValue: 0, + maxValue: 1, + defaultValue: 0.1, + }, + { + name: 'bloomRadius', + description: 'Bloom radius', + type: 'number', + minValue: 1, + maxValue: 10, + defaultValue: 3, + }, + { + name: 'dofFocusDistance', + description: 'Depth of field focus distance', + type: 'number', + minValue: 0, + maxValue: 1, + defaultValue: 0.5, + }, + { + name: 'dofFocusRange', + description: 'Depth of field focus range', + type: 'number', + minValue: 0.01, + maxValue: 1, + defaultValue: 0.1, + }, + { + name: 'dofBlurStrength', + description: 'Depth of field blur strength', + type: 'number', + minValue: 0, + maxValue: 10, + defaultValue: 2, + }, + ], + shader: ` +struct Params { + chromatic_aberration: f32, + vignette_strength: f32, + vignette_radius: f32, + distortion: f32, + bloom_strength: f32, + bloom_radius: f32, + dof_focus_distance: f32, + dof_focus_range: f32, + dof_blur_strength: f32, +} + +@group(0) @binding(0) var input_texture: texture_2d; +@group(0) @binding(1) var output_texture: texture_storage_2d; +@group(0) @binding(2) var params: Params; +@group(0) @binding(3) var depth_texture: texture_2d; +@group(0) @binding(4) var texture_sampler: sampler; + +// Helper functions +fn get_uv(coord: vec2, dimensions: vec2) -> vec2 { + return (vec2(coord) + 0.5) / vec2(dimensions); +} + +fn sample_texture(uv: vec2) -> vec4 { + let dimensions = vec2(textureDimensions(input_texture)); + let coord = vec2(uv * vec2(dimensions)); + return textureLoad(input_texture, coord, 0); +} + +fn apply_chromatic_aberration(uv: vec2, strength: f32) -> vec3 { + let center = vec2(0.5, 0.5); + let dist = uv - center; + + let r = sample_texture(uv + dist * strength).r; + let g = sample_texture(uv).g; + let b = sample_texture(uv - dist * strength).b; + + return vec3(r, g, b); +} + +fn apply_vignette(color: vec3, uv: vec2, strength: f32, radius: f32) -> vec3 { + let center = vec2(0.5, 0.5); + let dist = distance(uv, center); + let vignette = smoothstep(radius, radius - 0.05, dist); + return color * mix(1.0, vignette, strength); +} + +fn apply_distortion(uv: vec2, strength: f32) -> vec2 { + let center = vec2(0.5, 0.5); + let dist = uv - center; + let r2 = dot(dist, dist); + let f = 1.0 + r2 * (strength * 0.5); + return center + dist * f; +} + +fn apply_bloom(color: vec3, uv: vec2, strength: f32, radius: f32) -> vec3 { + var blurred_color = vec3(0.0); + let dimensions = vec2(textureDimensions(input_texture)); + let pixel_size = 1.0 / dimensions; + + for (var i = -4; i <= 4; i++) { + for (var j = -4; j <= 4; j++) { + let offset = vec2(f32(i), f32(j)) * pixel_size * radius; + let sample = sample_texture(uv + offset).rgb; + let weight = 1.0 - length(offset) / (radius * 5.0 * pixel_size); + bloom += max(vec3(0.0), sample - 0.5) * weight; + } + } + + bloom /= 81.0; // Normalize by the number of samples + return color + bloom * strength; +} + +fn apply_variable_chromatic_aberration(uv: vec2, strength: f32) -> vec3 { + let center = vec2(0.5, 0.5); + let dist = distance(uv, center); + let strength_scaled = strength * smoothstep(0.0, 1.0, dist * 2.0); + + let dist_vec = (uv - center) * strength_scaled; + let r = sample_texture(uv + dist_vec).r; + let g = sample_texture(uv).g; + let b = sample_texture(uv - dist_vec).b; + + return vec3(r, g, b); +} + +fn get_depth(uv: vec2) -> f32 { + return textureSample(depth_texture, texture_sampler, uv).r; +} + +fn apply_depth_of_field(color: vec3, uv: vec2, focus_distance: f32, focus_range: f32, blur_strength: f32) -> vec3 { + let depth = get_depth(uv); + let coc = abs(depth - focus_distance) / focus_range; + let blur_amount = smoothstep(0.0, 1.0, coc) * blur_strength; + + var blurred_color = vec3(0.0); + let dimensions = vec2(textureDimensions(input_texture)); + let pixel_size = 1.0 / dimensions; + + for (var i = -4; i <= 4; i++) { + for (var j = -4; j <= 4; j++) { + let offset = vec2(f32(i), f32(j)) * pixel_size * blur_amount; + blurred_color += sample_texture(uv + offset).rgb; + } + } + + blurred_color /= 81.0; // Normalize by the number of samples + return mix(color, blurred_color, blur_amount); +} + +@compute @workgroup_size(8, 8) +fn main(@builtin(global_invocation_id) global_id: vec3) { + let dimensions = textureDimensions(input_texture); + let coord = vec2(global_id.xy); + + if (coord.x >= i32(dimensions.x) || coord.y >= i32(dimensions.y)) { + return; + } + + var uv = vec2(f32(coord.x) / f32(dimensions.x), f32(coord.y) / f32(dimensions.y)); + + // Apply lens distortion + uv = apply_distortion(uv, params.distortion); + + // Check if the distorted UV is within bounds + if (any(uv < vec2(0.0)) || any(uv > vec2(1.0))) { + textureStore(output_texture, coord, vec4(0.0, 0.0, 0.0, 1.0)); + return; + } + + // Apply variable chromatic aberration + var color = apply_variable_chromatic_aberration(uv, params.chromatic_aberration); + + // Apply bloom + color = apply_bloom(color, uv, params.bloom_strength, params.bloom_radius); + + // Apply depth of field + color = apply_depth_of_field(color, uv, params.dof_focus_distance, params.dof_focus_range, params.dof_blur_strength); + + // Apply vignette + color = apply_vignette(color, uv, params.vignette_strength, params.vignette_radius); + + // Ensure color values are within [0, 1] range + color = clamp(color, vec3(0.0), vec3(1.0)); + + textureStore(output_texture, coord, vec4(color, 1.0)); +} +`, +} diff --git a/src/experiments/grading/filters/cinematic.ts b/src/experiments/grading/filters/cinematic.ts new file mode 100644 index 00000000..aa51a2d9 --- /dev/null +++ b/src/experiments/grading/filters/cinematic.ts @@ -0,0 +1,98 @@ +import { ColorGradingFilter } from '../types' + +export const cinematic: ColorGradingFilter = { + name: 'Cinematic Color Grading', + parameters: [ + { + name: 'preset', + description: 'Cinematic color preset', + type: 'string', + allowedValues: [ + 'Blade Runner', + 'Matrix', + 'Mad Max', + 'Moonlight', + 'La La Land', + ], + defaultValue: 'Blade Runner', + }, + { + name: 'intensity', + description: 'Intensity of the cinematic effect', + type: 'number', + minValue: 0, + maxValue: 1, + defaultValue: 0.5, + }, + { + name: 'contrast', + description: 'Image contrast', + type: 'number', + minValue: 0.5, + maxValue: 2, + defaultValue: 1.2, + }, + ], + shader: ` + struct Params { + preset: u32, + intensity: f32, + contrast: f32, + } + + @group(0) @binding(0) var input_texture: texture_2d; + @group(0) @binding(1) var output_texture: texture_storage_2d; + @group(0) @binding(2) var params: Params; + + fn apply_preset(color: vec3, preset: u32) -> vec3 { + switch preset { + case 0u: { // Blade Runner + return mix(color, color * vec3(0.9, 1.1, 1.5), params.intensity); + } + case 1u: { // Matrix + return mix(color, color * vec3(0.8, 1.2, 0.8), params.intensity); + } + case 2u: { // Mad Max + return mix(color, color * vec3(1.2, 1.0, 0.8), params.intensity); + } + case 3u: { // Moonlight + return mix(color, color * vec3(0.9, 1.0, 1.2), params.intensity); + } + case 4u: { // La La Land + return mix(color, color * vec3(1.1, 1.0, 0.9), params.intensity); + } + default: { + return color; + } + } + } + + @compute @workgroup_size(8, 8) + fn main(@builtin(global_invocation_id) global_id: vec3) { + let dimensions = textureDimensions(input_texture); + let coord = vec2(global_id.xy); + + if (coord.x >= dimensions.x || coord.y >= dimensions.y) { + return; + } + + var color = textureLoad(input_texture, coord, 0).rgb; + + // Apply contrast + color = (color - 0.5) * params.contrast + 0.5; + + // Apply cinematic color preset + color = apply_preset(color, params.preset); + + // Add subtle vignette effect + let uv = vec2(coord) / vec2(dimensions); + let vignette = 1.0 - smoothstep(0.5, 1.5, distance(uv, vec2(0.5))); + color *= mix(1.0, vignette, 0.2); + + // Ensure color values are within [0, 1] range + color = clamp(color, vec3(0.0), vec3(1.0)); + + textureStore(output_texture, coord, vec4(color, 1.0)); + } + `, +} diff --git a/src/experiments/grading/filters/colorMapping.ts b/src/experiments/grading/filters/colorMapping.ts new file mode 100644 index 00000000..82c97d29 --- /dev/null +++ b/src/experiments/grading/filters/colorMapping.ts @@ -0,0 +1,53 @@ +import { ColorGradingFilter } from '../types' + +// Example filter implementations +export const colorMapping: ColorGradingFilter = { + name: 'Color Mapping', + parameters: [ + { + name: 'redMultiplier', + description: 'Red channel multiplier', + type: 'number', + minValue: 0, + maxValue: 2, + defaultValue: 1, + }, + { + name: 'greenMultiplier', + description: 'Green channel multiplier', + type: 'number', + minValue: 0, + maxValue: 2, + defaultValue: 1, + }, + { + name: 'blueMultiplier', + description: 'Blue channel multiplier', + type: 'number', + minValue: 0, + maxValue: 2, + defaultValue: 1, + }, + ], + shader: ` + @group(0) @binding(0) var inputTexture : texture_2d; + @group(0) @binding(1) var outputTexture : texture_storage_2d; + @group(0) @binding(2) var params : vec3; + + @compute @workgroup_size(8, 8) + fn main(@builtin(global_invocation_id) global_id : vec3) { + let dims = textureDimensions(inputTexture); + if (global_id.x >= dims.x || global_id.y >= dims.y) { + return; + } + let color = textureLoad(inputTexture, global_id.xy, 0); + let mapped = vec4( + color.r * params.x, + color.g * params.y, + color.b * params.z, + color.a + ); + textureStore(outputTexture, global_id.xy, mapped); + } + `, +} diff --git a/src/experiments/grading/filters/colorTemperature.ts b/src/experiments/grading/filters/colorTemperature.ts new file mode 100644 index 00000000..d2bff0be --- /dev/null +++ b/src/experiments/grading/filters/colorTemperature.ts @@ -0,0 +1,103 @@ +import { ColorGradingFilter } from '../types' + +export const colorTemperature: ColorGradingFilter = { + name: 'Color Temperature Adjustment', + parameters: [ + { + name: 'temperature', + description: 'Color temperature in Kelvin', + type: 'number', + minValue: 1000, + maxValue: 40000, + defaultValue: 6500, + }, + { + name: 'tint', + description: 'Green-Magenta tint', + type: 'number', + minValue: -100, + maxValue: 100, + defaultValue: 0, + }, + ], + shader: ` + struct Params { + temperature: f32, + tint: f32, + } + + @group(0) @binding(0) var input_texture: texture_2d; + @group(0) @binding(1) var output_texture: texture_storage_2d; + @group(0) @binding(2) var params: Params; + + fn rgb_to_xyz(rgb: vec3) -> vec3 { + let m = mat3x3( + 0.4124564, 0.3575761, 0.1804375, + 0.2126729, 0.7151522, 0.0721750, + 0.0193339, 0.1191920, 0.9503041 + ); + return m * rgb; + } + + fn xyz_to_rgb(xyz: vec3) -> vec3 { + let m = mat3x3( + 3.2404542, -1.5371385, -0.4985314, + -0.9692660, 1.8760108, 0.0415560, + 0.0556434, -0.2040259, 1.0572252 + ); + return m * xyz; + } + + fn temperature_to_xyz(temperature: f32) -> vec3 { + let temp = temperature / 100.0; + var x: f32; + if (temp <= 66.0) { + x = 0.3; + } else { + x = 0.3 + 0.06 * pow((temp - 66.0) / 100.0, 2.5); + } + + var y: f32; + if (temp <= 66.0) { + y = 0.2 + 0.1 * log(temp) / log(66.0); + } else { + y = 0.3; + } + + let z = 1.0 - x - y; + return vec3(x, y, z); + } + + @compute @workgroup_size(8, 8) + fn main(@builtin(global_invocation_id) global_id: vec3) { + let dimensions = textureDimensions(input_texture); + let coord = vec2(global_id.xy); + + if (coord.x >= dimensions.x || coord.y >= dimensions.y) { + return; + } + + var color = textureLoad(input_texture, coord, 0).rgb; + + // Convert to XYZ color space + var xyz = rgb_to_xyz(color); + + // Apply color temperature adjustment + let target_xyz = temperature_to_xyz(params.temperature); + let reference_xyz = temperature_to_xyz(6500.0); // Reference D65 white point + xyz *= target_xyz / reference_xyz; + + // Apply tint (green-magenta balance) + let tint_factor = 1.0 + params.tint / 100.0; + xyz.y *= tint_factor; + + // Convert back to RGB + color = xyz_to_rgb(xyz); + + // Ensure color values are within [0, 1] range + color = clamp(color, vec3(0.0), vec3(1.0)); + + textureStore(output_texture, coord, vec4(color, 1.0)); + } + `, +} diff --git a/src/experiments/grading/filters/crossProcessing.ts b/src/experiments/grading/filters/crossProcessing.ts new file mode 100644 index 00000000..e21d9db1 --- /dev/null +++ b/src/experiments/grading/filters/crossProcessing.ts @@ -0,0 +1,126 @@ +import { ColorGradingFilter } from '../types' + +export const crossProcessing: ColorGradingFilter = { + name: 'Cross-Processing', + parameters: [ + { + name: 'intensity', + description: 'Intensity of the cross-processing effect', + type: 'number', + minValue: 0, + maxValue: 1, + defaultValue: 0.5, + }, + { + name: 'contrastBoost', + description: 'Amount of contrast boost', + type: 'number', + minValue: 0, + maxValue: 1, + defaultValue: 0.3, + }, + { + name: 'colorShift', + description: 'Direction of color shift', + type: 'string', + allowedValues: ['Cool', 'Warm'], + defaultValue: 'Cool', + }, + ], + shader: ` + struct Params { + intensity: f32, + contrast_boost: f32, + color_shift: u32, + } + + @group(0) @binding(0) var input_texture: texture_2d; + @group(0) @binding(1) var output_texture: texture_storage_2d; + @group(0) @binding(2) var params: Params; + + fn rgb_to_hsv(rgb: vec3) -> vec3 { + let v = max(max(rgb.r, rgb.g), rgb.b); + let c = v - min(min(rgb.r, rgb.g), rgb.b); + let s = select(0.0, c / v, v != 0.0); + + var h: f32; + if (c == 0.0) { + h = 0.0; + } else if (v == rgb.r) { + h = (rgb.g - rgb.b) / c; + } else if (v == rgb.g) { + h = 2.0 + (rgb.b - rgb.r) / c; + } else { + h = 4.0 + (rgb.r - rgb.g) / c; + } + h = fract(h / 6.0); + + return vec3(h, s, v); + } + + fn hsv_to_rgb(hsv: vec3) -> vec3 { + let h = hsv.x * 6.0; + let s = hsv.y; + let v = hsv.z; + + let c = v * s; + let x = c * (1.0 - abs(fract(h / 2.0) * 2.0 - 1.0)); + let m = v - c; + + var rgb: vec3; + if (h < 1.0) { + rgb = vec3(c, x, 0.0); + } else if (h < 2.0) { + rgb = vec3(x, c, 0.0); + } else if (h < 3.0) { + rgb = vec3(0.0, c, x); + } else if (h < 4.0) { + rgb = vec3(0.0, x, c); + } else if (h < 5.0) { + rgb = vec3(x, 0.0, c); + } else { + rgb = vec3(c, 0.0, x); + } + + return rgb + vec3(m); + } + + @compute @workgroup_size(8, 8) + fn main(@builtin(global_invocation_id) global_id: vec3) { + let dimensions = textureDimensions(input_texture); + let coord = vec2(global_id.xy); + + if (coord.x >= dimensions.x || coord.y >= dimensions.y) { + return; + } + + var color = textureLoad(input_texture, coord, 0).rgb; + + // Convert to HSV + var hsv = rgb_to_hsv(color); + + // Apply color shift + if (params.color_shift == 0u) { // Cool shift + hsv.x = fract(hsv.x - 0.1 * params.intensity); + } else { // Warm shift + hsv.x = fract(hsv.x + 0.1 * params.intensity); + } + + // Increase saturation + hsv.y = clamp(hsv.y + 0.2 * params.intensity, 0.0, 1.0); + + // Convert back to RGB + color = hsv_to_rgb(hsv); + + // Apply contrast boost + color = (color - 0.5) * (1.0 + params.contrast_boost) + 0.5; + + // Adjust individual channels for cross-processing look + color.r = clamp(color.r + 0.1 * params.intensity, 0.0, 1.0); + color.g = clamp(color.g - 0.05 * params.intensity, 0.0, 1.0); + color.b = clamp(color.b + 0.15 * params.intensity, 0.0, 1.0); + + textureStore(output_texture, coord, vec4(color, 1.0)); + } + `, +} diff --git a/src/experiments/grading/filters/filmDegradation.ts b/src/experiments/grading/filters/filmDegradation.ts new file mode 100644 index 00000000..4baa35d2 --- /dev/null +++ b/src/experiments/grading/filters/filmDegradation.ts @@ -0,0 +1,104 @@ +import { ColorGradingFilter } from '../types' + +export const filmDegradation: ColorGradingFilter = { + name: 'Film Degradation', + parameters: [ + { + name: 'scratchesIntensity', + description: 'Intensity of film scratches', + type: 'number', + minValue: 0, + maxValue: 1, + defaultValue: 0.3, + }, + { + name: 'dustIntensity', + description: 'Intensity of dust and spots', + type: 'number', + minValue: 0, + maxValue: 1, + defaultValue: 0.2, + }, + { + name: 'colorFading', + description: 'Color fading effect', + type: 'number', + minValue: 0, + maxValue: 1, + defaultValue: 0.3, + }, + { + name: 'lightLeakIntensity', + description: 'Intensity of light leaks', + type: 'number', + minValue: 0, + maxValue: 1, + defaultValue: 0.2, + }, + ], + shader: ` + struct Params { + scratches_intensity: f32, + dust_intensity: f32, + color_fading: f32, + light_leak_intensity: f32, + } + + @group(0) @binding(0) var input_texture: texture_2d; + @group(0) @binding(1) var output_texture: texture_storage_2d; + @group(0) @binding(2) var params: Params; + + fn rand(co: vec2) -> f32 { + return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453); + } + + fn noise(p: vec2) -> f32 { + let ip = floor(p); + let u = fract(p); + let u2 = u * u * (3.0 - 2.0 * u); + + let n00 = rand(ip); + let n01 = rand(ip + vec2(0.0, 1.0)); + let n10 = rand(ip + vec2(1.0, 0.0)); + let n11 = rand(ip + vec2(1.0, 1.0)); + + return mix(mix(n00, n10, u2.x), mix(n01, n11, u2.x), u2.y); + } + + @compute @workgroup_size(8, 8) + fn main(@builtin(global_invocation_id) global_id: vec3) { + let dimensions = textureDimensions(input_texture); + let coord = vec2(global_id.xy); + + if (coord.x >= dimensions.x || coord.y >= dimensions.y) { + return; + } + + var color = textureLoad(input_texture, coord, 0).rgb; + + // Apply color fading + color = mix(color, vec3(0.5), params.color_fading); + + // Apply scratches + let scratch = noise(vec2(coord.y * 0.1, 0.0)); + if (scratch > 1.0 - params.scratches_intensity * 0.1) { + color += vec3(0.1); + } + + // Apply dust and spots + let dust = noise(vec2(coord) * 0.02); + if (dust < params.dust_intensity * 0.2) { + color -= vec3(0.1); + } + + // Apply light leak + let leak = noise(vec2(coord) * 0.005); + color += vec3(1.0, 0.5, 0.0) * leak * params.light_leak_intensity; + + // Ensure color values are within [0, 1] range + color = clamp(color, vec3(0.0), vec3(1.0)); + + textureStore(output_texture, coord, vec4(color, 1.0)); + } + `, +} diff --git a/src/experiments/grading/filters/infrared.ts b/src/experiments/grading/filters/infrared.ts new file mode 100644 index 00000000..1b1b0417 --- /dev/null +++ b/src/experiments/grading/filters/infrared.ts @@ -0,0 +1,87 @@ +import { ColorGradingFilter } from '../types' + +export const infraredBlackAndWhite: ColorGradingFilter = { + name: 'Infrared Black and White', + parameters: [ + { + name: 'contrast', + description: 'Image contrast', + type: 'number', + minValue: 0.5, + maxValue: 2.0, + defaultValue: 1.2, + }, + { + name: 'grain', + description: 'Film grain intensity', + type: 'number', + minValue: 0, + maxValue: 1, + defaultValue: 0.2, + }, + { + name: 'glow', + description: 'Infrared glow effect', + type: 'number', + minValue: 0, + maxValue: 1, + defaultValue: 0.3, + }, + ], + shader: ` + struct Params { + contrast: f32, + grain: f32, + glow: f32, + } + + @group(0) @binding(0) var input_texture: texture_2d; + @group(0) @binding(1) var output_texture: texture_storage_2d; + @group(0) @binding(2) var params: Params; + + fn rand(co: vec2) -> f32 { + return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453); + } + + @compute @workgroup_size(8, 8) + fn main(@builtin(global_invocation_id) global_id: vec3) { + let dimensions = textureDimensions(input_texture); + let coord = vec2(global_id.xy); + + if (coord.x >= dimensions.x || coord.y >= dimensions.y) { + return; + } + + var color = textureLoad(input_texture, coord, 0).rgb; + + // Convert to infrared-like grayscale + let ir_gray = dot(color, vec3(0.2, 0.7, 0.1)); + + // Apply contrast + let contrasted = (ir_gray - 0.5) * params.contrast + 0.5; + + // Apply glow effect + var glow_sum = vec3(0.0); + let glow_radius = 5; + for (var i = -glow_radius; i <= glow_radius; i++) { + for (var j = -glow_radius; j <= glow_radius; j++) { + let sample_coord = coord + vec2(i, j); + if (sample_coord.x >= 0 && sample_coord.x < dimensions.x && + sample_coord.y >= 0 && sample_coord.y < dimensions.y) { + let sample = textureLoad(input_texture, sample_coord, 0).rgb; + let sample_gray = dot(sample, vec3(0.2, 0.7, 0.1)); + glow_sum += vec3(sample_gray); + } + } + } + let glow_avg = glow_sum / f32((2 * glow_radius + 1) * (2 * glow_radius + 1)); + let glowed = mix(vec3(contrasted), glow_avg, params.glow); + + // Apply grain + let grain = (rand(vec2(coord)) - 0.5) * params.grain; + let final_color = clamp(glowed + grain, vec3(0.0), vec3(1.0)); + + textureStore(output_texture, coord, vec4(final_color, 1.0)); + } + `, +} diff --git a/src/experiments/grading/filters/lomography.ts b/src/experiments/grading/filters/lomography.ts new file mode 100644 index 00000000..9ec98773 --- /dev/null +++ b/src/experiments/grading/filters/lomography.ts @@ -0,0 +1,143 @@ +import { ColorGradingFilter } from '../types' + +export const lomography: ColorGradingFilter = { + name: 'Lomography', + parameters: [ + { + name: 'saturation', + description: 'Color saturation', + type: 'number', + minValue: 0, + maxValue: 2, + defaultValue: 1.3, + }, + { + name: 'contrast', + description: 'Image contrast', + type: 'number', + minValue: 0.5, + maxValue: 2, + defaultValue: 1.2, + }, + { + name: 'vignetteIntensity', + description: 'Intensity of vignette effect', + type: 'number', + minValue: 0, + maxValue: 1, + defaultValue: 0.5, + }, + { + name: 'lightLeakIntensity', + description: 'Intensity of light leak effect', + type: 'number', + minValue: 0, + maxValue: 1, + defaultValue: 0.3, + }, + ], + shader: ` + struct Params { + saturation: f32, + contrast: f32, + vignette_intensity: f32, + light_leak_intensity: f32, + } + + @group(0) @binding(0) var input_texture: texture_2d; + @group(0) @binding(1) var output_texture: texture_storage_2d; + @group(0) @binding(2) var params: Params; + + fn rgb_to_hsv(rgb: vec3) -> vec3 { + let v = max(max(rgb.r, rgb.g), rgb.b); + let c = v - min(min(rgb.r, rgb.g), rgb.b); + let s = select(0.0, c / v, v != 0.0); + + var h: f32; + if (c == 0.0) { + h = 0.0; + } else if (v == rgb.r) { + h = (rgb.g - rgb.b) / c; + } else if (v == rgb.g) { + h = 2.0 + (rgb.b - rgb.r) / c; + } else { + h = 4.0 + (rgb.r - rgb.g) / c; + } + h = fract(h / 6.0); + + return vec3(h, s, v); + } + + fn hsv_to_rgb(hsv: vec3) -> vec3 { + let h = hsv.x * 6.0; + let s = hsv.y; + let v = hsv.z; + + let c = v * s; + let x = c * (1.0 - abs(fract(h / 2.0) * 2.0 - 1.0)); + let m = v - c; + + var rgb: vec3; + if (h < 1.0) { + rgb = vec3(c, x, 0.0); + } else if (h < 2.0) { + rgb = vec3(x, c, 0.0); + } else if (h < 3.0) { + rgb = vec3(0.0, c, x); + } else if (h < 4.0) { + rgb = vec3(0.0, x, c); + } else if (h < 5.0) { + rgb = vec3(x, 0.0, c); + } else { + rgb = vec3(c, 0.0, x); + } + + return rgb + vec3(m); + } + + fn rand(co: vec2) -> f32 { + return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453); + } + + @compute @workgroup_size(8, 8) + fn main(@builtin(global_invocation_id) global_id: vec3) { + let dimensions = textureDimensions(input_texture); + let coord = vec2(global_id.xy); + + if (coord.x >= dimensions.x || coord.y >= dimensions.y) { + return; + } + + var color = textureLoad(input_texture, coord, 0).rgb; + + // Convert to HSV + var hsv = rgb_to_hsv(color); + + // Increase saturation + hsv.y = clamp(hsv.y * params.saturation, 0.0, 1.0); + + // Convert back to RGB + color = hsv_to_rgb(hsv); + + // Apply contrast + color = (color - 0.5) * params.contrast + 0.5; + + // Apply vignette + let center = vec2(0.5, 0.5); + let uv = vec2(coord) / vec2(dimensions); + let dist = distance(uv, center); + let vignette = 1.0 - smoothstep(0.3, 0.7, dist * params.vignette_intensity); + color *= vignette; + + // Apply light leak + let leak = rand(uv * 10.0); + let leak_color = vec3(1.0, 0.5, 0.2); // Warm light leak color + color = mix(color, leak_color, leak * params.light_leak_intensity); + + // Ensure color values are within [0, 1] range + color = clamp(color, vec3(0.0), vec3(1.0)); + + textureStore(output_texture, coord, vec4(color, 1.0)); + } + `, +} diff --git a/src/experiments/grading/filters/splitToning.ts b/src/experiments/grading/filters/splitToning.ts new file mode 100644 index 00000000..89a3ccb5 --- /dev/null +++ b/src/experiments/grading/filters/splitToning.ts @@ -0,0 +1,143 @@ +import { ColorGradingFilter } from '../types' + +export const splitToning: ColorGradingFilter = { + name: 'Split Toning', + parameters: [ + { + name: 'highlightColor', + description: 'Color for highlights', + type: 'string', + allowedValues: ['Red', 'Green', 'Blue', 'Yellow', 'Cyan', 'Magenta'], + defaultValue: 'Yellow', + }, + { + name: 'shadowColor', + description: 'Color for shadows', + type: 'string', + allowedValues: ['Red', 'Green', 'Blue', 'Yellow', 'Cyan', 'Magenta'], + defaultValue: 'Blue', + }, + { + name: 'balance', + description: 'Balance between highlights and shadows', + type: 'number', + minValue: -1, + maxValue: 1, + defaultValue: 0, + }, + { + name: 'intensity', + description: 'Intensity of the split toning effect', + type: 'number', + minValue: 0, + maxValue: 1, + defaultValue: 0.5, + }, + ], + shader: ` + struct Params { + highlight_color: u32, + shadow_color: u32, + balance: f32, + intensity: f32, + } + + @group(0) @binding(0) var input_texture: texture_2d; + @group(0) @binding(1) var output_texture: texture_storage_2d; + @group(0) @binding(2) var params: Params; + + fn get_color(color_index: u32) -> vec3 { + switch color_index { + case 0u: { return vec3(1.0, 0.0, 0.0); } // Red + case 1u: { return vec3(0.0, 1.0, 0.0); } // Green + case 2u: { return vec3(0.0, 0.0, 1.0); } // Blue + case 3u: { return vec3(1.0, 1.0, 0.0); } // Yellow + case 4u: { return vec3(0.0, 1.0, 1.0); } // Cyan + case 5u: { return vec3(1.0, 0.0, 1.0); } // Magenta + default: { return vec3(1.0); } // White + } + } + + fn rgb_to_hsv(rgb: vec3) -> vec3 { + let v = max(max(rgb.r, rgb.g), rgb.b); + let c = v - min(min(rgb.r, rgb.g), rgb.b); + let s = select(0.0, c / v, v != 0.0); + + var h: f32; + if (c == 0.0) { + h = 0.0; + } else if (v == rgb.r) { + h = (rgb.g - rgb.b) / c; + } else if (v == rgb.g) { + h = 2.0 + (rgb.b - rgb.r) / c; + } else { + h = 4.0 + (rgb.r - rgb.g) / c; + } + h = fract(h / 6.0); + + return vec3(h, s, v); + } + + fn hsv_to_rgb(hsv: vec3) -> vec3 { + let h = hsv.x * 6.0; + let s = hsv.y; + let v = hsv.z; + + let c = v * s; + let x = c * (1.0 - abs(fract(h / 2.0) * 2.0 - 1.0)); + let m = v - c; + + var rgb: vec3; + if (h < 1.0) { + rgb = vec3(c, x, 0.0); + } else if (h < 2.0) { + rgb = vec3(x, c, 0.0); + } else if (h < 3.0) { + rgb = vec3(0.0, c, x); + } else if (h < 4.0) { + rgb = vec3(0.0, x, c); + } else if (h < 5.0) { + rgb = vec3(x, 0.0, c); + } else { + rgb = vec3(c, 0.0, x); + } + + return rgb + vec3(m); + } + + @compute @workgroup_size(8, 8) + fn main(@builtin(global_invocation_id) global_id: vec3) { + let dimensions = textureDimensions(input_texture); + let coord = vec2(global_id.xy); + + if (coord.x >= dimensions.x || coord.y >= dimensions.y) { + return; + } + + var color = textureLoad(input_texture, coord, 0).rgb; + + // Convert to HSV + var hsv = rgb_to_hsv(color); + + let highlight_color = get_color(params.highlight_color); + let shadow_color = get_color(params.shadow_color); + + // Calculate toning based on luminance and balance + let lum = dot(color, vec3(0.299, 0.587, 0.114)); + let toning_factor = smoothstep(0.0, 1.0, lum + params.balance); + let toning_color = mix(shadow_color, highlight_color, toning_factor); + + // Apply split toning + hsv.x = mix(hsv.x, rgb_to_hsv(toning_color).x, params.intensity * (1.0 - hsv.y)); + hsv.y = mix(hsv.y, rgb_to_hsv(toning_color).y, params.intensity * 0.3); + + // Convert back to RGB + color = hsv_to_rgb(hsv); + + // Ensure color values are within [0, 1] range + color = clamp(color, vec3(0.0), vec3(1.0)); + + textureStore(output_texture, coord, vec4(color, 1.0)); + } + `, +} diff --git a/src/experiments/grading/filters/toneMapping.ts b/src/experiments/grading/filters/toneMapping.ts new file mode 100644 index 00000000..72a18d98 --- /dev/null +++ b/src/experiments/grading/filters/toneMapping.ts @@ -0,0 +1,148 @@ +import { ColorGradingFilter } from '../types' + +export const hdrToneMapping: ColorGradingFilter = { + name: 'HDR Tone Mapping', + parameters: [ + { + name: 'exposure', + description: 'Exposure adjustment', + type: 'number', + minValue: -2, + maxValue: 2, + defaultValue: 0, + }, + { + name: 'contrast', + description: 'Contrast adjustment', + type: 'number', + minValue: 0.5, + maxValue: 2, + defaultValue: 1, + }, + { + name: 'saturation', + description: 'Color saturation', + type: 'number', + minValue: 0, + maxValue: 2, + defaultValue: 1, + }, + { + name: 'highlights', + description: 'Highlight adjustment', + type: 'number', + minValue: -1, + maxValue: 1, + defaultValue: 0, + }, + { + name: 'shadows', + description: 'Shadow adjustment', + type: 'number', + minValue: -1, + maxValue: 1, + defaultValue: 0, + }, + ], + shader: ` + struct Params { + exposure: f32, + contrast: f32, + saturation: f32, + highlights: f32, + shadows: f32, + } + + @group(0) @binding(0) var input_texture: texture_2d; + @group(0) @binding(1) var output_texture: texture_storage_2d; + @group(0) @binding(2) var params: Params; + + fn rgb_to_hsv(rgb: vec3) -> vec3 { + let v = max(max(rgb.r, rgb.g), rgb.b); + let c = v - min(min(rgb.r, rgb.g), rgb.b); + let s = select(0.0, c / v, v != 0.0); + + var h: f32; + if (c == 0.0) { + h = 0.0; + } else if (v == rgb.r) { + h = (rgb.g - rgb.b) / c; + } else if (v == rgb.g) { + h = 2.0 + (rgb.b - rgb.r) / c; + } else { + h = 4.0 + (rgb.r - rgb.g) / c; + } + h = fract(h / 6.0); + + return vec3(h, s, v); + } + + fn hsv_to_rgb(hsv: vec3) -> vec3 { + let h = hsv.x * 6.0; + let s = hsv.y; + let v = hsv.z; + + let c = v * s; + let x = c * (1.0 - abs(fract(h / 2.0) * 2.0 - 1.0)); + let m = v - c; + + var rgb: vec3; + if (h < 1.0) { + rgb = vec3(c, x, 0.0); + } else if (h < 2.0) { + rgb = vec3(x, c, 0.0); + } else if (h < 3.0) { + rgb = vec3(0.0, c, x); + } else if (h < 4.0) { + rgb = vec3(0.0, x, c); + } else if (h < 5.0) { + rgb = vec3(x, 0.0, c); + } else { + rgb = vec3(c, 0.0, x); + } + + return rgb + vec3(m); + } + + fn reinhard_tone_mapping(hdr: vec3) -> vec3 { + return hdr / (hdr + 1.0); + } + + @compute @workgroup_size(8, 8) + fn main(@builtin(global_invocation_id) global_id: vec3) { + let dimensions = textureDimensions(input_texture); + let coord = vec2(global_id.xy); + + if (coord.x >= dimensions.x || coord.y >= dimensions.y) { + return; + } + + var color = textureLoad(input_texture, coord, 0).rgb; + + // Apply exposure + color *= exp2(params.exposure); + + // Apply contrast + color = pow(color, vec3(params.contrast)); + + // Apply highlights and shadows adjustments + let luminance = dot(color, vec3(0.299, 0.587, 0.114)); + let shadow_adjust = 1.0 + params.shadows * (1.0 - luminance); + let highlight_adjust = 1.0 - params.highlights * luminance; + color *= shadow_adjust * highlight_adjust; + + // Apply HDR tone mapping + color = reinhard_tone_mapping(color); + + // Adjust saturation + var hsv = rgb_to_hsv(color); + hsv.y *= params.saturation; + color = hsv_to_rgb(hsv); + + // Ensure color values are within [0, 1] range + color = clamp(color, vec3(0.0), vec3(1.0)); + + textureStore(output_texture, coord, vec4(color, 1.0)); + } + `, +} diff --git a/src/experiments/grading/filters/vintageFilm.ts b/src/experiments/grading/filters/vintageFilm.ts new file mode 100644 index 00000000..db8f8154 --- /dev/null +++ b/src/experiments/grading/filters/vintageFilm.ts @@ -0,0 +1,299 @@ +import { ColorGradingFilter } from '../types' + +export const vintageFilm: ColorGradingFilter = { + name: 'Enhanced Vintage Film Stocks', + parameters: [ + { + name: 'preset', + description: 'Vintage film stock preset', + type: 'string', + allowedValues: [ + // Kodak films + 'Kodachrome 64', + 'Ektachrome 100', + 'Kodacolor 200', + 'Portra 400', + 'Tri-X 400', + 'Kodachrome 25', + 'Plus-X 125', + 'T-Max 400', + // Fujifilm + 'Fujicolor Pro 400H', + 'Velvia 50', + 'Provia 100F', + 'Superia 200', + 'Neopan 400', + // Ilford + 'HP5 Plus', + 'FP4 Plus', + 'Delta 3200', + // Agfa + 'Vista 200', + 'Ultra 50', + 'Scala 200X', + // Konica + 'Centuria 400', + 'VX 400', + // Other brands + 'CineStill 800T', + 'Polaroid 600', + 'Polaroid SX-70', + // Exotic and old formats + 'Autochrome Lumière', + 'Daguerreotype', + 'Cyanotype', + 'Tintype', + 'Technicolor', + 'Kodachrome II (1961)', + ], + defaultValue: 'Kodachrome 64', + }, + { + name: 'intensity', + description: 'Intensity of the film stock effect', + type: 'number', + minValue: 0, + maxValue: 1, + defaultValue: 0.8, + }, + { + name: 'grain', + description: 'Film grain intensity', + type: 'number', + minValue: 0, + maxValue: 1, + defaultValue: 0.2, + }, + { + name: 'ageEffect', + description: 'Simulated age of the film', + type: 'number', + minValue: 0, + maxValue: 1, + defaultValue: 0, + }, + { + name: 'colorShift', + description: 'Color shift adjustment', + type: 'number', + minValue: -1, + maxValue: 1, + defaultValue: 0, + }, + { + name: 'contrast', + description: 'Contrast adjustment', + type: 'number', + minValue: 0.5, + maxValue: 2, + defaultValue: 1, + }, + { + name: 'saturation', + description: 'Saturation adjustment', + type: 'number', + minValue: 0, + maxValue: 2, + defaultValue: 1, + }, + ], + shader: ` + struct Params { + preset: u32, + intensity: f32, + grain: f32, + age_effect: f32, + color_shift: f32, + contrast: f32, + saturation: f32, + } + + @group(0) @binding(0) var input_texture: texture_2d; + @group(0) @binding(1) var output_texture: texture_storage_2d; + @group(0) @binding(2) var params: Params; + + fn rand(co: vec2) -> f32 { + return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453); + } + + fn rgb_to_hsv(rgb: vec3) -> vec3 { + let v = max(max(rgb.r, rgb.g), rgb.b); + let c = v - min(min(rgb.r, rgb.g), rgb.b); + let s = select(0.0, c / v, v != 0.0); + + var h: f32; + if (c == 0.0) { + h = 0.0; + } else if (v == rgb.r) { + h = (rgb.g - rgb.b) / c; + } else if (v == rgb.g) { + h = 2.0 + (rgb.b - rgb.r) / c; + } else { + h = 4.0 + (rgb.r - rgb.g) / c; + } + h = fract(h / 6.0); + + return vec3(h, s, v); + } + + fn hsv_to_rgb(hsv: vec3) -> vec3 { + let h = hsv.x * 6.0; + let s = hsv.y; + let v = hsv.z; + + let c = v * s; + let x = c * (1.0 - abs(fract(h / 2.0) * 2.0 - 1.0)); + let m = v - c; + + var rgb: vec3; + if (h < 1.0) { + rgb = vec3(c, x, 0.0); + } else if (h < 2.0) { + rgb = vec3(x, c, 0.0); + } else if (h < 3.0) { + rgb = vec3(0.0, c, x); + } else if (h < 4.0) { + rgb = vec3(0.0, x, c); + } else if (h < 5.0) { + rgb = vec3(x, 0.0, c); + } else { + rgb = vec3(c, 0.0, x); + } + + return rgb + vec3(m); + } + + fn apply_film_preset(color: vec3, preset: u32) -> vec3 { + switch preset { + // Kodak films + case 0u: { return color * vec3(1.1, 1.0, 0.9) + vec3(0.0, 0.03, 0.07); } // Kodachrome 64 + case 1u: { return color * vec3(1.0, 1.05, 1.1) + vec3(0.05, 0.0, -0.05); } // Ektachrome 100 + case 2u: { return color * vec3(1.05, 1.0, 0.95) + vec3(0.02, 0.02, 0.0); } // Kodacolor 200 + case 3u: { return color * vec3(1.1, 1.05, 1.0) + vec3(0.05, 0.05, 0.0); } // Portra 400 + case 4u: { // Tri-X 400 + let bw = dot(color, vec3(0.299, 0.587, 0.114)); + return vec3(bw * 1.1); + } + case 5u: { return color * vec3(1.2, 1.1, 0.9) + vec3(-0.05, 0.05, 0.1); } // Kodachrome 25 + case 6u: { // Plus-X 125 + let bw = dot(color, vec3(0.299, 0.587, 0.114)); + return vec3(bw * 1.05 + 0.02); + } + case 7u: { // T-Max 400 + let bw = dot(color, vec3(0.299, 0.587, 0.114)); + return vec3(bw * 1.15 - 0.05); + } + // Fujifilm + case 8u: { return color * vec3(1.05, 1.1, 1.15) + vec3(0.1, 0.0, 0.1); } // Fujicolor Pro 400H + case 9u: { return color * vec3(1.2, 1.1, 1.0) + vec3(0.0, 0.1, 0.2); } // Velvia 50 + case 10u: { return color * vec3(1.05, 1.05, 1.1) + vec3(0.05, 0.05, 0.0); } // Provia 100F + case 11u: { return color * vec3(1.1, 1.05, 0.95) + vec3(0.0, 0.05, 0.1); } // Superia 200 + case 12u: { // Neopan 400 + let bw = dot(color, vec3(0.299, 0.587, 0.114)); + return vec3(bw * 1.1 - 0.03); + } + // Ilford + case 13u: { // HP5 Plus + let bw = dot(color, vec3(0.299, 0.587, 0.114)); + return vec3(bw * 1.05 + 0.05); + } + case 14u: { // FP4 Plus + let bw = dot(color, vec3(0.299, 0.587, 0.114)); + return vec3(bw * 1.02 + 0.02); + } + case 15u: { // Delta 3200 + let bw = dot(color, vec3(0.299, 0.587, 0.114)); + return vec3(bw * 1.2 - 0.1); + } + // Agfa + case 16u: { return color * vec3(1.05, 1.0, 0.95) + vec3(0.05, 0.0, -0.05); } // Vista 200 + case 17u: { return color * vec3(1.1, 1.05, 0.9) + vec3(0.0, 0.05, 0.1); } // Ultra 50 + case 18u: { // Scala 200X + let bw = dot(color, vec3(0.299, 0.587, 0.114)); + return vec3(bw * 1.1 + 0.05); + } + // Konica + case 19u: { return color * vec3(1.05, 1.1, 1.0) + vec3(0.05, 0.0, 0.05); } // Centuria 400 + case 20u: { return color * vec3(1.1, 1.05, 0.95) + vec3(0.0, 0.05, 0.1); } // VX 400 + // Other brands + case 21u: { return color * vec3(1.1, 1.0, 1.2) + vec3(0.1, 0.0, -0.1); } // CineStill 800T + case 22u: { return color * vec3(1.15, 1.1, 1.0) + vec3(0.05, 0.0, -0.05); } // Polaroid 600 + case 23u: { return color * vec3(1.2, 1.15, 0.9) + vec3(0.1, 0.05, -0.1); } // Polaroid SX-70 + // Exotic and old formats + case 24u: { // Autochrome Lumière + var sepia = rgb_to_hsv(color); + sepia.x = 0.08; // Hue shift towards sepia + sepia.y *= 0.7; // Reduce saturation + return hsv_to_rgb(sepia) * vec3(1.1, 1.0, 0.8); + } + case 25u: { // Daguerreotype + let bw = dot(color, vec3(0.299, 0.587, 0.114)); + return vec3(bw) * vec3(0.9, 1.0, 1.1) + vec3(0.1, 0.1, 0.1); + } + case 26u: { // Cyanotype + let bw = dot(color, vec3(0.299, 0.587, 0.114)); + return vec3(0.2, 0.4, 0.6) + bw * vec3(0.1, 0.3, 0.5); + } + case 27u: { // Tintype + let bw = dot(color, vec3(0.299, 0.587, 0.114)); + return vec3(bw) * vec3(0.8, 0.8, 0.9) + vec3(0.1, 0.1, 0.05); + } + case 28u: { // Technicolor + return color * vec3(1.3, 1.1, 1.0) + vec3(0.0, 0.1, 0.2); + } + case 29u: { // Kodachrome II (1961) + return color * vec3(1.2, 1.0, 0.8) + vec3(-0.05, 0.05, 0.15); + } + default: { + return color; + } + } + } + + fn apply_age_effect(color: vec3, age: f32) -> vec3 { + let sepia = vec3(1.2, 1.0, 0.8); + let aged = mix(color, color * sepia, age); + return mix(aged, aged * (1.0 - age * 0.2), age); // Slight fading + } + + @compute @workgroup_size(8, 8) + fn main(@builtin(global_invocation_id) global_id: vec3) { + let dimensions = textureDimensions(input_texture); + let coord = vec2(global_id.xy); + + if (coord.x >= dimensions.x || coord.y >= dimensions.y) { + return; + } + + var color = textureLoad(input_texture, coord, 0).rgb; + + // Apply film preset + color = mix(color, apply_film_preset(color, params.preset), params.intensity); + + // Apply contrast adjustment + color = pow(color, vec3(params.contrast)); + + // Apply color shift + var hsv = rgb_to_hsv(color); + hsv.x = fract(hsv.x + params.color_shift); + color = hsv_to_rgb(hsv); + + // Apply saturation adjustment + hsv = rgb_to_hsv(color); + hsv.y *= params.saturation; + color = hsv_to_rgb(hsv); + + // Apply age effect + color = apply_age_effect(color, params.age_effect); + + // Apply film grain + let grain = (rand(vec2(coord)) - 0.5) * params.grain; + color += vec3(grain); + + // Ensure color values are within [0, 1] range + color = clamp(color, vec3(0.0), vec3(1.0)); + + textureStore(output_texture, coord, vec4(color, 1.0)); + } + `, +} diff --git a/src/experiments/grading/types.ts b/src/experiments/grading/types.ts new file mode 100644 index 00000000..5c4a7d26 --- /dev/null +++ b/src/experiments/grading/types.ts @@ -0,0 +1,22 @@ +export type ColorGradingParameter = + | { + name: string + description: string + type: 'number' + minValue: number + maxValue: number + defaultValue: number + } + | { + name: string + description: string + type: 'string' + allowedValues: string[] + defaultValue: string + } + +export type ColorGradingFilter = { + name: string + parameters: Array + shader: string // WGSL shader code for the filter +} diff --git a/src/lib/utils/formatSegmentForExport.test.ts b/src/lib/utils/formatSegmentForExport.test.ts index 4a288a7e..d69de8cc 100644 --- a/src/lib/utils/formatSegmentForExport.test.ts +++ b/src/lib/utils/formatSegmentForExport.test.ts @@ -1,7 +1,12 @@ import { expect, test } from 'vitest' +import { + ClapOutputType, + ClapSegmentCategory, + ClapSegmentStatus, + newSegment, +} from '@aitube/clap' import { formatSegmentForExport } from './formatSegmentForExport' -import { newSegment } from '@aitube/clap' test('formatSegmentForExport', () => { expect( @@ -33,7 +38,7 @@ test('formatSegmentForExport', () => { assetFileFormat: '', assetSourceType: 'EMPTY', assetUrl: '', - category: 'generic', + category: ClapSegmentCategory.GENERIC, createdAt: '2024-07-13T19:30:13.387Z', createdBy: 'ai', editedBy: 'ai', @@ -43,7 +48,7 @@ test('formatSegmentForExport', () => { id: '301a3e6f-cb59-4a85-afd6-4737eeeee356', label: '', outputGain: 0, - outputType: 'text', + outputType: ClapOutputType.TEXT, prompt: '', renderId: '', revision: 0, @@ -51,7 +56,7 @@ test('formatSegmentForExport', () => { seed: 7549327, startTimeInLines: 0, startTimeInMs: 0, - status: 'to_generate', + status: ClapSegmentStatus.TO_GENERATE, track: 0, }, shortId: 'generic0', diff --git a/src/lib/utils/getTypeAndExtension.test.ts b/src/lib/utils/getTypeAndExtension.test.ts index 6cb86268..1b1f6152 100644 --- a/src/lib/utils/getTypeAndExtension.test.ts +++ b/src/lib/utils/getTypeAndExtension.test.ts @@ -1,4 +1,5 @@ import { expect, test } from 'vitest' +import { ClapOutputType } from '@aitube/clap' import { getTypeAndExtension } from './getTypeAndExtension' @@ -13,18 +14,18 @@ test('getTypeAndExtension', () => { assetFileFormat: 'image/gif', category: 'image', extension: 'gif', - outputType: 'image', + outputType: ClapOutputType.IMAGE, }) expect(getTypeAndExtension(pngUri)).toStrictEqual({ assetFileFormat: 'image/png', category: 'image', extension: 'png', - outputType: 'image', + outputType: ClapOutputType.IMAGE, }) expect(getTypeAndExtension(mp4Uri)).toStrictEqual({ assetFileFormat: 'video/mp4', category: 'video', extension: 'mp4', - outputType: 'video', + outputType: ClapOutputType.VIDEO, }) }) diff --git a/src/services/ui/theme.ts b/src/services/ui/theme.ts index b76d5d0d..4b83e62d 100644 --- a/src/services/ui/theme.ts +++ b/src/services/ui/theme.ts @@ -21,6 +21,7 @@ export const baseClapSegmentCategoryColors: ClapSegmentCategoryColors = { [ClapSegmentCategory.MESH]: { hue: 32, saturation: 30, lightness: 78.6 }, [ClapSegmentCategory.DEPTH]: { hue: 242, saturation: 30, lightness: 78.6 }, [ClapSegmentCategory.EVENT]: { hue: 270, saturation: 30, lightness: 78.6 }, + [ClapSegmentCategory.EFFECT]: { hue: 270, saturation: 30, lightness: 78.6 }, [ClapSegmentCategory.INTERFACE]: { hue: 216, saturation: 30, @@ -78,14 +79,14 @@ export const backstage: UITheme = { defaultBgColor: '#1c1917', defaultTextColor: '#d6d3d1', defaultPrimaryColor: '#FACC15', - defaultBorderColor: '#152639', + defaultBorderColor: '#3e3a39', logoColor: '#FACC15', editorBgColor: '#292524', editorCursorColor: '#f5f5f4', editorTextColor: '#d6d3d1', editorMenuBgColor: '#1c1917', editorMenuTextColor: 'd6d3d1', - editorBorderColor: '#152639', + editorBorderColor: '#3e3a39', monitorBgColor: '#1c1917', monitorSecondaryTextColor: '#D6D3D1', monitorPrimaryTextColor: '#FACC15', @@ -565,6 +566,11 @@ export const silent: UITheme = { [ClapSegmentCategory.MESH]: { hue: 32, saturation: 0, lightness: 85 }, [ClapSegmentCategory.DEPTH]: { hue: 242, saturation: 0, lightness: 85 }, [ClapSegmentCategory.EVENT]: { hue: 270, saturation: 0, lightness: 85 }, + [ClapSegmentCategory.EFFECT]: { + hue: 270, + saturation: 0, + lightness: 85, + }, [ClapSegmentCategory.INTERFACE]: { hue: 216, saturation: 0, diff --git a/tsconfig.json b/tsconfig.json index 457ca91f..be58954c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,7 +19,8 @@ ], "paths": { "@/*": ["./src/*"] - } + }, + "types": ["@webgpu/types", "@types/dom-speech-recognition"] }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "vitest.config.mts"], "exclude": ["node_modules"]