diff --git a/.browserslistrc b/.browserslistrc deleted file mode 100644 index 552eaf845..000000000 --- a/.browserslistrc +++ /dev/null @@ -1 +0,0 @@ -electron >= 11.2.0 diff --git a/.editorconfig b/.editorconfig index 9d08a1a82..cf640d53f 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,9 +1,9 @@ -root = true - -[*] -charset = utf-8 -indent_style = space -indent_size = 2 -end_of_line = lf -insert_final_newline = true -trim_trailing_whitespace = true +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true \ No newline at end of file diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 000000000..a6f34fea7 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,4 @@ +node_modules +dist +out +.gitignore diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 000000000..173664716 --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,15 @@ +/* eslint-env node */ +require("@rushstack/eslint-patch/modern-module-resolution"); + +module.exports = { + extends: [ + "eslint:recommended", + "plugin:vue/vue3-recommended", + "@electron-toolkit", + "@vue/eslint-config-prettier", + ], + rules: { + "vue/require-default-prop": "off", + "vue/multi-word-component-names": "off", + }, +}; diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 6f4f79fde..000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,26 +0,0 @@ -module.exports = { - root: true, - env: { - node: true - }, - extends: ["plugin:vue/essential", "@vue/prettier"], - plugins: ["no-for-each"], - rules: { - "no-console": "off", - "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off", - "no-for-each/no-for-each": 2, - "no-for-each/no-for-of": 2, - "no-for-each/no-for-in": 2, - "prefer-const": [ - "error", - { - destructuring: "any", - ignoreReadBeforeAssign: false - } - ], - curly: "error" - }, - parserOptions: { - parser: "babel-eslint" - } -}; diff --git a/.gitignore b/.gitignore index bcd7b7cb9..ab9410a8f 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,6 @@ yarn-error.log* #Electron-builder output /dist_electron .env +out + +test-results diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..9c6b791d5 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,6 @@ +out +dist +pnpm-lock.yaml +LICENSE.md +tsconfig.json +tsconfig.*.json diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 86d085f84..940260d85 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,7 +1,3 @@ { - "recommendations": [ - "vue.volar", - "esbenp.prettier-vscode", - "dbaeumer.vscode-eslint" - ] -} \ No newline at end of file + "recommendations": ["dbaeumer.vscode-eslint"] +} diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..0b6b9a649 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,39 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Debug Main Process", + "type": "node", + "request": "launch", + "cwd": "${workspaceRoot}", + "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron-vite", + "windows": { + "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron-vite.cmd" + }, + "runtimeArgs": ["--sourcemap"], + "env": { + "REMOTE_DEBUGGING_PORT": "9222" + } + }, + { + "name": "Debug Renderer Process", + "port": 9222, + "request": "attach", + "type": "chrome", + "webRoot": "${workspaceFolder}/src/renderer", + "timeout": 60000, + "presentation": { + "hidden": true + } + } + ], + "compounds": [ + { + "name": "Debug All", + "configurations": ["Debug Main Process", "Debug Renderer Process"], + "presentation": { + "order": 1 + } + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..4c05394ec --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "[typescript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[javascript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[json]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + } +} diff --git a/README.md b/README.md index 995b9a3dc..9da34f167 100644 --- a/README.md +++ b/README.md @@ -1,124 +1,34 @@ -

modV

-

modV logo

+# modv-vite -

- - GitHub release (latest by date including pre-releases) - - - Documentation - - - Maintenance - - - License: MIT - - - Twitter: @_modV_ - -

-

-modV is a modular audio visualisation environment built upon web technologies. -

+An Electron application with Vue +## Recommended IDE Setup -## Download +- [VSCode](https://code.visualstudio.com/) + [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) + [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) -Find the latest modV binaries available for download in the releases section. +## Project Setup -https://github.com/vcync/modV/releases/latest - - - -## Project development setup +### Install -``` -yarn +```bash +$ yarn ``` -### Compiles and hot-reloads for development +### Development +```bash +$ yarn dev ``` -yarn electron:serve -``` - -### Builds for release - -``` -yarn electron:build -``` - -### Caveats - -#### Removing a package -If you want to remove a package with `yarn remove`, make sure to run `yarn` afterwards as we are using `patch-package` without `postinstall-postinstall` because of https://github.com/vcync/modV/issues/554. +### Build +```bash +# For windows +$ yarn build:win +# For macOS +$ yarn build:mac -## Platform specifics for building and development - -### Windows - -#### Shell - -CMD or PowerShell is required as native binaries need to be compiled or fetched for Windows. WSL (Windows Subsystem for Linux) or WSL2 are not supported as they will try to compile those binaries for Ubuntu. - -#### Dependancies - -Visual Studio Tools and Python are required by node-gyp, which build native node modules. -Since Node.js 16, the official Windows installer can install them. - -If you're using nvm-windows or another headless Node.js install, you can easily install the required packages with [Chocolatey](https://chocolatey.org/install): - -``` -choco install python visualstudio2022-workload-vctools +# For Linux +$ yarn build:linux ``` - -#### 'vue-cli-service' is not recognized - -Please see issue 122 ([vcync/modv-3/issues/122#issuecomment-640100114](https://github.com/vcync/modv-3/issues/122#issuecomment-640100114)) on how to resolve this. - -### Ubuntu/Debian - -libndi is required for NDI sources and must be installed for modV to build. You can find that available to download here: [Palakis/obs-ndi/releases](https://github.com/Palakis/obs-ndi/releases) - -Last successful build was with `libndi4_4.5.1-1_amd64.deb`. - -### Other Linux flavours - -Untested. NDI is provided by grandiose, our fork is here: [vcync/grandiose](https://github.com/vcync/grandiose/) This fork of grandiose has other libndi supported platforms, however even on Ubuntu we needed the above libndi package to be installed. - -Let us know how you get on (good or bad) and we'll update the repo and docs accordingly. - - - -## Contributing - -Contributions, issues and feature requests are welcome! -Feel free to check [issues page](https://github.com/vcync/modV/issues). - - - -## Show your support - -Give a ⭐️ if this project helped you! - - - -## Acknowledgements - -Thank you to: - -- [Tim Pietrusky](https://nerddis.co/) for his continued support, help, mentorship and kindness -- [Live:JS](http://livejs.network/) for inspiration, motivation and advice -- Hugh Rawlinson, Nevo Segal and Jakub Fiala for the incredible audio analysis engine, [meyda](https://github.com/hughrawlinson/meyda) -- [Dario Villanueva](http://alolo.co/) for his advice and introduction to live visuals which inspired this whole project - - - -## License - -Copyright © 2022 [vcync](https://github.com/vcync). -This project is [MIT](https://github.com/vcync/modV/blob/main/LICENSE) licensed. diff --git a/babel.config.js b/babel.config.js deleted file mode 100644 index ca59b2744..000000000 --- a/babel.config.js +++ /dev/null @@ -1,12 +0,0 @@ -module.exports = { - presets: [ - "@vue/app", - { - exclude: ["transform-regenerator"] - } - ], - plugins: [ - "@babel/plugin-proposal-nullish-coalescing-operator", - "@babel/plugin-proposal-optional-chaining" - ] -}; diff --git a/dev-app-update.yml b/dev-app-update.yml new file mode 100644 index 000000000..9e5b033cc --- /dev/null +++ b/dev-app-update.yml @@ -0,0 +1,3 @@ +provider: generic +url: https://example.com/auto-updates +updaterCacheDirName: modv-vite-updater diff --git a/electron-builder.yml b/electron-builder.yml new file mode 100644 index 000000000..abc08713e --- /dev/null +++ b/electron-builder.yml @@ -0,0 +1,49 @@ +appId: gl.vcync.modv +productName: modV +directories: + buildResources: resources +files: + - '!**/.vscode/*' + - '!src/*' + - '!electron.vite.config.{js,ts,mjs,cjs}' + - '!{.eslintignore,.eslintrc.cjs,.prettierignore,.prettierrc.yaml,dev-app-update.yml,CHANGELOG.md,README.md}' + - '!{.env,.env.*,.npmrc,pnpm-lock.yaml}' + - '!tests/*' + - '!patches/*' +asarUnpack: + - resources/** + - node_modules/grandiose + - node_modules/ffmpeg-fluent +win: + executableName: modV +nsis: + artifactName: ${name}-${version}-setup.${ext} + shortcutName: ${productName} + uninstallDisplayName: ${productName} + createDesktopShortcut: always +mac: + entitlementsInherit: resources/entitlements.mac.plist + extendInfo: + - NSCameraUsageDescription: Application requests access to the device's camera. + - NSMicrophoneUsageDescription: Application requests access to the device's microphone. + - NSDocumentsFolderUsageDescription: Application requests access to the user's Documents folder. + - NSDownloadsFolderUsageDescription: Application requests access to the user's Downloads folder. + notarize: true + singleArchFiles: "node_modules/grandiose/**" +dmg: + artifactName: ${name}-${version}.${ext} + sign: false +linux: + target: + - AppImage + - snap + - deb + maintainer: modv.vcync.gl + category: Graphics +appImage: + artifactName: ${name}-${version}.${ext} +npmRebuild: false +# publish: +# provider: github +# channel: "prerelease" +# vPrefixedTagName: false diff --git a/electron.vite.config.mjs b/electron.vite.config.mjs new file mode 100644 index 000000000..23906f7c1 --- /dev/null +++ b/electron.vite.config.mjs @@ -0,0 +1,60 @@ +import { resolve } from "path"; +import { defineConfig, externalizeDepsPlugin } from "electron-vite"; +import vue from "@vitejs/plugin-vue"; +import svgLoader from "vite-svg-loader"; +import { nodePolyfills } from "vite-plugin-node-polyfills"; + +export default defineConfig({ + main: { + plugins: [ + externalizeDepsPlugin({ + include: ["webpack"], + }), + ], + }, + preload: { + plugins: [externalizeDepsPlugin()], + build: { + rollupOptions: { + input: { + index: resolve(__dirname, "src/preload/index.js"), + colorPicker: resolve(__dirname, "src/preload/colorPicker.js"), + }, + }, + }, + }, + renderer: { + build: { + rollupOptions: { + input: { + index: resolve(__dirname, "src/renderer/index.html"), + outputWindow: resolve(__dirname, "src/renderer/output-window.html"), + colorPicker: resolve(__dirname, "src/renderer/color-picker.html"), + splashScreen: resolve(__dirname, "src/renderer/splash-screen.html"), + }, + external: ["grandiose"], + }, + }, + resolve: { + alias: { + "@renderer": resolve("src/renderer/src"), + }, + }, + plugins: [ + vue({ + template: { + compilerOptions: { + isCustomElement: (tag) => ["grid", "c"].includes(tag), + }, + }, + }), + svgLoader(), + nodePolyfills({ + include: ["events"], + }), + ], + worker: { + format: "es", + }, + }, +}); diff --git a/jsconfig.json b/jsconfig.json deleted file mode 100644 index 40608e163..000000000 --- a/jsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extensions": [ - ".vue" - ], - "vueCompilerOptions": { - "target": 2 - } -} \ No newline at end of file diff --git a/package.json b/package.json index d551bc308..83622bcd8 100644 --- a/package.json +++ b/package.json @@ -1,51 +1,48 @@ { - "name": "modv", - "productName": "modV", - "description": "modular audio visualisation powered by JavaScript", - "author": "vcync", - "version": "3.20.0", - "private": true, - "homepage": "https://modv.vcync.gl/", - "repository": { - "type": "git", - "url": "git+https://github.com/vcync/modV.git" - }, - "bugs": { - "url": "https://github.com/vcync/modV/issues" - }, + "name": "modv-vite", + "version": "1.0.0", + "description": "An Electron application with Vue", + "main": "./out/main/index.js", + "author": "example.com", + "homepage": "https://electron-vite.org", "scripts": { - "serve": "vue-cli-service serve", - "build": "vue-cli-service build", - "lint": "vue-cli-service lint", - "electron:build": "vue-cli-service electron:build", - "electron:serve": "vue-cli-service electron:serve", - "postinstall": "electron-builder install-app-deps && patch-package", - "postuninstall": "electron-builder install-app-deps", + "build": "electron-vite build", + "build:linux": "npm run build && electron-builder --linux", + "build:mac": "npm run build && electron-builder --mac", + "build:unpack": "npm run build && electron-builder --dir", + "build:win": "npm run build && electron-builder --win", + "dev": "electron-vite dev", + "format": "prettier --write .", + "lint": "eslint . --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix", + "postinstall": "patch-package && electron-builder install-app-deps", + "start": "electron-vite preview", "test:e2e": "npx playwright test" }, "dependencies": { + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@ckpack/vue-color": "^1.5.0", + "@electron-toolkit/preload": "^3.0.0", + "@electron-toolkit/utils": "^3.0.0", "@electron/remote": "^2.1.2", "animated-gif-detector": "^1.2.0", - "animejs": "3.2.1", + "animejs": "^3.2.1", "canvas-text-wrapper": "github:cyberj/canvas-text-wrapper#master", + "chokidar": "2.1.8", "color": "^3.1.2", - "dotenv": "^8.2.0", "electron-updater": "^6.3.0", "fluent-ffmpeg": "^2.1.2", "fuse.js": "^6.2.1", - "golden-layout": "^1.5.9", - "grandiose": "github:vcync/grandiose#feat/workerCompatibility", + "golden-layout": "^2.6.0", + "grandiose": "github:vcync/grandiose-send-arm#31969cc77fe87ba2df183bfa19d37f25a01f2e11", "hapticjs": "^1.0.7", "interactive-shader-format": "github:vcync/interactive-shader-format-js#78b62b6f4c787b870852df4c8e7b1131e331d8a6", "lodash.get": "^4.4.2", "lodash.set": "^4.3.2", "mathjs": "^7.5.1", "meyda": "^5.6.0", - "mkdirp": "^0.5.1", + "node-osc": "^9.1.3", "npm": "6.14.6", - "nwjs-menu-browser": "^1.0.0", "ospath": "^1.2.2", - "patch-package": "^6.2.2", "pex-context": "^2.10.2", "promise-worker": "^2.0.1", "promise-worker-transferable": "^1.0.4", @@ -54,61 +51,32 @@ "tap-tempo": "^0.1.1", "three": "^0.131.3", "uuid": "^9.0.0", - "vue": "^3.0.0", - "vue-class-component": "^7.2.3", - "vue-color": "^2.7.1", - "vue-fragment": "^1.5.1", - "vue-golden-layout": "^2.1.0", - "vue-property-decorator": "^8.3.0", - "vue-smooth-dnd": "^0.8.1", - "vuex": "^3.6.2", + "vue": "^3.4.27", + "vue3-smooth-dnd": "^0.0.6", + "vuex": "^4.1.0", "vuex-persistedstate": "^4.0.0-beta.3", - "webpack": "^5.94.0", - "webpack-3": "npm:webpack@3.12.0" + "webpack": "3.12.0" }, "devDependencies": { - "@babel/core": "^7.0.0-0", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.0", - "@babel/plugin-proposal-optional-chaining": "^7.16.0", - "@playwright/test": "^1.31.2", - "@semantic-release/git": "^9.0.0", - "@vue/cli-plugin-babel": "^5.0.8", - "@vue/cli-plugin-eslint": "^3.12.1", - "@vue/cli-service": "^5.0.8", - "@vue/eslint-config-prettier": "^4.0.1", - "@vue/runtime-dom": "^3.2.47", - "babel-eslint": "^10.0.3", - "babel-loader": "^9.1.2", - "core-js": "^3.19.1", - "electron": "31.3.1", - "electron-builder": "^22.9.1", - "electron-notarize": "^1.2.2", - "electron-playwright-helpers": "^1.5.3", - "eslint": "^5.16.0", - "eslint-plugin-no-for-each": "^0.1.14", - "eslint-plugin-vue": "^5.2.3", - "lint-staged": "^8.2.1", - "node-loader": "^0.6.0", - "playwright": "^1.31.2", - "playwright-core": "^1.31.2", - "sass-loader": "^7.3.1", - "text-loader": "0.0.1", - "vue-cli-plugin-electron-builder": "3.0.0-alpha.4", - "vue-template-babel-compiler": "^2.0.0", - "vue-template-compiler": "^2.7.14", - "vuex-localstorage": "^1.0.0" - }, - "gitHooks": { - "pre-commit": "lint-staged" - }, - "lint-staged": { - "*.{js,vue}": [ - "vue-cli-service lint", - "git add" - ] - }, - "resolutions": { - "electron-builder": "23.0.2", - "@achrinza/node-ipc": "9.2.7" + "@electron-toolkit/eslint-config": "^1.0.1", + "@playwright/test": "^1.44.0", + "@rushstack/eslint-patch": "^1.6.1", + "@vitejs/plugin-vue": "^5.0.4", + "@vue/eslint-config-prettier": "^9.0.0", + "electron": "^31.3.1", + "electron-builder": "^24.9.1", + "electron-playwright-helpers": "^1.7.1", + "electron-vite": "^2.0.0", + "eslint": "^8.56.0", + "eslint-plugin-vue": "^9.20.1", + "patch-package": "^8.0.0", + "playwright": "^1.44.0", + "playwright-core": "^1.44.0", + "postinstall-postinstall": "^2.1.0", + "prettier": "^3.2.4", + "vite": "^5.0.12", + "vite-plugin-electron-renderer": "^0.14.5", + "vite-plugin-node-polyfills": "^0.21.0", + "vite-svg-loader": "^5.1.0" } -} \ No newline at end of file +} diff --git a/patches/golden-layout+2.6.0.patch b/patches/golden-layout+2.6.0.patch new file mode 100644 index 000000000..2a83c7f9c --- /dev/null +++ b/patches/golden-layout+2.6.0.patch @@ -0,0 +1,13 @@ +diff --git a/node_modules/golden-layout/dist/esm/ts/controls/tab.js b/node_modules/golden-layout/dist/esm/ts/controls/tab.js +index c230e60..f511166 100644 +--- a/node_modules/golden-layout/dist/esm/ts/controls/tab.js ++++ b/node_modules/golden-layout/dist/esm/ts/controls/tab.js +@@ -61,7 +61,7 @@ export class Tab { + if (reorderEnabled) { + this.enableReorder(); + } +- this._element.addEventListener('click', this._tabClickListener, { passive: true }); ++ this._element.addEventListener('pointerdown', this._tabClickListener, { passive: true }); + this._element.addEventListener('touchstart', this._tabTouchStartListener, { passive: true }); + if (this._componentItem.isClosable) { + this._closeElement.addEventListener('click', this._closeClickListener, { passive: true }); diff --git a/playwright.config.js b/playwright.config.js index 691eac234..b4263b962 100644 --- a/playwright.config.js +++ b/playwright.config.js @@ -5,5 +5,5 @@ expect.extend(extensions); export default defineConfig({ testDir: "./tests/e2e/spec", - workers: process.env.CI ? 1 : 2 + workers: process.env.CI ? 1 : 2, }); diff --git a/postcss.config.js b/postcss.config.js deleted file mode 100644 index 5bfb8f628..000000000 --- a/postcss.config.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - plugins: { - autoprefixer: {} - } -}; diff --git a/build/entitlements.mac.plist b/resources/entitlements.mac.plist similarity index 100% rename from build/entitlements.mac.plist rename to resources/entitlements.mac.plist diff --git a/build/icon.ico b/resources/icon.ico similarity index 100% rename from build/icon.ico rename to resources/icon.ico diff --git a/build/icon.png b/resources/icon.png similarity index 100% rename from build/icon.png rename to resources/icon.png diff --git a/build/icon@2x.png b/resources/icon@2x.png similarity index 100% rename from build/icon@2x.png rename to resources/icon@2x.png diff --git a/sample-preset.json b/sample-preset.json deleted file mode 100644 index 81515c839..000000000 --- a/sample-preset.json +++ /dev/null @@ -1,11119 +0,0 @@ -{ - "groups": [ - { - "enabled": true, - "name": "New Group", - "clearing": true, - "hidden": false, - "modules": [ - "f37d029c-cdbf-427d-91ac-5f5131c7fae4", - "df151ec6-2654-4ba1-b348-ada63583923f", - "339beb6c-3c28-47f1-81a8-eaad0d287406", - "9f6b3a26-d5a8-4c49-a640-ba1e798e4bcb", - "d9ee2124-0e6a-4640-8a16-ce08fc53c078", - "396f9093-4899-4762-8a45-86ee91483baf", - "b2b2be9e-5bac-4a74-83da-0b27a970cffe" - ], - "inherit": false, - "alpha": 1, - "compositeOperation": "normal", - "id": "f0327ea4-5f7d-494d-b5db-6bef0e763b0d", - "writeToSwap": true, - "pipeline": false - }, - { - "name": "New Group", - "clearing": true, - "enabled": true, - "hidden": false, - "modules": [ - "63070d96-3c8f-4af6-90b8-8397986aa128" - ], - "inherit": true, - "alpha": 1, - "compositeOperation": "normal", - "id": "a2f19209-a308-4836-a7aa-c8b734542ef0" - } - ], - "inputs": { - "focusedInput": { - "id": "9bb85105-3b17-422d-aec2-044556ca3162", - "title": "RGB Halftone-lookaround: Enabled" - }, - "inputs": { - "290c6d54-8568-4195-862c-dc814e43a2c9": { - "type": "action", - "location": "modules/updateProp", - "data": { - "moduleId": "9f6b3a26-d5a8-4c49-a640-ba1e798e4bcb", - "prop": "amount" - }, - "id": "290c6d54-8568-4195-862c-dc814e43a2c9" - }, - "de656b0b-6e4d-4ccb-8520-8c993608ba05": { - "type": "action", - "location": "modules/updateProp", - "data": { - "moduleId": "9f6b3a26-d5a8-4c49-a640-ba1e798e4bcb", - "prop": "speed" - }, - "id": "de656b0b-6e4d-4ccb-8520-8c993608ba05" - }, - "bc19451f-8cff-4f4d-bc51-458896ad9aad": { - "type": "action", - "location": "modules/updateProp", - "data": { - "moduleId": "9f6b3a26-d5a8-4c49-a640-ba1e798e4bcb", - "prop": "wrap" - }, - "id": "bc19451f-8cff-4f4d-bc51-458896ad9aad" - }, - "477b2f4f-f56d-45b2-b568-ab47c89f96cc": { - "type": "action", - "location": "modules/updateProp", - "data": { - "moduleId": "9f6b3a26-d5a8-4c49-a640-ba1e798e4bcb", - "prop": "size" - }, - "id": "477b2f4f-f56d-45b2-b568-ab47c89f96cc" - }, - "b24432a1-d760-4dca-80f3-1f2e33fcc74e": { - "type": "action", - "location": "modules/updateProp", - "data": { - "moduleId": "9f6b3a26-d5a8-4c49-a640-ba1e798e4bcb", - "prop": "intensity" - }, - "id": "b24432a1-d760-4dca-80f3-1f2e33fcc74e" - }, - "2e9a85c4-b5d0-4ea2-a908-b556e9c4517a": { - "type": "action", - "location": "modules/updateProp", - "data": { - "moduleId": "9f6b3a26-d5a8-4c49-a640-ba1e798e4bcb", - "prop": "soundType" - }, - "id": "2e9a85c4-b5d0-4ea2-a908-b556e9c4517a" - }, - "fc082f46-dfa5-4fe8-96ad-bb221ba34acd": { - "type": "action", - "location": "modules/updateProp", - "data": { - "moduleId": "9f6b3a26-d5a8-4c49-a640-ba1e798e4bcb", - "prop": "color" - }, - "id": "fc082f46-dfa5-4fe8-96ad-bb221ba34acd" - }, - "7b85d92f-4c89-4919-bc84-6b469aa7c08a": { - "type": "commit", - "location": "modules/UPDATE_ACTIVE_MODULE_META", - "data": { - "id": "9f6b3a26-d5a8-4c49-a640-ba1e798e4bcb", - "metaKey": "alpha" - }, - "id": "7b85d92f-4c89-4919-bc84-6b469aa7c08a" - }, - "f0b436b7-8a85-4dea-a89c-527ce7522824": { - "type": "commit", - "location": "modules/UPDATE_ACTIVE_MODULE_META", - "data": { - "id": "9f6b3a26-d5a8-4c49-a640-ba1e798e4bcb", - "metaKey": "enabled" - }, - "id": "f0b436b7-8a85-4dea-a89c-527ce7522824" - }, - "1a74f7fa-fd3c-456e-a412-49c6da1e49ae": { - "type": "commit", - "location": "modules/UPDATE_ACTIVE_MODULE_META", - "data": { - "id": "9f6b3a26-d5a8-4c49-a640-ba1e798e4bcb", - "metaKey": "compositeOperation" - }, - "id": "1a74f7fa-fd3c-456e-a412-49c6da1e49ae" - }, - "9e060f4c-dc02-4480-8c18-48cfb5ebce7f": { - "type": "action", - "location": "modules/updateProp", - "data": { - "moduleId": "63070d96-3c8f-4af6-90b8-8397986aa128", - "prop": "inputImage" - }, - "id": "9e060f4c-dc02-4480-8c18-48cfb5ebce7f" - }, - "766f609e-86e3-4b18-8faf-0982abb43903": { - "type": "action", - "location": "modules/updateProp", - "data": { - "moduleId": "63070d96-3c8f-4af6-90b8-8397986aa128", - "prop": "gridSize" - }, - "id": "766f609e-86e3-4b18-8faf-0982abb43903" - }, - "23de3a85-0973-47be-bac1-aef4de667771": { - "type": "action", - "location": "modules/updateProp", - "data": { - "moduleId": "63070d96-3c8f-4af6-90b8-8397986aa128", - "prop": "smoothing" - }, - "id": "23de3a85-0973-47be-bac1-aef4de667771" - }, - "a4267257-b60c-46ba-85fd-6801a0de5ac7": { - "type": "commit", - "location": "modules/UPDATE_ACTIVE_MODULE_META", - "data": { - "id": "63070d96-3c8f-4af6-90b8-8397986aa128", - "metaKey": "alpha" - }, - "id": "a4267257-b60c-46ba-85fd-6801a0de5ac7" - }, - "9bb85105-3b17-422d-aec2-044556ca3162": { - "type": "commit", - "location": "modules/UPDATE_ACTIVE_MODULE_META", - "data": { - "id": "63070d96-3c8f-4af6-90b8-8397986aa128", - "metaKey": "enabled" - }, - "id": "9bb85105-3b17-422d-aec2-044556ca3162" - }, - "c0f8e596-bbc8-4bb2-8c4c-313ecef917ed": { - "type": "commit", - "location": "modules/UPDATE_ACTIVE_MODULE_META", - "data": { - "id": "63070d96-3c8f-4af6-90b8-8397986aa128", - "metaKey": "compositeOperation" - }, - "id": "c0f8e596-bbc8-4bb2-8c4c-313ecef917ed" - }, - "f71bfe74-a360-4069-804a-b96db9437aa1": { - "type": "action", - "location": "modules/updateProp", - "data": { - "moduleId": "d9ee2124-0e6a-4640-8a16-ce08fc53c078", - "prop": "inputImage" - }, - "id": "f71bfe74-a360-4069-804a-b96db9437aa1" - }, - "00b34d1b-30d7-4302-bfb7-35e293fb6fd0": { - "type": "action", - "location": "modules/updateProp", - "data": { - "moduleId": "d9ee2124-0e6a-4640-8a16-ce08fc53c078", - "prop": "size" - }, - "id": "00b34d1b-30d7-4302-bfb7-35e293fb6fd0" - }, - "5d8d4dba-d891-44dd-9da8-efbb447172ab": { - "type": "action", - "location": "modules/updateProp", - "data": { - "moduleId": "d9ee2124-0e6a-4640-8a16-ce08fc53c078", - "prop": "rotation" - }, - "id": "5d8d4dba-d891-44dd-9da8-efbb447172ab" - }, - "e50ca8af-c2fd-4140-874f-aa03f02c8e05": { - "type": "action", - "location": "modules/updateProp", - "data": { - "moduleId": "d9ee2124-0e6a-4640-8a16-ce08fc53c078", - "prop": "angle" - }, - "id": "e50ca8af-c2fd-4140-874f-aa03f02c8e05" - }, - "5565ff57-51bd-4969-9462-987fdf1f2dbe": { - "type": "action", - "location": "modules/updateProp", - "data": { - "moduleId": "d9ee2124-0e6a-4640-8a16-ce08fc53c078", - "prop": "shift" - }, - "id": "5565ff57-51bd-4969-9462-987fdf1f2dbe" - }, - "77da0e44-7d2a-4313-ac0b-36f465e95619": { - "type": "commit", - "location": "modules/UPDATE_ACTIVE_MODULE_META", - "data": { - "id": "d9ee2124-0e6a-4640-8a16-ce08fc53c078", - "metaKey": "alpha" - }, - "id": "77da0e44-7d2a-4313-ac0b-36f465e95619" - }, - "b4157e46-00fe-47cf-944c-1befd3c6fd70": { - "type": "commit", - "location": "modules/UPDATE_ACTIVE_MODULE_META", - "data": { - "id": "d9ee2124-0e6a-4640-8a16-ce08fc53c078", - "metaKey": "enabled" - }, - "id": "b4157e46-00fe-47cf-944c-1befd3c6fd70" - }, - "d04b866b-261b-4495-9304-f7c4db3183c9": { - "type": "commit", - "location": "modules/UPDATE_ACTIVE_MODULE_META", - "data": { - "id": "d9ee2124-0e6a-4640-8a16-ce08fc53c078", - "metaKey": "compositeOperation" - }, - "id": "d04b866b-261b-4495-9304-f7c4db3183c9" - }, - "b2554546-d42e-4e98-85ce-5ea7f10d97a9": { - "type": "action", - "location": "modules/updateProp", - "data": { - "moduleId": "396f9093-4899-4762-8a45-86ee91483baf", - "prop": "inputImage" - }, - "id": "b2554546-d42e-4e98-85ce-5ea7f10d97a9" - }, - "2aba53ab-cac6-4ea0-984a-18f456807cac": { - "type": "action", - "location": "modules/updateProp", - "data": { - "moduleId": "396f9093-4899-4762-8a45-86ee91483baf", - "prop": "intensity" - }, - "id": "2aba53ab-cac6-4ea0-984a-18f456807cac" - }, - "6c738617-47ed-4e28-af63-a99cb5eef363": { - "type": "action", - "location": "modules/updateProp", - "data": { - "moduleId": "396f9093-4899-4762-8a45-86ee91483baf", - "prop": "invert_map" - }, - "id": "6c738617-47ed-4e28-af63-a99cb5eef363" - }, - "9ba3d6ae-5bfc-450d-88bc-5dbbb88fd934": { - "type": "commit", - "location": "modules/UPDATE_ACTIVE_MODULE_META", - "data": { - "id": "396f9093-4899-4762-8a45-86ee91483baf", - "metaKey": "alpha" - }, - "id": "9ba3d6ae-5bfc-450d-88bc-5dbbb88fd934" - }, - "a17dda3e-4ae2-45b5-9858-77ec58e87954": { - "type": "commit", - "location": "modules/UPDATE_ACTIVE_MODULE_META", - "data": { - "id": "396f9093-4899-4762-8a45-86ee91483baf", - "metaKey": "enabled" - }, - "id": "a17dda3e-4ae2-45b5-9858-77ec58e87954" - }, - "b2a207eb-64aa-4fa5-910e-9a98f39bd8c5": { - "type": "commit", - "location": "modules/UPDATE_ACTIVE_MODULE_META", - "data": { - "id": "396f9093-4899-4762-8a45-86ee91483baf", - "metaKey": "compositeOperation" - }, - "id": "b2a207eb-64aa-4fa5-910e-9a98f39bd8c5" - }, - "782594b1-fd58-426e-8666-69baebe30d7e": { - "type": "action", - "location": "modules/updateProp", - "data": { - "moduleId": "339beb6c-3c28-47f1-81a8-eaad0d287406", - "prop": "r" - }, - "id": "782594b1-fd58-426e-8666-69baebe30d7e" - }, - "741ba30b-e393-47bf-a5bc-4b876c92df6c": { - "type": "action", - "location": "modules/updateProp", - "data": { - "moduleId": "339beb6c-3c28-47f1-81a8-eaad0d287406", - "prop": "g" - }, - "id": "741ba30b-e393-47bf-a5bc-4b876c92df6c" - }, - "eef01aeb-7886-4486-9dac-72cbb172aed8": { - "type": "action", - "location": "modules/updateProp", - "data": { - "moduleId": "339beb6c-3c28-47f1-81a8-eaad0d287406", - "prop": "b" - }, - "id": "eef01aeb-7886-4486-9dac-72cbb172aed8" - }, - "959a159a-4288-43ee-92d8-dfb639567163": { - "type": "action", - "location": "modules/updateProp", - "data": { - "moduleId": "339beb6c-3c28-47f1-81a8-eaad0d287406", - "prop": "a" - }, - "id": "959a159a-4288-43ee-92d8-dfb639567163" - }, - "fcbb2217-3bf4-41b9-9671-26afc03e6f86": { - "type": "commit", - "location": "modules/UPDATE_ACTIVE_MODULE_META", - "data": { - "id": "339beb6c-3c28-47f1-81a8-eaad0d287406", - "metaKey": "alpha" - }, - "id": "fcbb2217-3bf4-41b9-9671-26afc03e6f86" - }, - "021ac6d6-296d-44f8-a564-2634493109e9": { - "type": "commit", - "location": "modules/UPDATE_ACTIVE_MODULE_META", - "data": { - "id": "339beb6c-3c28-47f1-81a8-eaad0d287406", - "metaKey": "enabled" - }, - "id": "021ac6d6-296d-44f8-a564-2634493109e9" - }, - "7548d90c-1fb1-465d-b404-ab7844e38e7d": { - "type": "commit", - "location": "modules/UPDATE_ACTIVE_MODULE_META", - "data": { - "id": "339beb6c-3c28-47f1-81a8-eaad0d287406", - "metaKey": "compositeOperation" - }, - "id": "7548d90c-1fb1-465d-b404-ab7844e38e7d" - }, - "365b7efd-f346-41a6-aad4-6044e429d8af": { - "type": "action", - "location": "modules/updateProp", - "data": { - "moduleId": "f37d029c-cdbf-427d-91ac-5f5131c7fae4", - "prop": "inputImage" - }, - "id": "365b7efd-f346-41a6-aad4-6044e429d8af" - }, - "fd90e0d6-41e6-4a65-90ae-f05e3585f6a6": { - "type": "action", - "location": "modules/updateProp", - "data": { - "moduleId": "f37d029c-cdbf-427d-91ac-5f5131c7fae4", - "prop": "scale" - }, - "id": "fd90e0d6-41e6-4a65-90ae-f05e3585f6a6" - }, - "a753844d-d2ff-4f70-aa55-4ed8d6cb2121": { - "type": "commit", - "location": "modules/UPDATE_ACTIVE_MODULE_META", - "data": { - "id": "f37d029c-cdbf-427d-91ac-5f5131c7fae4", - "metaKey": "alpha" - }, - "id": "a753844d-d2ff-4f70-aa55-4ed8d6cb2121" - }, - "16df58ab-864a-4b09-9bc6-8c9a4e42d4bd": { - "type": "commit", - "location": "modules/UPDATE_ACTIVE_MODULE_META", - "data": { - "id": "f37d029c-cdbf-427d-91ac-5f5131c7fae4", - "metaKey": "enabled" - }, - "id": "16df58ab-864a-4b09-9bc6-8c9a4e42d4bd" - }, - "3bba2a82-9bf4-4171-8431-5c84cbde7c38": { - "type": "commit", - "location": "modules/UPDATE_ACTIVE_MODULE_META", - "data": { - "id": "f37d029c-cdbf-427d-91ac-5f5131c7fae4", - "metaKey": "compositeOperation" - }, - "id": "3bba2a82-9bf4-4171-8431-5c84cbde7c38" - }, - "3bbd6199-77ff-44f3-bfd3-a8841f4ffa29": { - "type": "action", - "location": "modules/updateProp", - "data": { - "moduleId": "b2b2be9e-5bac-4a74-83da-0b27a970cffe", - "prop": "rOffset" - }, - "id": "3bbd6199-77ff-44f3-bfd3-a8841f4ffa29" - }, - "e3b0ae44-eb82-455d-a3dc-b58a1e36bea5": { - "type": "action", - "location": "modules/updateProp", - "data": { - "moduleId": "b2b2be9e-5bac-4a74-83da-0b27a970cffe", - "prop": "gOffset" - }, - "id": "e3b0ae44-eb82-455d-a3dc-b58a1e36bea5" - }, - "5f88ecbf-161f-4346-9a08-9b45eb0bd753": { - "type": "action", - "location": "modules/updateProp", - "data": { - "moduleId": "b2b2be9e-5bac-4a74-83da-0b27a970cffe", - "prop": "bOffset" - }, - "id": "5f88ecbf-161f-4346-9a08-9b45eb0bd753" - }, - "d99d8e26-497a-4bed-a5ca-4b0fadb08b16": { - "type": "commit", - "location": "modules/UPDATE_ACTIVE_MODULE_META", - "data": { - "id": "b2b2be9e-5bac-4a74-83da-0b27a970cffe", - "metaKey": "alpha" - }, - "id": "d99d8e26-497a-4bed-a5ca-4b0fadb08b16" - }, - "5716fafe-2110-4f6b-835f-e4998529495c": { - "type": "commit", - "location": "modules/UPDATE_ACTIVE_MODULE_META", - "data": { - "id": "b2b2be9e-5bac-4a74-83da-0b27a970cffe", - "metaKey": "enabled" - }, - "id": "5716fafe-2110-4f6b-835f-e4998529495c" - }, - "efc43509-105e-45f8-bb96-32f6fed2e473": { - "type": "commit", - "location": "modules/UPDATE_ACTIVE_MODULE_META", - "data": { - "id": "b2b2be9e-5bac-4a74-83da-0b27a970cffe", - "metaKey": "compositeOperation" - }, - "id": "efc43509-105e-45f8-bb96-32f6fed2e473" - }, - "b4091ed5-09db-4ab6-ada4-8383535a71a4": { - "type": "action", - "location": "modules/updateProp", - "data": { - "moduleId": "df151ec6-2654-4ba1-b348-ada63583923f", - "prop": "inputImage" - }, - "id": "b4091ed5-09db-4ab6-ada4-8383535a71a4" - }, - "99f2b02d-14ef-426a-8b7d-3b5326db705a": { - "type": "action", - "location": "modules/updateProp", - "data": { - "moduleId": "df151ec6-2654-4ba1-b348-ada63583923f", - "prop": "hue" - }, - "id": "99f2b02d-14ef-426a-8b7d-3b5326db705a" - }, - "f17ed110-720b-48ea-b055-4f774bd682c8": { - "type": "action", - "location": "modules/updateProp", - "data": { - "moduleId": "df151ec6-2654-4ba1-b348-ada63583923f", - "prop": "saturation" - }, - "id": "f17ed110-720b-48ea-b055-4f774bd682c8" - }, - "ec80304b-03f0-47a0-a2d8-6b416fb03e3f": { - "type": "commit", - "location": "modules/UPDATE_ACTIVE_MODULE_META", - "data": { - "id": "df151ec6-2654-4ba1-b348-ada63583923f", - "metaKey": "alpha" - }, - "id": "ec80304b-03f0-47a0-a2d8-6b416fb03e3f" - }, - "cbf0f84f-74be-4aa3-b6f7-1ee023f1ae71": { - "type": "commit", - "location": "modules/UPDATE_ACTIVE_MODULE_META", - "data": { - "id": "df151ec6-2654-4ba1-b348-ada63583923f", - "metaKey": "enabled" - }, - "id": "cbf0f84f-74be-4aa3-b6f7-1ee023f1ae71" - }, - "cb7c4c6b-e55b-4d5a-8601-074c830767d9": { - "type": "commit", - "location": "modules/UPDATE_ACTIVE_MODULE_META", - "data": { - "id": "df151ec6-2654-4ba1-b348-ada63583923f", - "metaKey": "compositeOperation" - }, - "id": "cb7c4c6b-e55b-4d5a-8601-074c830767d9" - } - }, - "inputLinks": { - "fd90e0d6-41e6-4a65-90ae-f05e3585f6a6": { - "id": "fd90e0d6-41e6-4a65-90ae-f05e3585f6a6", - "location": "meyda/getFeature", - "type": "getter", - "args": [ - "energy" - ], - "min": 0, - "max": 0.01 - }, - "5d8d4dba-d891-44dd-9da8-efbb447172ab": { - "id": "5d8d4dba-d891-44dd-9da8-efbb447172ab", - "location": "tweens.tweens['0a2e634a-f54f-4ffd-98bf-595857ac6268'].value[0]", - "type": "state", - "min": 0, - "max": 1 - }, - "00b34d1b-30d7-4302-bfb7-35e293fb6fd0": { - "id": "00b34d1b-30d7-4302-bfb7-35e293fb6fd0", - "location": "tweens.tweens['341e2bfd-02e1-42c8-9abb-2dfac3be14cf'].value[0]", - "type": "state", - "min": 0, - "max": 1 - } - } - }, - "midi": { - "devices": { - "-507337293-IAC Driver Bus 1-Apple Inc.": { - "id": "-507337293", - "name": "IAC Driver Bus 1", - "manufacturer": "Apple Inc.", - "channelData": { - "0": { - "242": 0 - }, - "46": { - "242": 118 - }, - "49": { - "242": 54 - }, - "61": { - "242": 56 - }, - "92": { - "242": 69 - }, - "112": { - "242": 6 - }, - "118": { - "242": 18 - }, - "undefined": {} - }, - "listenForInput": true, - "listenForClock": true - } - }, - "learning": false - }, - "modules": { - "9f6b3a26-d5a8-4c49-a640-ba1e798e4bcb": { - "meta": { - "name": "Ball", - "author": "2xAA", - "version": "1.0.0", - "audioFeatures": [ - "zcr", - "rms" - ], - "type": "2d", - "alpha": 1, - "enabled": true, - "compositeOperation": "normal", - "alphaInputId": "7b85d92f-4c89-4919-bc84-6b469aa7c08a", - "enabledInputId": "f0b436b7-8a85-4dea-a89c-527ce7522824", - "compositeOperationInputId": "1a74f7fa-fd3c-456e-a412-49c6da1e49ae" - }, - "$id": "9f6b3a26-d5a8-4c49-a640-ba1e798e4bcb", - "$moduleName": "Ball", - "$props": { - "amount": { - "label": "Amount", - "type": "int", - "min": 1, - "max": 300, - "default": 10, - "strict": true, - "id": "9ca5ba19-ab40-461b-8659-939177cfb481" - }, - "speed": { - "label": "Speed", - "type": "float", - "min": 0, - "max": 20, - "step": 0.01, - "default": 2, - "id": "37b9d8a3-3eaa-4189-82b2-b4fed06188c5" - }, - "wrap": { - "label": "Wrap", - "type": "bool", - "default": false, - "id": "43e2f2c9-29d3-40c7-a813-814cd6e61a88" - }, - "size": { - "label": "Size", - "type": "int", - "min": 1, - "max": 50, - "step": 1, - "default": 2, - "abs": true, - "id": "1fdc8ae0-6d83-4d26-8fdf-9974490f47e7" - }, - "intensity": { - "label": "RMS/ZCR Intensity", - "type": "int", - "min": 0, - "max": 30, - "step": 1, - "default": 15, - "abs": true, - "id": "8d57cbf7-56e5-4152-a86a-db3470f8e2a3" - }, - "soundType": { - "label": "RMS (unchecked) / ZCR (checked)", - "type": "bool", - "default": false, - "id": "31de44be-241a-4b9a-a33f-3db2977eea88" - }, - "color": { - "type": "tween", - "component": "PaletteControl", - "default": { - "data": [ - [ - 0, - 0, - 0 - ], - [ - 255, - 255, - 255 - ] - ], - "duration": 10000, - "easing": "linear" - }, - "id": "ced23f9a-ad17-455c-9693-40ca5bb190f7" - } - }, - "props": { - "amount": 22, - "speed": 6.475, - "wrap": false, - "size": 6, - "intensity": 15, - "soundType": false, - "color": { - "id": "bad555dd-f75b-4256-bb2d-5d430a5ae1ed", - "frames": [ - { - "0": 0, - "1": 0, - "2": 0 - }, - { - "0": 0, - "1": 0, - "2": 0 - }, - { - "0": 0, - "1": 0, - "2": 0 - }, - { - "0": 0, - "1": 0, - "2": 0 - }, - { - "0": 0, - "1": 0, - "2": 0 - }, - { - "0": 0, - "1": 0, - "2": 0 - }, - { - "0": 0, - "1": 0, - "2": 0 - }, - { - "0": 1.2233721350802031, - "1": 1.2233721350802031, - "2": 1.2233721350802031 - }, - { - "0": 7.4597227200976945, - "1": 7.4597227200976945, - "2": 7.4597227200976945 - }, - { - "0": 19.52108194247099, - "1": 19.52108194247099, - "2": 19.52108194247099 - }, - { - "0": 38.26712961751942, - "1": 38.26712961751942, - "2": 38.26712961751942 - }, - { - "0": 64.06724071350644, - "1": 64.06724071350644, - "2": 64.06724071350644 - }, - { - "0": 96.01646668517033, - "1": 96.01646668517033, - "2": 96.01646668517033 - }, - { - "0": 131.27001370165854, - "1": 131.27001370165854, - "2": 131.27001370165854 - }, - { - "0": 165.64341166682357, - "1": 165.64341166682357, - "2": 165.64341166682357 - }, - { - "0": 195.5173310851272, - "1": 195.5173310851272, - "2": 195.5173310851272 - }, - { - "0": 219.10911277756506, - "1": 219.10911277756506, - "2": 219.10911277756506 - }, - { - "0": 236.22093028419474, - "1": 236.22093028419474, - "2": 236.22093028419474 - }, - { - "0": 247.44163058291295, - "1": 247.44163058291295, - "2": 247.44163058291295 - }, - { - "0": 253.58414932213748, - "1": 253.58414932213748, - "2": 253.58414932213748 - }, - { - "0": 251.32784185693174, - "1": 251.32784185693174, - "2": 251.32784185693174 - }, - { - "0": 226.9837304288616, - "1": 226.9837304288616, - "2": 226.9837304288616 - }, - { - "0": 175.59642849517593, - "1": 175.59642849517593, - "2": 175.59642849517593 - }, - { - "0": 106.17065515408774, - "1": 106.17065515408774, - "2": 106.17065515408774 - }, - { - "0": 46.86160406137702, - "1": 46.86160406137702, - "2": 46.86160406137702 - }, - { - "0": 12.482037224632023, - "1": 12.482037224632023, - "2": 12.482037224632023 - } - ], - "data": [ - [ - 0, - 0, - 0 - ], - [ - 255, - 255, - 255 - ] - ], - "loop": true, - "easing": "easeInOutQuad", - "duration": 1546.3087248322147, - "direction": "normal", - "useBpm": true, - "bpmDivision": 64, - "value": { - "0": 12.482037224632023, - "1": 12.482037224632023, - "2": 12.482037224632023 - } - } - }, - "data": { - "soundType": false, - "intensity": 1, - "analysed": 0, - "baseSize": 1, - "size": 2, - "color": [ - 255, - 0, - 0, - 1 - ], - "speed": 1, - "balls": [ - { - "radius": 6, - "speed": 0, - "position": { - "x": 1824.7749999999912, - "y": 244.97499999999962 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 6, - "speed": 0, - "position": { - "x": 554.2750000000091, - "y": 797.9749999999996 - }, - "direction": { - "x": true, - "y": false - } - }, - { - "radius": 6, - "speed": 0, - "position": { - "x": 1612.775000000001, - "y": 118.07499999999999 - }, - "direction": { - "x": false, - "y": true - } - }, - { - "radius": 6, - "speed": 0, - "position": { - "x": 1383.8749999999952, - "y": 474.97499999999957 - }, - "direction": { - "x": true, - "y": false - } - }, - { - "radius": 6, - "speed": 0, - "position": { - "x": 1305.4749999999963, - "y": 121.07499999999996 - }, - "direction": { - "x": true, - "y": true - } - }, - { - "radius": 6, - "speed": 0, - "position": { - "x": 1516.775000000001, - "y": 13.975000000000025 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 6, - "speed": 0, - "position": { - "x": 863.7749999999997, - "y": 907.9749999999997 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 6, - "speed": 0, - "position": { - "x": 125.77499999999989, - "y": 114.97499999999997 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 6, - "speed": 0, - "position": { - "x": 958.7749999999997, - "y": 33.97500000000007 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 6, - "speed": 0, - "position": { - "x": 466.77499999999975, - "y": 567.9749999999996 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 6, - "speed": 0, - "position": { - "x": 1798.7749999999917, - "y": 869.9749999999995 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 6, - "speed": 0, - "position": { - "x": 6.72499999999982, - "y": 27.97499999999998 - }, - "direction": { - "x": true, - "y": false - } - }, - { - "radius": 6, - "speed": 0, - "position": { - "x": 598.7749999999996, - "y": 575.5250000000008 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 6, - "speed": 0, - "position": { - "x": 1055.775000000001, - "y": 937.9750000000001 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 6, - "speed": 0, - "position": { - "x": 1495.024999999994, - "y": 778.9749999999995 - }, - "direction": { - "x": true, - "y": false - } - }, - { - "radius": 6, - "speed": 0, - "position": { - "x": 1456.3249999999944, - "y": 245.97499999999962 - }, - "direction": { - "x": true, - "y": false - } - }, - { - "radius": 6, - "speed": 0, - "position": { - "x": 1527.775000000001, - "y": 298.97499999999945 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 6, - "speed": 0, - "position": { - "x": 1660.775000000001, - "y": 108.17499999999993 - }, - "direction": { - "x": false, - "y": true - } - }, - { - "radius": 6, - "speed": 0, - "position": { - "x": 1580.775000000001, - "y": 378.97499999999945 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 6, - "speed": 0, - "position": { - "x": 488.77499999999975, - "y": 283.97499999999957 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 6, - "speed": 0, - "position": { - "x": 770.7749999999996, - "y": 509.97499999999945 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 6, - "speed": 0, - "position": { - "x": 569.1750000000089, - "y": 192.97499999999985 - }, - "direction": { - "x": true, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 646, - "y": 591 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1123, - "y": 894 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 77, - "y": 87 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 467, - "y": 526 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1216, - "y": 1070 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 424, - "y": 923 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1081, - "y": 81 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1478, - "y": 356 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 45, - "y": 1049 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1516, - "y": 580 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1527, - "y": 854 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1529, - "y": 518 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 354, - "y": 214 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 754, - "y": 492 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 864, - "y": 213 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1131, - "y": 541 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1071, - "y": 353 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1486, - "y": 82 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 664, - "y": 542 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 904, - "y": 50 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 160, - "y": 146 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1459, - "y": 666 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1580, - "y": 915 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 370, - "y": 429 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1236, - "y": 29 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1066, - "y": 1 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 463, - "y": 753 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 291, - "y": 884 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 712, - "y": 108 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 227, - "y": 1044 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1887, - "y": 973 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 81, - "y": 578 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1910, - "y": 258 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 464, - "y": 286 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 355, - "y": 269 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1122, - "y": 341 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1076, - "y": 586 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 875, - "y": 492 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 478, - "y": 711 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 324, - "y": 361 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1645, - "y": 630 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1796, - "y": 768 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1186, - "y": 622 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 622, - "y": 91 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 230, - "y": 360 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1317, - "y": 456 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1519, - "y": 252 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1107, - "y": 877 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1741, - "y": 294 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 362, - "y": 225 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1301, - "y": 460 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1128, - "y": 981 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 561, - "y": 975 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 846, - "y": 466 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1316, - "y": 1025 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 681, - "y": 780 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1301, - "y": 230 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 445, - "y": 39 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 516, - "y": 980 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1080, - "y": 592 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1487, - "y": 584 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 822, - "y": 591 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1656, - "y": 63 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 153, - "y": 110 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 206, - "y": 1035 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 457, - "y": 642 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1504, - "y": 308 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1613, - "y": 703 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 922, - "y": 295 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1151, - "y": 134 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 454, - "y": 156 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1580, - "y": 766 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1184, - "y": 945 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 15, - "y": 977 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 203, - "y": 48 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1850, - "y": 517 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1161, - "y": 252 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1252, - "y": 168 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1290, - "y": 534 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1867, - "y": 594 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 348, - "y": 115 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 723, - "y": 414 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 911, - "y": 793 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1561, - "y": 534 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 604, - "y": 1078 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 355, - "y": 696 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 671, - "y": 51 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 866, - "y": 631 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 373, - "y": 556 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1289, - "y": 956 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 964, - "y": 938 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 890, - "y": 567 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1703, - "y": 688 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1055, - "y": 996 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1318, - "y": 651 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 172, - "y": 183 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 5, - "y": 328 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1624, - "y": 979 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1509, - "y": 980 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 204, - "y": 666 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1103, - "y": 846 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1799, - "y": 1010 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1230, - "y": 962 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1880, - "y": 287 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 337, - "y": 92 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 434, - "y": 631 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 513, - "y": 491 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1670, - "y": 1002 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 948, - "y": 574 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1280, - "y": 31 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1369, - "y": 239 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 158, - "y": 75 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 744, - "y": 973 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 761, - "y": 776 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1533, - "y": 582 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1169, - "y": 685 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 449, - "y": 787 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 275, - "y": 77 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 890, - "y": 894 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1620, - "y": 303 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 112, - "y": 894 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1829, - "y": 38 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1627, - "y": 607 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 993, - "y": 112 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1435, - "y": 1056 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 590, - "y": 1032 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1835, - "y": 124 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 112, - "y": 534 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 217, - "y": 22 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1875, - "y": 428 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1102, - "y": 1035 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 980, - "y": 951 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 719, - "y": 7 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1101, - "y": 815 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 930, - "y": 1009 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1378, - "y": 410 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 351, - "y": 9 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1603, - "y": 1002 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1758, - "y": 723 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1016, - "y": 670 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1447, - "y": 653 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 626, - "y": 640 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1139, - "y": 421 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 393, - "y": 714 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1719, - "y": 366 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1558, - "y": 792 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 209, - "y": 763 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 449, - "y": 697 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1673, - "y": 927 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 459, - "y": 534 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1045, - "y": 139 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1070, - "y": 890 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 222, - "y": 327 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1420, - "y": 179 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1657, - "y": 291 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 445, - "y": 1002 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 430, - "y": 312 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1494, - "y": 364 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 903, - "y": 529 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1810, - "y": 467 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1517, - "y": 375 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 769, - "y": 836 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 723, - "y": 875 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1639, - "y": 797 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1221, - "y": 523 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1496, - "y": 953 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 185, - "y": 459 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 396, - "y": 491 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 412, - "y": 617 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 927, - "y": 189 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1468, - "y": 484 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1556, - "y": 464 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1881, - "y": 1026 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 50, - "y": 537 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 126, - "y": 756 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1187, - "y": 658 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 520, - "y": 389 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1690, - "y": 495 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 111, - "y": 589 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 646, - "y": 847 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 261, - "y": 990 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 870, - "y": 351 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1578, - "y": 745 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 355, - "y": 532 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1372, - "y": 417 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1132, - "y": 1040 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1428, - "y": 428 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 552, - "y": 865 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1199, - "y": 254 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1122, - "y": 904 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 722, - "y": 302 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1724, - "y": 261 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 789, - "y": 600 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 604, - "y": 204 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1551, - "y": 297 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1034, - "y": 402 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1299, - "y": 973 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 121, - "y": 599 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1669, - "y": 258 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 255, - "y": 312 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 139, - "y": 25 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1042, - "y": 795 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1522, - "y": 644 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1690, - "y": 283 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 252, - "y": 912 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1802, - "y": 29 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 172, - "y": 759 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1168, - "y": 601 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1909, - "y": 281 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1806, - "y": 902 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 53, - "y": 44 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 878, - "y": 975 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 213, - "y": 938 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 31, - "y": 911 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 877, - "y": 1024 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1206, - "y": 333 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 533, - "y": 247 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1207, - "y": 349 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1247, - "y": 485 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1543, - "y": 752 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 467, - "y": 813 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1382, - "y": 748 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1303, - "y": 136 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 40, - "y": 166 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 72, - "y": 178 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 9, - "y": 581 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 945, - "y": 778 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 291, - "y": 25 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 193, - "y": 814 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 421, - "y": 56 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 810, - "y": 574 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 100, - "y": 549 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 688, - "y": 498 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 459, - "y": 959 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 747, - "y": 499 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1709, - "y": 344 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 361, - "y": 188 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 742, - "y": 746 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1490, - "y": 410 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1117, - "y": 918 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 451, - "y": 52 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1700, - "y": 797 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 625, - "y": 824 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 761, - "y": 178 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 456, - "y": 891 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 218, - "y": 712 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 440, - "y": 615 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1328, - "y": 315 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 590, - "y": 614 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 949, - "y": 1027 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 79, - "y": 586 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1589, - "y": 804 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 590, - "y": 470 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1740, - "y": 273 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1402, - "y": 847 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 78, - "y": 69 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1439, - "y": 1039 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1147, - "y": 442 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1130, - "y": 416 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1860, - "y": 305 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1403, - "y": 42 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 950, - "y": 322 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1341, - "y": 67 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1810, - "y": 742 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 783, - "y": 913 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1249, - "y": 983 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1453, - "y": 204 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1540, - "y": 867 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1870, - "y": 835 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1841, - "y": 340 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1409, - "y": 453 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 906, - "y": 888 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1101, - "y": 471 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 1708, - "y": 718 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 470, - "y": 554 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 411, - "y": 1042 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 966, - "y": 534 - }, - "direction": { - "x": false, - "y": false - } - }, - { - "radius": 0, - "speed": 0, - "position": { - "x": 769, - "y": 357 - }, - "direction": { - "x": false, - "y": false - } - } - ] - } - }, - "63070d96-3c8f-4af6-90b8-8397986aa128": { - "meta": { - "name": "RGB Halftone-lookaround", - "author": "by zoidberg", - "type": "isf", - "isfVersion": 2, - "previewWithOutput": true, - "alpha": 1, - "enabled": false, - "compositeOperation": "normal", - "alphaInputId": "a4267257-b60c-46ba-85fd-6801a0de5ac7", - "enabledInputId": "9bb85105-3b17-422d-aec2-044556ca3162", - "compositeOperationInputId": "c0f8e596-bbc8-4bb2-8c4c-313ecef917ed" - }, - "$id": "63070d96-3c8f-4af6-90b8-8397986aa128", - "$moduleName": "RGB Halftone-lookaround", - "$props": { - "inputImage": { - "type": "texture", - "label": "inputImage", - "id": "9e060f4c-dc02-4480-8c18-48cfb5ebce7f" - }, - "gridSize": { - "type": "float", - "label": "gridSize", - "default": 45, - "min": 1, - "max": 256, - "step": 0.01, - "id": "766f609e-86e3-4b18-8faf-0982abb43903" - }, - "smoothing": { - "type": "float", - "label": "smoothing", - "default": 0.15, - "min": 0, - "max": 1, - "step": 0.01, - "id": "23de3a85-0973-47be-bac1-aef4de667771" - } - }, - "props": { - "inputImage": { - "type": "inherit", - "options": {}, - "location": "", - "id": "", - "value": false - }, - "gridSize": 12.575, - "smoothing": 0.325 - }, - "data": {} - }, - "d9ee2124-0e6a-4640-8a16-ce08fc53c078": { - "meta": { - "name": "Sine Warp Tile", - "author": "by VIDVOX", - "type": "isf", - "isfVersion": 2, - "previewWithOutput": true, - "alpha": 1, - "enabled": true, - "compositeOperation": "normal", - "alphaInputId": "77da0e44-7d2a-4313-ac0b-36f465e95619", - "enabledInputId": "b4157e46-00fe-47cf-944c-1befd3c6fd70", - "compositeOperationInputId": "d04b866b-261b-4495-9304-f7c4db3183c9" - }, - "$id": "d9ee2124-0e6a-4640-8a16-ce08fc53c078", - "$moduleName": "Sine Warp Tile", - "$props": { - "inputImage": { - "type": "texture", - "label": "inputImage", - "id": "f71bfe74-a360-4069-804a-b96db9437aa1" - }, - "size": { - "type": "float", - "label": "size", - "default": 0.5, - "min": 0, - "max": 0.5, - "step": 0.01, - "id": "00b34d1b-30d7-4302-bfb7-35e293fb6fd0" - }, - "rotation": { - "type": "float", - "label": "rotation", - "default": 0, - "min": 0, - "max": 1, - "step": 0.01, - "id": "5d8d4dba-d891-44dd-9da8-efbb447172ab" - }, - "angle": { - "type": "float", - "label": "angle", - "default": 0, - "min": 0, - "max": 1, - "step": 0.01, - "id": "e50ca8af-c2fd-4140-874f-aa03f02c8e05" - }, - "shift": { - "type": "vec2", - "label": "shift", - "default": [ - 0.5, - 0.5 - ], - "id": "5565ff57-51bd-4969-9462-987fdf1f2dbe" - } - }, - "props": { - "inputImage": { - "type": "inherit", - "options": {}, - "location": "", - "id": "", - "value": false - }, - "size": 0.5, - "rotation": 0, - "angle": 0, - "shift": [ - 0.5, - 0.5 - ] - }, - "data": {} - }, - "396f9093-4899-4762-8a45-86ee91483baf": { - "meta": { - "name": "Edge Distort", - "author": "by VIDVOX", - "type": "isf", - "isfVersion": 2, - "previewWithOutput": true, - "alpha": 1, - "enabled": true, - "compositeOperation": "normal", - "alphaInputId": "9ba3d6ae-5bfc-450d-88bc-5dbbb88fd934", - "enabledInputId": "a17dda3e-4ae2-45b5-9858-77ec58e87954", - "compositeOperationInputId": "b2a207eb-64aa-4fa5-910e-9a98f39bd8c5" - }, - "$id": "396f9093-4899-4762-8a45-86ee91483baf", - "$moduleName": "Edge Distort", - "$props": { - "inputImage": { - "type": "texture", - "label": "inputImage", - "id": "b2554546-d42e-4e98-85ce-5ea7f10d97a9" - }, - "intensity": { - "type": "float", - "label": "intensity", - "default": 0.2, - "min": 0, - "max": 10, - "step": 0.01, - "id": "2aba53ab-cac6-4ea0-984a-18f456807cac" - }, - "invert_map": { - "type": "bool", - "label": "invert_map", - "default": false, - "id": "6c738617-47ed-4e28-af63-a99cb5eef363" - } - }, - "props": { - "inputImage": { - "type": "inherit", - "options": {}, - "location": "", - "id": "", - "value": false - }, - "intensity": 0.075, - "invert_map": false - }, - "data": {} - }, - "339beb6c-3c28-47f1-81a8-eaad0d287406": { - "meta": { - "name": "block-color", - "author": "2xAA", - "version": "1.0", - "type": "isf", - "isfVersion": 2, - "description": "Solid color block", - "alpha": 1, - "enabled": true, - "compositeOperation": "normal", - "alphaInputId": "fcbb2217-3bf4-41b9-9671-26afc03e6f86", - "enabledInputId": "021ac6d6-296d-44f8-a564-2634493109e9", - "compositeOperationInputId": "7548d90c-1fb1-465d-b404-ab7844e38e7d" - }, - "$id": "339beb6c-3c28-47f1-81a8-eaad0d287406", - "$moduleName": "block-color", - "$props": { - "r": { - "type": "float", - "label": "Red", - "default": 0, - "min": 0, - "max": 1, - "step": 0.01, - "id": "782594b1-fd58-426e-8666-69baebe30d7e" - }, - "g": { - "type": "float", - "label": "Green", - "default": 0, - "min": 0, - "max": 1, - "step": 0.01, - "id": "741ba30b-e393-47bf-a5bc-4b876c92df6c" - }, - "b": { - "type": "float", - "label": "Blue", - "default": 0, - "min": 0, - "max": 1, - "step": 0.01, - "id": "eef01aeb-7886-4486-9dac-72cbb172aed8" - }, - "a": { - "type": "float", - "label": "Alpha", - "default": 0, - "min": 0, - "max": 1, - "step": 0.01, - "id": "959a159a-4288-43ee-92d8-dfb639567163" - } - }, - "props": { - "r": 0, - "g": 0, - "b": 0, - "a": 0.05 - }, - "data": {} - }, - "f37d029c-cdbf-427d-91ac-5f5131c7fae4": { - "meta": { - "name": "scale", - "author": "2xAA", - "type": "isf", - "isfVersion": 2, - "description": "Scale", - "previewWithOutput": true, - "alpha": 1, - "enabled": false, - "compositeOperation": "normal", - "alphaInputId": "a753844d-d2ff-4f70-aa55-4ed8d6cb2121", - "enabledInputId": "16df58ab-864a-4b09-9bc6-8c9a4e42d4bd", - "compositeOperationInputId": "3bba2a82-9bf4-4171-8431-5c84cbde7c38" - }, - "$id": "f37d029c-cdbf-427d-91ac-5f5131c7fae4", - "$moduleName": "scale", - "$props": { - "inputImage": { - "type": "texture", - "label": "inputImage", - "id": "365b7efd-f346-41a6-aad4-6044e429d8af" - }, - "scale": { - "type": "float", - "label": "scale", - "default": 0, - "min": -2, - "max": 2, - "step": 0.01, - "id": "fd90e0d6-41e6-4a65-90ae-f05e3585f6a6" - } - }, - "props": { - "inputImage": { - "type": "inherit", - "options": {}, - "location": "", - "id": "", - "value": false - }, - "scale": 0.02157414634665019 - }, - "data": {} - }, - "b2b2be9e-5bac-4a74-83da-0b27a970cffe": { - "meta": { - "name": "Chromatic Abberation", - "author": "2xAA", - "version": "1.0.0", - "previewWithOutput": true, - "meyda": [], - "type": "shader", - "alpha": 1, - "enabled": false, - "compositeOperation": "normal", - "alphaInputId": "d99d8e26-497a-4bed-a5ca-4b0fadb08b16", - "enabledInputId": "5716fafe-2110-4f6b-835f-e4998529495c", - "compositeOperationInputId": "efc43509-105e-45f8-bb96-32f6fed2e473" - }, - "$id": "b2b2be9e-5bac-4a74-83da-0b27a970cffe", - "$moduleName": "Chromatic Abberation", - "$props": { - "rOffset": { - "type": "float", - "label": "Red Offset", - "min": 1, - "max": 2, - "step": 0.001, - "default": 1, - "id": "3bbd6199-77ff-44f3-bfd3-a8841f4ffa29" - }, - "gOffset": { - "type": "float", - "label": "Green Offset", - "min": 1, - "max": 2, - "step": 0.001, - "default": 1.015, - "id": "e3b0ae44-eb82-455d-a3dc-b58a1e36bea5" - }, - "bOffset": { - "type": "float", - "label": "Blue Offset", - "min": 1, - "max": 2, - "step": 0.001, - "default": 1.03, - "id": "5f88ecbf-161f-4346-9a08-9b45eb0bd753" - } - }, - "props": { - "rOffset": 1, - "gOffset": 1.015, - "bOffset": 1.03 - }, - "data": {} - }, - "df151ec6-2654-4ba1-b348-ada63583923f": { - "meta": { - "name": "Hue-Saturation", - "author": "2xAA", - "type": "isf", - "isfVersion": 2, - "description": "Hue/Saturation adjustment", - "previewWithOutput": true, - "alpha": 1, - "enabled": false, - "compositeOperation": "normal", - "alphaInputId": "ec80304b-03f0-47a0-a2d8-6b416fb03e3f", - "enabledInputId": "cbf0f84f-74be-4aa3-b6f7-1ee023f1ae71", - "compositeOperationInputId": "cb7c4c6b-e55b-4d5a-8601-074c830767d9" - }, - "$id": "df151ec6-2654-4ba1-b348-ada63583923f", - "$moduleName": "Hue-Saturation", - "$props": { - "inputImage": { - "type": "texture", - "label": "inputImage", - "id": "b4091ed5-09db-4ab6-ada4-8383535a71a4" - }, - "hue": { - "type": "float", - "label": "Hue", - "default": 0, - "min": -1, - "max": 1, - "step": 0.01, - "id": "99f2b02d-14ef-426a-8b7d-3b5326db705a" - }, - "saturation": { - "type": "float", - "label": "Saturation", - "default": 0, - "min": -1, - "max": 1, - "step": 0.01, - "id": "f17ed110-720b-48ea-b055-4f774bd682c8" - } - }, - "props": { - "inputImage": { - "type": "inherit", - "options": {}, - "location": "", - "id": "", - "value": false - }, - "hue": 0.1, - "saturation": 0 - }, - "data": {} - } - }, - "tweens": [ - { - "id": "bad555dd-f75b-4256-bb2d-5d430a5ae1ed", - "frames": [ - { - "0": 0, - "1": 0, - "2": 0 - }, - { - "0": 0, - "1": 0, - "2": 0 - }, - { - "0": 0, - "1": 0, - "2": 0 - }, - { - "0": 0, - "1": 0, - "2": 0 - }, - { - "0": 0, - "1": 0, - "2": 0 - }, - { - "0": 0, - "1": 0, - "2": 0 - }, - { - "0": 0, - "1": 0, - "2": 0 - }, - { - "0": 1.2233721350802031, - "1": 1.2233721350802031, - "2": 1.2233721350802031 - }, - { - "0": 7.4597227200976945, - "1": 7.4597227200976945, - "2": 7.4597227200976945 - }, - { - "0": 19.52108194247099, - "1": 19.52108194247099, - "2": 19.52108194247099 - }, - { - "0": 38.26712961751942, - "1": 38.26712961751942, - "2": 38.26712961751942 - }, - { - "0": 64.06724071350644, - "1": 64.06724071350644, - "2": 64.06724071350644 - }, - { - "0": 96.01646668517033, - "1": 96.01646668517033, - "2": 96.01646668517033 - }, - { - "0": 131.27001370165854, - "1": 131.27001370165854, - "2": 131.27001370165854 - }, - { - "0": 165.64341166682357, - "1": 165.64341166682357, - "2": 165.64341166682357 - }, - { - "0": 195.5173310851272, - "1": 195.5173310851272, - "2": 195.5173310851272 - }, - { - "0": 219.10911277756506, - "1": 219.10911277756506, - "2": 219.10911277756506 - }, - { - "0": 236.22093028419474, - "1": 236.22093028419474, - "2": 236.22093028419474 - }, - { - "0": 247.44163058291295, - "1": 247.44163058291295, - "2": 247.44163058291295 - }, - { - "0": 253.58414932213748, - "1": 253.58414932213748, - "2": 253.58414932213748 - }, - { - "0": 251.32784185693174, - "1": 251.32784185693174, - "2": 251.32784185693174 - }, - { - "0": 226.9837304288616, - "1": 226.9837304288616, - "2": 226.9837304288616 - }, - { - "0": 175.59642849517593, - "1": 175.59642849517593, - "2": 175.59642849517593 - }, - { - "0": 106.17065515408774, - "1": 106.17065515408774, - "2": 106.17065515408774 - }, - { - "0": 46.86160406137702, - "1": 46.86160406137702, - "2": 46.86160406137702 - }, - { - "0": 12.482037224632023, - "1": 12.482037224632023, - "2": 12.482037224632023 - } - ], - "data": [ - [ - 0, - 0, - 0 - ], - [ - 255, - 255, - 255 - ] - ], - "loop": true, - "easing": "easeInOutQuad", - "duration": 1546.3087248322147, - "direction": "normal", - "useBpm": true, - "bpmDivision": 64, - "value": { - "0": 0, - "1": 0, - "2": 0 - } - }, - { - "id": "908050aa-7f61-4540-b8a2-80264faac166", - "frames": [ - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0.11538461538461542 - }, - { - "0": 0.2692307692307693 - }, - { - "0": 0.42307692307692313 - }, - { - "0": 0.5769230769230769 - }, - { - "0": 0.7307692307692308 - }, - { - "0": 0.8846153846153846 - }, - { - "0": 0.9230769230769227 - }, - { - "0": 0.6153846153846152 - }, - { - "0": 0.30769230769230727 - } - ], - "data": [ - [ - 0 - ], - [ - 1 - ] - ], - "loop": true, - "easing": "linear", - "duration": 773.1543624161073, - "direction": "normal", - "useBpm": true, - "bpmDivision": 32, - "value": { - "0": 0 - } - }, - { - "id": "7d5fb574-0a61-4b7e-8735-b4212219d954", - "frames": [ - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0.038461538461538436 - }, - { - "0": 0.11538461538461542 - }, - { - "0": 0.1923076923076923 - }, - { - "0": 0.2692307692307693 - }, - { - "0": 0.34615384615384615 - }, - { - "0": 0.42307692307692313 - }, - { - "0": 0.5 - }, - { - "0": 0.5769230769230769 - }, - { - "0": 0.6538461538461537 - }, - { - "0": 0.7307692307692308 - }, - { - "0": 0.8076923076923077 - }, - { - "0": 0.8846153846153846 - }, - { - "0": 0.9615384615384615 - }, - { - "0": 0.9230769230769227 - }, - { - "0": 0.7692307692307689 - }, - { - "0": 0.6153846153846152 - }, - { - "0": 0.46153846153846145 - }, - { - "0": 0.30769230769230727 - }, - { - "0": 0.15384615384615352 - } - ], - "data": [ - [ - 0 - ], - [ - 1 - ] - ], - "loop": true, - "easing": "linear", - "duration": 1546.3087248322147, - "direction": "normal", - "useBpm": true, - "bpmDivision": 64, - "value": { - "0": 0 - } - }, - { - "id": "5c52007f-53bc-4568-a373-0017d2b6f54d", - "frames": [ - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0.038461538461538436 - }, - { - "0": 0.07692307692307687 - }, - { - "0": 0.11538461538461542 - }, - { - "0": 0.15384615384615385 - }, - { - "0": 0.1923076923076923 - }, - { - "0": 0.23076923076923073 - }, - { - "0": 0.2692307692307693 - }, - { - "0": 0.3076923076923077 - }, - { - "0": 0.34615384615384615 - }, - { - "0": 0.3846153846153846 - }, - { - "0": 0.42307692307692313 - }, - { - "0": 0.46153846153846156 - }, - { - "0": 0.5 - }, - { - "0": 0.5384615384615387 - }, - { - "0": 0.5769230769230769 - }, - { - "0": 0.6153846153846155 - }, - { - "0": 0.6538461538461537 - }, - { - "0": 0.6923076923076922 - }, - { - "0": 0.7307692307692308 - }, - { - "0": 0.769230769230769 - }, - { - "0": 0.8076923076923077 - }, - { - "0": 0.8461538461538464 - }, - { - "0": 0.8846153846153846 - }, - { - "0": 0.9230769230769232 - }, - { - "0": 0.9615384615384615 - }, - { - "0": 1 - }, - { - "0": 0.9230769230769227 - }, - { - "0": 0.8461538461538463 - }, - { - "0": 0.7692307692307689 - }, - { - "0": 0.6923076923076925 - }, - { - "0": 0.6153846153846152 - }, - { - "0": 0.5384615384615379 - }, - { - "0": 0.46153846153846145 - }, - { - "0": 0.38461538461538414 - }, - { - "0": 0.30769230769230727 - }, - { - "0": 0.23076923076923084 - }, - { - "0": 0.15384615384615352 - }, - { - "0": 0.0769230769230771 - } - ], - "data": [ - [ - 0 - ], - [ - 1 - ] - ], - "loop": true, - "easing": "linear", - "duration": 3092.6174496644294, - "direction": "normal", - "useBpm": true, - "bpmDivision": 128, - "value": { - "0": 0 - } - }, - { - "id": "f505793b-bd5d-4fda-86cb-e4f517a0f9bc", - "frames": [ - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0.038461538461538436 - }, - { - "0": 0.07692307692307687 - }, - { - "0": 0.11538461538461542 - }, - { - "0": 0.15384615384615385 - }, - { - "0": 0.1923076923076923 - }, - { - "0": 0.23076923076923073 - }, - { - "0": 0.2692307692307693 - }, - { - "0": 0.3076923076923077 - }, - { - "0": 0.34615384615384615 - }, - { - "0": 0.3846153846153846 - }, - { - "0": 0.42307692307692313 - }, - { - "0": 0.46153846153846156 - }, - { - "0": 0.5 - }, - { - "0": 0.5384615384615387 - }, - { - "0": 0.5769230769230769 - }, - { - "0": 0.6153846153846155 - }, - { - "0": 0.6538461538461537 - }, - { - "0": 0.6923076923076922 - }, - { - "0": 0.7307692307692308 - }, - { - "0": 0.769230769230769 - }, - { - "0": 0.8076923076923077 - }, - { - "0": 0.8461538461538464 - }, - { - "0": 0.8846153846153846 - }, - { - "0": 0.9230769230769232 - }, - { - "0": 0.9615384615384615 - }, - { - "0": 1 - }, - { - "0": 0.9230769230769227 - }, - { - "0": 0.8461538461538463 - }, - { - "0": 0.7692307692307689 - }, - { - "0": 0.6923076923076925 - }, - { - "0": 0.6153846153846152 - }, - { - "0": 0.5384615384615379 - }, - { - "0": 0.46153846153846145 - }, - { - "0": 0.38461538461538414 - }, - { - "0": 0.30769230769230727 - }, - { - "0": 0.23076923076923084 - }, - { - "0": 0.15384615384615352 - }, - { - "0": 0.0769230769230771 - } - ], - "data": [ - [ - 0 - ], - [ - 1 - ] - ], - "loop": true, - "easing": "linear", - "duration": 3092.6174496644294, - "direction": "normal", - "useBpm": true, - "bpmDivision": 128, - "value": { - "0": 0 - } - }, - { - "id": "c439372f-9868-41fa-82fa-9c761dd379c4", - "frames": [ - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0.038461538461538436 - }, - { - "0": 0.07692307692307687 - }, - { - "0": 0.11538461538461542 - }, - { - "0": 0.15384615384615385 - }, - { - "0": 0.1923076923076923 - }, - { - "0": 0.23076923076923073 - }, - { - "0": 0.2692307692307693 - }, - { - "0": 0.3076923076923077 - }, - { - "0": 0.34615384615384615 - }, - { - "0": 0.3846153846153846 - }, - { - "0": 0.42307692307692313 - }, - { - "0": 0.46153846153846156 - }, - { - "0": 0.5 - }, - { - "0": 0.5384615384615387 - }, - { - "0": 0.5769230769230769 - }, - { - "0": 0.6153846153846155 - }, - { - "0": 0.6538461538461537 - }, - { - "0": 0.6923076923076922 - }, - { - "0": 0.7307692307692308 - }, - { - "0": 0.769230769230769 - }, - { - "0": 0.8076923076923077 - }, - { - "0": 0.8461538461538464 - }, - { - "0": 0.8846153846153846 - }, - { - "0": 0.9230769230769232 - }, - { - "0": 0.9615384615384615 - }, - { - "0": 1 - }, - { - "0": 0.9230769230769227 - }, - { - "0": 0.8461538461538463 - }, - { - "0": 0.7692307692307689 - }, - { - "0": 0.6923076923076925 - }, - { - "0": 0.6153846153846152 - }, - { - "0": 0.5384615384615379 - }, - { - "0": 0.46153846153846145 - }, - { - "0": 0.38461538461538414 - }, - { - "0": 0.30769230769230727 - }, - { - "0": 0.23076923076923084 - }, - { - "0": 0.15384615384615352 - }, - { - "0": 0.0769230769230771 - } - ], - "data": [ - [ - 0 - ], - [ - 1 - ] - ], - "loop": true, - "easing": "linear", - "duration": 3092.6174496644294, - "direction": "normal", - "useBpm": true, - "bpmDivision": 128, - "value": { - "0": 0 - } - }, - { - "id": "1635fe76-249b-4568-b7aa-1fd33d73c6f0", - "frames": [ - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0.004060405567392934 - }, - { - "0": 0.008613033536269205 - }, - { - "0": 0.013767241872306253 - }, - { - "0": 0.019653860595333812 - }, - { - "0": 0.02642975594346092 - }, - { - "0": 0.03428333233456127 - }, - { - "0": 0.04344107264861464 - }, - { - "0": 0.054175135938293685 - }, - { - "0": 0.06681185351164191 - }, - { - "0": 0.08174062195594979 - }, - { - "0": 0.09942209184776345 - }, - { - "0": 0.12039359158679447 - }, - { - "0": 0.14526836147514013 - }, - { - "0": 0.17472357362555815 - }, - { - "0": 0.20947094197806496 - }, - { - "0": 0.25020442412487703 - }, - { - "0": 0.29752412585050597 - }, - { - "0": 0.35184525555391427 - }, - { - "0": 0.4133134094177401 - }, - { - "0": 0.48175485120453215 - }, - { - "0": 0.5566838657357992 - }, - { - "0": 0.6373682633248049 - }, - { - "0": 0.7229309883255829 - }, - { - "0": 0.8124556366811024 - }, - { - "0": 0.9050703999341164 - }, - { - "0": 1 - }, - { - "0": 0.9913869664637307 - }, - { - "0": 0.9803461394046662 - }, - { - "0": 0.9657166676654386 - }, - { - "0": 0.9458248640617064 - }, - { - "0": 0.9182593780440501 - }, - { - "0": 0.8796064084132053 - }, - { - "0": 0.825276426374442 - }, - { - "0": 0.7497955758751227 - }, - { - "0": 0.648154744446085 - }, - { - "0": 0.5182451487954677 - }, - { - "0": 0.36263173667519477 - }, - { - "0": 0.18754436331889823 - } - ], - "data": [ - [ - 0 - ], - [ - 1 - ] - ], - "loop": true, - "easing": "easeInCubic", - "duration": 3092.6174496644294, - "direction": "normal", - "useBpm": true, - "bpmDivision": 128, - "value": { - "0": 0 - } - }, - { - "id": "4fd4ce29-b83d-4498-8ec2-98be21477d60", - "frames": [ - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0.0016088510506455413 - }, - { - "0": 0.006485966307721594 - }, - { - "0": 0.014705069702887224 - }, - { - "0": 0.026335953379493578 - }, - { - "0": 0.04144282887916085 - }, - { - "0": 0.06008230554009138 - }, - { - "0": 0.0823009256372223 - }, - { - "0": 0.10813217658968283 - }, - { - "0": 0.1375928923079747 - }, - { - "0": 0.17067894993650568 - }, - { - "0": 0.20736016712826813 - }, - { - "0": 0.2475743118609811 - }, - { - "0": 0.291220156252879 - }, - { - "0": 0.3381495439296927 - }, - { - "0": 0.3881585047676721 - }, - { - "0": 0.44097754983691356 - }, - { - "0": 0.4962614214111358 - }, - { - "0": 0.5535787636277427 - }, - { - "0": 0.6124024176620251 - }, - { - "0": 0.672101317503898 - }, - { - "0": 0.731935235738415 - }, - { - "0": 0.7910538454868802 - }, - { - "0": 0.848501642105044 - }, - { - "0": 0.9032301088753066 - }, - { - "0": 0.9541180283202502 - }, - { - "0": 1 - }, - { - "0": 0.9935140336922783 - }, - { - "0": 0.9736640466205064 - }, - { - "0": 0.9399176944599085 - }, - { - "0": 0.8918678234103173 - }, - { - "0": 0.8293210500634942 - }, - { - "0": 0.7524256881390183 - }, - { - "0": 0.6618504560703076 - }, - { - "0": 0.559022450163086 - }, - { - "0": 0.4464212363722564 - }, - { - "0": 0.32789868249610155 - }, - { - "0": 0.2089461545131196 - }, - { - "0": 0.09676989112469359 - } - ], - "data": [ - [ - 0 - ], - [ - 1 - ] - ], - "loop": true, - "easing": "easeInSine", - "duration": 3092.6174496644294, - "direction": "normal", - "useBpm": true, - "bpmDivision": 128, - "value": { - "0": 0 - } - }, - { - "id": "56d87cf3-f305-44b9-b544-5cc2dfc2ad12", - "frames": [ - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": -0.017395975650704193 - }, - { - "0": -0.033594956128009675 - }, - { - "0": -0.048443858595931366 - }, - { - "0": -0.06176534673274153 - }, - { - "0": -0.07335317380280823 - }, - { - "0": -0.08296652937813435 - }, - { - "0": -0.09032318786730584 - }, - { - "0": -0.09509124233731761 - }, - { - "0": -0.09687921993493424 - }, - { - "0": -0.09522444773595193 - }, - { - "0": -0.08957972879829602 - }, - { - "0": -0.07929879983695091 - }, - { - "0": -0.06362184182071284 - }, - { - "0": -0.04166375172752573 - }, - { - "0": -0.01241026155895846 - }, - { - "0": 0.025269493572578346 - }, - { - "0": 0.07258109138316782 - }, - { - "0": 0.13071770598690893 - }, - { - "0": 0.2007148097091646 - }, - { - "0": 0.2832500868912812 - }, - { - "0": 0.37842578137133503 - }, - { - "0": 0.48561002524494784 - }, - { - "0": 0.60342395660921 - }, - { - "0": 0.7299113271468767 - }, - { - "0": 0.8628369479266256 - }, - { - "0": 1 - }, - { - "0": 1.0335949561280098 - }, - { - "0": 1.0617653467327415 - }, - { - "0": 1.0829665293781345 - }, - { - "0": 1.0950912423373176 - }, - { - "0": 1.0952244477359518 - }, - { - "0": 1.0792987998369508 - }, - { - "0": 1.0416637517275258 - }, - { - "0": 0.9747305064274212 - }, - { - "0": 0.8692822940130901 - }, - { - "0": 0.7167499131087186 - }, - { - "0": 0.514389974755052 - }, - { - "0": 0.2700886728531242 - } - ], - "data": [ - [ - 0 - ], - [ - 1 - ] - ], - "loop": true, - "easing": "easeInBack", - "duration": 3092.6174496644294, - "direction": "normal", - "useBpm": true, - "bpmDivision": 128, - "value": { - "0": 0 - } - }, - { - "id": "877c18d5-df56-4007-bf9b-038f6043dbd6", - "frames": [ - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0.0011288800774393595 - }, - { - "0": 0.000945495392707918 - }, - { - "0": 0.00026191572423481176 - }, - { - "0": -0.00100593016177816 - }, - { - "0": -0.0027720555061805127 - }, - { - "0": -0.004694375816134563 - }, - { - "0": -0.006128562541409708 - }, - { - "0": -0.006167998008224793 - }, - { - "0": -0.003814799069509747 - }, - { - "0": 0.0016928830055196373 - }, - { - "0": 0.010415648734555551 - }, - { - "0": 0.021195138159392772 - }, - { - "0": 0.03125 - }, - { - "0": 0.03612416247805947 - }, - { - "0": 0.03025585256665339 - }, - { - "0": 0.008381303175513943 - }, - { - "0": -0.032189765176900934 - }, - { - "0": -0.08870577619777614 - }, - { - "0": -0.1502200261163062 - }, - { - "0": -0.19611400132511053 - }, - { - "0": -0.19737593626319352 - }, - { - "0": -0.12207357022431128 - }, - { - "0": 0.05417225617662829 - }, - { - "0": 0.3333007595057783 - }, - { - "0": 0.6782444211005676 - }, - { - "0": 1 - }, - { - "0": 0.9990545046072921 - }, - { - "0": 1.0010059301617782 - }, - { - "0": 1.0046943758161346 - }, - { - "0": 1.0061679980082248 - }, - { - "0": 0.9983071169944803 - }, - { - "0": 0.9788048618406071 - }, - { - "0": 0.9638758375219405 - }, - { - "0": 0.9916186968244863 - }, - { - "0": 1.088705776197777 - }, - { - "0": 1.1961140013251106 - }, - { - "0": 1.122073570224311 - }, - { - "0": 0.6666992404942246 - } - ], - "data": [ - [ - 0 - ], - [ - 1 - ] - ], - "loop": true, - "easing": "easeInElastic", - "duration": 3092.6174496644294, - "direction": "normal", - "useBpm": true, - "bpmDivision": 128, - "value": { - "0": 0 - } - }, - { - "id": "c460861e-fd02-4437-af77-0d15e9b42642", - "frames": [ - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0.07150591728821545 - }, - { - "0": 0.1438539390981076 - }, - { - "0": 0.21603327541541908 - }, - { - "0": 0.2870177114563829 - }, - { - "0": 0.35585486791030374 - }, - { - "0": 0.42174009521180483 - }, - { - "0": 0.48406049982449717 - }, - { - "0": 0.5424057492249303 - }, - { - "0": 0.5965520744423507 - }, - { - "0": 0.646430435360068 - }, - { - "0": 0.6920892991902776 - }, - { - "0": 0.7336593043351011 - }, - { - "0": 0.7713235622464706 - }, - { - "0": 0.8052947050220611 - }, - { - "0": 0.8357982541348716 - }, - { - "0": 0.8630612235335279 - }, - { - "0": 0.8873047366726313 - }, - { - "0": 0.9087395606978877 - }, - { - "0": 0.9275636743754601 - }, - { - "0": 0.9439612034167261 - }, - { - "0": 0.9581022421861408 - }, - { - "0": 0.9701432255586194 - }, - { - "0": 0.9802276219159423 - }, - { - "0": 0.9884867949373485 - }, - { - "0": 0.9950409353028736 - }, - { - "0": 1 - }, - { - "0": 0.8561460609018916 - }, - { - "0": 0.7129822885436173 - }, - { - "0": 0.5782599047881947 - }, - { - "0": 0.45759425077507 - }, - { - "0": 0.35356956463993194 - }, - { - "0": 0.26634069566489826 - }, - { - "0": 0.1947052949779391 - }, - { - "0": 0.1369387764664719 - }, - { - "0": 0.09126043930211203 - }, - { - "0": 0.05603879658327404 - }, - { - "0": 0.029856774441380685 - }, - { - "0": 0.011513205062651521 - } - ], - "data": [ - [ - 0 - ], - [ - 1 - ] - ], - "loop": true, - "easing": "easeOutQuad", - "duration": 3092.6174496644294, - "direction": "normal", - "useBpm": true, - "bpmDivision": 128, - "value": { - "0": 0 - } - }, - { - "id": "603f45f4-11fe-4b7a-a62e-affcb0932d63", - "frames": [ - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0.0007001071475688031 - }, - { - "0": 0.002951278030718783 - }, - { - "0": 0.007027631037000884 - }, - { - "0": 0.013288990049361803 - }, - { - "0": 0.022222307038608363 - }, - { - "0": 0.03451225829395583 - }, - { - "0": 0.05117024639760723 - }, - { - "0": 0.07379269814198705 - }, - { - "0": 0.10514760498172109 - }, - { - "0": 0.15077868621379578 - }, - { - "0": 0.2249826422387366 - }, - { - "0": 0.39155830853406365 - }, - { - "0": 0.6766070275282037 - }, - { - "0": 0.7882165217729405 - }, - { - "0": 0.8497247849603856 - }, - { - "0": 0.890726144359269 - }, - { - "0": 0.9202601864941642 - }, - { - "0": 0.9423486255515054 - }, - { - "0": 0.9591579826961739 - }, - { - "0": 0.9720002234325575 - }, - { - "0": 0.981735447018549 - }, - { - "0": 0.9889609032579791 - }, - { - "0": 0.9941098298386403 - }, - { - "0": 0.9975074581837488 - }, - { - "0": 0.999404788775965 - }, - { - "0": 1 - }, - { - "0": 0.9970487219692812 - }, - { - "0": 0.9867110099506382 - }, - { - "0": 0.965487741706044 - }, - { - "0": 0.926207301858013 - }, - { - "0": 0.8492213137862038 - }, - { - "0": 0.6084416914659319 - }, - { - "0": 0.21178347822705956 - }, - { - "0": 0.10927385564073044 - }, - { - "0": 0.05765137444849433 - }, - { - "0": 0.027999776567442458 - }, - { - "0": 0.01103909674202086 - }, - { - "0": 0.002492541816251359 - } - ], - "data": [ - [ - 0 - ], - [ - 1 - ] - ], - "loop": true, - "easing": "easeInOutQuint", - "duration": 3092.6174496644294, - "direction": "normal", - "useBpm": true, - "bpmDivision": 128, - "value": { - "0": 0 - } - }, - { - "id": "0e89f3d0-b882-4b7f-b3d8-a4bf7c37efb5", - "frames": [ - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0.00001068436959655999 - }, - { - "0": 0.0002737259259927396 - }, - { - "0": 0.0009096243366864224 - }, - { - "0": 0.0019483594472287447 - }, - { - "0": 0.0034239214713570943 - }, - { - "0": 0.005375082459857275 - }, - { - "0": 0.007846366110467065 - }, - { - "0": 0.010889281175635047 - }, - { - "0": 0.014563910442593685 - }, - { - "0": 0.018940987335161866 - }, - { - "0": 0.024104653668317946 - }, - { - "0": 0.030156188820348363 - }, - { - "0": 0.03721915717470846 - }, - { - "0": 0.04544668247175526 - }, - { - "0": 0.055032011854698956 - }, - { - "0": 0.06622435465563409 - }, - { - "0": 0.07935354618378022 - }, - { - "0": 0.09487024882483135 - }, - { - "0": 0.11341526651371425 - }, - { - "0": 0.13594782727502544 - }, - { - "0": 0.16400586762367483 - }, - { - "0": 0.20030381353370813 - }, - { - "0": 0.25036611739966325 - }, - { - "0": 0.3281946866038322 - }, - { - "0": 0.47248142780300334 - }, - { - "0": 0.6281702447651325 - }, - { - "0": 0.7135814014416376 - }, - { - "0": 0.7679244349964309 - }, - { - "0": 0.8072615373769766 - }, - { - "0": 0.8377539383850329 - }, - { - "0": 0.8623693009673776 - }, - { - "0": 0.8827677456632145 - }, - { - "0": 0.8999758501300389 - }, - { - "0": 0.9146752581846095 - }, - { - "0": 0.9273432234730115 - }, - { - "0": 0.9383278716957855 - }, - { - "0": 0.9478915515235141 - }, - { - "0": 0.9562372866317359 - }, - { - "0": 0.9635256886805703 - }, - { - "0": 0.9698861974635968 - }, - { - "0": 0.975424797829346 - }, - { - "0": 0.980229466668156 - }, - { - "0": 0.984374110746052 - }, - { - "0": 0.9879214734975618 - }, - { - "0": 0.9909253204436314 - }, - { - "0": 0.9934321091786525 - }, - { - "0": 0.9954822841341133 - }, - { - "0": 0.9971112935848555 - }, - { - "0": 0.9983503979314199 - }, - { - "0": 0.9992273189857535 - }, - { - "0": 0.9997667666327615 - }, - { - "0": 0.9999908698452366 - }, - { - "0": 0.9996033636423013 - }, - { - "0": 0.9977251287135063 - }, - { - "0": 0.9940577400269195 - }, - { - "0": 0.9882538472978357 - }, - { - "0": 0.9798454685110091 - }, - { - "0": 0.968178299975103 - }, - { - "0": 0.9522929068369324 - }, - { - "0": 0.9306900668769827 - }, - { - "0": 0.9008080741251125 - }, - { - "0": 0.8576346334279773 - }, - { - "0": 0.7887957936807457 - }, - { - "0": 0.644134334698891 - }, - { - "0": 0.34580711518536955 - }, - { - "0": 0.22116211897459492 - }, - { - "0": 0.15562112515456672 - }, - { - "0": 0.11266224714381878 - }, - { - "0": 0.0819826953331032 - }, - { - "0": 0.05915678146051284 - }, - { - "0": 0.04184700762702187 - }, - { - "0": 0.028655808224766433 - }, - { - "0": 0.018675117736034696 - }, - { - "0": 0.011278538706374186 - }, - { - "0": 0.006014002764283988 - }, - { - "0": 0.002543515649923833 - }, - { - "0": 0.0006070865186531549 - } - ], - "data": [ - [ - 0 - ], - [ - 1 - ] - ], - "loop": true, - "easing": "easeInOutQuint", - "duration": 6185.234899328859, - "direction": "normal", - "useBpm": true, - "bpmDivision": 256, - "value": { - "0": 0 - } - }, - { - "id": "a5fffc62-5eb0-49c2-9983-747967036693", - "frames": [ - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0.00001068436959655999 - }, - { - "0": 0.0002737259259927396 - }, - { - "0": 0.0009096243366864224 - }, - { - "0": 0.0019483594472287447 - }, - { - "0": 0.0034239214713570943 - }, - { - "0": 0.005375082459857275 - }, - { - "0": 0.007846366110467065 - }, - { - "0": 0.010889281175635047 - }, - { - "0": 0.014563910442593685 - }, - { - "0": 0.018940987335161866 - }, - { - "0": 0.024104653668317946 - }, - { - "0": 0.030156188820348363 - }, - { - "0": 0.03721915717470846 - }, - { - "0": 0.04544668247175526 - }, - { - "0": 0.055032011854698956 - }, - { - "0": 0.06622435465563409 - }, - { - "0": 0.07935354618378022 - }, - { - "0": 0.09487024882483135 - }, - { - "0": 0.11341526651371425 - }, - { - "0": 0.13594782727502544 - }, - { - "0": 0.16400586762367483 - }, - { - "0": 0.20030381353370813 - }, - { - "0": 0.25036611739966325 - }, - { - "0": 0.3281946866038322 - }, - { - "0": 0.47248142780300334 - }, - { - "0": 0.6281702447651325 - }, - { - "0": 0.7135814014416376 - }, - { - "0": 0.7679244349964309 - }, - { - "0": 0.8072615373769766 - }, - { - "0": 0.8377539383850329 - }, - { - "0": 0.8623693009673776 - }, - { - "0": 0.8827677456632145 - }, - { - "0": 0.8999758501300389 - }, - { - "0": 0.9146752581846095 - }, - { - "0": 0.9273432234730115 - }, - { - "0": 0.9383278716957855 - }, - { - "0": 0.9478915515235141 - }, - { - "0": 0.9562372866317359 - }, - { - "0": 0.9635256886805703 - }, - { - "0": 0.9698861974635968 - }, - { - "0": 0.975424797829346 - }, - { - "0": 0.980229466668156 - }, - { - "0": 0.984374110746052 - }, - { - "0": 0.9879214734975618 - }, - { - "0": 0.9909253204436314 - }, - { - "0": 0.9934321091786525 - }, - { - "0": 0.9954822841341133 - }, - { - "0": 0.9971112935848555 - }, - { - "0": 0.9983503979314199 - }, - { - "0": 0.9992273189857535 - }, - { - "0": 0.9997667666327615 - }, - { - "0": 0.9999908698452366 - }, - { - "0": 0.9996033636423013 - }, - { - "0": 0.9977251287135063 - }, - { - "0": 0.9940577400269195 - }, - { - "0": 0.9882538472978357 - }, - { - "0": 0.9798454685110091 - }, - { - "0": 0.968178299975103 - }, - { - "0": 0.9522929068369324 - }, - { - "0": 0.9306900668769827 - }, - { - "0": 0.9008080741251125 - }, - { - "0": 0.8576346334279773 - }, - { - "0": 0.7887957936807457 - }, - { - "0": 0.644134334698891 - }, - { - "0": 0.34580711518536955 - }, - { - "0": 0.22116211897459492 - }, - { - "0": 0.15562112515456672 - }, - { - "0": 0.11266224714381878 - }, - { - "0": 0.0819826953331032 - }, - { - "0": 0.05915678146051284 - }, - { - "0": 0.04184700762702187 - }, - { - "0": 0.028655808224766433 - }, - { - "0": 0.018675117736034696 - }, - { - "0": 0.011278538706374186 - }, - { - "0": 0.006014002764283988 - }, - { - "0": 0.002543515649923833 - }, - { - "0": 0.0006070865186531549 - } - ], - "data": [ - [ - 0 - ], - [ - 1 - ] - ], - "loop": true, - "easing": "easeInOutQuint", - "duration": 6185.234899328859, - "direction": "normal", - "useBpm": true, - "bpmDivision": 256, - "value": { - "0": 0 - } - }, - { - "id": "75d4ab6d-a140-42ca-a737-265da14cd775", - "frames": [ - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.20000213687391932 - }, - { - "0": 0.20005474518519856 - }, - { - "0": 0.2001819248673373 - }, - { - "0": 0.20038967188944576 - }, - { - "0": 0.20068478429427142 - }, - { - "0": 0.20107501649197146 - }, - { - "0": 0.20156927322209342 - }, - { - "0": 0.20217785623512702 - }, - { - "0": 0.20291278208851876 - }, - { - "0": 0.2037881974670324 - }, - { - "0": 0.2048209307336636 - }, - { - "0": 0.20603123776406967 - }, - { - "0": 0.20744383143494172 - }, - { - "0": 0.20908933649435107 - }, - { - "0": 0.21100640237093982 - }, - { - "0": 0.21324487093112682 - }, - { - "0": 0.21587070923675605 - }, - { - "0": 0.2189740497649663 - }, - { - "0": 0.22268305330274285 - }, - { - "0": 0.2271895654550051 - }, - { - "0": 0.23280117352473498 - }, - { - "0": 0.24006076270674165 - }, - { - "0": 0.25007322347993266 - }, - { - "0": 0.2656389373207665 - }, - { - "0": 0.2944962855606007 - }, - { - "0": 0.3256340489530265 - }, - { - "0": 0.34271628028832757 - }, - { - "0": 0.3535848869992862 - }, - { - "0": 0.36145230747539536 - }, - { - "0": 0.3675507876770066 - }, - { - "0": 0.37247386019347556 - }, - { - "0": 0.37655354913264294 - }, - { - "0": 0.3799951700260078 - }, - { - "0": 0.38293505163692193 - }, - { - "0": 0.3854686446946023 - }, - { - "0": 0.3876655743391571 - }, - { - "0": 0.38957831030470286 - }, - { - "0": 0.3912474573263472 - }, - { - "0": 0.3927051377361141 - }, - { - "0": 0.3939772394927194 - }, - { - "0": 0.3950849595658692 - }, - { - "0": 0.3960458933336312 - }, - { - "0": 0.39687482214921044 - }, - { - "0": 0.3975842946995124 - }, - { - "0": 0.3981850640887263 - }, - { - "0": 0.39868642183573055 - }, - { - "0": 0.3990964568268227 - }, - { - "0": 0.3994222587169711 - }, - { - "0": 0.399670079586284 - }, - { - "0": 0.3998454637971507 - }, - { - "0": 0.39995335332655235 - }, - { - "0": 0.39999817396904735 - }, - { - "0": 0.39992067272846027 - }, - { - "0": 0.3995450257427013 - }, - { - "0": 0.39881154800538393 - }, - { - "0": 0.3976507694595672 - }, - { - "0": 0.39596909370220185 - }, - { - "0": 0.3936356599950206 - }, - { - "0": 0.3904585813673865 - }, - { - "0": 0.38613801337539655 - }, - { - "0": 0.38016161482502253 - }, - { - "0": 0.3715269266855955 - }, - { - "0": 0.35775915873614916 - }, - { - "0": 0.32882686693977825 - }, - { - "0": 0.2691614230370739 - }, - { - "0": 0.244232423794919 - }, - { - "0": 0.23112422503091334 - }, - { - "0": 0.22253244942876377 - }, - { - "0": 0.21639653906662065 - }, - { - "0": 0.2118313562921026 - }, - { - "0": 0.2083694015254044 - }, - { - "0": 0.2057311616449533 - }, - { - "0": 0.20373502354720696 - }, - { - "0": 0.20225570774127485 - }, - { - "0": 0.2012028005528568 - }, - { - "0": 0.20050870312998478 - }, - { - "0": 0.20012141730373065 - } - ], - "data": [ - [ - 0.2 - ], - [ - 0.4 - ] - ], - "loop": true, - "easing": "easeInOutQuint", - "duration": 6185.234899328859, - "direction": "normal", - "useBpm": true, - "bpmDivision": 256, - "value": { - "0": 0.2 - } - }, - { - "id": "10567fbb-f08c-4a82-95a6-8f7d720a82d8", - "frames": [ - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.2 - }, - { - "0": 0.20011615542349528 - }, - { - "0": 0.20072437265995327 - }, - { - "0": 0.2015688270009705 - }, - { - "0": 0.20265827630384609 - }, - { - "0": 0.20400155853957383 - }, - { - "0": 0.2056075060314067 - }, - { - "0": 0.20748483619055408 - }, - { - "0": 0.2096420145327502 - }, - { - "0": 0.2120870855004104 - }, - { - "0": 0.21482746658083995 - }, - { - "0": 0.21786970153787782 - }, - { - "0": 0.22121916943850858 - }, - { - "0": 0.224879747770041 - }, - { - "0": 0.22885343054213128 - }, - { - "0": 0.2331399060750408 - }, - { - "0": 0.2377361043458538 - }, - { - "0": 0.24263573029589885 - }, - { - "0": 0.24782880712237798 - }, - { - "0": 0.25330126161906985 - }, - { - "0": 0.25903459094459874 - }, - { - "0": 0.26500565515003593 - }, - { - "0": 0.2711866404456297 - }, - { - "0": 0.2775452326598957 - }, - { - "0": 0.2840450274411759 - }, - { - "0": 0.29064618360254985 - }, - { - "0": 0.29730630056712687 - }, - { - "0": 0.30398147391976915 - }, - { - "0": 0.3106274595849176 - }, - { - "0": 0.3172008620349725 - }, - { - "0": 0.3236602585728562 - }, - { - "0": 0.3299671808917182 - }, - { - "0": 0.3360868946883196 - }, - { - "0": 0.34198894381676104 - }, - { - "0": 0.3476474522071563 - }, - { - "0": 0.3530412000201797 - }, - { - "0": 0.35815350732168627 - }, - { - "0": 0.362971967897749 - }, - { - "0": 0.3674880782668141 - }, - { - "0": 0.3716968040738522 - }, - { - "0": 0.37559611982644564 - }, - { - "0": 0.37918655017340797 - }, - { - "0": 0.3824707330367693 - }, - { - "0": 0.3854530177967316 - }, - { - "0": 0.38813910586069705 - }, - { - "0": 0.3905357364523849 - }, - { - "0": 0.3926504172531906 - }, - { - "0": 0.3944911974220811 - }, - { - "0": 0.3960664792810738 - }, - { - "0": 0.3973848643562459 - }, - { - "0": 0.39845502931488075 - }, - { - "0": 0.3992856274819516 - }, - { - "0": 0.39988521193594034 - }, - { - "0": 0.3990870010342187 - }, - { - "0": 0.3970300458346334 - }, - { - "0": 0.3939489397230442 - }, - { - "0": 0.38977400986644734 - }, - { - "0": 0.3844405059331449 - }, - { - "0": 0.377894965777417 - }, - { - "0": 0.3701042056855985 - }, - { - "0": 0.3610671121096282 - }, - { - "0": 0.3508286259584449 - }, - { - "0": 0.33949392351111907 - }, - { - "0": 0.32723900582719484 - }, - { - "0": 0.31431256602709856 - }, - { - "0": 0.3010245859524937 - }, - { - "0": 0.28772072516997926 - }, - { - "0": 0.2747472907214077 - }, - { - "0": 0.2624160965729906 - }, - { - "0": 0.2509785619822332 - }, - { - "0": 0.24061393371781892 - }, - { - "0": 0.23143079600927366 - }, - { - "0": 0.22347738473804257 - }, - { - "0": 0.21675559500856637 - }, - { - "0": 0.21123488187889242 - }, - { - "0": 0.20686403299834105 - }, - { - "0": 0.20358017886552274 - }, - { - "0": 0.20131519808546838 - } - ], - "data": [ - [ - 0.2 - ], - [ - 0.4 - ] - ], - "loop": true, - "easing": "easeInOutSine", - "duration": 6185.234899328859, - "direction": "normal", - "useBpm": true, - "bpmDivision": 256, - "value": { - "0": 0.2 - } - }, - { - "id": "4dac49b2-c57c-4261-bd0a-7ff39a04391e", - "frames": [ - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0.0014487453199065147 - }, - { - "0": 0.008003117079147635 - }, - { - "0": 0.019284029065500356 - }, - { - "0": 0.035739403075755655 - }, - { - "0": 0.05770686108426248 - }, - { - "0": 0.0852714605917976 - }, - { - "0": 0.11806918188919738 - }, - { - "0": 0.15509046531979143 - }, - { - "0": 0.19461260113425372 - }, - { - "0": 0.23440172406994494 - }, - { - "0": 0.2721737893766391 - }, - { - "0": 0.30608240004035936 - }, - { - "0": 0.3349761565336282 - }, - { - "0": 0.3583731003468158 - }, - { - "0": 0.3762782117213941 - }, - { - "0": 0.3889823948441622 - }, - { - "0": 0.3969100586297614 - }, - { - "0": 0.3996087232858147 - }, - { - "0": 0.3967023650032195 - }, - { - "0": 0.3914720705304442 - }, - { - "0": 0.38368951488697645 - }, - { - "0": 0.373172588646872 - }, - { - "0": 0.3598514790334802 - }, - { - "0": 0.34386334687732545 - }, - { - "0": 0.32565407841712646 - }, - { - "0": 0.3060284059273921 - }, - { - "0": 0.28607411876185956 - }, - { - "0": 0.26694755266371006 - }, - { - "0": 0.24962143241256146 - }, - { - "0": 0.23473179252803741 - }, - { - "0": 0.22257017456801484 - }, - { - "0": 0.21316731383319099 - }, - { - "0": 0.20639547391228408 - }, - { - "0": 0.202049568027119 - }, - { - "0": 0.20034846627048586 - }, - { - "0": 0.20797482891153826 - }, - { - "0": 0.2224545085716621 - }, - { - "0": 0.24448239974251987 - }, - { - "0": 0.274639243310123 - }, - { - "0": 0.3132083130375615 - }, - { - "0": 0.3599037848572093 - }, - { - "0": 0.4135599213368887 - }, - { - "0": 0.47193855080764935 - }, - { - "0": 0.5318823787547526 - }, - { - "0": 0.5899015426751549 - }, - { - "0": 0.642942356621469 - }, - { - "0": 0.6889159036932466 - }, - { - "0": 0.7267883594793367 - }, - { - "0": 0.7563590533901945 - }, - { - "0": 0.7779512517595719 - }, - { - "0": 0.7921545930687377 - }, - { - "0": 0.7996556358078211 - }, - { - "0": 0.8020823758865874 - }, - { - "0": 0.8065117114648074 - }, - { - "0": 0.8134199296257493 - }, - { - "0": 0.8230103962620265 - }, - { - "0": 0.8353996022520541 - }, - { - "0": 0.8505311616125699 - }, - { - "0": 0.8680718254299823 - }, - { - "0": 0.887335537047731 - }, - { - "0": 0.9073108610174723 - }, - { - "0": 0.9268350449900034 - }, - { - "0": 0.9448500754531666 - }, - { - "0": 0.960600086517061 - }, - { - "0": 0.9736851599198638 - }, - { - "0": 0.9839992841250068 - }, - { - "0": 0.9916278278096518 - }, - { - "0": 0.99675724211722 - }, - { - "0": 0.9996137674910821 - }, - { - "0": 0.9960779324975737 - }, - { - "0": 0.9859812349214832 - }, - { - "0": 0.9697822862489741 - }, - { - "0": 0.9469520764037286 - }, - { - "0": 0.9171502348123981 - }, - { - "0": 0.880427982194055 - }, - { - "0": 0.8374858621249102 - }, - { - "0": 0.7898874313970603 - }, - { - "0": 0.7400463152005772 - }, - { - "0": 0.6908493535678593 - }, - { - "0": 0.6450276404580971 - }, - { - "0": 0.6046162316957842 - }, - { - "0": 0.5707579898153697 - }, - { - "0": 0.5438231674080767 - }, - { - "0": 0.5236606588690378 - }, - { - "0": 0.5098338017973154 - }, - { - "0": 0.501785931295121 - }, - { - "0": 0.49257511458658326 - }, - { - "0": 0.4611012648328614 - }, - { - "0": 0.4026677802740691 - }, - { - "0": 0.31809751456798707 - }, - { - "0": 0.21930181292494827 - }, - { - "0": 0.12744640495558274 - }, - { - "0": 0.058693461845106154 - }, - { - "0": 0.01716008249585249 - } - ], - "data": [ - [ - 0 - ], - [ - 0.4 - ], - [ - 0.2 - ], - [ - 0.8 - ], - [ - 1 - ], - [ - 0.5 - ] - ], - "loop": true, - "easing": "easeInOutSine", - "duration": 6185.234899328859, - "direction": "normal", - "useBpm": true, - "bpmDivision": 256, - "value": { - "0": 0 - } - }, - { - "id": "0a2e634a-f54f-4ffd-98bf-595857ac6268", - "frames": [ - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0.0014487453199065147 - }, - { - "0": 0.008003117079147635 - }, - { - "0": 0.019284029065500356 - }, - { - "0": 0.035739403075755655 - }, - { - "0": 0.05770686108426248 - }, - { - "0": 0.0852714605917976 - }, - { - "0": 0.11806918188919738 - }, - { - "0": 0.15509046531979143 - }, - { - "0": 0.19461260113425372 - }, - { - "0": 0.23440172406994494 - }, - { - "0": 0.2721737893766391 - }, - { - "0": 0.30608240004035936 - }, - { - "0": 0.3349761565336282 - }, - { - "0": 0.3583731003468158 - }, - { - "0": 0.3762782117213941 - }, - { - "0": 0.3889823948441622 - }, - { - "0": 0.3969100586297614 - }, - { - "0": 0.3996087232858147 - }, - { - "0": 0.3967023650032195 - }, - { - "0": 0.3914720705304442 - }, - { - "0": 0.38368951488697645 - }, - { - "0": 0.373172588646872 - }, - { - "0": 0.3598514790334802 - }, - { - "0": 0.34386334687732545 - }, - { - "0": 0.32565407841712646 - }, - { - "0": 0.3060284059273921 - }, - { - "0": 0.28607411876185956 - }, - { - "0": 0.26694755266371006 - }, - { - "0": 0.24962143241256146 - }, - { - "0": 0.23473179252803741 - }, - { - "0": 0.22257017456801484 - }, - { - "0": 0.21316731383319099 - }, - { - "0": 0.20639547391228408 - }, - { - "0": 0.202049568027119 - }, - { - "0": 0.20034846627048586 - }, - { - "0": 0.20797482891153826 - }, - { - "0": 0.2224545085716621 - }, - { - "0": 0.24448239974251987 - }, - { - "0": 0.274639243310123 - }, - { - "0": 0.3132083130375615 - }, - { - "0": 0.3599037848572093 - }, - { - "0": 0.4135599213368887 - }, - { - "0": 0.47193855080764935 - }, - { - "0": 0.5318823787547526 - }, - { - "0": 0.5899015426751549 - }, - { - "0": 0.642942356621469 - }, - { - "0": 0.6889159036932466 - }, - { - "0": 0.7267883594793367 - }, - { - "0": 0.7563590533901945 - }, - { - "0": 0.7779512517595719 - }, - { - "0": 0.7921545930687377 - }, - { - "0": 0.7996556358078211 - }, - { - "0": 0.8020823758865874 - }, - { - "0": 0.8065117114648074 - }, - { - "0": 0.8134199296257493 - }, - { - "0": 0.8230103962620265 - }, - { - "0": 0.8353996022520541 - }, - { - "0": 0.8505311616125699 - }, - { - "0": 0.8680718254299823 - }, - { - "0": 0.887335537047731 - }, - { - "0": 0.9073108610174723 - }, - { - "0": 0.9268350449900034 - }, - { - "0": 0.9448500754531666 - }, - { - "0": 0.960600086517061 - }, - { - "0": 0.9736851599198638 - }, - { - "0": 0.9839992841250068 - }, - { - "0": 0.9916278278096518 - }, - { - "0": 0.99675724211722 - }, - { - "0": 0.9996137674910821 - }, - { - "0": 0.9960779324975737 - }, - { - "0": 0.9859812349214832 - }, - { - "0": 0.9697822862489741 - }, - { - "0": 0.9469520764037286 - }, - { - "0": 0.9171502348123981 - }, - { - "0": 0.880427982194055 - }, - { - "0": 0.8374858621249102 - }, - { - "0": 0.7898874313970603 - }, - { - "0": 0.7400463152005772 - }, - { - "0": 0.6908493535678593 - }, - { - "0": 0.6450276404580971 - }, - { - "0": 0.6046162316957842 - }, - { - "0": 0.5707579898153697 - }, - { - "0": 0.5438231674080767 - }, - { - "0": 0.5236606588690378 - }, - { - "0": 0.5098338017973154 - }, - { - "0": 0.501785931295121 - }, - { - "0": 0.49257511458658326 - }, - { - "0": 0.4611012648328614 - }, - { - "0": 0.4026677802740691 - }, - { - "0": 0.31809751456798707 - }, - { - "0": 0.21930181292494827 - }, - { - "0": 0.12744640495558274 - }, - { - "0": 0.058693461845106154 - }, - { - "0": 0.01716008249585249 - } - ], - "data": [ - [ - 0 - ], - [ - 0.4 - ], - [ - 0.2 - ], - [ - 0.8 - ], - [ - 1 - ], - [ - 0.5 - ] - ], - "loop": true, - "easing": "easeInOutSine", - "duration": 6185.234899328859, - "direction": "normal", - "useBpm": true, - "bpmDivision": 256, - "value": { - "0": 0 - } - }, - { - "id": "c7782500-86e8-4e34-a464-5a8523d785ec", - "frames": [ - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0 - }, - { - "0": 0.0008455264005181257 - }, - { - "0": 0.004448357589810567 - }, - { - "0": 0.008425155292497778 - }, - { - "0": 0.012806571787161432 - }, - { - "0": 0.017627403099746093 - }, - { - "0": 0.02292738875460091 - }, - { - "0": 0.028752216400588414 - }, - { - "0": 0.03515479800282429 - }, - { - "0": 0.04219691109680791 - }, - { - "0": 0.04995133844879886 - }, - { - "0": 0.058504699921336924 - }, - { - "0": 0.06796126415175964 - }, - { - "0": 0.07844817688209163 - }, - { - "0": 0.09012278680413703 - }, - { - "0": 0.10318316119877766 - }, - { - "0": 0.11788360114207935 - }, - { - "0": 0.13455826476556926 - }, - { - "0": 0.1536584540687362 - }, - { - "0": 0.17581392465822462 - }, - { - "0": 0.20193834970856966 - }, - { - "0": 0.23341911251136094 - }, - { - "0": 0.2724683361501871 - }, - { - "0": 0.3227266568951425 - }, - { - "0": 0.3896439501482967 - }, - { - "0": 0.47561189438682583 - }, - { - "0": 0.5642469484868634 - }, - { - "0": 0.6355761393472105 - }, - { - "0": 0.689461637024293 - }, - { - "0": 0.7313357794711315 - }, - { - "0": 0.7651112503363633 - }, - { - "0": 0.7931844491225 - }, - { - "0": 0.817052667081024 - }, - { - "0": 0.8376965010974509 - }, - { - "0": 0.8557883363671445 - }, - { - "0": 0.8718078968917659 - }, - { - "0": 0.8861090808873489 - }, - { - "0": 0.8989603938024437 - }, - { - "0": 0.9105704396892997 - }, - { - "0": 0.9211045905201123 - }, - { - "0": 0.9306962409244938 - }, - { - "0": 0.9394546227901932 - }, - { - "0": 0.94747036615271 - }, - { - "0": 0.9548195429693069 - }, - { - "0": 0.9615666646724851 - }, - { - "0": 0.9677669425311795 - }, - { - "0": 0.9734680184478763 - }, - { - "0": 0.9787113086778441 - }, - { - "0": 0.9835330601425556 - }, - { - "0": 0.9879651902815489 - }, - { - "0": 0.9920359617442425 - }, - { - "0": 0.9957705295592008 - }, - { - "0": 0.9991913887621557 - }, - { - "0": 0.9945936354061435 - }, - { - "0": 0.9860308764541529 - }, - { - "0": 0.9756675405283879 - }, - { - "0": 0.9631472658452107 - }, - { - "0": 0.9479889583035739 - }, - { - "0": 0.9295191657443037 - }, - { - "0": 0.9067508611748786 - }, - { - "0": 0.8781480795393148 - }, - { - "0": 0.8411188776266383 - }, - { - "0": 0.7907622876927372 - }, - { - "0": 0.7162023570139846 - }, - { - "0": 0.5904490199664443 - }, - { - "0": 0.416031956075287 - }, - { - "0": 0.2991291724292938 - }, - { - "0": 0.2274059609558463 - }, - { - "0": 0.17751449993686297 - }, - { - "0": 0.1400280926177755 - }, - { - "0": 0.11055118552302423 - }, - { - "0": 0.08670084482133411 - }, - { - "0": 0.06703986730323597 - }, - { - "0": 0.050632546994620053 - }, - { - "0": 0.03683397811515543 - }, - { - "0": 0.025179738699614984 - }, - { - "0": 0.01532354218752252 - }, - { - "0": 0.006999798295247106 - } - ], - "data": [ - [ - 0 - ], - [ - 1 - ] - ], - "loop": true, - "easing": "easeInOutCirc", - "duration": 6185.234899328859, - "direction": "normal", - "useBpm": true, - "bpmDivision": 256, - "value": { - "0": 0 - } - }, - { - "id": "6996f713-e4db-41f8-a9b4-9c99a905372a", - "frames": [ - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.4999154473599482 - }, - { - "0": 0.4995551642410189 - }, - { - "0": 0.4991574844707502 - }, - { - "0": 0.4987193428212839 - }, - { - "0": 0.4982372596900254 - }, - { - "0": 0.4977072611245399 - }, - { - "0": 0.4971247783599412 - }, - { - "0": 0.49648452019971756 - }, - { - "0": 0.4957803088903192 - }, - { - "0": 0.4950048661551201 - }, - { - "0": 0.4941495300078663 - }, - { - "0": 0.49320387358482404 - }, - { - "0": 0.49215518231179084 - }, - { - "0": 0.4909877213195863 - }, - { - "0": 0.48968168388012223 - }, - { - "0": 0.4882116398857921 - }, - { - "0": 0.4865441735234431 - }, - { - "0": 0.48463415459312637 - }, - { - "0": 0.48241860753417753 - }, - { - "0": 0.47980616502914303 - }, - { - "0": 0.4766580887488639 - }, - { - "0": 0.47275316638498127 - }, - { - "0": 0.46772733431048574 - }, - { - "0": 0.4610356049851703 - }, - { - "0": 0.4524388105613174 - }, - { - "0": 0.44357530515131366 - }, - { - "0": 0.43644238606527896 - }, - { - "0": 0.4310538362975707 - }, - { - "0": 0.4268664220528869 - }, - { - "0": 0.42348887496636367 - }, - { - "0": 0.42068155508775 - }, - { - "0": 0.4182947332918976 - }, - { - "0": 0.4162303498902549 - }, - { - "0": 0.4144211663632856 - }, - { - "0": 0.4128192103108234 - }, - { - "0": 0.41138909191126516 - }, - { - "0": 0.4101039606197556 - }, - { - "0": 0.40894295603107006 - }, - { - "0": 0.4078895409479888 - }, - { - "0": 0.40693037590755066 - }, - { - "0": 0.4060545377209807 - }, - { - "0": 0.40525296338472905 - }, - { - "0": 0.4045180457030693 - }, - { - "0": 0.4038433335327515 - }, - { - "0": 0.4032233057468821 - }, - { - "0": 0.4026531981552124 - }, - { - "0": 0.4021288691322156 - }, - { - "0": 0.4016466939857445 - }, - { - "0": 0.4012034809718451 - }, - { - "0": 0.4007964038255758 - }, - { - "0": 0.40042294704407994 - }, - { - "0": 0.40008086112378444 - }, - { - "0": 0.40054063645938565 - }, - { - "0": 0.40139691235458475 - }, - { - "0": 0.40243324594716123 - }, - { - "0": 0.40368527341547894 - }, - { - "0": 0.4052011041696426 - }, - { - "0": 0.40704808342556964 - }, - { - "0": 0.4093249138825122 - }, - { - "0": 0.4121851920460685 - }, - { - "0": 0.4158881122373362 - }, - { - "0": 0.4209237712307263 - }, - { - "0": 0.42837976429860153 - }, - { - "0": 0.4409550980033556 - }, - { - "0": 0.4583968043924713 - }, - { - "0": 0.4700870827570706 - }, - { - "0": 0.47725940390441535 - }, - { - "0": 0.4822485500063137 - }, - { - "0": 0.48599719073822245 - }, - { - "0": 0.4889448814476976 - }, - { - "0": 0.4913299155178666 - }, - { - "0": 0.4932960132696764 - }, - { - "0": 0.494936745300538 - }, - { - "0": 0.49631660218848445 - }, - { - "0": 0.4974820261300385 - }, - { - "0": 0.49846764578124775 - }, - { - "0": 0.49930002017047526 - } - ], - "data": [ - [ - 0.5 - ], - [ - 0.4 - ] - ], - "loop": true, - "easing": "easeInOutCirc", - "duration": 6185.234899328859, - "direction": "normal", - "useBpm": true, - "bpmDivision": 256, - "value": { - "0": 0.5 - } - }, - { - "id": "bdd7a20d-56e8-4e53-88f8-c055fff21712", - "frames": [ - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.4997463420798446 - }, - { - "0": 0.4986654927230568 - }, - { - "0": 0.49747245341225066 - }, - { - "0": 0.4961580284638516 - }, - { - "0": 0.4947117790700762 - }, - { - "0": 0.4931217833736197 - }, - { - "0": 0.4913743350798235 - }, - { - "0": 0.48945356059915274 - }, - { - "0": 0.48734092667095763 - }, - { - "0": 0.4850145984653603 - }, - { - "0": 0.4824485900235989 - }, - { - "0": 0.4796116207544721 - }, - { - "0": 0.4764655469353725 - }, - { - "0": 0.47296316395875887 - }, - { - "0": 0.4690450516403667 - }, - { - "0": 0.4646349196573762 - }, - { - "0": 0.4596325205703292 - }, - { - "0": 0.45390246377937915 - }, - { - "0": 0.4472558226025326 - }, - { - "0": 0.4394184950874291 - }, - { - "0": 0.42997426624659174 - }, - { - "0": 0.41825949915494387 - }, - { - "0": 0.40318200293145723 - }, - { - "0": 0.383106814955511 - }, - { - "0": 0.3573164316839522 - }, - { - "0": 0.330725915453941 - }, - { - "0": 0.3093271581958369 - }, - { - "0": 0.2931615088927121 - }, - { - "0": 0.2805992661586606 - }, - { - "0": 0.270466624899091 - }, - { - "0": 0.26204466526325 - }, - { - "0": 0.25488419987569283 - }, - { - "0": 0.24869104967076477 - }, - { - "0": 0.24326349908985667 - }, - { - "0": 0.23845763093247024 - }, - { - "0": 0.23416727573379537 - }, - { - "0": 0.23031188185926688 - }, - { - "0": 0.22682886809321007 - }, - { - "0": 0.22366862284396632 - }, - { - "0": 0.22079112772265186 - }, - { - "0": 0.21816361316294203 - }, - { - "0": 0.21575889015418703 - }, - { - "0": 0.21355413710920795 - }, - { - "0": 0.2115300005982545 - }, - { - "0": 0.20966991724064615 - }, - { - "0": 0.2079595944656371 - }, - { - "0": 0.20638660739664677 - }, - { - "0": 0.20494008195723334 - }, - { - "0": 0.20361044291553532 - }, - { - "0": 0.20238921147672728 - }, - { - "0": 0.2012688411322398 - }, - { - "0": 0.2002425833713533 - }, - { - "0": 0.20162190937815697 - }, - { - "0": 0.20419073706375412 - }, - { - "0": 0.20729973784148364 - }, - { - "0": 0.2110558202464368 - }, - { - "0": 0.21560331250892786 - }, - { - "0": 0.2211442502767089 - }, - { - "0": 0.22797474164753645 - }, - { - "0": 0.23655557613820558 - }, - { - "0": 0.24766433671200855 - }, - { - "0": 0.2627713136921789 - }, - { - "0": 0.28513929289580464 - }, - { - "0": 0.3228652940100667 - }, - { - "0": 0.3751904131774139 - }, - { - "0": 0.41026124827121185 - }, - { - "0": 0.4317782117132461 - }, - { - "0": 0.4467456500189411 - }, - { - "0": 0.45799157221466735 - }, - { - "0": 0.46683464434309274 - }, - { - "0": 0.47398974655359977 - }, - { - "0": 0.4798880398090292 - }, - { - "0": 0.484810235901614 - }, - { - "0": 0.4889498065654534 - }, - { - "0": 0.4924460783901155 - }, - { - "0": 0.49540293734374324 - }, - { - "0": 0.4979000605114259 - } - ], - "data": [ - [ - 0.5 - ], - [ - 0.2 - ] - ], - "loop": true, - "easing": "easeInOutCirc", - "duration": 6185.234899328859, - "direction": "normal", - "useBpm": true, - "bpmDivision": 256, - "value": { - "0": 0.5 - } - }, - { - "id": "144dc5f0-8f18-44bf-a4da-9c13f6359ee1", - "frames": [ - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.4998444832202206 - }, - { - "0": 0.4998319090621881 - }, - { - "0": 0.499877771800653 - }, - { - "0": 0.5000053579405611 - }, - { - "0": 0.5002217907937317 - }, - { - "0": 0.5005036463199307 - }, - { - "0": 0.5007845596538563 - }, - { - "0": 0.5009512119003718 - }, - { - "0": 0.5008552833641957 - }, - { - "0": 0.5003479673047335 - }, - { - "0": 0.4993392944304272 - }, - { - "0": 0.4978761740486657 - }, - { - "0": 0.4962212060236473 - }, - { - "0": 0.4949012095041634 - }, - { - "0": 0.4946844100900471 - }, - { - "0": 0.49644455217501376 - }, - { - "0": 0.5008857820452395 - }, - { - "0": 0.5081393250703656 - }, - { - "0": 0.5173022531136426 - }, - { - "0": 0.5260619959005429 - }, - { - "0": 0.5306183213291941 - }, - { - "0": 0.5261462275777533 - }, - { - "0": 0.5079999079608627 - }, - { - "0": 0.47370353363154133 - }, - { - "0": 0.4254917090891285 - }, - { - "0": 0.37277290197049634 - }, - { - "0": 0.32722709802950367 - }, - { - "0": 0.2745082909108714 - }, - { - "0": 0.22629646636845857 - }, - { - "0": 0.19200009203913754 - }, - { - "0": 0.1738537724222468 - }, - { - "0": 0.16938167867080595 - }, - { - "0": 0.1739380040994571 - }, - { - "0": 0.18269774688635732 - }, - { - "0": 0.19186067492963427 - }, - { - "0": 0.19911421795476053 - }, - { - "0": 0.20355544782498625 - }, - { - "0": 0.20531558990995297 - }, - { - "0": 0.20509879049583662 - }, - { - "0": 0.20377879397635273 - }, - { - "0": 0.20212382595133432 - }, - { - "0": 0.20066070556957283 - }, - { - "0": 0.1996520326952665 - }, - { - "0": 0.1991447166358043 - }, - { - "0": 0.19904878809962817 - }, - { - "0": 0.19921544034614375 - }, - { - "0": 0.1994963536800693 - }, - { - "0": 0.1997782092062682 - }, - { - "0": 0.19999464205943884 - }, - { - "0": 0.200122228199347 - }, - { - "0": 0.2001680909378119 - }, - { - "0": 0.20015551677977939 - }, - { - "0": 0.20016316206868529 - }, - { - "0": 0.19994858154741507 - }, - { - "0": 0.19942238987236338 - }, - { - "0": 0.19904197797284864 - }, - { - "0": 0.19985604753126265 - }, - { - "0": 0.20253549713114485 - }, - { - "0": 0.20529034847881106 - }, - { - "0": 0.20271492879915526 - }, - { - "0": 0.18968474633834556 - }, - { - "0": 0.1722274812426598 - }, - { - "0": 0.1769562993982371 - }, - { - "0": 0.2372734449216216 - }, - { - "0": 0.3391953685475609 - }, - { - "0": 0.4384762821916678 - }, - { - "0": 0.5140137233101241 - }, - { - "0": 0.5301281123828613 - }, - { - "0": 0.5149326537619388 - }, - { - "0": 0.49950281120558915 - }, - { - "0": 0.4945871276213468 - }, - { - "0": 0.49662875953094654 - }, - { - "0": 0.49963902569679447 - }, - { - "0": 0.5009124856197221 - }, - { - "0": 0.5007198560233985 - }, - { - "0": 0.500159978050673 - }, - { - "0": 0.49985938417173537 - } - ], - "data": [ - [ - 0.5 - ], - [ - 0.2 - ] - ], - "loop": true, - "easing": "easeInOutElastic", - "duration": 6185.234899328859, - "direction": "normal", - "useBpm": true, - "bpmDivision": 256, - "value": { - "0": 0.5 - } - }, - { - "id": "51e34602-d6a7-45da-8044-32b6e472bd28", - "frames": [ - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5011688516844351 - }, - { - "0": 0.5056576018175244 - }, - { - "0": 0.5098300934072267 - }, - { - "0": 0.5136604463999693 - }, - { - "0": 0.5171193834789708 - }, - { - "0": 0.5201736101782826 - }, - { - "0": 0.5227850493296834 - }, - { - "0": 0.5249098879582216 - }, - { - "0": 0.5264973806242309 - }, - { - "0": 0.5274883337752434 - }, - { - "0": 0.5278131688590472 - }, - { - "0": 0.5273894250603447 - }, - { - "0": 0.5261185123745613 - }, - { - "0": 0.5238814595863924 - }, - { - "0": 0.5205333205008923 - }, - { - "0": 0.5158958196486737 - }, - { - "0": 0.5097477900517233 - }, - { - "0": 0.5018131489607696 - }, - { - "0": 0.4917470522039989 - }, - { - "0": 0.47912375372945015 - }, - { - "0": 0.46343777985513485 - }, - { - "0": 0.44414989009428885 - }, - { - "0": 0.42084701750134756 - }, - { - "0": 0.39360981885967466 - }, - { - "0": 0.36352643628123205 - }, - { - "0": 0.33280352066208474 - }, - { - "0": 0.30389797011206 - }, - { - "0": 0.27839164669081184 - }, - { - "0": 0.2567471303878319 - }, - { - "0": 0.23874337172394083 - }, - { - "0": 0.22391158648699344 - }, - { - "0": 0.2117608672064114 - }, - { - "0": 0.20185887851966383 - }, - { - "0": 0.19384793378482074 - }, - { - "0": 0.18743854474937144 - }, - { - "0": 0.18239747175499088 - }, - { - "0": 0.17853613484010794 - }, - { - "0": 0.17570096839381982 - }, - { - "0": 0.17376583146080832 - }, - { - "0": 0.17262616178678003 - }, - { - "0": 0.1721944996632523 - }, - { - "0": 0.17239705517085718 - }, - { - "0": 0.1731710613464914 - }, - { - "0": 0.17446271836099725 - }, - { - "0": 0.17622558360743518 - }, - { - "0": 0.17841930022723806 - }, - { - "0": 0.181008584385615 - }, - { - "0": 0.1839624119472249 - }, - { - "0": 0.18725336007417054 - }, - { - "0": 0.19085707017162523 - }, - { - "0": 0.19475180664145736 - }, - { - "0": 0.19891809186364967 - }, - { - "0": 0.19326866805961393 - }, - { - "0": 0.18543877249025803 - }, - { - "0": 0.17913041351902165 - }, - { - "0": 0.174640708035623 - }, - { - "0": 0.17236502988200322 - }, - { - "0": 0.17284461968844816 - }, - { - "0": 0.17684508160929016 - }, - { - "0": 0.1854898322096106 - }, - { - "0": 0.20048837137604225 - }, - { - "0": 0.22448945313753232 - }, - { - "0": 0.26129028001659976 - }, - { - "0": 0.31371433891167344 - }, - { - "0": 0.37467576406750014 - }, - { - "0": 0.4273804974211983 - }, - { - "0": 0.4652421796119917 - }, - { - "0": 0.4909102114451226 - }, - { - "0": 0.5078945819179435 - }, - { - "0": 0.5186719309154759 - }, - { - "0": 0.5248627790321487 - }, - { - "0": 0.5275450361816015 - }, - { - "0": 0.52746077573453 - }, - { - "0": 0.5251390692447342 - }, - { - "0": 0.5209691840593758 - }, - { - "0": 0.5152454558940835 - }, - { - "0": 0.5081957325314245 - } - ], - "data": [ - [ - 0.5 - ], - [ - 0.2 - ] - ], - "loop": true, - "easing": "easeInOutBack", - "duration": 6185.234899328859, - "direction": "normal", - "useBpm": true, - "bpmDivision": 256, - "value": { - "0": 0.5 - } - }, - { - "id": "51081af2-3129-423d-89b4-ec29acb95d42", - "frames": [ - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.499996794689121 - }, - { - "0": 0.4999178822222022 - }, - { - "0": 0.49972711269899406 - }, - { - "0": 0.49941549216583137 - }, - { - "0": 0.49897282355859285 - }, - { - "0": 0.4983874752620428 - }, - { - "0": 0.4976460901668599 - }, - { - "0": 0.4967332156473095 - }, - { - "0": 0.4956308268672219 - }, - { - "0": 0.49431770379945145 - }, - { - "0": 0.4927686038995046 - }, - { - "0": 0.4909531433538955 - }, - { - "0": 0.48883425284758747 - }, - { - "0": 0.4863659952584734 - }, - { - "0": 0.4834903964435903 - }, - { - "0": 0.4801326936033098 - }, - { - "0": 0.47619393614486594 - }, - { - "0": 0.4715389253525506 - }, - { - "0": 0.4659754200458857 - }, - { - "0": 0.45921565181749235 - }, - { - "0": 0.45079823971289756 - }, - { - "0": 0.43990885593988754 - }, - { - "0": 0.424890164780101 - }, - { - "0": 0.40154159401885037 - }, - { - "0": 0.358255571659099 - }, - { - "0": 0.3115489265704603 - }, - { - "0": 0.28592557956750875 - }, - { - "0": 0.2696226695010707 - }, - { - "0": 0.25782153878690706 - }, - { - "0": 0.24867381848449016 - }, - { - "0": 0.24128920970978673 - }, - { - "0": 0.2351696763010357 - }, - { - "0": 0.23000724496098834 - }, - { - "0": 0.22559742254461718 - }, - { - "0": 0.22179703295809655 - }, - { - "0": 0.21850163849126436 - }, - { - "0": 0.2156325345429458 - }, - { - "0": 0.21312881401047923 - }, - { - "0": 0.21094229339582893 - }, - { - "0": 0.20903414076092097 - }, - { - "0": 0.2073725606511962 - }, - { - "0": 0.2059311599995532 - }, - { - "0": 0.20468776677618444 - }, - { - "0": 0.2036235579507315 - }, - { - "0": 0.2027224038669106 - }, - { - "0": 0.20197036724640427 - }, - { - "0": 0.20135531475976604 - }, - { - "0": 0.20086661192454336 - }, - { - "0": 0.20049488062057402 - }, - { - "0": 0.20023180430427395 - }, - { - "0": 0.20006997001017157 - }, - { - "0": 0.20000273904642907 - }, - { - "0": 0.20011899090730964 - }, - { - "0": 0.2006824613859481 - }, - { - "0": 0.20178267799192418 - }, - { - "0": 0.20352384581064928 - }, - { - "0": 0.2060463594466973 - }, - { - "0": 0.20954651000746913 - }, - { - "0": 0.2143121279489203 - }, - { - "0": 0.2207929799369052 - }, - { - "0": 0.22975757776246625 - }, - { - "0": 0.24270960997160684 - }, - { - "0": 0.2633612618957763 - }, - { - "0": 0.30675969959033267 - }, - { - "0": 0.3962578654443891 - }, - { - "0": 0.4336513643076215 - }, - { - "0": 0.45331366245363 - }, - { - "0": 0.46620132585685436 - }, - { - "0": 0.47540519140006904 - }, - { - "0": 0.48225296556184616 - }, - { - "0": 0.48744589771189345 - }, - { - "0": 0.4914032575325701 - }, - { - "0": 0.4943974646791896 - }, - { - "0": 0.4966164383880877 - }, - { - "0": 0.4981957991707148 - }, - { - "0": 0.49923694530502283 - }, - { - "0": 0.49981787404440403 - } - ], - "data": [ - [ - 0.5 - ], - [ - 0.2 - ] - ], - "loop": true, - "easing": "easeInOutQuint", - "duration": 6185.234899328859, - "direction": "normal", - "useBpm": true, - "bpmDivision": 256, - "value": { - "0": 0.5 - } - }, - { - "id": "341e2bfd-02e1-42c8-9abb-2dfac3be14cf", - "frames": [ - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.5 - }, - { - "0": 0.4999960012682792 - }, - { - "0": 0.4998975202401037 - }, - { - "0": 0.4996593280432776 - }, - { - "0": 0.49927004070733233 - }, - { - "0": 0.49871674989694337 - }, - { - "0": 0.4979847324468626 - }, - { - "0": 0.49705708667916093 - }, - { - "0": 0.4959142721370488 - }, - { - "0": 0.4945335202012134 - }, - { - "0": 0.4928880695543964 - }, - { - "0": 0.4909461602022473 - }, - { - "0": 0.48866968872919797 - }, - { - "0": 0.4860123788627114 - }, - { - "0": 0.4829172434050029 - }, - { - "0": 0.47931298503617953 - }, - { - "0": 0.4751087656330408 - }, - { - "0": 0.470186393704235 - }, - { - "0": 0.4643882979514994 - }, - { - "0": 0.457498406762078 - }, - { - "0": 0.4492107714243899 - }, - { - "0": 0.4390769160562802 - }, - { - "0": 0.4264189689337079 - }, - { - "0": 0.410211305505171 - }, - { - "0": 0.3891044284787879 - }, - { - "0": 0.36258647259450294 - }, - { - "0": 0.334185362641531 - }, - { - "0": 0.30960245342691506 - }, - { - "0": 0.29038755229741975 - }, - { - "0": 0.27543999721036744 - }, - { - "0": 0.26354397900150167 - }, - { - "0": 0.25384921039856334 - }, - { - "0": 0.24579415365104368 - }, - { - "0": 0.23900136795286547 - }, - { - "0": 0.2332086816429132 - }, - { - "0": 0.22822782540326847 - }, - { - "0": 0.22391947827473246 - }, - { - "0": 0.22017780590799446 - }, - { - "0": 0.21692057156656275 - }, - { - "0": 0.2140826118540406 - }, - { - "0": 0.21161140717994276 - }, - { - "0": 0.2094639955844934 - }, - { - "0": 0.20760477209960793 - }, - { - "0": 0.20600388668548048 - }, - { - "0": 0.20463605607465807 - }, - { - "0": 0.20347966777138093 - }, - { - "0": 0.20251609413914384 - }, - { - "0": 0.20172916013176473 - }, - { - "0": 0.2011047251245774 - }, - { - "0": 0.2006303506728122 - }, - { - "0": 0.2002950338134425 - }, - { - "0": 0.20008899095228005 - }, - { - "0": 0.20000348121562128 - }, - { - "0": 0.20014850887830224 - }, - { - "0": 0.20085236506730408 - }, - { - "0": 0.20222812465196796 - }, - { - "0": 0.2044076388416867 - }, - { - "0": 0.20756824684116035 - }, - { - "0": 0.211956915338948 - }, - { - "0": 0.21793292547887294 - }, - { - "0": 0.22604913424751044 - }, - { - "0": 0.23722171481003987 - }, - { - "0": 0.2531278939511088 - }, - { - "0": 0.27725097966088574 - }, - { - "0": 0.3170605832663419 - }, - { - "0": 0.37246347828845533 - }, - { - "0": 0.4136960611609122 - }, - { - "0": 0.4390601376603516 - }, - { - "0": 0.45601056325190165 - }, - { - "0": 0.4681065069545124 - }, - { - "0": 0.47706550935699166 - }, - { - "0": 0.4838259852823552 - }, - { - "0": 0.48895429883875613 - }, - { - "0": 0.492818610536934 - }, - { - "0": 0.4956720896243472 - }, - { - "0": 0.4976966150110775 - }, - { - "0": 0.49902748414965536 - }, - { - "0": 0.49976823829610284 - } - ], - "data": [ - [ - 0.5 - ], - [ - 0.2 - ] - ], - "loop": true, - "easing": "easeInOutQuart", - "duration": 6185.234899328859, - "direction": "normal", - "useBpm": true, - "bpmDivision": 256, - "value": { - "0": 0.5 - } - } - ] -} diff --git a/src/App.vue b/src/App.vue deleted file mode 100644 index cec59cad4..000000000 --- a/src/App.vue +++ /dev/null @@ -1,504 +0,0 @@ - - - - - - - - - - - - - diff --git a/src/application/renderers/shader/index.js b/src/application/renderers/shader/index.js deleted file mode 100644 index 99511bc63..000000000 --- a/src/application/renderers/shader/index.js +++ /dev/null @@ -1,231 +0,0 @@ -import createContext from "pex-context"; -import { frames } from "../../worker/frame-counter"; -import store from "../../worker/store"; -import defaultShader from "./default-shader"; - -const shaderCanvas = new OffscreenCanvas(300, 300); -const shaderContext = shaderCanvas.getContext("webgl2", { - antialias: true, - desynchronized: true, - powerPreference: "high-performance", - premultipliedAlpha: false -}); - -store.dispatch("outputs/addAuxillaryOutput", { - name: "shader-buffer", - context: shaderContext, - group: "buffer" -}); - -const pex = createContext({ gl: shaderContext }); - -const a_position = pex.vertexBuffer([-1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1]); -const indices = pex.indexBuffer([0, 1, 2, 3, 4, 5]); - -const commands = {}; - -let canvasTexture; -let fftTexture; - -const clearCmd = { - pass: pex.pass({ - clearColor: [0, 0, 0, 1], - clearDepth: 1 - }) -}; - -function resize({ width, height }) { - shaderCanvas.width = width; - shaderCanvas.height = height; - - // pex.set({ - // width, - // height - // }); -} - -function generateUniforms(canvasTexture, uniforms, kick = false) { - const { width, height, dpr } = store.state.size; - - const date = new Date(); - const time = performance.now(); - const resolution = [width, height, dpr]; - - const defaults = { - iGlobalTime: time / 1000, - iFrame: frames(), - iDate: [date.getFullYear(), date.getMonth(), date.getDay(), time / 1000], - iTime: time / 1000, - iTimeDelta: time / 1000, - iResolution: resolution, - iChannel0: canvasTexture, - iChannel1: canvasTexture, - iChannel2: canvasTexture, - iChannel3: canvasTexture, - iChannelResolution: [resolution, resolution, resolution, resolution], - u_modVCanvas: canvasTexture, - u_fft: fftTexture, - u_fftResolution: fftTexture ? fftTexture.width : 1, - u_delta: time / 1000, - u_time: time, - u_kick: kick - }; - - return { ...uniforms, ...defaults }; -} - -function makeProgram(moduleDefinition) { - return new Promise(resolve => { - let vert = moduleDefinition.vertexShader; - let frag = moduleDefinition.fragmentShader; - - if (!vert) { - vert = defaultShader.v; - } - - if (!frag) { - frag = defaultShader.f; - } - - if (frag.search("gl_FragColor") < 0) { - frag = defaultShader.fWrap.replace(/(%MAIN_IMAGE_INJECT%)/, frag); - - vert = defaultShader.v300; - } - - const pipeline = pex.pipeline({ - depthTest: true, - vert, - frag - }); - - const shaderUniforms = {}; - - if (moduleDefinition.props) { - const modulePropsKeys = Object.keys(moduleDefinition.props); - const modulePropsKeysLength = modulePropsKeys.length; - - for (let i = 0; i < modulePropsKeysLength; i++) { - const key = modulePropsKeys[i]; - - if (moduleDefinition.props[key].type === "texture") { - shaderUniforms[key] = moduleDefinition.props[key].value; - } else { - shaderUniforms[key] = moduleDefinition.props[key]; - } - } - } - - const uniforms = generateUniforms(canvasTexture, shaderUniforms); - - const command = { - pipeline, - attributes: { - a_position, - position: a_position - }, - indices, - uniforms - }; - - commands[moduleDefinition.meta.name] = command; - - resolve(moduleDefinition); - }); -} - -async function setupModule(moduleDefinition) { - try { - return await makeProgram(moduleDefinition); - } catch (e) { - throw new Error(e); - } -} - -function render({ module, props, canvas, context, pipeline, kick, fftCanvas }) { - resize({ width: canvas.width, height: canvas.height }); - - if (!canvasTexture) { - canvasTexture = pex.texture2D({ - data: canvas.data || canvas, - width: canvas.width, - height: canvas.height, - pixelFormat: pex.PixelFormat.RGBA8, - encoding: pex.Encoding.Linear, - min: pex.Filter.Linear, - mag: pex.Filter.Linear, - wrap: pex.Wrap.Repeat - }); - fftTexture = pex.texture2D({ - data: fftCanvas.data || fftCanvas, - width: fftCanvas.width, - height: 1, - pixelFormat: pex.PixelFormat.RGBA8, - encoding: pex.Encoding.Linear, - wrap: pex.Wrap.Repeat - }); - } else { - pex.update(canvasTexture, { - width: canvas.width, - height: canvas.height, - data: canvas.data || canvas - }); - pex.update(fftTexture, { - width: fftCanvas.width, - height: 1, - data: fftCanvas.data || fftCanvas - }); - } - - const shaderUniforms = {}; - - if (props) { - const modulePropsKeys = Object.keys(props); - const modulePropsKeysLength = modulePropsKeys.length; - - for (let i = 0; i < modulePropsKeysLength; i++) { - const key = modulePropsKeys[i]; - - if (module.props[key].type === "texture") { - shaderUniforms[key] = props[key].value; - } else { - shaderUniforms[key] = props[key]; - } - } - } - - const uniforms = generateUniforms(canvasTexture, shaderUniforms, kick); - - const command = commands[module.meta.name]; - - pex.submit(clearCmd); - pex.submit(command, { - uniforms, - viewport: [0, 0, canvas.width, canvas.height] - }); - - // clear context if we're in pipeline mode - if (pipeline) { - context.clearRect(0, 0, canvas.width, canvas.height); - } - - // Copy Shader Canvas to Main Canvas - context.drawImage(shaderCanvas, 0, 0, canvas.width, canvas.height); -} - -/** - * Called each frame to update the Module - */ -function updateModule({ module, props, data, canvas, context, delta }) { - const { data: dataUpdated } = module.update({ - props, - data, - canvas, - context, - delta - }); - - return dataUpdated ?? data; -} - -export { setupModule, render, resize, updateModule }; diff --git a/src/application/sample-modules/Triangles.js b/src/application/sample-modules/Triangles.js deleted file mode 100644 index 8ab19a245..000000000 --- a/src/application/sample-modules/Triangles.js +++ /dev/null @@ -1,541 +0,0 @@ -export default { - meta: { - name: "TriangleLife", - type: "2d", - version: "0.0.0", - author: "radiodario" - }, - - props: { - N: { - label: "Grid Size", - type: "int", - min: 2, - max: 512, - default: 128 - }, - stroke: { - label: "Draw Stroke", - type: "bool", - default: false - }, - fill: { - label: "Draw Fill", - type: "bool", - default: true - }, - strokeWeight: { - type: "int", - label: "Stroke Weight", - min: 1, - max: 30, - default: 1, - abs: true - }, - strokeJoin: { - type: "enum", - label: "Stroke Join", - default: "round", - enum: [ - { label: "Round", value: "round" }, - { label: "Bevel", value: "bevel" }, - { label: "Miter", value: "miter" } - ] - }, - speed: { - label: "Colour Speed", - type: "int", - min: 1, - max: 1000, - default: 500 - }, - fg_alpha: { - label: "FG Alpha", - type: "float", - min: 0, - max: 1, - default: 1 - }, - seeds: { - label: "Seeds", - type: "int", - min: 1, - max: 25000, - default: 350 - }, - updateInterval: { - label: "Simulation Steps per Sec", - type: "int", - min: 1, - max: 120, // lol - default: 60 - }, - drawInterval: { - label: "Draw steps per Sec", - type: "int", - min: 1, - max: 120, // lol - default: 60 - }, - waveform: { - type: "enum", - label: "Colour Waveform", - default: "sin", - enum: [ - { label: "Sine", value: "sin" }, - { label: "Cosine", value: "cos" }, - { label: "Triangle", value: "triangle" }, - { label: "Saw", value: "saw" } - ] - }, - monochrome: { - label: "Monochrome", - type: "bool", - default: true - }, - monochromeHue: { - label: "Monochrome Hue", - type: "int", - default: 180, - min: 0, - max: 360 - }, - cycleHue: { - label: "Cycle Hue", - type: "bool", - default: false - }, - rule: { - type: "enum", - label: "Life Rule", - enum: [ - "2/1", - "2/2", - "0,1/3,3", - "1,2/4,6", - "*2/3", - "*2,3/3,3", - "*2,3/4,5", - "*2,3/4,6", - "*3,4/4,5", - "*3,4/4,6", - "**4,5/4,6", - "*4,6/4,4" - ].map(r => ({ label: r, value: r })), - default: "2/1", - set(args) { - return this.reset(args); - } - }, - resetField: { - type: "event", - label: "Reset Field", - set(args) { - if (args.props.resetField) { - return this.reset(args); - } - } - } - }, - - data: { - edge: 0, - field: [], - colorCounter: 0, - counterAngle: 0, - counterIncrease: 0, - lastUpdate: 0, - lastDraw: 0, - shouldDraw: true - }, - - init(args) { - return this.reset(args); - }, - - reset({ data, props }) { - data.rule = this.parseRule(props.rule); - data.field = this.initializeField(props); - const N = props.N; - for (var i = 0; i < props.seeds; i++) { - var idx = Math.floor(Math.random() * N * N); - data.field[idx] = 1; - } - - return data; - }, - - initializeField(props) { - var field = []; - var allCells = props.N * props.N; - for (var i = 0; i < allCells; i++) { - field[i] = 0; - } - return field; - }, - - resize({ canvas, data, props }) { - const width = canvas.width + 20; - const height = canvas.height; - - // triangle height and width - var kH = (2 * height) / (props.N * Math.sqrt(2)); - var kW = (2 * width) / props.N; - - data.edge = Math.max(kH, kW); - - return data; - }, - - draw({ - data, - props, - context, - context: { - canvas: { width, height } - } - }) { - if (data.shouldDraw) { - var N = props.N; - var x, - y, - i, - l, - baseY, - lEdge = data.edge * Math.cos(Math.PI / 6); - - var translate = { - x: (width - (N * data.edge) / 2) / 2, - y: (height - (N * data.edge * Math.SQRT2) / 2) / 2 - }; - - if (props.cycleHue) { - props.monochromeHue = - (props.monochromeHue + 360 / (1001 - props.speed)) % 360; - } - - for (i = 0, l = data.field.length; i < l; i++) { - if (data.field[i] <= 0) { - continue; - } - - x = i % N; - y = (i / N) | 0; - - baseY = y * lEdge; - this.drawTriangle(context, x, y, lEdge, baseY, translate, data); - this.setColors(context, x, y, props, data); - } - } - }, - - drawTriangle(context, x, y, lEdge, baseY, translate, { edge }) { - context.beginPath(); - - var type = (y % 2 << 1) + (x % 2); - - switch (type) { - case 0: - context.moveTo(((x + 0) * edge) / 2 + translate.x, baseY + translate.y); - context.lineTo(((x + 2) * edge) / 2 + translate.x, baseY + translate.y); - context.lineTo( - ((x + 1) * edge) / 2 + translate.x, - baseY + lEdge + translate.y - ); - break; - case 1: - context.moveTo(((x + 1) * edge) / 2 + translate.x, baseY + translate.y); - context.lineTo( - ((x + 2) * edge) / 2 + translate.x, - baseY + lEdge + translate.y - ); - context.lineTo( - ((x + 0) * edge) / 2 + translate.x, - baseY + lEdge + translate.y - ); - break; - case 2: - context.moveTo(((x + 1) * edge) / 2 + translate.x, baseY + translate.y); - context.lineTo( - ((x + 2) * edge) / 2 + translate.x, - baseY + translate.y + lEdge - ); - context.lineTo( - ((x + 0) * edge) / 2 + translate.x, - baseY + translate.y + lEdge - ); - break; - case 3: - context.moveTo(((x + 0) * edge) / 2 + translate.x, baseY + translate.y); - context.lineTo(((x + 2) * edge) / 2 + translate.x, baseY + translate.y); - context.lineTo( - ((x + 1) * edge) / 2 + translate.x, - baseY + translate.y + lEdge - ); - break; - } - - context.closePath(); - }, - - setColors(context, x, y, props, data) { - // var val = Field[x + (N * y)]; - const speed = 1001 - props.speed; - let color; - if (props.monochrome) { - color = hslToRgb(props.monochromeHue / 360, 1, 0.5, props.fg_alpha * 100); - } else { - data.counterIncrease = Math.PI / speed; - data.counterAngle += data.counterIncrease; - switch (props.waveform) { - case "sin": - data.colorCounter = 1 + Math.sin(data.counterAngle) / 2; - break; - case "cos": - data.colorCounter = 1 + Math.cos(data.counterAngle) / 2; - break; - case "triangle": - data.colorCounter = Math.abs((data.counterAngle % 2) - 1); - break; - case "saw": - data.colorCounter = Math.abs(data.counterAngle % 1); - break; - } - - color = hslToRgb(data.colorCounter, 1, 0.5, props.fg_alpha * 100); - } - - if (props.fill) { - context.fillStyle = color; - context.fill(); - } - if (props.stroke) { - context.strokeStyle = color; - context.lineWidth = props.strokeWeight; - context.lineJoin = props.strokeJoin; - context.stroke(); - } - }, - - update({ data, props }) { - const timestamp = performance.now(); - - if (timestamp > data.lastDraw + 1000 / props.drawInterval) { - data.shouldDraw = true; - data.lastDraw = timestamp; - } else { - data.shouldDraw = false; - } - - if (timestamp > data.lastUpdate + 1000 / props.updateInterval) { - let ln = 0; // live neighbor count - let i, l, val; - const nextField = this.initializeField(props); - - for (i = 0, l = data.field.length; i < l; i++) { - ln = this.computeLiveNeighbours(i, props, data); - val = data.field[i]; - nextField[i] = this.computeNextStateOfCell(val, ln, data.rule); - } - - data.field = nextField; - data.lastUpdate = timestamp; - } - - return data; - }, - - neighbours: { - O: [ - [-1, -2], - [-1, -1], - [-1, 0], - [-1, 1], - [-1, 2], - [0, -2], - [0, -1], - [0, 1], - [0, 2], - [1, -1], - [1, 0], - [1, 1] - ], - E: [ - [-1, -1], - [-1, 0], - [-1, 1], - [0, -2], - [0, -1], - [0, 1], - [0, 2], - [1, -2], - [1, -1], - [1, 0], - [1, 1], - [1, 2] - ] - }, - - computeLiveNeighbours(idx, props, data) { - const N = props.N; - const x = idx % N; - const y = (idx / N) | 0; - let LN = 0; - - /* - Each cell has 12 touching neighbors. There are two - types of cells, E and O cells. - */ - const type = (x + y) % 2; - let i, l, nList; - - // Even Cell - if (type === 1) { - nList = this.neighbours.E; - } - // Odd Cell - else { - nList = this.neighbours.O; - } - for (i = 0, l = nList.length; i < l; i++) { - var nb = this.neighbourAt(x, y, nList[i], props, data); - LN += nb; - } - - return LN; - }, - - neighbourAt(x, y, neighbour, props, data) { - const N = props.N; - let dx = x + neighbour[1]; - let dy = y + neighbour[0]; - // wrap around - if (dx >= N) { - dx = dx % N; - } - if (dx < 0) { - dx = N + dx; - } - if (dy >= N) { - dy = dy % N; - } - if (dy < 0) { - dy = N + dy; - } - - return data.field[dx + dy * N] || 0; - }, - - computeNextStateOfCell(val, LN, rule) { - if (val > 0) { - if (LN >= rule.env.l && LN <= rule.env.h) { - return 1; - } else { - return 0; - } - } else { - if (LN >= rule.fer.l && LN <= rule.fer.h) { - return 1; - } else { - return 0; - } - } - }, - - parseRule(ruleString) { - const ruleExp = /(\d+|\d+,\d+)\/(\d+|\d+,\d+)$/i; - - const results = ruleExp.exec(ruleString); - const rule = { - env: { - l: 0, - h: 0 - }, - fer: { - l: 0, - h: 0 - } - }; - - // environment - var env = results[1]; - if (env.length >= 3) { - var envp = env.split(","); - rule.env.l = +envp[0]; - rule.env.h = +envp[1]; - } else { - rule.env.l = +env; - rule.env.h = +env; - } - - // fertility - var fer = results[2]; - if (fer.length >= 3) { - var ferp = fer.split(","); - rule.fer.l = +ferp[0]; - rule.fer.h = +ferp[1]; - } else { - rule.fer.l = +fer; - rule.fer.h = +fer; - } - return rule; - } -}; - -function hslToRgb(h, s, l, a) { - var r, g, b; - - if (s == 0) { - r = g = b = l; // achromatic - } else { - var q = l < 0.5 ? l * (1 + s) : l + s - l * s; - var p = 2 * l - q; - r = hue2rgb(p, q, h + 1 / 3); - g = hue2rgb(p, q, h); - b = hue2rgb(p, q, h - 1 / 3); - } - - if (arguments.length == 3) { - return ( - "rgb(" + - Math.floor(r * 255) + - "," + - Math.floor(g * 255) + - "," + - Math.floor(b * 255) + - ")" - ); - } - if (arguments.length == 4) { - return ( - "rgba(" + - Math.floor(r * 255) + - "," + - Math.floor(g * 255) + - "," + - Math.floor(b * 255) + - ", " + - a + - ")" - ); - } -} - -function hue2rgb(p, q, t) { - if (t < 0) { - t += 1; - } - if (t > 1) { - t -= 1; - } - if (t < 1 / 6) { - return p + (q - p) * 6 * t; - } - if (t < 1 / 2) { - return q; - } - if (t < 2 / 3) { - return p + (q - p) * (2 / 3 - t) * 6; - } - return p; -} diff --git a/src/application/setup-grandiose.js b/src/application/setup-grandiose.js deleted file mode 100644 index 874b8e2c8..000000000 --- a/src/application/setup-grandiose.js +++ /dev/null @@ -1,37 +0,0 @@ -/* globals __dirname */ - -import store from "./worker/store/index"; - -let grandiose = undefined; - -export default function setupGrandiose() { - if (grandiose === undefined) { - /* eslint-disable */ - __dirname = `${__dirname}/node_modules/grandiose`; - __dirname = __dirname.replace("app.asar", "app.asar.unpacked"); - /* eslint-enable */ - - try { - grandiose = require("grandiose"); - } catch (error) { - if (error.message.includes("libndi.so")) { - store.dispatch("errors/createMessage", { - message: - "libndi is not installed, please see \"Ubuntu/Debian\" in the modV README." - }); - } else { - console.error(error); - } - } - - // eslint-disable-next-line - __dirname = __dirname.replace("/node_modules/grandiose", ""); - } - - // Make sure to set grandiose to undefined as it will be an empty object otherwise - if (!grandiose.isSupportedCPU) { - grandiose = undefined; - } - - return grandiose; -} diff --git a/src/application/worker/store/index.js b/src/application/worker/store/index.js deleted file mode 100644 index a1583374e..000000000 --- a/src/application/worker/store/index.js +++ /dev/null @@ -1,37 +0,0 @@ -import Vue from "vue"; -import Vuex from "vuex"; -import createPersistedState from "vuex-persistedstate"; - -const requireModule = require.context("./modules/", false, /\.js$/); -const modules = {}; - -const moduleKeys = requireModule.keys(); -for (let i = 0, len = moduleKeys.length; i < len; i++) { - const moduleName = moduleKeys[i]; - - modules[moduleName.replace(/(\.\/|\.js)/g, "")] = requireModule( - moduleName - ).default; -} - -Vue.use(Vuex); - -const plugins = []; - -// createPersistedState doesn't work in the worker store, so don't run it there. -// That's okay as the worker doesn't need to know about mediaStream. -// If we want other persisted items that the worker needs to know about -// we'll need to implement something more complex to commit via postMessage. -if (self.document !== undefined) { - const dataState = createPersistedState({ - paths: ["mediaStream"] - }); - - plugins.push(dataState); -} - -export default new Vuex.Store({ - modules, - plugins, - strict: false -}); diff --git a/src/background/background-constants.js b/src/background/background-constants.js deleted file mode 100644 index f7df46d58..000000000 --- a/src/background/background-constants.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - APP_SCHEME: "app" -}; diff --git a/src/background/background.js b/src/background/background.js deleted file mode 100644 index 592a2562c..000000000 --- a/src/background/background.js +++ /dev/null @@ -1,95 +0,0 @@ -import { app, ipcMain, protocol } from "electron"; -import { APP_SCHEME } from "./background-constants"; -import { getMediaManager } from "./media-manager"; -import { openFile } from "./open-file"; -import { createWindow } from "./windows"; - -require("@electron/remote/main").initialize(); - -const isDevelopment = process.env.NODE_ENV !== "production"; - -// Scheme must be registered before the app is ready -protocol.registerSchemesAsPrivileged([ - { - scheme: APP_SCHEME, - privileges: { - secure: true, - standard: true - } - } -]); - -app.on("open-file", (event, filePath) => { - event.preventDefault(); - - openFile(filePath); -}); - -// Quit when all windows are closed. -app.on("window-all-closed", () => { - // On macOS it is common for applications and their menu bar - // to stay active until the user quits explicitly with Cmd + Q - if (process.platform !== "darwin") { - app.quit(); - } -}); - -app.on("activate", async () => { - // On macOS it's common to re-create a window in the app when the - // dock icon is clicked and there are no other windows open. - createWindow({ windowName: "mainWindow" }); -}); - -// https://stackoverflow.com/a/66673831 -function fileHandler(req, callback) { - const { mediaDirectoryPath } = getMediaManager(); - const requestedPath = req.url.substr(7); - // Write some code to resolve path, calculate absolute path etc - const check = requestedPath.indexOf(mediaDirectoryPath) > -1; - - if (!check) { - callback({ - // -6 is FILE_NOT_FOUND - // https://source.chromium.org/chromium/chromium/src/+/master:net/base/net_error_list.h - error: -6 - }); - return; - } - - callback({ - path: requestedPath - }); -} - -// This method will be called when Electron has finished -// initialization and is ready to create browser windows. -// Some APIs can only be used after this event occurs. -app.on("ready", async () => { - protocol.registerFileProtocol("modv", fileHandler); - - app.commandLine.appendSwitch( - "disable-backgrounding-occluded-windows", - "true" - ); - - createWindow({ windowName: "mainWindow" }); - ipcMain.once("main-window-created", () => { - createWindow({ windowName: "splashScreen" }); - createWindow({ windowName: "colorPicker", options: { show: false } }); - }); -}); - -// Exit cleanly on request from parent process in development mode. -if (isDevelopment) { - if (process.platform === "win32") { - process.on("message", data => { - if (data === "graceful-exit") { - app.quit(); - } - }); - } else { - process.on("SIGTERM", () => { - app.quit(); - }); - } -} diff --git a/src/components/CollapsibleRow.vue b/src/components/CollapsibleRow.vue deleted file mode 100644 index 53075f4bd..000000000 --- a/src/components/CollapsibleRow.vue +++ /dev/null @@ -1,59 +0,0 @@ - - - - - diff --git a/src/components/InputDeviceConfig/NDI.vue b/src/components/InputDeviceConfig/NDI.vue deleted file mode 100644 index 010c595fe..000000000 --- a/src/components/InputDeviceConfig/NDI.vue +++ /dev/null @@ -1,146 +0,0 @@ - - - - - diff --git a/src/components/directives/ContextMenu.js b/src/components/directives/ContextMenu.js deleted file mode 100644 index 9ba7fe6d6..000000000 --- a/src/components/directives/ContextMenu.js +++ /dev/null @@ -1,23 +0,0 @@ -import { Menu } from "@electron/remote"; -import Vue from "vue"; - -function openContextMenu(e, template) { - const { clientX: x, clientY: y } = e; - - if (template) { - const menu = Menu.buildFromTemplate(template); - menu.popup({ x, y }); - } -} - -Vue.directive("contextMenu", { - inserted(el, { value: template }) { - el.addEventListener("contextmenu", async e => - openContextMenu(e, await template()) - ); - }, - - unbind() { - // el.removeEventListener("click", e => openContextMenu(e, template)); - } -}); diff --git a/src/components/directives/InfoView.js b/src/components/directives/InfoView.js deleted file mode 100644 index 16c4e36ac..000000000 --- a/src/components/directives/InfoView.js +++ /dev/null @@ -1,41 +0,0 @@ -import Vue from "vue"; - -const INFO_VIEW_ID_VAR = "$iVID"; - -function mouseover(id, $store) { - return () => { - $store.dispatch("infoView/setFocused", { - id - }); - }; -} - -Vue.directive("infoView", { - // When the bound element is inserted into the DOM... - async inserted(el, binding, vnode) { - const { value } = binding; - const { - context: { $store } - } = vnode; - - const id = await $store.dispatch("infoView/addDictionaryItem", { - id: value.id, - title: value.title, - body: value.body - }); - - vnode[INFO_VIEW_ID_VAR] = id; - - el.addEventListener("mouseover", mouseover(id, $store), true); - }, - - async unbind(el, binding, vnode) { - const { - context: { $store } - } = vnode; - - await $store.dispatch("infoView/removeDictionaryItem", { - id: vnode[INFO_VIEW_ID_VAR] - }); - } -}); diff --git a/src/components/directives/Search.js b/src/components/directives/Search.js deleted file mode 100644 index 9b0013753..000000000 --- a/src/components/directives/Search.js +++ /dev/null @@ -1,30 +0,0 @@ -import Vue from "vue"; - -const SEARCH_ID_VAR = "$searchId"; - -Vue.directive("searchTerms", { - // When the bound element is inserted into the DOM... - async inserted(el, binding, vnode) { - const { value } = binding; - const { - context: { $store } - } = vnode; - - const id = await $store.dispatch("search/addTerms", { - ...value - }); - - vnode[SEARCH_ID_VAR] = id; - el.setAttribute("data-searchId", id); - }, - - async unbind(el, binding, vnode) { - const { - context: { $store } - } = vnode; - - await $store.dispatch("search/removeId", { - id: vnode[SEARCH_ID_VAR] - }); - } -}); diff --git a/src/components/inputs/Number.vue b/src/components/inputs/Number.vue deleted file mode 100644 index 995b86a6f..000000000 --- a/src/components/inputs/Number.vue +++ /dev/null @@ -1,44 +0,0 @@ - - - - - diff --git a/src/components/inputs/index.js b/src/components/inputs/index.js deleted file mode 100644 index eac216ef4..000000000 --- a/src/components/inputs/index.js +++ /dev/null @@ -1,16 +0,0 @@ -import Vue from "vue"; -import Button from "./Button.vue"; -import Checkbox from "./Checkbox.vue"; -import Number from "./Number.vue"; -import Range from "./Range.vue"; -import Select from "./Select.vue"; -import Textarea from "./Textarea.vue"; -import TextInput from "./TextInput.vue"; - -Vue.component("Button", Button); -Vue.component("Checkbox", Checkbox); -Vue.component("Number", Number); -Vue.component("Range", Range); -Vue.component("Select", Select); -Vue.component("Textarea", Textarea); -Vue.component("TextInput", TextInput); diff --git a/src/main.js b/src/main.js deleted file mode 100644 index 92744c6ad..000000000 --- a/src/main.js +++ /dev/null @@ -1,59 +0,0 @@ -import Vue from "vue"; -import vgl from "vue-golden-layout"; -import { ipcRenderer } from "electron"; -import get from "lodash.get"; -import Fragment from "vue-fragment"; - -import "./components/inputs"; -import ElectronLink from "./components/ElectronLink"; -import "./components/directives/InfoView"; -import "./components/directives/Search"; -import "./components/directives/ValueTooltip"; -import "./components/directives/ContextMenu"; - -import App from "./App.vue"; -import modV from "./application"; -import store from "./ui-store"; - -Vue.config.ignoredElements = ["grid", "c"]; -Vue.config.productionTip = false; -Vue.use(vgl); -Vue.use(Fragment.Plugin); -Vue.component("ElectronLink", ElectronLink); - -window.modV = modV; - -Object.defineProperty(Vue.prototype, "$modV", { - get() { - return modV; - } -}); - -window.Vue = new Vue({ - render: h => h(App), - store -}); - -// For Playwright -window._get = get; - -async function start() { - ipcRenderer.send("main-window-created"); - const loadingElement = document.getElementById("loading"); - - // eslint-disable-next-line no-for-each/no-for-each - "loading".split("").forEach((char, index) => { - const span = document.createElement("span"); - span.textContent = char; - span.style = `animation-delay: ${index * 60}ms`; - loadingElement.appendChild(span); - }); - - modV.setup(); - await modV.ready; - - loadingElement.remove(); - window.Vue.$mount("#app"); -} - -start(); diff --git a/src/main/background-constants.js b/src/main/background-constants.js new file mode 100644 index 000000000..8a093e373 --- /dev/null +++ b/src/main/background-constants.js @@ -0,0 +1 @@ +export const APP_SCHEME = "modv"; diff --git a/src/background/check-media-permission.js b/src/main/check-media-permission.js similarity index 100% rename from src/background/check-media-permission.js rename to src/main/check-media-permission.js diff --git a/src/main/index.js b/src/main/index.js new file mode 100644 index 000000000..90fba07d4 --- /dev/null +++ b/src/main/index.js @@ -0,0 +1,130 @@ +import { MessageChannelMain, app, ipcMain, net, protocol } from "electron"; +import { APP_SCHEME } from "./background-constants"; +import { openFile } from "./open-file"; +import { createWindow } from "./windows"; + +require("@electron/remote/main").initialize(); + +app.commandLine.appendSwitch("max-active-webgl-contexts", 6); + +const isDevelopment = process.env.NODE_ENV !== "production"; + +// Scheme must be registered before the app is ready +protocol.registerSchemesAsPrivileged([ + { + scheme: APP_SCHEME, + privileges: { + secure: true, + standard: true, + stream: true, + supportFetchAPI: true, + bypassCSP: true, + }, + }, +]); + +app.on("open-file", (event, filePath) => { + event.preventDefault(); + + openFile(filePath); +}); + +// Quit when all windows are closed. +app.on("window-all-closed", () => { + // On macOS it is common for applications and their menu bar + // to stay active until the user quits explicitly with Cmd + Q + if (process.platform !== "darwin") { + app.quit(); + } +}); + +app.on("activate", async () => { + // On macOS it's common to re-create a window in the app when the + // dock icon is clicked and there are no other windows open. + createWindow({ windowName: "mainWindow" }); +}); + +function setupColorPickerUIMessageChannels(mainWindow, colorPickerWindow) { + const { + port1: colorPickerUIChannel_mainWindowPort, + port2: colorPickerUIChannel_colorPickerPort, + } = new MessageChannelMain(); + + mainWindow.webContents.postMessage("port:colorPickerUI", null, [ + colorPickerUIChannel_mainWindowPort, + ]); + + colorPickerWindow.webContents.postMessage("port:colorPickerUI", null, [ + colorPickerUIChannel_colorPickerPort, + ]); + + // return { + // colorPickerUIChannel_mainWindowPort: port1, + // colorPickerUIChannel_colorPickerPort: port2, + // }; +} + +// This method will be called when Electron has finished +// initialization and is ready to create browser windows. +// Some APIs can only be used after this event occurs. +app.on("ready", async () => { + protocol.handle(APP_SCHEME, (request) => { + const newPath = + "file://" + + new URL("http://modv.com/" + request.url.slice(`${APP_SCHEME}://`.length)) + .pathname; + + return net.fetch(newPath); + }); + + app.commandLine.appendSwitch( + "disable-backgrounding-occluded-windows", + "true", + ); + + const mainWindow = createWindow({ windowName: "mainWindow" }); + ipcMain.once("main-window-created", () => { + createWindow({ windowName: "splashScreen" }); + + /////// color picker + + const { + port1: colorPickerMainChannel_mainPort, + port2: colorPickerMainChannel_colorPickerPort, + } = new MessageChannelMain(); + + colorPickerMainChannel_mainPort.on("message", (e) => { + if (e.data === "create-port:colorPickerUI") { + setupColorPickerUIMessageChannels(mainWindow, colorPickerWindow); + } + }); + + const colorPickerWindow = createWindow({ + windowName: "colorPicker", + options: { show: false }, + }); + + colorPickerWindow.once("ready-to-show", () => { + setupColorPickerUIMessageChannels(mainWindow, colorPickerWindow); + + colorPickerWindow.webContents.postMessage("port:colorPickerMain", null, [ + colorPickerMainChannel_colorPickerPort, + ]); + }); + }); +}); + +// Exit cleanly on request from parent process in development mode. +if (isDevelopment) { + if (process.platform === "win32") { + process.on("message", (data) => { + if (data === "graceful-exit") { + app.quit(); + } + }); + } else { + process.on("SIGTERM", () => { + app.quit(); + }); + } +} diff --git a/src/background/media-manager.js b/src/main/media-manager.js similarity index 90% rename from src/background/media-manager.js rename to src/main/media-manager.js index f17049696..6e5671a12 100644 --- a/src/background/media-manager.js +++ b/src/main/media-manager.js @@ -1,4 +1,4 @@ -import MediaManager from "../media-manager"; +import MediaManager from "./media-manager/index"; import { updateMenu } from "./menu-bar"; import { setProjectNames } from "./projects"; @@ -16,7 +16,7 @@ export function getMediaManager() { pathChanged(message) { window.webContents.send("media-manager-path-changed", message); - } + }, }); } diff --git a/src/media-manager/add-read-handler.js b/src/main/media-manager/add-read-handler.js similarity index 100% rename from src/media-manager/add-read-handler.js rename to src/main/media-manager/add-read-handler.js diff --git a/src/media-manager/add-save-handler.js b/src/main/media-manager/add-save-handler.js similarity index 100% rename from src/media-manager/add-save-handler.js rename to src/main/media-manager/add-save-handler.js diff --git a/src/media-manager/create-watcher.js b/src/main/media-manager/create-watcher.js similarity index 100% rename from src/media-manager/create-watcher.js rename to src/main/media-manager/create-watcher.js diff --git a/src/media-manager/fs-create-profile.js b/src/main/media-manager/fs-create-profile.js similarity index 100% rename from src/media-manager/fs-create-profile.js rename to src/main/media-manager/fs-create-profile.js diff --git a/src/media-manager/index.js b/src/main/media-manager/index.js similarity index 94% rename from src/media-manager/index.js rename to src/main/media-manager/index.js index 97800db1e..3e2a9d45e 100644 --- a/src/media-manager/index.js +++ b/src/main/media-manager/index.js @@ -37,7 +37,7 @@ export default class MediaManager { constructor(options) { const defaults = { - mediaFolderName: "media" + mediaFolderName: "media", }; this.addReadHandler = addReadHandler.bind(this); @@ -71,7 +71,7 @@ export default class MediaManager { this.addSaveHandler({ saveHandler: presetSaveHandler }); - store.subscribe(mutation => { + store.subscribe((mutation) => { if (mutation.type.split("/")[0] !== "media") { return; } else if (mutation.type === "media/SET_MEDIA_DIRECTORY_PATH") { @@ -99,7 +99,7 @@ export default class MediaManager { async start() { await store.dispatch("media/setMediaDirectoryPath", { - path: this.mediaDirectoryPath + path: this.mediaDirectoryPath, }); await this.createWatcher(); } @@ -107,7 +107,7 @@ export default class MediaManager { async reset() { await store.dispatch("resetAll"); await store.dispatch("media/setMediaDirectoryPath", { - path: this.mediaDirectoryPath + path: this.mediaDirectoryPath, }); } @@ -134,7 +134,7 @@ export default class MediaManager { if (handler.fileTypes.indexOf(fileType) < -1) { throw new Error( - `The "${what}" save handler cannot save files with a type of "${fileType}"` + `The "${what}" save handler cannot save files with a type of "${fileType}"`, ); } @@ -143,9 +143,9 @@ export default class MediaManager { this.mediaDirectoryPath, project, handler.folder, - `${name}.${fileType}` + `${name}.${fileType}`, ), - payload + payload, ); return true; diff --git a/src/media-manager/log.js b/src/main/media-manager/log.js similarity index 100% rename from src/media-manager/log.js rename to src/main/media-manager/log.js diff --git a/src/media-manager/media-manager-utils/stream-to-string.js b/src/main/media-manager/media-manager-utils/stream-to-string.js similarity index 53% rename from src/media-manager/media-manager-utils/stream-to-string.js rename to src/main/media-manager/media-manager-utils/stream-to-string.js index 185441eb2..e26a6df85 100644 --- a/src/media-manager/media-manager-utils/stream-to-string.js +++ b/src/main/media-manager/media-manager-utils/stream-to-string.js @@ -1,9 +1,9 @@ // https://stackoverflow.com/a/49428486 -module.exports = function streamToString(stream) { +export function streamToString(stream) { const chunks = []; return new Promise((resolve, reject) => { - stream.on("data", chunk => chunks.push(Buffer.from(chunk))); - stream.on("error", err => reject(err)); + stream.on("data", (chunk) => chunks.push(Buffer.from(chunk))); + stream.on("error", (err) => reject(err)); stream.on("end", () => resolve(Buffer.concat(chunks).toString("utf8"))); }); -}; +} diff --git a/src/media-manager/parse-message.js b/src/main/media-manager/parse-message.js similarity index 100% rename from src/media-manager/parse-message.js rename to src/main/media-manager/parse-message.js diff --git a/src/media-manager/read-file.js b/src/main/media-manager/read-file.js similarity index 100% rename from src/media-manager/read-file.js rename to src/main/media-manager/read-file.js diff --git a/src/media-manager/read-handlers/image.js b/src/main/media-manager/read-handlers/image.js similarity index 100% rename from src/media-manager/read-handlers/image.js rename to src/main/media-manager/read-handlers/image.js diff --git a/src/media-manager/read-handlers/isf.js b/src/main/media-manager/read-handlers/isf.js similarity index 92% rename from src/media-manager/read-handlers/isf.js rename to src/main/media-manager/read-handlers/isf.js index 4eb5e3621..e24b20433 100644 --- a/src/media-manager/read-handlers/isf.js +++ b/src/main/media-manager/read-handlers/isf.js @@ -1,12 +1,12 @@ +import { streamToString } from "../media-manager-utils/stream-to-string"; const fs = require("fs"); const path = require("path"); const util = require("util"); -const webpack = require("webpack-3"); +const webpack = require("webpack"); const readFile = util.promisify(fs.readFile); const writeFile = util.promisify(fs.writeFile); const mkdir = util.promisify(fs.mkdir); -const streamToString = require("../media-manager-utils/stream-to-string"); /** * @typedef {OutputFileContext} @@ -32,7 +32,7 @@ export default { fileTypes: [ // @todo regex match - "fs" + "fs", ], ignored: [/isf[\\/]compiled/, /isf[\\/]temp/], @@ -57,13 +57,13 @@ export default { async process({ filePath, fileName, file }) { return { filePath: await compileModule({ filePath, fileName, file }), - folder: "isf/compiled" + folder: "isf/compiled", }; - } + }, }; function compileModule({ filePath, fileName, file }) { - return new Promise(async resolve => { + return new Promise(async (resolve) => { // Default vertex shader from ISF that is used when the user didn't specify anything let vertexShader = "void main() {isf_vertShaderInit();}"; let fragmentShader; @@ -91,16 +91,16 @@ function compileModule({ filePath, fileName, file }) { name: fileName.replace(/(\.\/|\.fs)/g, ""), author: "", version: "1.0.0", - type: "isf" + type: "isf", }, fragmentShader, - vertexShader + vertexShader, }; const tempFilePath = path.join( path.dirname(filePath), "temp", - path.basename(filePath) + path.basename(filePath), ); const tempDirectoryPath = path.join(path.dirname(filePath), "temp"); @@ -119,7 +119,7 @@ function compileModule({ filePath, fileName, file }) { const compiledFilePath = path.join( path.dirname(filePath), "compiled", - path.basename(filePath) + path.basename(filePath), ); const compiledDirectoryPath = path.join(path.dirname(filePath), "compiled"); @@ -144,11 +144,11 @@ function compileModule({ filePath, fileName, file }) { output: { path: compiledDirectoryPath, filename: path.basename(filePath), - libraryTarget: "var" + libraryTarget: "var", }, resolveLoader: { - modules: ["node_modules", __dirname + "/node_modules"] - } + modules: ["node_modules", __dirname + "/node_modules"], + }, }; webpack(webpackConfig, (err, stats) => { diff --git a/src/media-manager/read-handlers/module.js b/src/main/media-manager/read-handlers/module.js similarity index 91% rename from src/media-manager/read-handlers/module.js rename to src/main/media-manager/read-handlers/module.js index 00d62df61..55312546e 100644 --- a/src/media-manager/read-handlers/module.js +++ b/src/main/media-manager/read-handlers/module.js @@ -1,5 +1,5 @@ const recursiveDeps = require("recursive-deps"); -const webpack = require("webpack-3"); +const webpack = require("webpack"); const path = require("path"); const npm = require("npm"); const fs = require("fs"); @@ -28,7 +28,7 @@ export default { fileTypes: [ // @todo regex match - "js" + "js", ], ignored: [/module[\\/]compiled/], @@ -53,9 +53,9 @@ export default { async process({ filePath }, { log }) { return { filePath: await compileModule(filePath, log), - folder: "module/compiled" + folder: "module/compiled", }; - } + }, }; const ensurePackageJson = ({ dirPath }) => { @@ -79,11 +79,11 @@ function doWebpack(filePath) { output: { path: path.join(path.dirname(filePath), "compiled"), filename: path.basename(filePath), - libraryTarget: "var" + libraryTarget: "var", }, resolveLoader: { - modules: ["node_modules", __dirname + "/node_modules"] - } + modules: ["node_modules", __dirname + "/node_modules"], + }, }; webpack(webpackConfig, (err, stats) => { @@ -100,7 +100,7 @@ function doWebpack(filePath) { // 4. update modv clients with new file contents (then eval in modv) resolve( - path.join(path.dirname(filePath), "compiled", path.basename(filePath)) + path.join(path.dirname(filePath), "compiled", path.basename(filePath)), ); }); }); @@ -114,7 +114,7 @@ async function compileModule(filePath, log) { // // Shameless clone of szymonkaliski's awesome Neutron // https://github.com/szymonkaliski/Neutron/blob/b8523e0efa3a7cc8bf5fcafc753d3d01b3c5338c/src/index.js#L54 - recursiveDeps(filePath).then(dependencies => { + recursiveDeps(filePath).then((dependencies) => { if (!dependencies.length) { resolve(doWebpack(filePath)); } @@ -130,26 +130,26 @@ async function compileModule(filePath, log) { prefix: dirPath, progress: true, save: true, - unicode: false + unicode: false, }, - err => { + (err) => { if (err) { reject(err); } npm.commands.ls(dependencies, (_, data) => { const installedDeps = Object.keys(data.dependencies).filter( - key => data.dependencies[key].missing === undefined + (key) => data.dependencies[key].missing === undefined, ); const missingDeps = dependencies.filter( - dep => installedDeps.indexOf(dep) < 0 + (dep) => installedDeps.indexOf(dep) < 0, ); if (missingDeps.length) { log("🛒 Installing", dependencies.join(", "), "for", filePath); - npm.commands.install(missingDeps, err => { + npm.commands.install(missingDeps, (err) => { if (err) { reject(err); } @@ -161,7 +161,7 @@ async function compileModule(filePath, log) { resolve(doWebpack(filePath)); } }); - } + }, ); }); }); diff --git a/src/media-manager/read-handlers/palette.js b/src/main/media-manager/read-handlers/palette.js similarity index 100% rename from src/media-manager/read-handlers/palette.js rename to src/main/media-manager/read-handlers/palette.js diff --git a/src/media-manager/read-handlers/preset.js b/src/main/media-manager/read-handlers/preset.js similarity index 100% rename from src/media-manager/read-handlers/preset.js rename to src/main/media-manager/read-handlers/preset.js diff --git a/src/media-manager/read-handlers/video.js b/src/main/media-manager/read-handlers/video.js similarity index 100% rename from src/media-manager/read-handlers/video.js rename to src/main/media-manager/read-handlers/video.js diff --git a/src/media-manager/save-handlers/preset.js b/src/main/media-manager/save-handlers/preset.js similarity index 100% rename from src/media-manager/save-handlers/preset.js rename to src/main/media-manager/save-handlers/preset.js diff --git a/src/media-manager/store/index.js b/src/main/media-manager/store/index.js similarity index 82% rename from src/media-manager/store/index.js rename to src/main/media-manager/store/index.js index 0340050f9..721282625 100644 --- a/src/media-manager/store/index.js +++ b/src/main/media-manager/store/index.js @@ -1,21 +1,18 @@ -import Vue from "vue"; -import Vuex from "vuex"; +import { createStore } from "vuex"; import readHandlers from "./modules/read-handlers"; import saveHandlers from "./modules/save-handlers"; import media from "./modules/media"; import plugins from "./modules/plugins"; -Vue.use(Vuex); - const modules = { readHandlers, saveHandlers, media, - plugins + plugins, }; -const store = new Vuex.Store({ +const store = createStore({ strict: false, modules, @@ -27,8 +24,8 @@ const store = new Vuex.Store({ commit(`${moduleKey}/RESET_STATE`); } - } - } + }, + }, }); export default store; diff --git a/src/media-manager/store/modules/media.js b/src/main/media-manager/store/modules/media.js similarity index 69% rename from src/media-manager/store/modules/media.js rename to src/main/media-manager/store/modules/media.js index 552755fb5..76121de09 100644 --- a/src/media-manager/store/modules/media.js +++ b/src/main/media-manager/store/modules/media.js @@ -1,5 +1,3 @@ -import Vue from "vue"; - function initialState() { /** * Holds processed media @@ -8,12 +6,13 @@ function initialState() { */ return { media: {}, - path: null + path: null, }; } const getters = { - projects: state => Object.keys(state.media).sort((a, b) => a.localeCompare(b)) + projects: (state) => + Object.keys(state.media).sort((a, b) => a.localeCompare(b)), }; const actions = { @@ -21,26 +20,31 @@ const actions = { commit("ADD", { project, folder, item }); }, + // only runs in modV worker async setState({ commit }, newState) { - const store = require("../index.js").default; + // const { default: store } = await import( + // "../../../../renderer/src/application/worker/store/index" + // ); commit("CLEAR_MEDIA_STATE"); - const projectKeys = Object.keys(newState); + await this.dispatch("media/setMediaDirectoryPath", { path: newState.path }); + + const projectKeys = Object.keys(newState.media); for (let i = 0, len = projectKeys.length; i < len; i++) { const projectKey = projectKeys[i]; - const folderKeys = Object.keys(newState[projectKey]); + const folderKeys = Object.keys(newState.media[projectKey]); for (let j = 0, len = folderKeys.length; j < len; j++) { const folderKey = folderKeys[j]; - const items = Object.values(newState[projectKey][folderKey]); + const items = Object.values(newState.media[projectKey][folderKey]); for (let k = 0, len = items.length; k < len; k++) { const item = items[k]; - await store.dispatch("media/addMedia", { + await this.dispatch("media/addMedia", { project: projectKey, folder: folderKey, - item + item, }); } } @@ -51,17 +55,17 @@ const actions = { setMediaDirectoryPath({ commit }, { path }) { commit("SET_MEDIA_DIRECTORY_PATH", { path }); - } + }, }; const mutations = { ADD(state, { project, folder, item }) { if (!state.media[project]) { - Vue.set(state.media, project, {}); + state.media[project] = {}; } if (!state.media[project][folder]) { - Vue.set(state.media[project], folder, {}); + state.media[project][folder] = {}; } state.media[project][folder][item.name] = item; @@ -72,7 +76,7 @@ const mutations = { for (let i = 0, len = stateMediaKeys.length; i < len; i++) { const key = stateMediaKeys[i]; - Vue.delete(state.media, key); + delete state.media[key]; } }, @@ -88,7 +92,7 @@ const mutations = { SET_MEDIA_DIRECTORY_PATH(state, { path }) { state.path = path; - } + }, }; export default { @@ -96,5 +100,5 @@ export default { state: initialState, getters, actions, - mutations + mutations, }; diff --git a/src/media-manager/store/modules/plugins.js b/src/main/media-manager/store/modules/plugins.js similarity index 81% rename from src/media-manager/store/modules/plugins.js rename to src/main/media-manager/store/modules/plugins.js index b934f89fb..aef0d027f 100644 --- a/src/media-manager/store/modules/plugins.js +++ b/src/main/media-manager/store/modules/plugins.js @@ -1,5 +1,3 @@ -import Vue from "vue"; - function initialState() { /** * Holds Plugins @@ -8,7 +6,7 @@ function initialState() { */ return { plugins: {}, - pluginData: {} + pluginData: {}, }; } @@ -16,21 +14,21 @@ const getters = {}; const actions = { addMedia({ commit }, { project, folder, item }) { - return new Promise(resolve => { + return new Promise((resolve) => { commit("ADD", { project, folder, item }); resolve(); }); - } + }, }; const mutations = { ADD(state, { project, folder, item }) { if (!state[project]) { - Vue.set(state, project, {}); + state[project] = {}; } if (!state[project][folder]) { - Vue.set(state[project], folder, []); + state[project][folder] = []; } state[project][folder].push(item); @@ -44,7 +42,7 @@ const mutations = { state[key] = s[key]; } - } + }, }; export default { @@ -52,5 +50,5 @@ export default { state: initialState, getters, actions, - mutations + mutations, }; diff --git a/src/media-manager/store/modules/read-handlers.js b/src/main/media-manager/store/modules/read-handlers.js similarity index 78% rename from src/media-manager/store/modules/read-handlers.js rename to src/main/media-manager/store/modules/read-handlers.js index 20e70762b..8225505ee 100644 --- a/src/media-manager/store/modules/read-handlers.js +++ b/src/main/media-manager/store/modules/read-handlers.js @@ -1,5 +1,3 @@ -import Vue from "vue"; - function initialState() { /** * Holds the ReadHandlers @@ -12,33 +10,33 @@ function initialState() { } const getters = { - ignored: state => + ignored: (state) => Object.values(state).reduce( (arr, folder) => arr.concat(folder.reduce((arr, rh) => arr.concat(rh.ignored), [])), - [] + [], ), - forFileType: state => (folder, type) => + forFileType: (state) => (folder, type) => state[folder] && - state[folder].filter(rh => rh.fileTypes.indexOf(type) > -1), + state[folder].filter((rh) => rh.fileTypes.indexOf(type) > -1), - folders: state => Object.keys(state) + folders: (state) => Object.keys(state), }; const actions = { addHandler({ commit }, { readHandler }) { - return new Promise(resolve => { + return new Promise((resolve) => { commit("ADD", { folder: readHandler.folder, readHandler }); resolve(); }); - } + }, }; const mutations = { ADD(state, { folder, readHandler }) { if (!state[folder]) { - Vue.set(state, folder, []); + state[folder] = []; } state[folder].push(readHandler); @@ -52,7 +50,7 @@ const mutations = { state[key] = s[key]; } - } + }, }; export default { @@ -60,5 +58,5 @@ export default { state: initialState, getters, actions, - mutations + mutations, }; diff --git a/src/media-manager/store/modules/save-handlers.js b/src/main/media-manager/store/modules/save-handlers.js similarity index 75% rename from src/media-manager/store/modules/save-handlers.js rename to src/main/media-manager/store/modules/save-handlers.js index 0bc6f9136..2fe289d91 100644 --- a/src/media-manager/store/modules/save-handlers.js +++ b/src/main/media-manager/store/modules/save-handlers.js @@ -1,5 +1,3 @@ -import Vue from "vue"; - function initialState() { /** * Holds the SaveHandler @@ -12,32 +10,32 @@ function initialState() { } const getters = { - ignored: state => + ignored: (state) => Object.values(state).reduce( (arr, folder) => arr.concat(folder.reduce((arr, sh) => arr.concat(sh.ignored), [])), - [] + [], ), - forFileType: state => (folder, type) => + forFileType: (state) => (folder, type) => state[folder] && - state[folder].filter(sh => sh.fileTypes.indexOf(type) > -1), + state[folder].filter((sh) => sh.fileTypes.indexOf(type) > -1), - folders: state => Object.keys(state) + folders: (state) => Object.keys(state), }; const actions = { addHandler({ commit }, { saveHandler }) { - return new Promise(resolve => { + return new Promise((resolve) => { commit("ADD", saveHandler); resolve(); }); - } + }, }; const mutations = { ADD(state, saveHandler) { - Vue.set(state, saveHandler.folder, saveHandler); + state[saveHandler.folder] = saveHandler; }, RESET_STATE(state) { @@ -48,7 +46,7 @@ const mutations = { state[key] = s[key]; } - } + }, }; export default { @@ -56,5 +54,5 @@ export default { state: initialState, getters, actions, - mutations + mutations, }; diff --git a/src/background/menu-bar.js b/src/main/menu-bar.js similarity index 100% rename from src/background/menu-bar.js rename to src/main/menu-bar.js diff --git a/src/background/open-file.js b/src/main/open-file.js similarity index 100% rename from src/background/open-file.js rename to src/main/open-file.js diff --git a/src/background/projects.js b/src/main/projects.js similarity index 100% rename from src/background/projects.js rename to src/main/projects.js diff --git a/src/main/window-prefs.js b/src/main/window-prefs.js new file mode 100644 index 000000000..6dab1f519 --- /dev/null +++ b/src/main/window-prefs.js @@ -0,0 +1,261 @@ +import { app, dialog, ipcMain, screen, BrowserWindow } from "electron"; +import os from "node:os"; +import { join } from "path"; + +import store from "./media-manager/store"; +// import { autoUpdater } from "electron-updater"; @TODO add back in updater +import { checkMediaPermission } from "./check-media-permission"; +import { setProjectNames, setCurrentProject } from "./projects"; +import { closeWindow, createWindow, windows } from "./windows"; +import { updateMenu } from "./menu-bar"; +import { getMediaManager } from "./media-manager"; + +const isDevelopment = process.env.NODE_ENV === "development"; +const isTest = process.env.CI === "e2e"; +let modVReady = false; + +const windowPrefs = { + colorPicker: { + devPath: "/color-picker.html", + prodPath: "color-picker.html", + options: { + webPreferences: { + preload: join(__dirname, "../preload/colorPicker.js"), + contextIsolation: false, + nodeIntegration: false, + }, + transparent: true, + frame: false, + alwaysOnTop: true, + resizable: false, + skipTaskbar: true, + fullscreenable: false, + }, + unique: true, + create(window) { + window.on("close", (e) => { + e.preventDefault(); + + window.hide(); + }); + + window.on("blur", () => { + window.hide(); + }); + }, + }, + + mainWindow: { + devPath: "/index.html", + prodPath: "index.html", + options: { + show: isDevelopment, + webPreferences: { + preload: join(__dirname, "../preload/index.js"), + enableRemoteModule: true, + // electron 12 sets contextIsolation to true by default, this breaks modV + contextIsolation: false, + nodeIntegration: true, + nodeIntegrationInWorker: true, + nativeWindowOpen: true, // window.open return Window object(like in regular browsers), not BrowserWindowProxy + affinity: "main-window", // main window, and additional windows should work in one process + }, + }, + unique: true, + + beforeCreate() { + const { width, height } = screen.getPrimaryDisplay().workAreaSize; + + modVReady = false; + + return { + options: { + width, + height, + }, + }; + }, + + /** + * @param {Electron.BrowserWindow} window + */ + async create(window) { + require("@electron/remote/main").enable(window.webContents); + + ipcMain.handle("is-modv-ready", () => modVReady); + + window.setRepresentedFilename(os.homedir()); + window.setDocumentEdited(true); + window.setTitle("Untitled"); + + window.webContents.on("did-finish-load", () => { + window.setTitle("Untitled"); + }); + + // Configure child windows to open without a menubar (windows/linux) + window.webContents.on( + "new-window", + (event, url, frameName, disposition, options) => { + if (frameName === "modal") { + event.preventDefault(); + event.newGuest = new BrowserWindow({ + ...options, + autoHideMenuBar: true, + closable: false, + enableLargerThanScreen: true, + title: "", + }); + + event.newGuest.removeMenu(); + } + }, + ); + + const mm = getMediaManager(); + + mm.update = (message) => { + window.webContents.send("media-manager-update", message); + + setProjectNames(mm.$store.getters["media/projects"]); + updateMenu(); + }; + + mm.pathChanged = (message) => { + window.webContents.send("media-manager-path-changed", message); + }; + + ipcMain.on("open-window", (event, message) => { + createWindow({ windowName: message }, event); + }); + + ipcMain.on("close-window", (event, message) => { + closeWindow({ windowName: message }); + }); + + ipcMain.on("modv-ready", () => { + modVReady = true; + mm.start(); + }); + + ipcMain.on("modv-destroy", () => { + mm.reset(); + }); + + ipcMain.on("get-media-manager-state", (event) => { + event.reply( + "media-manager-state", + JSON.parse(JSON.stringify(store.state.media)), + ); + }); + + ipcMain.on("save-file", async (event, message) => { + try { + mm.saveFile(message); + } catch (e) { + event.reply("save-file", e); + } + + event.reply("save-file", "saved"); + }); + + ipcMain.on("current-project", (event, message) => { + setCurrentProject(message); + updateMenu(); + }); + + ipcMain.on("input-update", (event, message) => { + window.webContents.send("input-update", message); + }); + + window.on("close", async (e) => { + // 0 because this is the position of the buttons + // in the dialog's buttons array + let shouldQuit = 0; + + if (!isDevelopment && !isTest) { + const { response } = await dialog.showMessageBox(window, { + type: "question", + buttons: ["Yes", "No"], + message: "modV", + detail: "Are you sure you want to quit?", + }); + + shouldQuit = response; + } + + if (shouldQuit === 0) { + console.log("main sending webcontents modv-destroy"); + const workerDestruction = new Promise((resolve) => { + ipcMain.on("destroyed", resolve); + }); + + window.webContents.send("modv-destroy"); + + await workerDestruction; + + if (!isDevelopment && !isTest) { + e.preventDefault(); + // Use .exit instead of .quit to prevent close event firing again. + // Usually .quit would be preferable, but since we only have one + // instance of the main window we can just exit. + app.exit(); + } + } + }); + + // Check for updates + // autoUpdater.checkForUpdatesAndNotify(); + + if (process.platform !== "linux") { + await checkMediaPermission(); + } + }, + + destroy() { + ipcMain.removeAllListeners("open-window"); + ipcMain.removeAllListeners("modv-ready"); + ipcMain.removeAllListeners("modv-destroy"); + ipcMain.removeAllListeners("get-media-manager-state"); + ipcMain.removeAllListeners("save-file"); + ipcMain.removeAllListeners("current-project"); + ipcMain.removeAllListeners("input-update"); + ipcMain.removeHandler("is-modv-ready"); + }, + }, + + splashScreen: { + devPath: "/splash-screen.html", + prodPath: "splash-screen.html", + options: { + show: !isDevelopment, + webPreferences: { + nodeIntegration: true, + }, + transparent: true, + frame: false, + resizable: false, + skipTaskbar: true, + fullscreenable: false, + center: true, + movable: false, + backgroundColor: "#00000000", + hasShadow: false, + width: 600, + height: 600, + }, + unique: true, + + async create(window) { + ipcMain.on("modv-ready", () => { + try { + window.close(); + } catch (e) { + console.error(e); + } + windows["mainWindow"].maximize(); + }); + }, + }, +}; + +export { windowPrefs }; diff --git a/src/background/windows.js b/src/main/windows.js similarity index 77% rename from src/background/windows.js rename to src/main/windows.js index d23e911e0..d301eda5a 100644 --- a/src/background/windows.js +++ b/src/main/windows.js @@ -1,9 +1,10 @@ import { BrowserWindow } from "electron"; -import { createProtocol } from "vue-cli-plugin-electron-builder/lib"; -import { APP_SCHEME } from "./background-constants"; +import { is } from "@electron-toolkit/utils"; import { updateMenu } from "./menu-bar"; import { windowPrefs } from "./window-prefs"; +const path = require("path"); + const windows = {}; function createWindow({ windowName, options = {} }, event) { @@ -14,7 +15,7 @@ function createWindow({ windowName, options = {} }, event) { if (event) { event.reply("window-ready", { id: windows[windowName].webContents.id, - window: windowName + window: windowName, }); } @@ -31,7 +32,7 @@ function createWindow({ windowName, options = {} }, event) { // Create the browser window. windows[windowName] = new BrowserWindow({ ...windowOptions, - ...options + ...options, }); updateMenu(true); @@ -40,19 +41,18 @@ function createWindow({ windowName, options = {} }, event) { windowPrefs[windowName].create(windows[windowName]); } - if (process.env.WEBPACK_DEV_SERVER_URL) { + if (is.dev && process.env["ELECTRON_RENDERER_URL"]) { // Load the url of the dev server if in development mode windows[windowName].loadURL( - process.env.WEBPACK_DEV_SERVER_URL + windowPrefs[windowName].devPath + process.env["ELECTRON_RENDERER_URL"] + windowPrefs[windowName].devPath, ); if (!process.env.IS_TEST) { - windows[windowName].webContents.openDevTools(); + // windows[windowName].webContents.openDevTools(); } } else { - createProtocol(APP_SCHEME); // Load the index.html when not in development - windows[windowName].loadURL( - `${APP_SCHEME}://./${windowPrefs[windowName].prodPath}` + windows[windowName].loadFile( + path.join(__dirname, `../renderer/${windowPrefs[windowName].prodPath}`), ); } @@ -68,10 +68,12 @@ function createWindow({ windowName, options = {} }, event) { windows[windowName].webContents.once("dom-ready", () => { event.reply("window-ready", { id: windows[windowName].webContents.id, - window: windowName + window: windowName, }); }); } + + return windows[windowName]; } function closeWindow({ windowName }) { diff --git a/src/preload/colorPicker.js b/src/preload/colorPicker.js new file mode 100644 index 000000000..a7f1973d8 --- /dev/null +++ b/src/preload/colorPicker.js @@ -0,0 +1,24 @@ +import { ipcRenderer } from "electron"; + +let mainPort = null; + +ipcRenderer.on("port:colorPickerMain", (e) => { + mainPort = e.ports[0]; + + mainPort.postMessage("create-port:colorPickerUI"); +}); + +ipcRenderer.on("port:colorPickerUI", (e) => { + // colorPicker got port from main + + if (window.electronMessagePort) { + // colorpicker closed existing port + window.electronMessagePort.close(); + } + + // port received, make it globally available. + window.electronMessagePort = e.ports[0]; + + // Tell the renderer window we have the port, so it can attach listeners, etc. + window.postMessage("port:colorPickerUI", null); +}); diff --git a/src/preload/index.js b/src/preload/index.js new file mode 100644 index 000000000..8bb89675f --- /dev/null +++ b/src/preload/index.js @@ -0,0 +1,40 @@ +import { contextBridge } from "electron"; +import { electronAPI } from "@electron-toolkit/preload"; +import * as remote from "@electron/remote"; +const { vibrate } = require("hapticjs"); + +// Custom APIs for renderer +const api = { + vibrate, +}; + +// Use `contextBridge` APIs to expose Electron APIs to +// renderer only if context isolation is enabled, otherwise +// just add to the DOM global. +if (process.contextIsolated) { + try { + contextBridge.exposeInMainWorld("electron", electronAPI); + contextBridge.exposeInMainWorld("api", api); + contextBridge.exposeInMainWorld("remote", remote); + } catch (error) { + console.error(error); + } +} else { + window.electron = electronAPI; + window.remote = remote; + window.api = api; +} + +const { ipcRenderer } = require("electron"); + +ipcRenderer.on("port:colorPickerUI", (e) => { + // mainwindow got port from main + + if (window.electronMessagePort) { + // mainwindow closed existing port + window.electronMessagePort.close(); + } + + // port received, make it globally available. + window.electronMessagePort = e.ports[0]; +}); diff --git a/src/renderer/color-picker.html b/src/renderer/color-picker.html new file mode 100644 index 000000000..fa8122ab1 --- /dev/null +++ b/src/renderer/color-picker.html @@ -0,0 +1,18 @@ + + + + + + + + + + + +
+
+ + + + \ No newline at end of file diff --git a/src/renderer/index.html b/src/renderer/index.html new file mode 100644 index 000000000..a4b2e29e6 --- /dev/null +++ b/src/renderer/index.html @@ -0,0 +1,17 @@ + + + + + + + + Untitled + + + +
+
+ + + + \ No newline at end of file diff --git a/src/renderer/output-window.html b/src/renderer/output-window.html new file mode 100644 index 000000000..6e0066925 --- /dev/null +++ b/src/renderer/output-window.html @@ -0,0 +1,26 @@ + + + + + + + + + + + + diff --git a/src/renderer/splash-screen.html b/src/renderer/splash-screen.html new file mode 100644 index 000000000..4b9ddd0ff --- /dev/null +++ b/src/renderer/splash-screen.html @@ -0,0 +1,18 @@ + + + + + + + + + + + +
+
+ + + + \ No newline at end of file diff --git a/src/renderer/src/App.vue b/src/renderer/src/App.vue new file mode 100644 index 000000000..d629fc7a8 --- /dev/null +++ b/src/renderer/src/App.vue @@ -0,0 +1,612 @@ + + + + + + + + + + + + + diff --git a/src/application/constants.js b/src/renderer/src/application/constants.js similarity index 98% rename from src/application/constants.js rename to src/renderer/src/application/constants.js index 70bc9eb68..e4f5b8915 100644 --- a/src/application/constants.js +++ b/src/renderer/src/application/constants.js @@ -13,7 +13,7 @@ export default { get AUDIO_BUFFER_SIZE() { return 512; - } + }, }; export const GROUP_DISABLED = 0; diff --git a/src/application/createWebcodecVideo.js b/src/renderer/src/application/createWebcodecVideo.js similarity index 91% rename from src/application/createWebcodecVideo.js rename to src/renderer/src/application/createWebcodecVideo.js index 8002fc739..186c4533b 100644 --- a/src/application/createWebcodecVideo.js +++ b/src/renderer/src/application/createWebcodecVideo.js @@ -1,5 +1,5 @@ export function createWebcodecVideo({ id, url, textureDefinition }) { - return new Promise(async (resolve, reject) => { + return new Promise((resolve, reject) => { const video = document.createElement("video"); video.setAttribute("crossorigin", "anonymous"); video.setAttribute("loop", true); @@ -23,9 +23,9 @@ export function createWebcodecVideo({ id, url, textureDefinition }) { id, stream: frameStream, width: video.videoWidth || 256, - height: video.videoHeight || 256 + height: video.videoHeight || 256, }, - [frameStream] + [frameStream], ); resolve({ id, video, stream }); diff --git a/src/application/index.js b/src/renderer/src/application/index.js similarity index 77% rename from src/application/index.js rename to src/renderer/src/application/index.js index f9d24a4e1..a2bed85f4 100644 --- a/src/application/index.js +++ b/src/renderer/src/application/index.js @@ -1,14 +1,15 @@ import PromiseWorker from "promise-worker-transferable"; -import Vue from "vue"; -import { ipcRenderer } from "electron"; -import { app } from "@electron/remote"; +import { reactive } from "vue"; import { createWebcodecVideo } from "./createWebcodecVideo"; +const { app } = window.remote; +const { ipcRenderer } = window.electron; + import { setupMedia, enumerateDevices, getByteFrequencyData, - getByteTimeDomainData + getByteTimeDomainData, } from "./setup-media"; import setupBeatDetektor from "./setup-beat-detektor"; import setupMidi from "./setup-midi"; @@ -16,6 +17,7 @@ import store from "./worker/store"; import windowHandler from "./window-handler"; import use from "./use"; import { GROUP_ENABLED } from "./constants"; +import ModVWorker from "./worker/index.worker.js?worker"; let imageBitmap; const imageBitmapQueue = []; @@ -31,7 +33,7 @@ class ModV { createWebcodecVideo = createWebcodecVideo; use = use; debug = false; - features = Vue.observable({ + features = reactive({ energy: 0, rms: 0, zcr: 0, @@ -43,31 +45,29 @@ class ModV { spectralSkewness: 0, spectralKurtosis: 0, perceptualSpread: 0, - perceptualSharpness: 0 + perceptualSharpness: 0, }); videos = {}; _store = store; store = { - state: store.state + state: store.state, }; constructor() { let resolver = null; - this.ready = new Promise(resolve => { + this.ready = new Promise((resolve) => { resolver = resolve; }); - this.$worker = new Worker( - new URL("./worker/index.worker.js", import.meta.url) - ); + this.$worker = new ModVWorker(); this.$asyncWorker = new PromiseWorker(this.$worker); this.$worker.postMessage({ type: "__dirname", - payload: app.getAppPath() + payload: app.getAppPath(), }); - this.$worker.addEventListener("message", async e => { + this.$worker.addEventListener("message", async (e) => { const message = e.data; const { type } = message; @@ -81,16 +81,23 @@ class ModV { // console.log(`⚙️%c ${type}`, "color: red"); // } + if (type === "destroyed") { + console.log("webcontents got destroyed, sending onto main"); + ipcRenderer.send("destroyed"); + return; + } + if (type === "createWebcodecVideo") { const videoContext = await this.createWebcodecVideo(message); this.videos[videoContext.id] = videoContext; + return; } if (type === "removeWebcodecVideo") { const { video, stream } = this.videos[message.id]; video.src = ""; // eslint-disable-next-line no-for-each/no-for-each - stream.getTracks().forEach(track => track.stop()); + stream.getTracks().forEach((track) => track.stop()); delete this.videos[message.id]; } @@ -100,8 +107,17 @@ class ModV { } if (type === "worker-setup-complete") { + // Make the default group + this.store.dispatch("groups/createGroup", { enabled: GROUP_ENABLED }); + + this.store.dispatch("osc/createServer", { + host: "0.0.0.0", + port: 3333, + }); + resolver(); ipcRenderer.send("modv-ready"); + return; } if (Array.isArray(message)) { @@ -130,9 +146,9 @@ class ModV { { type: "commit", identifier: args[0], - payload: args[1] + payload: args[1], }, - args[2] + args[2], ); }, @@ -142,16 +158,13 @@ class ModV { __async: true, type: "dispatch", identifier: args[0], - payload: args[1] + payload: args[1], }, - args[2] + args[2], ); - } + }, }; - // Make the default group - this.store.dispatch("groups/createGroup", { enabled: GROUP_ENABLED }); - window.addEventListener("beforeunload", () => true); } @@ -186,9 +199,9 @@ class ModV { { type: "canvas", where: "output", - payload: offscreen + payload: offscreen, }, - [offscreen] + [offscreen], ); this.store.dispatch("windows/createWindow"); @@ -217,7 +230,7 @@ class ModV { await this.store.dispatch("projects/setCurrentProject", message); ipcRenderer.send( "current-project", - this.store.state.projects.currentProject + this.store.state.projects.currentProject, ); }); @@ -225,19 +238,45 @@ class ModV { this.store.dispatch("windows/createWindow"); }); - ipcRenderer.on("input-update", (event, { moduleId, prop, data }) => { - this.store.dispatch("modules/updateProp", { - moduleId, - prop, - data + ipcRenderer.on("modv-destroy", (event, message) => { + console.log("webcontents got modv-destroy, sending onto worker"); + + this.$worker.postMessage({ + type: "modv-destroy", }); }); + function messageHandler({ data: messageData }) { + if (messageData.type === "input-update") { + const { moduleId, prop, data } = messageData.payload; + this.store.dispatch("modules/updateProp", { + moduleId, + prop, + data, + }); + } + } + + window.electronMessagePort?.start(); + window.electronMessagePort?.addEventListener( + "message", + messageHandler.bind(this), + ); + ipcRenderer.send("get-media-manager-state"); window.addEventListener("beforeunload", () => { + this.$worker.postMessage({ + type: "modv-destroy", + }); ipcRenderer.send("modv-destroy"); }); + + import.meta.hot.on("vite:beforeFullReload", () => { + this.$worker.postMessage({ + type: "modv-destroy", + }); + }); } async inputLoop() { @@ -267,7 +306,7 @@ class ModV { const bitmap = imageBitmapQueue.splice(0, 1)[0]; this.$worker.postMessage({ type: "videoFrame", payload: bitmap }, [ - bitmap + bitmap, ]); } } @@ -275,13 +314,13 @@ class ModV { loop(delta) { const { - meyda: { features: featuresToGet } + meyda: { features: featuresToGet }, } = this.store.state; const features = this.meyda?.get(featuresToGet); if (features) { - this.updateBeatDetektor(delta, features); + this.updateBeatDetektor && this.updateBeatDetektor(delta, features); features.byteFrequencyData = Array.from(getByteFrequencyData() || []); features.byteTimeDomainData = Array.from(getByteTimeDomainData() || []); this.$worker.postMessage({ type: "meyda", payload: features }); @@ -305,7 +344,7 @@ class ModV { async generatePreset() { return await this.$asyncWorker.postMessage({ __async: true, - type: "generatePreset" + type: "generatePreset", }); } diff --git a/src/application/install-plugin.js b/src/renderer/src/application/install-plugin.js similarity index 84% rename from src/application/install-plugin.js rename to src/renderer/src/application/install-plugin.js index 67be0c4fa..d4662c427 100644 --- a/src/application/install-plugin.js +++ b/src/renderer/src/application/install-plugin.js @@ -1,6 +1,6 @@ import store from "./worker/store"; import uiStore from "../ui-store"; -import Vue from "vue"; +import { app } from "../main"; function camelize(str) { return str.replace(/(?:^\w|[A-Z]|\b\w|\s+)/g, (match, index) => { @@ -29,17 +29,17 @@ export default function installPlugin(plugin) { } if ("galleryTabComponent" in plugin) { - Vue.component(plugin.galleryTabComponent.name, plugin.galleryTabComponent); + app.component(plugin.galleryTabComponent.name, plugin.galleryTabComponent); } if ("controlPanelComponent" in plugin) { - Vue.component( + app.component( plugin.controlPanelComponent.name, - plugin.controlPanelComponent + plugin.controlPanelComponent, ); } if ("install" in plugin) { - plugin.install(Vue, store, uiStore); + plugin.install(app, store, uiStore); } } diff --git a/src/application/plugins/feature-assignment/index.js b/src/renderer/src/application/plugins/feature-assignment/index.js similarity index 96% rename from src/application/plugins/feature-assignment/index.js rename to src/renderer/src/application/plugins/feature-assignment/index.js index 2010bd47a..4ff6964ed 100644 --- a/src/application/plugins/feature-assignment/index.js +++ b/src/renderer/src/application/plugins/feature-assignment/index.js @@ -28,11 +28,11 @@ export default { store.dispatch("modules/updateProp", { moduleId, prop, - data: featureData + data: featureData, }); } } } } - } + }, }; diff --git a/src/application/plugins/feature-assignment/store.js b/src/renderer/src/application/plugins/feature-assignment/store.js similarity index 93% rename from src/application/plugins/feature-assignment/store.js rename to src/renderer/src/application/plugins/feature-assignment/store.js index 8280e0204..605ef6af7 100644 --- a/src/application/plugins/feature-assignment/store.js +++ b/src/renderer/src/application/plugins/feature-assignment/store.js @@ -1,7 +1,7 @@ const state = { feature: { - moduleId: ["prop"] - } + moduleId: ["prop"], + }, }; const mutations = { @@ -26,11 +26,11 @@ const mutations = { if (index > -1) { state[feature][moduleId].splice(index, 1); } - } + }, }; export default { namespaced: true, state, - mutations + mutations, }; diff --git a/src/application/plugins/grab-canvas.js b/src/renderer/src/application/plugins/grab-canvas.js similarity index 92% rename from src/application/plugins/grab-canvas.js rename to src/renderer/src/application/plugins/grab-canvas.js index f1e7d485f..176024237 100644 --- a/src/application/plugins/grab-canvas.js +++ b/src/renderer/src/application/plugins/grab-canvas.js @@ -14,7 +14,7 @@ const mappingContext = mappingCanvas.getContext("2d", { alpha: false, desynchronized: true, imageSmoothingEnabled: false, - willReadFrequently: true + willReadFrequently: true, }); export default { @@ -26,7 +26,7 @@ export default { min: 1, max: 1024, step: 1, - abs: true + abs: true, }, mappingHeight: { @@ -35,12 +35,12 @@ export default { min: 1, max: 1024, step: 1, - abs: true + abs: true, }, url: { type: "text", - default: "ws://localhost:3006/modV" + default: "ws://localhost:3006/modV", }, reconnectAfter: { @@ -49,13 +49,13 @@ export default { min: 1000, max: 60000, step: 1, - abs: true + abs: true, }, shouldReconnect: { type: "bool", - default: true - } + default: true, + }, }, async init({ store, props }) { @@ -65,7 +65,7 @@ export default { group: "Plugins", canvas: mappingCanvas, context: mappingContext, - reactToResize: false + reactToResize: false, }); } @@ -95,7 +95,7 @@ export default { connection = new WebSocket(url); // Listen for errors (e.g. could not connect) - connection.addEventListener("error", event => { + connection.addEventListener("error", (event) => { console.error("grab-canvas: WebSocket: Error:", event); // Reconnect is allowed @@ -149,14 +149,14 @@ export default { 0, 0, props.mappingWidth, - props.mappingHeight + props.mappingHeight, ); const imageData = mappingContext.getImageData( 0, 0, props.mappingWidth, - props.mappingHeight + props.mappingHeight, ); const { data } = imageData; const arrayData = Array.from(data); @@ -174,7 +174,7 @@ export default { if (connection !== undefined && connection.readyState === 1) { const message = { _type: "modV", - colors: data + colors: data, }; const messageString = JSON.stringify(message, null, 2); @@ -182,5 +182,5 @@ export default { // Send JSON message connection.send(messageString); } - } + }, }; diff --git a/src/application/renderers/2d.js b/src/renderer/src/application/renderers/2d.js similarity index 97% rename from src/application/renderers/2d.js rename to src/renderer/src/application/renderers/2d.js index d216a163a..6740d1f56 100644 --- a/src/application/renderers/2d.js +++ b/src/renderer/src/application/renderers/2d.js @@ -5,7 +5,7 @@ const twoDContext = twoDCanvas.getContext("2d"); store.dispatch("outputs/addAuxillaryOutput", { name: "2d-buffer", context: twoDContext, - group: "buffer" + group: "buffer", }); /** @@ -34,7 +34,8 @@ function render({ bpm, kick, props, - data + data, + osc, }) { if ( twoDCanvas.width !== canvas.width || @@ -58,7 +59,8 @@ function render({ bpm, kick, props, - data + data, + osc, }); twoDContext.restore(); @@ -74,14 +76,14 @@ function updateModule({ data, canvas, context, - delta + delta, }) { const { data: dataUpdated } = moduleDefinition.update({ props, data, canvas, context, - delta + delta, }); return dataUpdated ?? data; diff --git a/src/application/renderers/isf.js b/src/renderer/src/application/renderers/isf.js similarity index 62% rename from src/application/renderers/isf.js rename to src/renderer/src/application/renderers/isf.js index 1d9bb0d2c..39f39aaf1 100644 --- a/src/application/renderers/isf.js +++ b/src/renderer/src/application/renderers/isf.js @@ -3,22 +3,35 @@ import store from "../worker/store"; import { Renderer as ISFRenderer, Parser as ISFParser, - Upgrader as ISFUpgrader + Upgrader as ISFUpgrader, } from "interactive-shader-format/src/main.js"; import { getFeatures } from "../worker/audio-features"; import constants from "../constants"; -const isfCanvas = new OffscreenCanvas(300, 300); +const isfCanvas = new OffscreenCanvas(256, 256); const isfContext = isfCanvas.getContext("webgl2", { antialias: true, desynchronized: true, powerPreference: "high-performance", - premultipliedAlpha: false + premultipliedAlpha: false, }); store.dispatch("outputs/addAuxillaryOutput", { name: "isf-buffer", context: isfContext, - group: "buffer" + group: "buffer", +}); + +const isfCanvasGallery = new OffscreenCanvas(256, 256); +const isfContextGallery = isfCanvasGallery.getContext("webgl2", { + antialias: false, + desynchronized: true, + powerPreference: "high-performance", + premultipliedAlpha: false, +}); +store.dispatch("outputs/addAuxillaryOutput", { + name: "isf-buffer-gallery", + context: isfContextGallery, + group: "buffer", }); const renderers = {}; @@ -29,9 +42,16 @@ function resize({ width, height }) { isfCanvas.height = height; } -function render({ module, canvas, context, pipeline, props }) { - const renderer = renderers[module.meta.name]; - const moduleInputs = inputs[module.meta.name]; +async function render({ + moduleId, + canvas, + context, + pipeline, + props, + isGallery, +}) { + const renderer = renderers[moduleId]; + const moduleInputs = inputs[moduleId]; // Only update the audio data if the module has audio inputs to improve performance // for modules that don't use any audio inputs at all @@ -64,13 +84,26 @@ function render({ module, canvas, context, pipeline, props }) { } } - isfContext.clear(isfContext.COLOR_BUFFER_BIT); - renderer.draw(isfCanvas); + const resolvedIsfCanvas = isGallery ? isfCanvasGallery : isfCanvas; + const resolvedIsfContext = isGallery ? isfContextGallery : isfContext; + + if ( + resolvedIsfCanvas.width !== canvas.width || + resolvedIsfCanvas.height !== canvas.height + ) { + // We don't use the resize function as it's very non-performant for + // some reason... + resolvedIsfCanvas.width = canvas.width; + resolvedIsfCanvas.height = canvas.height; + } + + resolvedIsfContext.clear(resolvedIsfContext.COLOR_BUFFER_BIT); + renderer.draw(resolvedIsfCanvas); if (pipeline) { context.clearRect(0, 0, canvas.width, canvas.height); } - context.drawImage(isfCanvas, 0, 0, canvas.width, canvas.height); + context.drawImage(resolvedIsfCanvas, 0, 0, canvas.width, canvas.height); } /** @@ -82,20 +115,20 @@ function updateModule({ module, props, data, canvas, context, delta }) { data, canvas, context, - delta + delta, }); return dataUpdated ?? data; } -function resizeModule({ moduleDefinition, canvas, data, props }) { - return moduleDefinition.resize({ canvas, data, props }); +function resizeModule({ moduleDefinition, canvas, data, props, isGallery }) { + return moduleDefinition.resize({ canvas, data, props, isGallery }); } -async function setupModule(moduleDefinition) { - let fragmentShader = moduleDefinition.fragmentShader; - let vertexShader = moduleDefinition.vertexShader; - +function loadISF( + { fragmentShader, vertexShader, isGallery = false }, + parseOnly = true, +) { const parser = new ISFParser(); parser.parse(fragmentShader, vertexShader); if (parser.error) { @@ -109,22 +142,33 @@ async function setupModule(moduleDefinition) { } } + const resolvedIsfContext = isGallery ? isfContextGallery : isfContext; + + let renderer; + if (!parseOnly) { + renderer = new ISFRenderer(resolvedIsfContext, { + useWebAudio: false, + fftSize: constants.AUDIO_BUFFER_SIZE, + hasAudio: parser.hasAudio, + }); + renderer.loadSource(fragmentShader, vertexShader); + + if (!renderer.valid) { + throw renderer.errorWithCorrectedLines; + } + } + + return { renderer, parser }; +} + +async function setupModule(moduleDefinition) { + const { parser } = loadISF(moduleDefinition); + moduleDefinition.meta.isfVersion = parser.isfVersion; moduleDefinition.meta.author = parser.metadata.CREDIT; moduleDefinition.meta.description = parser.metadata.DESCRIPTION; moduleDefinition.meta.version = parser.metadata.VSN; - const renderer = new ISFRenderer(isfContext, { - useWebAudio: false, - fftSize: constants.AUDIO_BUFFER_SIZE, - hasAudio: parser.hasAudio - }); - renderer.loadSource(fragmentShader, vertexShader); - - if (!renderer.valid) { - throw renderer.errorWithCorrectedLines; - } - function addProp(name, prop) { if (!moduleDefinition.props) { moduleDefinition.props = {}; @@ -148,7 +192,7 @@ async function setupModule(moduleDefinition) { default: typeof input.DEFAULT !== "undefined" ? input.DEFAULT : 0.0, min: input.MIN, max: input.MAX, - step: 0.01 + step: 0.01, }); break; @@ -156,7 +200,7 @@ async function setupModule(moduleDefinition) { addProp(input.NAME, { type: "bool", label: input.LABEL || input.NAME, - default: Boolean(input.DEFAULT) + default: Boolean(input.DEFAULT), }); break; @@ -167,8 +211,8 @@ async function setupModule(moduleDefinition) { enum: input.VALUES.map((value, idx) => ({ label: input.LABELS[idx], value, - selected: value === input.DEFAULT - })) + selected: value === input.DEFAULT, + })), }); break; @@ -176,7 +220,7 @@ async function setupModule(moduleDefinition) { addProp(input.NAME, { type: "vec4", label: input.LABEL || input.NAME, - default: input.DEFAULT + default: input.DEFAULT, }); break; @@ -186,7 +230,7 @@ async function setupModule(moduleDefinition) { label: input.LABEL || input.NAME, default: input.DEFAULT || [0.0, 0.0], min: input.MIN, - max: input.MAX + max: input.MAX, }); break; @@ -195,7 +239,7 @@ async function setupModule(moduleDefinition) { addProp(input.NAME, { type: "texture", - label: input.LABEL || input.NAME + label: input.LABEL || input.NAME, }); break; @@ -203,23 +247,37 @@ async function setupModule(moduleDefinition) { case "event": addProp(input.NAME, { type: "event", - label: input.LABEL || input.NAME + label: input.LABEL || input.NAME, }); break; } } - renderers[moduleDefinition.meta.name] = renderer; - inputs[moduleDefinition.meta.name] = moduleInputs; moduleDefinition.draw = render; return moduleDefinition; } +function addActiveModule({ $id: id, meta: { isGallery } }, moduleDefinition) { + const { renderer, parser } = loadISF( + { ...moduleDefinition, isGallery }, + false, + ); + + inputs[id] = parser.inputs; + renderers[id] = renderer; +} + +function removeActiveModule(id) { + delete renderers[id]; +} + export default { setupModule, render, updateModule, resizeModule, - resize + resize, + addActiveModule, + removeActiveModule, }; diff --git a/src/application/renderers/shader.js b/src/renderer/src/application/renderers/shader.js similarity index 100% rename from src/application/renderers/shader.js rename to src/renderer/src/application/renderers/shader.js diff --git a/src/application/renderers/shader/default-shader.js b/src/renderer/src/application/renderers/shader/default-shader.js similarity index 99% rename from src/application/renderers/shader/default-shader.js rename to src/renderer/src/application/renderers/shader/default-shader.js index 25358556c..56adc4662 100644 --- a/src/application/renderers/shader/default-shader.js +++ b/src/renderer/src/application/renderers/shader/default-shader.js @@ -79,5 +79,5 @@ export default { mainImage(image, gl_FragCoord.xy); image.a = 1.; outColor = image; - }` + }`, }; diff --git a/src/renderer/src/application/renderers/shader/index.js b/src/renderer/src/application/renderers/shader/index.js new file mode 100644 index 000000000..0572362ae --- /dev/null +++ b/src/renderer/src/application/renderers/shader/index.js @@ -0,0 +1,322 @@ +import createContext from "pex-context"; +import { frames } from "../../worker/frame-counter"; +import store from "../../worker/store"; +import defaultShader from "./default-shader"; + +function createCanvas(name, contextOptions) { + const canvas = new OffscreenCanvas(256, 256); + const context = canvas.getContext("webgl2", contextOptions); + + let canvasTexture; + let fftTexture; + + const setCanvasTexture = (tex) => (canvasTexture = tex); + const setFftTexture = (tex) => (fftTexture = tex); + + const getCanvasTexture = () => canvasTexture; + const getFftTexture = () => fftTexture; + + store.dispatch("outputs/addAuxillaryOutput", { + name, + context, + group: "buffer", + }); + + const pex = createContext({ gl: context }); + + const a_position = pex.vertexBuffer([ + -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, + ]); + const indices = pex.indexBuffer([0, 1, 2, 3, 4, 5]); + + const commands = {}; + + const clearCommand = { + pass: pex.pass({ + clearColor: [0, 0, 0, 1], + clearDepth: 1, + }), + }; + + const addCommand = (name, command) => { + commands[name] = command; + }; + + return { + pex, + canvas, + context, + commands, + addCommand, + clearCommand, + a_position, + indices, + setCanvasTexture, + setFftTexture, + getCanvasTexture, + getFftTexture, + }; +} + +const shaderContext = createCanvas("shader-buffer", { + antialias: true, + desynchronized: true, + powerPreference: "high-performance", + premultipliedAlpha: false, +}); + +const shaderContextGallery = createCanvas("shader-buffer-gallery", { + antialias: false, + desynchronized: true, + powerPreference: "high-performance", + premultipliedAlpha: false, +}); + +function resize({ width, height }, canvasIn) { + const canvas = canvasIn ?? shaderContext.canvas; + + canvas.width = width; + canvas.height = height; + + // pex.set({ + // width, + // height + // }); +} + +function generateUniforms(canvasTexture, uniforms, kick = false, fftTexture) { + const { dpr } = store.state.size; + + const date = new Date(); + const time = performance.now(); + const resolution = [ + canvasTexture?.width || 0, + canvasTexture?.height || 0, + dpr, + ]; + + const defaults = { + iGlobalTime: time / 1000, + iFrame: frames(), + iDate: [date.getFullYear(), date.getMonth(), date.getDay(), time / 1000], + iTime: time / 1000, + iTimeDelta: time / 1000, + iResolution: resolution, + iChannel0: canvasTexture, + iChannel1: canvasTexture, + iChannel2: canvasTexture, + iChannel3: canvasTexture, + iChannelResolution: [resolution, resolution, resolution, resolution], + u_modVCanvas: canvasTexture, + u_fft: fftTexture, + u_fftResolution: fftTexture ? fftTexture.width : 1, + u_delta: time / 1000, + u_time: time, + u_kick: kick, + }; + + return { ...uniforms, ...defaults }; +} + +function makeProgram(moduleDefinition, id, isGallery) { + let vert = moduleDefinition.vertexShader; + let frag = moduleDefinition.fragmentShader; + + if (!vert) { + vert = defaultShader.v; + } + + if (!frag) { + frag = defaultShader.f; + } + + if (frag.search("gl_FragColor") < 0) { + frag = defaultShader.fWrap.replace(/(%MAIN_IMAGE_INJECT%)/, frag); + + vert = defaultShader.v300; + } + + const rendererContext = isGallery ? shaderContextGallery : shaderContext; + + const pipeline = rendererContext.pex.pipeline({ + depthTest: true, + vert, + frag, + }); + + const shaderUniforms = {}; + + if (moduleDefinition.props) { + const modulePropsKeys = Object.keys(moduleDefinition.props); + const modulePropsKeysLength = modulePropsKeys.length; + + for (let i = 0; i < modulePropsKeysLength; i++) { + const key = modulePropsKeys[i]; + + if (moduleDefinition.props[key].type === "texture") { + shaderUniforms[key] = moduleDefinition.props[key].value; + } else { + shaderUniforms[key] = moduleDefinition.props[key]; + } + } + } + + const uniforms = generateUniforms( + rendererContext.getCanvasTexture(), + shaderUniforms, + false, + rendererContext.fftTexture, + ); + + const command = { + pipeline, + attributes: { + a_position: rendererContext.a_position, + position: rendererContext.a_position, + }, + indices: rendererContext.indices, + uniforms, + }; + + rendererContext.addCommand(id, command); + + return moduleDefinition; +} + +async function setupModule(moduleDefinition) { + // try { + // return await makeProgram(moduleDefinition); + // } catch (e) { + // throw new Error(e); + // } + + return moduleDefinition; +} + +async function addActiveModule( + { $id: id, meta: { isGallery } }, + moduleDefinition, +) { + try { + return makeProgram(moduleDefinition, id, isGallery); + } catch (e) { + throw new Error(e); + } +} + +function render({ + module, + moduleId, + props, + canvas, + context, + pipeline, + kick, + fftCanvas, + isGallery, +}) { + const rendererContext = isGallery ? shaderContextGallery : shaderContext; + const { pex, setCanvasTexture, setFftTexture } = rendererContext; + + resize(canvas, rendererContext.canvas); + + if (!rendererContext.getCanvasTexture()) { + setCanvasTexture( + pex.texture2D({ + data: canvas.data || canvas, + width: canvas.width, + height: canvas.height, + pixelFormat: pex.PixelFormat.RGBA8, + encoding: pex.Encoding.Linear, + min: pex.Filter.Linear, + mag: pex.Filter.Linear, + wrap: pex.Wrap.Repeat, + }), + ); + + setFftTexture( + pex.texture2D({ + data: fftCanvas.data || fftCanvas, + width: fftCanvas.width, + height: 1, + pixelFormat: pex.PixelFormat.RGBA8, + encoding: pex.Encoding.Linear, + wrap: pex.Wrap.Repeat, + }), + ); + } else { + pex.update(rendererContext.getCanvasTexture(), { + width: canvas.width, + height: canvas.height, + data: canvas.data || canvas, + }); + + pex.update(rendererContext.getFftTexture(), { + width: fftCanvas.width, + height: 1, + data: fftCanvas.data || fftCanvas, + }); + } + + const shaderUniforms = {}; + + if (props) { + const modulePropsKeys = Object.keys(props); + const modulePropsKeysLength = modulePropsKeys.length; + + for (let i = 0; i < modulePropsKeysLength; i++) { + const key = modulePropsKeys[i]; + + if (module.props[key].type === "texture") { + shaderUniforms[key] = props[key].value; + } else { + shaderUniforms[key] = props[key]; + } + } + } + + const uniforms = generateUniforms( + rendererContext.getCanvasTexture(), + shaderUniforms, + kick, + rendererContext.getFftTexture(), + ); + + const command = rendererContext.commands[moduleId]; + + pex.submit(rendererContext.clearCommand); + try { + pex.submit(command, { + uniforms, + viewport: [0, 0, canvas.width, canvas.height], + }); + } catch (e) { + console.error(e); + // nothing + } + + // clear context if we're in pipeline mode + if (pipeline) { + context.clearRect(0, 0, canvas.width, canvas.height); + } + + // Copy Shader Canvas to Main Canvas + context.drawImage(rendererContext.canvas, 0, 0, canvas.width, canvas.height); +} + +/** + * Called each frame to update the Module + */ +function updateModule({ module, props, data, canvas, context, delta }) { + const { data: dataUpdated } = module.update({ + props, + data, + canvas, + context, + delta, + }); + + return dataUpdated ?? data; +} + +export { setupModule, render, resize, updateModule, addActiveModule }; diff --git a/src/application/renderers/three.js b/src/renderer/src/application/renderers/three.js similarity index 88% rename from src/application/renderers/three.js rename to src/renderer/src/application/renderers/three.js index 68ca85629..716008d73 100644 --- a/src/application/renderers/three.js +++ b/src/renderer/src/application/renderers/three.js @@ -10,13 +10,13 @@ const threeContext = threeCanvas.getContext("webgl2", { antialias: true, desynchronized: true, powerPreference: "high-performance", - premultipliedAlpha: false + premultipliedAlpha: false, }); store.dispatch("outputs/addAuxillaryOutput", { name: "three-buffer", context: threeContext, - group: "buffer" + group: "buffer", }); const renderer = new THREE.WebGLRenderer({ @@ -24,16 +24,18 @@ const renderer = new THREE.WebGLRenderer({ antialias: false, canvas: threeCanvas, powerPreference: "high-performance", - premultipliedAlpha: false + premultipliedAlpha: false, }); -renderer.setPixelRatio(1); + +const { dpr } = store.state.size; +renderer.setPixelRatio(dpr); const inputTextureCanvas = new OffscreenCanvas(300, 300); const inputTextureContext = inputTextureCanvas.getContext("2d"); store.dispatch("outputs/addAuxillaryOutput", { name: "three-inputTexture-buffer", context: inputTextureContext, - group: "buffer" + group: "buffer", }); const inputTexture = new THREE.CanvasTexture(inputTextureCanvas); @@ -66,8 +68,9 @@ function render({ props, data, fftCanvas, - pipeline + pipeline, }) { + resize(canvas); inputTextureContext.drawImage(canvas, 0, 0, canvas.width, canvas.height); inputTexture.image = inputTextureCanvas.transferToImageBitmap(); inputTexture.needsUpdate = true; @@ -88,7 +91,7 @@ function render({ data: { ...data }, scene, camera, - fftCanvas + fftCanvas, }); renderer.render(scene, camera); @@ -111,14 +114,14 @@ function updateModule({ data, canvas, context, - delta + delta, }) { const { scene, camera } = threeModuleData[moduleDefinition.meta.name]; const { data: dataUpdated, scene: sceneUpdated, - camera: cameraUpdated + camera: cameraUpdated, } = moduleDefinition.update({ THREE, props, @@ -127,12 +130,12 @@ function updateModule({ context, delta, scene, - camera + camera, }); threeModuleData[moduleDefinition.meta.name] = { scene: sceneUpdated ?? scene, - camera: cameraUpdated ?? camera + camera: cameraUpdated ?? camera, }; return dataUpdated ?? data; @@ -144,12 +147,12 @@ async function setupModule(moduleDefinition) { inputTexture, data: moduleDefinition.data || {}, width: renderer.domElement.width, - height: renderer.domElement.height + height: renderer.domElement.height, }); threeModuleData[moduleDefinition.meta.name] = { scene, - camera + camera, }; moduleDefinition.data = data; @@ -162,8 +165,9 @@ function resizeModule({ moduleDefinition, canvas, data, props }) { return moduleDefinition.resize({ canvas, data, props, camera, scene }); } -function removeModule(module) { - delete threeModuleData[module.meta.name]; +// @TODO create an asset system to reduce duplication of models (etc.) in memory +function removeActiveModule(/*module*/) { + // delete threeModuleData[module.meta.name]; } function createPresetData(module) { @@ -190,9 +194,9 @@ export default { resize, resizeModule, setupModule, - removeModule, + removeActiveModule, createPresetData, loadPresetData, - getModuleData + getModuleData, }; export { threeModuleData }; diff --git a/src/application/sample-modules/Ball.js b/src/renderer/src/application/sample-modules/Ball.js similarity index 89% rename from src/application/sample-modules/Ball.js rename to src/renderer/src/application/sample-modules/Ball.js index 4af71ff22..b71bece11 100644 --- a/src/application/sample-modules/Ball.js +++ b/src/renderer/src/application/sample-modules/Ball.js @@ -6,7 +6,7 @@ export default { author: "2xAA", version: "1.0.1", audioFeatures: ["zcr", "rms"], - type: "2d" + type: "2d", }, props: { @@ -18,7 +18,7 @@ export default { default: 10, // default: [1, 10, 20], // random: true, - strict: true + strict: true, }, speed: { @@ -27,13 +27,13 @@ export default { min: 0, max: 20, step: 0.01, - default: 2 + default: 2, }, wrap: { label: "Wrap", type: "bool", - default: false + default: false, }, size: { @@ -43,7 +43,7 @@ export default { max: 50, step: 1, default: 2, - abs: true + abs: true, }, intensity: { @@ -53,13 +53,13 @@ export default { max: 30, step: 1, default: 15, - abs: true + abs: true, }, soundType: { label: "RMS (unchecked) / ZCR (checked)", type: "bool", - default: false + default: false, }, color: { @@ -68,12 +68,12 @@ export default { default: { data: [ [0, 0, 0], - [255, 255, 255] + [255, 255, 255], ], duration: 10000, - easing: "linear" - } - } + easing: "linear", + }, + }, }, data: { @@ -84,7 +84,7 @@ export default { size: 2, color: [255, 0, 0, 1], speed: 1, - balls: [] + balls: [], }, init({ data, canvas }) { @@ -106,7 +106,7 @@ export default { speed, wrap, canvas, - radius: props.size + radius: props.size, }); } @@ -135,7 +135,7 @@ export default { positionX: Math.floor(Math.random() * canvas.width + 1), positionY: Math.floor(Math.random() * canvas.height + 1), directionX: Math.round(Math.random()), - directionY: Math.round(Math.random()) + directionY: Math.round(Math.random()), }); balls.push(ball); @@ -150,20 +150,20 @@ export default { directionX, directionY, speed = 0, - radius = 0 + radius = 0, }) { return { radius, speed, position: { x: positionX, y: positionY }, - direction: { x: directionX, y: directionY } + direction: { x: directionX, y: directionY }, }; }, updateBall({ canvas: { width, height }, ball, speed, radius, wrap }) { const { position: { x, y }, - direction: { x: directionX, y: directionY } + direction: { x: directionX, y: directionY }, } = ball; ball.radius = radius; @@ -214,7 +214,7 @@ export default { drawBall({ ball, color, context, analysed }) { context.beginPath(); context.fillStyle = `rgb(${Math.round(color[0])},${Math.round( - color[1] + color[1], )},${Math.round(color[2])})`; context.arc( ball.position.x, @@ -222,9 +222,9 @@ export default { Math.round(ball.radius + ball.radius * analysed), 0, 2 * Math.PI, - true + true, ); context.fill(); context.closePath(); - } + }, }; diff --git a/src/application/sample-modules/Bar.js b/src/renderer/src/application/sample-modules/Bar.js similarity index 74% rename from src/application/sample-modules/Bar.js rename to src/renderer/src/application/sample-modules/Bar.js index 7e068e311..248c8a449 100644 --- a/src/application/sample-modules/Bar.js +++ b/src/renderer/src/application/sample-modules/Bar.js @@ -2,7 +2,7 @@ export default { meta: { name: "Bar", author: "2xAA", - type: "2d" + type: "2d", }, props: { @@ -10,21 +10,21 @@ export default { type: "float", default: 0, min: 0, - max: 360 + max: 360, }, thickness: { type: "float", default: 20, min: 0, - max: 200 + max: 200, }, strobe: { type: "int", default: 0, min: 0, - max: 240 + max: 240, }, color1: { @@ -33,8 +33,8 @@ export default { r: 0, g: 0, b: 0, - a: 1 - } + a: 1, + }, }, color2: { @@ -43,9 +43,9 @@ export default { r: 1, g: 1, b: 1, - a: 1 - } - } + a: 1, + }, + }, }, draw({ canvas: { width, height }, context, delta, props }) { @@ -60,12 +60,14 @@ export default { context.moveTo(0, height / 2); context.lineTo(width, height / 2); if (Math.round(delta) % strobe < Math.round(strobe / 2)) { - context.strokeStyle = `rgba(${color1.r * 255},${color1.g * - 255},${color1.b * 255},${color1.a})`; + context.strokeStyle = `rgba(${color1.r * 255},${ + color1.g * 255 + },${color1.b * 255},${color1.a})`; } else { - context.strokeStyle = `rgba(${color2.r * 255},${color2.g * - 255},${color2.b * 255},${color2.a})`; + context.strokeStyle = `rgba(${color2.r * 255},${ + color2.g * 255 + },${color2.b * 255},${color2.a})`; } context.stroke(); - } + }, }; diff --git a/src/application/sample-modules/ChromaticAbberation.js b/src/renderer/src/application/sample-modules/ChromaticAbberation.js similarity index 85% rename from src/application/sample-modules/ChromaticAbberation.js rename to src/renderer/src/application/sample-modules/ChromaticAbberation.js index a4470e79b..444486680 100644 --- a/src/application/sample-modules/ChromaticAbberation.js +++ b/src/renderer/src/application/sample-modules/ChromaticAbberation.js @@ -1,4 +1,4 @@ -import chromaticAbberationFrag from "./ChromaticAbberation/chromaticAbberation.frag"; +import chromaticAbberationFrag from "./ChromaticAbberation/chromaticAbberation.frag?raw"; export default { meta: { @@ -7,7 +7,7 @@ export default { version: "1.0.0", previewWithOutput: true, meyda: [], // returned variables passed to the shader individually as uniforms - type: "shader" + type: "shader", }, fragmentShader: chromaticAbberationFrag, @@ -18,7 +18,7 @@ export default { min: 1.0, max: 2.0, step: 0.001, - default: 1.0 + default: 1.0, }, gOffset: { type: "float", @@ -26,7 +26,7 @@ export default { min: 1.0, max: 2.0, step: 0.001, - default: 1.015 + default: 1.015, }, bOffset: { type: "float", @@ -34,7 +34,7 @@ export default { min: 1.0, max: 2.0, step: 0.001, - default: 1.03 - } - } + default: 1.03, + }, + }, }; diff --git a/src/application/sample-modules/ChromaticAbberation/chromaticAbberation.frag b/src/renderer/src/application/sample-modules/ChromaticAbberation/chromaticAbberation.frag similarity index 100% rename from src/application/sample-modules/ChromaticAbberation/chromaticAbberation.frag rename to src/renderer/src/application/sample-modules/ChromaticAbberation/chromaticAbberation.frag diff --git a/src/application/sample-modules/Concentrics.js b/src/renderer/src/application/sample-modules/Concentrics.js similarity index 89% rename from src/application/sample-modules/Concentrics.js rename to src/renderer/src/application/sample-modules/Concentrics.js index 86cef54ec..c0f2a9660 100644 --- a/src/application/sample-modules/Concentrics.js +++ b/src/renderer/src/application/sample-modules/Concentrics.js @@ -6,7 +6,7 @@ export default { author: "2xAA", version: "1.0.0", audioFeatures: ["zcr", "rms"], - type: "2d" + type: "2d", }, props: { @@ -14,7 +14,7 @@ export default { type: "bool", variable: "", label: "Use RMS", - default: true + default: true, }, intensity: { @@ -22,7 +22,7 @@ export default { label: "RMS/ZCR Intensity", min: 0, max: 30, - default: 1 + default: 1, }, spacing: { @@ -30,7 +30,7 @@ export default { label: "Circle Spacing", min: 0, max: 100, - default: 5 + default: 5, }, objectDistance: { @@ -38,7 +38,7 @@ export default { label: "Object Distance", min: 0, max: 200, - default: 40 + default: 40, }, strokeWeight: { @@ -47,12 +47,12 @@ export default { min: 1, max: 20, default: 1, - strict: true - } + strict: true, + }, }, data: { - circles: [] + circles: [], }, init({ canvas, data }) { @@ -76,13 +76,13 @@ export default { this.updateCircles({ circles: data.circles[0], x: widthHalf + Math.sin(delta / 1000) * props.objectDistance, - y: heightHalf + Math.cos(delta / 1000) * (props.objectDistance / 2) + y: heightHalf + Math.cos(delta / 1000) * (props.objectDistance / 2), }); this.updateCircles({ circles: data.circles[1], x: widthHalf + -Math.sin(delta / 1000) * props.objectDistance, - y: heightHalf + -Math.cos(delta / 1000) * (props.objectDistance / 2) + y: heightHalf + -Math.cos(delta / 1000) * (props.objectDistance / 2), }); return data; @@ -105,7 +105,7 @@ export default { context, amp, strokeWeight, - spacing + spacing, }); this.drawCircles({ @@ -113,7 +113,7 @@ export default { context, amp, strokeWeight, - spacing + spacing, }); }, @@ -121,7 +121,7 @@ export default { return { hue: Math.round(Math.random() * 360), x, - y + y, }; }, @@ -144,9 +144,9 @@ export default { for (let i = 0; i < amp; i += 1) { if (i === amp - 1) { - context.strokeStyle = `hsl(${circles.hue}, 50%, ${(1 - - (amp - Math.round(amp))) * - 50}%)`; + context.strokeStyle = `hsl(${circles.hue}, 50%, ${ + (1 - (amp - Math.round(amp))) * 50 + }%)`; } context.beginPath(); @@ -154,5 +154,5 @@ export default { context.closePath(); context.stroke(); } - } + }, }; diff --git a/src/application/sample-modules/Counter.js b/src/renderer/src/application/sample-modules/Counter.js similarity index 89% rename from src/application/sample-modules/Counter.js rename to src/renderer/src/application/sample-modules/Counter.js index 4e2d041a9..a1de283c9 100644 --- a/src/application/sample-modules/Counter.js +++ b/src/renderer/src/application/sample-modules/Counter.js @@ -1,7 +1,7 @@ export default { meta: { name: "Counter", - type: "2d" + type: "2d", }, props: { @@ -9,12 +9,12 @@ export default { default: 0.5, min: 0, max: 1, - type: "float" - } + type: "float", + }, }, data: { - counter: 0 + counter: 0, }, multiply(value, multiplier) { @@ -31,5 +31,5 @@ export default { context.fillRect(0, 0, width, height); context.fillStyle = "black"; context.fillText(data.counter, width / 2, height / 2); - } + }, }; diff --git a/src/application/sample-modules/Cube.js b/src/renderer/src/application/sample-modules/Cube.js similarity index 92% rename from src/application/sample-modules/Cube.js rename to src/renderer/src/application/sample-modules/Cube.js index f91184a0e..9978cbd45 100644 --- a/src/application/sample-modules/Cube.js +++ b/src/renderer/src/application/sample-modules/Cube.js @@ -2,7 +2,7 @@ export default { meta: { name: "Cube", author: "2xAA", - type: "three" + type: "three", }, props: { @@ -10,21 +10,21 @@ export default { type: "vec3", default: [0, 0, 0], min: 0, - max: 1 + max: 1, }, scale: { type: "vec3", default: [1, 1, 1], min: 0, - max: 1 + max: 1, }, position: { type: "vec3", default: [0, 0, 0], min: 0, - max: 1 + max: 1, }, color: { @@ -33,18 +33,18 @@ export default { r: 1, g: 1, b: 1, - a: 1 - } + a: 1, + }, }, useMap: { type: "bool", - default: false - } + default: false, + }, }, data: { - cubeMesh: null + cubeMesh: null, }, setupThree({ THREE, data, width, height, inputTexture }) { @@ -65,7 +65,7 @@ export default { const material = new THREE.MeshStandardMaterial({ color: "#ffffff", roughness: 0.351, - map: inputTexture + map: inputTexture, }); const cubeMesh = new THREE.Mesh(geometry, material); @@ -88,9 +88,9 @@ export default { position, rotation, color: { r, g, b }, - useMap + useMap, }, - inputTexture + inputTexture, }) { data.cubeMesh.position.x = position[0]; data.cubeMesh.position.y = position[1]; @@ -115,5 +115,5 @@ export default { data.cubeMesh.material.color.r = r; data.cubeMesh.material.color.g = g; data.cubeMesh.material.color.b = b; - } + }, }; diff --git a/src/application/sample-modules/Fisheye.js b/src/renderer/src/application/sample-modules/Fisheye.js similarity index 69% rename from src/application/sample-modules/Fisheye.js rename to src/renderer/src/application/sample-modules/Fisheye.js index 12e43c2d3..b17f98a06 100644 --- a/src/application/sample-modules/Fisheye.js +++ b/src/renderer/src/application/sample-modules/Fisheye.js @@ -1,4 +1,4 @@ -import fragmentShader from "./Fisheye/fisheye.frag"; +import fragmentShader from "./Fisheye/fisheye.frag?raw"; export default { meta: { @@ -6,7 +6,7 @@ export default { type: "shader", version: "1.0.0", author: "???", - previewWithOutput: true + previewWithOutput: true, }, fragmentShader, @@ -18,7 +18,7 @@ export default { default: 180.0, min: 1.0, max: 360.0, - step: 0.5 - } - } + step: 0.5, + }, + }, }; diff --git a/src/application/sample-modules/Fisheye/fisheye.frag b/src/renderer/src/application/sample-modules/Fisheye/fisheye.frag similarity index 100% rename from src/application/sample-modules/Fisheye/fisheye.frag rename to src/renderer/src/application/sample-modules/Fisheye/fisheye.frag diff --git a/src/application/sample-modules/GreatBallOfFire.js b/src/renderer/src/application/sample-modules/GreatBallOfFire.js similarity index 96% rename from src/application/sample-modules/GreatBallOfFire.js rename to src/renderer/src/application/sample-modules/GreatBallOfFire.js index 55fe65044..d0011b565 100644 --- a/src/application/sample-modules/GreatBallOfFire.js +++ b/src/renderer/src/application/sample-modules/GreatBallOfFire.js @@ -3,7 +3,7 @@ export default { name: "Great Ball Of Fire", author: ":)", version: "1.0.0", - type: "isf" + type: "isf", }, fragmentShader: `/*{ "CREDIT": "by mojovideotech", @@ -76,8 +76,8 @@ export default { ], "DESCRIPTION": "GreatBallOfFire" }*/ - - + + /////////////////////////////////////////// // GreatBallOfFire by mojovideotech // @@ -88,7 +88,7 @@ export default { // // Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. /////////////////////////////////////////// - + #define saturate(oo) clamp(oo, 0.0, 1.0) #define MarchSteps 4 #define Radius 1.5 @@ -97,18 +97,18 @@ export default { #define Color2 vec4(1.0, 0.8, 0.2, 1.0) #define Color3 vec4(1.0, 0.03, 0.0, 1.0) #define Color4 vec4(0.4, 0.02, 0.02, 1.0) - - + + vec3 mod196(vec3 x) { return x - floor(x * (1.0 / 196.0)) * 196.0; } vec4 mod196(vec4 x) { return x - floor(x * (1.0 / 196.0)) * 196.0; } vec4 permute(vec4 x) { return mod196(((x*56.0)+1.0)*x); } vec4 taylorInvSqrt(vec4 r){ return 1.79284291400159 - 0.85373472095314 * r; } - + float snoise(vec3 v) { const vec2 C = vec2(1.0/6.0, 1.0/3.0); const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); - + vec3 i = floor(v + dot(v, C.yyy)); vec3 x0 = v - i + dot(i, C.xxx); vec3 g = step(x0.yzx, x0.xyz); @@ -118,15 +118,15 @@ export default { vec3 x1 = x0 - i1 + C.xxx; vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y - + i = mod196(i); vec4 p = permute( permute( permute( i.z + vec4(0.0, i1.z, i2.z, 1.0)) + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); - + float n_ = 0.142857142857; vec3 ns = n_ * D.wyz - D.xzx; - vec4 j = p - 49.0 * floor(p * ns.z * ns.z); + vec4 j = p - 49.0 * floor(p * ns.z * ns.z); vec4 x_ = floor(j * ns.z); - vec4 y_ = floor(j - 7.0 * x_); + vec4 y_ = floor(j - 7.0 * x_); vec4 x = x_ *ns.x + ns.yyyy; vec4 y = y_ *ns.x + ns.yyyy; vec4 h = 1.0 - abs(x) - abs(y); @@ -141,7 +141,7 @@ export default { vec3 p1 = vec3(a0.zw, h.y); vec3 p2 = vec3(a1.xy, h.z); vec3 p3 = vec3(a1.zw, h.w); - + vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); p0 *= norm.x; p1 *= norm.y; @@ -149,10 +149,10 @@ export default { p3 *= norm.w; vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); m = m * m; - + return 35.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3))); } - + float Turbulence(vec3 position, float minFreq, float maxFreq, float qWidth) { float value = 0.0; @@ -167,35 +167,35 @@ export default { } fade = clamp(2.0 * (cutoff-fOut)/cutoff, 0.0, 1.0); value += fade * abs(snoise(position * fOut))/fOut; - + return 1.0-value; } - + float SphereDist(vec3 position) { return length(position) - Radius; } - + vec4 Shade(float distance) { float c1 = saturate(distance*5.0 + 0.5); float c2 = saturate(distance*5.0); float c3 = saturate(distance*3.4 - 0.5); - + vec4 a = mix(Color1,Color2, c1); vec4 b = mix(a, Color3, c2); return mix(b, Color4, c3); } - + float RenderScene(vec3 position, out float distance) { float noise = Turbulence(position * density + vec3(rateZ, rateX, rateY)*TIME, 0.1, 1.5, 0.03) * depth; noise = saturate(abs(noise)); distance = SphereDist(position) - noise; - + return noise; } - + vec4 March(vec3 rayOrigin, vec3 rayStep) { vec3 position = rayOrigin; @@ -207,10 +207,10 @@ export default { if(distance < 0.05) break; position += rayStep * distance; } - + return mix(Shade(displacement), vec4(0.0, 0.0, 0.0, 0.0), float(distance >= 0.5)); } - + bool IntersectSphere(vec3 ro, vec3 rd, vec3 pos, float radius, out vec3 intersectPoint) { vec3 relDistance = (ro - pos); @@ -218,16 +218,16 @@ export default { float c = dot(relDistance, relDistance) - radius*radius; float d = b*b - c; intersectPoint = ro + rd*(-b - sqrt(d)); - + return d >= 0.0; } - + void main(void) { vec2 p = (gl_FragCoord.xy / RENDERSIZE.xy) * 2.0 - 1.0; p += offset; p.x *= RENDERSIZE.x/RENDERSIZE.y; - + float rotx = rotation* 4.0; float roty = -rotation * 4.0; float zoom = 16.0-(size*3.); @@ -242,8 +242,8 @@ export default { { col = March(origin, rd); } - + gl_FragColor = col; }`, - vertexShader: "void main() {isf_vertShaderInit();}" + vertexShader: "void main() {isf_vertShaderInit();}", }; diff --git a/src/application/sample-modules/GridStretch.js b/src/renderer/src/application/sample-modules/GridStretch.js similarity index 91% rename from src/application/sample-modules/GridStretch.js rename to src/renderer/src/application/sample-modules/GridStretch.js index e7a399008..9d7dff7fb 100644 --- a/src/application/sample-modules/GridStretch.js +++ b/src/renderer/src/application/sample-modules/GridStretch.js @@ -5,7 +5,7 @@ export default { version: 0.1, meyda: ["zcr", "rms"], previewWithOutput: true, - type: "2d" + type: "2d", }, props: { @@ -15,7 +15,7 @@ export default { min: 1, max: 20, step: 1, - default: 10 + default: 10, }, countY: { @@ -24,7 +24,7 @@ export default { min: 1, max: 20, step: 1, - default: 10 + default: 10, }, intensity: { @@ -32,19 +32,19 @@ export default { type: "float", min: 0, max: 30, - default: 15 + default: 15, }, zcr: { label: "RMS (unchecked) / ZCR (checked)", type: "bool", - default: false - } + default: false, + }, }, data: { newCanvas2: null, - newCtx2: null + newCtx2: null, }, init({ canvas, data }) { @@ -89,11 +89,11 @@ export default { i * sliceWidth - analysed, j * sliceHeight - analysed, sliceWidth + analysed * 2, - sliceHeight + analysed * 2 + sliceHeight + analysed * 2, ); } } context.drawImage(data.newCanvas2, 0, 0, canvas.width, canvas.height); - } + }, }; diff --git a/src/application/sample-modules/Line.js b/src/renderer/src/application/sample-modules/Line.js similarity index 90% rename from src/application/sample-modules/Line.js rename to src/renderer/src/application/sample-modules/Line.js index 94aeaaeff..a83de1c92 100644 --- a/src/application/sample-modules/Line.js +++ b/src/renderer/src/application/sample-modules/Line.js @@ -2,7 +2,7 @@ export default { meta: { type: "2d", name: "Line", - author: "2xAA" + author: "2xAA", }, props: { @@ -11,7 +11,7 @@ export default { default: 100, min: 5, max: 200, - strict: true + strict: true, }, spacing: { @@ -19,7 +19,7 @@ export default { default: 1, min: 1, max: 20, - abs: true + abs: true, }, lineWidth: { @@ -27,7 +27,7 @@ export default { default: 1, min: 1, max: 20, - abs: true + abs: true, }, color: { @@ -42,11 +42,11 @@ export default { colors: [ { r: 255, g: 255, b: 255, a: 1 }, { r: 0, g: 0, b: 0, a: 1 }, - { r: 255, g: 0, b: 0, a: 0.5 } + { r: 255, g: 0, b: 0, a: 0.5 }, ], - duration: 1000 - } - } + duration: 1000, + }, + }, }, speed: { @@ -54,31 +54,31 @@ export default { abs: true, min: 0, max: 2, - default: 1 - } + default: 1, + }, }, data: { vector: [ [0, 0], - [0, 0] + [0, 0], ], velocity: [ [1, 1], - [1, 1] + [1, 1], ], - history: [] + history: [], }, init({ data }) { data.vector = [ [Math.random(), Math.random()], - [Math.random(), Math.random()] + [Math.random(), Math.random()], ]; data.velocity = [ [Math.random() > 0.5 ? 1 : -1, Math.random() > 0.5 ? 1 : -1], - [Math.random() > 0.5 ? 1 : -1, Math.random() > 0.5 ? 1 : -1] + [Math.random() > 0.5 ? 1 : -1, Math.random() > 0.5 ? 1 : -1], ]; return data; @@ -133,5 +133,5 @@ export default { context.lineTo(Math.round(p2[0] * width), Math.round(p2[1] * height)); context.stroke(); } - } + }, }; diff --git a/src/application/sample-modules/MattiasCRT-2.0.js b/src/renderer/src/application/sample-modules/MattiasCRT-2.0.js similarity index 56% rename from src/application/sample-modules/MattiasCRT-2.0.js rename to src/renderer/src/application/sample-modules/MattiasCRT-2.0.js index 2f9556db5..69ce9f328 100644 --- a/src/application/sample-modules/MattiasCRT-2.0.js +++ b/src/renderer/src/application/sample-modules/MattiasCRT-2.0.js @@ -1,4 +1,4 @@ -import crtFrag from "./MattiasCRT/mattiasCrt.frag"; +import crtFrag from "./MattiasCRT/mattiasCrt.frag?raw"; export default { meta: { @@ -6,7 +6,7 @@ export default { author: "Mattias", version: "1.0.0", previewWithOutput: true, - type: "shader" + type: "shader", }, - fragmentShader: crtFrag + fragmentShader: crtFrag, }; diff --git a/src/application/sample-modules/MattiasCRT/mattiasCrt.frag b/src/renderer/src/application/sample-modules/MattiasCRT/mattiasCrt.frag similarity index 100% rename from src/application/sample-modules/MattiasCRT/mattiasCrt.frag rename to src/renderer/src/application/sample-modules/MattiasCRT/mattiasCrt.frag diff --git a/src/application/sample-modules/Pixelate.js b/src/renderer/src/application/sample-modules/Pixelate.js similarity index 92% rename from src/application/sample-modules/Pixelate.js rename to src/renderer/src/application/sample-modules/Pixelate.js index 4fbc0b46c..d4fdc15f8 100644 --- a/src/application/sample-modules/Pixelate.js +++ b/src/renderer/src/application/sample-modules/Pixelate.js @@ -5,7 +5,7 @@ export default { version: "1.0.0", audioFeatures: ["zcr", "rms"], type: "2d", - previewWithOutput: true + previewWithOutput: true, }, props: { @@ -15,13 +15,13 @@ export default { min: 2, max: 30, step: 1, - default: 5 + default: 5, }, soundReactive: { type: "bool", label: "Sound Reactive", - default: false + default: false, }, intensity: { @@ -30,14 +30,14 @@ export default { min: 0, max: 30, step: 1, - default: 15 + default: 15, }, soundType: { type: "bool", label: "RMS (unchecked) / ZCR (checked)", - default: false - } + default: false, + }, }, init({ canvas, data }) { @@ -89,7 +89,7 @@ export default { 0, 0, w, - h + h, ); context.drawImage( data.newCanvas2, @@ -100,8 +100,8 @@ export default { 0, 0, canvas.width, - canvas.height + canvas.height, ); context.restore(); - } + }, }; diff --git a/src/application/sample-modules/Plasma.js b/src/renderer/src/application/sample-modules/Plasma.js similarity index 79% rename from src/application/sample-modules/Plasma.js rename to src/renderer/src/application/sample-modules/Plasma.js index d3ab08876..01e76200d 100644 --- a/src/application/sample-modules/Plasma.js +++ b/src/renderer/src/application/sample-modules/Plasma.js @@ -1,4 +1,4 @@ -import plasmaFrag from "./Plasma/plasma.frag"; +import plasmaFrag from "./Plasma/plasma.frag?raw"; export default { meta: { @@ -6,7 +6,7 @@ export default { author: "2xAA", version: 0.1, meyda: [], // returned variables passed to the shader individually as uniforms - type: "shader" + type: "shader", }, fragmentShader: plasmaFrag, props: { @@ -16,7 +16,7 @@ export default { min: 1.0, max: 150.0, step: 1.0, - default: 50.0 + default: 50.0, }, u_scaleY: { @@ -25,7 +25,7 @@ export default { min: 1.0, max: 150.0, step: 1.0, - default: 50.0 + default: 50.0, }, u_timeScale: { @@ -34,7 +34,7 @@ export default { min: 1.0, max: 1000.0, step: 1.0, - default: 100.0 - } - } + default: 100.0, + }, + }, }; diff --git a/src/application/sample-modules/Plasma/plasma.frag b/src/renderer/src/application/sample-modules/Plasma/plasma.frag similarity index 100% rename from src/application/sample-modules/Plasma/plasma.frag rename to src/renderer/src/application/sample-modules/Plasma/plasma.frag diff --git a/src/application/sample-modules/Polygon.js b/src/renderer/src/application/sample-modules/Polygon.js similarity index 100% rename from src/application/sample-modules/Polygon.js rename to src/renderer/src/application/sample-modules/Polygon.js diff --git a/src/application/sample-modules/Smear.js b/src/renderer/src/application/sample-modules/Smear.js similarity index 82% rename from src/application/sample-modules/Smear.js rename to src/renderer/src/application/sample-modules/Smear.js index 518e70682..6cb049f6f 100644 --- a/src/application/sample-modules/Smear.js +++ b/src/renderer/src/application/sample-modules/Smear.js @@ -2,7 +2,7 @@ export default { meta: { name: "Smear", type: "2d", - audioFeatures: ["rms", "energy"] + audioFeatures: ["rms", "energy"], }, props: { @@ -10,26 +10,26 @@ export default { type: "int", min: -20, max: 20, - default: 0 + default: 0, }, speedY: { type: "int", min: -20, max: 20, - default: 10 + default: 10, }, sizeX: { type: "int", min: -20, max: 20, - default: 0 + default: 0, }, sizeY: { type: "int", min: -20, max: 20, - default: 0 - } + default: 0, + }, }, draw({ context, canvas, props }) { @@ -37,5 +37,5 @@ export default { const { speedX, speedY, sizeX, sizeY } = props; context.drawImage(canvas, -speedX, -speedY, width + sizeX, height + sizeY); - } + }, }; diff --git a/src/application/sample-modules/Text.js b/src/renderer/src/application/sample-modules/Text.js similarity index 83% rename from src/application/sample-modules/Text.js rename to src/renderer/src/application/sample-modules/Text.js index 4aa7984d3..0abafe2c1 100644 --- a/src/application/sample-modules/Text.js +++ b/src/renderer/src/application/sample-modules/Text.js @@ -1,11 +1,9 @@ -import ctw from "canvas-text-wrapper"; - -const CanvasTextWrapper = ctw.CanvasTextWrapper; +const { CanvasTextWrapper } = require("canvas-text-wrapper"); export default { meta: { name: "Text", - type: "2d" + type: "2d", }, props: { @@ -14,7 +12,7 @@ export default { default: "", set(args) { this.drawText(args); - } + }, }, size: { @@ -24,7 +22,7 @@ export default { default: 16, set(args) { this.drawText(args); - } + }, }, offsetX: { @@ -35,7 +33,7 @@ export default { step: 1, set(args) { this.drawText(args); - } + }, }, offsetY: { @@ -46,7 +44,7 @@ export default { step: 1, set(args) { this.drawText(args); - } + }, }, strokeSize: { @@ -57,7 +55,7 @@ export default { abs: true, set(args) { this.drawText(args); - } + }, }, font: { @@ -66,7 +64,7 @@ export default { default: "sans-serif", set(args) { this.drawText(args); - } + }, }, weight: { @@ -74,7 +72,7 @@ export default { default: "bold", set(args) { this.drawText(args); - } + }, }, fill: { @@ -82,7 +80,7 @@ export default { default: true, set(args) { this.drawText(args); - } + }, }, fillColor: { @@ -91,11 +89,11 @@ export default { r: 1, g: 1, b: 1, - a: 1 + a: 1, }, set(args) { this.drawText(args); - } + }, }, stroke: { @@ -103,7 +101,7 @@ export default { default: false, set(args) { this.drawText(args); - } + }, }, strokeColor: { @@ -112,12 +110,12 @@ export default { r: 1, g: 0, b: 0, - a: 1 + a: 1, }, set(args) { this.drawText(args); - } - } + }, + }, }, init({ canvas: { width, height }, data, props }) { @@ -150,23 +148,25 @@ export default { fillColor, fill, offsetX, - offsetY + offsetY, } = props; const { canvas, canvas: { width, height }, - context + context, } = data; if (fill) { - context.fillStyle = `rgba(${fillColor.r * 255},${fillColor.g * - 255},${fillColor.b * 255},${fillColor.a})`; + context.fillStyle = `rgba(${fillColor.r * 255},${ + fillColor.g * 255 + },${fillColor.b * 255},${fillColor.a})`; } else { context.fillStyle = "rgba(0,0,0,0)"; } - context.strokeStyle = `rgba(${strokeColor.r * 255},${strokeColor.g * - 255},${strokeColor.b * 255},${strokeColor.a})`; + context.strokeStyle = `rgba(${strokeColor.r * 255},${ + strokeColor.g * 255 + },${strokeColor.b * 255},${strokeColor.a})`; context.lineWidth = strokeSize; context.clearRect(0, 0, width, height); @@ -179,7 +179,7 @@ export default { textAlign: "center", strokeText: stroke, offsetX: calculatedOffsetX, - offsetY: calculatedOffsetY + offsetY: calculatedOffsetY, }); - } + }, }; diff --git a/src/application/sample-modules/Texture2d.js b/src/renderer/src/application/sample-modules/Texture2d.js similarity index 92% rename from src/application/sample-modules/Texture2d.js rename to src/renderer/src/application/sample-modules/Texture2d.js index c35da9d41..5d2ff0754 100644 --- a/src/application/sample-modules/Texture2d.js +++ b/src/renderer/src/application/sample-modules/Texture2d.js @@ -3,11 +3,11 @@ export default { name: "Texture 2D", type: "2d", version: "1.0.0", - author: "NERDDISCO" + author: "NERDDISCO", }, props: { texture: { - type: "texture" + type: "texture", }, scale: { label: "Scale", @@ -15,7 +15,7 @@ export default { default: 1, min: 0, max: 5, - step: 0.001 + step: 0.001, }, offsetX: { label: "Offset X in %", @@ -23,7 +23,7 @@ export default { default: 0, min: -100, max: 100, - step: 1 + step: 1, }, offsetY: { label: "Offset Y in %", @@ -31,7 +31,7 @@ export default { default: 0, min: -100, max: 100, - step: 1 + step: 1, }, constrain: { label: "Constrain", @@ -40,9 +40,9 @@ export default { enum: [ { label: "None (Scale)", value: "none" }, { label: "Contain", value: "contain" }, - { label: "Cover", value: "cover" } - ] - } + { label: "Cover", value: "cover" }, + ], + }, }, draw({ canvas: { width, height }, context, props }) { const { constrain, offsetX, offsetY, scale, texture } = props; @@ -100,8 +100,8 @@ export default { x + calculatedOffsetX, y + calculatedOffsetY, imageWidth, - imageHeight + imageHeight, ); } - } + }, }; diff --git a/src/application/sample-modules/Waveform.js b/src/renderer/src/application/sample-modules/Waveform.js similarity index 89% rename from src/application/sample-modules/Waveform.js rename to src/renderer/src/application/sample-modules/Waveform.js index 7d6d6e0e4..b79c1a07c 100644 --- a/src/application/sample-modules/Waveform.js +++ b/src/renderer/src/application/sample-modules/Waveform.js @@ -6,7 +6,7 @@ export default { author: "2xAA", version: "1.0.0", audioFeatures: ["buffer"], - type: "2d" + type: "2d", }, props: { @@ -16,7 +16,7 @@ export default { min: 1, max: 30, default: 1, - abs: true + abs: true, }, maxHeight: { @@ -24,7 +24,7 @@ export default { label: "Height", min: 1.0, max: 100.0, - default: 100.0 + default: 100.0, }, maxWidth: { @@ -32,7 +32,7 @@ export default { label: "Width", min: 0, max: 1.0, - default: 1.0 + default: 1.0, }, windowing: { @@ -44,8 +44,8 @@ export default { { label: "Hanning", value: "hanning" }, { label: "Hamming", value: "hamming" }, { label: "Blackman", value: "blackman" }, - { label: "Sine", value: "sine" } - ] + { label: "Sine", value: "sine" }, + ], }, color: { @@ -54,12 +54,12 @@ export default { default: { data: [ [255, 255, 255], - [255, 255, 255] + [255, 255, 255], ], duration: 10000, - easing: "linear" - } - } + easing: "linear", + }, + }, }, draw({ canvas, context, features, meyda, props }) { @@ -68,7 +68,7 @@ export default { maxWidth, maxHeight, strokeWeight, - windowing + windowing, } = props; const { width, height } = canvas; const bufferLength = features.buffer.length; @@ -76,7 +76,7 @@ export default { context.lineWidth = strokeWeight; context.strokeStyle = `rgb(${Math.round(color[0])},${Math.round( - color[1] + color[1], )},${Math.round(color[2])})`; context.beginPath(); @@ -98,5 +98,5 @@ export default { context.lineTo(width * maxWidth, height / 2); context.stroke(); - } + }, }; diff --git a/src/application/sample-modules/Webcam.js b/src/renderer/src/application/sample-modules/Webcam.js similarity index 87% rename from src/application/sample-modules/Webcam.js rename to src/renderer/src/application/sample-modules/Webcam.js index 23c1d2e7c..2737d2e59 100644 --- a/src/application/sample-modules/Webcam.js +++ b/src/renderer/src/application/sample-modules/Webcam.js @@ -3,7 +3,7 @@ export default { type: "2d", name: "Webcam", author: "2xAA", - version: "1.0.0" + version: "1.0.0", }, props: { @@ -11,20 +11,20 @@ export default { type: "float", min: 0, max: 10, - default: 1 + default: 1, }, position: { type: "vec2", default: [0.5, 0.5], min: 0, - max: 1 + max: 1, }, imageSmoothing: { type: "bool", - default: true - } + default: true, + }, }, draw({ canvas, context, video: { canvas: video }, props }) { @@ -39,7 +39,7 @@ export default { width * position[0] - (videoWidth * scale) / 2, height * (1 - position[1]) - (videoHeight * scale) / 2, videoWidth * scale, - videoHeight * scale + videoHeight * scale, ); - } + }, }; diff --git a/src/application/sample-modules/Wobble.js b/src/renderer/src/application/sample-modules/Wobble.js similarity index 72% rename from src/application/sample-modules/Wobble.js rename to src/renderer/src/application/sample-modules/Wobble.js index 364104db0..928cb4a92 100644 --- a/src/application/sample-modules/Wobble.js +++ b/src/renderer/src/application/sample-modules/Wobble.js @@ -1,4 +1,4 @@ -import fragmentShader from "./Wobble/wobble.frag"; +import fragmentShader from "./Wobble/wobble.frag?raw"; export default { meta: { @@ -6,7 +6,7 @@ export default { name: "Wobble", author: "2xAA", version: "1.0.0", - previewWithOutput: true + previewWithOutput: true, }, fragmentShader, @@ -18,7 +18,7 @@ export default { min: 0.0, max: 0.05, step: 0.001, - default: 0.001 + default: 0.001, }, size: { @@ -27,7 +27,7 @@ export default { min: 1.0, max: 50.0, step: 1.0, - default: 1.0 - } - } + default: 1.0, + }, + }, }; diff --git a/src/application/sample-modules/Wobble/wobble.frag b/src/renderer/src/application/sample-modules/Wobble/wobble.frag similarity index 100% rename from src/application/sample-modules/Wobble/wobble.frag rename to src/renderer/src/application/sample-modules/Wobble/wobble.frag diff --git a/src/application/sample-modules/X-Drips.js b/src/renderer/src/application/sample-modules/X-Drips.js similarity index 93% rename from src/application/sample-modules/X-Drips.js rename to src/renderer/src/application/sample-modules/X-Drips.js index bc604683e..60420d005 100644 --- a/src/application/sample-modules/X-Drips.js +++ b/src/renderer/src/application/sample-modules/X-Drips.js @@ -1,7 +1,7 @@ export default { meta: { type: "2d", - name: "X Drips" + name: "X Drips", }, props: { @@ -9,14 +9,14 @@ export default { default: 70, type: "int", min: 0, - max: 70 + max: 70, }, insetHeight: { default: 15, type: "int", min: 0, - max: 70 + max: 70, }, maxDripHeight: { @@ -24,8 +24,8 @@ export default { type: "float", min: 0, max: 1, - abs: true - } + abs: true, + }, }, data: { @@ -34,7 +34,7 @@ export default { heights: [80, 145, 220], colors: ["#15216b", "#f33a58", "#f76272", "#ff9fda", "#e10079", "#a231ef"], color: "#000", - pattern: [] + pattern: [], }, generatePattern({ canvas, data }) { @@ -57,7 +57,7 @@ export default { type: "width", width: selectedWidth, height: selectedHeight, - random + random, }); } else { selectedWidth = spacings[Math.floor(Math.random() * spacings.length)]; @@ -65,7 +65,7 @@ export default { type: "space", width: selectedWidth, height: selectedHeight, - random + random, }); } @@ -124,7 +124,7 @@ export default { insetHeight + piece.height + h, piece.width / 2, 0, - Math.PI * 2 + Math.PI * 2, ); context.fill(); } @@ -134,23 +134,23 @@ export default { x, dripBaseHeight - h / 3, piece.width, - insetHeight + piece.height + insetHeight + piece.height, ); this.clearCircle( context, x + piece.width / 2, dripBaseHeight - h / 3, - piece.width / 2 + piece.width / 2, ); this.clearCircle( context, x + piece.width / 2, insetHeight + piece.height + dripBaseHeight - h / 3, - piece.width / 2 + piece.width / 2, ); } x += piece.width; } - } + }, }; diff --git a/src/application/sample-modules/isf/ASCII Art.fs b/src/renderer/src/application/sample-modules/isf/ASCII Art.fs similarity index 100% rename from src/application/sample-modules/isf/ASCII Art.fs rename to src/renderer/src/application/sample-modules/isf/ASCII Art.fs diff --git a/src/application/sample-modules/isf/Angular.fs b/src/renderer/src/application/sample-modules/isf/Angular.fs similarity index 100% rename from src/application/sample-modules/isf/Angular.fs rename to src/renderer/src/application/sample-modules/isf/Angular.fs diff --git a/src/application/sample-modules/isf/Auto Color Tone.fs b/src/renderer/src/application/sample-modules/isf/Auto Color Tone.fs similarity index 100% rename from src/application/sample-modules/isf/Auto Color Tone.fs rename to src/renderer/src/application/sample-modules/isf/Auto Color Tone.fs diff --git a/src/application/sample-modules/isf/Auto Levels.fs b/src/renderer/src/application/sample-modules/isf/Auto Levels.fs similarity index 100% rename from src/application/sample-modules/isf/Auto Levels.fs rename to src/renderer/src/application/sample-modules/isf/Auto Levels.fs diff --git a/src/application/sample-modules/isf/Auto Levels.vs b/src/renderer/src/application/sample-modules/isf/Auto Levels.vs similarity index 100% rename from src/application/sample-modules/isf/Auto Levels.vs rename to src/renderer/src/application/sample-modules/isf/Auto Levels.vs diff --git a/src/application/sample-modules/isf/Bloom.fs b/src/renderer/src/application/sample-modules/isf/Bloom.fs similarity index 100% rename from src/application/sample-modules/isf/Bloom.fs rename to src/renderer/src/application/sample-modules/isf/Bloom.fs diff --git a/src/application/sample-modules/isf/Bloom.vs b/src/renderer/src/application/sample-modules/isf/Bloom.vs similarity index 100% rename from src/application/sample-modules/isf/Bloom.vs rename to src/renderer/src/application/sample-modules/isf/Bloom.vs diff --git a/src/application/sample-modules/isf/Bounce.fs b/src/renderer/src/application/sample-modules/isf/Bounce.fs similarity index 100% rename from src/application/sample-modules/isf/Bounce.fs rename to src/renderer/src/application/sample-modules/isf/Bounce.fs diff --git a/src/application/sample-modules/isf/Bow Tie Horizontal.fs b/src/renderer/src/application/sample-modules/isf/Bow Tie Horizontal.fs similarity index 100% rename from src/application/sample-modules/isf/Bow Tie Horizontal.fs rename to src/renderer/src/application/sample-modules/isf/Bow Tie Horizontal.fs diff --git a/src/application/sample-modules/isf/Bow Tie Vertical.fs b/src/renderer/src/application/sample-modules/isf/Bow Tie Vertical.fs similarity index 100% rename from src/application/sample-modules/isf/Bow Tie Vertical.fs rename to src/renderer/src/application/sample-modules/isf/Bow Tie Vertical.fs diff --git a/src/application/sample-modules/isf/Boxinator.fs b/src/renderer/src/application/sample-modules/isf/Boxinator.fs similarity index 100% rename from src/application/sample-modules/isf/Boxinator.fs rename to src/renderer/src/application/sample-modules/isf/Boxinator.fs diff --git a/src/application/sample-modules/isf/Brick Pattern.fs b/src/renderer/src/application/sample-modules/isf/Brick Pattern.fs similarity index 100% rename from src/application/sample-modules/isf/Brick Pattern.fs rename to src/renderer/src/application/sample-modules/isf/Brick Pattern.fs diff --git a/src/application/sample-modules/isf/Bright.fs b/src/renderer/src/application/sample-modules/isf/Bright.fs similarity index 100% rename from src/application/sample-modules/isf/Bright.fs rename to src/renderer/src/application/sample-modules/isf/Bright.fs diff --git a/src/application/sample-modules/isf/BrightnessContrast.fs b/src/renderer/src/application/sample-modules/isf/BrightnessContrast.fs similarity index 100% rename from src/application/sample-modules/isf/BrightnessContrast.fs rename to src/renderer/src/application/sample-modules/isf/BrightnessContrast.fs diff --git a/src/application/sample-modules/isf/Broken LCD.fs b/src/renderer/src/application/sample-modules/isf/Broken LCD.fs similarity index 100% rename from src/application/sample-modules/isf/Broken LCD.fs rename to src/renderer/src/application/sample-modules/isf/Broken LCD.fs diff --git a/src/application/sample-modules/isf/Bump Distortion.fs b/src/renderer/src/application/sample-modules/isf/Bump Distortion.fs similarity index 100% rename from src/application/sample-modules/isf/Bump Distortion.fs rename to src/renderer/src/application/sample-modules/isf/Bump Distortion.fs diff --git a/src/application/sample-modules/isf/Burn.fs b/src/renderer/src/application/sample-modules/isf/Burn.fs similarity index 100% rename from src/application/sample-modules/isf/Burn.fs rename to src/renderer/src/application/sample-modules/isf/Burn.fs diff --git a/src/application/sample-modules/isf/Butterfly Wave Scrawler.fs b/src/renderer/src/application/sample-modules/isf/Butterfly Wave Scrawler.fs similarity index 100% rename from src/application/sample-modules/isf/Butterfly Wave Scrawler.fs rename to src/renderer/src/application/sample-modules/isf/Butterfly Wave Scrawler.fs diff --git a/src/application/sample-modules/isf/CMYK Halftone-Lookaround.fs b/src/renderer/src/application/sample-modules/isf/CMYK Halftone-Lookaround.fs similarity index 100% rename from src/application/sample-modules/isf/CMYK Halftone-Lookaround.fs rename to src/renderer/src/application/sample-modules/isf/CMYK Halftone-Lookaround.fs diff --git a/src/application/sample-modules/isf/CMYK Halftone.fs b/src/renderer/src/application/sample-modules/isf/CMYK Halftone.fs similarity index 100% rename from src/application/sample-modules/isf/CMYK Halftone.fs rename to src/renderer/src/application/sample-modules/isf/CMYK Halftone.fs diff --git a/src/application/sample-modules/isf/Channel Slide.fs b/src/renderer/src/application/sample-modules/isf/Channel Slide.fs similarity index 100% rename from src/application/sample-modules/isf/Channel Slide.fs rename to src/renderer/src/application/sample-modules/isf/Channel Slide.fs diff --git a/src/application/sample-modules/isf/Checkerboard.fs b/src/renderer/src/application/sample-modules/isf/Checkerboard.fs similarity index 100% rename from src/application/sample-modules/isf/Checkerboard.fs rename to src/renderer/src/application/sample-modules/isf/Checkerboard.fs diff --git a/src/application/sample-modules/isf/Chroma Zoom.fs b/src/renderer/src/application/sample-modules/isf/Chroma Zoom.fs similarity index 100% rename from src/application/sample-modules/isf/Chroma Zoom.fs rename to src/renderer/src/application/sample-modules/isf/Chroma Zoom.fs diff --git a/src/application/sample-modules/isf/Circle Crop.fs b/src/renderer/src/application/sample-modules/isf/Circle Crop.fs similarity index 100% rename from src/application/sample-modules/isf/Circle Crop.fs rename to src/renderer/src/application/sample-modules/isf/Circle Crop.fs diff --git a/src/application/sample-modules/isf/Circle Open.fs b/src/renderer/src/application/sample-modules/isf/Circle Open.fs similarity index 100% rename from src/application/sample-modules/isf/Circle Open.fs rename to src/renderer/src/application/sample-modules/isf/Circle Open.fs diff --git a/src/application/sample-modules/isf/Circle Splash Distortion.fs b/src/renderer/src/application/sample-modules/isf/Circle Splash Distortion.fs similarity index 100% rename from src/application/sample-modules/isf/Circle Splash Distortion.fs rename to src/renderer/src/application/sample-modules/isf/Circle Splash Distortion.fs diff --git a/src/application/sample-modules/isf/Circle Trails.fs b/src/renderer/src/application/sample-modules/isf/Circle Trails.fs similarity index 100% rename from src/application/sample-modules/isf/Circle Trails.fs rename to src/renderer/src/application/sample-modules/isf/Circle Trails.fs diff --git a/src/application/sample-modules/isf/Circle Warp.fs b/src/renderer/src/application/sample-modules/isf/Circle Warp.fs similarity index 100% rename from src/application/sample-modules/isf/Circle Warp.fs rename to src/renderer/src/application/sample-modules/isf/Circle Warp.fs diff --git a/src/application/sample-modules/isf/Circle Wrap Distortion.fs b/src/renderer/src/application/sample-modules/isf/Circle Wrap Distortion.fs similarity index 100% rename from src/application/sample-modules/isf/Circle Wrap Distortion.fs rename to src/renderer/src/application/sample-modules/isf/Circle Wrap Distortion.fs diff --git a/src/application/sample-modules/isf/Circle.fs b/src/renderer/src/application/sample-modules/isf/Circle.fs similarity index 100% rename from src/application/sample-modules/isf/Circle.fs rename to src/renderer/src/application/sample-modules/isf/Circle.fs diff --git a/src/application/sample-modules/isf/Circuits.fs b/src/renderer/src/application/sample-modules/isf/Circuits.fs similarity index 100% rename from src/application/sample-modules/isf/Circuits.fs rename to src/renderer/src/application/sample-modules/isf/Circuits.fs diff --git a/src/application/sample-modules/isf/Circular Feedback Mask.fs b/src/renderer/src/application/sample-modules/isf/Circular Feedback Mask.fs similarity index 100% rename from src/application/sample-modules/isf/Circular Feedback Mask.fs rename to src/renderer/src/application/sample-modules/isf/Circular Feedback Mask.fs diff --git a/src/application/sample-modules/isf/Circular Screen.fs b/src/renderer/src/application/sample-modules/isf/Circular Screen.fs similarity index 100% rename from src/application/sample-modules/isf/Circular Screen.fs rename to src/renderer/src/application/sample-modules/isf/Circular Screen.fs diff --git a/src/application/sample-modules/isf/Circular Screen.vs b/src/renderer/src/application/sample-modules/isf/Circular Screen.vs similarity index 100% rename from src/application/sample-modules/isf/Circular Screen.vs rename to src/renderer/src/application/sample-modules/isf/Circular Screen.vs diff --git a/src/application/sample-modules/isf/City Lights.fs b/src/renderer/src/application/sample-modules/isf/City Lights.fs similarity index 100% rename from src/application/sample-modules/isf/City Lights.fs rename to src/renderer/src/application/sample-modules/isf/City Lights.fs diff --git a/src/application/sample-modules/isf/City Lights.vs b/src/renderer/src/application/sample-modules/isf/City Lights.vs similarity index 100% rename from src/application/sample-modules/isf/City Lights.vs rename to src/renderer/src/application/sample-modules/isf/City Lights.vs diff --git a/src/application/sample-modules/isf/Collage.fs b/src/renderer/src/application/sample-modules/isf/Collage.fs similarity index 100% rename from src/application/sample-modules/isf/Collage.fs rename to src/renderer/src/application/sample-modules/isf/Collage.fs diff --git a/src/application/sample-modules/isf/CollapsingArchitecture.fs b/src/renderer/src/application/sample-modules/isf/CollapsingArchitecture.fs similarity index 100% rename from src/application/sample-modules/isf/CollapsingArchitecture.fs rename to src/renderer/src/application/sample-modules/isf/CollapsingArchitecture.fs diff --git a/src/application/sample-modules/isf/Color Blowout.fs b/src/renderer/src/application/sample-modules/isf/Color Blowout.fs similarity index 100% rename from src/application/sample-modules/isf/Color Blowout.fs rename to src/renderer/src/application/sample-modules/isf/Color Blowout.fs diff --git a/src/application/sample-modules/isf/Color Blowout.vs b/src/renderer/src/application/sample-modules/isf/Color Blowout.vs similarity index 100% rename from src/application/sample-modules/isf/Color Blowout.vs rename to src/renderer/src/application/sample-modules/isf/Color Blowout.vs diff --git a/src/application/sample-modules/isf/Color Controls.fs b/src/renderer/src/application/sample-modules/isf/Color Controls.fs similarity index 100% rename from src/application/sample-modules/isf/Color Controls.fs rename to src/renderer/src/application/sample-modules/isf/Color Controls.fs diff --git a/src/application/sample-modules/isf/Color History.fs b/src/renderer/src/application/sample-modules/isf/Color History.fs similarity index 100% rename from src/application/sample-modules/isf/Color History.fs rename to src/renderer/src/application/sample-modules/isf/Color History.fs diff --git a/src/application/sample-modules/isf/Color Invert.fs b/src/renderer/src/application/sample-modules/isf/Color Invert.fs similarity index 100% rename from src/application/sample-modules/isf/Color Invert.fs rename to src/renderer/src/application/sample-modules/isf/Color Invert.fs diff --git a/src/application/sample-modules/isf/Color Levels.fs b/src/renderer/src/application/sample-modules/isf/Color Levels.fs similarity index 100% rename from src/application/sample-modules/isf/Color Levels.fs rename to src/renderer/src/application/sample-modules/isf/Color Levels.fs diff --git a/src/application/sample-modules/isf/Color Monochrome.fs b/src/renderer/src/application/sample-modules/isf/Color Monochrome.fs similarity index 100% rename from src/application/sample-modules/isf/Color Monochrome.fs rename to src/renderer/src/application/sample-modules/isf/Color Monochrome.fs diff --git a/src/application/sample-modules/isf/Color Phase.fs b/src/renderer/src/application/sample-modules/isf/Color Phase.fs similarity index 100% rename from src/application/sample-modules/isf/Color Phase.fs rename to src/renderer/src/application/sample-modules/isf/Color Phase.fs diff --git a/src/application/sample-modules/isf/Color Posterize.fs b/src/renderer/src/application/sample-modules/isf/Color Posterize.fs similarity index 100% rename from src/application/sample-modules/isf/Color Posterize.fs rename to src/renderer/src/application/sample-modules/isf/Color Posterize.fs diff --git a/src/application/sample-modules/isf/Color Relookup.fs b/src/renderer/src/application/sample-modules/isf/Color Relookup.fs similarity index 100% rename from src/application/sample-modules/isf/Color Relookup.fs rename to src/renderer/src/application/sample-modules/isf/Color Relookup.fs diff --git a/src/application/sample-modules/isf/Color Scales.fs b/src/renderer/src/application/sample-modules/isf/Color Scales.fs similarity index 100% rename from src/application/sample-modules/isf/Color Scales.fs rename to src/renderer/src/application/sample-modules/isf/Color Scales.fs diff --git a/src/application/sample-modules/isf/Color Schemes.fs b/src/renderer/src/application/sample-modules/isf/Color Schemes.fs similarity index 100% rename from src/application/sample-modules/isf/Color Schemes.fs rename to src/renderer/src/application/sample-modules/isf/Color Schemes.fs diff --git a/src/application/sample-modules/isf/Color Test Grid.fs b/src/renderer/src/application/sample-modules/isf/Color Test Grid.fs similarity index 100% rename from src/application/sample-modules/isf/Color Test Grid.fs rename to src/renderer/src/application/sample-modules/isf/Color Test Grid.fs diff --git a/src/application/sample-modules/isf/Colour Distance.fs b/src/renderer/src/application/sample-modules/isf/Colour Distance.fs similarity index 100% rename from src/application/sample-modules/isf/Colour Distance.fs rename to src/renderer/src/application/sample-modules/isf/Colour Distance.fs diff --git a/src/application/sample-modules/isf/Comet Tails.fs b/src/renderer/src/application/sample-modules/isf/Comet Tails.fs similarity index 100% rename from src/application/sample-modules/isf/Comet Tails.fs rename to src/renderer/src/application/sample-modules/isf/Comet Tails.fs diff --git a/src/application/sample-modules/isf/Convergence.fs b/src/renderer/src/application/sample-modules/isf/Convergence.fs similarity index 100% rename from src/application/sample-modules/isf/Convergence.fs rename to src/renderer/src/application/sample-modules/isf/Convergence.fs diff --git a/src/application/sample-modules/isf/Corner Color Tint.fs b/src/renderer/src/application/sample-modules/isf/Corner Color Tint.fs similarity index 100% rename from src/application/sample-modules/isf/Corner Color Tint.fs rename to src/renderer/src/application/sample-modules/isf/Corner Color Tint.fs diff --git a/src/application/sample-modules/isf/Corner Colors.fs b/src/renderer/src/application/sample-modules/isf/Corner Colors.fs similarity index 100% rename from src/application/sample-modules/isf/Corner Colors.fs rename to src/renderer/src/application/sample-modules/isf/Corner Colors.fs diff --git a/src/application/sample-modules/isf/Crazy Parametric Fun.fs b/src/renderer/src/application/sample-modules/isf/Crazy Parametric Fun.fs similarity index 100% rename from src/application/sample-modules/isf/Crazy Parametric Fun.fs rename to src/renderer/src/application/sample-modules/isf/Crazy Parametric Fun.fs diff --git a/src/application/sample-modules/isf/CrossZoom.fs b/src/renderer/src/application/sample-modules/isf/CrossZoom.fs similarity index 100% rename from src/application/sample-modules/isf/CrossZoom.fs rename to src/renderer/src/application/sample-modules/isf/CrossZoom.fs diff --git a/src/application/sample-modules/isf/Crosshatch.fs b/src/renderer/src/application/sample-modules/isf/Crosshatch.fs similarity index 100% rename from src/application/sample-modules/isf/Crosshatch.fs rename to src/renderer/src/application/sample-modules/isf/Crosshatch.fs diff --git a/src/application/sample-modules/isf/Crosswarp.fs b/src/renderer/src/application/sample-modules/isf/Crosswarp.fs similarity index 100% rename from src/application/sample-modules/isf/Crosswarp.fs rename to src/renderer/src/application/sample-modules/isf/Crosswarp.fs diff --git a/src/application/sample-modules/isf/Cubic Warp.fs b/src/renderer/src/application/sample-modules/isf/Cubic Warp.fs similarity index 100% rename from src/application/sample-modules/isf/Cubic Warp.fs rename to src/renderer/src/application/sample-modules/isf/Cubic Warp.fs diff --git a/src/application/sample-modules/isf/Deinterlace.fs b/src/renderer/src/application/sample-modules/isf/Deinterlace.fs similarity index 100% rename from src/application/sample-modules/isf/Deinterlace.fs rename to src/renderer/src/application/sample-modules/isf/Deinterlace.fs diff --git a/src/application/sample-modules/isf/Diagonal Blur.fs b/src/renderer/src/application/sample-modules/isf/Diagonal Blur.fs similarity index 100% rename from src/application/sample-modules/isf/Diagonal Blur.fs rename to src/renderer/src/application/sample-modules/isf/Diagonal Blur.fs diff --git a/src/application/sample-modules/isf/Diagonalize.fs b/src/renderer/src/application/sample-modules/isf/Diagonalize.fs similarity index 100% rename from src/application/sample-modules/isf/Diagonalize.fs rename to src/renderer/src/application/sample-modules/isf/Diagonalize.fs diff --git a/src/application/sample-modules/isf/Digital Clock.fs b/src/renderer/src/application/sample-modules/isf/Digital Clock.fs similarity index 100% rename from src/application/sample-modules/isf/Digital Clock.fs rename to src/renderer/src/application/sample-modules/isf/Digital Clock.fs diff --git a/src/application/sample-modules/isf/Directional Warp.fs b/src/renderer/src/application/sample-modules/isf/Directional Warp.fs similarity index 100% rename from src/application/sample-modules/isf/Directional Warp.fs rename to src/renderer/src/application/sample-modules/isf/Directional Warp.fs diff --git a/src/application/sample-modules/isf/Directional Wipe.fs b/src/renderer/src/application/sample-modules/isf/Directional Wipe.fs similarity index 100% rename from src/application/sample-modules/isf/Directional Wipe.fs rename to src/renderer/src/application/sample-modules/isf/Directional Wipe.fs diff --git a/src/application/sample-modules/isf/Directional.fs b/src/renderer/src/application/sample-modules/isf/Directional.fs similarity index 100% rename from src/application/sample-modules/isf/Directional.fs rename to src/renderer/src/application/sample-modules/isf/Directional.fs diff --git a/src/application/sample-modules/isf/Dirty Lens.fs b/src/renderer/src/application/sample-modules/isf/Dirty Lens.fs similarity index 100% rename from src/application/sample-modules/isf/Dirty Lens.fs rename to src/renderer/src/application/sample-modules/isf/Dirty Lens.fs diff --git a/src/application/sample-modules/isf/Displace.fs b/src/renderer/src/application/sample-modules/isf/Displace.fs similarity index 100% rename from src/application/sample-modules/isf/Displace.fs rename to src/renderer/src/application/sample-modules/isf/Displace.fs diff --git a/src/application/sample-modules/isf/Displacement.fs b/src/renderer/src/application/sample-modules/isf/Displacement.fs similarity index 100% rename from src/application/sample-modules/isf/Displacement.fs rename to src/renderer/src/application/sample-modules/isf/Displacement.fs diff --git a/src/application/sample-modules/isf/Dither-Bayer.fs b/src/renderer/src/application/sample-modules/isf/Dither-Bayer.fs similarity index 100% rename from src/application/sample-modules/isf/Dither-Bayer.fs rename to src/renderer/src/application/sample-modules/isf/Dither-Bayer.fs diff --git a/src/application/sample-modules/isf/Doom Screen Transition.fs b/src/renderer/src/application/sample-modules/isf/Doom Screen Transition.fs similarity index 100% rename from src/application/sample-modules/isf/Doom Screen Transition.fs rename to src/renderer/src/application/sample-modules/isf/Doom Screen Transition.fs diff --git a/src/application/sample-modules/isf/Doorway.fs b/src/renderer/src/application/sample-modules/isf/Doorway.fs similarity index 100% rename from src/application/sample-modules/isf/Doorway.fs rename to src/renderer/src/application/sample-modules/isf/Doorway.fs diff --git a/src/application/sample-modules/isf/Dot Screen.fs b/src/renderer/src/application/sample-modules/isf/Dot Screen.fs similarity index 100% rename from src/application/sample-modules/isf/Dot Screen.fs rename to src/renderer/src/application/sample-modules/isf/Dot Screen.fs diff --git a/src/application/sample-modules/isf/Dot Screen.vs b/src/renderer/src/application/sample-modules/isf/Dot Screen.vs similarity index 100% rename from src/application/sample-modules/isf/Dot Screen.vs rename to src/renderer/src/application/sample-modules/isf/Dot Screen.vs diff --git a/src/application/sample-modules/isf/Double Vision.fs b/src/renderer/src/application/sample-modules/isf/Double Vision.fs similarity index 100% rename from src/application/sample-modules/isf/Double Vision.fs rename to src/renderer/src/application/sample-modules/isf/Double Vision.fs diff --git a/src/application/sample-modules/isf/Dreamy Zoom.fs b/src/renderer/src/application/sample-modules/isf/Dreamy Zoom.fs similarity index 100% rename from src/application/sample-modules/isf/Dreamy Zoom.fs rename to src/renderer/src/application/sample-modules/isf/Dreamy Zoom.fs diff --git a/src/application/sample-modules/isf/Dreamy.fs b/src/renderer/src/application/sample-modules/isf/Dreamy.fs similarity index 100% rename from src/application/sample-modules/isf/Dreamy.fs rename to src/renderer/src/application/sample-modules/isf/Dreamy.fs diff --git a/src/application/sample-modules/isf/Dual Side Scroller And Flip.fs b/src/renderer/src/application/sample-modules/isf/Dual Side Scroller And Flip.fs similarity index 100% rename from src/application/sample-modules/isf/Dual Side Scroller And Flip.fs rename to src/renderer/src/application/sample-modules/isf/Dual Side Scroller And Flip.fs diff --git a/src/application/sample-modules/isf/Duotone.fs b/src/renderer/src/application/sample-modules/isf/Duotone.fs similarity index 100% rename from src/application/sample-modules/isf/Duotone.fs rename to src/renderer/src/application/sample-modules/isf/Duotone.fs diff --git a/src/application/sample-modules/isf/Echo Trace.fs b/src/renderer/src/application/sample-modules/isf/Echo Trace.fs similarity index 100% rename from src/application/sample-modules/isf/Echo Trace.fs rename to src/renderer/src/application/sample-modules/isf/Echo Trace.fs diff --git a/src/application/sample-modules/isf/Edge Blowout.fs b/src/renderer/src/application/sample-modules/isf/Edge Blowout.fs similarity index 100% rename from src/application/sample-modules/isf/Edge Blowout.fs rename to src/renderer/src/application/sample-modules/isf/Edge Blowout.fs diff --git a/src/application/sample-modules/isf/Edge Blur.fs b/src/renderer/src/application/sample-modules/isf/Edge Blur.fs similarity index 100% rename from src/application/sample-modules/isf/Edge Blur.fs rename to src/renderer/src/application/sample-modules/isf/Edge Blur.fs diff --git a/src/application/sample-modules/isf/Edge Blur.vs b/src/renderer/src/application/sample-modules/isf/Edge Blur.vs similarity index 100% rename from src/application/sample-modules/isf/Edge Blur.vs rename to src/renderer/src/application/sample-modules/isf/Edge Blur.vs diff --git a/src/application/sample-modules/isf/Edge Distort.fs b/src/renderer/src/application/sample-modules/isf/Edge Distort.fs similarity index 100% rename from src/application/sample-modules/isf/Edge Distort.fs rename to src/renderer/src/application/sample-modules/isf/Edge Distort.fs diff --git a/src/application/sample-modules/isf/Edge Distort.vs b/src/renderer/src/application/sample-modules/isf/Edge Distort.vs similarity index 100% rename from src/application/sample-modules/isf/Edge Distort.vs rename to src/renderer/src/application/sample-modules/isf/Edge Distort.vs diff --git a/src/application/sample-modules/isf/Edge Trace.fs b/src/renderer/src/application/sample-modules/isf/Edge Trace.fs similarity index 100% rename from src/application/sample-modules/isf/Edge Trace.fs rename to src/renderer/src/application/sample-modules/isf/Edge Trace.fs diff --git a/src/application/sample-modules/isf/Edge Trace.vs b/src/renderer/src/application/sample-modules/isf/Edge Trace.vs similarity index 100% rename from src/application/sample-modules/isf/Edge Trace.vs rename to src/renderer/src/application/sample-modules/isf/Edge Trace.vs diff --git a/src/application/sample-modules/isf/Edges.fs b/src/renderer/src/application/sample-modules/isf/Edges.fs similarity index 100% rename from src/application/sample-modules/isf/Edges.fs rename to src/renderer/src/application/sample-modules/isf/Edges.fs diff --git a/src/application/sample-modules/isf/Edges.vs b/src/renderer/src/application/sample-modules/isf/Edges.vs similarity index 100% rename from src/application/sample-modules/isf/Edges.vs rename to src/renderer/src/application/sample-modules/isf/Edges.vs diff --git a/src/application/sample-modules/isf/Emboss.fs b/src/renderer/src/application/sample-modules/isf/Emboss.fs similarity index 100% rename from src/application/sample-modules/isf/Emboss.fs rename to src/renderer/src/application/sample-modules/isf/Emboss.fs diff --git a/src/application/sample-modules/isf/Emboss.vs b/src/renderer/src/application/sample-modules/isf/Emboss.vs similarity index 100% rename from src/application/sample-modules/isf/Emboss.vs rename to src/renderer/src/application/sample-modules/isf/Emboss.vs diff --git a/src/application/sample-modules/isf/Etch-a-Sketch.fs b/src/renderer/src/application/sample-modules/isf/Etch-a-Sketch.fs similarity index 100% rename from src/application/sample-modules/isf/Etch-a-Sketch.fs rename to src/renderer/src/application/sample-modules/isf/Etch-a-Sketch.fs diff --git a/src/application/sample-modules/isf/Exposure Adjust.fs b/src/renderer/src/application/sample-modules/isf/Exposure Adjust.fs similarity index 100% rename from src/application/sample-modules/isf/Exposure Adjust.fs rename to src/renderer/src/application/sample-modules/isf/Exposure Adjust.fs diff --git a/src/application/sample-modules/isf/Fade Color.fs b/src/renderer/src/application/sample-modules/isf/Fade Color.fs similarity index 100% rename from src/application/sample-modules/isf/Fade Color.fs rename to src/renderer/src/application/sample-modules/isf/Fade Color.fs diff --git a/src/application/sample-modules/isf/Fade Gray Scale.fs b/src/renderer/src/application/sample-modules/isf/Fade Gray Scale.fs similarity index 100% rename from src/application/sample-modules/isf/Fade Gray Scale.fs rename to src/renderer/src/application/sample-modules/isf/Fade Gray Scale.fs diff --git a/src/application/sample-modules/isf/Fade.fs b/src/renderer/src/application/sample-modules/isf/Fade.fs similarity index 100% rename from src/application/sample-modules/isf/Fade.fs rename to src/renderer/src/application/sample-modules/isf/Fade.fs diff --git a/src/application/sample-modules/isf/False Color.fs b/src/renderer/src/application/sample-modules/isf/False Color.fs similarity index 100% rename from src/application/sample-modules/isf/False Color.fs rename to src/renderer/src/application/sample-modules/isf/False Color.fs diff --git a/src/application/sample-modules/isf/Fast Blur.fs b/src/renderer/src/application/sample-modules/isf/Fast Blur.fs similarity index 100% rename from src/application/sample-modules/isf/Fast Blur.fs rename to src/renderer/src/application/sample-modules/isf/Fast Blur.fs diff --git a/src/application/sample-modules/isf/Fast Blur.vs b/src/renderer/src/application/sample-modules/isf/Fast Blur.vs similarity index 100% rename from src/application/sample-modules/isf/Fast Blur.vs rename to src/renderer/src/application/sample-modules/isf/Fast Blur.vs diff --git a/src/application/sample-modules/isf/FastMosh.fs b/src/renderer/src/application/sample-modules/isf/FastMosh.fs similarity index 100% rename from src/application/sample-modules/isf/FastMosh.fs rename to src/renderer/src/application/sample-modules/isf/FastMosh.fs diff --git a/src/application/sample-modules/isf/FastMosh.vs b/src/renderer/src/application/sample-modules/isf/FastMosh.vs similarity index 100% rename from src/application/sample-modules/isf/FastMosh.vs rename to src/renderer/src/application/sample-modules/isf/FastMosh.vs diff --git a/src/application/sample-modules/isf/Film Burn.fs b/src/renderer/src/application/sample-modules/isf/Film Burn.fs similarity index 100% rename from src/application/sample-modules/isf/Film Burn.fs rename to src/renderer/src/application/sample-modules/isf/Film Burn.fs diff --git a/src/application/sample-modules/isf/Flip H.fs b/src/renderer/src/application/sample-modules/isf/Flip H.fs similarity index 100% rename from src/application/sample-modules/isf/Flip H.fs rename to src/renderer/src/application/sample-modules/isf/Flip H.fs diff --git a/src/application/sample-modules/isf/Flip V.fs b/src/renderer/src/application/sample-modules/isf/Flip V.fs similarity index 100% rename from src/application/sample-modules/isf/Flip V.fs rename to src/renderer/src/application/sample-modules/isf/Flip V.fs diff --git a/src/application/sample-modules/isf/Flipbook.fs b/src/renderer/src/application/sample-modules/isf/Flipbook.fs similarity index 100% rename from src/application/sample-modules/isf/Flipbook.fs rename to src/renderer/src/application/sample-modules/isf/Flipbook.fs diff --git a/src/application/sample-modules/isf/Fly Eye.fs b/src/renderer/src/application/sample-modules/isf/Fly Eye.fs similarity index 100% rename from src/application/sample-modules/isf/Fly Eye.fs rename to src/renderer/src/application/sample-modules/isf/Fly Eye.fs diff --git a/src/application/sample-modules/isf/FractilianParabolicCircleInversion.fs b/src/renderer/src/application/sample-modules/isf/FractilianParabolicCircleInversion.fs similarity index 100% rename from src/application/sample-modules/isf/FractilianParabolicCircleInversion.fs rename to src/renderer/src/application/sample-modules/isf/FractilianParabolicCircleInversion.fs diff --git a/src/application/sample-modules/isf/Freeze Frame.fs b/src/renderer/src/application/sample-modules/isf/Freeze Frame.fs similarity index 100% rename from src/application/sample-modules/isf/Freeze Frame.fs rename to src/renderer/src/application/sample-modules/isf/Freeze Frame.fs diff --git a/src/application/sample-modules/isf/Frosted Glass.fs b/src/renderer/src/application/sample-modules/isf/Frosted Glass.fs similarity index 100% rename from src/application/sample-modules/isf/Frosted Glass.fs rename to src/renderer/src/application/sample-modules/isf/Frosted Glass.fs diff --git a/src/application/sample-modules/isf/Gamma Correction.fs b/src/renderer/src/application/sample-modules/isf/Gamma Correction.fs similarity index 100% rename from src/application/sample-modules/isf/Gamma Correction.fs rename to src/renderer/src/application/sample-modules/isf/Gamma Correction.fs diff --git a/src/application/sample-modules/isf/Ghosting.fs b/src/renderer/src/application/sample-modules/isf/Ghosting.fs similarity index 100% rename from src/application/sample-modules/isf/Ghosting.fs rename to src/renderer/src/application/sample-modules/isf/Ghosting.fs diff --git a/src/application/sample-modules/isf/Glitch Displace.fs b/src/renderer/src/application/sample-modules/isf/Glitch Displace.fs similarity index 100% rename from src/application/sample-modules/isf/Glitch Displace.fs rename to src/renderer/src/application/sample-modules/isf/Glitch Displace.fs diff --git a/src/application/sample-modules/isf/Glitch Memories.fs b/src/renderer/src/application/sample-modules/isf/Glitch Memories.fs similarity index 100% rename from src/application/sample-modules/isf/Glitch Memories.fs rename to src/renderer/src/application/sample-modules/isf/Glitch Memories.fs diff --git a/src/application/sample-modules/isf/Glitch Shifter.fs b/src/renderer/src/application/sample-modules/isf/Glitch Shifter.fs similarity index 100% rename from src/application/sample-modules/isf/Glitch Shifter.fs rename to src/renderer/src/application/sample-modules/isf/Glitch Shifter.fs diff --git a/src/application/sample-modules/isf/Gloom.fs b/src/renderer/src/application/sample-modules/isf/Gloom.fs similarity index 100% rename from src/application/sample-modules/isf/Gloom.fs rename to src/renderer/src/application/sample-modules/isf/Gloom.fs diff --git a/src/application/sample-modules/isf/Gloom.vs b/src/renderer/src/application/sample-modules/isf/Gloom.vs similarity index 100% rename from src/application/sample-modules/isf/Gloom.vs rename to src/renderer/src/application/sample-modules/isf/Gloom.vs diff --git a/src/application/sample-modules/isf/Glow-Fast.fs b/src/renderer/src/application/sample-modules/isf/Glow-Fast.fs similarity index 100% rename from src/application/sample-modules/isf/Glow-Fast.fs rename to src/renderer/src/application/sample-modules/isf/Glow-Fast.fs diff --git a/src/application/sample-modules/isf/Glow-Fast.vs b/src/renderer/src/application/sample-modules/isf/Glow-Fast.vs similarity index 100% rename from src/application/sample-modules/isf/Glow-Fast.vs rename to src/renderer/src/application/sample-modules/isf/Glow-Fast.vs diff --git a/src/application/sample-modules/isf/Glow.fs b/src/renderer/src/application/sample-modules/isf/Glow.fs similarity index 100% rename from src/application/sample-modules/isf/Glow.fs rename to src/renderer/src/application/sample-modules/isf/Glow.fs diff --git a/src/application/sample-modules/isf/Glow.vs b/src/renderer/src/application/sample-modules/isf/Glow.vs similarity index 100% rename from src/application/sample-modules/isf/Glow.vs rename to src/renderer/src/application/sample-modules/isf/Glow.vs diff --git a/src/application/sample-modules/isf/Graph Paper.fs b/src/renderer/src/application/sample-modules/isf/Graph Paper.fs similarity index 100% rename from src/application/sample-modules/isf/Graph Paper.fs rename to src/renderer/src/application/sample-modules/isf/Graph Paper.fs diff --git a/src/application/sample-modules/isf/GreatBallOfFire.fs b/src/renderer/src/application/sample-modules/isf/GreatBallOfFire.fs similarity index 100% rename from src/application/sample-modules/isf/GreatBallOfFire.fs rename to src/renderer/src/application/sample-modules/isf/GreatBallOfFire.fs diff --git a/src/application/sample-modules/isf/Grid Flip.fs b/src/renderer/src/application/sample-modules/isf/Grid Flip.fs similarity index 100% rename from src/application/sample-modules/isf/Grid Flip.fs rename to src/renderer/src/application/sample-modules/isf/Grid Flip.fs diff --git a/src/application/sample-modules/isf/Grid Warp.fs b/src/renderer/src/application/sample-modules/isf/Grid Warp.fs similarity index 100% rename from src/application/sample-modules/isf/Grid Warp.fs rename to src/renderer/src/application/sample-modules/isf/Grid Warp.fs diff --git a/src/application/sample-modules/isf/HSVtoRGB.fs b/src/renderer/src/application/sample-modules/isf/HSVtoRGB.fs similarity index 100% rename from src/application/sample-modules/isf/HSVtoRGB.fs rename to src/renderer/src/application/sample-modules/isf/HSVtoRGB.fs diff --git a/src/application/sample-modules/isf/Hatch Blur.fs b/src/renderer/src/application/sample-modules/isf/Hatch Blur.fs similarity index 100% rename from src/application/sample-modules/isf/Hatch Blur.fs rename to src/renderer/src/application/sample-modules/isf/Hatch Blur.fs diff --git a/src/application/sample-modules/isf/Heart Transition.fs b/src/renderer/src/application/sample-modules/isf/Heart Transition.fs similarity index 100% rename from src/application/sample-modules/isf/Heart Transition.fs rename to src/renderer/src/application/sample-modules/isf/Heart Transition.fs diff --git a/src/application/sample-modules/isf/Heart.fs b/src/renderer/src/application/sample-modules/isf/Heart.fs similarity index 100% rename from src/application/sample-modules/isf/Heart.fs rename to src/renderer/src/application/sample-modules/isf/Heart.fs diff --git a/src/application/sample-modules/isf/HexVortex.fs b/src/renderer/src/application/sample-modules/isf/HexVortex.fs similarity index 100% rename from src/application/sample-modules/isf/HexVortex.fs rename to src/renderer/src/application/sample-modules/isf/HexVortex.fs diff --git a/src/application/sample-modules/isf/Hexagonalize.fs b/src/renderer/src/application/sample-modules/isf/Hexagonalize.fs similarity index 100% rename from src/application/sample-modules/isf/Hexagonalize.fs rename to src/renderer/src/application/sample-modules/isf/Hexagonalize.fs diff --git a/src/application/sample-modules/isf/Histogram Viewer.fs b/src/renderer/src/application/sample-modules/isf/Histogram Viewer.fs similarity index 100% rename from src/application/sample-modules/isf/Histogram Viewer.fs rename to src/renderer/src/application/sample-modules/isf/Histogram Viewer.fs diff --git a/src/application/sample-modules/isf/HorizVertHold.fs b/src/renderer/src/application/sample-modules/isf/HorizVertHold.fs similarity index 100% rename from src/application/sample-modules/isf/HorizVertHold.fs rename to src/renderer/src/application/sample-modules/isf/HorizVertHold.fs diff --git a/src/application/sample-modules/isf/Hue-Saturation.fs b/src/renderer/src/application/sample-modules/isf/Hue-Saturation.fs similarity index 100% rename from src/application/sample-modules/isf/Hue-Saturation.fs rename to src/renderer/src/application/sample-modules/isf/Hue-Saturation.fs diff --git a/src/application/sample-modules/isf/Hyperspace.fs b/src/renderer/src/application/sample-modules/isf/Hyperspace.fs similarity index 100% rename from src/application/sample-modules/isf/Hyperspace.fs rename to src/renderer/src/application/sample-modules/isf/Hyperspace.fs diff --git a/src/application/sample-modules/isf/Interlace Mirror.fs b/src/renderer/src/application/sample-modules/isf/Interlace Mirror.fs similarity index 100% rename from src/application/sample-modules/isf/Interlace Mirror.fs rename to src/renderer/src/application/sample-modules/isf/Interlace Mirror.fs diff --git a/src/application/sample-modules/isf/Interlace.fs b/src/renderer/src/application/sample-modules/isf/Interlace.fs similarity index 100% rename from src/application/sample-modules/isf/Interlace.fs rename to src/renderer/src/application/sample-modules/isf/Interlace.fs diff --git a/src/application/sample-modules/isf/Inverted Page Curl.fs b/src/renderer/src/application/sample-modules/isf/Inverted Page Curl.fs similarity index 100% rename from src/application/sample-modules/isf/Inverted Page Curl.fs rename to src/renderer/src/application/sample-modules/isf/Inverted Page Curl.fs diff --git a/src/application/sample-modules/isf/Kaleidoscope Tile.fs b/src/renderer/src/application/sample-modules/isf/Kaleidoscope Tile.fs similarity index 100% rename from src/application/sample-modules/isf/Kaleidoscope Tile.fs rename to src/renderer/src/application/sample-modules/isf/Kaleidoscope Tile.fs diff --git a/src/application/sample-modules/isf/Kaleidoscope Transition.fs b/src/renderer/src/application/sample-modules/isf/Kaleidoscope Transition.fs similarity index 100% rename from src/application/sample-modules/isf/Kaleidoscope Transition.fs rename to src/renderer/src/application/sample-modules/isf/Kaleidoscope Transition.fs diff --git a/src/application/sample-modules/isf/Kaleidoscope.fs b/src/renderer/src/application/sample-modules/isf/Kaleidoscope.fs similarity index 100% rename from src/application/sample-modules/isf/Kaleidoscope.fs rename to src/renderer/src/application/sample-modules/isf/Kaleidoscope.fs diff --git a/src/application/sample-modules/isf/Key Frame Artifacts.fs b/src/renderer/src/application/sample-modules/isf/Key Frame Artifacts.fs similarity index 100% rename from src/application/sample-modules/isf/Key Frame Artifacts.fs rename to src/renderer/src/application/sample-modules/isf/Key Frame Artifacts.fs diff --git a/src/application/sample-modules/isf/Layer Mask.fs b/src/renderer/src/application/sample-modules/isf/Layer Mask.fs similarity index 100% rename from src/application/sample-modules/isf/Layer Mask.fs rename to src/renderer/src/application/sample-modules/isf/Layer Mask.fs diff --git a/src/application/sample-modules/isf/Layer Position.fs b/src/renderer/src/application/sample-modules/isf/Layer Position.fs similarity index 100% rename from src/application/sample-modules/isf/Layer Position.fs rename to src/renderer/src/application/sample-modules/isf/Layer Position.fs diff --git a/src/application/sample-modules/isf/Lens Flare.fs b/src/renderer/src/application/sample-modules/isf/Lens Flare.fs similarity index 100% rename from src/application/sample-modules/isf/Lens Flare.fs rename to src/renderer/src/application/sample-modules/isf/Lens Flare.fs diff --git a/src/application/sample-modules/isf/Lens Flare.vs b/src/renderer/src/application/sample-modules/isf/Lens Flare.vs similarity index 100% rename from src/application/sample-modules/isf/Lens Flare.vs rename to src/renderer/src/application/sample-modules/isf/Lens Flare.vs diff --git a/src/application/sample-modules/isf/Life.fs b/src/renderer/src/application/sample-modules/isf/Life.fs similarity index 100% rename from src/application/sample-modules/isf/Life.fs rename to src/renderer/src/application/sample-modules/isf/Life.fs diff --git a/src/application/sample-modules/isf/Life.vs b/src/renderer/src/application/sample-modules/isf/Life.vs similarity index 100% rename from src/application/sample-modules/isf/Life.vs rename to src/renderer/src/application/sample-modules/isf/Life.vs diff --git a/src/application/sample-modules/isf/Line Screen.fs b/src/renderer/src/application/sample-modules/isf/Line Screen.fs similarity index 100% rename from src/application/sample-modules/isf/Line Screen.fs rename to src/renderer/src/application/sample-modules/isf/Line Screen.fs diff --git a/src/application/sample-modules/isf/Line Screen.vs b/src/renderer/src/application/sample-modules/isf/Line Screen.vs similarity index 100% rename from src/application/sample-modules/isf/Line Screen.vs rename to src/renderer/src/application/sample-modules/isf/Line Screen.vs diff --git a/src/application/sample-modules/isf/Linear Blur.fs b/src/renderer/src/application/sample-modules/isf/Linear Blur.fs similarity index 100% rename from src/application/sample-modules/isf/Linear Blur.fs rename to src/renderer/src/application/sample-modules/isf/Linear Blur.fs diff --git a/src/application/sample-modules/isf/Linear Gradient.fs b/src/renderer/src/application/sample-modules/isf/Linear Gradient.fs similarity index 100% rename from src/application/sample-modules/isf/Linear Gradient.fs rename to src/renderer/src/application/sample-modules/isf/Linear Gradient.fs diff --git a/src/application/sample-modules/isf/Lines.fs b/src/renderer/src/application/sample-modules/isf/Lines.fs similarity index 100% rename from src/application/sample-modules/isf/Lines.fs rename to src/renderer/src/application/sample-modules/isf/Lines.fs diff --git a/src/application/sample-modules/isf/LogTransWarpSpiral.fs b/src/renderer/src/application/sample-modules/isf/LogTransWarpSpiral.fs similarity index 100% rename from src/application/sample-modules/isf/LogTransWarpSpiral.fs rename to src/renderer/src/application/sample-modules/isf/LogTransWarpSpiral.fs diff --git a/src/application/sample-modules/isf/Long Exposure.fs b/src/renderer/src/application/sample-modules/isf/Long Exposure.fs similarity index 100% rename from src/application/sample-modules/isf/Long Exposure.fs rename to src/renderer/src/application/sample-modules/isf/Long Exposure.fs diff --git a/src/application/sample-modules/isf/Luma Transition.fs b/src/renderer/src/application/sample-modules/isf/Luma Transition.fs similarity index 100% rename from src/application/sample-modules/isf/Luma Transition.fs rename to src/renderer/src/application/sample-modules/isf/Luma Transition.fs diff --git a/src/application/sample-modules/isf/Luminance Melt.fs b/src/renderer/src/application/sample-modules/isf/Luminance Melt.fs similarity index 100% rename from src/application/sample-modules/isf/Luminance Melt.fs rename to src/renderer/src/application/sample-modules/isf/Luminance Melt.fs diff --git a/src/application/sample-modules/isf/Luminance Posterize.fs b/src/renderer/src/application/sample-modules/isf/Luminance Posterize.fs similarity index 100% rename from src/application/sample-modules/isf/Luminance Posterize.fs rename to src/renderer/src/application/sample-modules/isf/Luminance Posterize.fs diff --git a/src/application/sample-modules/isf/MBOX3.fs b/src/renderer/src/application/sample-modules/isf/MBOX3.fs similarity index 100% rename from src/application/sample-modules/isf/MBOX3.fs rename to src/renderer/src/application/sample-modules/isf/MBOX3.fs diff --git a/src/application/sample-modules/isf/Maximum Component.fs b/src/renderer/src/application/sample-modules/isf/Maximum Component.fs similarity index 100% rename from src/application/sample-modules/isf/Maximum Component.fs rename to src/renderer/src/application/sample-modules/isf/Maximum Component.fs diff --git a/src/application/sample-modules/isf/Median.fs b/src/renderer/src/application/sample-modules/isf/Median.fs similarity index 100% rename from src/application/sample-modules/isf/Median.fs rename to src/renderer/src/application/sample-modules/isf/Median.fs diff --git a/src/application/sample-modules/isf/Meta Image.fs b/src/renderer/src/application/sample-modules/isf/Meta Image.fs similarity index 100% rename from src/application/sample-modules/isf/Meta Image.fs rename to src/renderer/src/application/sample-modules/isf/Meta Image.fs diff --git a/src/application/sample-modules/isf/Micro Buffer RGB.fs b/src/renderer/src/application/sample-modules/isf/Micro Buffer RGB.fs similarity index 100% rename from src/application/sample-modules/isf/Micro Buffer RGB.fs rename to src/renderer/src/application/sample-modules/isf/Micro Buffer RGB.fs diff --git a/src/application/sample-modules/isf/Micro Buffer.fs b/src/renderer/src/application/sample-modules/isf/Micro Buffer.fs similarity index 100% rename from src/application/sample-modules/isf/Micro Buffer.fs rename to src/renderer/src/application/sample-modules/isf/Micro Buffer.fs diff --git a/src/application/sample-modules/isf/Minimum Component.fs b/src/renderer/src/application/sample-modules/isf/Minimum Component.fs similarity index 100% rename from src/application/sample-modules/isf/Minimum Component.fs rename to src/renderer/src/application/sample-modules/isf/Minimum Component.fs diff --git a/src/application/sample-modules/isf/Mirror Edge.fs b/src/renderer/src/application/sample-modules/isf/Mirror Edge.fs similarity index 100% rename from src/application/sample-modules/isf/Mirror Edge.fs rename to src/renderer/src/application/sample-modules/isf/Mirror Edge.fs diff --git a/src/application/sample-modules/isf/Mirror Edge.vs b/src/renderer/src/application/sample-modules/isf/Mirror Edge.vs similarity index 100% rename from src/application/sample-modules/isf/Mirror Edge.vs rename to src/renderer/src/application/sample-modules/isf/Mirror Edge.vs diff --git a/src/application/sample-modules/isf/Mirror.fs b/src/renderer/src/application/sample-modules/isf/Mirror.fs similarity index 100% rename from src/application/sample-modules/isf/Mirror.fs rename to src/renderer/src/application/sample-modules/isf/Mirror.fs diff --git a/src/application/sample-modules/isf/Morph.fs b/src/renderer/src/application/sample-modules/isf/Morph.fs similarity index 100% rename from src/application/sample-modules/isf/Morph.fs rename to src/renderer/src/application/sample-modules/isf/Morph.fs diff --git a/src/application/sample-modules/isf/Mosaic.fs b/src/renderer/src/application/sample-modules/isf/Mosaic.fs similarity index 100% rename from src/application/sample-modules/isf/Mosaic.fs rename to src/renderer/src/application/sample-modules/isf/Mosaic.fs diff --git a/src/application/sample-modules/isf/Multi Gradient.fs b/src/renderer/src/application/sample-modules/isf/Multi Gradient.fs similarity index 100% rename from src/application/sample-modules/isf/Multi Gradient.fs rename to src/renderer/src/application/sample-modules/isf/Multi Gradient.fs diff --git a/src/application/sample-modules/isf/Multi Hue Shift.fs b/src/renderer/src/application/sample-modules/isf/Multi Hue Shift.fs similarity index 100% rename from src/application/sample-modules/isf/Multi Hue Shift.fs rename to src/renderer/src/application/sample-modules/isf/Multi Hue Shift.fs diff --git a/src/application/sample-modules/isf/Multi Pass Gaussian Blur.fs b/src/renderer/src/application/sample-modules/isf/Multi Pass Gaussian Blur.fs similarity index 100% rename from src/application/sample-modules/isf/Multi Pass Gaussian Blur.fs rename to src/renderer/src/application/sample-modules/isf/Multi Pass Gaussian Blur.fs diff --git a/src/application/sample-modules/isf/Multi Pass Gaussian Blur.vs b/src/renderer/src/application/sample-modules/isf/Multi Pass Gaussian Blur.vs similarity index 100% rename from src/application/sample-modules/isf/Multi Pass Gaussian Blur.vs rename to src/renderer/src/application/sample-modules/isf/Multi Pass Gaussian Blur.vs diff --git a/src/application/sample-modules/isf/Multi-Pixellate.fs b/src/renderer/src/application/sample-modules/isf/Multi-Pixellate.fs similarity index 100% rename from src/application/sample-modules/isf/Multi-Pixellate.fs rename to src/renderer/src/application/sample-modules/isf/Multi-Pixellate.fs diff --git a/src/application/sample-modules/isf/MultiFrame 2x2.fs b/src/renderer/src/application/sample-modules/isf/MultiFrame 2x2.fs similarity index 100% rename from src/application/sample-modules/isf/MultiFrame 2x2.fs rename to src/renderer/src/application/sample-modules/isf/MultiFrame 2x2.fs diff --git a/src/application/sample-modules/isf/MultiFrame 3x3.fs b/src/renderer/src/application/sample-modules/isf/MultiFrame 3x3.fs similarity index 100% rename from src/application/sample-modules/isf/MultiFrame 3x3.fs rename to src/renderer/src/application/sample-modules/isf/MultiFrame 3x3.fs diff --git a/src/application/sample-modules/isf/Multiply Blend.fs b/src/renderer/src/application/sample-modules/isf/Multiply Blend.fs similarity index 100% rename from src/application/sample-modules/isf/Multiply Blend.fs rename to src/renderer/src/application/sample-modules/isf/Multiply Blend.fs diff --git a/src/application/sample-modules/isf/Neon.fs b/src/renderer/src/application/sample-modules/isf/Neon.fs similarity index 100% rename from src/application/sample-modules/isf/Neon.fs rename to src/renderer/src/application/sample-modules/isf/Neon.fs diff --git a/src/application/sample-modules/isf/Neon.vs b/src/renderer/src/application/sample-modules/isf/Neon.vs similarity index 100% rename from src/application/sample-modules/isf/Neon.vs rename to src/renderer/src/application/sample-modules/isf/Neon.vs diff --git a/src/application/sample-modules/isf/Night Vision.fs b/src/renderer/src/application/sample-modules/isf/Night Vision.fs similarity index 100% rename from src/application/sample-modules/isf/Night Vision.fs rename to src/renderer/src/application/sample-modules/isf/Night Vision.fs diff --git a/src/application/sample-modules/isf/Noise Adapt.fs b/src/renderer/src/application/sample-modules/isf/Noise Adapt.fs similarity index 100% rename from src/application/sample-modules/isf/Noise Adapt.fs rename to src/renderer/src/application/sample-modules/isf/Noise Adapt.fs diff --git a/src/application/sample-modules/isf/Noise Displace.fs b/src/renderer/src/application/sample-modules/isf/Noise Displace.fs similarity index 100% rename from src/application/sample-modules/isf/Noise Displace.fs rename to src/renderer/src/application/sample-modules/isf/Noise Displace.fs diff --git a/src/application/sample-modules/isf/Noise Pixellate.fs b/src/renderer/src/application/sample-modules/isf/Noise Pixellate.fs similarity index 100% rename from src/application/sample-modules/isf/Noise Pixellate.fs rename to src/renderer/src/application/sample-modules/isf/Noise Pixellate.fs diff --git a/src/application/sample-modules/isf/Noise.fs b/src/renderer/src/application/sample-modules/isf/Noise.fs similarity index 100% rename from src/application/sample-modules/isf/Noise.fs rename to src/renderer/src/application/sample-modules/isf/Noise.fs diff --git a/src/application/sample-modules/isf/Optical Flow Distort.fs b/src/renderer/src/application/sample-modules/isf/Optical Flow Distort.fs similarity index 100% rename from src/application/sample-modules/isf/Optical Flow Distort.fs rename to src/renderer/src/application/sample-modules/isf/Optical Flow Distort.fs diff --git a/src/application/sample-modules/isf/Optical Flow Distort.vs b/src/renderer/src/application/sample-modules/isf/Optical Flow Distort.vs similarity index 100% rename from src/application/sample-modules/isf/Optical Flow Distort.vs rename to src/renderer/src/application/sample-modules/isf/Optical Flow Distort.vs diff --git a/src/application/sample-modules/isf/Optical Flow Generator.fs b/src/renderer/src/application/sample-modules/isf/Optical Flow Generator.fs similarity index 100% rename from src/application/sample-modules/isf/Optical Flow Generator.fs rename to src/renderer/src/application/sample-modules/isf/Optical Flow Generator.fs diff --git a/src/application/sample-modules/isf/Perlin Transition.fs b/src/renderer/src/application/sample-modules/isf/Perlin Transition.fs similarity index 100% rename from src/application/sample-modules/isf/Perlin Transition.fs rename to src/renderer/src/application/sample-modules/isf/Perlin Transition.fs diff --git a/src/application/sample-modules/isf/Pinch.fs b/src/renderer/src/application/sample-modules/isf/Pinch.fs similarity index 100% rename from src/application/sample-modules/isf/Pinch.fs rename to src/renderer/src/application/sample-modules/isf/Pinch.fs diff --git a/src/application/sample-modules/isf/Pinwheel.fs b/src/renderer/src/application/sample-modules/isf/Pinwheel.fs similarity index 100% rename from src/application/sample-modules/isf/Pinwheel.fs rename to src/renderer/src/application/sample-modules/isf/Pinwheel.fs diff --git a/src/application/sample-modules/isf/Pixel Shifter.fs b/src/renderer/src/application/sample-modules/isf/Pixel Shifter.fs similarity index 100% rename from src/application/sample-modules/isf/Pixel Shifter.fs rename to src/renderer/src/application/sample-modules/isf/Pixel Shifter.fs diff --git a/src/application/sample-modules/isf/Pixelize.fs b/src/renderer/src/application/sample-modules/isf/Pixelize.fs similarity index 100% rename from src/application/sample-modules/isf/Pixelize.fs rename to src/renderer/src/application/sample-modules/isf/Pixelize.fs diff --git a/src/application/sample-modules/isf/Pixellate.fs b/src/renderer/src/application/sample-modules/isf/Pixellate.fs similarity index 100% rename from src/application/sample-modules/isf/Pixellate.fs rename to src/renderer/src/application/sample-modules/isf/Pixellate.fs diff --git a/src/application/sample-modules/isf/Polar Function.fs b/src/renderer/src/application/sample-modules/isf/Polar Function.fs similarity index 100% rename from src/application/sample-modules/isf/Polar Function.fs rename to src/renderer/src/application/sample-modules/isf/Polar Function.fs diff --git a/src/application/sample-modules/isf/Polka Dots Curtain.fs b/src/renderer/src/application/sample-modules/isf/Polka Dots Curtain.fs similarity index 100% rename from src/application/sample-modules/isf/Polka Dots Curtain.fs rename to src/renderer/src/application/sample-modules/isf/Polka Dots Curtain.fs diff --git a/src/application/sample-modules/isf/Poly Star.fs b/src/renderer/src/application/sample-modules/isf/Poly Star.fs similarity index 100% rename from src/application/sample-modules/isf/Poly Star.fs rename to src/renderer/src/application/sample-modules/isf/Poly Star.fs diff --git a/src/application/sample-modules/isf/Posterize.fs b/src/renderer/src/application/sample-modules/isf/Posterize.fs similarity index 100% rename from src/application/sample-modules/isf/Posterize.fs rename to src/renderer/src/application/sample-modules/isf/Posterize.fs diff --git a/src/application/sample-modules/isf/Power Warp.fs b/src/renderer/src/application/sample-modules/isf/Power Warp.fs similarity index 100% rename from src/application/sample-modules/isf/Power Warp.fs rename to src/renderer/src/application/sample-modules/isf/Power Warp.fs diff --git a/src/application/sample-modules/isf/Quad Mask.fs b/src/renderer/src/application/sample-modules/isf/Quad Mask.fs similarity index 100% rename from src/application/sample-modules/isf/Quad Mask.fs rename to src/renderer/src/application/sample-modules/isf/Quad Mask.fs diff --git a/src/application/sample-modules/isf/Quad Tile.fs b/src/renderer/src/application/sample-modules/isf/Quad Tile.fs similarity index 100% rename from src/application/sample-modules/isf/Quad Tile.fs rename to src/renderer/src/application/sample-modules/isf/Quad Tile.fs diff --git a/src/application/sample-modules/isf/RE RGB Gradient Generator.fs b/src/renderer/src/application/sample-modules/isf/RE RGB Gradient Generator.fs similarity index 100% rename from src/application/sample-modules/isf/RE RGB Gradient Generator.fs rename to src/renderer/src/application/sample-modules/isf/RE RGB Gradient Generator.fs diff --git a/src/application/sample-modules/isf/RGB EQ.fs b/src/renderer/src/application/sample-modules/isf/RGB EQ.fs similarity index 100% rename from src/application/sample-modules/isf/RGB EQ.fs rename to src/renderer/src/application/sample-modules/isf/RGB EQ.fs diff --git a/src/application/sample-modules/isf/RGB Halftone-lookaround.fs b/src/renderer/src/application/sample-modules/isf/RGB Halftone-lookaround.fs similarity index 100% rename from src/application/sample-modules/isf/RGB Halftone-lookaround.fs rename to src/renderer/src/application/sample-modules/isf/RGB Halftone-lookaround.fs diff --git a/src/application/sample-modules/isf/RGB Halftone.fs b/src/renderer/src/application/sample-modules/isf/RGB Halftone.fs similarity index 100% rename from src/application/sample-modules/isf/RGB Halftone.fs rename to src/renderer/src/application/sample-modules/isf/RGB Halftone.fs diff --git a/src/application/sample-modules/isf/RGB Invert.fs b/src/renderer/src/application/sample-modules/isf/RGB Invert.fs similarity index 100% rename from src/application/sample-modules/isf/RGB Invert.fs rename to src/renderer/src/application/sample-modules/isf/RGB Invert.fs diff --git a/src/application/sample-modules/isf/RGB Strobe.fs b/src/renderer/src/application/sample-modules/isf/RGB Strobe.fs similarity index 100% rename from src/application/sample-modules/isf/RGB Strobe.fs rename to src/renderer/src/application/sample-modules/isf/RGB Strobe.fs diff --git a/src/application/sample-modules/isf/RGB Trails 3.0.fs b/src/renderer/src/application/sample-modules/isf/RGB Trails 3.0.fs similarity index 100% rename from src/application/sample-modules/isf/RGB Trails 3.0.fs rename to src/renderer/src/application/sample-modules/isf/RGB Trails 3.0.fs diff --git a/src/application/sample-modules/isf/RGBA Swap.fs b/src/renderer/src/application/sample-modules/isf/RGBA Swap.fs similarity index 100% rename from src/application/sample-modules/isf/RGBA Swap.fs rename to src/renderer/src/application/sample-modules/isf/RGBA Swap.fs diff --git a/src/application/sample-modules/isf/RGBtoHSV.fs b/src/renderer/src/application/sample-modules/isf/RGBtoHSV.fs similarity index 100% rename from src/application/sample-modules/isf/RGBtoHSV.fs rename to src/renderer/src/application/sample-modules/isf/RGBtoHSV.fs diff --git a/src/application/sample-modules/isf/Radial Gradient.fs b/src/renderer/src/application/sample-modules/isf/Radial Gradient.fs similarity index 100% rename from src/application/sample-modules/isf/Radial Gradient.fs rename to src/renderer/src/application/sample-modules/isf/Radial Gradient.fs diff --git a/src/application/sample-modules/isf/Radial Replicate.fs b/src/renderer/src/application/sample-modules/isf/Radial Replicate.fs similarity index 100% rename from src/application/sample-modules/isf/Radial Replicate.fs rename to src/renderer/src/application/sample-modules/isf/Radial Replicate.fs diff --git a/src/application/sample-modules/isf/Radial.fs b/src/renderer/src/application/sample-modules/isf/Radial.fs similarity index 100% rename from src/application/sample-modules/isf/Radial.fs rename to src/renderer/src/application/sample-modules/isf/Radial.fs diff --git a/src/application/sample-modules/isf/Random Checkerboard.fs b/src/renderer/src/application/sample-modules/isf/Random Checkerboard.fs similarity index 100% rename from src/application/sample-modules/isf/Random Checkerboard.fs rename to src/renderer/src/application/sample-modules/isf/Random Checkerboard.fs diff --git a/src/application/sample-modules/isf/Random Freeze.fs b/src/renderer/src/application/sample-modules/isf/Random Freeze.fs similarity index 100% rename from src/application/sample-modules/isf/Random Freeze.fs rename to src/renderer/src/application/sample-modules/isf/Random Freeze.fs diff --git a/src/application/sample-modules/isf/Random Lines.fs b/src/renderer/src/application/sample-modules/isf/Random Lines.fs similarity index 100% rename from src/application/sample-modules/isf/Random Lines.fs rename to src/renderer/src/application/sample-modules/isf/Random Lines.fs diff --git a/src/application/sample-modules/isf/Random Shape Blast.fs b/src/renderer/src/application/sample-modules/isf/Random Shape Blast.fs similarity index 100% rename from src/application/sample-modules/isf/Random Shape Blast.fs rename to src/renderer/src/application/sample-modules/isf/Random Shape Blast.fs diff --git a/src/application/sample-modules/isf/Random Shape.fs b/src/renderer/src/application/sample-modules/isf/Random Shape.fs similarity index 100% rename from src/application/sample-modules/isf/Random Shape.fs rename to src/renderer/src/application/sample-modules/isf/Random Shape.fs diff --git a/src/application/sample-modules/isf/Random Squares Mask.fs b/src/renderer/src/application/sample-modules/isf/Random Squares Mask.fs similarity index 100% rename from src/application/sample-modules/isf/Random Squares Mask.fs rename to src/renderer/src/application/sample-modules/isf/Random Squares Mask.fs diff --git a/src/application/sample-modules/isf/Random Squares.fs b/src/renderer/src/application/sample-modules/isf/Random Squares.fs similarity index 100% rename from src/application/sample-modules/isf/Random Squares.fs rename to src/renderer/src/application/sample-modules/isf/Random Squares.fs diff --git a/src/application/sample-modules/isf/Random Stripes.fs b/src/renderer/src/application/sample-modules/isf/Random Stripes.fs similarity index 100% rename from src/application/sample-modules/isf/Random Stripes.fs rename to src/renderer/src/application/sample-modules/isf/Random Stripes.fs diff --git a/src/application/sample-modules/isf/Replicate Random.fs b/src/renderer/src/application/sample-modules/isf/Replicate Random.fs similarity index 100% rename from src/application/sample-modules/isf/Replicate Random.fs rename to src/renderer/src/application/sample-modules/isf/Replicate Random.fs diff --git a/src/application/sample-modules/isf/Replicate.fs b/src/renderer/src/application/sample-modules/isf/Replicate.fs similarity index 100% rename from src/application/sample-modules/isf/Replicate.fs rename to src/renderer/src/application/sample-modules/isf/Replicate.fs diff --git a/src/application/sample-modules/isf/Resize Glitch.fs b/src/renderer/src/application/sample-modules/isf/Resize Glitch.fs similarity index 100% rename from src/application/sample-modules/isf/Resize Glitch.fs rename to src/renderer/src/application/sample-modules/isf/Resize Glitch.fs diff --git a/src/application/sample-modules/isf/Ripple Transition.fs b/src/renderer/src/application/sample-modules/isf/Ripple Transition.fs similarity index 100% rename from src/application/sample-modules/isf/Ripple Transition.fs rename to src/renderer/src/application/sample-modules/isf/Ripple Transition.fs diff --git a/src/application/sample-modules/isf/Ripples.fs b/src/renderer/src/application/sample-modules/isf/Ripples.fs similarity index 100% rename from src/application/sample-modules/isf/Ripples.fs rename to src/renderer/src/application/sample-modules/isf/Ripples.fs diff --git a/src/application/sample-modules/isf/Rotate Scale Fade.fs b/src/renderer/src/application/sample-modules/isf/Rotate Scale Fade.fs similarity index 100% rename from src/application/sample-modules/isf/Rotate Scale Fade.fs rename to src/renderer/src/application/sample-modules/isf/Rotate Scale Fade.fs diff --git a/src/application/sample-modules/isf/Rotate.fs b/src/renderer/src/application/sample-modules/isf/Rotate.fs similarity index 100% rename from src/application/sample-modules/isf/Rotate.fs rename to src/renderer/src/application/sample-modules/isf/Rotate.fs diff --git a/src/application/sample-modules/isf/Rotate.vs b/src/renderer/src/application/sample-modules/isf/Rotate.vs similarity index 100% rename from src/application/sample-modules/isf/Rotate.vs rename to src/renderer/src/application/sample-modules/isf/Rotate.vs diff --git a/src/application/sample-modules/isf/Saturation Bleed.fs b/src/renderer/src/application/sample-modules/isf/Saturation Bleed.fs similarity index 100% rename from src/application/sample-modules/isf/Saturation Bleed.fs rename to src/renderer/src/application/sample-modules/isf/Saturation Bleed.fs diff --git a/src/application/sample-modules/isf/Saturation Bleed.vs b/src/renderer/src/application/sample-modules/isf/Saturation Bleed.vs similarity index 100% rename from src/application/sample-modules/isf/Saturation Bleed.vs rename to src/renderer/src/application/sample-modules/isf/Saturation Bleed.vs diff --git a/src/application/sample-modules/isf/Sepia Tone.fs b/src/renderer/src/application/sample-modules/isf/Sepia Tone.fs similarity index 100% rename from src/application/sample-modules/isf/Sepia Tone.fs rename to src/renderer/src/application/sample-modules/isf/Sepia Tone.fs diff --git a/src/application/sample-modules/isf/Set Alpha.fs b/src/renderer/src/application/sample-modules/isf/Set Alpha.fs similarity index 100% rename from src/application/sample-modules/isf/Set Alpha.fs rename to src/renderer/src/application/sample-modules/isf/Set Alpha.fs diff --git a/src/application/sample-modules/isf/Shake.fs b/src/renderer/src/application/sample-modules/isf/Shake.fs similarity index 100% rename from src/application/sample-modules/isf/Shake.fs rename to src/renderer/src/application/sample-modules/isf/Shake.fs diff --git a/src/application/sample-modules/isf/Shape Mask.fs b/src/renderer/src/application/sample-modules/isf/Shape Mask.fs similarity index 100% rename from src/application/sample-modules/isf/Shape Mask.fs rename to src/renderer/src/application/sample-modules/isf/Shape Mask.fs diff --git a/src/application/sample-modules/isf/Shape Morph Feedback Mask.fs b/src/renderer/src/application/sample-modules/isf/Shape Morph Feedback Mask.fs similarity index 100% rename from src/application/sample-modules/isf/Shape Morph Feedback Mask.fs rename to src/renderer/src/application/sample-modules/isf/Shape Morph Feedback Mask.fs diff --git a/src/application/sample-modules/isf/Shape Morph Wrap.fs b/src/renderer/src/application/sample-modules/isf/Shape Morph Wrap.fs similarity index 100% rename from src/application/sample-modules/isf/Shape Morph Wrap.fs rename to src/renderer/src/application/sample-modules/isf/Shape Morph Wrap.fs diff --git a/src/application/sample-modules/isf/Sharpen Luminance.fs b/src/renderer/src/application/sample-modules/isf/Sharpen Luminance.fs similarity index 100% rename from src/application/sample-modules/isf/Sharpen Luminance.fs rename to src/renderer/src/application/sample-modules/isf/Sharpen Luminance.fs diff --git a/src/application/sample-modules/isf/Sharpen Luminance.vs b/src/renderer/src/application/sample-modules/isf/Sharpen Luminance.vs similarity index 100% rename from src/application/sample-modules/isf/Sharpen Luminance.vs rename to src/renderer/src/application/sample-modules/isf/Sharpen Luminance.vs diff --git a/src/application/sample-modules/isf/Sharpen RGB.fs b/src/renderer/src/application/sample-modules/isf/Sharpen RGB.fs similarity index 100% rename from src/application/sample-modules/isf/Sharpen RGB.fs rename to src/renderer/src/application/sample-modules/isf/Sharpen RGB.fs diff --git a/src/application/sample-modules/isf/Sharpen RGB.vs b/src/renderer/src/application/sample-modules/isf/Sharpen RGB.vs similarity index 100% rename from src/application/sample-modules/isf/Sharpen RGB.vs rename to src/renderer/src/application/sample-modules/isf/Sharpen RGB.vs diff --git a/src/application/sample-modules/isf/Shockwave Pulse.fs b/src/renderer/src/application/sample-modules/isf/Shockwave Pulse.fs similarity index 100% rename from src/application/sample-modules/isf/Shockwave Pulse.fs rename to src/renderer/src/application/sample-modules/isf/Shockwave Pulse.fs diff --git a/src/application/sample-modules/isf/Shockwave.fs b/src/renderer/src/application/sample-modules/isf/Shockwave.fs similarity index 100% rename from src/application/sample-modules/isf/Shockwave.fs rename to src/renderer/src/application/sample-modules/isf/Shockwave.fs diff --git a/src/application/sample-modules/isf/Show Alpha.fs b/src/renderer/src/application/sample-modules/isf/Show Alpha.fs similarity index 100% rename from src/application/sample-modules/isf/Show Alpha.fs rename to src/renderer/src/application/sample-modules/isf/Show Alpha.fs diff --git a/src/application/sample-modules/isf/Side Scroller And Flip.fs b/src/renderer/src/application/sample-modules/isf/Side Scroller And Flip.fs similarity index 100% rename from src/application/sample-modules/isf/Side Scroller And Flip.fs rename to src/renderer/src/application/sample-modules/isf/Side Scroller And Flip.fs diff --git a/src/application/sample-modules/isf/Simple Zoom Transition.fs b/src/renderer/src/application/sample-modules/isf/Simple Zoom Transition.fs similarity index 100% rename from src/application/sample-modules/isf/Simple Zoom Transition.fs rename to src/renderer/src/application/sample-modules/isf/Simple Zoom Transition.fs diff --git a/src/application/sample-modules/isf/Sine Warp Gradient.fs b/src/renderer/src/application/sample-modules/isf/Sine Warp Gradient.fs similarity index 100% rename from src/application/sample-modules/isf/Sine Warp Gradient.fs rename to src/renderer/src/application/sample-modules/isf/Sine Warp Gradient.fs diff --git a/src/application/sample-modules/isf/Sine Warp Tile.fs b/src/renderer/src/application/sample-modules/isf/Sine Warp Tile.fs similarity index 100% rename from src/application/sample-modules/isf/Sine Warp Tile.fs rename to src/renderer/src/application/sample-modules/isf/Sine Warp Tile.fs diff --git a/src/application/sample-modules/isf/Sketch.fs b/src/renderer/src/application/sample-modules/isf/Sketch.fs similarity index 100% rename from src/application/sample-modules/isf/Sketch.fs rename to src/renderer/src/application/sample-modules/isf/Sketch.fs diff --git a/src/application/sample-modules/isf/Sketch.vs b/src/renderer/src/application/sample-modules/isf/Sketch.vs similarity index 100% rename from src/application/sample-modules/isf/Sketch.vs rename to src/renderer/src/application/sample-modules/isf/Sketch.vs diff --git a/src/application/sample-modules/isf/Slice.fs b/src/renderer/src/application/sample-modules/isf/Slice.fs similarity index 100% rename from src/application/sample-modules/isf/Slice.fs rename to src/renderer/src/application/sample-modules/isf/Slice.fs diff --git a/src/application/sample-modules/isf/Sliding Strips.fs b/src/renderer/src/application/sample-modules/isf/Sliding Strips.fs similarity index 100% rename from src/application/sample-modules/isf/Sliding Strips.fs rename to src/renderer/src/application/sample-modules/isf/Sliding Strips.fs diff --git a/src/application/sample-modules/isf/Slit Scan Mask.fs b/src/renderer/src/application/sample-modules/isf/Slit Scan Mask.fs similarity index 100% rename from src/application/sample-modules/isf/Slit Scan Mask.fs rename to src/renderer/src/application/sample-modules/isf/Slit Scan Mask.fs diff --git a/src/application/sample-modules/isf/Slit Scan.fs b/src/renderer/src/application/sample-modules/isf/Slit Scan.fs similarity index 100% rename from src/application/sample-modules/isf/Slit Scan.fs rename to src/renderer/src/application/sample-modules/isf/Slit Scan.fs diff --git a/src/application/sample-modules/isf/Smoke Screen.fs b/src/renderer/src/application/sample-modules/isf/Smoke Screen.fs similarity index 100% rename from src/application/sample-modules/isf/Smoke Screen.fs rename to src/renderer/src/application/sample-modules/isf/Smoke Screen.fs diff --git a/src/application/sample-modules/isf/Smudged Lens.fs b/src/renderer/src/application/sample-modules/isf/Smudged Lens.fs similarity index 100% rename from src/application/sample-modules/isf/Smudged Lens.fs rename to src/renderer/src/application/sample-modules/isf/Smudged Lens.fs diff --git a/src/application/sample-modules/isf/Smudged Lens.vs b/src/renderer/src/application/sample-modules/isf/Smudged Lens.vs similarity index 100% rename from src/application/sample-modules/isf/Smudged Lens.vs rename to src/renderer/src/application/sample-modules/isf/Smudged Lens.vs diff --git a/src/application/sample-modules/isf/Soft Blur.fs b/src/renderer/src/application/sample-modules/isf/Soft Blur.fs similarity index 100% rename from src/application/sample-modules/isf/Soft Blur.fs rename to src/renderer/src/application/sample-modules/isf/Soft Blur.fs diff --git a/src/application/sample-modules/isf/Soft Blur.vs b/src/renderer/src/application/sample-modules/isf/Soft Blur.vs similarity index 100% rename from src/application/sample-modules/isf/Soft Blur.vs rename to src/renderer/src/application/sample-modules/isf/Soft Blur.vs diff --git a/src/application/sample-modules/isf/Soft Flip.fs b/src/renderer/src/application/sample-modules/isf/Soft Flip.fs similarity index 100% rename from src/application/sample-modules/isf/Soft Flip.fs rename to src/renderer/src/application/sample-modules/isf/Soft Flip.fs diff --git a/src/application/sample-modules/isf/Solarize.fs b/src/renderer/src/application/sample-modules/isf/Solarize.fs similarity index 100% rename from src/application/sample-modules/isf/Solarize.fs rename to src/renderer/src/application/sample-modules/isf/Solarize.fs diff --git a/src/application/sample-modules/isf/Solid Color.fs b/src/renderer/src/application/sample-modules/isf/Solid Color.fs similarity index 100% rename from src/application/sample-modules/isf/Solid Color.fs rename to src/renderer/src/application/sample-modules/isf/Solid Color.fs diff --git a/src/application/sample-modules/isf/Sorting Smear.fs b/src/renderer/src/application/sample-modules/isf/Sorting Smear.fs similarity index 100% rename from src/application/sample-modules/isf/Sorting Smear.fs rename to src/renderer/src/application/sample-modules/isf/Sorting Smear.fs diff --git a/src/application/sample-modules/isf/Sorting Smear.vs b/src/renderer/src/application/sample-modules/isf/Sorting Smear.vs similarity index 100% rename from src/application/sample-modules/isf/Sorting Smear.vs rename to src/renderer/src/application/sample-modules/isf/Sorting Smear.vs diff --git a/src/application/sample-modules/isf/Sphere Map.fs b/src/renderer/src/application/sample-modules/isf/Sphere Map.fs similarity index 100% rename from src/application/sample-modules/isf/Sphere Map.fs rename to src/renderer/src/application/sample-modules/isf/Sphere Map.fs diff --git a/src/application/sample-modules/isf/Spiral.fs b/src/renderer/src/application/sample-modules/isf/Spiral.fs similarity index 100% rename from src/application/sample-modules/isf/Spiral.fs rename to src/renderer/src/application/sample-modules/isf/Spiral.fs diff --git a/src/application/sample-modules/isf/Squares Wire.fs b/src/renderer/src/application/sample-modules/isf/Squares Wire.fs similarity index 100% rename from src/application/sample-modules/isf/Squares Wire.fs rename to src/renderer/src/application/sample-modules/isf/Squares Wire.fs diff --git a/src/application/sample-modules/isf/Squeeze.fs b/src/renderer/src/application/sample-modules/isf/Squeeze.fs similarity index 100% rename from src/application/sample-modules/isf/Squeeze.fs rename to src/renderer/src/application/sample-modules/isf/Squeeze.fs diff --git a/src/application/sample-modules/isf/Star.fs b/src/renderer/src/application/sample-modules/isf/Star.fs similarity index 100% rename from src/application/sample-modules/isf/Star.fs rename to src/renderer/src/application/sample-modules/isf/Star.fs diff --git a/src/application/sample-modules/isf/Stereo Viewer.fs b/src/renderer/src/application/sample-modules/isf/Stereo Viewer.fs similarity index 100% rename from src/application/sample-modules/isf/Stereo Viewer.fs rename to src/renderer/src/application/sample-modules/isf/Stereo Viewer.fs diff --git a/src/application/sample-modules/isf/Stripes.fs b/src/renderer/src/application/sample-modules/isf/Stripes.fs similarity index 100% rename from src/application/sample-modules/isf/Stripes.fs rename to src/renderer/src/application/sample-modules/isf/Stripes.fs diff --git a/src/application/sample-modules/isf/Strobe.fs b/src/renderer/src/application/sample-modules/isf/Strobe.fs similarity index 100% rename from src/application/sample-modules/isf/Strobe.fs rename to src/renderer/src/application/sample-modules/isf/Strobe.fs diff --git a/src/application/sample-modules/isf/Swap Transition.fs b/src/renderer/src/application/sample-modules/isf/Swap Transition.fs similarity index 100% rename from src/application/sample-modules/isf/Swap Transition.fs rename to src/renderer/src/application/sample-modules/isf/Swap Transition.fs diff --git a/src/application/sample-modules/isf/Swirl.fs b/src/renderer/src/application/sample-modules/isf/Swirl.fs similarity index 100% rename from src/application/sample-modules/isf/Swirl.fs rename to src/renderer/src/application/sample-modules/isf/Swirl.fs diff --git a/src/application/sample-modules/isf/TV Static.fs b/src/renderer/src/application/sample-modules/isf/TV Static.fs similarity index 100% rename from src/application/sample-modules/isf/TV Static.fs rename to src/renderer/src/application/sample-modules/isf/TV Static.fs diff --git a/src/application/sample-modules/isf/Time Glitch RGB.fs b/src/renderer/src/application/sample-modules/isf/Time Glitch RGB.fs similarity index 100% rename from src/application/sample-modules/isf/Time Glitch RGB.fs rename to src/renderer/src/application/sample-modules/isf/Time Glitch RGB.fs diff --git a/src/application/sample-modules/isf/Toon.fs b/src/renderer/src/application/sample-modules/isf/Toon.fs similarity index 100% rename from src/application/sample-modules/isf/Toon.fs rename to src/renderer/src/application/sample-modules/isf/Toon.fs diff --git a/src/application/sample-modules/isf/Trail Mask.fs b/src/renderer/src/application/sample-modules/isf/Trail Mask.fs similarity index 100% rename from src/application/sample-modules/isf/Trail Mask.fs rename to src/renderer/src/application/sample-modules/isf/Trail Mask.fs diff --git a/src/application/sample-modules/isf/Trapezoid Distortion.fs b/src/renderer/src/application/sample-modules/isf/Trapezoid Distortion.fs similarity index 100% rename from src/application/sample-modules/isf/Trapezoid Distortion.fs rename to src/renderer/src/application/sample-modules/isf/Trapezoid Distortion.fs diff --git a/src/application/sample-modules/isf/Triangle Warp.fs b/src/renderer/src/application/sample-modules/isf/Triangle Warp.fs similarity index 100% rename from src/application/sample-modules/isf/Triangle Warp.fs rename to src/renderer/src/application/sample-modules/isf/Triangle Warp.fs diff --git a/src/application/sample-modules/isf/Triangle.fs b/src/renderer/src/application/sample-modules/isf/Triangle.fs similarity index 100% rename from src/application/sample-modules/isf/Triangle.fs rename to src/renderer/src/application/sample-modules/isf/Triangle.fs diff --git a/src/application/sample-modules/isf/Triangles.fs b/src/renderer/src/application/sample-modules/isf/Triangles.fs similarity index 100% rename from src/application/sample-modules/isf/Triangles.fs rename to src/renderer/src/application/sample-modules/isf/Triangles.fs diff --git a/src/application/sample-modules/isf/Trio Tone.fs b/src/renderer/src/application/sample-modules/isf/Trio Tone.fs similarity index 100% rename from src/application/sample-modules/isf/Trio Tone.fs rename to src/renderer/src/application/sample-modules/isf/Trio Tone.fs diff --git a/src/application/sample-modules/isf/Triple Rotate.fs b/src/renderer/src/application/sample-modules/isf/Triple Rotate.fs similarity index 100% rename from src/application/sample-modules/isf/Triple Rotate.fs rename to src/renderer/src/application/sample-modules/isf/Triple Rotate.fs diff --git a/src/application/sample-modules/isf/Truchet Tile.fs b/src/renderer/src/application/sample-modules/isf/Truchet Tile.fs similarity index 100% rename from src/application/sample-modules/isf/Truchet Tile.fs rename to src/renderer/src/application/sample-modules/isf/Truchet Tile.fs diff --git a/src/application/sample-modules/isf/Twirl.fs b/src/renderer/src/application/sample-modules/isf/Twirl.fs similarity index 100% rename from src/application/sample-modules/isf/Twirl.fs rename to src/renderer/src/application/sample-modules/isf/Twirl.fs diff --git a/src/application/sample-modules/isf/UltimateFlame.fs b/src/renderer/src/application/sample-modules/isf/UltimateFlame.fs similarity index 100% rename from src/application/sample-modules/isf/UltimateFlame.fs rename to src/renderer/src/application/sample-modules/isf/UltimateFlame.fs diff --git a/src/application/sample-modules/isf/UltimateSpiral.fs b/src/renderer/src/application/sample-modules/isf/UltimateSpiral.fs similarity index 100% rename from src/application/sample-modules/isf/UltimateSpiral.fs rename to src/renderer/src/application/sample-modules/isf/UltimateSpiral.fs diff --git a/src/application/sample-modules/isf/Undulating Burn Out.fs b/src/renderer/src/application/sample-modules/isf/Undulating Burn Out.fs similarity index 100% rename from src/application/sample-modules/isf/Undulating Burn Out.fs rename to src/renderer/src/application/sample-modules/isf/Undulating Burn Out.fs diff --git a/src/application/sample-modules/isf/Unsharp Mask.fs b/src/renderer/src/application/sample-modules/isf/Unsharp Mask.fs similarity index 100% rename from src/application/sample-modules/isf/Unsharp Mask.fs rename to src/renderer/src/application/sample-modules/isf/Unsharp Mask.fs diff --git a/src/application/sample-modules/isf/Unsharp Mask.vs b/src/renderer/src/application/sample-modules/isf/Unsharp Mask.vs similarity index 100% rename from src/application/sample-modules/isf/Unsharp Mask.vs rename to src/renderer/src/application/sample-modules/isf/Unsharp Mask.vs diff --git a/src/application/sample-modules/isf/VHS Glitch.fs b/src/renderer/src/application/sample-modules/isf/VHS Glitch.fs similarity index 100% rename from src/application/sample-modules/isf/VHS Glitch.fs rename to src/renderer/src/application/sample-modules/isf/VHS Glitch.fs diff --git a/src/application/sample-modules/isf/VHS Glitch.fs.fs b/src/renderer/src/application/sample-modules/isf/VHS Glitch.fs.fs similarity index 100% rename from src/application/sample-modules/isf/VHS Glitch.fs.fs rename to src/renderer/src/application/sample-modules/isf/VHS Glitch.fs.fs diff --git a/src/application/sample-modules/isf/VU Meter.fs b/src/renderer/src/application/sample-modules/isf/VU Meter.fs similarity index 100% rename from src/application/sample-modules/isf/VU Meter.fs rename to src/renderer/src/application/sample-modules/isf/VU Meter.fs diff --git a/src/application/sample-modules/isf/VVMotionBlur 3.0.fs b/src/renderer/src/application/sample-modules/isf/VVMotionBlur 3.0.fs similarity index 100% rename from src/application/sample-modules/isf/VVMotionBlur 3.0.fs rename to src/renderer/src/application/sample-modules/isf/VVMotionBlur 3.0.fs diff --git a/src/application/sample-modules/isf/Vertex Manipulator.fs b/src/renderer/src/application/sample-modules/isf/Vertex Manipulator.fs similarity index 100% rename from src/application/sample-modules/isf/Vertex Manipulator.fs rename to src/renderer/src/application/sample-modules/isf/Vertex Manipulator.fs diff --git a/src/application/sample-modules/isf/Vertex Manipulator.vs b/src/renderer/src/application/sample-modules/isf/Vertex Manipulator.vs similarity index 100% rename from src/application/sample-modules/isf/Vertex Manipulator.vs rename to src/renderer/src/application/sample-modules/isf/Vertex Manipulator.vs diff --git a/src/application/sample-modules/isf/Vertical Tearing.fs b/src/renderer/src/application/sample-modules/isf/Vertical Tearing.fs similarity index 100% rename from src/application/sample-modules/isf/Vertical Tearing.fs rename to src/renderer/src/application/sample-modules/isf/Vertical Tearing.fs diff --git a/src/application/sample-modules/isf/Vibrance.fs b/src/renderer/src/application/sample-modules/isf/Vibrance.fs similarity index 100% rename from src/application/sample-modules/isf/Vibrance.fs rename to src/renderer/src/application/sample-modules/isf/Vibrance.fs diff --git a/src/application/sample-modules/isf/Vignette.fs b/src/renderer/src/application/sample-modules/isf/Vignette.fs similarity index 100% rename from src/application/sample-modules/isf/Vignette.fs rename to src/renderer/src/application/sample-modules/isf/Vignette.fs diff --git a/src/application/sample-modules/isf/Water Drop.fs b/src/renderer/src/application/sample-modules/isf/Water Drop.fs similarity index 100% rename from src/application/sample-modules/isf/Water Drop.fs rename to src/renderer/src/application/sample-modules/isf/Water Drop.fs diff --git a/src/application/sample-modules/isf/WaveLines.fs b/src/renderer/src/application/sample-modules/isf/WaveLines.fs similarity index 100% rename from src/application/sample-modules/isf/WaveLines.fs rename to src/renderer/src/application/sample-modules/isf/WaveLines.fs diff --git a/src/application/sample-modules/isf/White Point Adjust.fs b/src/renderer/src/application/sample-modules/isf/White Point Adjust.fs similarity index 100% rename from src/application/sample-modules/isf/White Point Adjust.fs rename to src/renderer/src/application/sample-modules/isf/White Point Adjust.fs diff --git a/src/application/sample-modules/isf/Wind.fs b/src/renderer/src/application/sample-modules/isf/Wind.fs similarity index 100% rename from src/application/sample-modules/isf/Wind.fs rename to src/renderer/src/application/sample-modules/isf/Wind.fs diff --git a/src/application/sample-modules/isf/Window Blinds.fs b/src/renderer/src/application/sample-modules/isf/Window Blinds.fs similarity index 100% rename from src/application/sample-modules/isf/Window Blinds.fs rename to src/renderer/src/application/sample-modules/isf/Window Blinds.fs diff --git a/src/application/sample-modules/isf/Window Slice.fs b/src/renderer/src/application/sample-modules/isf/Window Slice.fs similarity index 100% rename from src/application/sample-modules/isf/Window Slice.fs rename to src/renderer/src/application/sample-modules/isf/Window Slice.fs diff --git a/src/application/sample-modules/isf/Wipe Down.fs b/src/renderer/src/application/sample-modules/isf/Wipe Down.fs similarity index 100% rename from src/application/sample-modules/isf/Wipe Down.fs rename to src/renderer/src/application/sample-modules/isf/Wipe Down.fs diff --git a/src/application/sample-modules/isf/Wipe Left.fs b/src/renderer/src/application/sample-modules/isf/Wipe Left.fs similarity index 100% rename from src/application/sample-modules/isf/Wipe Left.fs rename to src/renderer/src/application/sample-modules/isf/Wipe Left.fs diff --git a/src/application/sample-modules/isf/Wipe Right.fs b/src/renderer/src/application/sample-modules/isf/Wipe Right.fs similarity index 100% rename from src/application/sample-modules/isf/Wipe Right.fs rename to src/renderer/src/application/sample-modules/isf/Wipe Right.fs diff --git a/src/application/sample-modules/isf/Wipe Up.fs b/src/renderer/src/application/sample-modules/isf/Wipe Up.fs similarity index 100% rename from src/application/sample-modules/isf/Wipe Up.fs rename to src/renderer/src/application/sample-modules/isf/Wipe Up.fs diff --git a/src/application/sample-modules/isf/XYZoom.fs b/src/renderer/src/application/sample-modules/isf/XYZoom.fs similarity index 100% rename from src/application/sample-modules/isf/XYZoom.fs rename to src/renderer/src/application/sample-modules/isf/XYZoom.fs diff --git a/src/application/sample-modules/isf/Y-C Time Blur.fs b/src/renderer/src/application/sample-modules/isf/Y-C Time Blur.fs similarity index 100% rename from src/application/sample-modules/isf/Y-C Time Blur.fs rename to src/renderer/src/application/sample-modules/isf/Y-C Time Blur.fs diff --git a/src/application/sample-modules/isf/Zebre.fs b/src/renderer/src/application/sample-modules/isf/Zebre.fs similarity index 100% rename from src/application/sample-modules/isf/Zebre.fs rename to src/renderer/src/application/sample-modules/isf/Zebre.fs diff --git a/src/application/sample-modules/isf/Zoom In Circles.fs b/src/renderer/src/application/sample-modules/isf/Zoom In Circles.fs similarity index 100% rename from src/application/sample-modules/isf/Zoom In Circles.fs rename to src/renderer/src/application/sample-modules/isf/Zoom In Circles.fs diff --git a/src/application/sample-modules/isf/Zoom.fs b/src/renderer/src/application/sample-modules/isf/Zoom.fs similarity index 100% rename from src/application/sample-modules/isf/Zoom.fs rename to src/renderer/src/application/sample-modules/isf/Zoom.fs diff --git a/src/application/sample-modules/isf/Zooming Feedback.fs b/src/renderer/src/application/sample-modules/isf/Zooming Feedback.fs similarity index 100% rename from src/application/sample-modules/isf/Zooming Feedback.fs rename to src/renderer/src/application/sample-modules/isf/Zooming Feedback.fs diff --git a/src/application/sample-modules/isf/badtv.fs b/src/renderer/src/application/sample-modules/isf/badtv.fs similarity index 100% rename from src/application/sample-modules/isf/badtv.fs rename to src/renderer/src/application/sample-modules/isf/badtv.fs diff --git a/src/application/sample-modules/isf/block-color.fs b/src/renderer/src/application/sample-modules/isf/block-color.fs similarity index 100% rename from src/application/sample-modules/isf/block-color.fs rename to src/renderer/src/application/sample-modules/isf/block-color.fs diff --git a/src/application/sample-modules/isf/cube.fs b/src/renderer/src/application/sample-modules/isf/cube.fs similarity index 100% rename from src/application/sample-modules/isf/cube.fs rename to src/renderer/src/application/sample-modules/isf/cube.fs diff --git a/src/application/sample-modules/isf/digital-crystal-tunnel.fs b/src/renderer/src/application/sample-modules/isf/digital-crystal-tunnel.fs similarity index 100% rename from src/application/sample-modules/isf/digital-crystal-tunnel.fs rename to src/renderer/src/application/sample-modules/isf/digital-crystal-tunnel.fs diff --git a/src/application/sample-modules/isf/feedback.fs b/src/renderer/src/application/sample-modules/isf/feedback.fs similarity index 100% rename from src/application/sample-modules/isf/feedback.fs rename to src/renderer/src/application/sample-modules/isf/feedback.fs diff --git a/src/application/sample-modules/isf/film-grain.fs b/src/renderer/src/application/sample-modules/isf/film-grain.fs similarity index 100% rename from src/application/sample-modules/isf/film-grain.fs rename to src/renderer/src/application/sample-modules/isf/film-grain.fs diff --git a/src/application/sample-modules/isf/hexagons.fs b/src/renderer/src/application/sample-modules/isf/hexagons.fs similarity index 100% rename from src/application/sample-modules/isf/hexagons.fs rename to src/renderer/src/application/sample-modules/isf/hexagons.fs diff --git a/src/application/sample-modules/isf/plasma.fs b/src/renderer/src/application/sample-modules/isf/plasma.fs similarity index 100% rename from src/application/sample-modules/isf/plasma.fs rename to src/renderer/src/application/sample-modules/isf/plasma.fs diff --git a/src/application/sample-modules/isf/rgbglitchmod.fs b/src/renderer/src/application/sample-modules/isf/rgbglitchmod.fs similarity index 100% rename from src/application/sample-modules/isf/rgbglitchmod.fs rename to src/renderer/src/application/sample-modules/isf/rgbglitchmod.fs diff --git a/src/application/sample-modules/isf/rgbtimeglitch.fs b/src/renderer/src/application/sample-modules/isf/rgbtimeglitch.fs similarity index 100% rename from src/application/sample-modules/isf/rgbtimeglitch.fs rename to src/renderer/src/application/sample-modules/isf/rgbtimeglitch.fs diff --git a/src/application/sample-modules/isf/rotozoomer.fs b/src/renderer/src/application/sample-modules/isf/rotozoomer.fs similarity index 100% rename from src/application/sample-modules/isf/rotozoomer.fs rename to src/renderer/src/application/sample-modules/isf/rotozoomer.fs diff --git a/src/application/sample-modules/isf/scale.fs b/src/renderer/src/application/sample-modules/isf/scale.fs similarity index 100% rename from src/application/sample-modules/isf/scale.fs rename to src/renderer/src/application/sample-modules/isf/scale.fs diff --git a/src/application/sample-modules/isf/spherical-shader-tut.fs b/src/renderer/src/application/sample-modules/isf/spherical-shader-tut.fs similarity index 100% rename from src/application/sample-modules/isf/spherical-shader-tut.fs rename to src/renderer/src/application/sample-modules/isf/spherical-shader-tut.fs diff --git a/src/application/sample-modules/isf/st_Ms2SD1.fs.fs b/src/renderer/src/application/sample-modules/isf/st_Ms2SD1.fs.fs similarity index 100% rename from src/application/sample-modules/isf/st_Ms2SD1.fs.fs rename to src/renderer/src/application/sample-modules/isf/st_Ms2SD1.fs.fs diff --git a/src/application/sample-modules/isf/st_lsfGDH.fs b/src/renderer/src/application/sample-modules/isf/st_lsfGDH.fs similarity index 100% rename from src/application/sample-modules/isf/st_lsfGDH.fs rename to src/renderer/src/application/sample-modules/isf/st_lsfGDH.fs diff --git a/src/application/sample-modules/isf/tapestryfract.fs b/src/renderer/src/application/sample-modules/isf/tapestryfract.fs similarity index 100% rename from src/application/sample-modules/isf/tapestryfract.fs rename to src/renderer/src/application/sample-modules/isf/tapestryfract.fs diff --git a/src/application/sample-modules/isf/v002 Bleach Bypass.fs b/src/renderer/src/application/sample-modules/isf/v002 Bleach Bypass.fs similarity index 100% rename from src/application/sample-modules/isf/v002 Bleach Bypass.fs rename to src/renderer/src/application/sample-modules/isf/v002 Bleach Bypass.fs diff --git a/src/application/sample-modules/isf/v002 Crosshatch.fs b/src/renderer/src/application/sample-modules/isf/v002 Crosshatch.fs similarity index 100% rename from src/application/sample-modules/isf/v002 Crosshatch.fs rename to src/renderer/src/application/sample-modules/isf/v002 Crosshatch.fs diff --git a/src/application/sample-modules/isf/v002 Dilate.fs b/src/renderer/src/application/sample-modules/isf/v002 Dilate.fs similarity index 100% rename from src/application/sample-modules/isf/v002 Dilate.fs rename to src/renderer/src/application/sample-modules/isf/v002 Dilate.fs diff --git a/src/application/sample-modules/isf/v002 Dilate.vs b/src/renderer/src/application/sample-modules/isf/v002 Dilate.vs similarity index 100% rename from src/application/sample-modules/isf/v002 Dilate.vs rename to src/renderer/src/application/sample-modules/isf/v002 Dilate.vs diff --git a/src/application/sample-modules/isf/v002 Erode.fs b/src/renderer/src/application/sample-modules/isf/v002 Erode.fs similarity index 100% rename from src/application/sample-modules/isf/v002 Erode.fs rename to src/renderer/src/application/sample-modules/isf/v002 Erode.fs diff --git a/src/application/sample-modules/isf/v002 Erode.vs b/src/renderer/src/application/sample-modules/isf/v002 Erode.vs similarity index 100% rename from src/application/sample-modules/isf/v002 Erode.vs rename to src/renderer/src/application/sample-modules/isf/v002 Erode.vs diff --git a/src/application/sample-modules/isf/v002 Light Leak.fs b/src/renderer/src/application/sample-modules/isf/v002 Light Leak.fs similarity index 100% rename from src/application/sample-modules/isf/v002 Light Leak.fs rename to src/renderer/src/application/sample-modules/isf/v002 Light Leak.fs diff --git a/src/application/sample-modules/isf/v002 Light Leak.vs b/src/renderer/src/application/sample-modules/isf/v002 Light Leak.vs similarity index 100% rename from src/application/sample-modules/isf/v002 Light Leak.vs rename to src/renderer/src/application/sample-modules/isf/v002 Light Leak.vs diff --git a/src/application/sample-modules/isf/v002 Technicolor.fs b/src/renderer/src/application/sample-modules/isf/v002 Technicolor.fs similarity index 100% rename from src/application/sample-modules/isf/v002 Technicolor.fs rename to src/renderer/src/application/sample-modules/isf/v002 Technicolor.fs diff --git a/src/application/sample-modules/isf/v002 Vignette.fs b/src/renderer/src/application/sample-modules/isf/v002 Vignette.fs similarity index 100% rename from src/application/sample-modules/isf/v002 Vignette.fs rename to src/renderer/src/application/sample-modules/isf/v002 Vignette.fs diff --git a/src/application/sample-modules/isf/v002-CRT-Displacement.fs b/src/renderer/src/application/sample-modules/isf/v002-CRT-Displacement.fs similarity index 100% rename from src/application/sample-modules/isf/v002-CRT-Displacement.fs rename to src/renderer/src/application/sample-modules/isf/v002-CRT-Displacement.fs diff --git a/src/application/sample-modules/isf/v002-CRT-Mask-RGB-Shadow.png b/src/renderer/src/application/sample-modules/isf/v002-CRT-Mask-RGB-Shadow.png similarity index 100% rename from src/application/sample-modules/isf/v002-CRT-Mask-RGB-Shadow.png rename to src/renderer/src/application/sample-modules/isf/v002-CRT-Mask-RGB-Shadow.png diff --git a/src/application/sample-modules/isf/v002-CRT-Mask-RGB-Staggered.png b/src/renderer/src/application/sample-modules/isf/v002-CRT-Mask-RGB-Staggered.png similarity index 100% rename from src/application/sample-modules/isf/v002-CRT-Mask-RGB-Staggered.png rename to src/renderer/src/application/sample-modules/isf/v002-CRT-Mask-RGB-Staggered.png diff --git a/src/application/sample-modules/isf/v002-CRT-Mask-RGB-Straight.png b/src/renderer/src/application/sample-modules/isf/v002-CRT-Mask-RGB-Straight.png similarity index 100% rename from src/application/sample-modules/isf/v002-CRT-Mask-RGB-Straight.png rename to src/renderer/src/application/sample-modules/isf/v002-CRT-Mask-RGB-Straight.png diff --git a/src/application/sample-modules/isf/v002-CRT-Mask-Scanline-Staggered.png b/src/renderer/src/application/sample-modules/isf/v002-CRT-Mask-Scanline-Staggered.png similarity index 100% rename from src/application/sample-modules/isf/v002-CRT-Mask-Scanline-Staggered.png rename to src/renderer/src/application/sample-modules/isf/v002-CRT-Mask-Scanline-Staggered.png diff --git a/src/application/sample-modules/isf/v002-CRT-Mask.fs b/src/renderer/src/application/sample-modules/isf/v002-CRT-Mask.fs similarity index 100% rename from src/application/sample-modules/isf/v002-CRT-Mask.fs rename to src/renderer/src/application/sample-modules/isf/v002-CRT-Mask.fs diff --git a/src/application/setup-beat-detektor.js b/src/renderer/src/application/setup-beat-detektor.js similarity index 87% rename from src/application/setup-beat-detektor.js rename to src/renderer/src/application/setup-beat-detektor.js index f6e40d20f..a4c1e3a94 100644 --- a/src/application/setup-beat-detektor.js +++ b/src/renderer/src/application/setup-beat-detektor.js @@ -1,6 +1,6 @@ -import BeatDetektor from "../../lib/BeatDetektor"; +import BeatDetektor from "../../../../lib/BeatDetektor.js"; -export default function() { +export default function () { const beatDetektor = new BeatDetektor(85, 169); const beatDetektorKick = new BeatDetektor.modules.vis.BassKick(); diff --git a/src/renderer/src/application/setup-grandiose.js b/src/renderer/src/application/setup-grandiose.js new file mode 100644 index 000000000..6105dfa0a --- /dev/null +++ b/src/renderer/src/application/setup-grandiose.js @@ -0,0 +1,53 @@ +let grandiose = require("grandiose"); + +// let grandiose = undefined; +let sender = undefined; + +export async function setupGrandiose() { + if (grandiose === undefined) { + /* eslint-disable */ + // __dirname = `${__dirname}/node_modules/grandiose`; + // __dirname = __dirname.replace("app.asar", "app.asar.unpacked"); + /* eslint-enable */ + + try { + grandiose = require("grandiose"); + } catch (error) { + if (error.message.includes("libndi.so")) { + const store = await import("./worker/store/index"); + store.dispatch("errors/createMessage", { + message: + "libndi is not installed, please see \"Ubuntu/Debian\" in the modV README.", + }); + } else { + console.error(error); + } + } + + // eslint-disable-next-line + // __dirname = __dirname.replace("/node_modules/grandiose", ""); + } + + // Make sure to set grandiose to undefined as it will be an empty object otherwise + if (!grandiose.isSupportedCPU()) { + grandiose = undefined; + } + + return grandiose; +} + +export async function getGrandioseSender() { + if (grandiose === undefined) { + await setupGrandiose(); + } + + if (!sender) { + sender = await grandiose.send({ + name: `modV`, + clockVideo: false, + clockAudio: false, + }); + } + + return sender; +} diff --git a/src/application/setup-media.js b/src/renderer/src/application/setup-media.js similarity index 93% rename from src/application/setup-media.js rename to src/renderer/src/application/setup-media.js index 553862b29..8007ccf50 100644 --- a/src/application/setup-media.js +++ b/src/renderer/src/application/setup-media.js @@ -12,7 +12,7 @@ async function enumerateDevices() { const devices = await navigator.mediaDevices.enumerateDevices(); const sources = { audio: [], - video: [] + video: [], }; for (let i = 0, len = devices.length; i < len; i++) { @@ -48,7 +48,7 @@ async function getMediaStream({ audioSourceId, videoSourceId }) { if (audioSourceId) { audioConstraints.audio = { echoCancellation: { exact: false }, - deviceId: audioSourceId + deviceId: audioSourceId, }; } @@ -56,15 +56,15 @@ async function getMediaStream({ audioSourceId, videoSourceId }) { videoConstraints.video = { deviceId: videoSourceId, frameRate: { - ideal: 60 - } + ideal: 60, + }, }; } /* Ask for user media access */ return [ audioSourceId && navigator.mediaDevices.getUserMedia(audioConstraints), - videoSourceId && navigator.mediaDevices.getUserMedia(videoConstraints) + videoSourceId && navigator.mediaDevices.getUserMedia(videoConstraints), ]; } @@ -109,8 +109,8 @@ async function setupMedia({ audioId, videoId, useDefaultDevices = false }) { const [audioMediaStream, videoMediaStream] = await Promise.all( await getMediaStream({ audioSourceId, - videoSourceId - }) + videoSourceId, + }), ); // This video element is required to keep the camera alive for the ImageCapture API @@ -136,7 +136,7 @@ async function setupMedia({ audioId, videoId, useDefaultDevices = false }) { } store.commit("mediaStream/SET_CURRENT_VIDEO_SOURCE", { - videoId: videoSourceId + videoId: videoSourceId, }); } @@ -147,7 +147,7 @@ async function setupMedia({ audioId, videoId, useDefaultDevices = false }) { // Create new Audio Context this.audioContext = new window.AudioContext({ - latencyHint: "playback" + latencyHint: "playback", }); // Create new Audio Analyser @@ -158,7 +158,7 @@ async function setupMedia({ audioId, videoId, useDefaultDevices = false }) { floatFrequencyDataArray = new Float32Array(analyserNode.frequencyBinCount); byteFrequencyDataArray = new Uint8Array(analyserNode.frequencyBinCount); byteTimeDomainDataArray = new Uint8Array( - analyserNode.frequencyBinCount / 2 + analyserNode.frequencyBinCount / 2, ); // Create a gain node @@ -168,9 +168,8 @@ async function setupMedia({ audioId, videoId, useDefaultDevices = false }) { this.gainNode.gain.value = 1; // Create the audio input stream (audio) - this.audioStream = this.audioContext.createMediaStreamSource( - audioMediaStream - ); + this.audioStream = + this.audioContext.createMediaStreamSource(audioMediaStream); // Connect the audio stream to the analyser (this is a passthru) (audio->(analyser)) this.audioStream.connect(analyserNode); @@ -185,11 +184,11 @@ async function setupMedia({ audioId, videoId, useDefaultDevices = false }) { source: this.gainNode, bufferSize: constants.AUDIO_BUFFER_SIZE, windowingFunction: "rect", - featureExtractors: ["complexSpectrum"] + featureExtractors: ["complexSpectrum"], }); store.commit("mediaStream/SET_CURRENT_AUDIO_SOURCE", { - audioId: audioSourceId + audioId: audioSourceId, }); } @@ -220,5 +219,5 @@ export { setupMedia, getFloatFrequencyData, getByteFrequencyData, - getByteTimeDomainData + getByteTimeDomainData, }; diff --git a/src/application/setup-midi.js b/src/renderer/src/application/setup-midi.js similarity index 93% rename from src/application/setup-midi.js rename to src/renderer/src/application/setup-midi.js index 09fc8d460..135533f85 100644 --- a/src/application/setup-midi.js +++ b/src/renderer/src/application/setup-midi.js @@ -9,7 +9,7 @@ const TYPE_CC = 176; // create a new audioContext to use intead of modV's // existing context - we get timing jitters otherwise const audioContext = new window.AudioContext({ - latencyHint: "playback" + latencyHint: "playback", }); // hack around chrome's autoplay policy @@ -23,7 +23,7 @@ window.addEventListener("click", resume); function handleInput(message) { const { data: [type, channel, data], - currentTarget: { id, name, manufacturer } + currentTarget: { id, name, manufacturer }, } = message; const device = store.state.midi.devices[`${id}-${name}-${manufacturer}`]; @@ -57,7 +57,7 @@ function handleInput(message) { if (checkDifference > 50) { console.warn( "MIDI: resetting clock detection as difference was too big", - checkDifference + checkDifference, ); diffHistory.splice(0, diffHistory.length); clockHistory.splice(0, clockHistory.length); @@ -118,7 +118,7 @@ function handleInput(message) { id: `${id}-${name}-${manufacturer}`, type: _type, channel, - data: _data + data: _data, }); } @@ -133,7 +133,8 @@ function handleInput(message) { function handleDevices(inputs) { // loop over all available inputs and listen for any MIDI input - for(let input of inputs.values()) { // eslint-disable-line + for (let input of inputs.values()) { + // eslint-disable-line // each time there is a midi message call the onMIDIMessage function input.removeEventListener("midimessage", handleInput); input.addEventListener("midimessage", handleInput); @@ -141,7 +142,7 @@ function handleDevices(inputs) { store.commit("midi/ADD_DEVICE", { id: input.id, name: input.name, - manufacturer: input.manufacturer + manufacturer: input.manufacturer, }); } } @@ -154,7 +155,7 @@ async function setupMidi() { handleDevices.bind(this)(access.inputs); - access.addEventListener("statechange", e => { + access.addEventListener("statechange", (e) => { handleDevices(e.currentTarget.inputs); }); } else { diff --git a/src/application/setup-tweens.js b/src/renderer/src/application/setup-tweens.js similarity index 100% rename from src/application/setup-tweens.js rename to src/renderer/src/application/setup-tweens.js diff --git a/src/application/use.js b/src/renderer/src/application/use.js similarity index 100% rename from src/application/use.js rename to src/renderer/src/application/use.js diff --git a/src/application/utils/apply-expression.js b/src/renderer/src/application/utils/apply-expression.js similarity index 59% rename from src/application/utils/apply-expression.js rename to src/renderer/src/application/utils/apply-expression.js index b3cb08566..495192212 100644 --- a/src/application/utils/apply-expression.js +++ b/src/renderer/src/application/utils/apply-expression.js @@ -2,9 +2,8 @@ import get from "lodash.get"; import store from "../worker/store"; export function applyExpression({ value, inputId }) { - const expressionAssignment = store.getters["expressions/getByInputId"]( - inputId - ); + const expressionAssignment = + store.getters["expressions/getByInputId"](inputId); const input = store.state.inputs.inputs[inputId]; @@ -14,10 +13,11 @@ export function applyExpression({ value, inputId }) { const scope = { value: dataOut, time: Date.now(), - inputValue: get(store.state, input.getLocation) + inputValue: get(store.state, input.getLocation), + osc: store.state.osc.data, }; - dataOut = expressionAssignment.func.evaluate(scope); + dataOut = expressionAssignment.func(scope); } return dataOut; diff --git a/src/application/utils/conform-file-path.js b/src/renderer/src/application/utils/conform-file-path.js similarity index 70% rename from src/application/utils/conform-file-path.js rename to src/renderer/src/application/utils/conform-file-path.js index 38dfde947..a2f090c14 100644 --- a/src/application/utils/conform-file-path.js +++ b/src/renderer/src/application/utils/conform-file-path.js @@ -1,4 +1,7 @@ -import path from "path"; +const path = { + posix: { sep: "/" }, + win32: { sep: "\\" }, +}; export const conformFilePath = (filePath = "") => filePath diff --git a/src/application/utils/get-next-name.js b/src/renderer/src/application/utils/get-next-name.js similarity index 82% rename from src/application/utils/get-next-name.js rename to src/renderer/src/application/utils/get-next-name.js index e60b0b6ce..ba78231f3 100644 --- a/src/application/utils/get-next-name.js +++ b/src/renderer/src/application/utils/get-next-name.js @@ -7,7 +7,7 @@ function nameTemplate(name, count) { } export default function findBestName(nameIn, names) { - return new Promise(resolve => { + return new Promise((resolve) => { if (names.indexOf(nameIn) < 0) { resolve(nameIn); } @@ -17,7 +17,7 @@ export default function findBestName(nameIn, names) { let count = 1; let newName = nameTemplate(nameIn, count); - const filteredNames = names.filter(arrName => arrName.match(nameRe)); + const filteredNames = names.filter((arrName) => arrName.match(nameRe)); while (filteredNames.indexOf(newName) > -1) { count += 1; diff --git a/src/application/utils/get-prop-default.js b/src/renderer/src/application/utils/get-prop-default.js similarity index 83% rename from src/application/utils/get-prop-default.js rename to src/renderer/src/application/utils/get-prop-default.js index a536c3479..ae9fc9e57 100644 --- a/src/application/utils/get-prop-default.js +++ b/src/renderer/src/application/utils/get-prop-default.js @@ -1,15 +1,19 @@ -import Vue from "vue"; +import { reactive } from "vue"; import store from "../worker/store"; export default async function getPropDefault( module, propName, prop, - useExistingData + useExistingData, ) { const { random, type } = prop; let defaultValue = prop.default; + if (!defaultValue && type === "enum") { + return prop.enum.find((a) => a.selected)?.value; + } + if (store.state.dataTypes[type]) { if (!defaultValue && store.state.dataTypes[type].inputs) { defaultValue = store.state.dataTypes[type].inputs(); @@ -23,7 +27,7 @@ export default async function getPropDefault( return await store.state.dataTypes[type].create( propData, module.meta.isGallery, - useExistingData + useExistingData, ); } } @@ -33,7 +37,7 @@ export default async function getPropDefault( } if (Array.isArray(defaultValue)) { - defaultValue = Vue.observable(defaultValue); + defaultValue = reactive(defaultValue); } if ( diff --git a/src/application/utils/lerp.js b/src/renderer/src/application/utils/lerp.js similarity index 100% rename from src/application/utils/lerp.js rename to src/renderer/src/application/utils/lerp.js diff --git a/src/application/utils/map.js b/src/renderer/src/application/utils/map.js similarity index 58% rename from src/application/utils/map.js rename to src/renderer/src/application/utils/map.js index b90a931e9..c7103d750 100644 --- a/src/application/utils/map.js +++ b/src/renderer/src/application/utils/map.js @@ -1,4 +1,4 @@ export default function map(value, low1, high1, low2, high2) { // eslint-disable-next-line - return low2 + (high2 - low2) * (value - low1) / (high1 - low1); + return low2 + ((high2 - low2) * (value - low1)) / (high1 - low1); } diff --git a/src/application/window-handler.js b/src/renderer/src/application/window-handler.js similarity index 89% rename from src/application/window-handler.js rename to src/renderer/src/application/window-handler.js index 39dfd17b6..7ae11dd73 100644 --- a/src/application/window-handler.js +++ b/src/renderer/src/application/window-handler.js @@ -9,7 +9,7 @@ export default function windowHandler() { canvas.ownerDocument.body.style.cursor = "none"; } - return function() { + return function () { if (mouseTimer) { clearTimeout(mouseTimer); } @@ -19,10 +19,16 @@ export default function windowHandler() { }; } + /** + * @param {Object} args + * @param {Window} args.win + * @param {HTMLCanvasElement} args.canvas + * @param {string} args.backgroundColor + */ function configureWindow({ win, canvas, backgroundColor }) { win.document.body.appendChild(canvas); win.document.body.style.backgroundColor = backgroundColor; - win.addEventListener("beforeunload", ev => { + win.addEventListener("beforeunload", (ev) => { // Setting any value other than undefined here will prevent the window // from closing or reloading ev.returnValue = true; @@ -42,7 +48,7 @@ export default function windowHandler() { } } - return function() { + return function () { if (poll) { clearTimeout(poll); } @@ -56,7 +62,7 @@ export default function windowHandler() { this.store.dispatch("size/setSize", { width, - height + height, }); } @@ -67,14 +73,14 @@ export default function windowHandler() { const win = window.open( "./output-window.html", "modal", - `width=${width}, height=${height}, location=no, menubar=no, left=0` + `width=${width}, height=${height}, location=no, menubar=no, left=0`, ); win.document.title = title; if (win === null || typeof win === "undefined") { console.log( "Could not create Output Window", - "modV couldn't open an Output Window. Please check you've allowed pop-ups, then reload" + "modV couldn't open an Output Window. Please check you've allowed pop-ups, then reload", ); return; @@ -89,15 +95,15 @@ export default function windowHandler() { { canvas: offscreen, name: `window-${Object.keys(windows).length}`, - group: "window" + group: "window", }, - [offscreen] + [offscreen], ); this.store.commit("windows/UPDATE_WINDOW", { id, key: "outputId", - value: outputId + value: outputId, }); canvas.style.backgroundColor = "transparent"; diff --git a/src/application/worker/audio-features.js b/src/renderer/src/application/worker/audio-features.js similarity index 95% rename from src/application/worker/audio-features.js rename to src/renderer/src/application/worker/audio-features.js index 4f3951b2f..4979f2e87 100644 --- a/src/application/worker/audio-features.js +++ b/src/renderer/src/application/worker/audio-features.js @@ -30,7 +30,7 @@ function getSmoothedFeature(feature, id, smoothingValue) { smoothedFeatures[id] = lerp( smoothedFeatures[id] || 0, features[feature], - smoothingValue + smoothingValue, ); return smoothedFeatures[id]; @@ -44,5 +44,5 @@ export { removeSmoothingId, getSmoothedFeature, MAX_SMOOTHING, - SMOOTHING_STEP + SMOOTHING_STEP, }; diff --git a/src/application/worker/frame-counter.js b/src/renderer/src/application/worker/frame-counter.js similarity index 100% rename from src/application/worker/frame-counter.js rename to src/renderer/src/application/worker/frame-counter.js diff --git a/src/application/worker/index.worker.js b/src/renderer/src/application/worker/index.worker.js similarity index 65% rename from src/application/worker/index.worker.js rename to src/renderer/src/application/worker/index.worker.js index 7a8432f0e..d4c08df33 100644 --- a/src/application/worker/index.worker.js +++ b/src/renderer/src/application/worker/index.worker.js @@ -1,28 +1,37 @@ -/* eslint-env worker node */ -const { default: constants } = require("../constants"); +/* eslint-env worker */ +import constants from "../constants"; +import registerPromiseWorker from "promise-worker/register"; +import store from "./store"; +import loop, { ndiWorker } from "./loop"; +import grabCanvasPlugin from "../plugins/grab-canvas"; +import get from "lodash.get"; +import { tick as frameTick } from "./frame-counter"; +import { getFeatures, setFeatures } from "./audio-features"; + +const fs = require("fs"); let lastKick = false; -async function start() { - const registerPromiseWorker = require("promise-worker/register"); - const fs = require("fs"); - const store = require("./store").default; - const loop = require("./loop").default; - const grabCanvasPlugin = require("../plugins/grab-canvas").default; - const get = require("lodash.get"); +function getFilename(path) { + return path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf(".")); +} + +function getTime() { + const hrTime = global["process"].hrtime(); + return hrTime[0] * 1000000000 + hrTime[1]; +} +async function start() { // For Playwright self._get = get; - const { tick: frameTick } = require("./frame-counter"); - const { getFeatures, setFeatures } = require("./audio-features"); // const featureAssignmentPlugin = require("../plugins/feature-assignment"); let interval = store.getters["fps/interval"]; const commitQueue = []; - store.subscribe(mutation => { + store.subscribe((mutation) => { const { type: mutationType, payload: mutationPayload } = mutation; if (mutationType === "beats/SET_BPM" || mutationType === "fps/SET_FPS") { @@ -53,12 +62,12 @@ async function start() { } const { - inputs: { inputs, inputLinks } + inputs: { inputs, inputLinks }, } = store.state; // Update mutation type Input Links const mutationTypeInputLinks = Object.values(inputLinks).filter( - link => link.type === "mutation" + (link) => link.type === "mutation", ); const inputLinksLength = mutationTypeInputLinks.length; for (let i = 0; i < inputLinksLength; ++i) { @@ -78,7 +87,7 @@ async function start() { if (match.payload) { const matchPayloadKeys = Object.keys(match.payload); - payloadMatches = matchPayloadKeys.every(key => { + payloadMatches = matchPayloadKeys.every((key) => { const value = match.payload[key]; return value === mutationPayload[key]; }); @@ -108,106 +117,97 @@ async function start() { self.postMessage({ type: "commitQueue", - payload: commits + payload: commits, }); } store.dispatch("plugins/add", grabCanvasPlugin); - const renderers = require.context("../renderers/", false, /\.js$/); - - const rendererKeys = renderers.keys(); - for (let i = 0, len = rendererKeys.length; i < len; i++) { - const rendererName = rendererKeys[i]; - - const { - render, - setupModule, - removeModule, - updateModule, - resizeModule, - tick, - resize, - createPresetData, - loadPresetData, - getModuleData - } = renderers(rendererName).default; - - store.commit("renderers/ADD_RENDERER", { - name: rendererName.replace(/(\.\/|\.js)/g, ""), - render, - resize, - setupModule, - removeModule, - updateModule, - resizeModule, - createPresetData, - loadPresetData, - getModuleData, - tick + const rendererModules = import.meta.glob("../renderers/*.js"); + + for (const pathKey in rendererModules) { + const rendererName = getFilename(pathKey); + + rendererModules[pathKey]().then((mod) => { + const { + render, + setupModule, + updateModule, + resizeModule, + tick, + resize, + createPresetData, + loadPresetData, + getModuleData, + addActiveModule, + removeActiveModule, + } = mod.default; + + store.commit("renderers/ADD_RENDERER", { + name: rendererName.replace(/(\.\/|\.js)/g, ""), + render, + resize, + setupModule, + updateModule, + resizeModule, + createPresetData, + loadPresetData, + getModuleData, + addActiveModule, + removeActiveModule, + tick, + }); }); } - const modulesToRegister = []; - const sampleModules = require.context("../sample-modules/", false, /\.js$/); - - const sampleModuleKeys = sampleModules.keys(); - for (let i = 0, len = sampleModuleKeys.length; i < len; i++) { - const moduleName = sampleModuleKeys[i]; - - const sampleModule = sampleModules(moduleName).default; - - // if (module.hot) { - // // console.log(module); - // const path = `./src/application/sample-modules/${moduleName.replace( - // "./", - // "" - // )}`; - // // console.log(path); - // module.hot.accept( - // `./src/application/sample-modules/${moduleName.replace("./", "")}`, - // function() { - // console.log(`Accepting the updated ${moduleName} module!`); - // debugger; - // } - // ); - // } - - modulesToRegister.push(sampleModule); + let modulesToRegister = []; + const sampleModules = import.meta.glob("../sample-modules/*.js"); + + for (const pathKey in sampleModules) { + const mod = await sampleModules[pathKey](); + modulesToRegister.push(mod.default); } - const isfModules = require.context("../sample-modules/isf", false, /\.fs$/); - const isfModulesVs = require.context("../sample-modules/isf", false, /\.vs$/); - const isfModulesVsKeys = isfModulesVs.keys(); + const isfModules = import.meta.glob("../sample-modules/isf/*.fs", { + query: "?raw", + }); + const isfModulesVs = import.meta.glob("../sample-modules/isf/*.vs", { + query: "?raw", + }); - const isfModuleKeys = isfModules.keys(); + const isfModulesVsKeys = Object.keys(isfModulesVs); + + const isfModuleKeys = Object.keys(isfModules); for (let i = 0, len = isfModuleKeys.length; i < len; i++) { - const fileName = isfModuleKeys[i]; - const fragmentShader = isfModules(fileName); + const key = isfModuleKeys[i]; + const fragmentShader = (await isfModules[key]()).default; let vertexShader = "void main() {isf_vertShaderInit();}"; - const vsIndex = isfModulesVsKeys.indexOf(fileName.replace(".fs", ".vs")); + const vsIndex = isfModulesVsKeys.indexOf(key.replace(".fs", ".vs")); if (vsIndex > -1) { - vertexShader = isfModulesVs(isfModulesVsKeys[vsIndex]); + vertexShader = (await isfModulesVs[isfModulesVsKeys[vsIndex]]()).default; } + const isfModule = { meta: { - name: fileName.replace(/(\.\/|\.fs)/g, ""), + name: getFilename(isfModuleKeys[i]), author: "", version: "1.0.0", - type: "isf" + type: "isf", }, fragmentShader, - vertexShader + vertexShader, }; modulesToRegister.push(isfModule); } await Promise.all( - modulesToRegister.map(module => - store.dispatch("modules/registerModule", { module }) - ) + modulesToRegister.map((module) => + store.dispatch("modules/registerModule", { module }), + ), ); + modulesToRegister = []; + // store.dispatch("plugins/add", featureAssignmentPlugin); const webcamOutput = await store.dispatch("outputs/getAuxillaryOutput", { @@ -215,7 +215,7 @@ async function start() { reactToResize: false, width: 1920, height: 1080, - group: "input" + group: "input", }); store.dispatch("outputs/setWebcamOutput", webcamOutput.context); @@ -225,25 +225,30 @@ async function start() { width: constants.AUDIO_BUFFER_SIZE, height: 1, group: "audio", - id: "fft" + id: "fft", }); - // eslint-disable-next-line - let raf = requestAnimationFrame(looper); + let raf; + if (!raf) { + raf = requestAnimationFrame(looper); + } + let frames = 0; let prevTime = 0; let now; - let then = Date.now(); + let then = getTime(); let delta; function looper(rafDelta) { raf = requestAnimationFrame(looper); - now = Date.now(); + now = getTime(); delta = now - then; - if (delta > interval) { + sendCommitQueue(); + + if (delta > interval * 1000000) { // update time stuffs // Just `then = now` is not enough. @@ -258,17 +263,16 @@ async function start() { // by subtracting delta (112) % interval (100). // Hope that makes sense. - then = now - (delta % interval); + then = now - (delta % (interval * 1000000)); frameActions(rafDelta); } } function frameActions(delta) { - sendCommitQueue(); self.postMessage({ type: "tick", - payload: delta + payload: delta, }); loop(delta, getFeatures(), fftOutput); @@ -281,7 +285,7 @@ async function start() { if (time >= prevTime + 1000) { store.commit( "metrics/SET_FPS_MEASURE", - (frames * 1000) / (time - prevTime) + (frames * 1000) / (time - prevTime), ); prevTime = time; @@ -289,7 +293,7 @@ async function start() { } } - self.addEventListener("message", async e => { + self.addEventListener("message", async (e) => { const message = e.data; const { type, identifier, payload } = message; if (Array.isArray(message) && message[1].__async) { @@ -331,16 +335,22 @@ async function start() { console.log(preset); + const cleanupFunctionsAfterSwap = []; + const storeModuleKeys = Object.keys(preset); for (let i = 0, len = storeModuleKeys.length; i < len; i++) { const storeModuleKey = storeModuleKeys[i]; try { console.log("Loading from preset…", storeModuleKey); - await store.dispatch( + const fn = await store.dispatch( `${storeModuleKey}/loadPresetData`, - preset[storeModuleKey] + preset[storeModuleKey], ); + + if (fn) { + cleanupFunctionsAfterSwap.push(fn); + } } catch (e) { console.error(e); } @@ -351,13 +361,26 @@ async function start() { store.commit("inputs/SWAP"); store.commit("expressions/SWAP"); + cleanupFunctionsAfterSwap.forEach((fn) => fn()); + + return; + } + + if (type === "modv-destroy") { + console.log("worker got modv-destroy, sending onto ndi worker"); + + ndiWorker.addEventListener("message", () => { + console.log("worker got destroyed, sending onto webcontents"); + self.postMessage({ type: "destroyed" }); + }); + ndiWorker.postMessage({ type: "destroy" }); return; } store[type](identifier, payload); }); - registerPromiseWorker(async message => { + registerPromiseWorker(async (message) => { const { type, identifier, payload, __async } = message; if (__async) { if (type === "generatePreset") { @@ -369,7 +392,7 @@ async function start() { try { preset[storeModuleKey] = await store.dispatch( - `${storeModuleKey}/createPresetData` + `${storeModuleKey}/createPresetData`, ); } catch (e) { // do nothing @@ -395,7 +418,7 @@ async function start() { self.store = store; self.postMessage({ - type: "worker-setup-complete" + type: "worker-setup-complete", }); } diff --git a/src/application/worker/loop.js b/src/renderer/src/application/worker/loop.js similarity index 89% rename from src/application/worker/loop.js rename to src/renderer/src/application/worker/loop.js index dd5f76a21..cc48c21d8 100644 --- a/src/application/worker/loop.js +++ b/src/renderer/src/application/worker/loop.js @@ -3,6 +3,7 @@ import get from "lodash.get"; import store from "./store"; import map from "../utils/map"; import constants, { GROUP_DISABLED, GROUP_ENABLED } from "../constants"; +import NdiWorker from "./ndi-worker.worker.js?worker"; import { applyWindow } from "meyda/dist/esm/utilities"; const meyda = { windowing: applyWindow }; @@ -11,14 +12,16 @@ let bufferCanvas; let bufferContext; const fallbackByteFrequencyData = Array(constants.AUDIO_BUFFER_SIZE).fill(0); -function loop(delta, features, fftOutput) { +export const ndiWorker = new NdiWorker(); + +async function loop(delta, features, fftOutput) { if (!bufferCanvas) { bufferCanvas = new OffscreenCanvas(300, 300); bufferContext = bufferCanvas.getContext("2d"); store.dispatch("outputs/addAuxillaryOutput", { name: "loop-buffer", context: bufferContext, - group: "buffer" + group: "buffer", }); return; @@ -31,7 +34,7 @@ function loop(delta, features, fftOutput) { inputs: { inputs, inputLinks }, outputs: { main, debug, debugContext, auxillary, webcam: video }, renderers, - windows + windows, } = store.state; const groupIndexRenderOrder = store.getters["groups/groupIndexRenderOrder"]; @@ -53,7 +56,7 @@ function loop(delta, features, fftOutput) { fftOutput.context.putImageData( new ImageData(uInt8Array, byteFrequencyData.length), 0, - 0 + 0, ); // Update Input Links @@ -68,7 +71,7 @@ function loop(delta, features, fftOutput) { type, location, data, - data: { path } + data: { path }, } = bind; const { @@ -77,7 +80,7 @@ function loop(delta, features, fftOutput) { args: linkArguments, min, max, - source + source, } = link; const moduleId = store.state.inputs.inputs[inputId].data.moduleId; @@ -124,7 +127,7 @@ function loop(delta, features, fftOutput) { preProcessFrameFunctions[i].preProcessFrame({ features, store, - props: preProcessFrameFunctions[i].$props + props: preProcessFrameFunctions[i].$props, }); } @@ -165,7 +168,7 @@ function loop(delta, features, fftOutput) { 0, 0, bufferContext.canvas.width, - bufferContext.canvas.height + bufferContext.canvas.height, ); } @@ -173,7 +176,7 @@ function loop(delta, features, fftOutput) { const canvasToInherit = inheritFrom === -1 ? lastCanvas - : groups.find(group => group.id === inheritFrom).context.context + : groups.find((group) => group.id === inheritFrom).context.context .canvas; drawTo.drawImage( @@ -181,7 +184,7 @@ function loop(delta, features, fftOutput) { 0, 0, drawTo.canvas.width, - drawTo.canvas.height + drawTo.canvas.height, ); if (pipeline && !isGalleryGroup) { @@ -190,7 +193,7 @@ function loop(delta, features, fftOutput) { 0, 0, drawTo.canvas.width, - drawTo.canvas.height + drawTo.canvas.height, ); } } @@ -235,13 +238,13 @@ function loop(delta, features, fftOutput) { data: { ...data }, canvas, context: drawTo, - delta + delta, }); store.commit("modules/UPDATE_ACTIVE_MODULE", { id: module.$id, key: "data", - value: moduleData + value: moduleData, }); } @@ -255,6 +258,7 @@ function loop(delta, features, fftOutput) { context: drawTo, delta, module: moduleDefinition, + moduleId: module.$id, features, meyda, video, @@ -262,7 +266,9 @@ function loop(delta, features, fftOutput) { data: moduleData, pipeline, kick, - fftCanvas: fftOutput.context.canvas + fftCanvas: fftOutput.context.canvas, + isGallery: isGalleryGroup, + osc: store.state.osc.data, }); drawTo.restore(); @@ -273,7 +279,7 @@ function loop(delta, features, fftOutput) { 0, 0, canvas.width, - canvas.height + canvas.height, ); drawTo.clearRect(0, 0, canvas.width, canvas.height); @@ -282,7 +288,7 @@ function loop(delta, features, fftOutput) { 0, 0, bufferCanvas.width, - bufferCanvas.height + bufferCanvas.height, ); } } @@ -305,7 +311,7 @@ function loop(delta, features, fftOutput) { context: { context }, alpha, enabled, - modules + modules, } = group; const groupModulesLength = modules.length; if (enabled !== GROUP_ENABLED || groupModulesLength < 1 || !(alpha > 0)) { @@ -359,7 +365,7 @@ function loop(delta, features, fftOutput) { 0, 0, debugCanvas.width, - debugCanvas.height + debugCanvas.height, ); } } @@ -373,9 +379,23 @@ function loop(delta, features, fftOutput) { canvas: main.canvas, features, store, - props: postProcessFrameFunctions[i].$props + props: postProcessFrameFunctions[i].$props, }); } + + // Gotta transfer after everything else as it transfers ownership of the canvas content + // i.e. main.canvas goes blank + + if (store.state.ndi.outputEnabled) { + const imageBitmap = await main.canvas.transferToImageBitmap(); + ndiWorker.postMessage( + { + type: "imageBitmap", + payload: { imageBitmap }, + }, + [imageBitmap], + ); + } } export default loop; diff --git a/src/renderer/src/application/worker/ndi-worker.worker.js b/src/renderer/src/application/worker/ndi-worker.worker.js new file mode 100644 index 000000000..3af1bfff8 --- /dev/null +++ b/src/renderer/src/application/worker/ndi-worker.worker.js @@ -0,0 +1,160 @@ +/* global BigInt */ +/* env node worker */ +import { getGrandioseSender, setupGrandiose } from "../setup-grandiose"; + +let sender; +let grandiose; + +const canvas = new OffscreenCanvas(256, 256); +const context = canvas.getContext("2d", { + alpha: false, + willReadFrequently: true, +}); + +// process.hrtime accessed via global["process"] to bypass the slightly +// incorrect bundle polyfill +const timeStart = + BigInt(Date.now()) * BigInt(1e6) - global["process"].hrtime.bigint(); + +function timeNow() { + return timeStart + global["process"].hrtime.bigint(); +} + +let buffer; +let imageData; +let senderPromise; +let ndiWidth = 256; +let ndiHeight = 256; +let prevTime = performance.now(); +let frames = 0; +let targetFps = 60; +let followModVFps = true; +let actualFps = 0; + +const NDI_LIB_FOURCC = (ch0, ch1, ch2, ch3) => + ch0.charCodeAt(0) | + (ch1.charCodeAt(0) << 8) | + (ch2.charCodeAt(0) << 16) | + (ch3.charCodeAt(0) << 24); + +const FOURCC_UYVY = NDI_LIB_FOURCC("U", "Y", "V", "Y"); +const FOURCC_UYVA = NDI_LIB_FOURCC("U", "Y", "V", "A"); +const FOURCC_P216 = NDI_LIB_FOURCC("P", "2", "1", "6"); +const FOURCC_PA16 = NDI_LIB_FOURCC("P", "A", "1", "6"); +const FOURCC_YV12 = NDI_LIB_FOURCC("Y", "V", "1", "2"); +const FOURCC_I420 = NDI_LIB_FOURCC("I", "4", "2", "0"); +const FOURCC_NV12 = NDI_LIB_FOURCC("N", "V", "1", "2"); +const FOURCC_BGRA = NDI_LIB_FOURCC("B", "G", "R", "A"); +const FOURCC_BGRX = NDI_LIB_FOURCC("B", "G", "R", "X"); +const FOURCC_RGBA = NDI_LIB_FOURCC("R", "G", "B", "A"); +const FOURCC_RGBX = NDI_LIB_FOURCC("R", "G", "B", "X"); +const FOURCC_FLTp = NDI_LIB_FOURCC("F", "L", "T", "p"); + +const fourCC = { + FOURCC_UYVY, + FOURCC_UYVA, + FOURCC_P216, + FOURCC_PA16, + FOURCC_YV12, + FOURCC_I420, + FOURCC_NV12, + FOURCC_BGRA, + FOURCC_BGRX, + FOURCC_RGBA, + FOURCC_RGBX, + FOURCC_FLTp, +}; + +(async () => { + grandiose = await setupGrandiose(); + sender = await getGrandioseSender(); +})(); + +// @TODO add extra handling for Grandiose destroy. self.onclose seems to do +// nothing. This should allow us to keep one NDI Output name instead of +// appending the date. Also better for memory as somewhere a reference is kept +// to the old sender. +self.onclose = function () { + if (sender) { + sender.destroy(); + } +}; + +self.onmessage = async function ({ data: { type, payload } }) { + if (type === "setScale") { + const { width, height } = payload; + ndiWidth = width; + ndiHeight = height; + } + + if (type === "destroy") { + console.log( + "ndi worker got modv-destroy, doing that and replying destroyed", + ); + + if (senderPromise) { + await senderPromise; + } + + await sender.destroy(); + self.postMessage("destroyed"); + sender = null; + self.close(); + return; + } + + if (!sender || type !== "imageBitmap") { + return; + } + + const { + imageBitmap, + imageBitmap: { width, height }, + } = payload; + + canvas.width = width; + canvas.height = height; + + context.drawImage(imageBitmap, 0, 0); + imageBitmap.close(); + + imageData = context.getImageData(0, 0, width, height); + + buffer = Buffer.from(imageData.data); + + if (buffer.byteLength % 4 !== 0) { + return; + } + + // https://github.com/rse/vingester/blob/master/vingester-browser-worker.js + const now = timeNow(); + const bytesForRGBA = 4; + const frame = { + timecode: now / BigInt(100), + + xres: width, + yres: height, + frameRateN: actualFps * 1000, + frameRateD: 1000, + pictureAspectRatio: width / height, + frameFormatType: grandiose.FORMAT_TYPE_PROGRESSIVE, + lineStrideBytes: width * bytesForRGBA, + + fourCC: fourCC.FOURCC_RGBX, + data: buffer, + }; + + senderPromise = sender.video(frame); + await senderPromise; + + frames += 1; + + const time = performance.now(); + + if (time >= prevTime + 1000) { + actualFps = (frames * 1000) / (time - prevTime); + + prevTime = time; + frames = 0; + } +}; diff --git a/src/renderer/src/application/worker/store/index.js b/src/renderer/src/application/worker/store/index.js new file mode 100644 index 000000000..745e3e872 --- /dev/null +++ b/src/renderer/src/application/worker/store/index.js @@ -0,0 +1,74 @@ +import { createStore } from "vuex"; +import createPersistedState from "vuex-persistedstate"; + +import beats from "./modules/beats.js"; +import dataTypes from "./modules/dataTypes.js"; +import errors from "./modules/errors.js"; +import expressions from "./modules/expressions.js"; +import fonts from "./modules/fonts.js"; +import fps from "./modules/fps.js"; +import groups from "./modules/groups.js"; +import images from "./modules/images.js"; +import inputs from "./modules/inputs.js"; +import media from "./modules/media.js"; +import mediaStream from "./modules/mediaStream.js"; +import metrics from "./modules/metrics.js"; +import meyda from "./modules/meyda.js"; +import midi from "./modules/midi.js"; +import modules from "./modules/modules.js"; +import ndi from "./modules/ndi.js"; +import osc from "./modules/osc.js"; +import outputs from "./modules/outputs.js"; +import plugins from "./modules/plugins.js"; +import projects from "./modules/projects.js"; +import renderers from "./modules/renderers.js"; +import size from "./modules/size.js"; +import tweens from "./modules/tweens.js"; +import videos from "./modules/videos.js"; +import windows from "./modules/windows.js"; + +const vuexPlugins = []; + +// createPersistedState doesn't work in the worker store, so don't run it there. +// That's okay as the worker doesn't need to know about mediaStream. +// If we want other persisted items that the worker needs to know about +// we'll need to implement something more complex to commit via postMessage. +if (self.document !== undefined) { + const dataState = createPersistedState({ + paths: ["mediaStream"], + }); + + vuexPlugins.push(dataState); +} + +export default createStore({ + modules: { + beats, + dataTypes, + errors, + expressions, + fonts, + fps, + groups, + images, + inputs, + media, + mediaStream, + metrics, + meyda, + midi, + modules, + ndi, + osc, + outputs, + plugins, + projects, + renderers, + size, + tweens, + videos, + windows, + }, + plugins: vuexPlugins, + strict: false, +}); diff --git a/src/application/worker/store/modules/beats.js b/src/renderer/src/application/worker/store/modules/beats.js similarity index 83% rename from src/application/worker/store/modules/beats.js rename to src/renderer/src/application/worker/store/modules/beats.js index ba819a570..4b6ed4d3b 100644 --- a/src/application/worker/store/modules/beats.js +++ b/src/renderer/src/application/worker/store/modules/beats.js @@ -1,10 +1,8 @@ -import Vue from "vue"; - const state = { bpm: 0, bpmSource: "beatdetektor", kick: false, - bpmSources: ["beatdetektor", "midi", "tap"] + bpmSources: ["beatdetektor", "midi", "tap"], }; const actions = { @@ -16,7 +14,7 @@ const actions = { if (source === state.bpmSource) { commit("SET_BPM", { bpm }); } - } + }, }; const mutations = { @@ -33,13 +31,13 @@ const mutations = { }, SET_BPM_SOURCE(state, { source }) { - Vue.set(state, "bpmSource", source); - } + state.bpmSource = source; + }, }; export default { namespaced: true, state, mutations, - actions + actions, }; diff --git a/src/application/worker/store/modules/common/swap.js b/src/renderer/src/application/worker/store/modules/common/swap.js similarity index 62% rename from src/application/worker/store/modules/common/swap.js rename to src/renderer/src/application/worker/store/modules/common/swap.js index 9eed32aa5..1a6e1e47e 100644 --- a/src/application/worker/store/modules/common/swap.js +++ b/src/renderer/src/application/worker/store/modules/common/swap.js @@ -1,5 +1,3 @@ -import Vue from "vue"; - /* * When loading a preset we want to swap the data from the preset with the current state * and make sure that only the "allowed" properties are moved, see sharedPropertyRestrictions. @@ -7,13 +5,19 @@ import Vue from "vue"; * The idea is that this makes loading presets smooth and the end user will not see any * glitches in the render loop. */ -export function SWAP(swap, getDefault, sharedPropertyRestrictions) { - return function(state) { +export function SWAP( + swap, + getDefault, + sharedPropertyRestrictions, + setDefault = true, +) { + return function (state) { const stateKeys = Object.keys(state); + const swapIndexes = {}; if (stateKeys.length) { // eslint-disable-next-line - stateKeys.forEach(key => { + stateKeys.forEach((key) => { const isArray = Array.isArray(state[key]); if (sharedPropertyRestrictions) { @@ -22,20 +26,29 @@ export function SWAP(swap, getDefault, sharedPropertyRestrictions) { // eslint-disable-next-line if (isArray) { + swapIndexes[key] = swap[key].length; + swap[key].push( + ...state[key].filter( + (...args) => !sharedPropertyRestrictions[key](...args), + ), + ); + state[key] = state[key].filter(sharedPropertyRestrictions[key]); } else { const restrictedKeys = sharedPropertyRestrictions[key]( - state[key] + state[key], ); // eslint-disable-next-line - stateChildKeys.forEach(stateChildKey => { + stateChildKeys.forEach((stateChildKey) => { if (restrictedKeys.indexOf(stateChildKey) < 0) { + swap[key][stateChildKey] = state[key][stateChildKey]; delete state[key][stateChildKey]; } }); } } else if (sharedPropertyRestrictions[key]) { + swap[key] = state[key]; delete state[key]; } } else { @@ -48,7 +61,7 @@ export function SWAP(swap, getDefault, sharedPropertyRestrictions) { if (swapKeys.length) { // eslint-disable-next-line - swapKeys.forEach(key => { + swapKeys.forEach((key) => { const isArray = Array.isArray(swap[key]); if (sharedPropertyRestrictions) { @@ -56,34 +69,41 @@ export function SWAP(swap, getDefault, sharedPropertyRestrictions) { const swapChildKeys = Object.keys(swap[key]); if (isArray) { - Vue.set(state, key, [...state[key], ...swap[key]]); + state[key] = [ + ...state[key], + ...swap[key].slice(0, swapIndexes[key]), + ]; + + swap[key] = swap[key].slice(swapIndexes[key], swap[key].length); } else { const restrictedKeys = sharedPropertyRestrictions[key](swap[key]); // eslint-disable-next-line - swapChildKeys.forEach(swapChildKey => { + swapChildKeys.forEach((swapChildKey) => { if (restrictedKeys.indexOf(swapChildKey) < 0) { - Vue.set(state[key], swapChildKey, swap[key][swapChildKey]); + state[key][swapChildKey] = swap[key][swapChildKey]; } }); } } else if (sharedPropertyRestrictions[key]) { if (isArray) { - Vue.set(state, key, [...swap[key]]); + state[key] = [...swap[key]]; } else { - Vue.set(state, key, { ...swap[key] }); + state[key] = { ...swap[key] }; } } } else { if (isArray) { - Vue.set(state, key, [...state[key], ...swap[key]]); + state[key] = [...state[key], ...swap[key]]; } else { - Vue.set(state, key, { ...state[key], ...swap[key] }); + state[key] = { ...state[key], ...swap[key] }; } } }); } - Object.assign(swap, getDefault()); + if (setDefault) { + Object.assign(swap, getDefault()); + } }; } diff --git a/src/application/worker/store/modules/dataTypes.js b/src/renderer/src/application/worker/store/modules/dataTypes.js similarity index 78% rename from src/application/worker/store/modules/dataTypes.js rename to src/renderer/src/application/worker/store/modules/dataTypes.js index 8dab2f645..7cb5d6eb8 100644 --- a/src/application/worker/store/modules/dataTypes.js +++ b/src/renderer/src/application/worker/store/modules/dataTypes.js @@ -3,35 +3,35 @@ import { frames, advanceFrame } from "./tweens"; const state = { text: { - get: value => value + get: (value) => value, }, int: { - get: value => value + get: (value) => value, }, bool: { - get: value => value + get: (value) => value, }, event: { - get: value => value + get: (value) => value, }, vec2: { - get: value => value, - inputs: () => ({ 0: 0, 1: 0 }) + get: (value) => value, + inputs: () => ({ 0: 0, 1: 0 }), }, vec3: { - get: value => value, - inputs: () => ({ 0: 0, 1: 0, 2: 0 }) + get: (value) => value, + inputs: () => ({ 0: 0, 1: 0, 2: 0 }), }, vec4: { - get: value => value, - inputs: () => ({ 0: 0, 1: 0, 2: 0, 3: 0 }) + get: (value) => value, + inputs: () => ({ 0: 0, 1: 0, 2: 0, 3: 0 }), }, float: { - get: value => value + get: (value) => value, }, color: { - get: value => value, - inputs: () => ({ r: 0, g: 0, b: 0, a: 0 }) + get: (value) => value, + inputs: () => ({ r: 0, g: 0, b: 0, a: 0 }), }, texture: { async create(textureDefinition = {}, isGallery, useExistingData = false) { @@ -44,7 +44,7 @@ const state = { let id; try { ({ id } = await store.dispatch("images/createImageFromPath", { - path + path, })); } catch (e) { console.error(e); @@ -59,7 +59,7 @@ const state = { try { ({ id } = await store.dispatch( "videos/createVideoFromPath", - textureDefinition + textureDefinition, )); } catch (e) { console.error(e); @@ -81,7 +81,7 @@ const state = { enumerable: true, get() { return store.state.dataTypes.texture.get(textureDefinition); - } + }, }); }, async destroy(textureDefinition) { @@ -89,58 +89,61 @@ const state = { if (type === "video") { await store.dispatch("videos/removeVideoById", { - id + id, }); } }, - get: textureDefinition => { + get: (textureDefinition) => { if (!textureDefinition.location.length) { return false; } return store.getters[textureDefinition.location](textureDefinition.id); - } + }, }, enum: { - get: value => value + get: (value) => value, }, tween: { async create(args, isGallery) { const tween = await store.dispatch("tweens/createTween", { ...args, - isGallery + isGallery, }); return Object.defineProperty(tween, "value", { enumerable: true, get() { return store.state.dataTypes.tween.get(tween); - } + }, }); }, - get: value => { + get: (value) => { const tween = store.state.tweens.tweens[value.id]; const frame = tween.frames[frames[value.id]]; advanceFrame(value.id); return frame; - } - } + }, + }, + osc: { + get: (value) => value, + }, }; const getters = { - types: state => Object.keys(state) + types: (state) => Object.keys(state), }; const actions = { createType({ state }, { type, args }) { return state[type].create(args); - } + }, }; export default { namespaced: true, state, getters, - actions + actions, }; diff --git a/src/application/worker/store/modules/errors.js b/src/renderer/src/application/worker/store/modules/errors.js similarity index 78% rename from src/application/worker/store/modules/errors.js rename to src/renderer/src/application/worker/store/modules/errors.js index 051dd4e8b..254dfc85e 100644 --- a/src/application/worker/store/modules/errors.js +++ b/src/renderer/src/application/worker/store/modules/errors.js @@ -1,8 +1,7 @@ -import Vue from "vue"; import { v4 as uuidv4 } from "uuid"; const state = { - messages: {} + messages: {}, }; const actions = { @@ -16,22 +15,22 @@ const actions = { deleteMessage({ commit }, { id }) { commit("REMOVE_MESSAGE", { id }); - } + }, }; const mutations = { CREATE_MESSAGE(state, { message, id }) { - Vue.set(state.messages, id, message); + state.messages[id] = message; }, REMOVE_MESSAGE(state, { id }) { - Vue.delete(state.messages, id); - } + delete state.messages[id]; + }, }; export default { namespaced: true, state, mutations, - actions + actions, }; diff --git a/src/application/worker/store/modules/expressions.js b/src/renderer/src/application/worker/store/modules/expressions.js similarity index 73% rename from src/application/worker/store/modules/expressions.js rename to src/renderer/src/application/worker/store/modules/expressions.js index cfca79b47..f34fc3b93 100644 --- a/src/application/worker/store/modules/expressions.js +++ b/src/renderer/src/application/worker/store/modules/expressions.js @@ -1,11 +1,10 @@ import get from "lodash.get"; import { v4 as uuidv4 } from "uuid"; import { SWAP } from "./common/swap"; -const math = require("mathjs"); function getDefaultState() { return { - assignments: {} + assignments: {}, }; } @@ -14,11 +13,13 @@ const swap = getDefaultState(); // getters const getters = { - getByInputId: state => inputId => { + getByInputId: (state) => (inputId) => { const assignmentValues = Object.values(state.assignments); - return assignmentValues.find(assignment => assignment.inputId === inputId); - } + return assignmentValues.find( + (assignment) => assignment.inputId === inputId, + ); + }, }; function compileExpression(expression, scopeItems = {}) { @@ -26,14 +27,20 @@ function compileExpression(expression, scopeItems = {}) { let newFunction; try { - const node = math.parse(expression, scope); - - newFunction = node.compile(); - newFunction.evaluate(scope); + newFunction = new Function( + "scope", + ` + const { ${Object.keys(scope).join(", ")} } = scope; + return ${expression}; + `, + ); } catch (e) { - throw e; + console.error("error in expression", e); + return; } + newFunction(scope); + return newFunction; } @@ -41,7 +48,7 @@ function compileExpression(expression, scopeItems = {}) { const actions = { create( { rootState, commit }, - { expression = "value", id, inputId, writeToSwap } + { expression = "value", id, inputId, writeToSwap }, ) { if (!inputId) { throw new Error("Input ID required"); @@ -60,7 +67,8 @@ const actions = { // This would be something to fix in the future, maybe use an entire store // for swap, or write a more specific mechanism to look up values in swap // state. - inputValue: writeToSwap ? 0 : get(rootState, input.getLocation) + inputValue: writeToSwap ? 0 : get(rootState, input.getLocation), + osc: rootState.osc.data, }); if (!func) { @@ -71,7 +79,8 @@ const actions = { id: expressionId, inputId, func, - expression + expression, + evaluateEveryFrame: false, }; commit("ADD_EXPRESSION", { assignment, writeToSwap }); @@ -98,7 +107,8 @@ const actions = { const input = rootState.inputs.inputs[existingExpression.inputId]; const func = compileExpression(expression, { - inputValue: get(rootState, input.getLocation) + inputValue: get(rootState, input.getLocation), + osc: rootState.osc.data, }); if (!func) { @@ -112,6 +122,19 @@ const actions = { return existingExpression.id; }, + updateEvaluation({ commit }, { id, evaluateEveryFrame, writeToSwap }) { + const existingExpression = state.assignments[id]; + + if (!existingExpression) { + throw new Error(`Existing expression with ID ${id} not found`); + } + + existingExpression.evaluateEveryFrame = evaluateEveryFrame; + + commit("ADD_EXPRESSION", { assignment: existingExpression, writeToSwap }); + return existingExpression.id; + }, + remove({ commit }, args) { commit("REMOVE_EXPRESSION", args); }, @@ -127,7 +150,7 @@ const actions = { await dispatch("create", { ...assignment, writeToSwap: true }); } - } + }, }; // mutations @@ -141,7 +164,7 @@ const mutations = { delete state.assignments[id]; }, - SWAP: SWAP(swap, getDefaultState) + SWAP: SWAP(swap, getDefaultState), }; export default { @@ -149,5 +172,5 @@ export default { state, getters, actions, - mutations + mutations, }; diff --git a/src/application/worker/store/modules/fonts.js b/src/renderer/src/application/worker/store/modules/fonts.js similarity index 63% rename from src/application/worker/store/modules/fonts.js rename to src/renderer/src/application/worker/store/modules/fonts.js index 0b2079d14..4a435a8f7 100644 --- a/src/application/worker/store/modules/fonts.js +++ b/src/renderer/src/application/worker/store/modules/fonts.js @@ -1,30 +1,30 @@ const state = { defaultFonts: ["serif", "sans-serif", "cursive", "monospace"], - localFonts: [] + localFonts: [], }; const getters = { - fonts: state => [ + fonts: (state) => [ ...state.defaultFonts, ...state.localFonts .filter( (value, index, self) => - index === self.findIndex(t => t.family === value.family) + index === self.findIndex((t) => t.family === value.family), ) - .map(font => font.family) - .sort((a, b) => a.localeCompare(b)) - ] + .map((font) => font.family) + .sort((a, b) => a.localeCompare(b)), + ], }; const mutations = { SET_LOCAL_FONTS(state, fonts = []) { state.localFonts = fonts; - } + }, }; export default { namespaced: true, state, getters, - mutations + mutations, }; diff --git a/src/application/worker/store/modules/fps.js b/src/renderer/src/application/worker/store/modules/fps.js similarity index 82% rename from src/application/worker/store/modules/fps.js rename to src/renderer/src/application/worker/store/modules/fps.js index 8ec68b852..167cb9658 100644 --- a/src/application/worker/store/modules/fps.js +++ b/src/renderer/src/application/worker/store/modules/fps.js @@ -1,9 +1,9 @@ const state = { - fps: 60 + fps: 60, }; const getters = { - interval: state => 1000 / state.fps + interval: (state) => 1000 / state.fps, }; const actions = { @@ -13,13 +13,13 @@ const actions = { } commit("SET_FPS", { fps }); - } + }, }; const mutations = { SET_FPS(state, { fps }) { state.fps = fps; - } + }, }; export default { @@ -27,5 +27,5 @@ export default { state, getters, mutations, - actions + actions, }; diff --git a/src/application/worker/store/modules/groups.js b/src/renderer/src/application/worker/store/modules/groups.js similarity index 74% rename from src/application/worker/store/modules/groups.js rename to src/renderer/src/application/worker/store/modules/groups.js index 47851f1c8..ba0abbc51 100644 --- a/src/application/worker/store/modules/groups.js +++ b/src/renderer/src/application/worker/store/modules/groups.js @@ -79,12 +79,20 @@ import { applyExpression } from "../../../utils/apply-expression"; * }; */ +/** + * @typedef GroupsState + * @prop {Group[]} groups + */ + +/** + * @returns {GroupsState} + */ function getDefaultState() { return { groups: [] }; } const state = getDefaultState(); -const swap = getDefaultState(); +let swap = getDefaultState(); // Any keys marked false or arrays with keys given // will not be moved from the base state when swapped @@ -94,14 +102,14 @@ const sharedPropertyRestrictions = { // returns a boolean. True to remove, false to keep. // Objects return an Array of keys to remove. // This keeps gallery group in place - group - ) => group.name === constants.GALLERY_GROUP_NAME + group, + ) => group.name === constants.GALLERY_GROUP_NAME, }; const getters = { - groupIndexRenderOrder: state => { + groupIndexRenderOrder: (state) => { const galleryGroupIndex = state.groups.findIndex( - group => group.name === constants.GALLERY_GROUP_NAME + (group) => group.name === constants.GALLERY_GROUP_NAME, ); const indexes = [...state.groups.keys()]; @@ -111,7 +119,11 @@ const getters = { } return indexes; - } + }, + + getById: (state) => (id) => { + return state.groups.find((group) => group.id === id); + }, }; const actions = { @@ -121,7 +133,7 @@ const actions = { const inherit = args.inherit === undefined ? true : args.inherit; const existingGroupIndex = writeTo.groups.findIndex( - group => group.id === args.id + (group) => group.id === args.id, ); if (existingGroupIndex > -1) { @@ -146,8 +158,9 @@ const actions = { context: await store.dispatch("outputs/getAuxillaryOutput", { name, group: "group", - id - }) + id, + reactToResize: args.reactToResize ?? true, + }), }; const inputs = [ @@ -156,7 +169,7 @@ const actions = { "clearing", "inherit", "compositeOperation", - "pipeline" + "pipeline", ]; for (let i = 0; i < inputs.length; i += 1) { const inputName = inputs[i]; @@ -169,7 +182,7 @@ const actions = { await store.dispatch("inputs/addInput", { type: "commit", location: "groups/UPDATE_GROUP_BY_KEY", - data: { groupId: group.id, key: inputName } + data: { groupId: group.id, key: inputName }, }) ).id; } @@ -180,8 +193,15 @@ const actions = { return group; }, - async removeGroup({ commit }, { groupId, writeToSwap }) { - const group = state.groups.find(group => group.id === groupId); + async removeGroup({ commit, dispatch }, { groupId }) { + await dispatch("cleanUpGroupResources", { groupId }); + + commit("REMOVE_GROUP", { id: groupId }); + }, + + async cleanUpGroupResources(state, { groupId, readFromSwap }) { + const readFrom = readFromSwap ? swap : state; + const group = readFrom.groups.find((group) => group.id === groupId); const inputIds = [ group.alphaInputId, @@ -189,14 +209,14 @@ const actions = { group.clearingInputId, group.inheritInputId, group.compositeOperationInputId, - group.pipelineInputId + group.pipelineInputId, ]; for (let i = 0; i < inputIds.length; i += 1) { const inputId = inputIds[i]; await store.dispatch("inputs/removeInput", { - inputId + inputId, }); } @@ -206,12 +226,12 @@ const actions = { await store.dispatch("modules/removeActiveModule", { moduleId }); } - commit("REMOVE_GROUP", { id: groupId, writeToSwap }); + await store.dispatch("outputs/removeAuxillaryOutput", group.id); }, orderByIds({ commit }, { ids }) { - const newGroups = ids.map(id => { - return state.groups.find(group => group.id === id); + const newGroups = ids.map((id) => { + return state.groups.find((group) => group.id === id); }); commit("REPLACE_GROUPS", { groups: newGroups }); @@ -219,8 +239,8 @@ const actions = { createPresetData() { return state.groups - .filter(group => group.name !== constants.GALLERY_GROUP_NAME) - .map(group => { + .filter((group) => group.name !== constants.GALLERY_GROUP_NAME) + .map((group) => { const clonedGroup = { ...group }; delete clonedGroup.context; return clonedGroup; @@ -228,36 +248,58 @@ const actions = { }, updateGroupName({ commit }, { groupId, name }) { - const group = state.groups.find(group => group.id === groupId); + const group = state.groups.find((group) => group.id === groupId); store.commit("outputs/UPDATE_AUXILLARY", { auxillaryId: group.context.id, data: { - name - } + name, + }, }); commit("UPDATE_GROUP", { groupId, data: { - name - } + name, + }, }); }, - async loadPresetData({ dispatch }, groups) { + async loadPresetData({ dispatch, commit }, groups) { + const oldGroupIds = Object.values(state.groups) + .filter((group) => group.name !== constants.GALLERY_GROUP_NAME) + .map((group) => group.id); + for (let i = 0, len = groups.length; i < len; i++) { const group = groups[i]; - await dispatch("createGroup", { ...group, writeToSwap: true }); + await dispatch("createGroup", { + ...group, + writeToSwap: true, + }); } - return; + return async function modulesCleanupAfterSwap() { + const groupIds = oldGroupIds.filter( + (id) => state.groups.findIndex((group) => group.id === id) < 0, + ); + + for (let i = 0, len = groupIds.length; i < len; i++) { + const id = groupIds[i]; + + await dispatch("cleanUpGroupResources", { + groupId: id, + readFromSwap: true, + }); + } + + commit("CLEAR_SWAP"); + }; }, updateGroupInput({ commit }, { groupId, key, data, writeToSwap }) { let dataOut = data; - const group = state.groups.find(group => group.id === groupId); + const group = state.groups.find((group) => group.id === groupId); const inputId = group[`${key}InputId`]; dataOut = applyExpression({ inputId, value: dataOut }); @@ -265,13 +307,13 @@ const actions = { }, async duplicateModule({ commit }, { groupId, moduleId }) { - const group = state.groups.find(group => group.id === groupId); + const group = state.groups.find((group) => group.id === groupId); const position = - group.modules.findIndex(moduleListId => moduleListId === moduleId) + 1; + group.modules.findIndex((moduleListId) => moduleListId === moduleId) + 1; const existingModule = store.state.modules.active[moduleId]; const existingInputIds = store.getters["modules/activeModuleInputIds"]( - existingModule.$id + existingModule.$id, ); const existingInputLinks = existingInputIds.reduce((obj, id) => { @@ -282,11 +324,11 @@ const actions = { const duplicateModule = await store.dispatch("modules/makeActiveModule", { moduleName: existingModule.meta.name, existingModule, - generateNewIds: true + generateNewIds: true, }); const newInputIds = store.getters["modules/activeModuleInputIds"]( - duplicateModule.$id + duplicateModule.$id, ); for (let i = 0; i < newInputIds.length; i += 1) { @@ -296,18 +338,17 @@ const actions = { if (existingInputLinks[existingInputId]) { await store.dispatch("inputs/createInputLink", { ...existingInputLinks[existingInputId], - inputId: newInputId + inputId: newInputId, }); } - const existingExpression = store.getters["expressions/getByInputId"]( - existingInputId - ); + const existingExpression = + store.getters["expressions/getByInputId"](existingInputId); if (existingExpression) { await store.dispatch("expressions/create", { expression: existingExpression.expression, - inputId: newInputId + inputId: newInputId, }); } } @@ -315,20 +356,21 @@ const actions = { commit("ADD_MODULE_TO_GROUP", { moduleId: duplicateModule.$id, groupId, - position + position, }); - } + }, }; const mutations = { ADD_GROUP(state, { group, writeToSwap }) { const writeTo = writeToSwap ? swap : state; writeTo.groups.push(group); + if (writeToSwap) console.log("written group to swap"); }, REMOVE_GROUP(state, { id, writeToSwap }) { const writeTo = writeToSwap ? swap : state; - const index = writeTo.groups.findIndex(group => group.id === id); + const index = writeTo.groups.findIndex((group) => group.id === id); if (index > -1) { writeTo.groups.splice(index, 1); @@ -351,14 +393,14 @@ const mutations = { if (!hasWrittenGalleryId) { writeTo.groups.push( - oldGroups.find(group => group.name === constants.GALLERY_GROUP_NAME) + oldGroups.find((group) => group.name === constants.GALLERY_GROUP_NAME), ); } }, REPLACE_GROUP_MODULES(state, { groupId, modules, writeToSwap }) { const writeTo = writeToSwap ? swap : state; - const index = writeTo.groups.findIndex(group => group.id === groupId); + const index = writeTo.groups.findIndex((group) => group.id === groupId); if (index > -1) { writeTo.groups[index].modules = modules; @@ -367,7 +409,9 @@ const mutations = { ADD_MODULE_TO_GROUP(state, { moduleId, groupId, position, writeToSwap }) { const writeTo = writeToSwap ? swap : state; - const groupIndex = writeTo.groups.findIndex(group => group.id === groupId); + const groupIndex = writeTo.groups.findIndex( + (group) => group.id === groupId, + ); if (groupIndex < 0) { return false; @@ -382,9 +426,11 @@ const mutations = { REMOVE_MODULE_FROM_GROUP(state, { moduleId, groupId, writeToSwap }) { const writeTo = writeToSwap ? swap : state; - const groupIndex = writeTo.groups.findIndex(group => group.id === groupId); + const groupIndex = writeTo.groups.findIndex( + (group) => group.id === groupId, + ); const moduleIndex = writeTo.groups[groupIndex].modules.findIndex( - module => module === moduleId + (module) => module === moduleId, ); if (groupIndex < 0 || moduleIndex < 0) { @@ -396,7 +442,7 @@ const mutations = { UPDATE_GROUP(state, { groupId, data, writeToSwap }) { const writeTo = writeToSwap ? swap : state; - const index = writeTo.groups.findIndex(group => group.id === groupId); + const index = writeTo.groups.findIndex((group) => group.id === groupId); if (index > -1) { const dataKeys = Object.keys(data); @@ -411,14 +457,21 @@ const mutations = { UPDATE_GROUP_BY_KEY(state, { groupId, key, data, writeToSwap }) { const writeTo = writeToSwap ? swap : state; - const index = writeTo.groups.findIndex(group => group.id === groupId); + const index = writeTo.groups.findIndex((group) => group.id === groupId); if (index > -1) { writeTo.groups[index][key] = data; } }, - SWAP: SWAP(swap, getDefaultState, sharedPropertyRestrictions) + SWAP: (state) => { + console.log("swapping groups"); + SWAP(swap, getDefaultState, sharedPropertyRestrictions, false)(state); + }, + + CLEAR_SWAP: () => { + swap = getDefaultState(); + }, }; export default { @@ -426,5 +479,5 @@ export default { state, getters, actions, - mutations + mutations, }; diff --git a/src/application/worker/store/modules/images.js b/src/renderer/src/application/worker/store/modules/images.js similarity index 73% rename from src/application/worker/store/modules/images.js rename to src/renderer/src/application/worker/store/modules/images.js index b3ca197e9..5c0ff2489 100644 --- a/src/application/worker/store/modules/images.js +++ b/src/renderer/src/application/worker/store/modules/images.js @@ -1,17 +1,15 @@ import streamToBlob from "stream-to-blob"; -import fs from "fs"; -import path from "path"; - -import Vue from "vue"; import { v4 as uuidv4 } from "uuid"; - import store from "../"; import { conformFilePath } from "../../../utils/conform-file-path"; +const fs = require("fs"); +const path = require("path"); + const state = {}; const getters = { - image: state => id => state[id] + image: (state) => (id) => state[id], }; const actions = { @@ -22,17 +20,13 @@ const actions = { try { joinedFilePath = path.join( store.state.media.path, - conformFilePath(filePath) + conformFilePath(filePath), ); } catch (e) { console.log(e); } - try { - stream = fs.createReadStream(joinedFilePath); - } catch (error) { - throw error; - } + stream = fs.createReadStream(joinedFilePath); if (!stream) { return {}; @@ -44,13 +38,13 @@ const actions = { const id = uuidv4(); commit("SAVE_IMAGE", { id, imageBitmap }); return { id }; - } + }, }; const mutations = { SAVE_IMAGE(state, { id, imageBitmap }) { - Vue.set(state, id, imageBitmap); - } + state[id] = imageBitmap; + }, }; export default { @@ -58,5 +52,5 @@ export default { state, getters, actions, - mutations + mutations, }; diff --git a/src/application/worker/store/modules/inputs.js b/src/renderer/src/application/worker/store/modules/inputs.js similarity index 90% rename from src/application/worker/store/modules/inputs.js rename to src/renderer/src/application/worker/store/modules/inputs.js index bcd13786d..3fe9e142b 100644 --- a/src/application/worker/store/modules/inputs.js +++ b/src/renderer/src/application/worker/store/modules/inputs.js @@ -1,4 +1,3 @@ -import Vue from "vue"; import { v4 as uuidv4 } from "uuid"; import { SWAP } from "./common/swap"; @@ -10,7 +9,7 @@ import { SWAP } from "./common/swap"; const InputLinkType = { getter: "getter", mutation: "mutation", - state: "state" + state: "state", }; /** @@ -81,7 +80,7 @@ function getDefaultState() { return { focusedInput: { id: null, title: null }, inputs: {}, - inputLinks: {} + inputLinks: {}, }; } @@ -89,10 +88,10 @@ const state = getDefaultState(); const swap = getDefaultState(); const getters = { - inputsByActiveModuleId: state => moduleId => + inputsByActiveModuleId: (state) => (moduleId) => Object.values(state.inputs).filter( - input => input.data.moduleId === moduleId - ) + (input) => input.data.moduleId === moduleId, + ), }; const actions = { @@ -106,21 +105,23 @@ const actions = { addInput( { commit }, - { type, getLocation, location, data, id = uuidv4(), writeToSwap } + { type, getLocation, location, data, id = uuidv4(), writeToSwap }, ) { const input = { type, getLocation, location, data, id }; commit("ADD_INPUT", { input, writeToSwap }); return input; }, - removeInput({ commit }, { inputId, writeToSwap }) { + removeInput({ commit }, { inputId, silent = false, writeToSwap }) { const writeTo = writeToSwap ? swap : state; if (!writeTo.inputs[inputId]) { - console.warn( - "Did not remove input. Could not find input with id", - inputId - ); + if (!silent) { + console.warn( + "Did not remove input. Could not find input with id", + inputId, + ); + } return false; } @@ -140,8 +141,8 @@ const actions = { max = 1, source, match, - writeToSwap - } + writeToSwap, + }, ) { const writeTo = writeToSwap ? swap : state; @@ -159,12 +160,12 @@ const actions = { min, max, source, - match + match, }; if (!writeTo.inputs[inputId]) { console.warn( "Did not create inputLink. Could not find input with id", - inputId + inputId, ); return false; @@ -211,10 +212,10 @@ const actions = { await dispatch("createInputLink", { inputId: link.id, ...link, - writeToSwap: true + writeToSwap: true, }); } - } + }, }; const mutations = { @@ -232,13 +233,13 @@ const mutations = { REMOVE_INPUT(state, { inputId, writeToSwap }) { const writeTo = writeToSwap ? swap : state; - Vue.delete(writeTo.inputs, inputId); + delete writeTo.inputs[inputId]; }, ADD_INPUT_LINK(state, { inputLink, writeToSwap }) { const writeTo = writeToSwap ? swap : state; - Vue.set(writeTo.inputLinks, inputLink.id, inputLink); + writeTo.inputLinks[inputLink.id] = inputLink; }, UPDATE_INPUT_LINK(state, { inputId, key, value, writeToSwap }) { @@ -248,16 +249,16 @@ const mutations = { return; } - Vue.set(writeTo.inputLinks[inputId], key, value); + writeTo.inputLinks[inputId][key] = value; }, REMOVE_INPUT_LINK(state, { inputId, writeToSwap }) { const writeTo = writeToSwap ? swap : state; - Vue.delete(writeTo.inputLinks, inputId); + delete writeTo.inputLinks[inputId]; }, - SWAP: SWAP(swap, getDefaultState) + SWAP: SWAP(swap, getDefaultState), }; export default { @@ -265,5 +266,5 @@ export default { state, getters, actions, - mutations + mutations, }; diff --git a/src/application/worker/store/modules/media.js b/src/renderer/src/application/worker/store/modules/media.js similarity index 84% rename from src/application/worker/store/modules/media.js rename to src/renderer/src/application/worker/store/modules/media.js index b4de11bc4..fa58c9f71 100644 --- a/src/application/worker/store/modules/media.js +++ b/src/renderer/src/application/worker/store/modules/media.js @@ -1,8 +1,9 @@ import store from "../"; import streamToBlob from "stream-to-blob"; -import fs from "fs"; -import path from "path"; -import media from "../../../../media-manager/store/modules/media"; +import media from "../../../../../../main/media-manager/store/modules/media.js"; + +const fs = require("fs"); +const path = require("path"); /** * Holds processed media @@ -19,7 +20,7 @@ const actions = { async addMedia({ commit }, { project, folder, item }) { if (folder === "module" || folder === "isf") { const stream = fs.createReadStream( - path.join(store.state.media.path, item.path) + path.join(store.state.media.path, item.path), ); const blob = await streamToBlob(stream); @@ -39,6 +40,7 @@ const actions = { } catch (e) { console.error(`Could not load module`, item.name); console.error(e); + return; } try { @@ -51,7 +53,7 @@ const actions = { } commit("ADD", { project, folder, item }); - } + }, }; const mutations = media.mutations; @@ -61,5 +63,5 @@ export default { state, getters, actions, - mutations + mutations, }; diff --git a/src/application/worker/store/modules/mediaStream.js b/src/renderer/src/application/worker/store/modules/mediaStream.js similarity index 92% rename from src/application/worker/store/modules/mediaStream.js rename to src/renderer/src/application/worker/store/modules/mediaStream.js index 043c6850a..56220281f 100644 --- a/src/application/worker/store/modules/mediaStream.js +++ b/src/renderer/src/application/worker/store/modules/mediaStream.js @@ -3,7 +3,7 @@ const state = { video: [], currentAudioSource: null, - currentVideoSource: null + currentVideoSource: null, }; const mutations = { @@ -29,11 +29,11 @@ const mutations = { SET_CURRENT_VIDEO_SOURCE(state, { videoId }) { state.currentVideoSource = videoId; - } + }, }; export default { namespaced: true, state, - mutations + mutations, }; diff --git a/src/application/worker/store/modules/metrics.js b/src/renderer/src/application/worker/store/modules/metrics.js similarity index 83% rename from src/application/worker/store/modules/metrics.js rename to src/renderer/src/application/worker/store/modules/metrics.js index 40866e99b..5dc2057d9 100644 --- a/src/application/worker/store/modules/metrics.js +++ b/src/renderer/src/application/worker/store/modules/metrics.js @@ -1,15 +1,15 @@ const state = { - fps: 0 + fps: 0, }; const mutations = { SET_FPS_MEASURE(state, fps) { state.fps = fps; - } + }, }; export default { namespaced: true, state, - mutations + mutations, }; diff --git a/src/application/worker/store/modules/meyda.js b/src/renderer/src/application/worker/store/modules/meyda.js similarity index 94% rename from src/application/worker/store/modules/meyda.js rename to src/renderer/src/application/worker/store/modules/meyda.js index de06b704e..39ecd1226 100644 --- a/src/application/worker/store/modules/meyda.js +++ b/src/renderer/src/application/worker/store/modules/meyda.js @@ -4,7 +4,7 @@ import { removeSmoothingId, getSmoothedFeature, MAX_SMOOTHING, - SMOOTHING_STEP + SMOOTHING_STEP, } from "../../audio-features"; import { v4 as uuidv4 } from "uuid"; @@ -23,11 +23,11 @@ const state = { "spectralSkewness", "spectralKurtosis", "perceptualSpread", - "perceptualSharpness" + "perceptualSharpness", ], smoothingIds: [], MAX_SMOOTHING, - SMOOTHING_STEP + SMOOTHING_STEP, }; const getters = { @@ -37,7 +37,7 @@ const getters = { } return getFeature(feature); - } + }, }; const actions = { @@ -54,7 +54,7 @@ const actions = { // eslint-disable-next-line no-empty-pattern removeSmoothingId({}, id) { removeSmoothingId(id); - } + }, }; const mutations = { @@ -84,7 +84,7 @@ const mutations = { if (index > -1) { state.smoothingIds.splice(index, 1); } - } + }, }; export default { @@ -92,5 +92,5 @@ export default { state, getters, actions, - mutations + mutations, }; diff --git a/src/application/worker/store/modules/midi.js b/src/renderer/src/application/worker/store/modules/midi.js similarity index 71% rename from src/application/worker/store/modules/midi.js rename to src/renderer/src/application/worker/store/modules/midi.js index 46c30aa85..44d439f2b 100644 --- a/src/application/worker/store/modules/midi.js +++ b/src/renderer/src/application/worker/store/modules/midi.js @@ -1,15 +1,13 @@ -import Vue from "vue"; - const state = { devices: {}, - learning: false + learning: false, }; const actions = { learn({ commit }) { let resolve; - const promise = new Promise(r => { - resolve = message => { + const promise = new Promise((r) => { + resolve = (message) => { commit("SET_LEARNING", false); r(message); }; @@ -26,12 +24,12 @@ const actions = { async loadPresetData({ commit }, newState) { commit("SET_STATE", newState); return; - } + }, }; const mutations = { ADD_DEVICE(state, { id, name, manufacturer }) { - Vue.set(state.devices, `${id}-${name}-${manufacturer}`, { + state.devices[`${id}-${name}-${manufacturer}`] = { id, name, manufacturer, @@ -39,24 +37,24 @@ const mutations = { listenForInput: true, listenForClock: false, ccLatch: false, - noteOnLatch: false - }); + noteOnLatch: false, + }; }, UPDATE_DEVICE(state, { id, key, value }) { - Vue.set(state.devices[id], key, value); + state.devices[id][key] = value; }, WRITE_DATA(state, { id, channel, type, data }) { if (!state.devices[id].channelData[channel]) { - Vue.set(state.devices[id].channelData, channel, {}); + state.devices[id].channelData[channel] = {}; } - Vue.set(state.devices[id].channelData[channel], type, data); + state.devices[id].channelData[channel][type] = data; }, SET_LEARNING(state, value) { - Vue.set(state, "learning", value); + state.learning = value; }, SET_STATE(state, newState) { @@ -67,12 +65,12 @@ const mutations = { state[key] = newState[key]; } - } + }, }; export default { namespaced: true, state, mutations, - actions + actions, }; diff --git a/src/application/worker/store/modules/modules.js b/src/renderer/src/application/worker/store/modules/modules.js similarity index 83% rename from src/application/worker/store/modules/modules.js rename to src/renderer/src/application/worker/store/modules/modules.js index 77a333bca..0dc35b943 100644 --- a/src/application/worker/store/modules/modules.js +++ b/src/renderer/src/application/worker/store/modules/modules.js @@ -1,4 +1,3 @@ -import Vue from "vue"; import { SWAP } from "./common/swap"; import getNextName from "../../../utils/get-next-name"; import getPropDefault from "../../../utils/get-prop-default"; @@ -15,13 +14,13 @@ const sharedPropertyRestrictions = { registered: false, // will not move active: ( // keeps gallery item modules in place - value + value, ) => Object.values(value) - .filter(module => module.meta.isGallery) - .map(module => module.$id), + .filter((module) => module.meta.isGallery) + .map((module) => module.$id), propQueue: true, // will move - metaQueue: true // will move + metaQueue: true, // will move }; function getDefaultState() { @@ -29,7 +28,7 @@ function getDefaultState() { registered: {}, active: {}, propQueue: {}, - metaQueue: {} + metaQueue: {}, }; } @@ -45,7 +44,7 @@ async function initialiseModuleProperties( useExistingData = false, existingData = {}, writeToSwap = false, - generateNewIds = false + generateNewIds = false, ) { const propKeys = Object.keys(props); const propsWithoutId = []; @@ -72,7 +71,7 @@ async function initialiseModuleProperties( module, propKey, prop, - useExistingData + useExistingData, ); if ( @@ -85,7 +84,7 @@ async function initialiseModuleProperties( getLocation: `modules.active["${module.$id}"].props["${propKey}"]`, location: "modules/updateProp", data: { moduleId: module.$id, prop: propKey }, - writeToSwap + writeToSwap, }); if ( @@ -104,10 +103,10 @@ async function initialiseModuleProperties( data: { moduleId: module.$id, prop: propKey, - path: `[${key}]` + path: `[${key}]`, }, id: `${inputBind.id}-${key}`, - writeToSwap + writeToSwap, }); } } @@ -120,23 +119,23 @@ async function initialiseModuleProperties( } const getters = { - activeModuleInputIds: state => activeModuleId => { + activeModuleInputIds: (state) => (activeModuleId) => { const activeModule = state.active[activeModuleId]; return [ activeModule.meta.alphaInputId, activeModule.meta.enabledInputId, activeModule.meta.compositeOperationInputId, ...store.getters["inputs/inputsByActiveModuleId"](activeModule.$id).map( - input => input.id - ) + (input) => input.id, + ), ]; - } + }, }; const actions = { async registerModule( { commit, rootState }, - { module: moduleDefinition, hot = false } + { module: moduleDefinition, hot = false }, ) { const { renderers } = rootState; @@ -153,8 +152,8 @@ const actions = { const { name, type } = moduleDefinition.meta; const existingModuleWithDuplicateName = Object.values( - state.registered - ).findIndex(registeredModule => registeredModule.meta.name === name); + state.registered, + ).findIndex((registeredModule) => registeredModule.meta.name === name); if (!hot && existingModuleWithDuplicateName > -1) { console.error(`Module registered with name "${name}" already exists.`); @@ -166,7 +165,7 @@ const actions = { moduleDefinition = await renderers[type].setupModule(moduleDefinition); } catch (e) { console.error( - `Error in ${type} renderer setup whilst registering "${name}". This module was ommited from registration. \n\n${e}` + `Error in ${type} renderer setup whilst registering "${name}". This module was ommited from registration. \n\n${e}`, ); return false; @@ -177,7 +176,7 @@ const actions = { if (hot) { const activeModuleValues = Object.values(state.active).filter( - activeModule => activeModule.meta.name === name + (activeModule) => activeModule.meta.name === name, ); for (let i = 0, len = activeModuleValues.length; i < len; i += 1) { @@ -185,7 +184,7 @@ const actions = { const activeModule = { ...existingActiveModule }; const { canvas } = rootState.outputs.main || { - canvas: { width: 0, height: 0 } + canvas: { width: 0, height: 0 }, }; const { props } = moduleDefinition; @@ -197,7 +196,7 @@ const actions = { { ...activeModule }, false, true, - existingActiveModule + existingActiveModule, ); commit("ADD_ACTIVE_MODULE", { module: initialisedModule }); @@ -207,7 +206,7 @@ const actions = { const returnedData = moduleDefinition.init({ canvas, data: { ...data }, - props: activeModule.props + props: activeModule.props, }); if (returnedData) { @@ -215,7 +214,7 @@ const actions = { id: activeModule.$id, key: "data", value: returnedData, - writeToSwap: false + writeToSwap: false, }); } } @@ -230,8 +229,8 @@ const actions = { moduleMeta = {}, existingModule, generateNewIds = false, - writeToSwap - } + writeToSwap, + }, ) { const writeTo = writeToSwap ? swap : state; const expectedModuleName = existingModule @@ -247,36 +246,36 @@ const actions = { module = { meta: { ...moduleDefinition.meta, ...moduleMeta }, ...(existingModule && JSON.parse(JSON.stringify(existingModule))), - $status: [] + $status: [], }; } else { module = { meta: { ...moduleMeta }, ...existingModule, - $status: [] + $status: [], }; console.error( - `Could not find registered module with name ${expectedModuleName}.` + `Could not find registered module with name ${expectedModuleName}.`, ); module.$status.push({ type: "error", - message: `Module "${expectedModuleName}" is not registered. modV will skip this while rendering` + message: `Module "${expectedModuleName}" is not registered. modV will skip this while rendering`, }); } if (moduleMeta.isGallery) { const existingModuleWithDuplicateNameInGallery = Object.values( - writeTo.active + writeTo.active, ).find( - activeModule => - activeModule.meta.isGallery && activeModule.meta.name === moduleName + (activeModule) => + activeModule.meta.isGallery && activeModule.meta.name === moduleName, ); if (existingModuleWithDuplicateNameInGallery) { console.warn( - `Module active in gallery with name "${moduleName}" already exists.` + `Module active in gallery with name "${moduleName}" already exists.`, ); return existingModuleWithDuplicateNameInGallery; } @@ -292,7 +291,7 @@ const actions = { type: "action", getLocation: `modules.active["${module.$id}"].meta.alpha`, location: "modules/updateMeta", - data: { id: module.$id, metaKey: "alpha" } + data: { id: module.$id, metaKey: "alpha" }, }); module.meta.alphaInputId = alphaInputBind.id; @@ -301,7 +300,7 @@ const actions = { type: "action", getLocation: `modules.active["${module.$id}"].meta.enabled`, location: "modules/updateMeta", - data: { id: module.$id, metaKey: "enabled" } + data: { id: module.$id, metaKey: "enabled" }, }); module.meta.enabledInputId = enabledInputBind.id; @@ -310,13 +309,16 @@ const actions = { type: "action", getLocation: `modules.active["${module.$id}"].meta.compositeOperation`, location: "modules/updateMeta", - data: { moduleId: module.$id, metaKey: "compositeOperation" } + data: { moduleId: module.$id, metaKey: "compositeOperation" }, }); module.meta.compositeOperationInputId = coInputBind.id; } } + const { renderers } = rootState; + const { type } = module.meta; + if (!existingModule) { module.$moduleName = moduleName; module.props = {}; @@ -335,7 +337,7 @@ const actions = { module.meta.name = await getNextName( `${moduleName}`, - Object.keys(state.active) + Object.keys(state.active), ); module.meta.alpha = 1; module.meta.enabled = false; @@ -366,16 +368,13 @@ const actions = { } } } else { - const { renderers } = rootState; - const { type } = module.meta; - if (renderers[type].setupModule) { try { const newDef = await renderers[type].setupModule(moduleDefinition); module.data = newDef.data; } catch (e) { console.error( - `Error in ${type} renderer setup whilst registering "${name}". This module was ommited from registration. \n\n${e}` + `Error in ${type} renderer setup whilst registering "${name}". This module was ommited from registration. \n\n${e}`, ); return false; @@ -389,10 +388,20 @@ const actions = { true, existingModule, writeToSwap, - generateNewIds + generateNewIds, ); } + if (renderers[type].addActiveModule) { + try { + await renderers[type].addActiveModule(module, moduleDefinition); + } catch (e) { + console.error( + `Error in ${type} renderer addActiveModule whilst registering "${module.meta.name}".\n\n${e}`, + ); + } + } + // We're done setting up the module, we can commit now commit("ADD_ACTIVE_MODULE", { module, writeToSwap }); @@ -407,7 +416,7 @@ const actions = { } const { canvas } = rootState.outputs.main || { - canvas: { width: 0, height: 0 } + canvas: { width: 0, height: 0 }, }; if (moduleDefinition && "init" in moduleDefinition) { @@ -415,7 +424,7 @@ const actions = { const returnedData = moduleDefinition.init({ canvas, data: { ...data }, - props: module.props + props: module.props, }); if (returnedData) { @@ -423,7 +432,7 @@ const actions = { id: module.$id, key: "data", value: returnedData, - writeToSwap + writeToSwap, }); } } @@ -439,11 +448,11 @@ const actions = { moduleDefinition, canvas, data: { ...data }, - props + props, }); } catch (error) { console.error( - `module#resize() in ${module.meta.name} threw an error: ${error}` + `module#resize() in ${module.meta.name} threw an error: ${error}`, ); } @@ -452,7 +461,7 @@ const actions = { id: module.$id, key: "data", value: returnedData, - writeToSwap + writeToSwap, }); } } @@ -463,7 +472,7 @@ const actions = { async updateProp( { state, commit, rootState }, - { moduleId, prop, data, path = "", writeToSwap } + { moduleId, prop, data, path = "", writeToSwap }, ) { if (!state.active[moduleId]) { console.error(`The module with the moduleId ${moduleId} doesn't exist.`); @@ -476,7 +485,7 @@ const actions = { const currentValue = get( state.active[moduleId][prop], path, - state.active[moduleId][prop] + state.active[moduleId][prop], ); const { type } = propData; @@ -514,10 +523,10 @@ const actions = { data: { value: dataOut, type: propData.type, - path + path, }, - writeToSwap + writeToSwap, }); const registeredModule = state.registered[moduleName]; @@ -525,21 +534,20 @@ const actions = { if ("set" in registeredModule.props[prop]) { const { renderers } = rootState; - const { getModuleData = () => ({}) } = renderers[ - registeredModule.meta.type - ]; + const { getModuleData = () => ({}) } = + renderers[registeredModule.meta.type]; const newData = registeredModule.props[prop].set.bind(registeredModule)({ ...getModuleData(registeredModule.meta.name), data: { ...state.active[moduleId].data }, - props: state.active[moduleId].props + props: state.active[moduleId].props, }); if (newData) { commit("UPDATE_ACTIVE_MODULE", { id: moduleId, key: "data", - value: newData + value: newData, }); } } @@ -566,7 +574,7 @@ const actions = { id: moduleId, metaKey, data: dataOut, - writeToSwap + writeToSwap, }); }, @@ -588,11 +596,11 @@ const actions = { moduleDefinition, canvas: { width, height }, data: { ...data }, - props + props, }); } catch (error) { console.error( - `module#resize() in ${module.meta.name} threw an error: ${error}` + `module#resize() in ${module.meta.name} threw an error: ${error}`, ); } @@ -600,7 +608,7 @@ const actions = { commit("UPDATE_ACTIVE_MODULE", { id: moduleId, key: "data", - value: returnedData + value: returnedData, }); } } @@ -616,14 +624,14 @@ const actions = { const returnedData = moduleDefinition.init({ canvas: { width, height }, data: { ...data }, - props + props, }); if (returnedData) { commit("UPDATE_ACTIVE_MODULE", { id: moduleId, key: "data", - value: returnedData + value: returnedData, }); } } @@ -633,11 +641,11 @@ const actions = { const { renderers } = rootState; return Object.values(state.active) - .filter(module => !module.meta.isGallery) + .filter((module) => !module.meta.isGallery) .reduce((obj, module) => { const { meta: { type }, - data + data, } = module; obj[module.$id] = { ...module }; @@ -646,7 +654,7 @@ const actions = { if (renderers[type].createPresetData) { module.data = { ...data, - ...renderers[type].createPresetData(module) + ...renderers[type].createPresetData(module), }; } @@ -657,32 +665,55 @@ const actions = { async loadPresetData({ dispatch }, modules) { const moduleValues = Object.values(modules); + const oldModuleIds = Object.values(state.active) + .filter( + (module) => + !module.meta.isGallery && + moduleValues.findIndex((newModule) => newModule.$id === module.$id) < + 0, + ) + .map((module) => module.$id); + for (let i = 0, len = moduleValues.length; i < len; i++) { const module = moduleValues[i]; await dispatch("makeActiveModule", { moduleName: module.$moduleName, existingModule: module, - writeToSwap: true + writeToSwap: true, }); } - return; + return async function modulesCleanupAfterSwap() { + const moduleIds = Object.values(oldModuleIds); + + for (let i = 0, len = moduleIds.length; i < len; i++) { + const id = moduleIds[i]; + + await dispatch("removeActiveModule", { + moduleId: id, + writeToSwap: true, + }); + } + + Object.assign(swap, getDefaultState()); + }; }, async removeActiveModule({ commit, rootState }, { moduleId, writeToSwap }) { const writeTo = writeToSwap ? swap : state; const module = writeTo.active[moduleId]; - const { - meta, - meta: { type } - } = module; if (!module) { throw new Error(`No module with id "${moduleId}" found`); } + const { + meta, + meta: { type }, + } = module; + const { renderers } = rootState; if (renderers[type].removeActiveModule) { renderers[type].removeActiveModule(module); @@ -691,16 +722,19 @@ const actions = { const metaInputIds = [ meta.alphaInputId, meta.compositeOperationInputId, - meta.enabledInputId + meta.enabledInputId, ]; const moduleProperties = Object.entries(module.$props).map( ([key, prop]) => ({ key, id: prop.id, - type: prop.type - }) + type: prop.type, + }), ); - const inputIds = [...moduleProperties, ...metaInputIds.map(id => ({ id }))]; + const inputIds = [ + ...moduleProperties, + ...metaInputIds.map((id) => ({ id })), + ]; for (let i = 0, len = moduleProperties.length; i < len; i++) { const { key, type: propType } = moduleProperties[i]; @@ -716,11 +750,13 @@ const actions = { await store.dispatch("inputs/removeInputLink", { inputId, - writeToSwap + writeToSwap, }); await store.dispatch("inputs/removeInput", { - inputId + inputId, + silent: true, + writeToSwap, }); // clear up datatypes with multiple inputs @@ -735,34 +771,36 @@ const actions = { const key = dataTypeInputsKeys[j]; await store.dispatch("inputs/removeInputLink", { inputId: `${inputId}-${key}`, - writeToSwap + writeToSwap, }); await store.dispatch("inputs/removeInput", { - inputId: `${inputId}-${key}` + inputId: `${inputId}-${key}`, + silent: true, + writeToSwap, }); } } } commit("REMOVE_ACTIVE_MODULE", { moduleId, writeToSwap }); - } + }, }; const mutations = { ADD_REGISTERED_MODULE(state, { module, writeToSwap }) { const writeTo = writeToSwap ? swap : state; - Vue.set(writeTo.registered, module.meta.name, module); + writeTo.registered[module.meta.name] = module; }, REMOVE_REGISTERED_MODULE(state, { moduleName, writeToSwap }) { const writeTo = writeToSwap ? swap : state; - Vue.delete(writeTo.registered, moduleName); + delete writeTo.registered[moduleName]; }, ADD_ACTIVE_MODULE(state, { module, writeToSwap }) { const writeTo = writeToSwap ? swap : state; - Vue.set(writeTo.active, module.$id, module); + writeTo.active[module.$id] = module; }, REMOVE_ACTIVE_MODULE(state, { moduleId, writeToSwap }) { @@ -772,12 +810,12 @@ const mutations = { UPDATE_ACTIVE_MODULE(state, { id, key, value, writeToSwap }) { const writeTo = writeToSwap ? swap : state; - Vue.set(writeTo.active[id], key, value); + writeTo.active[id][key] = value; }, async UPDATE_ACTIVE_MODULE_PROP( state, - { moduleId, prop, data, data: { path }, group, groupName, writeToSwap } + { moduleId, prop, data, data: { path }, group, groupName, writeToSwap }, ) { const writeTo = writeToSwap ? swap : state; const value = data.value; @@ -789,17 +827,17 @@ const mutations = { // } if (typeof group === "number") { - Vue.set(writeTo.active[moduleId][groupName].props[prop], group, value); + writeTo.active[moduleId][groupName].props[prop][group] = value; } else if (path) { const tempValue = writeTo.active[moduleId].props[prop]; set(tempValue, path, value); if (Array.isArray(tempValue)) { - Vue.set(writeTo.active[moduleId].props, prop, [...tempValue]); + writeTo.active[moduleId].props[prop] = [...tempValue]; } else { - Vue.set(writeTo.active[moduleId].props, prop, tempValue); + writeTo.active[moduleId].props[prop] = tempValue; } } else { - Vue.set(writeTo.active[moduleId].props, prop, value); + writeTo.active[moduleId].props[prop] = value; } }, @@ -807,11 +845,11 @@ const mutations = { const writeTo = writeToSwap ? swap : state; if (id) { - Vue.set(writeTo.active[id].meta, metaKey, data); + writeTo.active[id].meta[metaKey] = data; } }, - SWAP: SWAP(swap, getDefaultState, sharedPropertyRestrictions) + SWAP: SWAP(swap, getDefaultState, sharedPropertyRestrictions, false), }; export default { @@ -819,5 +857,5 @@ export default { state, getters, actions, - mutations + mutations, }; diff --git a/src/application/worker/store/modules/ndi.js b/src/renderer/src/application/worker/store/modules/ndi.js similarity index 70% rename from src/application/worker/store/modules/ndi.js rename to src/renderer/src/application/worker/store/modules/ndi.js index e4b093317..412525342 100644 --- a/src/application/worker/store/modules/ndi.js +++ b/src/renderer/src/application/worker/store/modules/ndi.js @@ -1,9 +1,16 @@ import { v4 as uuidv4 } from "uuid"; -import Vue from "vue"; import store from "../"; -import grandiose from "../../../setup-grandiose"; +import { setupGrandiose as getGrandiose } from "../../../setup-grandiose"; const state = { + outputEnabled: false, + outputName: "modV", + outputWidth: 1920, + outputHeight: 1080, + followModVOutputSize: true, + followModVFps: true, + outputTargetFps: 60, + discovering: false, timeout: 30 * 1000, @@ -28,12 +35,12 @@ const state = { ], discoveryOptions: { - showLocalSources: true - } + showLocalSources: true, + }, }; -function checkCpu() { - if (!grandiose().isSupportedCPU()) { +async function checkCpu() { + if (!(await (await getGrandiose()).isSupportedCPU())) { throw new Error("Your CPU is not supported for NDI"); } } @@ -42,7 +49,7 @@ async function waitForFrame(receiverContext) { const { receiver, outputId } = receiverContext; const { context, - context: { canvas } + context: { canvas }, } = store.state.outputs.auxillary[outputId]; let dataFrame; @@ -62,7 +69,7 @@ async function waitForFrame(receiverContext) { const ui8c = new Uint8ClampedArray( uint8array.buffer, uint8array.byteOffset, - uint8array.byteLength / Uint8ClampedArray.BYTES_PER_ELEMENT + uint8array.byteLength / Uint8ClampedArray.BYTES_PER_ELEMENT, ); const image = new ImageData(ui8c, dataFrame.xres); @@ -86,10 +93,14 @@ const actions = { commit("SET_DISCOVERING", true); try { - const sources = await grandiose().find( - state.discoveryOptions, - state.timeout - ); + const result = await ( + await getGrandiose() + ).find({ + ...state.discoveryOptions, + }); + + const sources = result.sources(); + commit("SET_SOURCES", sources); } catch (e) { console.log(e); @@ -103,15 +114,18 @@ const actions = { }, async createReceiver({ commit }, receiverOptions) { - receiverOptions.colorFormat = grandiose().COLOR_FORMAT_RGBX_RGBA; - receiverOptions.bandwidth = grandiose().BANDWIDTH_LOWEST; + const grandiose = await getGrandiose(); + + receiverOptions.colorFormat = grandiose.COLOR_FORMAT_RGBX_RGBA; + receiverOptions.bandwidth = grandiose.BANDWIDTH_HIGHEST; + receiverOptions.allowVideoFields = false; - const receiver = await grandiose().receive(receiverOptions); + const receiver = await grandiose.receive(receiverOptions); const outputContext = await store.dispatch("outputs/getAuxillaryOutput", { name: receiverOptions.source.name, group: "NDI", - reactToResize: false + reactToResize: false, }); const receiverId = uuidv4(); @@ -119,7 +133,7 @@ const actions = { id: receiverId, outputId: outputContext.id, receiver, - enabled: false + enabled: false, }; commit("ADD_RECIEVER", receiverContext); @@ -161,16 +175,16 @@ const actions = { } await store.dispatch("ndi/disableReceiver", { - receiverId: receiverContext.id + receiverId: receiverContext.id, }); await store.dispatch( "outputs/removeAuxillaryOutput", - receiverContext.outputId + receiverContext.outputId, ); commit("DELETE_RECIEVER", receiverContext); - } + }, }; const mutations = { @@ -187,21 +201,46 @@ const mutations = { }, ADD_RECIEVER(state, receiverContext) { - Vue.set(state.receivers, receiverContext.id, receiverContext); + state.receivers[receiverContext.id] = receiverContext; }, UPDATE_RECIEVER(state, receiverContext) { - Vue.set(state.receivers, receiverContext.id, receiverContext); + state.receivers[receiverContext.id] = receiverContext; }, DELETE_RECIEVER(state, receiverContext) { - Vue.delete(state.receivers, receiverContext.id); - } + delete state.receivers[receiverContext.id]; + }, + + SET_OUTPUT_ENABLED(state, enabled) { + state.outputEnabled = enabled; + }, + + SET_OUTPUT_NAME(state, name = "modV") { + state.outputName = name; + }, + + SET_OUTPUT_SIZE(state, { width, height }) { + state.outputWidth = width ?? state.outputWidth; + state.outputHeight = height ?? state.outputHeight; + }, + + SET_FOLLOW_MODV_OUTPUT_SIZE(state, follow) { + state.followModVOutputSize = follow; + }, + + SET_FOLLOW_MODV_FPS(state, follow) { + state.followModVFps = follow; + }, + + SET_OUTPUT_TARGET_FPS(state, fps) { + state.outputTargetFps = fps; + }, }; export default { namespaced: true, state, actions, - mutations + mutations, }; diff --git a/src/renderer/src/application/worker/store/modules/osc.js b/src/renderer/src/application/worker/store/modules/osc.js new file mode 100644 index 000000000..c3bbf4a9d --- /dev/null +++ b/src/renderer/src/application/worker/store/modules/osc.js @@ -0,0 +1,80 @@ +import set from "lodash.set"; +import { v4 as uuidv4 } from "uuid"; +const { Server } = require("node-osc"); + +const state = { + servers: { + // "server-uuidv4": { + // server: {}, // the server instance, + // id: '', + // name: '', + // } + }, + + data: { + // "server-uuidv4": recieved data + }, +}; + +const getters = { + serverList: (state) => + Object.entries(state.servers).reduce(([id, { name }], list) => { + list[id] = name; + return list; + }, {}), +}; + +const actions = { + async createServer({ commit }, serverOptions) { + const server = new Server(serverOptions.port, serverOptions.host, () => { + console.log("OSC Server is listening"); + }); + + const id = uuidv4(); + + server.on("message", (msg) => { + // console.log(msg); + commit("WRITE_DATA", { id, msg }); + }); + + const serverContext = { + id, + server, + name: serverOptions.name ?? `${serverOptions.host}:${serverOptions.port}`, + }; + + commit("ADD_SERVER", serverContext); + + return serverContext; + }, + + async removeServer({ commit }, id) { + const serverContext = state.servers[id]; + + serverContext.server.close(); + + commit("DELETE_SERVER", id); + }, +}; + +const mutations = { + ADD_SERVER(state, serverContext) { + state.servers[serverContext.id] = serverContext; + }, + + DELETE_RECIEVER(state, id) { + delete state.servers[id]; + }, + + WRITE_DATA(state, { msg }) { + set(state.data, msg[0].substring(1).replaceAll("/", "."), msg.slice(1)); + }, +}; + +export default { + namespaced: true, + state, + getters, + actions, + mutations, +}; diff --git a/src/application/worker/store/modules/outputs.js b/src/renderer/src/application/worker/store/modules/outputs.js similarity index 90% rename from src/application/worker/store/modules/outputs.js rename to src/renderer/src/application/worker/store/modules/outputs.js index c1bb5d37b..d779bdce0 100644 --- a/src/application/worker/store/modules/outputs.js +++ b/src/renderer/src/application/worker/store/modules/outputs.js @@ -1,4 +1,3 @@ -import Vue from "vue"; import { v4 as uuidv4 } from "uuid"; const state = { @@ -8,11 +7,11 @@ const state = { debug: false, debugId: "main", - debugContext: null + debugContext: null, }; const getters = { - canvasToDebug: state => { + canvasToDebug: (state) => { if (state.debugId === "main") { return { context: state.main }; } @@ -20,10 +19,10 @@ const getters = { return state.auxillary[state.debugId]; }, - resizable: state => - Object.values(state.auxillary).filter(aux => aux.reactToResize), + resizable: (state) => + Object.values(state.auxillary).filter((aux) => aux.reactToResize), - auxillaryCanvas: state => id => state.auxillary[id].context.canvas + auxillaryCanvas: (state) => (id) => state.auxillary[id].context.canvas, }; /** @@ -57,8 +56,8 @@ const actions = { id = "", reactToResize = true, width = state.main ? state.main.canvas.width : 300, - height = state.main ? state.main.canvas.height : 300 - } + height = state.main ? state.main.canvas.height : 300, + }, ) { if (type === "2d") { options.storage = "discardable"; @@ -76,7 +75,7 @@ const actions = { context: canvasContext, reactToResize, group, - id + id, }); return outputContext; @@ -111,7 +110,7 @@ const actions = { resizeDebug({ commit }, { width, height }) { commit("RESIZE_DEBUG", { width, height }); - } + }, }; const mutations = { @@ -124,11 +123,11 @@ const mutations = { }, ADD_AUXILLARY(state, outputContext) { - Vue.set(state.auxillary, outputContext.id, outputContext); + state.auxillary[outputContext.id] = outputContext; }, REMOVE_AUXILLARY(state, id) { - Vue.delete(state.auxillary, id); + delete state.auxillary[id]; }, UPDATE_AUXILLARY(state, { auxillaryId, data }) { @@ -184,7 +183,7 @@ const mutations = { SET_DEBUG_CONTEXT(state, context) { state.debugContext = context; - } + }, }; export default { @@ -192,5 +191,5 @@ export default { state, getters, actions, - mutations + mutations, }; diff --git a/src/application/worker/store/modules/plugins.js b/src/renderer/src/application/worker/store/modules/plugins.js similarity index 83% rename from src/application/worker/store/modules/plugins.js rename to src/renderer/src/application/worker/store/modules/plugins.js index b33947436..92a0506e5 100644 --- a/src/application/worker/store/modules/plugins.js +++ b/src/renderer/src/application/worker/store/modules/plugins.js @@ -15,13 +15,15 @@ function camelize(str) { const state = []; const getters = { - preProcessFrame: state => { - return state.filter(plugin => !!plugin.preProcessFrame && plugin.enabled); + preProcessFrame: (state) => { + return state.filter((plugin) => !!plugin.preProcessFrame && plugin.enabled); }, - postProcessFrame: state => { - return state.filter(plugin => !!plugin.postProcessFrame && plugin.enabled); - } + postProcessFrame: (state) => { + return state.filter( + (plugin) => !!plugin.postProcessFrame && plugin.enabled, + ); + }, }; const actions = { @@ -45,7 +47,7 @@ const actions = { const key = keys[i]; const prop = plugin.props[key]; - plugin.$props[key] = await getPropDefault(module, key, prop, false); + plugin.$props[key] = await getPropDefault(plugin, key, prop, false); if (!plugin.$props[key]) { plugin.$props[key] = null; @@ -59,7 +61,7 @@ const actions = { }, setEnabled({ commit }, { pluginId, enabled }) { - const plugin = state.find(item => item.id === pluginId); + const plugin = state.find((item) => item.id === pluginId); if (!plugin) { return false; @@ -79,7 +81,7 @@ const actions = { }, async updateProp({ commit }, { pluginId, prop, data }) { - const plugin = state.find(item => item.id === pluginId); + const plugin = state.find((item) => item.id === pluginId); if (!plugin) { return false; @@ -116,7 +118,7 @@ const actions = { } commit("UPDATE_PROP", { pluginId, prop, data: dataOut }); - } + }, }; const mutations = { @@ -125,7 +127,7 @@ const mutations = { }, SET_PLUGIN_ENABLE(state, { pluginId, enabled }) { - const plugin = state.find(item => item.id === pluginId); + const plugin = state.find((item) => item.id === pluginId); if (!plugin) { return false; @@ -135,14 +137,14 @@ const mutations = { }, UPDATE_PROP(state, { pluginId, prop, data }) { - const plugin = state.find(item => item.id === pluginId); + const plugin = state.find((item) => item.id === pluginId); if (!plugin) { return false; } plugin.$props[prop] = data; - } + }, }; export default { @@ -150,5 +152,5 @@ export default { state, getters, actions, - mutations + mutations, }; diff --git a/src/application/worker/store/modules/projects.js b/src/renderer/src/application/worker/store/modules/projects.js similarity index 85% rename from src/application/worker/store/modules/projects.js rename to src/renderer/src/application/worker/store/modules/projects.js index 9f0fd42f9..9b321b63b 100644 --- a/src/application/worker/store/modules/projects.js +++ b/src/renderer/src/application/worker/store/modules/projects.js @@ -1,22 +1,22 @@ const state = { - currentProject: "default" + currentProject: "default", }; const actions = { setCurrentProject({ commit }, projectName) { commit("SET_CURRENT_PROJECT", projectName); - } + }, }; const mutations = { SET_CURRENT_PROJECT(state, currentProject) { state.currentProject = currentProject; - } + }, }; export default { namespaced: true, state, actions, - mutations + mutations, }; diff --git a/src/application/worker/store/modules/renderers.js b/src/renderer/src/application/worker/store/modules/renderers.js similarity index 67% rename from src/application/worker/store/modules/renderers.js rename to src/renderer/src/application/worker/store/modules/renderers.js index 7ed4fdd1d..8ad3ecd24 100644 --- a/src/application/worker/store/modules/renderers.js +++ b/src/renderer/src/application/worker/store/modules/renderers.js @@ -1,12 +1,12 @@ const state = {}; const getters = { - renderersWithTick: state => { + renderersWithTick: (state) => { const keys = Object.keys(state); return keys - .map(key => state[key].tick && state[key]) - .filter(renderer => renderer); - } + .map((key) => state[key].tick && state[key]) + .filter((renderer) => renderer); + }, }; const mutations = { @@ -15,12 +15,12 @@ const mutations = { }, REMOVE_RENDERER(state, name) { delete state[name]; - } + }, }; export default { namespaced: true, getters, state, - mutations + mutations, }; diff --git a/src/application/worker/store/modules/size.js b/src/renderer/src/application/worker/store/modules/size.js similarity index 93% rename from src/application/worker/store/modules/size.js rename to src/renderer/src/application/worker/store/modules/size.js index 58ab9f473..73d0aea56 100644 --- a/src/application/worker/store/modules/size.js +++ b/src/renderer/src/application/worker/store/modules/size.js @@ -3,11 +3,11 @@ import store from "../index"; const state = { width: 0, height: 0, - dpr: 1 + dpr: 1, }; const getters = { - area: state => state.width * state.height + area: (state) => state.width * state.height, }; const actions = { @@ -31,7 +31,7 @@ const actions = { } commit("SET_SIZE", { width, height, dpr }); - } + }, }; const mutations = { @@ -39,7 +39,7 @@ const mutations = { state.width = width; state.height = height; state.dpr = dpr; - } + }, }; export default { @@ -47,5 +47,5 @@ export default { state, getters, actions, - mutations + mutations, }; diff --git a/src/application/worker/store/modules/tweens.js b/src/renderer/src/application/worker/store/modules/tweens.js similarity index 89% rename from src/application/worker/store/modules/tweens.js rename to src/renderer/src/application/worker/store/modules/tweens.js index e1c421984..5e89f5e4e 100644 --- a/src/application/worker/store/modules/tweens.js +++ b/src/renderer/src/application/worker/store/modules/tweens.js @@ -1,13 +1,12 @@ -import Vue from "vue"; import anime from "animejs"; import store from "../"; import { v4 as uuidv4 } from "uuid"; if (typeof window === "undefined") { // shims for anime in a worker - self.NodeList = function() {}; - self.HTMLCollection = function() {}; - self.SVGElement = function() {}; + self.NodeList = function () {}; + self.HTMLCollection = function () {}; + self.SVGElement = function () {}; self.window = { Promise }; } @@ -16,17 +15,17 @@ const progress = {}; const state = { tweens: {}, - easings: Object.keys(anime.penner).map(easing => ({ + easings: Object.keys(anime.penner).map((easing) => ({ value: easing, label: easing .replace(/([a-z])([A-Z])/g, "$1 $2") - .replace(/^\w/, c => c.toUpperCase()) - })) + .replace(/^\w/, (c) => c.toUpperCase()), + })), }; const getters = { progress: () => progress, - frames: () => frames + frames: () => frames, }; async function buildFrames({ @@ -39,7 +38,7 @@ async function buildFrames({ bpmDivision, useBpm, durationAsTotalTime, - steps + steps, }) { let newDuration = 1000; @@ -60,7 +59,7 @@ async function buildFrames({ seek = frames[id] / state.tweens[id].frames.length; } - return new Promise(resolve => { + return new Promise((resolve) => { const objOut = {}; const mapped = {}; @@ -93,7 +92,7 @@ async function buildFrames({ loop, update(anim) { progress[id] = anim.progress; - } + }, }); const animationCache = []; @@ -147,8 +146,8 @@ const actions = { bpmDivision = 16, durationAsTotalTime = false, isGallery, - steps = 0 - } + steps = 0, + }, ) { const animationCache = await buildFrames({ id, @@ -160,7 +159,7 @@ const actions = { useBpm, bpmDivision, durationAsTotalTime, - steps + steps, }); const tween = { @@ -175,7 +174,7 @@ const actions = { bpmDivision, durationAsTotalTime, isGallery, - steps + steps, }; commit("ADD_TWEEN", tween); @@ -198,7 +197,7 @@ const actions = { key: "duration", value: tween.durationAsTotalTime ? calculatedBpm - : calculatedBpm * tween.data.length + : calculatedBpm * tween.data.length, }); const frames = await buildFrames(tween); @@ -206,14 +205,14 @@ const actions = { commit("UPDATE_TWEEN_VALUE", { id: tween.id, key: "frames", - value: frames + value: frames, }); } } }, createPresetData() { - return Object.values(state.tweens).filter(tween => !tween.isGallery); + return Object.values(state.tweens).filter((tween) => !tween.isGallery); }, async loadPresetData(context, tweens) { @@ -223,21 +222,21 @@ const actions = { await store.dispatch("dataTypes/createType", { type: "tween", - args: tween + args: tween, }); } - } + }, }; const mutations = { ADD_TWEEN(state, tween) { - Vue.set(state.tweens, tween.id, tween); + state.tweens[tween.id] = tween; frames[tween.id] = 0; }, UPDATE_TWEEN_VALUE(state, { id, key, value }) { state.tweens[id][key] = value; - } + }, }; function advanceFrame(id) { @@ -255,5 +254,5 @@ export default { state, getters, actions, - mutations + mutations, }; diff --git a/src/application/worker/store/modules/videos.js b/src/renderer/src/application/worker/store/modules/videos.js similarity index 86% rename from src/application/worker/store/modules/videos.js rename to src/renderer/src/application/worker/store/modules/videos.js index a359531ab..4632ac56b 100644 --- a/src/application/worker/store/modules/videos.js +++ b/src/renderer/src/application/worker/store/modules/videos.js @@ -1,25 +1,24 @@ -import Vue from "vue"; import { v4 as uuidv4 } from "uuid"; -import path from "path"; import store from "../"; import { conformFilePath } from "../../../utils/conform-file-path"; +const path = require("path"); const state = {}; const getters = { - video: state => id => state[id]?.outputContext?.context.canvas + video: (state) => (id) => state[id]?.outputContext?.context.canvas, }; const actions = { createVideoFromPath({ rootState, commit }, textureDefinition) { const { id = uuidv4(), - options: { path: filePath } + options: { path: filePath }, } = textureDefinition; - const url = `modv://${path.join( + const url = `modv://.${path.join( rootState.media.path, - conformFilePath(filePath) + conformFilePath(filePath), )}`; if (typeof window !== "undefined") { @@ -27,7 +26,7 @@ const actions = { type: "createWebcodecVideo", id, url, - textureDefinition + textureDefinition, }); } @@ -40,12 +39,12 @@ const actions = { const outputContext = await store.dispatch("outputs/getAuxillaryOutput", { name: state[id].path, options: { - desynchronized: true + desynchronized: true, }, group: "videos", reactToResize: false, width, - height + height, }); frameReader.read().then(function processFrame({ done, value: frame }) { @@ -70,7 +69,7 @@ const actions = { if (typeof window !== "undefined") { self.postMessage({ type: "removeWebcodecVideo", - id + id, }); } return; @@ -93,18 +92,18 @@ const actions = { height, frameReader, outputContext, - needsRemoval: false + needsRemoval: false, }); }, async removeVideoById({ commit }, { id }) { commit("UPDATE_VIDEO", { id, needsRemoval: true }); - } + }, }; const mutations = { CREATE_VIDEO(state, { id, path }) { - Vue.set(state, id, { path }); + state[id] = { path }; }, UPDATE_VIDEO(state, video) { @@ -114,7 +113,7 @@ const mutations = { REMOVE_VIDEO(state, { id }) { delete state[id]; - } + }, }; export default { @@ -122,5 +121,5 @@ export default { state, getters, actions, - mutations + mutations, }; diff --git a/src/application/worker/store/modules/windows.js b/src/renderer/src/application/worker/store/modules/windows.js similarity index 80% rename from src/application/worker/store/modules/windows.js rename to src/renderer/src/application/worker/store/modules/windows.js index f7418f83f..198e189b4 100644 --- a/src/application/worker/store/modules/windows.js +++ b/src/renderer/src/application/worker/store/modules/windows.js @@ -1,5 +1,3 @@ -import Vue from "vue"; - import { v4 as uuidv4 } from "uuid"; const state = {}; @@ -15,24 +13,24 @@ const actions = { y: 0, fullscreen: false, backgroundColor: "#000", - outputId: "" + outputId: "", }; win.id = uuidv4(); commit("ADD_WINDOW", win); return win.id; - } + }, }; const mutations = { ADD_WINDOW(state, window) { - Vue.set(state, window.id, window); + state[window.id] = window; }, UPDATE_WINDOW(state, { id, key, value }) { - Vue.set(state[id], key, value); - } + state[id][key] = value; + }, // REMOVE_WINDOW(state, id) {} }; @@ -42,5 +40,5 @@ export default { state, // getters, actions, - mutations + mutations, }; diff --git a/src/assets/fonts/Inter-italic.var.woff2 b/src/renderer/src/assets/fonts/Inter-italic.var.woff2 similarity index 100% rename from src/assets/fonts/Inter-italic.var.woff2 rename to src/renderer/src/assets/fonts/Inter-italic.var.woff2 diff --git a/src/assets/fonts/Inter-roman.var.woff2 b/src/renderer/src/assets/fonts/Inter-roman.var.woff2 similarity index 100% rename from src/assets/fonts/Inter-roman.var.woff2 rename to src/renderer/src/assets/fonts/Inter-roman.var.woff2 diff --git a/src/assets/fonts/iaw-mono-Bold.woff b/src/renderer/src/assets/fonts/iaw-mono-Bold.woff similarity index 100% rename from src/assets/fonts/iaw-mono-Bold.woff rename to src/renderer/src/assets/fonts/iaw-mono-Bold.woff diff --git a/src/assets/fonts/iaw-mono-Bold.woff2 b/src/renderer/src/assets/fonts/iaw-mono-Bold.woff2 similarity index 100% rename from src/assets/fonts/iaw-mono-Bold.woff2 rename to src/renderer/src/assets/fonts/iaw-mono-Bold.woff2 diff --git a/src/assets/fonts/iaw-mono-BoldItalic.woff b/src/renderer/src/assets/fonts/iaw-mono-BoldItalic.woff similarity index 100% rename from src/assets/fonts/iaw-mono-BoldItalic.woff rename to src/renderer/src/assets/fonts/iaw-mono-BoldItalic.woff diff --git a/src/assets/fonts/iaw-mono-BoldItalic.woff2 b/src/renderer/src/assets/fonts/iaw-mono-BoldItalic.woff2 similarity index 100% rename from src/assets/fonts/iaw-mono-BoldItalic.woff2 rename to src/renderer/src/assets/fonts/iaw-mono-BoldItalic.woff2 diff --git a/src/assets/fonts/iaw-mono-Italic.woff b/src/renderer/src/assets/fonts/iaw-mono-Italic.woff similarity index 100% rename from src/assets/fonts/iaw-mono-Italic.woff rename to src/renderer/src/assets/fonts/iaw-mono-Italic.woff diff --git a/src/assets/fonts/iaw-mono-Italic.woff2 b/src/renderer/src/assets/fonts/iaw-mono-Italic.woff2 similarity index 100% rename from src/assets/fonts/iaw-mono-Italic.woff2 rename to src/renderer/src/assets/fonts/iaw-mono-Italic.woff2 diff --git a/src/assets/fonts/iaw-mono-Regular.woff b/src/renderer/src/assets/fonts/iaw-mono-Regular.woff similarity index 100% rename from src/assets/fonts/iaw-mono-Regular.woff rename to src/renderer/src/assets/fonts/iaw-mono-Regular.woff diff --git a/src/assets/fonts/iaw-mono-Regular.woff2 b/src/renderer/src/assets/fonts/iaw-mono-Regular.woff2 similarity index 100% rename from src/assets/fonts/iaw-mono-Regular.woff2 rename to src/renderer/src/assets/fonts/iaw-mono-Regular.woff2 diff --git a/src/assets/graphics/Arrow-vertical.svg b/src/renderer/src/assets/graphics/Arrow-vertical.svg similarity index 100% rename from src/assets/graphics/Arrow-vertical.svg rename to src/renderer/src/assets/graphics/Arrow-vertical.svg diff --git a/src/assets/graphics/Arrow.svg b/src/renderer/src/assets/graphics/Arrow.svg similarity index 100% rename from src/assets/graphics/Arrow.svg rename to src/renderer/src/assets/graphics/Arrow.svg diff --git a/src/components/ABSwap.vue b/src/renderer/src/components/ABSwap.vue similarity index 95% rename from src/components/ABSwap.vue rename to src/renderer/src/components/ABSwap.vue index 246a70a44..9ba2f6d9c 100644 --- a/src/components/ABSwap.vue +++ b/src/renderer/src/components/ABSwap.vue @@ -10,7 +10,7 @@ export default { swap() { this.$modV.store.commit("groups/SWAP", {}); this.$modV.store.commit("modules/SWAP", {}); - } - } + }, + }, }; diff --git a/src/components/ActiveModule.vue b/src/renderer/src/components/ActiveModule.vue similarity index 87% rename from src/components/ActiveModule.vue rename to src/renderer/src/components/ActiveModule.vue index 655451eef..ac3ad2f75 100644 --- a/src/components/ActiveModule.vue +++ b/src/renderer/src/components/ActiveModule.vue @@ -1,26 +1,27 @@