From 43e3af81cb4b95227ba4415095d6b03403a4422c Mon Sep 17 00:00:00 2001 From: Mike Ammerlaan Date: Tue, 19 Nov 2024 16:14:42 -0800 Subject: [PATCH] feat(ux): Improve bb import/export, add audio handling. add validation (#46) * fix(dependencies): Remove unused dependencies * feat(ux): Improve bb import/export, add audio handling. add validation * feat(valservice): Add validation over HTTP - Add basic validation-over-http mode - Add and fix tests * feat(editor): Entity visual/audio controller editing * feat(editors): Modify render controller editor - Start support to separate out education edition targeting - Blockbench export * fix(ci): Update build script * fix(links): Canonicalize texture path * fix(val): Temporarily disable unlinked info generator as it is not comprehensive enough * fix(ux): Fix issue with new project creation * fix(actions): Fix image links * fix(docs): Update contributing --- CONTRIBUTING.md | 3 + NOTICE.md | 24 + README.md | 4 +- app/.vscode/launch.json | 14 + app/gulpfile.js | 8 +- app/package-lock.json | 1103 +- app/package.json | 6 +- app/public/data/content/blank.ogg | Bin 0 -> 19197 bytes .../forms/audio_item_properties.form.json | 40 + .../data/forms/entity_sound_event.form.json | 27 + .../data/forms/entity_type_resource.form.json | 22 +- .../entity_type_resource_animations.form.json | 10 + .../entity_type_resource_geometry.form.json | 10 + .../entity_type_resource_materials.form.json | 9 + .../entity_type_resource_textures.form.json | 10 + .../forms/render_controller_set.form.json | 71 + .../render_controller_set_geometry.form.json | 36 + .../render_controller_set_materials.form.json | 36 + .../render_controller_set_misc.form.json | 22 + .../render_controller_set_textures.form.json | 37 + app/public/data/gallery.json | 10 - app/reslist/packs-preview.resources.json | 16 + app/reslist/packs.resources.json | 2 +- app/reslist/samples.resources.json | 2 +- app/reslist/schemas.resources.json | 2 +- app/reslist/scriptsamples.resources.json | 2 +- app/src/UX/App.tsx | 136 +- app/src/UX/AudioItemProperties.css | 24 + app/src/UX/AudioItemProperties.tsx | 207 + app/src/UX/AudioManager.css | 354 + app/src/UX/AudioManager.tsx | 841 ++ app/src/UX/BlockTypeTile.tsx | 7 +- app/src/UX/CartoSettingsPanel.tsx | 10 +- app/src/UX/DirectoryStorage.ts | 25 + app/src/UX/DocumentedCommandEditor.tsx | 1 + app/src/UX/EntityTypeEditor.tsx | 1 + app/src/UX/EntityTypeResourceEditor.css | 18 +- app/src/UX/EntityTypeResourceEditor.tsx | 376 +- app/src/UX/Home.css | 60 +- app/src/UX/Home.tsx | 538 +- app/src/UX/IntegrateItem.tsx | 3 +- app/src/UX/ItemTileButton.tsx | 4 +- app/src/UX/NewProject.css | 96 + app/src/UX/NewProject.tsx | 300 + app/src/UX/ProjectActions.tsx | 4 +- app/src/UX/ProjectAddButton.tsx | 13 + app/src/UX/ProjectEditor.tsx | 25 +- app/src/UX/ProjectEditorUtilities.ts | 74 +- app/src/UX/ProjectGallery.css | 2 +- app/src/UX/ProjectItemEditor.tsx | 108 +- app/src/UX/ProjectItemList.css | 10 + app/src/UX/ProjectItemList.tsx | 66 +- app/src/UX/ProjectPropertyEditor.css | 4 +- app/src/UX/ProjectPropertyEditor.tsx | 66 +- app/src/UX/ProjectTile.css | 21 +- app/src/UX/ProjectTile.tsx | 10 +- app/src/UX/RenderControllerSetEditor.css | 30 + app/src/UX/RenderControllerSetEditor.tsx | 242 + app/src/UX/SoundEventSetEditor.css | 24 + app/src/UX/SoundEventSetEditor.tsx | 120 + app/src/UX/audio-encoder.d.ts | 3 + app/src/UX/waveform-playlist.d.ts | 47 + app/src/app/Carto.ts | 12 +- app/src/app/ICartoData.ts | 2 + app/src/app/IGalleryItem.ts | 1 + app/src/app/IProjectItemData.ts | 4 +- app/src/app/IProjectItemSeed.ts | 1 + .../IProjectItemUnfulfilledRelationship.ts | 9 + app/src/app/IProjectSeed.ts | 15 + app/src/app/Project.ts | 73 +- app/src/app/ProjectItem.ts | 43 +- app/src/app/ProjectItemManager.ts | 235 + app/src/app/ProjectItemRelations.ts | 115 +- app/src/app/ProjectItemUtilities.ts | 36 +- app/src/app/ProjectUtilities.ts | 126 +- app/src/cli/ClUtils.ts | 7 + app/src/cli/index.ts | 636 +- app/src/core/ContentIndex.ts | 27 +- app/src/core/Utilities.ts | 139 + app/src/dataform/DataForm.css | 40 +- app/src/dataform/DataForm.tsx | 381 +- app/src/dataform/DataFormProcessor.ts | 137 + app/src/dataform/IField.ts | 4 + app/src/dataform/StringArray.tsx | 14 +- app/src/index.css | 10 + .../info/AddOnItemRequirementsGenerator.ts | 8 +- app/src/info/AddOnRequirementsGenerator.ts | 22 +- app/src/info/GeneratorRegistrations.ts | 2 + app/src/info/PackInfoGenerator.ts | 41 +- app/src/info/ProjectInfoSet.ts | 5 +- app/src/info/TextureImageInfoGenerator.ts | 5 +- app/src/info/TextureInfoGenerator.ts | 144 +- app/src/info/UnlinkedItemInfoGenerator.ts | 90 + app/src/info/WorldDataInfoGenerator.ts | 1 + app/src/integrations/BlockbenchModel.ts | 631 +- app/src/integrations/IBlockbenchModel.ts | 28 +- app/src/local/HttpServer.ts | 454 + app/src/local/ILocalEnvironmentData.ts | 19 - app/src/local/LocalEnvironment.ts | 107 +- app/src/local/ServerManager.ts | 201 + app/src/local/ServerMessage.ts | 70 + app/src/manager/BaseGameVersionManager.ts | 4 +- .../manager/BehaviorPackEntityTypeManager.ts | 4 +- .../manager/BehaviorPackItemTypeManager.ts | 4 +- app/src/manager/FormatVersionManager.ts | 4 +- app/src/manager/MinEngineVersionManager.ts | 4 +- .../AnimationControllerResourceDefinition.ts | 40 +- .../minecraft/AnimationResourceDefinition.ts | 44 +- .../minecraft/AttachableResourceDefinition.ts | 363 +- app/src/minecraft/Database.ts | 175 +- app/src/minecraft/EntityTypeDefinition.ts | 16 +- .../minecraft/EntityTypeResourceDefinition.ts | 305 +- app/src/minecraft/IAddonManifest.ts | 7 + app/src/minecraft/IClientAttachable.ts | 2 +- app/src/minecraft/IEntityTypeResource.ts | 3 +- app/src/minecraft/IModelGeometry.ts | 32 +- app/src/minecraft/IMusicDefinitionCatalog.ts | 12 + app/src/minecraft/IRenderControllerSet.ts | 29 + .../minecraft/IResourceRenderController.ts | 22 - app/src/minecraft/ISoundCatalog.ts | 39 + app/src/minecraft/ISoundDefinitionCatalog.ts | 34 + ...inTexture.ts => ITerrainTextureCatalog.ts} | 9 +- .../minecraft/ItemTextureCatalogDefinition.ts | 135 +- app/src/minecraft/MinecraftDefinitions.ts | 27 +- app/src/minecraft/MinecraftUtilities.ts | 163 + app/src/minecraft/ModelGeometryDefinition.ts | 78 +- .../MusicDefinitionCatalogDefinition.ts | 183 + .../RenderControllerSetDefinition.ts | 181 + app/src/minecraft/ResourceRenderController.ts | 104 - app/src/minecraft/SoundCatalogDefinition.ts | 391 + .../SoundDefinitionCatalogDefinition.ts | 421 + .../TerrainTextureCatalogDefinition.ts | 143 +- .../blockActors/BlockActorFactory.ts | 1 + app/src/storage/FileBase.ts | 2 +- app/src/storage/FileSystemFolder.ts | 2 +- app/src/storage/FolderBase.ts | 9 +- app/src/storage/StorageUtilities.ts | 38 + app/src/test/CommandLineTest.ts | 148 +- .../behavior_packs/cn_test/manifest.json | 17 +- .../resource_packs/cn_test/manifest.json | 16 +- .../behavior_packs/deployJs/manifest.json | 2 +- .../serveCommandValidate/report.json | 9212 +++++++++++++++++ app/test/scenarios/simple/report.json | 38 +- .../content1.mcr.json | 25 +- .../content1.report.html | 2 +- .../content2.mcr.json | 13 +- .../content2.report.html | 2 +- .../content3.mcr.json | 13 +- .../content3.report.html | 2 +- .../content3.csv | 6 +- .../content3.mcr.json | 11 +- .../content3.report.html | 2 +- .../validateLinkErrors/content_linkerrors.csv | 96 + .../content_linkerrors.mcr.json | 3681 +++++++ .../content_linkerrors.report.html | 211 + .../content_linkerrorsaddon.csv | 15 + .../content_linkerrorsaddon.report.html | 211 + .../animations/biceson.animation.json | 55 + .../animations/nardolphle.animation.json | 25 + .../animations/sheepomelon.animation.json | 67 + .../aop_mobsrp/entity/biceson.entity.json | 39 + .../aop_mobsrp/entity/nardolphle.entity.json | 30 + .../aop_mobsrp/entity/sheepomelon.entity.json | 42 + .../resource_packs/aop_mobsrp/sounds.json | 21 + .../aop_mobsrp/sounds/ambientsounds/co2.ogg | Bin 0 -> 27897 bytes .../sounds/ambientsounds/co3_unlinked.ogg | Bin 0 -> 27897 bytes .../aop_mobsrp/sounds/music_definitions.json | 12 + .../aop_mobsrp/sounds/sound_definitions.json | 26 + .../moremobs/nardolphle_imageisnotlinked.png | Bin 0 -> 1900 bytes samplecontent/addon/gulpfile.js | 187 +- .../resource_packs/aop_mobsrp/sounds.json | 71 - .../aop_mobsrp/texts/en_US.lang | 10 - .../textures/aop/moremobs/raccoon.png | Bin 1457 -> 0 bytes samplecontent/addon/scripts/main.ts | 2 +- 174 files changed, 24476 insertions(+), 2155 deletions(-) create mode 100644 CONTRIBUTING.md create mode 100644 app/public/data/content/blank.ogg create mode 100644 app/public/data/forms/audio_item_properties.form.json create mode 100644 app/public/data/forms/entity_sound_event.form.json create mode 100644 app/public/data/forms/entity_type_resource_animations.form.json create mode 100644 app/public/data/forms/entity_type_resource_geometry.form.json create mode 100644 app/public/data/forms/entity_type_resource_materials.form.json create mode 100644 app/public/data/forms/entity_type_resource_textures.form.json create mode 100644 app/public/data/forms/render_controller_set.form.json create mode 100644 app/public/data/forms/render_controller_set_geometry.form.json create mode 100644 app/public/data/forms/render_controller_set_materials.form.json create mode 100644 app/public/data/forms/render_controller_set_misc.form.json create mode 100644 app/public/data/forms/render_controller_set_textures.form.json create mode 100644 app/reslist/packs-preview.resources.json create mode 100644 app/src/UX/AudioItemProperties.css create mode 100644 app/src/UX/AudioItemProperties.tsx create mode 100644 app/src/UX/AudioManager.css create mode 100644 app/src/UX/AudioManager.tsx create mode 100644 app/src/UX/DirectoryStorage.ts create mode 100644 app/src/UX/NewProject.css create mode 100644 app/src/UX/NewProject.tsx create mode 100644 app/src/UX/RenderControllerSetEditor.css create mode 100644 app/src/UX/RenderControllerSetEditor.tsx create mode 100644 app/src/UX/SoundEventSetEditor.css create mode 100644 app/src/UX/SoundEventSetEditor.tsx create mode 100644 app/src/UX/audio-encoder.d.ts create mode 100644 app/src/UX/waveform-playlist.d.ts create mode 100644 app/src/app/IProjectItemUnfulfilledRelationship.ts create mode 100644 app/src/app/IProjectSeed.ts create mode 100644 app/src/dataform/DataFormProcessor.ts create mode 100644 app/src/info/UnlinkedItemInfoGenerator.ts create mode 100644 app/src/local/HttpServer.ts create mode 100644 app/src/local/ServerManager.ts create mode 100644 app/src/local/ServerMessage.ts create mode 100644 app/src/minecraft/IMusicDefinitionCatalog.ts create mode 100644 app/src/minecraft/IRenderControllerSet.ts delete mode 100644 app/src/minecraft/IResourceRenderController.ts create mode 100644 app/src/minecraft/ISoundCatalog.ts create mode 100644 app/src/minecraft/ISoundDefinitionCatalog.ts rename app/src/minecraft/{ITerrainTexture.ts => ITerrainTextureCatalog.ts} (64%) create mode 100644 app/src/minecraft/MusicDefinitionCatalogDefinition.ts create mode 100644 app/src/minecraft/RenderControllerSetDefinition.ts delete mode 100644 app/src/minecraft/ResourceRenderController.ts create mode 100644 app/src/minecraft/SoundCatalogDefinition.ts create mode 100644 app/src/minecraft/SoundDefinitionCatalogDefinition.ts create mode 100644 app/test/scenarios/serveCommandValidate/report.json create mode 100644 app/test/scenarios/validateLinkErrors/content_linkerrors.csv create mode 100644 app/test/scenarios/validateLinkErrors/content_linkerrors.mcr.json create mode 100644 app/test/scenarios/validateLinkErrors/content_linkerrors.report.html create mode 100644 app/test/scenarios/validateLinkErrors/content_linkerrorsaddon.csv create mode 100644 app/test/scenarios/validateLinkErrors/content_linkerrorsaddon.report.html create mode 100644 samplecontent/addon/altdiffs/linkerrors/resource_packs/aop_mobsrp/animations/biceson.animation.json create mode 100644 samplecontent/addon/altdiffs/linkerrors/resource_packs/aop_mobsrp/animations/nardolphle.animation.json create mode 100644 samplecontent/addon/altdiffs/linkerrors/resource_packs/aop_mobsrp/animations/sheepomelon.animation.json create mode 100644 samplecontent/addon/altdiffs/linkerrors/resource_packs/aop_mobsrp/entity/biceson.entity.json create mode 100644 samplecontent/addon/altdiffs/linkerrors/resource_packs/aop_mobsrp/entity/nardolphle.entity.json create mode 100644 samplecontent/addon/altdiffs/linkerrors/resource_packs/aop_mobsrp/entity/sheepomelon.entity.json create mode 100644 samplecontent/addon/altdiffs/linkerrors/resource_packs/aop_mobsrp/sounds.json create mode 100644 samplecontent/addon/altdiffs/linkerrors/resource_packs/aop_mobsrp/sounds/ambientsounds/co2.ogg create mode 100644 samplecontent/addon/altdiffs/linkerrors/resource_packs/aop_mobsrp/sounds/ambientsounds/co3_unlinked.ogg create mode 100644 samplecontent/addon/altdiffs/linkerrors/resource_packs/aop_mobsrp/sounds/music_definitions.json create mode 100644 samplecontent/addon/altdiffs/linkerrors/resource_packs/aop_mobsrp/sounds/sound_definitions.json create mode 100644 samplecontent/addon/altdiffs/linkerrors/resource_packs/aop_mobsrp/textures/aop/moremobs/nardolphle_imageisnotlinked.png delete mode 100644 samplecontent/addon/resource_packs/aop_mobsrp/textures/aop/moremobs/raccoon.png diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..beb40b1f --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,3 @@ +# Contributing + +Unfortunately, we are not able to accept pull request contributions from the broader community at this time. diff --git a/NOTICE.md b/NOTICE.md index 8e337745..e89947f3 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -4,6 +4,30 @@ Copyright 2024 Mojang AB This repository incorporates material as listed below or described in the code. +### waveform-playlist + +#### MIT License + +Copyright (c) 2015 Naomi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + ### Noto Sans Font #### SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 diff --git a/README.md b/README.md index 5b05216e..b7b8365a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Minecraft Creator Tools -This is project is a work in progress for a set of web-based tools for Minecraft Creators. +This project is a work in progress for a set of web-based and command line tools for Minecraft creators. Visit the [documentation](https://mctools.dev/docs/) for more information on Minecraft Creator Tools and the current set of capabilities. @@ -8,6 +8,8 @@ See the [changelog](CHANGELOG.md) for detailed updates and notes. If you have is See the [Project Structure](ProjectStructure.md) file for a look at the structure of the codebase including a tour of major types. +Please note that, at this time, we are not able to accept pull request contributions from the broader community. + ## Using Creator Tools Visit this web app via . diff --git a/app/.vscode/launch.json b/app/.vscode/launch.json index 6a0eaff9..e412718e 100644 --- a/app/.vscode/launch.json +++ b/app/.vscode/launch.json @@ -120,6 +120,20 @@ "runtimeArgs": ["--nolazy", "--max-old-space-size=32768"], "outFiles": ["${workspaceFolder}/toolbuild/jsn/**/*.js"] }, + { + "name": "cli (serve)", + "cwd": "${workspaceRoot}/", + "args": ["serve", "basicwebservices", "-once", "-adminpc", "admn-psco"], + "type": "node", + "request": "launch", + "program": "${workspaceRoot}/src/cli/index.ts", + "preLaunchTask": "gulp: jsncorebuild", + "sourceMaps":true, + "runtimeExecutable": null, + "localRoot": "${workspaceRoot}/src", + "runtimeArgs": ["--nolazy"], + "outFiles": ["${workspaceFolder}/toolbuild/jsn/**/*.js"] + }, { "name": "cli (create)", "cwd": "${workspaceRoot}/", diff --git a/app/gulpfile.js b/app/gulpfile.js index a6719e82..d478c0d7 100644 --- a/app/gulpfile.js +++ b/app/gulpfile.js @@ -72,6 +72,7 @@ const versionSource = ["toolbuild/jsn/package.json"]; const mcreslistsigs = ["reslist/schemas.resources.json"]; const mcreslistvanillasigs = ["reslist/packs.resources.json"]; +const mcreslistpreviewvanillasigs = ["reslist/packs-preview.resources.json"]; const mcreslistsamplesigs = ["reslist/samples.resources.json"]; const mcreslistscriptsamplesigs = ["reslist/scriptsamples.resources.json"]; const mcreslistgametestsigs = ["reslist/gametestsamples.resources.json"]; @@ -265,7 +266,11 @@ function runDownloadGameTests() { } function runDownloadVanillaResources() { - return gulp.src(mcreslistvanillasigs, { base: "" }).pipe(downloadResources("public/res/latest/van/")); + return gulp.src(mcreslistvanillasigs, { base: "" }).pipe(downloadResources("public/res/latest/van/release/")); +} + +function runDownloadVanillaPreviewResources() { + return gulp.src(mcreslistpreviewvanillasigs, { base: "" }).pipe(downloadResources("public/res/latest/van/preview/")); } gulp.task("jsnwebbuild", gulp.series("clean-jsnwebbuild", compileJsnWebBuild, "postclean-jsnwebbuild")); @@ -298,6 +303,7 @@ gulp.task( runDownloadScriptSamples, runDownloadGameTests, runDownloadVanillaResources, + runDownloadVanillaPreviewResources, copyCheckedInRes ) ) diff --git a/app/package-lock.json b/app/package-lock.json index 40994001..091e4675 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -47,7 +47,8 @@ "threads": "^1.7.0", "trash": "^8.0.0", "tui-grid": "^4.18.1", - "uuid": "^9.0.0" + "uuid": "^9.0.0", + "waveform-playlist": "^4.3.3" }, "bin": { "mct": "toolbuild/jsn/cli/index.js" @@ -77,6 +78,7 @@ "@minecraft/server-net": "^1.0.0-beta.1.21.30-preview.25", "@minecraft/server-ui": "^1.4.0-beta.1.21.30-preview.25", "@minecraft/vanilla-data": "^1.21.22", + "@npm/types": "^1.0.2", "@octokit/rest": "^18.5.2", "@octokit/types": "^6.13.0", "@testing-library/react": "^11.2.5", @@ -2132,11 +2134,12 @@ "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" }, "node_modules/@babel/runtime": { - "version": "7.17.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz", - "integrity": "sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", + "license": "MIT", "dependencies": { - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" @@ -2151,6 +2154,12 @@ "regenerator-runtime": "^0.13.4" } }, + "node_modules/@babel/runtime/node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" + }, "node_modules/@babel/template": { "version": "7.22.15", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", @@ -4163,7 +4172,8 @@ "node_modules/@npm/types": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@npm/types/-/types-1.0.2.tgz", - "integrity": "sha512-KXZccTDEnWqNrrx6JjpJKU/wJvNeg9BDgjS0XhmlZab7br921HtyVbsYzJr4L+xIvjdJ20Wh9dgxgCI2a5CEQw==" + "integrity": "sha512-KXZccTDEnWqNrrx6JjpJKU/wJvNeg9BDgjS0XhmlZab7br921HtyVbsYzJr4L+xIvjdJ20Wh9dgxgCI2a5CEQw==", + "dev": true }, "node_modules/@octokit/auth-token": { "version": "2.4.5", @@ -5020,18 +5030,20 @@ } }, "node_modules/@types/eslint-scope": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.3.tgz", - "integrity": "sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==", + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "license": "MIT", "dependencies": { "@types/eslint": "*", "@types/estree": "*" } }, "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "license": "MIT" }, "node_modules/@types/express": { "version": "4.17.13", @@ -6416,6 +6428,25 @@ "node": ">= 4.5.0" } }, + "node_modules/automation-events": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/automation-events/-/automation-events-7.1.4.tgz", + "integrity": "sha512-KCkUSGBKlZz2DTnjzHLnPzlTayExlkeIrzIgq5OqZgwvZsmgSsyQOXv/L+r8P14yR69xfSnwL2FmmzSCzI9o/g==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=18.2.0" + } + }, + "node_modules/automation-events/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, "node_modules/axe-core": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.2.tgz", @@ -6899,9 +6930,10 @@ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", @@ -6911,7 +6943,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.11.0", + "qs": "6.13.0", "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -6925,6 +6957,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -6933,6 +6966,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -6941,6 +6975,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -6948,21 +6983,8 @@ "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/body-parser/node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, "node_modules/body-scroll-lock": { "version": "3.1.5", @@ -7010,6 +7032,12 @@ "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" }, + "node_modules/browser-split": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/browser-split/-/browser-split-0.0.1.tgz", + "integrity": "sha512-JhvgRb2ihQhsljNda3BI8/UcRHVzrVwo3Q+P8vDtSiyobXuFpuZ9mq+MbRGMnC22CjW3RrfXdg6j6ITX8M+7Ow==", + "license": "MIT" + }, "node_modules/browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", @@ -7017,9 +7045,9 @@ "dev": true }, "node_modules/browserslist": { - "version": "4.22.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", - "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", "funding": [ { "type": "opencollective", @@ -7034,11 +7062,12 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001565", - "electron-to-chromium": "^1.4.601", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" @@ -7356,6 +7385,15 @@ "node": ">= 6" } }, + "node_modules/camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/caniuse-api": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", @@ -7368,9 +7406,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001636", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001636.tgz", - "integrity": "sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg==", + "version": "1.0.30001680", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001680.tgz", + "integrity": "sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==", "funding": [ { "type": "opencollective", @@ -7384,7 +7422,8 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/canvas": { "version": "2.11.2", @@ -8344,6 +8383,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -8357,9 +8397,10 @@ } }, "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -9544,7 +9585,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dev": true, "dependencies": { "es5-ext": "^0.10.50", "type": "^1.0.1" @@ -9927,6 +9967,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" @@ -10109,6 +10150,11 @@ } ] }, + "node_modules/dom-walk": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", + "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" + }, "node_modules/domelementtype": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", @@ -10159,9 +10205,10 @@ ] }, "node_modules/dompurify": { - "version": "2.4.7", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.7.tgz", - "integrity": "sha512-kxxKlPEDa6Nc5WJi+qRgPbOAbgTpSULL+vI3NUXsZMlkJxTqYI9wg5ZTay2sFrdZRWHPWNi+EdAhcJf81WtoMQ==" + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.5.7.tgz", + "integrity": "sha512-2q4bEI+coQM8f5ez7kt2xclg1XsecaV9ASJk/54vwlfRRNQfDqJz2pzQ8t0Ix/ToBpXlVjrRIx7pFC/o8itG2Q==", + "license": "(MPL-2.0 OR Apache-2.0)" }, "node_modules/domutils": { "version": "1.7.0", @@ -10267,7 +10314,8 @@ "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" }, "node_modules/ejs": { "version": "3.1.10", @@ -10284,9 +10332,10 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.624", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.624.tgz", - "integrity": "sha512-w9niWuheXjz23vezH3w90n9KKcHe0UkhTfJ+rXJkuGGogHyQbQ7KS1x0a8ER4LbI3ljFS/gqxKh1TidNXDMHOg==" + "version": "1.5.56", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.56.tgz", + "integrity": "sha512-7lXb9dAvimCFdvUMTyucD4mnIndt/xhRKFAlky0CyFogdnNmdPQNoHI23msF/2V4mpTxMzgMdjK4+YRlFlRQZw==", + "license": "ISC" }, "node_modules/emittery": { "version": "0.8.1", @@ -10313,9 +10362,10 @@ } }, "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -10352,9 +10402,10 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", - "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -10418,6 +10469,16 @@ "errno": "cli.js" } }, + "node_modules/error": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/error/-/error-4.4.0.tgz", + "integrity": "sha512-SNDKualLUtT4StGFP7xNfuFybL2f6iJujFtrWuvJqGbVQGaN+adE23veqzPz1hjUjTunLi2EnJ+0SJxtbJreKw==", + "dependencies": { + "camelize": "^1.0.0", + "string-template": "~0.2.0", + "xtend": "~4.0.0" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -10519,7 +10580,6 @@ "version": "0.10.64", "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", - "dev": true, "hasInstallScript": true, "dependencies": { "es6-iterator": "^2.0.3", @@ -10535,7 +10595,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "dev": true, "dependencies": { "d": "1", "es5-ext": "^0.10.35", @@ -10546,7 +10605,6 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "dev": true, "dependencies": { "d": "^1.0.1", "ext": "^1.1.2" @@ -10576,9 +10634,10 @@ } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", "engines": { "node": ">=6" } @@ -11333,7 +11392,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", - "dev": true, "dependencies": { "d": "^1.0.1", "es5-ext": "^0.10.62", @@ -11347,8 +11405,7 @@ "node_modules/esniff/node_modules/type": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", - "dev": true + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" }, "node_modules/espree": { "version": "9.4.1", @@ -11464,15 +11521,23 @@ "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, + "node_modules/ev-store": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ev-store/-/ev-store-7.0.0.tgz", + "integrity": "sha512-otazchNRnGzp2YarBJ+GXKVGvhxVATB1zmaStxJBYet0Dyq7A9VhH8IUEB/gRcL6Ch52lfpgPTRJ2m49epyMsQ==", + "dependencies": { + "individual": "^3.0.0" + } + }, "node_modules/event-emitter": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", - "dev": true, "dependencies": { "d": "1", "es5-ext": "~0.10.14" @@ -11691,36 +11756,37 @@ } }, "node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", + "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.2", + "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", + "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.2.0", + "finalhandler": "1.3.1", "fresh": "0.5.2", "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", + "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", + "path-to-regexp": "0.1.10", "proxy-addr": "~2.0.7", - "qs": "6.11.0", + "qs": "6.13.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", + "send": "0.19.0", + "serve-static": "1.16.2", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", @@ -11757,20 +11823,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, - "node_modules/express/node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/express/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -11802,7 +11854,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", - "dev": true, "dependencies": { "type": "^2.0.0" } @@ -11810,8 +11861,7 @@ "node_modules/ext/node_modules/type": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/type/-/type-2.3.0.tgz", - "integrity": "sha512-rgPIqOdfK/4J9FhiVrZ3cveAjRRo5rsQBAIhnylX874y1DX/kEKSVdLsnuHB6l1KTjHyU01VjiMBHgU2adejyg==", - "dev": true + "integrity": "sha512-rgPIqOdfK/4J9FhiVrZ3cveAjRRo5rsQBAIhnylX874y1DX/kEKSVdLsnuHB6l1KTjHyU01VjiMBHgU2adejyg==" }, "node_modules/extend": { "version": "3.0.2", @@ -11938,6 +11988,21 @@ "node": ">=0.10.0" } }, + "node_modules/fade-curves": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fade-curves/-/fade-curves-1.0.2.tgz", + "integrity": "sha512-n/wDBCVJvKDTUXDX/1k25cijioEvQeBdn9Pa9VgxJLQD0mUs65A+UOhaWid6vYJKquNnl9Y0UnfFn+Efbs8zuw==", + "license": "MIT" + }, + "node_modules/fade-maker": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/fade-maker/-/fade-maker-1.0.3.tgz", + "integrity": "sha512-6x1BEnGMXz0PV8Ug81evYMcVyDZ3zm8II+ID8B1/9R4+iJHGdhpYGIQuCq4Ca57A3B6Cyl6EhJGYWFnkQRo02Q==", + "license": "MIT", + "dependencies": { + "fade-curves": "^1.0.2" + } + }, "node_modules/fancy-log": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", @@ -12325,12 +12390,13 @@ } }, "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "license": "MIT", "dependencies": { "debug": "2.6.9", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", @@ -12345,6 +12411,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -12352,12 +12419,14 @@ "node_modules/finalhandler/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, "node_modules/finalhandler/node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -12857,6 +12926,7 @@ "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -13445,6 +13515,16 @@ "node": ">=0.10.0" } }, + "node_modules/global": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", + "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "license": "MIT", + "dependencies": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, "node_modules/global-modules": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", @@ -14089,6 +14169,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -14104,6 +14185,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -14112,6 +14194,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -14148,9 +14231,10 @@ } }, "node_modules/http-proxy-middleware": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.4.tgz", - "integrity": "sha512-m/4FxX17SUvz4lJ5WPXOHDUuCwIqXLfLHs1s0uZ3oYjhoXlx9csYxaOa0ElDEJ+h8Q4iJ1s+lTMbiCa4EXIJqg==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", + "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", + "license": "MIT", "dependencies": { "@types/http-proxy": "^1.17.8", "http-proxy": "^1.18.1", @@ -14322,6 +14406,11 @@ "node": ">=8" } }, + "node_modules/individual": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/individual/-/individual-3.0.0.tgz", + "integrity": "sha512-rUY5vtT748NMRbEMrTNiFfy29BgGZwGXUi2NFUVMWQrogSLzlJvQV9eeMWi+g1aVaQ53tpyLAQtd5x/JH0Nh1g==" + }, "node_modules/infer-owner": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", @@ -14352,6 +14441,12 @@ "resolved": "https://registry.npmjs.org/inline-style-expand-shorthand/-/inline-style-expand-shorthand-1.6.0.tgz", "integrity": "sha512-REormb3TCk/CIeL5/Q1rdHYM9tW8YKGKzbvgAH4IXrDsJmq9BnV69yhIGGMzV2IRkR/J6MuLNhY7UfoIJjunog==" }, + "node_modules/inline-worker": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/inline-worker/-/inline-worker-1.1.0.tgz", + "integrity": "sha512-2nlxBGg5Uoop6IRco9wMzlAz62690ylokrUDg3IaCi9bJaq0HykbWlRtRXgvSKiBNmCBGXnOCFBkIFjaSGJocA==", + "license": "MIT" + }, "node_modules/inquirer": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.0.tgz", @@ -14801,6 +14896,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", + "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-observable": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-2.1.0.tgz", @@ -18669,6 +18773,12 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "node_modules/lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==", + "license": "MIT" + }, "node_modules/lodash.clone": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", @@ -18680,6 +18790,18 @@ "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" }, + "node_modules/lodash.defaultsdeep": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz", + "integrity": "sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==", + "license": "MIT" + }, + "node_modules/lodash.forown": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.forown/-/lodash.forown-4.4.0.tgz", + "integrity": "sha512-xcpca6BCshoe5SFSrQOoV8FBEbNzcBa6QQYmtv48eEFNzdwQLkHkcWSaBlecHhyHb1BUk1xqFdXoiSLJkt/w5w==", + "license": "MIT" + }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -19074,6 +19196,7 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -19143,9 +19266,13 @@ } }, "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/merge-stream": { "version": "2.0.0", @@ -19169,11 +19296,12 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -19184,6 +19312,7 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", "bin": { "mime": "cli.js" }, @@ -19218,6 +19347,14 @@ "node": ">=6" } }, + "node_modules/min-document": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", + "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", + "dependencies": { + "dom-walk": "^0.1.0" + } + }, "node_modules/mini-css-extract-plugin": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.1.tgz", @@ -19786,8 +19923,7 @@ "node_modules/next-tick": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", - "dev": true + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" }, "node_modules/no-case": { "version": "3.0.4", @@ -20076,9 +20212,10 @@ "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "license": "MIT" }, "node_modules/nopt": { "version": "5.0.0", @@ -20435,6 +20572,7 @@ "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", "dependencies": { "ee-first": "1.1.1" }, @@ -20891,9 +21029,10 @@ } }, "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", + "license": "MIT" }, "node_modules/path-type": { "version": "4.0.0", @@ -20929,9 +21068,10 @@ } }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", @@ -21266,6 +21406,15 @@ "node": ">=0.8" } }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -21403,6 +21552,21 @@ "teleport": ">=0.2.0" } }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", @@ -21466,6 +21630,7 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -21480,6 +21645,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -24507,9 +24673,10 @@ } }, "node_modules/rollup": { - "version": "2.70.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.70.2.tgz", - "integrity": "sha512-EitogNZnfku65I1DD5Mxe8JYRUCy0hkK5X84IlDtUs+O6JRMpRciXTzyCUuX11b5L5pvjH+OmFXiQ3XjabcXgg==", + "version": "2.79.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz", + "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", + "license": "MIT", "bin": { "rollup": "dist/bin/rollup" }, @@ -24729,9 +24896,10 @@ } }, "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "license": "MIT", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -24755,6 +24923,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -24762,12 +24931,23 @@ "node_modules/send/node_modules/debug/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, "node_modules/send/node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -24775,12 +24955,14 @@ "node_modules/send/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" }, "node_modules/send/node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -24848,14 +25030,15 @@ "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" }, "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "license": "MIT", "dependencies": { - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.18.0" + "send": "0.19.0" }, "engines": { "node": ">= 0.8.0" @@ -24918,7 +25101,8 @@ "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" }, "node_modules/shallow-clone": { "version": "3.0.1", @@ -25427,6 +25611,23 @@ "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.1.tgz", "integrity": "sha512-h88QkzREN/hy8eRdyNhhsO7RSJ5oyTqxxmmn0dzBIMUclZsjpfmrsg81vp8mjjAs2vAZ72nyWxRUwSwmh0e4xg==" }, + "node_modules/standardized-audio-context": { + "version": "25.3.77", + "resolved": "https://registry.npmjs.org/standardized-audio-context/-/standardized-audio-context-25.3.77.tgz", + "integrity": "sha512-Ki9zNz6pKcC5Pi+QPjPyVsD9GwJIJWgryji0XL9cAJXMGyn+dPOf6Qik1AHei0+UNVcc4BOCa0hWLBzlwqsW/A==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.25.6", + "automation-events": "^7.0.9", + "tslib": "^2.7.0" + } + }, + "node_modules/standardized-audio-context/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, "node_modules/state-local": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz", @@ -25540,6 +25741,11 @@ "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz", "integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==" }, + "node_modules/string-template": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", + "integrity": "sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw==" + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -26397,10 +26603,27 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", "engines": { "node": ">=0.6" } }, + "node_modules/tone": { + "version": "14.9.17", + "resolved": "https://registry.npmjs.org/tone/-/tone-14.9.17.tgz", + "integrity": "sha512-+Qb7M4NMua+tb5Z52+MEVmjye0fjJuIFBePx423pqr9E6/lHDqZAG+fUAvo+Ujm48q0s9bVLRAyT1ETJJglNtg==", + "license": "MIT", + "dependencies": { + "standardized-audio-context": "^25.3.70", + "tslib": "^2.3.1" + } + }, + "node_modules/tone/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, "node_modules/tough-cookie": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", @@ -26925,8 +27148,7 @@ "node_modules/type": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", - "dev": true + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" }, "node_modules/type-check": { "version": "0.4.0", @@ -26962,6 +27184,7 @@ "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -27150,6 +27373,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -27217,9 +27441,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "funding": [ { "type": "opencollective", @@ -27234,9 +27458,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.2.0", + "picocolors": "^1.1.0" }, "bin": { "update-browserslist-db": "cli.js" @@ -27509,6 +27734,28 @@ "node": ">=0.8" } }, + "node_modules/virtual-dom": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/virtual-dom/-/virtual-dom-2.1.1.tgz", + "integrity": "sha512-wb6Qc9Lbqug0kRqo/iuApfBpJJAq14Sk1faAnSmtqXiwahg7PVTvWMs9L02Z8nNIMqbwsxzBAA90bbtRLbw0zg==", + "license": "MIT", + "dependencies": { + "browser-split": "0.0.1", + "error": "^4.3.0", + "ev-store": "^7.0.0", + "global": "^4.3.0", + "is-object": "^1.0.1", + "next-tick": "^0.2.2", + "x-is-array": "0.1.0", + "x-is-string": "0.1.0" + } + }, + "node_modules/virtual-dom/node_modules/next-tick": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-0.2.2.tgz", + "integrity": "sha512-f7h4svPtl+QidoBv4taKXUjJ70G2asaZ8G28nS0OkqaalX8dwwrtWtyxEDPK62AC00ur/+/E0pUwBwY5EPn15Q==", + "license": "MIT" + }, "node_modules/w3c-hr-time": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", @@ -27582,6 +27829,35 @@ "node": ">=10.13.0" } }, + "node_modules/waveform-playlist": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/waveform-playlist/-/waveform-playlist-4.3.3.tgz", + "integrity": "sha512-s1UVWBg3t9fwhz8dAKQ2JLBJQc7jBtTjuPQ46FDjd8Q6wb9BOuNNZHl//Ud497yFliYlHE44Cioy8kqN+e5MTg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.17.2", + "event-emitter": "^0.3.4", + "fade-curves": "^1.0.2", + "fade-maker": "^1.0.3", + "inline-worker": "^1.1.0", + "lodash.assign": "^4.0.0", + "lodash.defaultsdeep": "^4.6.1", + "lodash.forown": "^4.0.0", + "tone": "^14.7.77", + "uuid": "^8.3.2", + "virtual-dom": "^2.1.1", + "webaudio-peaks": "^1.0.0" + } + }, + "node_modules/waveform-playlist/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/wbuf": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", @@ -27598,6 +27874,12 @@ "defaults": "^1.0.3" } }, + "node_modules/webaudio-peaks": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/webaudio-peaks/-/webaudio-peaks-1.0.0.tgz", + "integrity": "sha512-N7ck946hz2LNZxVveeMA3nWawFwYxfd0LYVXBwLJJvOrOx/8QBTFMuqqz+qUZecjDPpMxgNWsRSU/pTy5B7CSw==", + "license": "MIT" + }, "node_modules/webidl-conversions": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", @@ -27607,20 +27889,20 @@ } }, "node_modules/webpack": { - "version": "5.92.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.92.1.tgz", - "integrity": "sha512-JECQ7IwJb+7fgUFBlrJzbyu3GEuNBcdqr1LD7IbSzwkSmIevTm8PF+wej3Oxuz/JFBUZ6O1o43zsPkwm1C4TmA==", + "version": "5.96.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.96.1.tgz", + "integrity": "sha512-l2LlBSvVZGhL4ZrPwyr8+37AunkcYj5qh8o6u2/2rzoPc8gxFJkLj1WxNgooi9pnoc06jh0BjuXnamM4qlujZA==", + "license": "MIT", "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.5", + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", "@webassemblyjs/ast": "^1.12.1", "@webassemblyjs/wasm-edit": "^1.12.1", "@webassemblyjs/wasm-parser": "^1.12.1", - "acorn": "^8.7.1", - "acorn-import-attributes": "^1.9.5", - "browserslist": "^4.21.10", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.0", + "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", @@ -27855,9 +28137,10 @@ } }, "node_modules/webpack/node_modules/acorn": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", - "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -27865,14 +28148,6 @@ "node": ">=0.4.0" } }, - "node_modules/webpack/node_modules/acorn-import-attributes": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", - "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", - "peerDependencies": { - "acorn": "^8" - } - }, "node_modules/webpack/node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -28370,6 +28645,16 @@ } } }, + "node_modules/x-is-array": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/x-is-array/-/x-is-array-0.1.0.tgz", + "integrity": "sha512-goHPif61oNrr0jJgsXRfc8oqtYzvfiMJpTqwE7Z4y9uH+T3UozkGqQ4d2nX9mB9khvA8U2o/UbPOFjgC7hLWIA==" + }, + "node_modules/x-is-string": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz", + "integrity": "sha512-GojqklwG8gpzOVEVki5KudKNoq7MbbjYZCbyWzEz7tyPA7eleiE0+ePwOWQQRb5fm86rD3S8Tc0tSFf3AOv50w==" + }, "node_modules/xdg-basedir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", @@ -29962,11 +30247,18 @@ "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" }, "@babel/runtime": { - "version": "7.17.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz", - "integrity": "sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", "requires": { - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.14.0" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + } } }, "@babel/runtime-corejs3": { @@ -31561,7 +31853,8 @@ "@npm/types": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@npm/types/-/types-1.0.2.tgz", - "integrity": "sha512-KXZccTDEnWqNrrx6JjpJKU/wJvNeg9BDgjS0XhmlZab7br921HtyVbsYzJr4L+xIvjdJ20Wh9dgxgCI2a5CEQw==" + "integrity": "sha512-KXZccTDEnWqNrrx6JjpJKU/wJvNeg9BDgjS0XhmlZab7br921HtyVbsYzJr4L+xIvjdJ20Wh9dgxgCI2a5CEQw==", + "dev": true }, "@octokit/auth-token": { "version": "2.4.5", @@ -32217,18 +32510,18 @@ } }, "@types/eslint-scope": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.3.tgz", - "integrity": "sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==", + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", "requires": { "@types/eslint": "*", "@types/estree": "*" } }, "@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" }, "@types/express": { "version": "4.17.13", @@ -33326,6 +33619,22 @@ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", "dev": true }, + "automation-events": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/automation-events/-/automation-events-7.1.4.tgz", + "integrity": "sha512-KCkUSGBKlZz2DTnjzHLnPzlTayExlkeIrzIgq5OqZgwvZsmgSsyQOXv/L+r8P14yR69xfSnwL2FmmzSCzI9o/g==", + "requires": { + "@babel/runtime": "^7.26.0", + "tslib": "^2.8.1" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, "axe-core": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.4.2.tgz", @@ -33707,9 +34016,9 @@ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" }, "body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", "requires": { "bytes": "3.1.2", "content-type": "~1.0.5", @@ -33719,7 +34028,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.11.0", + "qs": "6.13.0", "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -33747,14 +34056,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "requires": { - "side-channel": "^1.0.4" - } } } }, @@ -33801,6 +34102,11 @@ "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" }, + "browser-split": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/browser-split/-/browser-split-0.0.1.tgz", + "integrity": "sha512-JhvgRb2ihQhsljNda3BI8/UcRHVzrVwo3Q+P8vDtSiyobXuFpuZ9mq+MbRGMnC22CjW3RrfXdg6j6ITX8M+7Ow==" + }, "browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", @@ -33808,14 +34114,14 @@ "dev": true }, "browserslist": { - "version": "4.22.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", - "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", "requires": { - "caniuse-lite": "^1.0.30001565", - "electron-to-chromium": "^1.4.601", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.1" } }, "bser": { @@ -34044,6 +34350,11 @@ "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==" }, + "camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==" + }, "caniuse-api": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", @@ -34056,9 +34367,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001636", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001636.tgz", - "integrity": "sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg==" + "version": "1.0.30001680", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001680.tgz", + "integrity": "sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==" }, "canvas": { "version": "2.11.2", @@ -34837,9 +35148,9 @@ } }, "cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==" + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==" }, "cookie-signature": { "version": "1.0.6", @@ -35615,7 +35926,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dev": true, "requires": { "es5-ext": "^0.10.50", "type": "^1.0.1" @@ -36043,6 +36353,11 @@ } } }, + "dom-walk": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", + "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==" + }, "domelementtype": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", @@ -36079,9 +36394,9 @@ } }, "dompurify": { - "version": "2.4.7", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.7.tgz", - "integrity": "sha512-kxxKlPEDa6Nc5WJi+qRgPbOAbgTpSULL+vI3NUXsZMlkJxTqYI9wg5ZTay2sFrdZRWHPWNi+EdAhcJf81WtoMQ==" + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.5.7.tgz", + "integrity": "sha512-2q4bEI+coQM8f5ez7kt2xclg1XsecaV9ASJk/54vwlfRRNQfDqJz2pzQ8t0Ix/ToBpXlVjrRIx7pFC/o8itG2Q==" }, "domutils": { "version": "1.7.0", @@ -36196,9 +36511,9 @@ } }, "electron-to-chromium": { - "version": "1.4.624", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.624.tgz", - "integrity": "sha512-w9niWuheXjz23vezH3w90n9KKcHe0UkhTfJ+rXJkuGGogHyQbQ7KS1x0a8ER4LbI3ljFS/gqxKh1TidNXDMHOg==" + "version": "1.5.56", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.56.tgz", + "integrity": "sha512-7lXb9dAvimCFdvUMTyucD4mnIndt/xhRKFAlky0CyFogdnNmdPQNoHI23msF/2V4mpTxMzgMdjK4+YRlFlRQZw==" }, "emittery": { "version": "0.8.1", @@ -36216,9 +36531,9 @@ "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" }, "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==" }, "encoding": { "version": "0.1.13", @@ -36251,9 +36566,9 @@ } }, "enhanced-resolve": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz", - "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", "requires": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -36298,6 +36613,16 @@ "prr": "~1.0.1" } }, + "error": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/error/-/error-4.4.0.tgz", + "integrity": "sha512-SNDKualLUtT4StGFP7xNfuFybL2f6iJujFtrWuvJqGbVQGaN+adE23veqzPz1hjUjTunLi2EnJ+0SJxtbJreKw==", + "requires": { + "camelize": "^1.0.0", + "string-template": "~0.2.0", + "xtend": "~4.0.0" + } + }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -36381,7 +36706,6 @@ "version": "0.10.64", "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", - "dev": true, "requires": { "es6-iterator": "^2.0.3", "es6-symbol": "^3.1.3", @@ -36393,7 +36717,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "dev": true, "requires": { "d": "1", "es5-ext": "^0.10.35", @@ -36404,7 +36727,6 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "dev": true, "requires": { "d": "^1.0.1", "ext": "^1.1.2" @@ -36428,9 +36750,9 @@ "integrity": "sha512-L/FlOPMMFtw+6qPAbuPvJXdrOYOp9yx/PEwSrIZW0qghY4vgV003evdYDwqQ/9ENMQI0B6RMod9xT4FHtto6OQ==" }, "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==" }, "escape-html": { "version": "1.0.3", @@ -36973,7 +37295,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", - "dev": true, "requires": { "d": "^1.0.1", "es5-ext": "^0.10.62", @@ -36984,8 +37305,7 @@ "type": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", - "dev": true + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" } } }, @@ -37066,11 +37386,18 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" }, + "ev-store": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ev-store/-/ev-store-7.0.0.tgz", + "integrity": "sha512-otazchNRnGzp2YarBJ+GXKVGvhxVATB1zmaStxJBYet0Dyq7A9VhH8IUEB/gRcL6Ch52lfpgPTRJ2m49epyMsQ==", + "requires": { + "individual": "^3.0.0" + } + }, "event-emitter": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", - "dev": true, "requires": { "d": "1", "es5-ext": "~0.10.14" @@ -37242,36 +37569,36 @@ } }, "express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", "requires": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.2", + "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", + "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.2.0", + "finalhandler": "1.3.1", "fresh": "0.5.2", "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", + "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", + "path-to-regexp": "0.1.10", "proxy-addr": "~2.0.7", - "qs": "6.11.0", + "qs": "6.13.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", + "send": "0.19.0", + "serve-static": "1.16.2", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", @@ -37302,14 +37629,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, - "qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "requires": { - "side-channel": "^1.0.4" - } - }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -37326,7 +37645,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", - "dev": true, "requires": { "type": "^2.0.0" }, @@ -37334,8 +37652,7 @@ "type": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/type/-/type-2.3.0.tgz", - "integrity": "sha512-rgPIqOdfK/4J9FhiVrZ3cveAjRRo5rsQBAIhnylX874y1DX/kEKSVdLsnuHB6l1KTjHyU01VjiMBHgU2adejyg==", - "dev": true + "integrity": "sha512-rgPIqOdfK/4J9FhiVrZ3cveAjRRo5rsQBAIhnylX874y1DX/kEKSVdLsnuHB6l1KTjHyU01VjiMBHgU2adejyg==" } } }, @@ -37441,6 +37758,19 @@ } } }, + "fade-curves": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fade-curves/-/fade-curves-1.0.2.tgz", + "integrity": "sha512-n/wDBCVJvKDTUXDX/1k25cijioEvQeBdn9Pa9VgxJLQD0mUs65A+UOhaWid6vYJKquNnl9Y0UnfFn+Efbs8zuw==" + }, + "fade-maker": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/fade-maker/-/fade-maker-1.0.3.tgz", + "integrity": "sha512-6x1BEnGMXz0PV8Ug81evYMcVyDZ3zm8II+ID8B1/9R4+iJHGdhpYGIQuCq4Ca57A3B6Cyl6EhJGYWFnkQRo02Q==", + "requires": { + "fade-curves": "^1.0.2" + } + }, "fancy-log": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", @@ -37795,12 +38125,12 @@ } }, "finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "requires": { "debug": "2.6.9", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", @@ -38679,6 +39009,15 @@ } } }, + "global": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", + "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "requires": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, "global-modules": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", @@ -39227,9 +39566,9 @@ } }, "http-proxy-middleware": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.4.tgz", - "integrity": "sha512-m/4FxX17SUvz4lJ5WPXOHDUuCwIqXLfLHs1s0uZ3oYjhoXlx9csYxaOa0ElDEJ+h8Q4iJ1s+lTMbiCa4EXIJqg==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", + "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", "requires": { "@types/http-proxy": "^1.17.8", "http-proxy": "^1.18.1", @@ -39336,6 +39675,11 @@ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true }, + "individual": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/individual/-/individual-3.0.0.tgz", + "integrity": "sha512-rUY5vtT748NMRbEMrTNiFfy29BgGZwGXUi2NFUVMWQrogSLzlJvQV9eeMWi+g1aVaQ53tpyLAQtd5x/JH0Nh1g==" + }, "infer-owner": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", @@ -39366,6 +39710,11 @@ "resolved": "https://registry.npmjs.org/inline-style-expand-shorthand/-/inline-style-expand-shorthand-1.6.0.tgz", "integrity": "sha512-REormb3TCk/CIeL5/Q1rdHYM9tW8YKGKzbvgAH4IXrDsJmq9BnV69yhIGGMzV2IRkR/J6MuLNhY7UfoIJjunog==" }, + "inline-worker": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/inline-worker/-/inline-worker-1.1.0.tgz", + "integrity": "sha512-2nlxBGg5Uoop6IRco9wMzlAz62690ylokrUDg3IaCi9bJaq0HykbWlRtRXgvSKiBNmCBGXnOCFBkIFjaSGJocA==" + }, "inquirer": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.0.tgz", @@ -39693,6 +40042,11 @@ "has-tostringtag": "^1.0.0" } }, + "is-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", + "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==" + }, "is-observable": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-2.1.0.tgz", @@ -42573,6 +42927,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==" + }, "lodash.clone": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", @@ -42584,6 +42943,16 @@ "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" }, + "lodash.defaultsdeep": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz", + "integrity": "sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==" + }, + "lodash.forown": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.forown/-/lodash.forown-4.4.0.tgz", + "integrity": "sha512-xcpca6BCshoe5SFSrQOoV8FBEbNzcBa6QQYmtv48eEFNzdwQLkHkcWSaBlecHhyHb1BUk1xqFdXoiSLJkt/w5w==" + }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -42974,9 +43343,9 @@ } }, "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==" }, "merge-stream": { "version": "2.0.0", @@ -42994,11 +43363,11 @@ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" }, "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "requires": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" } }, @@ -43025,6 +43394,14 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" }, + "min-document": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", + "integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==", + "requires": { + "dom-walk": "^0.1.0" + } + }, "mini-css-extract-plugin": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.1.tgz", @@ -43439,8 +43816,7 @@ "next-tick": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", - "dev": true + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" }, "no-case": { "version": "3.0.4", @@ -43669,9 +44045,9 @@ "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" }, "node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" }, "nopt": { "version": "5.0.0", @@ -44285,9 +44661,9 @@ "dev": true }, "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==" }, "path-type": { "version": "4.0.0", @@ -44314,9 +44690,9 @@ } }, "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" }, "picomatch": { "version": "2.3.1", @@ -44557,6 +44933,11 @@ "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz", "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==" }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==" + }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -44679,6 +45060,14 @@ "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" }, + "qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "requires": { + "side-channel": "^1.0.6" + } + }, "querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", @@ -46680,9 +47069,9 @@ } }, "rollup": { - "version": "2.70.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.70.2.tgz", - "integrity": "sha512-EitogNZnfku65I1DD5Mxe8JYRUCy0hkK5X84IlDtUs+O6JRMpRciXTzyCUuX11b5L5pvjH+OmFXiQ3XjabcXgg==", + "version": "2.79.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz", + "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==", "requires": { "fsevents": "~2.3.2" } @@ -46849,9 +47238,9 @@ } }, "send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "requires": { "debug": "2.6.9", "depd": "2.0.0", @@ -46888,6 +47277,11 @@ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" + }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -46959,14 +47353,14 @@ } }, "serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "requires": { - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.18.0" + "send": "0.19.0" } }, "set-blocking": { @@ -47429,6 +47823,23 @@ "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.1.tgz", "integrity": "sha512-h88QkzREN/hy8eRdyNhhsO7RSJ5oyTqxxmmn0dzBIMUclZsjpfmrsg81vp8mjjAs2vAZ72nyWxRUwSwmh0e4xg==" }, + "standardized-audio-context": { + "version": "25.3.77", + "resolved": "https://registry.npmjs.org/standardized-audio-context/-/standardized-audio-context-25.3.77.tgz", + "integrity": "sha512-Ki9zNz6pKcC5Pi+QPjPyVsD9GwJIJWgryji0XL9cAJXMGyn+dPOf6Qik1AHei0+UNVcc4BOCa0hWLBzlwqsW/A==", + "requires": { + "@babel/runtime": "^7.25.6", + "automation-events": "^7.0.9", + "tslib": "^2.7.0" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, "state-local": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz", @@ -47514,6 +47925,11 @@ "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz", "integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==" }, + "string-template": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", + "integrity": "sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw==" + }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -48125,6 +48541,22 @@ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" }, + "tone": { + "version": "14.9.17", + "resolved": "https://registry.npmjs.org/tone/-/tone-14.9.17.tgz", + "integrity": "sha512-+Qb7M4NMua+tb5Z52+MEVmjye0fjJuIFBePx423pqr9E6/lHDqZAG+fUAvo+Ujm48q0s9bVLRAyT1ETJJglNtg==", + "requires": { + "standardized-audio-context": "^25.3.70", + "tslib": "^2.3.1" + }, + "dependencies": { + "tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" + } + } + }, "tough-cookie": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", @@ -48492,8 +48924,7 @@ "type": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", - "dev": true + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" }, "type-check": { "version": "0.4.0", @@ -48716,12 +49147,12 @@ "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==" }, "update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.2.0", + "picocolors": "^1.1.0" } }, "uri-js": { @@ -48947,6 +49378,28 @@ } } }, + "virtual-dom": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/virtual-dom/-/virtual-dom-2.1.1.tgz", + "integrity": "sha512-wb6Qc9Lbqug0kRqo/iuApfBpJJAq14Sk1faAnSmtqXiwahg7PVTvWMs9L02Z8nNIMqbwsxzBAA90bbtRLbw0zg==", + "requires": { + "browser-split": "0.0.1", + "error": "^4.3.0", + "ev-store": "^7.0.0", + "global": "^4.3.0", + "is-object": "^1.0.1", + "next-tick": "^0.2.2", + "x-is-array": "0.1.0", + "x-is-string": "0.1.0" + }, + "dependencies": { + "next-tick": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-0.2.2.tgz", + "integrity": "sha512-f7h4svPtl+QidoBv4taKXUjJ70G2asaZ8G28nS0OkqaalX8dwwrtWtyxEDPK62AC00ur/+/E0pUwBwY5EPn15Q==" + } + } + }, "w3c-hr-time": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", @@ -49010,6 +49463,32 @@ "graceful-fs": "^4.1.2" } }, + "waveform-playlist": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/waveform-playlist/-/waveform-playlist-4.3.3.tgz", + "integrity": "sha512-s1UVWBg3t9fwhz8dAKQ2JLBJQc7jBtTjuPQ46FDjd8Q6wb9BOuNNZHl//Ud497yFliYlHE44Cioy8kqN+e5MTg==", + "requires": { + "@babel/runtime": "^7.17.2", + "event-emitter": "^0.3.4", + "fade-curves": "^1.0.2", + "fade-maker": "^1.0.3", + "inline-worker": "^1.1.0", + "lodash.assign": "^4.0.0", + "lodash.defaultsdeep": "^4.6.1", + "lodash.forown": "^4.0.0", + "tone": "^14.7.77", + "uuid": "^8.3.2", + "virtual-dom": "^2.1.1", + "webaudio-peaks": "^1.0.0" + }, + "dependencies": { + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + } + } + }, "wbuf": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", @@ -49026,26 +49505,30 @@ "defaults": "^1.0.3" } }, + "webaudio-peaks": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/webaudio-peaks/-/webaudio-peaks-1.0.0.tgz", + "integrity": "sha512-N7ck946hz2LNZxVveeMA3nWawFwYxfd0LYVXBwLJJvOrOx/8QBTFMuqqz+qUZecjDPpMxgNWsRSU/pTy5B7CSw==" + }, "webidl-conversions": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==" }, "webpack": { - "version": "5.92.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.92.1.tgz", - "integrity": "sha512-JECQ7IwJb+7fgUFBlrJzbyu3GEuNBcdqr1LD7IbSzwkSmIevTm8PF+wej3Oxuz/JFBUZ6O1o43zsPkwm1C4TmA==", + "version": "5.96.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.96.1.tgz", + "integrity": "sha512-l2LlBSvVZGhL4ZrPwyr8+37AunkcYj5qh8o6u2/2rzoPc8gxFJkLj1WxNgooi9pnoc06jh0BjuXnamM4qlujZA==", "requires": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.5", + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", "@webassemblyjs/ast": "^1.12.1", "@webassemblyjs/wasm-edit": "^1.12.1", "@webassemblyjs/wasm-parser": "^1.12.1", - "acorn": "^8.7.1", - "acorn-import-attributes": "^1.9.5", - "browserslist": "^4.21.10", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.0", + "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", @@ -49063,15 +49546,9 @@ }, "dependencies": { "acorn": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", - "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==" - }, - "acorn-import-attributes": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", - "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", - "requires": {} + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==" }, "ajv": { "version": "6.12.6", @@ -49625,6 +50102,16 @@ "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "requires": {} }, + "x-is-array": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/x-is-array/-/x-is-array-0.1.0.tgz", + "integrity": "sha512-goHPif61oNrr0jJgsXRfc8oqtYzvfiMJpTqwE7Z4y9uH+T3UozkGqQ4d2nX9mB9khvA8U2o/UbPOFjgC7hLWIA==" + }, + "x-is-string": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz", + "integrity": "sha512-GojqklwG8gpzOVEVki5KudKNoq7MbbjYZCbyWzEz7tyPA7eleiE0+ePwOWQQRb5fm86rD3S8Tc0tSFf3AOv50w==" + }, "xdg-basedir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", diff --git a/app/package.json b/app/package.json index 9e0ffba7..e5c48493 100644 --- a/app/package.json +++ b/app/package.json @@ -50,7 +50,8 @@ "threads": "^1.7.0", "trash": "^8.0.0", "tui-grid": "^4.18.1", - "uuid": "^9.0.0" + "uuid": "^9.0.0", + "waveform-playlist": "^4.3.3" }, "scripts": { "devenv": "gulp devenv --max_old_space_size=16384", @@ -59,7 +60,7 @@ "webbuild": "cross-env CI=true react-scripts --max_old_space_size=16384 build", "jsnbuild": "gulp jsnbuild", "jsncorebuild": "gulp jsncorebuild", - "process": "npx ./toolbuild/jsn/ validate --force -ot noreports -i ./public/res/latest/van/ -o ./public/data && gulp copyjsnodedata", + "process": "npx ./toolbuild/jsn/ validate --force -ot noreports -i ./public/res/latest/van/release/ -o ./public/data && npx gulp copyjsnodedata", "all": "npm install && npm run-script allbuild", "allbuild": "npm run-script devenvandjsnbuild && npm run-script webbuild", "devenvandjsnbuild": "npm run-script devenv && npm run-script jsnbuild && npm run-script process", @@ -119,6 +120,7 @@ "@minecraft/server-ui": "^1.4.0-beta.1.21.30-preview.25", "@minecraft/vanilla-data": "^1.21.22", "@octokit/rest": "^18.5.2", + "@npm/types": "^1.0.2", "@octokit/types": "^6.13.0", "@testing-library/react": "^11.2.5", "@testing-library/user-event": "^12.8.1", diff --git a/app/public/data/content/blank.ogg b/app/public/data/content/blank.ogg new file mode 100644 index 0000000000000000000000000000000000000000..dfc0a268957c6ce6d2d5f8cd5342e61bf5d10970 GIT binary patch literal 19197 zcmeFZcT^Nz(=XaX&LALyB0-TPIS+AAksvuplB6)GWQHhdFaRO~l4r;nhNK`lDgqJ* zBuPfeIp;8^(dT{7d%ydwbM9Ja-TzKcPtWe1s(00pCK-?@a`4TB{W9|OrnWHV6lB35nS0_gY8%H;u3o;PG zzkTrBx%&_TkbpVD>TE5@-be!gpaB3&4j!s#xGGO}OgguBLX65qszvB+Ld@G1#wTII zt^c~PiCJF;00IEXO&Xp#ull?PYRkwK?wSUDrYV)nMjWa$4JG}$$N9uD=W~voV-L?Q z5=vu2kO2Tph5Ze^?#1PC2zwACcnM~9{m!17sG9(?$uxSq(&7tsSWLvqo52v1IeE7;ZF zVX*;7aF~Gd2YS^{^qrrWyZbn_w)u4E#QQ{*^z=0hz{B0l(8Fff!+qGp&p6?YX_cRG z)f>~FZ_EzfSTP3ua~}Fl9bBA$hRy~7(r!ZIW_U7gT+R3m&A@*hREP&yU$BIYH0lOV zRHkYU{CV-S#EPc{6%L)He4V8ff2x4fOK|ZtK-x2O&j0I#8^_uF?@!p%@4NsEmK-iPvanF$?qLEgA*n$MRWlSfzOYxTy zSRo{RmJQvD-sy%?q36=_=@a|Eywy+Ss?JYH{4<00Jxnv;T=I0FTGCLxXhe@H1v>k0 z%9}QkxG4Vzn8&n`MAgb<1=f4^15KPiVg$A|?nTe%Rnvp1w=s!a<<M^39Wa zzCeG0E#8hM+EtU9fvF?wr1fsni@g6TJ}_|JtbQ`KCck9!3nzL^&z{2`&Egh86`dyh zohOUsefWK~{8!q#OkCM+FaM034FF!#{E^~+UH*vjUn$Ot3gzwKF6$EMfH1Cl9o#20IjthO;2j=z<91lu4G=A`PZ;NT|i1pDa z>4<6QT{i2x?B35{qbFh3FK*LsU^D1pGg4t=TIpw8@sGm%Rhy|{_y5qG3l+Hm4WCho zBKV)0lg1tXTPpmfY7~cY6sLEb?OSv{DrG4@gY3U(&ePD`gwWiO(1nn2?zeHz-l8$p z8TK8;D>eVy^WU1I?8*V2pynvKa{PzpGzl}`1+}S^Ph;or80GpvhPo+T`OgUefTl=_ z2Y=QP9bNuGUGYI(egl2E|Fy<|rGsJ`{bC?vV*!8(0A{mt23}CnK8}RGReVaK`i;5e zk@Qkh=A*FS$eZ_7*Vy&CXb8#^dR5=h5BxTHejTCz?tPK9iXwkSt1kOo9x=G=kpSsT z096}=Sp%Q>0Y0dC7l&#;pg|Amrn|5r;L+442BVXM(JB4C{Xe^cgv4|R!1JGOKtg@` zkUp`0Xn|CkM3rD-pe6Y~KmHq9I^qzm|DXjE(}3w~{GU_$zdih44*YL90E#$-3j8wM zNoT)}hm?W>W&;mg0|8hnsVb-EnVzSqz3Wcyz~`zmII`R^YN2>?h4F@OZ< zI$-~Prc4!D0Fa8ZHU{y9N|X%*K-w6m5CcGzjW^4G-_8H`-2Xxlg5(BqYK9SmGjk_i z_!DDT6d$>zF`$9(brnVrxu}eH@pRY3ZZQyZi&@_SXb6F6XZp?`Vmh-@aoNu@zPs=} z=)d>D1_VKGZ-{}(ODPN9Ii%PfaNOLX8PD)Q^8&J+@Ph3UPu2LSw4Z)g1K2o#re9KV zbKV);p&)+3bhz+!?%dO%*U&RCi=Q!yTX>tnjn2W;2!MpJe@qkz?w+Fmoh_z853a)C zYHW4|J^%Ki2Mnf|9IV+drUBL*Cd_z>&dJAsmIU^v;-I_Pm5_@(3}{{OE-D$A4aeFb zpMmXaiuv&M|K2mDVKB=z#kV^F5I~K@+87f}U)+`Q0l;(<1Ym0-k#5f`CAp?iwF%H) zExiGRfU*!~r6!zB@r3pcS-O?_9Tj$KU0q(DY_dDNw_Lax0Q0!At-*Rp(Yn%L9u){U+`uYXF}imalMo>ONCvAw0N7t{huUij(dz$U_hq1I z`eM3LxIlKRM&)>?aDlk>c~sWl9JDO< z3%rZLtbDDw;Qz3@)z}5|S8AF-zPsBnRb7~GK5_uias~k2k5=xlqcc7=frbw6!d|`> zCgA}w7ZH0F%^ek-VCC9Lbl%iLP8Nr3FYx!C6-f5nkkoiBeO$d?yUbeJeK3B(&&Gh%iZZ)_{q< zFas7!oSqe963SEY8=N384;+fgBXaia7?XGW6^x1Y?BJ}~fq73v)yly zOrmMO9Q0465|z-}=raxob&SY?u4VL|?x zm}=061Vyj)Lc%WON;iuU0g4&h>kCgTi{wv%A_y0)hdjrz=i=9D+kbyM*6sUnNEBzhP zzXdT-V7=^r3P3_&|Nj(#gurh8wg3|s5Ipvx?nUCyHUA<7-u}J*EyxB5fti1^E(n3Q z|Md5VP>e3`-&=6`#lKknZu0Vf(-bY1#Z#siQHTA}SRf*ZljUL#rDR!u;CBG!$AWusiqetEj1KYJ4-WO zsxdjYHU`q(2^G3gRBlCR^_}UGVNrFh99{2Qro~!X_&1I0ZZ(|X;-!bkXYo3p2#l-S zLk;Q{q7BF3Q9dFN1NfdVDwU-J^P09xMpVy0f378S>b!V8h*0vy{0~~7w0(7$)Va~$ z9Ri3_=faO$&01`sEZ@~9ztc-bp?V>NDEa|PgGgidY+K;x$yt6uC}J+dMzH1%d<6oFeD_fJG~aNgxXm;0UhyO^{7ypqEOD8zv#(1Y}*N z2PSQN9Zo8pIkX8Y!VVq;1j~>B8GeP6qlND)(yyi~egGLoWJ(=Ry^xYRl{(^fHp?$F zLJvGxvcfu^{%YQ8LCdlEev+jR9=m&Db3`pr%GKlt*-+OUW|p!)GWu*$Z}ektynXaa zAXN!u?J9PX?lF`&7{5Enetzm`U116#r@FAID&QI6>3AUiY8xS;`B`$x+S zVr|2z&nZ`1uOZn>XWJ7-*wn4=LoK9w&ZivPB986SK1x#HB2Sxo2BcX4IUrs_#s{tY zrx2xCUb`wHxcdeI6c+=?PdLazlz|fjU?c*N-b4Uwljf!X0lqUn@R69&2q2>-2M)m) zmn=ZcHUxaU)L`T5IF?I7BgEHlb6S-n$N{jS?Z!MlKh(MRT1^dep$rKfzBV#L2N}Mn zxDRdetsC3)PEIatk2_`CZ?~xS;Xof67a}3ml|i>QwnB=o?F|juw{v5&OIT>ic7U?uzbChkAD zWNt%vp%W8lF+|Aj_iALP6pksZx;3pFH$%I4iCF8I_q)ROnJ^owmC!ZgeK-8x9XU$- zquvR9&Iy1zpxS0!R7TJ-s_6CA&84lTe$hySfp!r93jy?_u2=$=hJbaBvsR!lj7;QB znl`}hOz;C}pnFU7Ht8#Gu{L{tI37O<$Vs!#Yk0t-hc6J_!%Sh^+q8GL`tOKtalGB)}~bjNRl zKFr8j^y>ad<2An=d3nd;fLp2Y{u1*2zEp!T>*_JFSKS}g`9$w-TK$Y99OhYsl9u!% z=HzdV$99}sX-mr>WSMHcoa~bkIwtrn@N?il`BIDofGHDa7#eb?J{!DuB?u62SKH z5g|Y(L_vn6hhG9Bsc2XzkaB<$kYaOMpIG}HU+cO&UoR+xF;2gbK*)aKlh5T(3ofbU zsi`W0%$t55n);PPZuMa2=v@5UndywMp~LCU%-Q49>=w=S2@NMS+W7wVcOtodGyRayEVsiBHOsr#^B6rUh*k8 zUluL1RNwr|X}caJC)fQ+lOem|AWzcxk{{x<`Z%sOq0PM&P!UUskt5am5WuhrFKI^H@S#iEPW^^VclEZDU8id_ih~l?h&nzl znvpl`BlaRby7dE(=1t2iIe@&x$N~rfDy)#Fxol*Q-mymlO|%rSz*_()hz^}&s%~jl zYr-}j91)QMA=^u1Pp_dWh1_}6c;`R^B83x}*sr-BZ!10JDnqX@S^GUVsES;Fw{4WZgPcwBnOM|RFH8g zLPaE2ZKVG8;@|c@@Yow!Q@j%Vs4CBXLoexsFXLpqs4xc=>@+-RGyCLIo?S_|wPCV` z%Ru$nb~gXMwSnGFh06ZGAf2LauZDCA^BO!MDaQ)Er>BuaJyOEnU^p-_nOZcpO12}z ziPsd@x$u|_XzC_H-X;y#6j|JGxjpH7CXZn%4Yl?cZ;~niYRDb4I_v}kPNvUf;Oytk zXSQ^Xw2QB^TEbd#6>Q;(tJ{{CY!3Zw`O2uf6;iDI)F|q+NQ;tqd zIcweggjIqJ<7a2_VFve@<(YxWTwU|%Wa{pRI*c__b;a4lmK_t$A;)&3nlFwY&bu6O zQg@!Qr3V@dd#>GpiYdvzYUliw+ln%$y-|t|3zWXo-M*BhBm^9U+UKF8Wt-DCb1hSc zN;X#d%l2BhYBB2t7TNhEo^U*&?h!|}z+*x`buN8KgpUR{PMywf5w&k=x#GY9ZvzaV zCIQ9bLyt%{u5aYeTTEpfw}~(FP5KATzsv&PsGuZHHJb4c<{$}V<1V*g2I5%M3B+=K zXz2Tc6xUk4(qms^m zW#?hlfaj$IP>t(~l#IsEC>`EBdeE%^Oy{E>V83laaSP-P4aKd$rZj*C+0U!KC-ZCP z8zn0QK*J+vFM$SE?=6eP207);Vi|iL?$PSp+&x*oJw40l=sK+{=F!Td1K7_snpmNX zm7b*(so-`=CWi(+w`7-3EO6Hv_h0^^GF=r4wJ)%PYxax2B{{~?T~?(Bw*GC2Pf{z- z%c{vm9_+Nv?|267FntH&74T)lS~-+BW3LP@@+2;fo><>XgpV$H^n1S_6el-UeW;<+ zEQHKvIgoAY^_2=r_W^1GnL=M5L>2i2>|I*>x?HwP7NoAr3*#^RFF@;GS*ECSgvKvdEw07n%A^58w3Pi8_GS-`ZKPFdlc=b(K;@3 zd|Ew|_Cj$yAsEjn)h|NsIh-2G?RtJSaLtLmLIc(M1qbx;o>0G=Pm!!UzZ|8g__%zz z=dB6Koq*_r2Xk5ITQke;T{Q5_({KQ9KZJSy@fa%uA4DVJ__5vc=Xn-o2ZgCNV$&>{ z#ON0PK%bItLhopHK2Dt9TG@W$z1ZBQWfLcr)LFzN`jO8v6wP#Hb60490YoRxO_{a4 zpvxvjG|2_P<_!Q{pzsTI9KAR;6L z35ww9=y6HMy(pJ7Sp1gvvne(J_$At#kl8nM^+q{HC+dba8GuZo_VV47yWF|{86Qx; z%p7i6jM==aaHzK(`E3jmqEOk*85)4Y-s;Gd-{9Zo7eUGr2zef~J&BZ3XNK!G%j%`?@U#hrF<=`ici?Bk17=#u6S3lF4k`E0Xo zL0pK9`ITaV%7{=i4tJOG6`@3It;RN7b0Ks@BJ0?=IuG3{=6x0u46l(KQ2HjcXIta@ z)MO#|G{2BQa;0nWBZZ9n25x!1WE$__8Z7FPsi#cP-o!v#8yX{tJ9L*cb4qDs_byc{ ze%aM^L$oj5k!+d0fNLiwM{>oVVdsi06=Na;ODYS%eIzhuiLb5=c~Pke0iG(7U)A-J zmtl3FWgF;uFVLSY3`7jpb@C%nS+X*wbod)j@FfD2W z_f%Z%@~)^`qaIw;7W;^+U}OAb$2QfEs6oEA_T~cTT$S7-N4=MuH=xe);bBl_NEE;Q z7lrkbOPp77lrpn0uIfWOy4KZXA`8p?{0U~i;_=&l%;vu+DITolZO^y9(mt|_&voBj z1T`6aXIG=(wjK1^@l{~*F&t~Kst@PHdhhg>N28$4n;e5O21+*KKD`09AC$~cFx{Ci zco7)9?uNtB*jt8K3R?w?877bD+~c{de}@8Wkm?9W%ZfQ9 zoGcj3kc&t$-%QW#jE-phd9)i`yDnH7n23$bEy-Q#74~(JEq>&eaIFT5!!PT4BM7}7 zTB3`1{v2+2+`5z3@4RXSrGD2yB+8vBEhrDsxq2M9jp&IT;Ua`P$*N-pl8sY6D7@P! zE;$EuPkgtp53u!n-Tw9=x3y+pvzeu2(V1r7W$YGH>c|+&RI0G3Cd04Ny_IT7?cqFM#j|B+Ls4B&9(P1zm(Mh6O zl|wg?*Os}5F&$ku8lif4%T^A9CC!gwuUA7{(=<1}WcUbtoFCkd=K-E?^aFKOHUJCt z1Z9&L+ecGmJMkv|M^#n&X%H3lTstmGs|^^netuP&(A4)CO~r7-RN#7z$A6F z?1tLwGL}I&{F*Tk4W{XuFkdJP((R(FIqSQK4|k*zPV)b$L-?az8+{#Z#I!L)YL7v_|_I zy_8~DG2{sWvTF%~B(|hPmxH(hkD{j?+)~J9?PSjIjrPld5#5yDL1~&mV?NYAPS>!BbMaGhXDZ zRQr5w-s33i&G@D@yn9l5$W1Pu8}m@K|6AX>0oSw1V)GoK#Fuh+xfBGVB8EHFy>3QC z?{rw%k>nh4J_axr&-zcoa@tu9Q*F&-QI+4bidQ?#{g-W&lVRz8B1>-@y1${8UL?#0 zsbNWw@)qSfPLt{pKd0Q2pJUYz4nLMH`R7s_t}Sh;E{+U#0sXxLuBcU@cKspbqx+^$ zee62p+!9kz`_Yf4rpb=1)oMH=9Xne8^}g|N z^QcG(GLD4t>nAnE!IU;n{& zHL)YHL|%xfTlc0=?2(A*SzGdCto0|i;R;sh>qRb)nx8d-)UTHEIP>K!;8R#BL$+Ep zD*RY~L%^a-!XGz1(MK(II`xc2DkXn}nG5lpvoR;2plHG8d+ia+{9{z$b6RvD+OJe( z61cTeMZnMssQ$FMQ~!**^4keR5JMgleiQ$ugw%Eu(%e*q3s7qYgY1@sf4m?r5`eAq za5P5--0(80>^FA5x$EkE)mTN)1)`blzbl}iKvadhU7fsYwumFA0uOkuA&G;QHez0U zH#(9@Ov2t4&0$@SN*Uqm$P#IPvX5wcPi?*kS!P`Oy1HT1GsHKyGKaVJ8e@IebM8%A zXCfS36BU#WA=FEsq}rmn6W}D*eyqK0M?# zFg|R>K27`=)Zasf2>%q37g(DZP;4@x_%LQ)JEUw{hEZ#$p96!vF#d@rA{%QFlHx~J z=3`D_Eh2b}tute+wLQ53vhSw`&uUM$QG3IZyPN_30m4EEln;w3g)$yoT?aKAB|NY1 zj$bz??X5@ii)Y7vX_h{4aI;ufSJ~I^zi?a>A3E+e!4Ukt+Z3VtYrE7Rw^rCd1n*U6T`o=ZDgdn;bx05cKfU{LU=e-!;2gr z56^oxHr?~1N4f8$#WWNqlXhv!*!3pLGJI7_i@o>f8T6s=)G_C)yvKD^hor^u$-o2r zScAa>a!UueQoo)!K4G*OFyV0gV}PScT|}ltZYIt0LG!V^<-4Xw0MgmA-Ssto zQDz8!jUV#T^Z-@bw|R`FelHET5H)at4M3;znsST_<^7Lf>}{o%1ZZNN#G4))x}WKg zhssamxQ7SyO6|&QK#*JJ4ftS`&!3$tv1Y+lzp{B{Wu-($ym{(6_0#23jj^@ish3^9 zf3sYz>XJP9#i;CBs_=;A8o=Tivk|m15S>56n4;b!Q!8STw7Sy}S?9z39lh%7GOyk} zT5dMDqtiOz@>@{soGFxb-sQb7)n%EH8riWu`Vl7^{&tz!tw61jDlyjpQDKWgt$AYe-0ia2Z2BEIR``p_kr0Le1yP(vlugAN%A2?!RydS+nX9>sju1C zm0xLq8&g2fAwTn#j2lU3^79X;gl~NPeChLTQq>E`6KL8Uqstq^v2HNL$IFGAP995} zFA6;OvBDgUJZm`*qb@h%WA@b4^J^seV0vqLe6f}_Cm24dDY1FNUlFl*2e)3w*EQzx zBB+`9-F8{ZyGDteEVujD!#WKygE zwlWcfuU@Y*&{V5q;Z!x7!?T{MBT^PY+sg`1<3v@{rq!mKK*JYU#Q+Lw0CxK>WLd3= z2xyW3Hi6I6P{5TsD;vVb4||Chj28)p<$P1-%sBv1N*|4KIRi{rLIj$`uQ}M=EwD;& zrKcmo13n&T?~}ovY7yHv2x{*`a0l&A+Y7_56LnVa{`kJnafg1)b>C(!O&r$1e& zsqhf)Z{ay`V($sT7gDBiy92B zkG4IvbGQc2(KWtx3v?Wi2=RL?x|2ozDFtJVC7l&DSAAV}o#sy*nbrhMkV2pbN*(TnZNGhNh*O{5hk@5iq&8x#)qoCyABy@mp;a-VOdJ*LzY5*O4M6W%e z?mB%M){`#Spx_x1(PTSju7PjUAXOU}NStU?fs!Z|9*;)h{D}x818NfdF!_lu`;P!t zNUBWYysQ+}M|)Q`%c)^JZO+C}VrCd=T_C*|8z4&!G~kEL6S7$u13EB#(2hHGj=5Zf zlp1m*K|5ae-uJMt;ypU3Ge-Xo2tAQ5n+Hvwvn!v@;vS#$%0%an5&2ddY3{^(ybq|y z#Z4(woy_ehGPmtRQR+P5eV+KCHxJyfo&C7|#p+112 zEDbPJ36_#M^kLb&a>dra7k@}gZ=-IPd%i#X?z=s6YFQNAV81rf)Vw5}THO=1nxjDN zr*&TNzDqn`Fxl`2fTfrmW<_Si6~9beI~LV6fCwl1D4bE5%_qdJ&Rl+8;Hgs^=3Bp* zE1KwypUTgHp;^MA}})SaK-=u<8wt0nGSYCBx<_6pwj>}>F@8(?%c2_Scvys z*qKOlxJU2iRK8)p#(MqmRps&s<%E)|BZV@xMZ<(l@w@DkU*-Z9^^MlF))h6TsB0y+ zDfASo-*pvKRg@`BZlZ7$z)_uow3`FIxcKRUJZYQ+q^Qc zi#$zShbO#Arr7&4&^L&Q>^5ySd9 zz0(l4PHosi$(+Mr;j{qlv@iji0lI!)#H^-?n1kpd*6uha<9tt>z_c~Op`JL91^Csx zL#nQD#^`X<f3j00m&<%x>hn@G zOwxMTxDe&n;Nu#O^$R1xJ8bYWt*}n9s%bo5ej5cJN*9a2(sC+{kk!In`Z-2#X04e^ zP7q{Az_cAztsGq_V_sZHdt|Unf`u{bX>L8(mwAj`Q+E2MJtC-ej9M2Z21~9@KdCrat_>5#5Q{0Z>-`{d9TnzJaB(10NA2Y z8xy&ytjF;J_x%+H-z|{4ReO3%%N6po#y_ZQV5xAxr-uf7+jM2_?kx2l^D&=`k~v5j z?uWq-oSuIl*z%t*&UdmzpKj`LW$konu^N2!#qZ+yftS?v?mRp{6S0`I-qJ0(lDnOc zxSZOT^L>17;>kUWU3&K%dBlt9e)n2U_^mU!eAJe-pUsf3)O)9l!C;o-S+RxQBZr;l z5pi_juTF{yeB1aFyvk=pDe1x9k7A+SflEDYyVl9$pIU~A>1EeZ<Vd@Dym_dim6Vf>wSWPkHB`E-Ha*JTbyUf-yJe=i@x|$a=Q-l4|4GxA zHbYH(IeaZh20(CwB}TA|5DA%Pbykc*jNt*Az)&k`HXf%;DqfZo&`i!+VL-njukGvUm^vZ*d08F5q!~*pJN`jhR0&?z&{HYyI`oFg zWH3oO_KAS-XWo3G>A>*wqhbHk17{(*vKX#p!DuYUdbF`Jy@6cfY_43FYPPmN~ZqY_FAiVadVe5B}E4`AQMQk~$pZ*M4Q zGPAu@F@HA~nk>?n+G_X^Q?TgOt#AXFhhy)G?&y|3wYAxI@=(C;pBwwY6VAtaZ({F! zOLC!Wo5WkJbFCIZgx+sA7Bk13c2z~0IZI+V6wecRKq%$HF;BsrmJUHjM#S0EHxdm-9F+Dz(wNoIsAOL#7t+C0s1tnDD_WV z{<{hWy^lsZ3PqPoqP)@FeLX2|d+h>WAFEEv7JfNFQ`U%+Hjk=%E(Gi`l#%^potdh= zG+vE9lW+13n6Oy;*lKajlazdPQ0r>uAT-}2d0*F&y0h-7Gce1oW zN@t%1*<#F%OM!n(zxr5&5*x=3SB#Y^Wg zuU>6Obw>1*$cD@977xaDAuwD=>J<0f0~W0J1ZwQCUu;hd9^nFC9Jd)5C>Zo>r=EBG ze(LxQ9(7DXH!IQab;38Dx$Jawb?)i+vyBZXSI3J{)E*q~C+EUadq&#wn&;_Ab=`W& zx#sWoQvT#)4UR+(`s>~nU9yxuop((Q^F^^H(iCFr=gTEX6MDw)>}-Mk2YEt*KC(a-`C0FWd20daHdzm-uy$dK`Rl@Fio)qFaz@ zdt|;l2iy4Ef|9W+fehzmOJacMIid46ylJl{7=L^5cYS=?3+P&vCCLGRFXa7dN>lkJosE zmA^7)%0oS(V7^EFhJzQ|tZrjtvsPx~88^2@N!2I3H+Swh>eD0N*4ZaM>+UJH;N}!` zP-oA1`8`$g#MBXmY&XJF4efjTX7p-&wQbEls%?_hQZuq=<#1Quc7td`e)`z>8;_yE z<(+MsQg7x7D$c`gbnqx)r04l5uZQHWR!{ZqH94hqy*;bMbS|wSdE2T2ORt(|EHyqA z-nTu!IeXr1*8g-Y)=!~rYgpEH%w>_-_0DJkJKgrUD7B}nVWP&8dzwfEzAicMM5JJr zXw%q~YQ+h`eUu0wU+3G;UA|7y%8=CA+@#XabrTR0Bg|=R{1yAdTv6L-ghiKbf^PFL z<|9GL7#<(!RnDl71?Pf+magglEv*_6Fo2hT~*{x z84=sFRqX~NDe_^iR8#Z#nFqvP^74(fhg;t_4p`1PLzl1E^-`sONFD)w4hV0K3I@yj%@NqnN(hdqOe$TJ3-I2jv3g@x|f+G=TJtW7+ zTQhBTo~gJu>vfyXi{JuMlySBh_{tVx(%~@!@&B>LKNa3qxs6aXx7a_@$*R7$L0q&N zEp;C2oXi zQ!cVOEt!u?u-ZPQA&tocTstb4Zng!CnC2>YA~UtdIOHN-Dp!MVHy))FYwDH-$`)xj zMF^~`t;_M|y=Hj>l!PbokDYHY(i(m`5Ly?q52n4*~OPH51 zA{&(+*fYDaiXsyY12scqJRq&M2VefVL|k|u7-Ya}>QoxZ$MF87$5rv6B9=OR5!Ji9 zM1r-{xp{RT)Z$NkEr=EyC?X#j#2O30x2MWwoQ~_mO;4a63(>0YYuyF)w8mSVQduY4 zFICrO%(KwS9B?Vip4B<{Fqv$57fS~nr`Ja)Xvq*u8@lWE`<8Obtc0AEN{G+cOV*;` zt{R%#!SB{l)QM#)mP&%LE$Qtd)MMVi>r(uS^VKi{JUSJP{bx3o_^w)day{pU6K&t;P41c;nI-bSe?~UzA{@g# zs?EHPEnAX=pZTzOFErWf4M`imW6(#_eEHH#X0nLnaLd`c>ID%3®mEx|ql+&Ai+ zRRJ#=u0Q-7l_UYc<)C3m@T(%g*5&(Iet9epgL#mzOOFo-UCFUMSUTtNL?9r@nJw)0 z$L>Z8hq+{|V;_l;K!MhZ!q<2v&7NZm?23l#)WTA5%6bsW6T`S?D*2N&`L*$K3A%y% z3^7wvo$H}2OAC{2)(_io_2?OOl-QWidxR>Xc|EtYYO6W*V;MsMhb4Wt8yBy#_!iec*j26iy?t)xD1|SfGCICU4y(M!ag4gJ z|B%&SH?_z5<6G06=BtzziT#u44f2e(mXQ*l(x-VZl^jk7x+0nfTO;h0b#^t`1T7bc zos1A?XL}np2^&l$$Tch6xK@Aao@m#Pl$qlFSA50eT!#QAq({t+vRbem1j8i*s{iz#MW5rSdxV!k5-)D!hAk>?< z45Rm8PzIS#=<6Y?33GUU;;Z5#Jwze3E_fZQwa4+k%*(ghnae-G@MI?QZT-318kTPv z6Bcpp>SWL_4{)q>-rErg+1erlche2oBOPO6x#E>kS8;8o?}5=YnLt**Vyq}!?X zaYt6)6-F}cIPHkG8>-&T-Wx2J`ZChLgT0~Qu@=bQuIJKlWNZ+7n!ApvTh#vn?dJ1& zTH_icIzN`Mgzn;vsuIMcplUi&ch&c?`b!x78dJaT=gNEPYu`BLb;Cn#lQk&)f5|sc zOwhWQZUzKL6dY^}D@O~;0pH}5UEE z0$-zj-G*4Go;Ay7JN|v~$Ze$()WGMI!u+NC-?*S#)TB4iG*O)I zxZ6*l^{DGrPLl87I91o`o++meW=XBak)-&g$5SUKE0wvmOYkG;^%ZM_jr6QZr>Hro zR{*M}OhRk(>-qRNrReAnU#b`Blf$cKKPc+kJwMm4W^ETOXnS(D6lCfCL@^x@AB;$E z>NlwJ+OooJz&~5cTlKf~h#x^HsB6OO4_?&i`EqN0m4X!KkF;)VAgZmL2P8=(NN(I1 zykkAGRPaEtQ?a>Zgl!XWOLs<+8PdiH<9Ws45yI-gU1oncy8?0+3~+hpXe9ubo2RL< zL`L;a%3~i%-bHrMg9vt4V8+4&{A|vXnah`?#pgf&z#oGqk9QGx7)avy{ z$}?=C{N4!unNaz=t`T9V%ue1LBhM(Y8?_nIk@^RRU90f(v(+wYkLOFj6aCbxCkB`~_7LnV(BG)nM%f@^A78_14Q7r&$I5xTZ+N(2V z%fyN=Q&xGXnZoXQhZ-+p$PBbc4ZuNNG z{!kZMopPtI9KTFouAB@;TGNw4WqDCMF7$S&Ayr zc*xg1zv{Xq0jC#|fPE_Qt=mIw0p&|aEXa0Krvt>+N@)$f@)2_B;QIF(a?2OQ0)9(U zPKXV7Tz=U`cCf$};+RN8E5Mito`5=V`kXis!QtLrV0vUdKaR2T2@-|+@2?(-w~b`r zXV_{kyeQ2}u6|JalgNwiNPkaq!NP5yW232GeOSzva^IwXW47HsnRQ^QEZ{(Bbss)8 z(Hw*#RiTla(Ayo<+K|?3`RG2wX`FEP+s7W<7>`M^xXkY%?P|Z{oual{qVc&AErxRS zFQ>yyoe^vXrOBxE4TzmNPNDPMes5|l->!-o5mScU`N1+ga|-eJS;Y605$=C~b$i}+ zU2gp2wcpHBKSeNlM0Xyf4!lJ6nW-o#-eezpjVHz_?EK~>zSI?Ada4xgwZNJ=!3&@! zEOl&~ezl!N<_T3OF_^d=8P zmRHQoo@@9uT&sDGJYL(|eDM=~lH!R($r@j)V(7z0&B-3ccojQke4fD?)LgfhVJ=>U z26Ld3d}9&SI$E0Ya?g5>=xoj1x~T``%Gcuy1A3&Ua1G|$qH-@5Yr5NWnO&M7rZqj#Z7cC}3_S>AN9 z!KX>@x{_EEWK3s|qs^=}4q)x8x!h45X19H&gI5bPLb3ht3C*e9uG`uej++rVz8Xti zk3KWYl{}u%ba7A!DQUJ3<)YS%hGuibr^DPI^cP)fFAVpfYSjFm_0%g8!C044^;~yjm3mRH*TY|LoBq0RH(e92a{u2tnLx%HlLa zj(Y^|&(H%u8u5QtWYa$@a=FG7O`uZnWtvIbvB9AVamrX;R229(mOx%Wa%#pa&5DTG z!|bgJshRB?*Pj2hkAAzfu$6c)qM11NOig9J?>0|BE9#Un@OMK zAeZv^VxirjiTh}Beuf5OvaUY^&6mHv?!Wf#&W8lK_ck%|BUgIWwR))C)(}6FmsUpZ zerWOMia$y{LM;bOp`UqZd>!oQvRhM&&(EjzuSkG*=#8VM0`cI8a|7&bdsYgh2_+{s zd1Jk!B!*~C#)V;Gz^waQq5FRKMm(!&d_=*NBwe2Bv8BRln|S7Vr|-JR*^`y+(4FJ} zZKsHFhcOYRB3%XTI@&?i45HB3d+LvRZzoMFUK)l~28*%fFNW|slau@b5hb($xPj1* z#{zs$lUmZy@IG%4gP||ez2Ga5Hyb><;bX0^J5^F=czRNZ4}>(IubdTBoKN6>&;cwF z3R7q6p9@vza`Xjvj@*cNHddTykIVJ`p z2mG|e)Fju(2YZGTTHJhCF+7tC@{z|WlaJZ#0ya~o^Vx5v6<`*S^9RPMf`{AP$-u}r zLOs*|=x*!O(Y;b)*ZE}hHQg`nb3MaQ3O}PC8hClc3GwX78l-adJVBEK3YiNY+PCFR zyo!w{>xvQ`f?NzMCW)N+`U{KtHy!LNnj+-+)L{ei4(C0%j^^Inrc7E1GDw!1O6Jw9 zW(Y&K841;eoUXL}v2QgMlHdZ|(H0^xDxrS&?yXw}G+@LL@5wjp$@uQfuohK`f_T@M zFy3soSH6XOSev=kvYVWi!%2=uYNNiP*jc4-<-@X>1fQtZT1=`Qf$v~2TWJ!~!T$x( zK5oR!WopBY_XP0M+-cxvx#_WDktVChmAS5G>v;dbT5EqWl4;gGsKc5_vt%l{oDQ9m zU%i%+gx|gDWm&Yovaw^Yq@i)2MQ0>J@On-<%15&`2ysZ8xoQCuyAR}y=@8@gI;+%?RZ7|@B&f=ziLiPeZb z3KLHB%Jc|zSv`;QlvvF_&*ya=E8NhW;G3c#HYMOELR42*1Qq5BpvjTIuB0yBS0V}B z>p2h=BlboaTK((EuntOYH-enaZ~cra+8;?Te1=CSm9jt>2pPsJJZS*rRBm}gk<-l^ z`q}z_qLKJboac3&5y#3~yw$`fTL%Z2SGN?u%%6Ui3Gh90GM^OhZalePc^wtJdVX!G z`O^20nc<1uEy}cwDu0Td(EfSb-OA^jGC*x-ccf`Ig({q!X`8LK&*wuEWuarf@cs4m zdt*52VX=u`oewAj;|)K?;{maorH^$*rYQPnSLw*r&u-Xh8;JO%Tg9tB?OT;8NJDGd zATS5*w`=d|qWBWkzGJ}cNfQB8Qw*_y*xjj=m*nR)bO^J+>GwgwV#F_}EEqmoRxPck ztG<{oHw}mEKUv^nFlkC7$k1meIO=#$@JwZTu<4cDRpbNiWFl<{IWwJAViXPXl{y|6 z?eaUUoDb)o>1vAG+9}+K3M#xy`g%uLIwP|P6NC|YpbB~pK+hG^(EUyXj>d_<(P!by z*b2MVI*!pRT|QvzG%je9hX1&>HdS!LF+SZEeI>=52UtGru;Xm6m-RFcns=D%?$T>` z{(OUa(9M%UR8S#cn}b(kVr=0-sgm#BYgCEo0l&`MBqgm}Ps3Tg+Jg#Q$cPxA*M3yk z>HIy+HNel`@GSWG)@WJS%#U}gZjXMeqy)Chv`xra@8Ki?V^4EIO5k8qAJ1N}oVtF4 z1$gn|e*_Hy^8WI!4>_lEJ#{_K85Q#Yz)R!o8v5hEsj27oR{izg7I-gu_0zv*>U@68 z+1#RDX0!I{IgB&=eLsD>qNE(-oBksi`~Jb!vg3=7ci#EYP6u5AX%iBu z+EAee#ODMBE#JFIB?Dm5LjgQZa7hIK-evrsBYi;t8|X6rch)bZfDJ$iMTDRaLI4P< zDhL1o0002+0q4pCz;ghbS!Bu2(C;%na3agqY06qqr1^@u4ypueT0IW?jrYr!!lm$N6 W+yurHz!Yq5ZUR$NOu^=+0muTEmTZ>* literal 0 HcmV?d00001 diff --git a/app/public/data/forms/audio_item_properties.form.json b/app/public/data/forms/audio_item_properties.form.json new file mode 100644 index 00000000..7844f97a --- /dev/null +++ b/app/public/data/forms/audio_item_properties.form.json @@ -0,0 +1,40 @@ +{ + "title": "Audio Properties", + "fields": [ + { + "id": "definitions", + "displayTitle": false, + "allowCreateDelete": false, + "dataType": 14, + "subForm": { + "fields": [ + { + "id": "sounds", + "displayTitle": false, + "allowCreateDelete": false, + "objectArrayTitleFieldKey": "name", + "dataType": 15, + "subForm": { + "fields": [ + { + "id": "volume", + "title": "Volume", + "experienceType": 3, + "dataType": 3, + "minValue": 0, + "maxValue": 1, + "step": 0.05 + }, + { + "id": "weight", + "title": "Weight", + "dataType": 0 + } + ] + } + } + ] + } + } + ] +} diff --git a/app/public/data/forms/entity_sound_event.form.json b/app/public/data/forms/entity_sound_event.form.json new file mode 100644 index 00000000..0dd4001b --- /dev/null +++ b/app/public/data/forms/entity_sound_event.form.json @@ -0,0 +1,27 @@ +{ + "title": "Entity Sound Event", + "fields": [ + { + "id": "volume", + "title": "Volume", + "dataType": 3, + "minValue": 0, + "maxValue": 1, + "step": 0.05, + "experienceType": 3, + "description": "Overall adjustment to the volume level of the set of sounds" + }, + { + "id": "pitch", + "title": "Pitch", + "dataType": 3, + "description": "Overall adjustment to the pitch level of the set of sounds" + }, + { + "id": "events", + "title": "Events", + "dataType": 24, + "description": "A set of associated events." + } + ] +} diff --git a/app/public/data/forms/entity_type_resource.form.json b/app/public/data/forms/entity_type_resource.form.json index 5c72fe3b..33cf86dd 100644 --- a/app/public/data/forms/entity_type_resource.form.json +++ b/app/public/data/forms/entity_type_resource.form.json @@ -3,27 +3,31 @@ { "id": "identifier", "title": "Id", - "dataType": 2 + "dataType": 2, + "description": "A targeted identifier this visual/audio description uses." }, { "id": "materials", - "dataType": 24 + "dataType": 24, + "description": "A list of identified models that this entity uses." }, { "id": "textures", - "dataType": 24 + "dataType": 24, + "title": "Textures", + "description": "A list of identified textures that this entity uses." }, { "id": "geometry", - "dataType": 24 + "dataType": 24, + "title:": "Geometry model", + "description": "A list of identified models that this entity uses." }, { "id": "animations", - "dataType": 24 - }, - { - "id": "render_controllers", - "dataType": 17 + "dataType": 24, + "title:": "Animations", + "description": "A list of identified animation that this entity uses." } ] } diff --git a/app/public/data/forms/entity_type_resource_animations.form.json b/app/public/data/forms/entity_type_resource_animations.form.json new file mode 100644 index 00000000..d8ad7e3e --- /dev/null +++ b/app/public/data/forms/entity_type_resource_animations.form.json @@ -0,0 +1,10 @@ +{ + "fields": [ + { + "id": "animations", + "dataType": 24, + "title:": "Animations", + "description": "A list of identified animation that this entity uses." + } + ] +} diff --git a/app/public/data/forms/entity_type_resource_geometry.form.json b/app/public/data/forms/entity_type_resource_geometry.form.json new file mode 100644 index 00000000..64dac019 --- /dev/null +++ b/app/public/data/forms/entity_type_resource_geometry.form.json @@ -0,0 +1,10 @@ +{ + "fields": [ + { + "id": "geometry", + "dataType": 24, + "title:": "Geometry model", + "description": "A list of identified models that this entity uses." + } + ] +} diff --git a/app/public/data/forms/entity_type_resource_materials.form.json b/app/public/data/forms/entity_type_resource_materials.form.json new file mode 100644 index 00000000..13e84476 --- /dev/null +++ b/app/public/data/forms/entity_type_resource_materials.form.json @@ -0,0 +1,9 @@ +{ + "fields": [ + { + "id": "materials", + "dataType": 24, + "description": "A list of identified models that this entity uses." + } + ] +} diff --git a/app/public/data/forms/entity_type_resource_textures.form.json b/app/public/data/forms/entity_type_resource_textures.form.json new file mode 100644 index 00000000..777fdc2c --- /dev/null +++ b/app/public/data/forms/entity_type_resource_textures.form.json @@ -0,0 +1,10 @@ +{ + "fields": [ + { + "id": "textures", + "dataType": 24, + "title": "Textures", + "description": "A list of identified textures that this entity uses." + } + ] +} diff --git a/app/public/data/forms/render_controller_set.form.json b/app/public/data/forms/render_controller_set.form.json new file mode 100644 index 00000000..330d4b0a --- /dev/null +++ b/app/public/data/forms/render_controller_set.form.json @@ -0,0 +1,71 @@ +{ + "title": "Render Controller Set", + "fields": [ + { + "id": "render_controllers", + "displayTitle": false, + "allowCreateDelete": false, + "dataType": 14, + "subForm": { + "fields": [ + { + "id": "geometry", + "title": "Geometry", + "description": "A name or expression that describes which model to use for this item", + "dataType": 2 + }, + { + "id": "materials", + "title": "Materials", + "description": "A name or expression that expresses logic for which material to use to display this particular entity", + "dataType": 29 + }, + { + "id": "textures", + "title": "Textures", + "description": "A name or expression that expresses logic for which texture to select", + "dataType": 17 + }, + { + "id": "arrays", + "title": "Lists", + "description": "Lists of available textures, materials, and geometries that can be selected", + "dataType": 16, + "subForm": { + "fields": [ + { + "id": "textures", + "title": "Textures", + "undefinedIfEmpty": true, + "description": "Lists of textures that can be used in selection calculations", + "dataType": 28 + }, + { + "id": "materials", + "title": "Materials", + "undefinedIfEmpty": true, + "description": "Lists of materials that can be used in selection calculations", + "dataType": 28 + }, + { + "id": "geometries", + "title": "Geometries", + "undefinedIfEmpty": true, + "description": "Lists of geometries that can be used in selection calculations", + "dataType": 28 + } + ] + } + }, + { + "id": "part_visibility", + "title": "Part Visibility", + "description": "Lists of available textures, materials, and geometries that can be selected", + "objectArrayTitleFieldKey": "name", + "dataType": 24 + } + ] + } + } + ] +} diff --git a/app/public/data/forms/render_controller_set_geometry.form.json b/app/public/data/forms/render_controller_set_geometry.form.json new file mode 100644 index 00000000..c2a88839 --- /dev/null +++ b/app/public/data/forms/render_controller_set_geometry.form.json @@ -0,0 +1,36 @@ +{ + "title": "Render Controller Set", + "fields": [ + { + "id": "render_controllers", + "displayTitle": false, + "allowCreateDelete": false, + "dataType": 14, + "subForm": { + "fields": [ + { + "id": "geometry", + "title": "Geometry", + "description": "A name or expression that describes which model to use for this item", + "dataType": 2 + }, + { + "id": "arrays", + "title": "Lists", + "dataType": 16, + "subForm": { + "fields": [ + { + "id": "geometries", + "title": "Geometries", + "description": "Lists of geometries that can be used in selection calculations", + "dataType": 28 + } + ] + } + } + ] + } + } + ] +} diff --git a/app/public/data/forms/render_controller_set_materials.form.json b/app/public/data/forms/render_controller_set_materials.form.json new file mode 100644 index 00000000..1657cbf2 --- /dev/null +++ b/app/public/data/forms/render_controller_set_materials.form.json @@ -0,0 +1,36 @@ +{ + "title": "Render Controller Set", + "fields": [ + { + "id": "render_controllers", + "displayTitle": false, + "allowCreateDelete": false, + "dataType": 14, + "subForm": { + "fields": [ + { + "id": "materials", + "title": "Materials", + "description": "A name or expression that expresses logic for which material to use to display this particular entity", + "dataType": 29 + }, + { + "id": "arrays", + "title": "Lists", + "dataType": 16, + "subForm": { + "fields": [ + { + "id": "materials", + "title": "Materials", + "description": "Lists of materials that can be used in selection calculations", + "dataType": 28 + } + ] + } + } + ] + } + } + ] +} diff --git a/app/public/data/forms/render_controller_set_misc.form.json b/app/public/data/forms/render_controller_set_misc.form.json new file mode 100644 index 00000000..a5f6b71e --- /dev/null +++ b/app/public/data/forms/render_controller_set_misc.form.json @@ -0,0 +1,22 @@ +{ + "title": "Render Controller Set", + "fields": [ + { + "id": "render_controllers", + "displayTitle": false, + "allowCreateDelete": false, + "dataType": 14, + "subForm": { + "fields": [ + { + "id": "part_visibility", + "title": "Part Visibility", + "description": "Lists of available textures, materials, and geometries that can be selected", + "objectArrayTitleFieldKey": "name", + "dataType": 24 + } + ] + } + } + ] +} diff --git a/app/public/data/forms/render_controller_set_textures.form.json b/app/public/data/forms/render_controller_set_textures.form.json new file mode 100644 index 00000000..5f8dac44 --- /dev/null +++ b/app/public/data/forms/render_controller_set_textures.form.json @@ -0,0 +1,37 @@ +{ + "title": "Render Controller Set", + "fields": [ + { + "id": "render_controllers", + "displayTitle": false, + "allowCreateDelete": false, + "dataType": 14, + "subForm": { + "fields": [ + { + "id": "textures", + "title": "Textures", + "description": "A name or expression that expresses logic for which texture to select", + "dataType": 17, + "allowCreateDelete": false + }, + { + "id": "arrays", + "title": "Lists", + "dataType": 16, + "subForm": { + "fields": [ + { + "id": "textures", + "title": "Textures", + "description": "Lists of textures that can be used in selection calculations", + "dataType": 28 + } + ] + } + } + ] + } + } + ] +} diff --git a/app/public/data/gallery.json b/app/public/data/gallery.json index 05b1a4d1..8180021a 100644 --- a/app/public/data/gallery.json +++ b/app/public/data/gallery.json @@ -6,7 +6,6 @@ "gitHubOwner": "microsoft", "gitHubRepoName": "minecraft-samples", "gitHubFolder": "/addon_starter/start", - "localLogo": "blocks/barrel_bottom.png", "id": "addonStarter", "type": 0 }, @@ -16,7 +15,6 @@ "gitHubOwner": "microsoft", "gitHubRepoName": "minecraft-scripting-samples", "gitHubFolder": "/ts-starter", - "localLogo": "blocks/cartography_table_side2.png", "id": "tsStarter", "type": 0 }, @@ -26,7 +24,6 @@ "gitHubOwner": "microsoft", "gitHubRepoName": "minecraft-samples", "gitHubFolder": "/addon_starter/complete", - "localLogo": "blocks/cartography_table_side2.png", "id": "addonFull", "type": 0 }, @@ -36,7 +33,6 @@ "gitHubOwner": "microsoft", "gitHubRepoName": "minecraft-scripting-samples", "gitHubFolder": "/script-box", - "localLogo": "blocks/cartography_table_side1.png", "id": "scriptBox", "type": 0 }, @@ -46,7 +42,6 @@ "gitHubOwner": "microsoft", "gitHubRepoName": "minecraft-scripting-samples", "gitHubFolder": "/editor-script-box", - "localLogo": "map/map_background.png", "tags": ["editor"], "id": "editor-scriptBox", "type": 0 @@ -57,7 +52,6 @@ "gitHubOwner": "microsoft", "gitHubRepoName": "minecraft-scripting-samples", "gitHubFolder": "/editor-basics", - "localLogo": "map/map_background.png", "id": "editor-basics", "tags": ["editor"], "type": 0 @@ -68,7 +62,6 @@ "gitHubOwner": "microsoft", "gitHubRepoName": "minecraft-scripting-samples", "gitHubFolder": "/ts-starter-complete-cotta", - "localLogo": "blocks/glazed_terracotta_yellow.png", "id": "cottaGame", "type": 0 }, @@ -78,7 +71,6 @@ "gitHubOwner": "microsoft", "gitHubRepoName": "minecraft-scripting-samples", "gitHubFolder": "/custom-components", - "localLogo": "items/potion_bottle_damageBoost.png", "id": "registeringExampleCustomComponent", "type": 0 }, @@ -1052,7 +1044,6 @@ "description": "The tall and mysterious Enderman is a neutral mob that can be seen during late nights, standing in the distance while staring blindly into the horizon before teleporting away.", "gitHubOwner": "mojang", "gitHubRepoName": "bedrock-samples", - "localLogo": "entity/enderman/enderman.tga", "id": "enderman", "type": 4, "logoLocation": { "x": 28, "y": 46, "width": 8, "height": 8, "imageWidth": 64 }, @@ -1122,7 +1113,6 @@ "description": "Sheep can provide you with wool, which is a useful material in many crafting recipes and can be dyed into different colors.", "gitHubOwner": "mojang", "gitHubRepoName": "bedrock-samples", - "localLogo": "entity/sheep/sheep.tga", "id": "sheep", "type": 4, "logoLocation": { "x": 28, "y": 46, "width": 8, "height": 8, "imageWidth": 64 }, diff --git a/app/reslist/packs-preview.resources.json b/app/reslist/packs-preview.resources.json new file mode 100644 index 00000000..eb15a124 --- /dev/null +++ b/app/reslist/packs-preview.resources.json @@ -0,0 +1,16 @@ +{ + "url": "https://github.com/Mojang/bedrock-samples/archive/acc158ace8d048413c6be79c26584914643c9a12.zip", + "ignoreFirstFolder": true, + "exclude": [ + "documentation/", + "scripts/", + "ui/", + "gui/", + "painting/", + "persona_thumbnails/", + "trading/", + "pack_icon.png", + ".github", + "manifest.json" + ] +} diff --git a/app/reslist/packs.resources.json b/app/reslist/packs.resources.json index 087b61e1..9ea30f26 100644 --- a/app/reslist/packs.resources.json +++ b/app/reslist/packs.resources.json @@ -1,5 +1,5 @@ { - "url": "https://github.com/Mojang/bedrock-samples/archive/14404383059147f3f19aae34836c1e8f209bd2df.zip", + "url": "https://github.com/Mojang/bedrock-samples/archive/6e0daa70a8c94130fd04f65295e672f99d7adc6d.zip", "ignoreFirstFolder": true, "exclude": [ "documentation/", diff --git a/app/reslist/samples.resources.json b/app/reslist/samples.resources.json index da53415b..e630fe3f 100644 --- a/app/reslist/samples.resources.json +++ b/app/reslist/samples.resources.json @@ -1,5 +1,5 @@ { - "url": "https://github.com/microsoft/minecraft-samples/archive/4d33c13deb7c862d775905c2336da5c2f4c52285.zip", + "url": "https://github.com/microsoft/minecraft-samples/archive/fd42374a119c38c7cdb813f22b8594f1c6449d71.zip", "replaceFirstFolderWith": "minecraft-samples-main", "exclude": [ "add_entity_robot/", diff --git a/app/reslist/schemas.resources.json b/app/reslist/schemas.resources.json index 4842efc1..f6c09c58 100644 --- a/app/reslist/schemas.resources.json +++ b/app/reslist/schemas.resources.json @@ -1,5 +1,5 @@ { - "url": "https://github.com/Blockception/Minecraft-bedrock-json-schemas/archive/67326c3e50d136483444e82d00fecb0a570c9a64.zip", + "url": "https://github.com/Blockception/Minecraft-bedrock-json-schemas/archive/31ad665f0774ad56449164ff29ff9a96c0b7e694.zip", "replaceFirstFolderWith": "schemas", "exclude": [ ".git", diff --git a/app/reslist/scriptsamples.resources.json b/app/reslist/scriptsamples.resources.json index 9634deb1..66cd10dd 100644 --- a/app/reslist/scriptsamples.resources.json +++ b/app/reslist/scriptsamples.resources.json @@ -1,5 +1,5 @@ { - "url": "https://github.com/microsoft/minecraft-scripting-samples/archive/0a9509f18ad476e317ea4427049000e583ce7d2e.zip", + "url": "https://github.com/microsoft/minecraft-scripting-samples/archive/9a961de8fd2770410d84d0ea7abb3b23512d7565.zip", "replaceFirstFolderWith": "minecraft-scripting-samples-main", "exclude": [] } diff --git a/app/src/UX/App.tsx b/app/src/UX/App.tsx index 81e44425..9dec5457 100644 --- a/app/src/UX/App.tsx +++ b/app/src/UX/App.tsx @@ -13,6 +13,7 @@ import CartoApp from "../app/CartoApp"; import StorageUtilities from "../storage/StorageUtilities"; import { ThemeInput } from "@fluentui/react-northstar"; import { CartoEditorViewMode } from "../app/ICartoData"; +import MCWorld from "../minecraft/MCWorld"; import ProjectItem from "../app/ProjectItem"; import ZipStorage from "../storage/ZipStorage"; import ProjectUtilities from "../app/ProjectUtilities"; @@ -22,6 +23,7 @@ import ProjectEditorUtilities, { ProjectEditorMode } from "./ProjectEditorUtilit import HttpStorage from "../storage/HttpStorage"; import { ProjectImportExclusions } from "../app/ProjectExporter"; import Database from "../minecraft/Database"; +import IProjectSeed from "../app/IProjectSeed"; export enum NewProjectTemplateType { empty, @@ -102,7 +104,7 @@ export default class App extends Component { } public async _loadLocalStorageProject() { - if (CartoApp.carto === undefined || !CartoApp.carto.isLoaded) { + if (!CartoApp.carto || !CartoApp.carto.isLoaded) { return; } @@ -200,7 +202,7 @@ export default class App extends Component { } private _handleHashChange() { - const result = this._getStateFromUrlWithSideEffects(false); + const result = this._getStateFromUrlWithSideEffects(true); if (result && this._isMountedInternal) { this.setState({ @@ -231,7 +233,6 @@ export default class App extends Component { const isPersisted = await WebUtilities.getIsPersisted(); const newState = this._getStateFromUrlWithSideEffects(); - let nextMode = this.state.mode; if (newState) { @@ -242,13 +243,16 @@ export default class App extends Component { this._updateWindowTitle(nextMode, this.state.activeProject); - this.setState({ + const newComponentState = { + carto: CartoApp.carto, mode: nextMode, isPersisted: isPersisted, activeProject: this.state.activeProject, hasBanner: this.state.hasBanner, visualSeed: this.state.visualSeed, - }); + }; + + this.setState(newComponentState); } private _getStateFromUrlWithSideEffects(dontProcessQueryStrings?: boolean): AppState | undefined { @@ -322,7 +326,7 @@ export default class App extends Component { const segments = commandData.split("/"); if (segments.length === 1) { - this._handleNewProject("Project", NewProjectTemplateType.gameTest); + this._handleNewProject({ name: "Project" }, NewProjectTemplateType.gameTest); return { mode: AppMode.project, @@ -334,7 +338,7 @@ export default class App extends Component { const segments = commandData.split("/"); if (segments.length === 1) { - this._handleNewProject("Project", NewProjectTemplateType.gameTest); + this._handleNewProject({ name: "Project" }, NewProjectTemplateType.gameTest); return { mode: AppMode.codeToolbox, @@ -406,7 +410,7 @@ export default class App extends Component { const segments = CartoApp.modeParameter.split("/"); if (segments.length === 2) { - this._handleNewProject("Project", NewProjectTemplateType.gameTest); + this._handleNewProject({ name: "Project" }, NewProjectTemplateType.gameTest); selectedItem = segments[1]; } @@ -455,20 +459,24 @@ export default class App extends Component { } private async _handleNewProject( - newProjectName: string, + newProjectSeed: IProjectSeed, newProjectType: NewProjectTemplateType, - newProjectCreator?: string, - newProjectShortName?: string, newProjectPath?: string, additionalFilePath?: string, additionalFile?: File, editorStartMode?: ProjectEditorMode, startInReadOnly?: boolean ) { - if (CartoApp.carto === undefined || !CartoApp.carto.isLoaded) { + if (!CartoApp.carto || !CartoApp.carto.isLoaded) { return; } + let newProjectName = newProjectSeed.name; + + if (!newProjectName) { + newProjectName = "New Project"; + } + if (additionalFile && additionalFilePath && this.state && this._isMountedInternal) { this._doLog( "Loading " + newProjectName + (additionalFilePath.length > 2 ? " from " + additionalFilePath : "") + "..." @@ -537,14 +545,13 @@ export default class App extends Component { } private async _handleNewProjectFromFolder(folderPath: string) { - if (CartoApp.carto === undefined || !CartoApp.carto.isLoaded) { + if (!CartoApp.carto || !CartoApp.carto.isLoaded) { return; } const newProject = await CartoApp.carto.ensureProjectForFolder(folderPath); newProject.save(); - CartoApp.carto.save(); this._setProject(newProject); @@ -564,7 +571,7 @@ export default class App extends Component { } private async _handleNewProjectFromFolderInstance(folder: IFolder, name?: string, isDocumentationProject?: boolean) { - if (CartoApp.carto === undefined || !CartoApp.carto.isLoaded) { + if (!CartoApp.carto || !CartoApp.carto.isLoaded) { return; } @@ -585,7 +592,7 @@ export default class App extends Component { } private async _ensureProjectFromGalleryId(galleryId: string, updateContent?: string) { - if (CartoApp.carto === undefined || !CartoApp.carto.isLoaded) { + if (CartoApp.carto === undefined) { return; } @@ -600,10 +607,6 @@ export default class App extends Component { } private async _ensureProjectFromGallery(project: IGalleryItem, updateContent?: string) { - if (CartoApp.carto === undefined || !CartoApp.carto.isLoaded) { - return; - } - this._ensureProjectFromGitHubTemplate( project.title, project.gitHubOwner, @@ -635,12 +638,7 @@ export default class App extends Component { ) { const carto = CartoApp.carto; - if ( - this.state === null || - carto === undefined || - this._loadingMessage !== undefined || - (window.document.title && window.document.title.indexOf("Loading") >= 0) - ) { + if (this.state === null || carto === undefined || this._loadingMessage !== undefined) { return; } @@ -711,18 +709,17 @@ export default class App extends Component { sampleSet, sampleId, updateContent, - description + { + name: description, + } ); } - private async _newProjectFromGallery( - galleryItem: IGalleryItem, - name?: string, - creator?: string, - shortName?: string, - description?: string - ) { - if (CartoApp.carto === undefined || !CartoApp.carto.isLoaded) { + private async _newProjectFromGallery(newProjectSeed: IProjectSeed) { + const galleryItem = newProjectSeed.galleryProject; + + if (!galleryItem) { + Log.unexpectedUndefined("ANPFG"); return; } @@ -740,10 +737,7 @@ export default class App extends Component { ? galleryItem.id : undefined, undefined, - name, - creator, - shortName, - description, + newProjectSeed, galleryItem.type ); } @@ -760,10 +754,7 @@ export default class App extends Component { sampleSet?: string, sampleId?: string, updateContent?: string, - suggestedName?: string, - suggestedCreator?: string, - suggestedShortName?: string, - description?: string, + projectSeed?: IProjectSeed, galleryType?: GalleryItemType ) { const carto = CartoApp.carto; @@ -772,6 +763,11 @@ export default class App extends Component { return; } + let suggestedCreator = projectSeed?.creator; + let suggestedName = projectSeed?.name; + let suggestedShortName = projectSeed?.shortName; + let description = projectSeed?.description; + if (suggestedCreator === undefined) { suggestedCreator = carto.creator; } @@ -877,15 +873,16 @@ export default class App extends Component { newProject.originalSampleId = sampleId; newProject.creator = suggestedCreator; newProject.shortName = suggestedShortName; + newProject.track = projectSeed?.track; if ((galleryType === GalleryItemType.entityType || galleryType === GalleryItemType.blockType) && galleryId) { const galleryProject = await carto.getGalleryProjectById(galleryId); if (galleryProject) { if (galleryType === GalleryItemType.entityType) { - await ProjectUtilities.addEntityTypeFromGallery(newProject, galleryProject); + await ProjectUtilities.addEntityTypeFromGallery(newProject, galleryProject, suggestedName); } else if (galleryType === GalleryItemType.blockType) { - await ProjectUtilities.addBlockTypeFromGallery(newProject, galleryProject); + await ProjectUtilities.addBlockTypeFromGallery(newProject, galleryProject, suggestedName); } } } @@ -974,6 +971,35 @@ export default class App extends Component { }); } + private async _newProjectFromMinecraftFolder(folderType: LocalFolderType, folder: IFolder) { + if (!CartoApp.carto || !CartoApp.carto.isLoaded) { + return; + } + + let proposedProjectName = StorageUtilities.getBaseFromName(folder.fullPath); + const mcw = await MCWorld.ensureMCWorldOnFolder(folder); + + if (mcw && mcw.name) { + proposedProjectName = mcw.name; + } + + const newProject = await CartoApp.carto.ensureProjectForFolder(folder.fullPath, proposedProjectName); + + newProject.save(); + CartoApp.carto.save(); + + this._updateWindowTitle(AppMode.project, newProject); + this.initProject(newProject); + + this.setState({ + mode: AppMode.project, + isPersisted: this.state.isPersisted, + hasBanner: this.state.hasBanner, + visualSeed: this.state.visualSeed, + activeProject: newProject, + }); + } + private async _ensureProjectFromMinecraftFolder(folderType: LocalFolderType, folder: IFolder, isReadOnly: boolean) { const carto = CartoApp.carto; @@ -1093,24 +1119,16 @@ export default class App extends Component { window.document.title = title; } - private _handleProjectGalleryCommand( - command: GalleryProjectCommand, - project: IGalleryItem, - name?: string, - creator?: string, - shortName?: string, - description?: string - ) { + private _handleProjectGalleryCommand(command: GalleryProjectCommand, projectSeed: IProjectSeed) { switch (command) { case GalleryProjectCommand.newProject: case GalleryProjectCommand.projectSelect: - this._newProjectFromGallery(project, name, creator, shortName, description); + this._newProjectFromGallery(projectSeed); break; case GalleryProjectCommand.ensureProject: - this._ensureProjectFromGallery(project); - break; - case GalleryProjectCommand.forkProject: - alert("Forking projects is not implemented... yet."); + if (projectSeed.galleryProject) { + this._ensureProjectFromGallery(projectSeed.galleryProject); + } break; } } @@ -1258,8 +1276,8 @@ export default class App extends Component { } else if (this.state.mode === AppMode.home) { interior = ( ; + carto: Carto; + file?: IFile; + project: Project; + setActivePersistable?: (persistObject: IPersistable) => void; +} + +interface IAudioItemPropertiesState { + fileToEdit?: IFile; + isLoaded: boolean; + soundDefinitionCatalog: SoundDefinitionCatalogDefinition | undefined; + soundCatalog: SoundCatalogDefinition | undefined; + formData: IAudioItemFormData | undefined; +} + +interface IAudioItemFormData { + definitions: { [name: string]: ISoundDefinition }; +} + +export default class AudioItemProperties extends Component { + constructor(props: IAudioItemPropertiesProps) { + super(props); + + this._definitionLoaded = this._definitionLoaded.bind(this); + this._handleDataFormPropertyChange = this._handleDataFormPropertyChange.bind(this); + + this.state = { + fileToEdit: props.file, + isLoaded: false, + soundDefinitionCatalog: undefined, + soundCatalog: undefined, + formData: undefined, + }; + + this._updateManager(true); + } + + static getDerivedStateFromProps(props: IAudioItemPropertiesProps, state: IAudioItemPropertiesState) { + if (state === undefined || state === null) { + state = { + fileToEdit: props.file, + isLoaded: false, + soundDefinitionCatalog: undefined, + soundCatalog: undefined, + formData: undefined, + }; + + return state; + } + + if (props.file !== state.fileToEdit) { + state.fileToEdit = props.file; + state.isLoaded = false; + + return state; + } + + return null; // No change to state + } + + componentDidMount(): void { + this._updateManager(true); + + if (this.props.setActivePersistable) { + this.props.setActivePersistable(this); + } + } + + componentDidUpdate(prevProps: IAudioItemPropertiesProps, prevState: IAudioItemPropertiesState) { + if (prevProps.file !== this.props.file) { + this.setState({ + soundCatalog: this.state.soundCatalog, + soundDefinitionCatalog: this.state.soundDefinitionCatalog, + formData: undefined, + }); + + this._updateManager(true); + } + } + + async _updateManager(setState: boolean) { + await Database.ensureFormLoaded("audio_item_properties"); + + this._doUpdate(setState); + } + + _definitionLoaded(defA: SpawnRulesBehaviorDefinition, defB: SpawnRulesBehaviorDefinition) { + this._doUpdate(true); + } + + async _doUpdate(setState: boolean) { + let soundDefinitionCat = await ProjectItemManager.ensureSoundDefinitionCatalogDefinition(this.props.project); + let soundCat = await ProjectItemManager.ensureSoundCatalogDefinition(this.props.project); + + const formData: IAudioItemFormData = { + definitions: {}, + }; + + if (this.props.file && soundDefinitionCat) { + let matches = soundDefinitionCat.getSoundDefinitionMatchesByPath(this.props.file); + + if (matches) { + let keyCount = 0; + + for (const key in matches) { + if (key) { + keyCount++; + } + } + + if (keyCount === 0) { + soundDefinitionCat.ensureDefintionForFile(this.props.project, this.props.file); + + const nextMatches = soundDefinitionCat.getSoundDefinitionMatchesByPath(this.props.file); + + if (nextMatches) { + matches = nextMatches; + } + } + + formData.definitions = matches; + } + } + + if (setState) { + this.setState({ + fileToEdit: this.state.fileToEdit, + isLoaded: true, + soundDefinitionCatalog: soundDefinitionCat, + soundCatalog: soundCat, + formData: formData, + }); + } else { + this.state = { + fileToEdit: this.props.file, + isLoaded: true, + soundDefinitionCatalog: soundDefinitionCat, + soundCatalog: soundCat, + formData: formData, + }; + } + } + + async persist() { + if (this.state !== undefined && this.state.soundDefinitionCatalog) { + this.state.soundDefinitionCatalog.persist(); + } + + if (this.state !== undefined && this.state.soundCatalog) { + this.state.soundCatalog.persist(); + } + } + + _handleDataFormPropertyChange(props: IDataFormProps, property: IProperty, newValue: any) { + if (typeof newValue === "object") { + } + } + + render() { + if ( + this.state === null || + !this.state.soundCatalog || + !this.state.soundDefinitionCatalog || + Database.uxCatalog === null + ) { + return
Loading...
; + } + + const form = Database.getForm("audio_item_properties"); + + return ( +
+
+
+ +
+
+
+ ); + } +} diff --git a/app/src/UX/AudioManager.css b/app/src/UX/AudioManager.css new file mode 100644 index 00000000..86a8e4c5 --- /dev/null +++ b/app/src/UX/AudioManager.css @@ -0,0 +1,354 @@ +.aum-outer { + image-rendering: pixelated; +} + +.aum-image { + padding: 6px; + width: 100%; + height: 100%; + image-rendering: pixelated; + background-repeat: no-repeat; + background-size: contain; +} + +.aum-float { + position: absolute; + margin: 8px; + z-index: 100; +} + +.aum-status { + padding-left: 7px; + margin-top: 10px; + min-height: 20px; +} + +.aum-float BUTTON { + padding-left: 0px; + padding-right: 0px; + width: 36px; + min-width: inherit; +} + +.playlist { + margin: 5px 0px 5px 0px; +} + +.playlist *, +.playlist ::after, +.playlist ::before { + box-sizing: border-box; +} + +.playlist .btn:not(:disabled) { + cursor: pointer; +} + +.playlist .fas { + font-style: normal; + font-size: 16pt; +} +.playlist .btn-group-lean { + display: flex; + align-items: center; + justify-content: space-between; +} + +.playlist .btn-group-lean button { + margin-left: 6px; + margin-right: 6px; + margin-top: 4px; + height: 24px; +} + +.playlist .fa-volume-up::before { + content: "Vol"; + font-size: small; + position: relative; + top: -3px; + font-family: inherit; +} + +.playlist .fa-caret-up::before { + content: "\25B2"; + font-size: small; + position: relative; + top: -3px; + font-family: inherit; +} + +.playlist .fa-caret-down::before { + content: "\25BC"; + font-size: small; + position: relative; + top: -3px; + font-family: inherit; +} + +.playlist .fa-times::before { + content: "\0078"; + font-family: inherit; + line-height: 0; + position: relative; + top: -2px; +} + +.playlist .btn { + display: inline-block; + width: 60px; + text-align: center; + vertical-align: middle; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.playlist .btn-outline-dark { + border-color: var(--wp-mute-solo-color); +} + +.playlist .btn-outline-dark:hover { + background-color: var(--wp-mute-solo-color); + border-color: var(--wp-mute-solo-color); +} + +.playlist .btn-outline-dark:active:focus, +.playlist .btn-outline-dark:focus { + box-shadow: 0 0 0 0.2rem var(--wp-mute-solo-focus-color); +} + +.playlist .btn-xs { + padding: 0.25rem 0.4rem; + font-size: 0.875rem; + line-height: 0.5; +} + +.playlist .btn-group { + margin-top: 6px; + margin-bottom: 6px; +} + +.playlist .btn-group button { + padding: 8px; + margin-left: 4px; + margin-right: 4px; +} + +.playlist .btn-group > .btn:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.playlist .btn-group > .btn:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.playlist .playlist-time-scale { + height: 30px; +} + +.playlist .state-cursor, +.playlist .state-select { + cursor: text; +} + +.playlist .state-fadein { + cursor: w-resize; +} + +.playlist .state-fadeout { + cursor: e-resize; +} + +.playlist .state-shift { + cursor: ew-resize; +} + +.playlist .channel-wrapper.silent .channel { + opacity: 0.3; +} + +.playlist .controls { + text-align: center; +} + +.playlist .playlist-tracks { + border-top: solid 1px black; + border-bottom: solid 1px black; + padding: 4px; +} + +.playlist .waveform { + background-color: #3c8527; +} + +.playlist-dark .controls { + background-color: #312f2dd0; +} + +.playlist .controls .track-header { + overflow: hidden; + height: 26px; + display: flex; + align-items: center; + justify-content: space-between; + margin: 5px 4px 5px 4px; + padding: 8px 0px 8px 0px; + font-size: 0.75rem; +} + +.playlist .controls .track-header button { + width: 60px; + height: 24px; + display: flex; + align-items: center; + justify-content: center; +} + +.playlist .controls .track-header span { + margin: 10px; + max-width: 70px; +} + +.playlist .cursor { + background: "purple"; +} + +.playlist .selection.point { + background: "red"; +} + +.playlist .selection.segment { + background: "red"; +} + +.playlist .channel { + background: "red"; +} + +.playlist .channel-progress { + background: "red"; +} + +.playlist .cursor { + background: "red"; +} + +.playlist .controls label { + width: 100%; + display: flex; + font-size: small; + justify-content: space-between; + font-size: inherit; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + transform: translate(0, 0); + padding: 0 1rem; + margin-bottom: 0.2rem; +} + +.playlist .controls label:before { + padding-right: 5px; + -moz-osx-font-smoothing: grayscale; +} + +.playlist .controls label:after { + padding-left: 5px; +} + +.playlist .controls label.volume:before { + content: "-"; +} + +.playlist .controls label.volume:after { + content: "+"; +} + +.playlist .controls label.stereopan:before { + content: "L"; +} + +.playlist .controls label.stereopan:after { + content: "R"; +} + +.playlist .controls input[type="range"] { + display: inline-block; + width: 75%; + accent-color: #3c8527; +} + +.playlist .controls input[type="range"]::-webkit-slider-runnable-track { + height: 5px; + border: none; + border-radius: 0px; +} + +.playlist .controls input[type="range"]::-moz-range-track { + height: 5px; + border: none; + border-radius: 0px; +} + +.playlist .controls input[type="range"]::-webkit-slider-thumb { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + border: none; + height: 12px; + width: 12px; + border-radius: 0%; + margin-top: -5px; + cursor: ew-resize; +} + +.playlist .volume-lean { + height: 30px; +} + +.playlist .controls input[type="range"]::-moz-range-thumb { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + border: none; + height: 12px; + width: 12px; + border-radius: 0%; + margin-top: -5px; + cursor: ew-resize; +} + +.playlist .controls input[type="range"]:focus { + outline: none; +} + +.aum-bin { + overflow-y: auto; +} +.aum-propTitle { + padding-left: 40px; +} + +.aum-recordbutton { + color: rgb(201, 39, 39); +} + +.playlist .selection.point { + background: #42932b; +} +.playlist .selection.segment { + background: rgba(0, 0, 0, 0.1); +} + +.playlist .channel { + background: #3c8527; +} +.playlist .channel-progress { + background: #55bf38; +} +.playlist .cursor { + background: black; +} diff --git a/app/src/UX/AudioManager.tsx b/app/src/UX/AudioManager.tsx new file mode 100644 index 00000000..7b242528 --- /dev/null +++ b/app/src/UX/AudioManager.tsx @@ -0,0 +1,841 @@ +import { Component } from "react"; +import IFile from "../storage/IFile"; +import "./AudioManager.css"; +import React from "react"; +import IPersistable from "./IPersistable"; +import Carto from "../app/Carto"; +import { ThemeInput, Toolbar } from "@fluentui/react-northstar"; +import WaveformPlaylist, { IWaveformEventEmitter, WaveformPlaylistObj } from "waveform-playlist"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { + faBackward, + faCircle, + faForward, + faICursor, + faMagnifyingGlassMinus, + faMagnifyingGlassPlus, + faMousePointer, + faPause, + faPlay, + faStop, +} from "@fortawesome/free-solid-svg-icons"; +import StorageUtilities from "../storage/StorageUtilities"; +import { faEdit } from "@fortawesome/free-regular-svg-icons"; +import CartoApp, { CartoThemeStyle } from "../app/CartoApp"; +import Project from "../app/Project"; +import AudioItemProperties from "./AudioItemProperties"; + +export enum AudioManagerMode { + view = 0, + edit = 1, + record = 2, +} + +interface IAudioManagerProps { + file?: IFile; + theme: ThemeInput; + initialContent?: Uint8Array; + placeholder?: string; + visualSeed?: number; + setActivePersistable?: (persistObject: IPersistable) => void; + heightOffset?: number; + readOnly: boolean; + carto: Carto; + project: Project; + onUpdateContent?: (newContent: Uint8Array) => void; + onCommit?: (newContent: Uint8Array) => void; +} + +interface IAudioManagerState { + fileToEdit?: IFile; + content?: Uint8Array; + mode: AudioManagerMode; +} + +interface IViewState { + startTime?: number; + endTime?: number; +} + +export default class AudioManager extends Component { + private rootElt: React.RefObject; + private statusElt: React.RefObject; + private viewAudioElement: HTMLDivElement | null = null; + private viewPlaylist: WaveformPlaylistObj | null = null; + private recordPlaylist: WaveformPlaylistObj | null = null; + private editAudioElement: HTMLDivElement | null = null; + private recordAudioElement: HTMLDivElement | null = null; + private editPlaylist: WaveformPlaylistObj | null = null; + private coreEditFilePath: string | undefined = undefined; + private coreViewFilePath: string | undefined = undefined; + private _isPersisting: boolean = false; + private _pendingPersistRequests: ((value: unknown) => void)[] = []; + private _activeEditorPersistable?: IPersistable; + private _setToViewAfterPersist = false; + + private viewState: IViewState = {}; + private editState: IViewState = {}; + + private canRecord = false; + private _editorThumbPrint: string = ""; + private _viewThumbPrint: string = ""; + private activeEventEmitter: IWaveformEventEmitter | undefined = undefined; + private editEventEmitter: IWaveformEventEmitter | undefined = undefined; + private recordEventEmitter: IWaveformEventEmitter | undefined = undefined; + + constructor(props: IAudioManagerProps) { + super(props); + this.rootElt = React.createRef(); + this.statusElt = React.createRef(); + + this._toggleEdit = this._toggleEdit.bind(this); + this.pause = this.pause.bind(this); + this.play = this.play.bind(this); + this.recordAdd = this.recordAdd.bind(this); + this.rewind = this.rewind.bind(this); + this.zoomIn = this.zoomIn.bind(this); + this.zoomOut = this.zoomOut.bind(this); + this.stop = this.stop.bind(this); + this.stopRecording = this.stopRecording.bind(this); + this.persist = this.persist.bind(this); + this.persistRecord = this.persistRecord.bind(this); + this.fastForward = this.fastForward.bind(this); + this.setCursorStyle = this.setCursorStyle.bind(this); + this.setSelectionStyle = this.setSelectionStyle.bind(this); + this.updateViewSelect = this.updateViewSelect.bind(this); + this.updateEditSelect = this.updateEditSelect.bind(this); + this._audioRenderingComplete = this._audioRenderingComplete.bind(this); + this._recordAudioRenderingComplete = this._recordAudioRenderingComplete.bind(this); + this._handleNewChildPersistable = this._handleNewChildPersistable.bind(this); + this.state = { + fileToEdit: props.file, + content: this.props.initialContent, + mode: AudioManagerMode.view, + }; + } + + _handleNewChildPersistable(newPersistable: IPersistable) { + this._activeEditorPersistable = newPersistable; + } + + pause() { + if (this.state.mode === AudioManagerMode.view && this.viewPlaylist) { + this.viewPlaylist.pause(); + } else if (this.state.mode === AudioManagerMode.edit && this.editPlaylist) { + this.editPlaylist.pause(); + } + } + + play() { + if (this.state.mode === AudioManagerMode.view && this.viewPlaylist) { + this.viewPlaylist.play(); + } else if (this.state.mode === AudioManagerMode.edit && this.editPlaylist) { + this.editPlaylist.play(); + } + } + + zoomIn() { + if (this.activeEventEmitter) { + this.activeEventEmitter.emit("zoomin"); + } + } + + zoomOut() { + if (this.activeEventEmitter) { + this.activeEventEmitter.emit("zoomout"); + } + } + + setCursorStyle() { + if (this.activeEventEmitter) { + this.activeEventEmitter.emit("statechange", "cursor"); + } + } + + setSelectionStyle() { + if (this.activeEventEmitter) { + this.activeEventEmitter.emit("statechange", "select"); + } + } + + async recordAdd() { + this.setState({ + fileToEdit: this.state.fileToEdit, + content: this.state.content, + mode: AudioManagerMode.record, + }); + + await this._addAudioInterior(AudioManagerMode.record); + + if (this.recordPlaylist) { + if (this.canRecord) { + this.recordPlaylist.record(); + } else { + const getUserMedia = + (navigator as any).getUserMedia || + (navigator as any).webkitGetUserMedia || + (navigator as any).mozGetUserMedia || + (navigator as any).msGetUserMedia; + + const playlist = this.recordPlaylist; + + const me = this; + if (navigator.mediaDevices) { + navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => { + playlist.initRecorder(stream); + me.canRecord = true; + playlist.record(); + }); + } else if (getUserMedia && "MediaRecorder" in window) { + getUserMedia({ audio: true }, (stream: any) => { + playlist.initRecorder(stream); + me.canRecord = true; + playlist.record(); + }); + } + } + } + } + + rewind() { + if (this.state.mode === AudioManagerMode.view && this.viewPlaylist) { + this.viewPlaylist.rewind(); + } else if (this.state.mode === AudioManagerMode.edit && this.editPlaylist) { + this.editPlaylist.rewind(); + } + } + + stop() { + if (this.state.mode === AudioManagerMode.view && this.viewPlaylist) { + this.viewPlaylist.stop(); + } else if (this.state.mode === AudioManagerMode.edit && this.editPlaylist) { + this.editPlaylist.stop(); + } + } + + stopRecording() { + if (this.state.mode === AudioManagerMode.record && this.recordPlaylist) { + this.recordPlaylist.stop(); + } + + this.persistRecord(); + } + + fastForward() { + if (this.state.mode === AudioManagerMode.view && this.viewPlaylist) { + this.viewPlaylist.fastForward(); + } else if (this.state.mode === AudioManagerMode.edit && this.editPlaylist) { + this.editPlaylist.fastForward(); + } + } + + componentDidMount() { + this._addAudioInterior(); + + if (this.props.setActivePersistable) { + this.props.setActivePersistable(this); + } + } + + async getAudioWorkingFolder() { + if (this.props.file) { + const audioWorkingFolder = await this.props.project.ensureWorkingFolderForFile(this.props.file); + + if (audioWorkingFolder) { + await audioWorkingFolder.load(); + + if ( + audioWorkingFolder.fileCount === 0 && + this.props.file.content && + this.props.file.content instanceof Uint8Array + ) { + const coreFile = audioWorkingFolder.ensureFile(this.props.file.name); + coreFile.setContent(this.props.file.content); + } + } + + return audioWorkingFolder; + } + + return undefined; + } + + async _addAudioInterior(newMode?: AudioManagerMode) { + if (newMode === undefined) { + newMode = this.state.mode; + } + + if (this.rootElt !== null && this.rootElt.current !== null) { + if (this.props.file) { + await this.props.file.loadContent(); + + if (this.props.file.content && this.props.file.content instanceof Uint8Array) { + const blob = new Blob([this.props.file.content], { type: "audio/x-mpeg-3" }); + + while (this.rootElt.current && this.rootElt.current.childNodes.length > 0) { + this.rootElt.current.removeChild(this.rootElt.current.childNodes[0]); + } + + if (newMode === AudioManagerMode.view) { + let thumbPrint = this.props.file.content.length + String(this.props.file.latestModified); + + if ( + this.viewAudioElement && + thumbPrint === this._viewThumbPrint && + this.viewPlaylist && + this.coreViewFilePath === this.props.file.extendedPath + ) { + this.rootElt.current.appendChild(this.viewAudioElement); + this.activeEventEmitter = this.viewPlaylist.getEventEmitter(); + } else { + this.viewAudioElement = document.createElement("DIV") as HTMLDivElement; + this.rootElt.current.appendChild(this.viewAudioElement); + this.coreViewFilePath = this.props.file.extendedPath; + this._viewThumbPrint = thumbPrint; + + this.viewPlaylist = WaveformPlaylist({ + ac: new (window.AudioContext || (window as any).webkitAudioContext)(), + samplesPerPixel: 512, + mono: true, + timescale: true, + waveHeight: 240, + container: this.viewAudioElement, + isAutomaticScroll: true, + state: "cursor", + seekStyle: "line", + colors: { + waveOutlineColor: "#E0EFF1", + timeColor: "grey", + fadeColor: "black", + }, + controls: { + show: true, + width: 180, + widgets: { + muteOrSolo: false, + volume: true, + stereoPan: true, + collapse: false, + remove: false, + }, + }, + zoomLevels: [128, 256, 512, 1024, 2048, 4096], + }); + this.activeEventEmitter = this.viewPlaylist.getEventEmitter(); + this.activeEventEmitter.on("select", this.updateViewSelect); + + await this.viewPlaylist.load([ + { + src: blob, + name: StorageUtilities.getBaseFromName(this.props.file.name), + }, + ]); + + if (this.viewPlaylist) { + this.viewPlaylist.initExporter(); + } + } + } else if (newMode === AudioManagerMode.edit) { + const audioWorkingFolder = await this.getAudioWorkingFolder(); + const files = []; + let thumbPrint = ""; + + if (audioWorkingFolder) { + for (const workingFileName in audioWorkingFolder.files) { + const workingFile = audioWorkingFolder.files[workingFileName]; + + if (workingFile) { + await workingFile.loadContent(); + if (workingFile.content && workingFile.content instanceof Uint8Array) { + const workingBlob = new Blob([workingFile.content], { type: "audio/x-mpeg-3" }); + + files.push({ + src: workingBlob, + name: StorageUtilities.getBaseFromName(workingFile.name), + }); + + thumbPrint += workingFile.fullPath + "|"; + } + } + } + } else { + files.push({ + src: blob, + name: StorageUtilities.getBaseFromName(this.props.file.name), + }); + } + + if ( + this.editAudioElement && + thumbPrint === this._editorThumbPrint && + this.editPlaylist && + this.coreEditFilePath === this.props.file.extendedPath + ) { + this.rootElt.current.appendChild(this.editAudioElement); + this.activeEventEmitter = this.editPlaylist.getEventEmitter(); + this.editEventEmitter = this.activeEventEmitter; + } else { + this.editAudioElement = document.createElement("DIV") as HTMLDivElement; + this.rootElt.current.appendChild(this.editAudioElement); + this.coreEditFilePath = this.props.file.extendedPath; + this._editorThumbPrint = thumbPrint; + + this.editPlaylist = WaveformPlaylist({ + ac: new (window.AudioContext || (window as any).webkitAudioContext)(), + samplesPerPixel: 512, + mono: true, + timescale: true, + waveHeight: 240, + container: this.editAudioElement, + isAutomaticScroll: true, + seekStyle: "line", + state: "cursor", + colors: { + waveOutlineColor: "#E0EFF1", + timeColor: "grey", + fadeColor: "black", + }, + states: { + cursor: true, + fadein: true, + fadeout: true, + select: true, + shift: true, + }, + controls: { + show: true, + width: 180, + widgets: { + muteOrSolo: true, + volume: true, + stereoPan: true, + collapse: true, + remove: true, + }, + }, + zoomLevels: [128, 256, 512, 1024, 2048, 4096], + }); + + this.activeEventEmitter = this.editPlaylist.getEventEmitter(); + this.editEventEmitter = this.activeEventEmitter; + this.editEventEmitter.on("select", this.updateEditSelect); + this.editEventEmitter.on("audiorenderingfinished", this._audioRenderingComplete); + + await this.editPlaylist.load(files); + + if (this.editPlaylist) { + this.editPlaylist.initExporter(); + } + } + } else if (newMode === AudioManagerMode.record) { + if ( + this.recordAudioElement && + this.recordPlaylist && + this.coreEditFilePath === this.props.file.extendedPath + ) { + this.rootElt.current.appendChild(this.recordAudioElement); + this.activeEventEmitter = this.recordPlaylist.getEventEmitter(); + this.editEventEmitter = this.activeEventEmitter; + } else { + this.recordAudioElement = document.createElement("DIV") as HTMLDivElement; + this.rootElt.current.appendChild(this.recordAudioElement); + this.coreEditFilePath = this.props.file.extendedPath; + + this.recordPlaylist = WaveformPlaylist({ + ac: new (window.AudioContext || (window as any).webkitAudioContext)(), + samplesPerPixel: 512, + mono: true, + timescale: true, + waveHeight: 240, + container: this.recordAudioElement, + isAutomaticScroll: true, + seekStyle: "line", + state: "cursor", + colors: { + waveOutlineColor: "#E0EFF1", + timeColor: "grey", + fadeColor: "black", + }, + states: { + cursor: true, + fadein: true, + fadeout: true, + select: true, + shift: true, + }, + controls: { + show: true, + width: 180, + widgets: { + muteOrSolo: false, + volume: false, + stereoPan: false, + collapse: false, + remove: false, + }, + }, + zoomLevels: [128, 256, 512, 1024, 2048, 4096], + }); + + this.activeEventEmitter = this.recordPlaylist.getEventEmitter(); + this.recordEventEmitter = this.activeEventEmitter; + this.recordEventEmitter.on("select", this.updateEditSelect); + this.recordEventEmitter.on("audiorenderingfinished", this._recordAudioRenderingComplete); + + await this.recordPlaylist.load([]); + + if (this.recordPlaylist) { + this.recordPlaylist.initExporter(); + } + } + } + + this.updateView(); + } + } + } + } + + updateViewSelect(start: number, end: number) { + this.viewState.startTime = start; + this.viewState.endTime = end; + + this.updateView(); + } + + async _audioRenderingComplete(type: string, data: any) { + if (type === "buffer") { + /* + const file = this.props.file; + + audioEncoder(data, 128, null, async (mp3Blob: Blob) => { + if (file) { + const arrayBuffer = await mp3Blob.arrayBuffer(); + const uint8Array = new Uint8Array(arrayBuffer); + + file.setContent(uint8Array); + */ + if (this._setToViewAfterPersist) { + this._setToViewAfterPersist = false; + + this.setState({ + fileToEdit: this.props.file, + content: this.state.content, + mode: AudioManagerMode.view, + }); + } + + this._isPersisting = false; + + const pendingLoad = this._pendingPersistRequests; + this._pendingPersistRequests = []; + + for (const prom of pendingLoad) { + prom(undefined); + } + } + } + + async _recordAudioRenderingComplete(type: string, data: any) { + if (type === "buffer") { + const workfolder = await this.getAudioWorkingFolder(); + + if (!workfolder) { + return; + } + + /*const fileName = await StorageUtilities.getUniqueFileName("audio", "mp3", workfolder); + + const file = workfolder.ensureFile(fileName); + + audioEncoder(data, 128, null, async (mp3Blob: Blob) => { + if (file) { + const arrayBuffer = await mp3Blob.arrayBuffer(); + const uint8Array = new Uint8Array(arrayBuffer); + + file.setContent(uint8Array); + + await file.saveContent(); +*/ + this.setState({ + fileToEdit: this.props.file, + content: this.state.content, + mode: AudioManagerMode.edit, + }); + } + // }); + //} + } + + updateEditSelect(start: number, end: number) { + this.editState.startTime = start; + this.editState.endTime = end; + + this.updateView(); + } + + updateView() { + if (!this.state || !this.statusElt.current) { + return; + } + + while (this.statusElt.current.childNodes.length > 0) { + this.statusElt.current.removeChild(this.statusElt.current.childNodes[0]); + } + + const viewState = this.state.mode ? this.viewState : this.editState; + + const displayElt = document.createElement("SPAN") as HTMLSpanElement; + + let str = ""; + + if (viewState.startTime !== undefined && viewState.endTime !== undefined) { + str += "Selected: "; + + if (viewState.startTime === viewState.endTime) { + str += viewState.startTime.toFixed(3); + } else { + str += viewState.startTime.toFixed(3) + " to " + viewState.endTime.toFixed(3); + } + } + + displayElt.innerText = str; + + this.statusElt.current.appendChild(displayElt); + } + + componentDidUpdate(prevProps: IAudioManagerProps, prevState: IAudioManagerState) { + if (this.props.file !== prevProps.file || this.props.visualSeed !== prevProps.visualSeed) { + this.setState({ + fileToEdit: this.props.file, + content: this.props.initialContent, + mode: AudioManagerMode.view, + }); + this._addAudioInterior(); + } else if (this.state.mode !== prevState.mode) { + this._addAudioInterior(); + } + } + + _toggleEdit() { + if (this.state.mode === AudioManagerMode.edit) { + this.persist(); + + this._setToViewAfterPersist = true; + } else { + this.setState({ + mode: AudioManagerMode.edit, + fileToEdit: this.state.fileToEdit, + content: this.state.content, + }); + } + } + + static getDerivedStateFromProps(props: IAudioManagerProps, state: IAudioManagerState) { + if (state === undefined || state === null) { + state = { + fileToEdit: props.file, + mode: AudioManagerMode.view, + }; + + return state; + } + if (props.file !== state.fileToEdit) { + state.fileToEdit = props.file; + return state; + } + + return null; // No change to state + } + + async persist() { + if (this._activeEditorPersistable) { + await this._activeEditorPersistable.persist(); + } + + if (this.editEventEmitter) { + const pendingPersists = this._pendingPersistRequests; + + const prom = (resolve: (value: unknown) => void, reject: (reason?: any) => void) => { + pendingPersists.push(resolve); + }; + + if (!this._isPersisting) { + this._isPersisting = true; + this.editEventEmitter.emit("startaudiorendering", "buffer"); + } + + if (this._isPersisting) { + await new Promise(prom); + } + } + } + + async persistRecord() { + if (this.recordEventEmitter) { + this.recordEventEmitter.emit("startaudiorendering", "buffer"); + } + } + + render() { + const height = "calc(100vh - " + ((this.props.heightOffset ? this.props.heightOffset : 500) + 34) + "px)"; + + let toolbarItems = []; + + if (this.state.mode === AudioManagerMode.record) { + toolbarItems = [ + { + icon: , + key: "toggleEdit", + onClick: this._toggleEdit, + title: "Toggles Edit mode", + }, + { + key: "dividerEdit", + kind: "divider", + }, + { + icon: , + key: "stop", + onClick: this.stopRecording, + title: "Stops playback", + }, + ]; + } else { + toolbarItems = [ + /*{ + icon: , + key: "toggleEdit", + onClick: this._toggleEdit, + title: "Toggles Edit mode", + }, + { + key: "dividerEdit", + kind: "divider", + },*/ + { + icon: , + key: "pause", + onClick: this.pause, + title: "Pauses playback of the recording", + }, + { + icon: , + key: "play", + onClick: this.play, + title: "Plays the selected track", + }, + { + icon: , + key: "stop", + onClick: this.stop, + title: "Stops playback", + }, + { + icon: , + key: "rewind", + onClick: this.rewind, + title: "Rewinds the current playback", + }, + { + icon: , + key: "forward", + onClick: this.rewind, + title: "Forwards the current playback", + }, + { + key: "dividerZoom", + kind: "divider", + }, + { + icon: , + key: "zoomOut", + onClick: this.zoomOut, + title: "Zooms out", + }, + { + icon: , + key: "zoomIn", + onClick: this.zoomIn, + title: "Zooms in on the current wave", + }, + ]; + } + + if (this.state.mode === AudioManagerMode.edit) { + toolbarItems.push({ + key: "dividerMouse", + kind: "divider", + }); + + toolbarItems.push({ + icon: , + key: "selectCursor", + onClick: this.setCursorStyle, + title: "Select an item", + }); + + toolbarItems.push({ + icon: , + key: "selectSelection", + onClick: this.setSelectionStyle, + title: "Select an range", + }); + + toolbarItems.push({ + key: "dividerRec", + kind: "divider", + }); + + toolbarItems.push({ + icon: , + key: "recordAdd", + onClick: this.recordAdd, + title: "Records a new track", + }); + } + + let audioItemProps = <>; + + if (this.state.mode !== AudioManagerMode.record) { + audioItemProps = ( +
+
Audio properties
+ +
+ ); + } + + return ( +
+
+ +
+
+
+
+ {audioItemProps} +
+
+ ); + } +} diff --git a/app/src/UX/BlockTypeTile.tsx b/app/src/UX/BlockTypeTile.tsx index a1d13ac2..c44dab65 100644 --- a/app/src/UX/BlockTypeTile.tsx +++ b/app/src/UX/BlockTypeTile.tsx @@ -47,7 +47,12 @@ export default class BlockTypeTile extends Component ); } diff --git a/app/src/UX/CartoSettingsPanel.tsx b/app/src/UX/CartoSettingsPanel.tsx index c0f928ae..a246a4ac 100644 --- a/app/src/UX/CartoSettingsPanel.tsx +++ b/app/src/UX/CartoSettingsPanel.tsx @@ -1,6 +1,6 @@ import { Component, SyntheticEvent } from "react"; import IAppProps from "./IAppProps"; -import Carto from "./../app/Carto"; +import Carto, { CartoTargetStrings } from "./../app/Carto"; import "./CartoSettingsPanel.css"; import { Input, @@ -28,8 +28,6 @@ interface ICartoSettingsPanelState { formatBeforeSave: boolean; } -export const CartoTargetStrings = ["Latest Minecraft release", "Latest Minecraft preview"]; - export default class CartoSettingsPanel extends Component { private _activeEditorPersistable?: IPersistable; @@ -96,6 +94,8 @@ export default class CartoSettingsPanel extends Component diff --git a/app/src/UX/DirectoryStorage.ts b/app/src/UX/DirectoryStorage.ts new file mode 100644 index 00000000..446a8318 --- /dev/null +++ b/app/src/UX/DirectoryStorage.ts @@ -0,0 +1,25 @@ +import Storage from "../storage/Storage"; + +export default class DirectoryStorage extends Storage { + static getEntriesAsPromise(dirEntry: FileSystemDirectoryEntry): Promise { + return new Promise((resolve, reject) => { + const result: FileSystemEntry[] = []; + const reader = dirEntry.createReader(); + const doBatch = () => { + reader.readEntries((entries) => { + if (entries.length > 0) { + entries.forEach((e) => result.push(e)); + doBatch(); + } else { + resolve(result); + } + }, reject); + }; + doBatch(); + }); + } + + async processDirectory(dirEntry: FileSystemDirectoryEntry) { + // const results = await DirectoryStorage.getEntriesAsPromise(dirEntry); + } +} diff --git a/app/src/UX/DocumentedCommandEditor.tsx b/app/src/UX/DocumentedCommandEditor.tsx index 9438e753..df532833 100644 --- a/app/src/UX/DocumentedCommandEditor.tsx +++ b/app/src/UX/DocumentedCommandEditor.tsx @@ -188,6 +188,7 @@ export default class DocumentedCommandEditor extends Component< infoForm.fields.push({ id: "overloads", title: "Overloads", + allowCreateDelete: false, subForm: Database.getForm("command_overload"), subFields: overloadSubfields, objectArrayToSubFieldKey: "id", diff --git a/app/src/UX/EntityTypeEditor.tsx b/app/src/UX/EntityTypeEditor.tsx index 9eeae7cd..a4bdfa3d 100644 --- a/app/src/UX/EntityTypeEditor.tsx +++ b/app/src/UX/EntityTypeEditor.tsx @@ -606,6 +606,7 @@ export default class EntityTypeEditor extends Component diff --git a/app/src/UX/EntityTypeResourceEditor.css b/app/src/UX/EntityTypeResourceEditor.css index ac6cb5ee..fca0c42f 100644 --- a/app/src/UX/EntityTypeResourceEditor.css +++ b/app/src/UX/EntityTypeResourceEditor.css @@ -5,6 +5,13 @@ overflow-y: auto; } +.etre-toolBarArea { + width: 100%; + padding-top: 3px; + padding-left: 29px; + height: 34px; +} + .etre-headerTransition { background-position-x: left; background-repeat: repeat-x; @@ -19,6 +26,15 @@ } .etre-form { - padding-top: 20px; + padding-top: 10px; padding-left: 20px; } + +.etre-rc-header { + padding-left: 20px; + padding-top: 10px; +} + +.etre-header-interior { + font-size: large; +} diff --git a/app/src/UX/EntityTypeResourceEditor.tsx b/app/src/UX/EntityTypeResourceEditor.tsx index 9ed61283..984f474d 100644 --- a/app/src/UX/EntityTypeResourceEditor.tsx +++ b/app/src/UX/EntityTypeResourceEditor.tsx @@ -7,18 +7,49 @@ import { ThemeInput } from "@fluentui/styles"; import DataForm, { IDataFormProps } from "../dataform/DataForm"; import IProperty from "../dataform/IProperty"; import EntityTypeResourceDefinition from "../minecraft/EntityTypeResourceDefinition"; +import ProjectItem from "../app/ProjectItem"; +import RenderControllerSetDefinition from "../minecraft/RenderControllerSetDefinition"; +import RenderControllerSetEditor, { RenderControllerSetEditorFocus } from "./RenderControllerSetEditor"; +import { ProjectItemType } from "../app/IProjectItemData"; +import MinecraftDefinitions from "../minecraft/MinecraftDefinitions"; +import IPersistable from "./IPersistable"; +import { CustomTabLabel } from "./Labels"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { + faCube, + faPaintBrush, + faPersonWalkingArrowLoopLeft, + faSliders, + faVolumeUp, +} from "@fortawesome/free-solid-svg-icons"; +import { Toolbar } from "@fluentui/react-northstar"; +import SoundCatalogDefinition from "../minecraft/SoundCatalogDefinition"; +import { ISoundEventSet } from "../minecraft/ISoundCatalog"; +import SoundEventSetEditor, { SoundEventSetType } from "./SoundEventSetEditor"; + +export enum EntityTypeResourceEditorMode { + textures = 0, + geometry = 1, + animations = 2, + materials = 3, + audio = 4, +} interface IEntityTypeResourceEditorProps extends IFileProps { heightOffset: number; readOnly: boolean; displayHeader?: boolean; theme: ThemeInput; + projectItem: ProjectItem; } interface IEntityTypeResourceEditorState { fileToEdit: IFile; isLoaded: boolean; - selectedItem: EntityTypeResourceDefinition | undefined; + sound: ISoundEventSet | undefined; + mode: EntityTypeResourceEditorMode; + renderControllerSets?: RenderControllerSetDefinition[] | undefined; + entityTypeResource: EntityTypeResourceDefinition | undefined; } export default class EntityTypeResourceEditor extends Component< @@ -26,19 +57,31 @@ export default class EntityTypeResourceEditor extends Component< IEntityTypeResourceEditorState > { private _lastFileEdited?: IFile; + private _childPersistables: IPersistable[]; constructor(props: IEntityTypeResourceEditorProps) { super(props); this._definitionLoaded = this._definitionLoaded.bind(this); this._handleDataFormPropertyChange = this._handleDataFormPropertyChange.bind(this); + this._handleNewChildPersistable = this._handleNewChildPersistable.bind(this); + + this._setGeometryMode = this._setGeometryMode.bind(this); + this._setMaterialsMode = this._setMaterialsMode.bind(this); + this._setAnimationsMode = this._setAnimationsMode.bind(this); + this._setAudioMode = this._setAudioMode.bind(this); + this._setTexturesMode = this._setTexturesMode.bind(this); this.state = { fileToEdit: props.file, isLoaded: false, - selectedItem: undefined, + sound: undefined, + mode: EntityTypeResourceEditorMode.textures, + entityTypeResource: undefined, }; + this._childPersistables = []; + this._updateManager(true); } @@ -47,7 +90,9 @@ export default class EntityTypeResourceEditor extends Component< state = { fileToEdit: props.file, isLoaded: false, - selectedItem: undefined, + sound: undefined, + mode: EntityTypeResourceEditorMode.textures, + entityTypeResource: undefined, }; return state; @@ -63,7 +108,8 @@ export default class EntityTypeResourceEditor extends Component< return null; } - componentDidUpdate(prevProps: IEntityTypeResourceEditorProps, prevState: IEntityTypeResourceEditorState) { + componentDidMount(): void { + this._childPersistables = []; this._updateManager(true); } @@ -71,12 +117,14 @@ export default class EntityTypeResourceEditor extends Component< if (this.state !== undefined && this.state.fileToEdit !== undefined) { if (this.state.fileToEdit !== this._lastFileEdited) { this._lastFileEdited = this.state.fileToEdit; - - await EntityTypeResourceDefinition.ensureOnFile(this.state.fileToEdit, this._definitionLoaded); } } - await Database.ensureFormLoaded("entity_type_resource"); + await Database.ensureFormLoaded("entity_type_resource_animations"); + await Database.ensureFormLoaded("entity_type_resource_geometry"); + await Database.ensureFormLoaded("entity_type_resource_materials"); + await Database.ensureFormLoaded("entity_type_resource_textures"); + await Database.ensureFormLoaded("entity_sound_event"); if ( this.state.fileToEdit && @@ -94,23 +142,63 @@ export default class EntityTypeResourceEditor extends Component< } async _doUpdate(setState: boolean) { - let selItem = this.state.selectedItem; + let selItem = this.state.entityTypeResource; if (selItem === undefined && this.state && this.state.fileToEdit && this.state.fileToEdit.manager) { selItem = this.state.fileToEdit.manager as EntityTypeResourceDefinition; } + const renderControllerSets: RenderControllerSetDefinition[] = []; + + if (this.props.projectItem && this.props.projectItem.childItems) { + for (const item of this.props.projectItem.childItems) { + if (item.childItem.itemType === ProjectItemType.renderControllerJson) { + const renderControllerSet = (await MinecraftDefinitions.get(item.childItem)) as RenderControllerSetDefinition; + + renderControllerSets.push(renderControllerSet); + } + } + } + + const etrd = await EntityTypeResourceDefinition.ensureOnFile(this.state.fileToEdit, this._definitionLoaded); + + const items = this.props.projectItem.project.getItemsCopy(); + let soundEvent: ISoundEventSet | undefined = undefined; + + for (const projItem of items) { + if (projItem.itemType === ProjectItemType.soundCatalog) { + const soundDef = (await MinecraftDefinitions.get(projItem)) as SoundCatalogDefinition; + + if ( + soundDef && + soundDef.data && + soundDef.data.entity_sounds && + soundDef.data.entity_sounds.entities && + etrd && + etrd.id + ) { + soundEvent = soundDef.data.entity_sounds.entities[etrd.id]; + } + } + } + if (setState) { this.setState({ fileToEdit: this.state.fileToEdit, isLoaded: true, - selectedItem: this.state.selectedItem, + mode: this.state.mode, + sound: soundEvent, + entityTypeResource: etrd, + renderControllerSets: renderControllerSets, }); } else { this.state = { fileToEdit: this.props.file, isLoaded: true, - selectedItem: this.state.selectedItem, + mode: this.state.mode, + sound: soundEvent, + entityTypeResource: etrd, + renderControllerSets: renderControllerSets, }; } } @@ -125,6 +213,18 @@ export default class EntityTypeResourceEditor extends Component< srbd.persist(); } } + + if (this._childPersistables) { + for (const persister of this._childPersistables) { + persister.persist(); + } + } + } + + _handleNewChildPersistable(newPersistable: IPersistable) { + if (!this._childPersistables.includes(newPersistable)) { + this._childPersistables.push(newPersistable); + } } _handleDataFormPropertyChange(props: IDataFormProps, property: IProperty, newValue: any) { @@ -137,8 +237,37 @@ export default class EntityTypeResourceEditor extends Component< } } + _setMode(mode: EntityTypeResourceEditorMode) { + this.setState({ + fileToEdit: this.state.fileToEdit, + isLoaded: this.state.isLoaded, + mode: mode, + }); + } + + _setTexturesMode() { + this._setMode(EntityTypeResourceEditorMode.textures); + } + + _setGeometryMode() { + this._setMode(EntityTypeResourceEditorMode.geometry); + } + + _setMaterialsMode() { + this._setMode(EntityTypeResourceEditorMode.materials); + } + + _setAnimationsMode() { + this._setMode(EntityTypeResourceEditorMode.animations); + } + + _setAudioMode() { + this._setMode(EntityTypeResourceEditorMode.audio); + } + render() { const height = "calc(100vh - " + this.props.heightOffset + "px)"; + const toolbarItems = []; if ( this.state === null || @@ -159,35 +288,201 @@ export default class EntityTypeResourceEditor extends Component< this.props.setActivePersistable(this); } - const definitionFile = this.state.fileToEdit.manager as EntityTypeResourceDefinition; - const def = definitionFile._dataWrapper; + let isButtonCompact = false; + + toolbarItems.push({ + icon: ( + } + text={"Textures"} + isCompact={isButtonCompact} + isSelected={this.state.mode === EntityTypeResourceEditorMode.textures} + theme={this.props.theme} + /> + ), + key: "etreTexturesTab", + onClick: this._setTexturesMode, + title: "Textures", + }); + + toolbarItems.push({ + icon: ( + } + text={"Geometry"} + isCompact={isButtonCompact} + isSelected={this.state.mode === EntityTypeResourceEditorMode.geometry} + theme={this.props.theme} + /> + ), + key: "etreGeometryTab", + onClick: this._setGeometryMode, + title: "Geometry", + }); + + toolbarItems.push({ + icon: ( + } + text={"Materials"} + isCompact={isButtonCompact} + isSelected={this.state.mode === EntityTypeResourceEditorMode.materials} + theme={this.props.theme} + /> + ), + key: "etreMaterialsTab", + onClick: this._setMaterialsMode, + title: "Materials", + }); + + toolbarItems.push({ + icon: ( + } + text={"Animations"} + isCompact={isButtonCompact} + isSelected={this.state.mode === EntityTypeResourceEditorMode.animations} + theme={this.props.theme} + /> + ), + key: "etreAnimationsTab", + onClick: this._setAnimationsMode, + title: "Animations", + }); + + toolbarItems.push({ + icon: ( + } + text={"Audio"} + isCompact={isButtonCompact} + isSelected={this.state.mode === EntityTypeResourceEditorMode.audio} + theme={this.props.theme} + /> + ), + key: "etreAudioTab", + onClick: this._setAudioMode, + title: "Audio", + }); + + const resourceDefinition = this.state.fileToEdit.manager as EntityTypeResourceDefinition; + const def = resourceDefinition.dataWrapper; if (def === undefined) { return
Loading definition...
; } - let defInner = def["minecraft:client_entity"]; - if (defInner === undefined) { - defInner = { - description: { - identifier: "", - materials: {}, - textures: {}, - geometry: {}, - particle_effects: {}, - animations: {}, - render_controllers: [], - scripts: {}, - }, - }; - def["minecraft:client_entity"] = defInner; + let resourceData = resourceDefinition.ensureData(); + + let form = undefined; + let focus = RenderControllerSetEditorFocus.all; + + if (this.state.mode === EntityTypeResourceEditorMode.textures) { + form = Database.getForm("entity_type_resource_textures"); + focus = RenderControllerSetEditorFocus.textures; + } else if (this.state.mode === EntityTypeResourceEditorMode.geometry) { + form = Database.getForm("entity_type_resource_geometry"); + focus = RenderControllerSetEditorFocus.geometry; + } else if (this.state.mode === EntityTypeResourceEditorMode.materials) { + form = Database.getForm("entity_type_resource_materials"); + focus = RenderControllerSetEditorFocus.materials; + } else if (this.state.mode === EntityTypeResourceEditorMode.animations) { + form = Database.getForm("entity_type_resource_animations"); } - const form = Database.getForm("entity_type_resource"); - let header = <>; if (this.props.displayHeader === undefined || this.props.displayHeader) { - header =
Entity Type Resources
; + header = ( +
+ Entity Type Visuals and Audio +
+ ); + } + + let renderControllerEditors = []; + + let renderControllerHeader = <>; + + if ( + this.state.renderControllerSets && + this.state.renderControllerSets.length > 0 && + this.state.mode !== EntityTypeResourceEditorMode.audio && + this.state.mode !== EntityTypeResourceEditorMode.animations + ) { + let rcTitle = "Render Controllers"; + let rcDescrip = + "Render controllers tell Minecraft how to select a texture, geometry model, and material rendering strategy based on the configuration of the mob."; + + if (this.state.mode === EntityTypeResourceEditorMode.textures) { + rcTitle = "Texture render controllers"; + rcDescrip = + "Texture render controllers tell Minecraft how to select a texture based on the configuration of the mob."; + } else if (this.state.mode === EntityTypeResourceEditorMode.geometry) { + rcTitle = "Geometry render controllers"; + rcDescrip = + "Geometry render controllers tell Minecraft how to select a geometry model based on the configuration of the mob."; + } else if (this.state.mode === EntityTypeResourceEditorMode.materials) { + rcTitle = "Materials render controllers"; + rcDescrip = + "Materials render controllers tell Minecraft how to select a material render strategy based on the configuration of the mob."; + } + + renderControllerHeader = ( +
+
{rcTitle}
+
{rcDescrip}
+
+ ); + + for (const renderControllerSet of this.state.renderControllerSets) { + renderControllerEditors.push( + + ); + } + } + + let mainInterior = <>; + + if (this.state.mode === EntityTypeResourceEditorMode.audio) { + if (this.state.entityTypeResource && this.state.entityTypeResource.id) { + mainInterior = ( + + ); + } + } else if (form) { + mainInterior = ( + + ); } return ( @@ -200,16 +495,19 @@ export default class EntityTypeResourceEditor extends Component< > {header}
-
- +
+
+ +
{mainInterior}
+ {renderControllerHeader} +
{renderControllerEditors}
); diff --git a/app/src/UX/Home.css b/app/src/UX/Home.css index d74385e8..cc4d5c3f 100644 --- a/app/src/UX/Home.css +++ b/app/src/UX/Home.css @@ -25,7 +25,6 @@ .home-main { grid-template-columns: 400px 1fr; display: grid; - width: 100vw; } .home-header { @@ -96,7 +95,7 @@ } .home-toolTile { - height: 120px; + height: 130px; display: inline-flex; margin-top: 10px; margin-left: 6px; @@ -223,6 +222,7 @@ .home-inlineMessage { padding: 20px; + margin-bottom: 10px; } .home-loadingIcon { @@ -274,62 +274,6 @@ height: 60px; } -.home-newCreator { - grid-row: 2; - grid-column: 1; - padding-top: 5px; -} - -.home-newCreatorInput { - grid-row: 2; - grid-column: 2; -} - -.home-newName { - grid-row: 1; - grid-column: 1; - padding-top: 5px; -} - -.home-newNameInput { - grid-row: 1; - grid-column: 2; -} - -.home-newShortName { - grid-row: 3; - grid-column: 1; - padding-top: 5px; -} - -.home-newShortNameInput { - grid-row: 3; - grid-column: 2; -} - -.home-newDescription { - grid-row: 4; - grid-column: 1; - padding-top: 5px; -} - -.home-newDescriptionInput { - grid-row: 4; - grid-column: 2; -} - -.home-newFolder { - padding-top: 35px; - grid-row: 5; - grid-column: 1; -} - -.home-newPath { - padding-top: 35px; - grid-row: 5; - grid-column: 2; -} - .home-projects { font-size: medium; margin-top: 1px; diff --git a/app/src/UX/Home.tsx b/app/src/UX/Home.tsx index f82c98cf..44cc6cf5 100644 --- a/app/src/UX/Home.tsx +++ b/app/src/UX/Home.tsx @@ -4,9 +4,7 @@ import { AppMode } from "./App"; import "./Home.css"; import { List, - Button, Dialog, - Input, InputProps, ThemeInput, FormInput, @@ -43,8 +41,11 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faMagnifyingGlass } from "@fortawesome/free-solid-svg-icons"; import WebUtilities from "./WebUtilities"; import FileSystemFolder from "../storage/FileSystemFolder"; +import { MinecraftFlavor } from "../app/ICartoData"; import IStorage from "../storage/IStorage"; import MinecraftBox from "./MinecraftBox"; +import IProjectSeed from "../app/IProjectSeed"; +import NewProject from "./NewProject"; enum HomeDialogMode { none = 0, @@ -65,19 +66,10 @@ interface IHomeProps extends IAppProps { onProjectSelected?: (project: Project) => void; onLog: (message: string) => Promise; onSetProject: (project: Project) => void; - onGalleryItemCommand: ( - command: GalleryProjectCommand, - project: IGalleryItem, - name?: string, - creator?: string, - shortName?: string, - description?: string - ) => void; + onGalleryItemCommand: (command: GalleryProjectCommand, newProjectSeed: IProjectSeed) => void; onNewProjectSelected?: ( - name: string, + newProjectSeed: IProjectSeed, newProjectType: NewProjectTemplateType, - creator?: string, - shortName?: string, path?: string, additionalFilePath?: string, additionalFile?: File, @@ -101,14 +93,10 @@ interface IHomeState { selectedProject?: string; search?: string; errorMessage?: string; - inlineMessage?: string; - newProjectName?: string; - newProjectShortName?: string; - newProjectCreator?: string; - newProjectDescription?: string; - newProjectPath?: string; + inlineUpdateMessage?: string; + inlineLoadingMessage?: string; + newProjectSeed?: IProjectSeed; contextFocusedProject?: number; - newGalleryProject?: IGalleryItem; } export default class Home extends Component { @@ -138,7 +126,6 @@ export default class Home extends Component { this._onCartoLoaded = this._onCartoLoaded.bind(this); this._onDeploymentStorageChanged = this._onDeploymentStorageChanged.bind(this); this._onDeploymentStorageChanged = this._onDeploymentStorageChanged.bind(this); - this._handleNewProjectSelectedClick = this._handleNewProjectSelectedClick.bind(this); this._handleOpenFolderClick = this._handleOpenFolderClick.bind(this); this._handleOpenLocalFolderClick = this._handleOpenLocalFolderClick.bind(this); this._handleOpenWebLocalDeployClick = this._handleOpenWebLocalDeployClick.bind(this); @@ -151,13 +138,7 @@ export default class Home extends Component { this._handleNewProjectConfirm = this._handleNewProjectConfirm.bind(this); this._handleErrorMessageConfirm = this._handleErrorMessageConfirm.bind(this); this._handleDeleteProjectConfirm = this._handleDeleteProjectConfirm.bind(this); - this._handleNewProjectName = this._handleNewProjectName.bind(this); this._doManageConsent = this._doManageConsent.bind(this); - this._handleNewProjectNameChange = this._handleNewProjectNameChange.bind(this); - this._handleNewProjectShortNameChange = this._handleNewProjectShortNameChange.bind(this); - this._handleNewProjectCreatorChange = this._handleNewProjectCreatorChange.bind(this); - this._handleNewProjectDescriptionChange = this._handleNewProjectDescriptionChange.bind(this); - this._handleSelectFolderClick = this._handleSelectFolderClick.bind(this); this._handleExportAllKey = this._handleExportAllKey.bind(this); this._handleExportAllClick = this._handleExportAllClick.bind(this); this._handleNewSearch = this._handleNewSearch.bind(this); @@ -171,6 +152,7 @@ export default class Home extends Component { this._processIncomingFile = this._processIncomingFile.bind(this); this._startDelayLoadItems = this._startDelayLoadItems.bind(this); this._recentItemContextMenuClick = this._recentItemContextMenuClick.bind(this); + this._handleNewProjectSeedUpdate = this._handleNewProjectSeedUpdate.bind(this); if (typeof window !== "undefined") { window.setTimeout(this._startDelayLoadItems, 10); @@ -201,8 +183,7 @@ export default class Home extends Component { isDeployingToComMojang: this.props.carto.isDeployingToComMojang, search: this.state.search, effect: HomeEffect.none, - newProjectName: this.state.newProjectName, - newProjectPath: this.state.newProjectPath, + newProjectSeed: this.state.newProjectSeed, }); } } @@ -232,8 +213,7 @@ export default class Home extends Component { dialogMode: this.state.dialogMode, isDeployingToComMojang: this.props.carto.isDeployingToComMojang, effect: HomeEffect.dragOver, - newProjectName: this.state.newProjectName, - newProjectPath: this.state.newProjectPath, + newProjectSeed: this.state.newProjectSeed, }); } } @@ -265,6 +245,60 @@ export default class Home extends Component { } } + private async _handleDirectoryHandle(dirHandle: FileSystemDirectoryHandle, isDocumentationProject?: boolean) { + const name = dirHandle.name.toLowerCase(); + + if (name === "mc_lnk" || name === "mcpvw_lnk" || name.indexOf("bds") >= 0 || name.indexOf("server") >= 0) { + let fss = new FileSystemStorage(dirHandle as FileSystemDirectoryHandle, dirHandle.name); + + const safeMessage = await (fss.rootFolder as FileSystemFolder).getFirstUnsafeError(); + + if (safeMessage !== undefined) { + Log.debugAlert(safeMessage); + return false; + } + + CartoApp.deploymentStorage = fss; + + this.props.carto.isDeployingToComMojang = true; + this.props.carto.updateDeploymentStorage(fss); + this.props.carto.ensureMinecraft(MinecraftFlavor.deploymentStorage); + this.setState({ + gallery: this.state.gallery, + search: this.state.search, + isDeployingToComMojang: this.props.carto.isDeployingToComMojang, + newProjectSeed: this.state.newProjectSeed, + effect: HomeEffect.none, + dialogMode: HomeDialogMode.none, + inlineLoadingMessage: this.state.inlineLoadingMessage, + inlineUpdateMessage: "Set deployment folder as '" + name + "'.", + }); + + return true; + } else { + let fss = new FileSystemStorage(dirHandle as FileSystemDirectoryHandle, dirHandle.name); + + const safeMessage = await (fss.rootFolder as FileSystemFolder).getFirstUnsafeError(); + + if (safeMessage !== undefined) { + this.setState({ + errorMessage: + "Folder has unsupported files within it. Please choose a folder on your device that only has Minecraft asset files in it (.json, .png, .mcfunction, etc.)\r\n\r\nDetails: " + + safeMessage, + dialogMode: HomeDialogMode.errorMessage, + isDeployingToComMojang: this.props.carto.isDeployingToComMojang, + }); + return false; + } + if (this.props.onNewProjectFromFolderInstanceSelected) { + this.props.onNewProjectFromFolderInstanceSelected(fss.rootFolder, dirHandle.name, isDocumentationProject); + return true; + } + } + + return false; + } + private async _handleFileDrop(ev: DragEvent): Promise { if (this.state && this.state.dialogMode !== HomeDialogMode.none) { return; @@ -285,17 +319,31 @@ export default class Home extends Component { if (dtitem.webkitGetAsEntry) { entry = dtitem.webkitGetAsEntry(); + } else if ((dtitem as any).getAsEntry) { + entry = (dtitem as any).getAsEntry(); } if (entry && entry.isDirectory) { - const directoryReader = (entry as any).createReader(); - const me = this; + const dirHandle = await dtitem.getAsFileSystemHandle(); - directoryReader.readEntries(function (entries: any) { - entries.forEach((childEntry: any) => { - me._processInputtedEntry((entry as any).fullPath, childEntry); + if (dirHandle) { + const perm = await dirHandle.requestPermission({ + mode: "readwrite", }); - }); + + if (perm) { + await this._handleDirectoryHandle(dirHandle as FileSystemDirectoryHandle); + } + } else { + const directoryReader = (entry as any).createReader(); + const me = this; + + directoryReader.readEntries(function (entries: any) { + entries.forEach((childEntry: any) => { + me._processInputtedEntry((entry as any).fullPath, childEntry); + }); + }); + } } else if (dtitem.kind === "file") { const file = dtitem.getAsFile(); if (file) { @@ -327,11 +375,11 @@ export default class Home extends Component { } this.props.onNewProjectSelected( - fileName, + { + name: fileName, + }, NewProjectTemplateType.empty, undefined, - undefined, - undefined, path, file, editorStartMode, @@ -356,91 +404,10 @@ export default class Home extends Component { dialogMode: this.state.dialogMode, effect: this.state.effect, isDeployingToComMojang: this.props.carto.isDeployingToComMojang, - newProjectName: this.state.newProjectName, - newProjectPath: this.state.newProjectPath, - newProjectShortName: this.state.newProjectShortName, - newProjectCreator: this.state.newProjectCreator, - newProjectDescription: this.state.newProjectDescription, - }); - } - - private _handleNewProjectNameChange(e: SyntheticEvent, data: (InputProps & { value: string }) | undefined) { - if (data === undefined || this.state == null) { - return; - } - - this.setState({ - gallery: this.state.gallery, - dialogMode: this.state.dialogMode, - effect: this.state.effect, - isDeployingToComMojang: this.props.carto.isDeployingToComMojang, - newProjectName: data.value, - newProjectPath: this.state.newProjectPath, - newProjectShortName: this.state.newProjectShortName, - newProjectCreator: this.state.newProjectCreator, - newProjectDescription: this.state.newProjectDescription, + newProjectSeed: this.state.newProjectSeed, }); } - private _handleNewProjectDescriptionChange(e: SyntheticEvent, data: (InputProps & { value: string }) | undefined) { - if (data === undefined || this.state == null) { - return; - } - - this.setState({ - gallery: this.state.gallery, - dialogMode: this.state.dialogMode, - effect: this.state.effect, - isDeployingToComMojang: this.props.carto.isDeployingToComMojang, - newProjectName: this.state.newProjectName, - newProjectPath: this.state.newProjectPath, - newProjectShortName: this.state.newProjectShortName, - newProjectCreator: this.state.newProjectCreator, - newProjectDescription: data.value, - }); - } - - private _handleNewProjectShortNameChange(e: SyntheticEvent, data: (InputProps & { value: string }) | undefined) { - if (data === undefined || this.state == null) { - return; - } - - this.setState({ - gallery: this.state.gallery, - dialogMode: this.state.dialogMode, - effect: this.state.effect, - isDeployingToComMojang: this.props.carto.isDeployingToComMojang, - newProjectName: this.state.newProjectName, - newProjectPath: this.state.newProjectPath, - newProjectShortName: data.value, - newProjectCreator: this.state.newProjectCreator, - newProjectDescription: this.state.newProjectDescription, - }); - } - - private _handleNewProjectCreatorChange(e: SyntheticEvent, data: (InputProps & { value: string }) | undefined) { - if (data === undefined || this.state == null) { - return; - } - - this.setState({ - gallery: this.state.gallery, - dialogMode: this.state.dialogMode, - effect: this.state.effect, - isDeployingToComMojang: this.props.carto.isDeployingToComMojang, - newProjectName: this.state.newProjectName, - newProjectPath: this.state.newProjectPath, - newProjectShortName: this.state.newProjectShortName, - newProjectCreator: data.value, - newProjectDescription: this.state.newProjectDescription, - }); - - if (this.props.carto) { - this.props.carto.creator = data.value; - this.props.carto.save(); - } - } - componentDidUpdate(prevProps: IHomeProps, prevState: IHomeState) { this.setCarto(this.props.carto); } @@ -457,40 +424,37 @@ export default class Home extends Component { this.setState({ gallery: this.state.gallery, search: this.state.search, - newProjectName: this.state.newProjectName, + newProjectSeed: this.state.newProjectSeed, isDeployingToComMojang: this.props.carto.isDeployingToComMojang, - newProjectCreator: this.state.newProjectCreator, - newProjectDescription: this.state.newProjectDescription, - newProjectPath: this.state.newProjectPath, - newGalleryProject: this.state.newGalleryProject, effect: HomeEffect.none, dialogMode: HomeDialogMode.none, - inlineMessage: "Downloading backup zip as '" + name + "'...", + inlineLoadingMessage: "Creating backup zip as '" + name + "'...", + inlineUpdateMessage: this.state.inlineUpdateMessage, }); - const operId = await this.props.carto.notifyOperationStarted("Exporting all projects as zip."); + // give a pause for the state to update with the loading message. + window.setTimeout(async () => { + const operId = await this.props.carto.notifyOperationStarted("Exporting all projects as zip."); - const zipStorage = await this.props.carto.getExportZip(); + const zipStorage = await this.props.carto.getExportZip(); - const zipBinary = await zipStorage.generateBlobAsync(); + const zipBinary = await zipStorage.generateBlobAsync(); - await this.props.carto.notifyOperationEnded(operId, "Export of projects created; downloading"); + await this.props.carto.notifyOperationEnded(operId, "Export of projects created; downloading"); - saveAs(zipBinary, name); + saveAs(zipBinary, name); - this.setState({ - gallery: this.state.gallery, - search: this.state.search, - newProjectName: this.state.newProjectName, - isDeployingToComMojang: this.props.carto.isDeployingToComMojang, - newProjectCreator: this.state.newProjectCreator, - newProjectDescription: this.state.newProjectDescription, - newProjectPath: this.state.newProjectPath, - newGalleryProject: this.state.newGalleryProject, - effect: HomeEffect.none, - dialogMode: HomeDialogMode.none, - inlineMessage: undefined, - }); + this.setState({ + gallery: this.state.gallery, + search: this.state.search, + newProjectSeed: this.state.newProjectSeed, + isDeployingToComMojang: this.props.carto.isDeployingToComMojang, + effect: HomeEffect.none, + dialogMode: HomeDialogMode.none, + inlineLoadingMessage: undefined, + inlineUpdateMessage: this.state.inlineUpdateMessage, + }); + }, 1); } async _updateCarto() { @@ -532,11 +496,7 @@ export default class Home extends Component { effect: this.state.effect, search: this.state.search, errorMessage: this.state.errorMessage, - newProjectName: this.state.newProjectName, - newProjectCreator: this.state.newProjectCreator, - newProjectDescription: this.state.newProjectDescription, - newProjectPath: this.state.newProjectPath, - newGalleryProject: this.state.newGalleryProject, + newProjectSeed: this.state.newProjectSeed, contextFocusedProject: this.state.contextFocusedProject, }); } @@ -551,45 +511,6 @@ export default class Home extends Component { this.forceUpdate(); } - private async _handleSelectFolderClick() { - Log.debug("Opening folder via services."); - - const result = await AppServiceProxy.sendAsync(AppServiceProxyCommands.openFolder, ""); - - if (result && result.length > 0) { - this.setState({ - gallery: this.state.gallery, - dialogMode: this.state.dialogMode, - isDeployingToComMojang: this.props.carto.isDeployingToComMojang, - newProjectName: this.state.newProjectName, - newProjectPath: result, - }); - } - } - - private async _handleNewProjectSelectedClick() { - const projectName = await this.props.carto.getNewProjectName("Project"); - - this.setState({ - gallery: this.state?.gallery, - dialogMode: HomeDialogMode.newProject, - isDeployingToComMojang: this.props.carto.isDeployingToComMojang, - newProjectName: projectName, - newProjectCreator: this.props.carto.creator, - newProjectDescription: this.state.newProjectDescription, - }); - } - - private async _handleNewProjectName() { - this.setState({ - gallery: this.state?.gallery, - dialogMode: HomeDialogMode.newProject, - isDeployingToComMojang: this.props.carto.isDeployingToComMojang, - newProjectCreator: this.props.carto.creator, - newProjectDescription: this.state.newProjectDescription, - }); - } - private _handleDialogCancel() { this.setState({ gallery: this.state?.gallery, @@ -612,11 +533,7 @@ export default class Home extends Component { effect: this.state.effect, search: this.state.search, errorMessage: this.state.errorMessage, - newProjectName: this.state.newProjectName, - newProjectCreator: this.state.newProjectCreator, - newProjectDescription: this.state.newProjectDescription, - newProjectPath: this.state.newProjectPath, - newGalleryProject: this.state.newGalleryProject, + newProjectSeed: this.state.newProjectSeed, contextFocusedProject: curIndex, }); e.preventDefault(); @@ -645,11 +562,7 @@ export default class Home extends Component { search: this.state.search, isDeployingToComMojang: this.props.carto.isDeployingToComMojang, errorMessage: this.state.errorMessage, - newProjectName: this.state.newProjectName, - newProjectCreator: this.state.newProjectCreator, - newProjectDescription: this.state.newProjectDescription, - newProjectPath: this.state.newProjectPath, - newGalleryProject: this.state.newGalleryProject, + newProjectSeed: this.state.newProjectSeed, contextFocusedProject: undefined, }); } @@ -683,27 +596,17 @@ export default class Home extends Component { }); if ( - this.state.newGalleryProject && - this.state.newProjectName !== undefined && + this.state.newProjectSeed && + this.state.newProjectSeed.name !== undefined && this.props.onGalleryItemCommand !== undefined ) { - this.props.onGalleryItemCommand( - GalleryProjectCommand.newProject, - this.state.newGalleryProject, - this.state.newProjectName, - this.state.newProjectCreator, - this.state.newProjectShortName, - this.state.newProjectDescription - ); - } else if (this.props.onNewProjectSelected && this.state?.newProjectName !== undefined) { - this.props.onNewProjectSelected( - this.state.newProjectName, - NewProjectTemplateType.gameTest, - this.state.newProjectCreator, - this.state.newProjectShortName, - this.state.newProjectPath, - this.state.newProjectDescription - ); + this.props.onGalleryItemCommand(GalleryProjectCommand.newProject, this.state.newProjectSeed); + } else if ( + this.props.onNewProjectSelected && + this.state?.newProjectSeed && + this.state.newProjectSeed.name !== undefined + ) { + this.props.onNewProjectSelected(this.state.newProjectSeed, NewProjectTemplateType.gameTest); } } @@ -724,8 +627,7 @@ export default class Home extends Component { search: this.state.search, effect: this.state.effect, isDeployingToComMojang: this.props.carto.isDeployingToComMojang, - newProjectName: this.state.newProjectName, - newProjectPath: this.state.newProjectPath, + newProjectSeed: this.state.newProjectSeed, }); } @@ -742,22 +644,8 @@ export default class Home extends Component { mode: "readwrite", })) as FileSystemDirectoryHandle | undefined; - if (result && this.props.onNewProjectFromFolderInstanceSelected) { - const storage = new FileSystemStorage(result); - - const safeMessage = await (storage.rootFolder as FileSystemFolder).getFirstUnsafeError(); - - if (safeMessage !== undefined) { - this.setState({ - errorMessage: - "Folder has unsupported files within it. Please choose a folder on your device that only has Minecraft asset files in it (.json, .png, .mcfunction, etc.)\r\n\r\nDetails: " + - safeMessage, - dialogMode: HomeDialogMode.errorMessage, - isDeployingToComMojang: this.props.carto.isDeployingToComMojang, - }); - } else { - this.props.onNewProjectFromFolderInstanceSelected(storage.rootFolder, result.name, isDocumentationProject); - } + if (result) { + await this._handleDirectoryHandle(result as FileSystemDirectoryHandle, isDocumentationProject); } } @@ -795,18 +683,6 @@ export default class Home extends Component { } } - private _handleToolTileMouseDown(event: MouseEvent) { - if (event.currentTarget && event.currentTarget.className.indexOf("tileDown") < 0) { - event.currentTarget.className = event.currentTarget.className + " home-tileDown"; - } - } - - private _handleToolTileMouseUp(event: MouseEvent) { - if (event.currentTarget && event.currentTarget.className.indexOf("tileDown") >= 0) { - event.currentTarget.className = event.currentTarget.className.replace(" home-tileDown", ""); - } - } - private _handleProjectGalleryCommand(command: GalleryProjectCommand, project: IGalleryItem) { if (command === GalleryProjectCommand.newProject) { this.setState({ @@ -816,15 +692,17 @@ export default class Home extends Component { search: this.state.search, errorMessage: undefined, isDeployingToComMojang: this.props.carto.isDeployingToComMojang, - newProjectName: ProjectUtilities.getSuggestedProjectName(project), - newProjectCreator: this.props.carto.creator, - newProjectPath: this.state.newProjectPath, - newGalleryProject: project, - newProjectDescription: this.state.newProjectDescription, + newProjectSeed: { + name: ProjectUtilities.getSuggestedProjectName(project), + creator: this.props.carto.creator, + galleryProject: project, + }, }); } else { if (this.props.onGalleryItemCommand !== undefined) { - this.props.onGalleryItemCommand(command, project); + this.props.onGalleryItemCommand(command, { + galleryProject: project, + }); } } } @@ -904,8 +782,22 @@ export default class Home extends Component { search: newSearch, isDeployingToComMojang: this.props.carto.isDeployingToComMojang, effect: this.state.effect, - newProjectName: this.state.newProjectName, - newProjectPath: this.state.newProjectPath, + newProjectSeed: this.state.newProjectSeed, + }); + } + + private _handleNewProjectSeedUpdate(newSeed: IProjectSeed) { + if (this.state == null) { + return; + } + + this.setState({ + gallery: this.state.gallery, + dialogMode: this.state.dialogMode, + search: this.state.search, + isDeployingToComMojang: this.props.carto.isDeployingToComMojang, + effect: this.state.effect, + newProjectSeed: newSeed, }); } @@ -913,6 +805,7 @@ export default class Home extends Component { const projectListItems: ShorthandValue[] = []; let dialogArea = <>; + let localGallery = <>; const webOnlyLinks: any[] = []; const browserWidth = WebUtilities.getWidth(); @@ -967,19 +860,34 @@ export default class Home extends Component { let gallery = []; let mainToolArea = []; + let messageArea = []; let toolBin: any[] = []; - gallery.push( + messageArea.push(
Loading...
); if (this.state !== null && this.state.gallery !== undefined) { - gallery = []; + messageArea = []; - if (this.state !== null && this.state.inlineMessage) { - gallery.push( + if (this.state !== null && this.state.inlineUpdateMessage) { + messageArea.push( +
+ {this.state.inlineUpdateMessage} +
+ ); + } + if (this.state !== null && this.state.inlineLoadingMessage) { + messageArea.push(
{ }} > Waiting spinner - {this.state.inlineMessage} + {this.state.inlineLoadingMessage}
); } @@ -1086,98 +994,7 @@ export default class Home extends Component { } } - if (this.state?.dialogMode === HomeDialogMode.newProject) { - const additionalDialogButtons = []; - - if (AppServiceProxy.hasAppServiceOrDebug) { - let path = this.state.newProjectPath; - - if (path === undefined) { - let delimiter = "\\"; - - if (!AppServiceProxy.hasAppService) { - delimiter = "/"; - } - - path = this.carto?.projectsStorage.rootFolder.fullPath + delimiter + this.state.newProjectName; - } - - additionalDialogButtons.push( -
- Store project at: -
- ); - - additionalDialogButtons.push( -
-
{path}
-
- ); - } - - const newDialogInnerContent = ( -
-
Title:
-
- -
-
Creator Name:
-
- -
-
Short Name:
-
- 0 && - this.state.newProjectName && - this.state.newProjectName.length > 0 - ? ProjectUtilities.getSuggestedProjectShortName( - this.state.newProjectCreator, - this.state.newProjectName - ) - : "short name" - } - key="newProjectShortName" - value={this.state.newProjectShortName !== "" ? this.state.newProjectShortName : undefined} - onChange={this._handleNewProjectShortNameChange} - /> -
-
Description:
-
- -
- {additionalDialogButtons} -
- ); - + if (this.state?.dialogMode === HomeDialogMode.newProject && this.state.newProjectSeed) { dialogArea = ( { confirmButton="OK" onCancel={this._handleDialogCancel} onConfirm={this._handleNewProjectConfirm} - content={newDialogInnerContent} - header={"New Minecraft Project"} + content={ + + } + header={"New Minecraft " + this.state.newProjectSeed?.galleryProject?.title + " Project"} /> ); } else if (this.state?.dialogMode === HomeDialogMode.errorMessage) { @@ -1551,7 +1375,9 @@ export default class Home extends Component { height: browserWidth >= 800 ? "calc(100vh - " + (168 + this.props.heightOffset) + "px)" : "", }} > + {messageArea} {mainToolArea} + {localGallery} {gallery} diff --git a/app/src/UX/IntegrateItem.tsx b/app/src/UX/IntegrateItem.tsx index 796dbd43..6cf86356 100644 --- a/app/src/UX/IntegrateItem.tsx +++ b/app/src/UX/IntegrateItem.tsx @@ -215,7 +215,8 @@ export default class IntegrateItem extends Component; + projectSeed: IProjectSeed; + onNewProjectUpdated: (newProject: IProjectSeed) => void; +} + +interface INewProjectState { + newProjectName?: string; + newProjectPath?: string; + newProjectShortName?: string; + newProjectCreator?: string; + newProjectDescription?: string; + newProjectTrack?: MinecraftTrack; +} + +export default class NewProject extends Component { + constructor(props: INewProjectProps) { + super(props); + + this._handleNewProjectNameChange = this._handleNewProjectNameChange.bind(this); + this._handleNewProjectShortNameChange = this._handleNewProjectShortNameChange.bind(this); + this._handleNewProjectCreatorChange = this._handleNewProjectCreatorChange.bind(this); + this._handleNewProjectDescriptionChange = this._handleNewProjectDescriptionChange.bind(this); + this._handleTrackChange = this._handleTrackChange.bind(this); + + this._handleSelectFolderClick = this._handleSelectFolderClick.bind(this); + + this.state = { + newProjectName: this.props.projectSeed.name, + newProjectPath: this.props.projectSeed.path, + newProjectShortName: this.props.projectSeed.shortName, + newProjectCreator: this.props.projectSeed.creator, + newProjectDescription: this.props.projectSeed.description, + newProjectTrack: this.props.projectSeed.track, + }; + } + + async _handleTrackChange( + event: React.MouseEvent | React.KeyboardEvent | null, + data: DropdownProps + ) { + let track: MinecraftTrack | undefined = MinecraftTrack.main; + + if (data.value === ProjectTargetStrings[1]) { + track = MinecraftTrack.main; + } else if (data.value === ProjectTargetStrings[2]) { + track = MinecraftTrack.preview; + } else if (data.value === ProjectTargetStrings[3]) { + track = MinecraftTrack.edu; + } else if (data.value === ProjectTargetStrings[4]) { + track = MinecraftTrack.eduPreview; + } else { + track = undefined; + } + + const newState = { + newProjectName: this.state.newProjectName, + newProjectPath: this.state.newProjectPath, + newProjectShortName: this.state.newProjectShortName, + newProjectCreator: this.state.newProjectCreator, + newProjectDescription: this.state.newProjectDescription, + newProjectTrack: track, + }; + + this.setState(newState); + this._updateSeed(newState); + } + + private _handleNewProjectNameChange(e: SyntheticEvent, data: (InputProps & { value: string }) | undefined) { + if (data === undefined || this.state == null) { + return; + } + + const newState = { + newProjectName: data.value, + newProjectPath: this.state.newProjectPath, + newProjectShortName: this.state.newProjectShortName, + newProjectCreator: this.state.newProjectCreator, + newProjectDescription: this.state.newProjectDescription, + newProjectTrack: this.state.newProjectTrack, + }; + + this.setState(newState); + this._updateSeed(newState); + } + + _updateSeed(state?: INewProjectState) { + if (!state) { + state = this.state; + } + + if (this.props.onNewProjectUpdated) { + this.props.onNewProjectUpdated({ + name: state.newProjectName, + creator: state.newProjectCreator, + shortName: state.newProjectShortName, + description: state.newProjectDescription, + galleryProject: this.props.projectSeed.galleryProject, + track: state.newProjectTrack, + }); + } + } + + private _handleNewProjectDescriptionChange(e: SyntheticEvent, data: TextAreaProps | undefined) { + if (data === undefined || this.state == null) { + return; + } + + const newState = { + newProjectName: this.state.newProjectName, + newProjectPath: this.state.newProjectPath, + newProjectShortName: this.state.newProjectShortName, + newProjectCreator: this.state.newProjectCreator, + newProjectDescription: data.value, + newProjectTrack: this.state.newProjectTrack, + }; + + this.setState(newState); + this._updateSeed(newState); + } + + private _handleNewProjectShortNameChange(e: SyntheticEvent, data: (InputProps & { value: string }) | undefined) { + if (data === undefined || this.state == null) { + return; + } + + const newState = { + newProjectName: this.state.newProjectName, + newProjectPath: this.state.newProjectPath, + newProjectShortName: data.value, + newProjectCreator: this.state.newProjectCreator, + newProjectDescription: this.state.newProjectDescription, + newProjectTrack: this.state.newProjectTrack, + }; + + this.setState(newState); + this._updateSeed(newState); + } + + private _handleNewProjectCreatorChange(e: SyntheticEvent, data: (InputProps & { value: string }) | undefined) { + if (data === undefined || this.state == null) { + return; + } + + const newState = { + newProjectName: this.state.newProjectName, + newProjectPath: this.state.newProjectPath, + newProjectShortName: this.state.newProjectShortName, + newProjectCreator: data.value, + newProjectDescription: this.state.newProjectDescription, + newProjectTrack: this.state.newProjectTrack, + }; + + this.setState(newState); + this._updateSeed(newState); + + if (this.props.carto) { + this.props.carto.creator = data.value; + this.props.carto.save(); + } + } + + private async _handleSelectFolderClick() { + Log.debug("Opening folder via services."); + + const result = await AppServiceProxy.sendAsync(AppServiceProxyCommands.openFolder, ""); + + if (result && result.length > 0) { + this.setState({ + newProjectName: this.state.newProjectName, + newProjectPath: result, + }); + } + } + + render() { + const additionalDialogButtons = []; + + if (AppServiceProxy.hasAppServiceOrDebug) { + let path = this.state.newProjectPath; + + if (path === undefined) { + let delimiter = "\\"; + + if (!AppServiceProxy.hasAppService) { + delimiter = "/"; + } + + path = this.props.carto.projectsStorage.rootFolder.fullPath + delimiter + this.state.newProjectName; + } + + additionalDialogButtons.push( +
+ Store project at: +
+ ); + + additionalDialogButtons.push( +
+
{path}
+
+ ); + } + + const targetStrings = []; + + const index = this.props.carto.track ? (this.props.carto.track as number) : 0; + + targetStrings.push(""); + + for (const targetString of CartoTargetStrings) { + targetStrings.push(targetString); + } + + return ( +
+
Title:
+
+ +
+
Creator Name:
+
+ +
+
Short Name:
+
+ 0 && + this.state.newProjectName && + this.state.newProjectName.length > 0 + ? ProjectUtilities.getSuggestedProjectShortName(this.state.newProjectCreator, this.state.newProjectName) + : "short name" + } + key="newProjectShortName" + value={this.state.newProjectShortName !== "" ? this.state.newProjectShortName : undefined} + onChange={this._handleNewProjectShortNameChange} + /> +
+
Description:
+
+