diff --git a/Gemfile.lock b/Gemfile.lock index 32515384a5..147d3c5da0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ GEM remote: https://rubygems.org/ specs: - action_text-trix (2.1.16) + action_text-trix (2.1.17) railties actioncable (8.1.2) actionpack (= 8.1.2) @@ -115,7 +115,7 @@ GEM delayed_job_active_record (4.1.11) activerecord (>= 3.0, < 9.0) delayed_job (>= 3.0, < 5) - devise (5.0.2) + devise (5.0.3) bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 7.0) @@ -196,7 +196,7 @@ GEM prism (>= 1.3.0) rdoc (>= 4.0.0) reline (>= 0.4.2) - json (2.19.1) + json (2.19.2) jsonapi-renderer (0.2.2) jwt (3.1.2) base64 @@ -218,7 +218,7 @@ GEM activesupport (>= 4) railties (>= 4) request_store (~> 1.0) - loofah (2.25.0) + loofah (2.25.1) crass (~> 1.0.2) nokogiri (>= 1.12.0) mail (2.9.0) @@ -360,14 +360,14 @@ GEM rspec-mocks (3.13.8) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) - rspec-rails (8.0.3) + rspec-rails (8.0.4) actionpack (>= 7.2) activesupport (>= 7.2) railties (>= 7.2) - rspec-core (~> 3.13) - rspec-expectations (~> 3.13) - rspec-mocks (~> 3.13) - rspec-support (~> 3.13) + rspec-core (>= 3.13.0, < 5.0.0) + rspec-expectations (>= 3.13.0, < 5.0.0) + rspec-mocks (>= 3.13.0, < 5.0.0) + rspec-support (>= 3.13.0, < 5.0.0) rspec-support (3.13.7) rspec_junit_formatter (0.6.0) rspec-core (>= 2, < 4, != 2.12.0) @@ -409,7 +409,7 @@ GEM useragent (0.16.11) warden (1.2.9) rack (>= 2.0.9) - webmock (3.26.1) + webmock (3.26.2) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) diff --git a/bun.lock b/bun.lock index cf82288f00..151944dcb8 100644 --- a/bun.lock +++ b/bun.lock @@ -5,8 +5,8 @@ "": { "name": "farmbot-web-frontend", "dependencies": { - "@blueprintjs/core": "6.9.1", - "@blueprintjs/select": "6.1.3", + "@blueprintjs/core": "6.10.0", + "@blueprintjs/select": "6.1.4", "@monaco-editor/react": "4.7.0", "@react-spring/three": "10.0.3", "@react-three/drei": "10.7.7", @@ -31,7 +31,7 @@ "farmbot": "15.9.3", "fengari": "0.1.5", "fengari-web": "0.1.4", - "i18next": "25.8.17", + "i18next": "25.8.18", "lodash": "4.17.23", "markdown-it": "14.1.1", "markdown-it-emoji": "3.0.0", @@ -50,7 +50,7 @@ "redux": "5.0.1", "redux-immutable-state-invariant": "2.1.0", "redux-thunk": "3.1.0", - "rollbar": "3.0.0", + "rollbar": "3.1.0", "suncalc": "1.9.0", "takeme": "0.12.0", "three": "0.183.2", @@ -59,7 +59,7 @@ }, "devDependencies": { "@eslint/js": "10.0.1", - "@happy-dom/global-registrator": "20.8.3", + "@happy-dom/global-registrator": "20.8.4", "@react-three/eslint-plugin": "0.1.2", "@testing-library/dom": "10.4.1", "@testing-library/jest-dom": "6.9.1", @@ -69,8 +69,8 @@ "@types/jest": "30.0.0", "@types/readable-stream": "4.0.23", "@types/suncalc": "1.9.2", - "@typescript-eslint/eslint-plugin": "8.57.0", - "@typescript-eslint/parser": "8.57.0", + "@typescript-eslint/eslint-plugin": "8.57.1", + "@typescript-eslint/parser": "8.57.1", "eslint": "10.0.3", "eslint-plugin-eslint-comments": "3.2.0", "eslint-plugin-import": "2.32.0", @@ -79,7 +79,7 @@ "eslint-plugin-promise": "7.2.1", "eslint-plugin-react": "7.37.5", "eslint-plugin-react-hooks": "7.0.1", - "happy-dom": "20.8.3", + "happy-dom": "20.8.4", "jest": "30.3.0", "jest-canvas-mock": "2.5.2", "jest-cli": "30.3.0", @@ -178,13 +178,13 @@ "@bcoe/v8-coverage": ["@bcoe/v8-coverage@0.2.3", "", {}, "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw=="], - "@blueprintjs/colors": ["@blueprintjs/colors@5.1.14", "", { "dependencies": { "tslib": "~2.6.2" } }, "sha512-Ak6NpUBc0nFpWxucYe7GgMwdcrlARX7yfSPxt4va7z2IM05peNh8OOZ2jQij5+sIgU6IoIkgILAqlQ8nNRhWww=="], + "@blueprintjs/colors": ["@blueprintjs/colors@5.1.15", "", { "dependencies": { "tslib": "~2.6.2" } }, "sha512-hxv11fKWwU707NaVWKUpJPOOCeinRC7zNhF2sX6vLN0UmDqHapItARTLW5DvwKTyPoDQQXUpX9yFwDlTQPbQ9w=="], - "@blueprintjs/core": ["@blueprintjs/core@6.9.1", "", { "dependencies": { "@blueprintjs/colors": "^5.1.14", "@blueprintjs/icons": "^6.6.0", "@floating-ui/react": "^0.27.13", "@popperjs/core": "^2.11.8", "classnames": "^2.3.1", "normalize.css": "^8.0.1", "react-popper": "^2.3.0", "react-transition-group": "^4.4.5", "tslib": "~2.6.2", "use-sync-external-store": "^1.2.0" }, "peerDependencies": { "@types/react": "18", "react": "18", "react-dom": "18" }, "optionalPeers": ["@types/react"], "bin": { "upgrade-blueprint-2.0.0-rename": "scripts/upgrade-blueprint-2.0.0-rename.sh", "upgrade-blueprint-3.0.0-rename": "scripts/upgrade-blueprint-3.0.0-rename.sh" } }, "sha512-RmkIpN6dGch7ZCT8dkmbK80JgcIqV4w19SmzJTot7QKm7fDRsi2hcusV/LOvn7WgZvS9Z8URzIp357jAN9Nv5A=="], + "@blueprintjs/core": ["@blueprintjs/core@6.10.0", "", { "dependencies": { "@blueprintjs/colors": "^5.1.15", "@blueprintjs/icons": "^6.7.0", "@floating-ui/react": "^0.27.13", "@popperjs/core": "^2.11.8", "classnames": "^2.3.1", "normalize.css": "^8.0.1", "react-popper": "^2.3.0", "react-transition-group": "^4.4.5", "tslib": "~2.6.2", "use-sync-external-store": "^1.2.0" }, "peerDependencies": { "@types/react": "18", "react": "18", "react-dom": "18" }, "optionalPeers": ["@types/react"], "bin": { "upgrade-blueprint-2.0.0-rename": "scripts/upgrade-blueprint-2.0.0-rename.sh", "upgrade-blueprint-3.0.0-rename": "scripts/upgrade-blueprint-3.0.0-rename.sh" } }, "sha512-k6B8aeIwuH0ns2NAz4iWWcfv5/0v5Av9ePQXmNbs2VOdPSRn3X0l1mhyNBAjuuXHJV3OEENGE1HSbFi6f1NNJw=="], - "@blueprintjs/icons": ["@blueprintjs/icons@6.6.0", "", { "dependencies": { "change-case": "^4.1.2", "classnames": "^2.3.1", "tslib": "~2.6.2" }, "peerDependencies": { "@types/react": "18", "react": "18", "react-dom": "18" }, "optionalPeers": ["@types/react"] }, "sha512-IaMTAAY554iqUCvfO9+okAnC/qprypQqkNOkBdAkID6lXud8PSyfJWdXneSBQnU/fHU1UA+7xILJ6Wr4wGoJGw=="], + "@blueprintjs/icons": ["@blueprintjs/icons@6.7.0", "", { "dependencies": { "change-case": "^4.1.2", "classnames": "^2.3.1", "tslib": "~2.6.2" }, "peerDependencies": { "@types/react": "18", "react": "18", "react-dom": "18" }, "optionalPeers": ["@types/react"] }, "sha512-wT8LjdXz5ogWYtWGsMpmLHbgg5Ml7rGcTg4QzHRL4NROaS2LEuNCNRQxmRNBdRdfpKcnGGwXNYqUNZYurB1r4Q=="], - "@blueprintjs/select": ["@blueprintjs/select@6.1.3", "", { "dependencies": { "@blueprintjs/colors": "^5.1.14", "@blueprintjs/core": "^6.9.1", "@blueprintjs/icons": "^6.6.0", "classnames": "^2.3.1", "tslib": "~2.6.2" }, "peerDependencies": { "@types/react": "18", "react": "18", "react-dom": "18" }, "optionalPeers": ["@types/react"] }, "sha512-BsDVwHvDplhNplcPizYVPi6y0KOqAB18Nw+spaQlACKYN9A2MmRe1EOCb1xYUu2dyx3Xz1sUMr1/2l6Dy/I2Ug=="], + "@blueprintjs/select": ["@blueprintjs/select@6.1.4", "", { "dependencies": { "@blueprintjs/colors": "^5.1.15", "@blueprintjs/core": "^6.10.0", "@blueprintjs/icons": "^6.7.0", "classnames": "^2.3.1", "tslib": "~2.6.2" }, "peerDependencies": { "@types/react": "18", "react": "18", "react-dom": "18" }, "optionalPeers": ["@types/react"] }, "sha512-j0eAwfApM3cUjuLQALgkN7QKNKGbNlPlL4LhngENYvs9bZMuHdtARFBT9FZV3UCqiIpAQmIccdvYJ0VtwV8Irg=="], "@csstools/color-helpers": ["@csstools/color-helpers@5.1.0", "", {}, "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA=="], @@ -234,7 +234,7 @@ "@floating-ui/utils": ["@floating-ui/utils@0.2.10", "", {}, "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="], - "@happy-dom/global-registrator": ["@happy-dom/global-registrator@20.8.3", "", { "dependencies": { "@types/node": ">=20.0.0", "happy-dom": "^20.8.3" } }, "sha512-9z6lLr6K6dIFLiB9jI0tKTlYzCComn5RL7L1mN3EdMSCyRQB8I6A0FO/On8yYKkXuunexzPDC98zDflvv2wDrQ=="], + "@happy-dom/global-registrator": ["@happy-dom/global-registrator@20.8.4", "", { "dependencies": { "@types/node": ">=20.0.0", "happy-dom": "^20.8.4" } }, "sha512-cXGYd3xIAcviiGO6lPXdG6Yg244xwRgtY2dicAQ6HiB87E2IL2ekgfR5QIos18UtjiAsnCpLS3m78JfDorJcYg=="], "@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="], @@ -500,25 +500,25 @@ "@types/yargs-parser": ["@types/yargs-parser@21.0.3", "", {}, "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ=="], - "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.57.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.57.0", "@typescript-eslint/type-utils": "8.57.0", "@typescript-eslint/utils": "8.57.0", "@typescript-eslint/visitor-keys": "8.57.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.57.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-qeu4rTHR3/IaFORbD16gmjq9+rEs9fGKdX0kF6BKSfi+gCuG3RCKLlSBYzn/bGsY9Tj7KE/DAQStbp8AHJGHEQ=="], + "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.57.1", "", { "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.57.1", "@typescript-eslint/type-utils": "8.57.1", "@typescript-eslint/utils": "8.57.1", "@typescript-eslint/visitor-keys": "8.57.1", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.57.1", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-Gn3aqnvNl4NGc6x3/Bqk1AOn0thyTU9bqDRhiRnUWezgvr2OnhYCWCgC8zXXRVqBsIL1pSDt7T9nJUe0oM0kDQ=="], - "@typescript-eslint/parser": ["@typescript-eslint/parser@8.57.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.57.0", "@typescript-eslint/types": "8.57.0", "@typescript-eslint/typescript-estree": "8.57.0", "@typescript-eslint/visitor-keys": "8.57.0", "debug": "^4.4.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-XZzOmihLIr8AD1b9hL9ccNMzEMWt/dE2u7NyTY9jJG6YNiNthaD5XtUHVF2uCXZ15ng+z2hT3MVuxnUYhq6k1g=="], + "@typescript-eslint/parser": ["@typescript-eslint/parser@8.57.1", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.57.1", "@typescript-eslint/types": "8.57.1", "@typescript-eslint/typescript-estree": "8.57.1", "@typescript-eslint/visitor-keys": "8.57.1", "debug": "^4.4.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-k4eNDan0EIMTT/dUKc/g+rsJ6wcHYhNPdY19VoX/EOtaAG8DLtKCykhrUnuHPYvinn5jhAPgD2Qw9hXBwrahsw=="], - "@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.57.0", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.57.0", "@typescript-eslint/types": "^8.57.0", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-pR+dK0BlxCLxtWfaKQWtYr7MhKmzqZxuii+ZjuFlZlIGRZm22HnXFqa2eY+90MUz8/i80YJmzFGDUsi8dMOV5w=="], + "@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.57.1", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.57.1", "@typescript-eslint/types": "^8.57.1", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-vx1F37BRO1OftsYlmG9xay1TqnjNVlqALymwWVuYTdo18XuKxtBpCj1QlzNIEHlvlB27osvXFWptYiEWsVdYsg=="], - "@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.57.0", "", { "dependencies": { "@typescript-eslint/types": "8.57.0", "@typescript-eslint/visitor-keys": "8.57.0" } }, "sha512-nvExQqAHF01lUM66MskSaZulpPL5pgy5hI5RfrxviLgzZVffB5yYzw27uK/ft8QnKXI2X0LBrHJFr1TaZtAibw=="], + "@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.57.1", "", { "dependencies": { "@typescript-eslint/types": "8.57.1", "@typescript-eslint/visitor-keys": "8.57.1" } }, "sha512-hs/QcpCwlwT2L5S+3fT6gp0PabyGk4Q0Rv2doJXA0435/OpnSR3VRgvrp8Xdoc3UAYSg9cyUjTeFXZEPg/3OKg=="], - "@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.57.0", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-LtXRihc5ytjJIQEH+xqjB0+YgsV4/tW35XKX3GTZHpWtcC8SPkT/d4tqdf1cKtesryHm2bgp6l555NYcT2NLvA=="], + "@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.57.1", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-0lgOZB8cl19fHO4eI46YUx2EceQqhgkPSuCGLlGi79L2jwYY1cxeYc1Nae8Aw1xjgW3PKVDLlr3YJ6Bxx8HkWg=="], - "@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.57.0", "", { "dependencies": { "@typescript-eslint/types": "8.57.0", "@typescript-eslint/typescript-estree": "8.57.0", "@typescript-eslint/utils": "8.57.0", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-yjgh7gmDcJ1+TcEg8x3uWQmn8ifvSupnPfjP21twPKrDP/pTHlEQgmKcitzF/rzPSmv7QjJ90vRpN4U+zoUjwQ=="], + "@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.57.1", "", { "dependencies": { "@typescript-eslint/types": "8.57.1", "@typescript-eslint/typescript-estree": "8.57.1", "@typescript-eslint/utils": "8.57.1", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-+Bwwm0ScukFdyoJsh2u6pp4S9ktegF98pYUU0hkphOOqdMB+1sNQhIz8y5E9+4pOioZijrkfNO/HUJVAFFfPKA=="], - "@typescript-eslint/types": ["@typescript-eslint/types@8.57.0", "", {}, "sha512-dTLI8PEXhjUC7B9Kre+u0XznO696BhXcTlOn0/6kf1fHaQW8+VjJAVHJ3eTI14ZapTxdkOmc80HblPQLaEeJdg=="], + "@typescript-eslint/types": ["@typescript-eslint/types@8.57.1", "", {}, "sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ=="], - "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.57.0", "", { "dependencies": { "@typescript-eslint/project-service": "8.57.0", "@typescript-eslint/tsconfig-utils": "8.57.0", "@typescript-eslint/types": "8.57.0", "@typescript-eslint/visitor-keys": "8.57.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-m7faHcyVg0BT3VdYTlX8GdJEM7COexXxS6KqGopxdtkQRvBanK377QDHr4W/vIPAR+ah9+B/RclSW5ldVniO1Q=="], + "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.57.1", "", { "dependencies": { "@typescript-eslint/project-service": "8.57.1", "@typescript-eslint/tsconfig-utils": "8.57.1", "@typescript-eslint/types": "8.57.1", "@typescript-eslint/visitor-keys": "8.57.1", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-ybe2hS9G6pXpqGtPli9Gx9quNV0TWLOmh58ADlmZe9DguLq0tiAKVjirSbtM1szG6+QH6rVXyU6GTLQbWnMY+g=="], - "@typescript-eslint/utils": ["@typescript-eslint/utils@8.57.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.57.0", "@typescript-eslint/types": "8.57.0", "@typescript-eslint/typescript-estree": "8.57.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-5iIHvpD3CZe06riAsbNxxreP+MuYgVUsV0n4bwLH//VJmgtt54sQeY2GszntJ4BjYCpMzrfVh2SBnUQTtys2lQ=="], + "@typescript-eslint/utils": ["@typescript-eslint/utils@8.57.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.57.1", "@typescript-eslint/types": "8.57.1", "@typescript-eslint/typescript-estree": "8.57.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-XUNSJ/lEVFttPMMoDVA2r2bwrl8/oPx8cURtczkSEswY5T3AeLmCy+EKWQNdL4u0MmAHOjcWrqJp2cdvgjn8dQ=="], - "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.57.0", "", { "dependencies": { "@typescript-eslint/types": "8.57.0", "eslint-visitor-keys": "^5.0.0" } }, "sha512-zm6xx8UT/Xy2oSr2ZXD0pZo7Jx2XsCoID2IUh9YSTFRu7z+WdwYTRk6LhUftm1crwqbuoF6I8zAFeCMw0YjwDg=="], + "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.57.1", "", { "dependencies": { "@typescript-eslint/types": "8.57.1", "eslint-visitor-keys": "^5.0.0" } }, "sha512-YWnmJkXbofiz9KbnbbwuA2rpGkFPLbAIetcCNO6mJ8gdhdZ/v7WDXsoGFAJuM6ikUFKTlSQnjWnVO4ux+UzS6A=="], "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], @@ -1120,7 +1120,7 @@ "handlebars": ["handlebars@4.7.8", "", { "dependencies": { "minimist": "^1.2.5", "neo-async": "^2.6.2", "source-map": "^0.6.1", "wordwrap": "^1.0.0" }, "optionalDependencies": { "uglify-js": "^3.1.4" }, "bin": "bin/handlebars" }, "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ=="], - "happy-dom": ["happy-dom@20.8.3", "", { "dependencies": { "@types/node": ">=20.0.0", "@types/whatwg-mimetype": "^3.0.2", "@types/ws": "^8.18.1", "entities": "^7.0.1", "whatwg-mimetype": "^3.0.0", "ws": "^8.18.3" } }, "sha512-lMHQRRwIPyJ70HV0kkFT7jH/gXzSI7yDkQFe07E2flwmNDFoWUTRMKpW2sglsnpeA7b6S2TJPp98EbQxai8eaQ=="], + "happy-dom": ["happy-dom@20.8.4", "", { "dependencies": { "@types/node": ">=20.0.0", "@types/whatwg-mimetype": "^3.0.2", "@types/ws": "^8.18.1", "entities": "^7.0.1", "whatwg-mimetype": "^3.0.0", "ws": "^8.18.3" } }, "sha512-GKhjq4OQCYB4VLFBzv8mmccUadwlAusOZOI7hC1D9xDIT5HhzkJK17c4el2f6R6C715P9xB4uiMxeKUa2nHMwQ=="], "has-ansi": ["has-ansi@2.0.0", "", { "dependencies": { "ansi-regex": "^2.0.0" } }, "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg=="], @@ -1164,7 +1164,7 @@ "human-signals": ["human-signals@2.1.0", "", {}, "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw=="], - "i18next": ["i18next@25.8.17", "", { "dependencies": { "@babel/runtime": "^7.28.6" }, "peerDependencies": { "typescript": "^5" }, "optionalPeers": ["typescript"] }, "sha512-vWtCttyn5bpOK4hWbRAe1ZXkA+Yzcn2OcACT+WJavtfGMcxzkfvXTLMeOU8MUhRmAySKjU4VVuKlo0sSGeBokA=="], + "i18next": ["i18next@25.8.18", "", { "dependencies": { "@babel/runtime": "^7.28.6" }, "peerDependencies": { "typescript": "^5" }, "optionalPeers": ["typescript"] }, "sha512-lzY5X83BiL5AP77+9DydbrqkQHFN9hUzWGjqjLpPcp5ZOzuu1aSoKaU3xbBLSjWx9dAzW431y+d+aogxOZaKRA=="], "iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], @@ -1788,7 +1788,7 @@ "robust-predicates": ["robust-predicates@3.0.2", "", {}, "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg=="], - "rollbar": ["rollbar@3.0.0", "", { "dependencies": { "@rrweb/record": "^2.0.0-alpha.18", "async": "~3.2.3", "error-stack-parser-es": "^1.0.5", "json-stringify-safe": "~5.0.0", "lru-cache": "~2.2.1", "request-ip": "~3.3.0", "source-map": "^0.5.7" } }, "sha512-FN3dO3SQzR1u5k7fVVyC97qXtOyzM8k79cpk2crklp/NcHVPpmF0QPMypNFRN9ujoycdl77+YwGU7PAfjP/wYA=="], + "rollbar": ["rollbar@3.1.0", "", { "dependencies": { "@rrweb/record": "^2.0.0-alpha.18", "async": "~3.2.3", "error-stack-parser-es": "^1.0.5", "json-stringify-safe": "~5.0.0", "lru-cache": "~2.2.1", "request-ip": "~3.3.0", "source-map": "^0.5.7" } }, "sha512-YELG0MDRzOLnV5sa2vL/IiGEgNoK5JAivKlpjcJewEIqgmiVlEAPFQUNNB3fsK1PZy6VdHpsUd+Xp4qEuAylfQ=="], "rrdom": ["rrdom@2.0.0-alpha.20", "", { "dependencies": { "rrweb-snapshot": "^2.0.0-alpha.20" } }, "sha512-hoqjS4662LtBp82qEz9GrqU36UpEmCvTA2Hns3qdF7cklLFFy3G+0Th8hLytJENleHHWxsB5nWJ3eXz5mSRxdQ=="], diff --git a/config/initializers/mutations.rb b/config/initializers/mutations.rb index 55736760c0..35a70b14e1 100644 --- a/config/initializers/mutations.rb +++ b/config/initializers/mutations.rb @@ -1,3 +1,5 @@ +require Rails.root.join("app/lib/mutations/hstore_filter") + MUTATIONS_DEFAULTS = Mutations::DefaultErrorMessageCreator::MESSAGES # I don't like the errors that mutations provides for :before and :after, diff --git a/frontend/three_d_garden/__tests__/fps_probe_test.tsx b/frontend/three_d_garden/__tests__/fps_probe_test.tsx index fe59be6e61..5c4718ec7c 100644 --- a/frontend/three_d_garden/__tests__/fps_probe_test.tsx +++ b/frontend/three_d_garden/__tests__/fps_probe_test.tsx @@ -1,13 +1,14 @@ import React from "react"; import { render } from "@testing-library/react"; import * as threeFiber from "@react-three/fiber"; -import { countSceneObjects, FPSProbe } from "../fps_probe"; +import { countSceneObjects, FPSProbe, REPORT_EVERY_N } from "../fps_probe"; describe("FPSProbe", () => { let useFrameSpy: jest.SpyInstance; let useThreeSpy: jest.SpyInstance; beforeEach(() => { + window.logStore = undefined; useFrameSpy = jest.spyOn(threeFiber, "useFrame") .mockImplementation(jest.fn()); useThreeSpy = jest.spyOn(threeFiber, "useThree") @@ -92,6 +93,27 @@ describe("FPSProbe", () => { nowSpy.mockRestore(); }); + it("logs an fps report every nth probe", () => { + let t = 0; + const nowSpy = jest.spyOn(performance, "now").mockImplementation(() => { + t += 2000; + return t; + }); + window.logStore = { log: jest.fn() }; + render(); + const frameHandler = useFrameSpy.mock.calls[0][0] as () => void; + for (let i = 0; i < 100; i++) { + frameHandler(); + frameHandler(); + } + expect(window.logStore.log).toHaveBeenCalledWith( + "3D Garden FPS", + { average: 1, best: 1, total: REPORT_EVERY_N, worst: 1 }, + "info", + ); + nowSpy.mockRestore(); + }); + it("counts scene objects", () => { const objects = [ { isMesh: true, type: "Mesh", name: "soil" }, diff --git a/frontend/three_d_garden/bot/components/bounds.tsx b/frontend/three_d_garden/bot/components/bounds.tsx index f8d05ba09f..8e7aca31c7 100644 --- a/frontend/three_d_garden/bot/components/bounds.tsx +++ b/frontend/three_d_garden/bot/components/bounds.tsx @@ -1,15 +1,14 @@ import React from "react"; import { Config } from "../../config"; -import { Line } from "@react-three/drei"; -import { Group } from "../../components"; +import { Box, Edges } from "@react-three/drei"; +import { Group, MeshBasicMaterial } from "../../components"; import { threeSpace, zero as zeroFunc, - extents as extentsFunc, - zZero as zZeroFunc, zDir as zDirFunc, } from "../../helpers"; import { DistanceIndicator } from "../../elements"; +import { BackSide } from "three"; export interface BoundsProps { config: Config; @@ -19,33 +18,33 @@ export const Bounds = (props: BoundsProps) => { const { bedLengthOuter, bedWidthOuter, x, y, z, zAxisLength, columnLength, beamLength, bounds, - bedXOffset, bedYOffset, + bedXOffset, bedYOffset, botSizeX, botSizeY, botSizeZ, } = props.config; - const zZero = zZeroFunc(props.config); const zDir = zDirFunc(props.config); const zero = zeroFunc(props.config); - const extents = extentsFunc(props.config); - const zDip = (x: number, y: number): [number, number, number][] => [ - [x, y, extents.z], - [x, y, zero.z], - [x, y, extents.z], - ]; return - + position={[ + zero.x + botSizeX / 2, + zero.y + botSizeY / 2, + zero.z - botSizeZ / 2, + ]} + args={[ + botSizeX, + botSizeY, + botSizeZ, + ]}> + + + { end={{ x: threeSpace(0, bedLengthOuter), y: threeSpace(bedWidthOuter, bedWidthOuter), - z: zZero - z + zAxisLength, + z: zero.z - z + zAxisLength, }} /> @@ -90,12 +89,12 @@ export const Bounds = (props: BoundsProps) => { start={{ x: threeSpace(x + 100, bedLengthOuter) + bedXOffset, y: threeSpace(y, bedWidthOuter) + bedYOffset, - z: zZero - zDir * z, + z: zero.z - zDir * z, }} end={{ x: threeSpace(x + 100, bedLengthOuter) + bedXOffset, y: threeSpace(y, bedWidthOuter) + bedYOffset, - z: zZero - zDir * z + zAxisLength, + z: zero.z - zDir * z + zAxisLength, }} /> ; diff --git a/frontend/three_d_garden/fps_probe.tsx b/frontend/three_d_garden/fps_probe.tsx index 303ecc3699..c3e9949da9 100644 --- a/frontend/three_d_garden/fps_probe.tsx +++ b/frontend/three_d_garden/fps_probe.tsx @@ -55,9 +55,13 @@ const formatTopCounts = ( return entries.map(([key, value]) => `${key}: ${value}`).join(", "); }; +export const REPORT_EVERY_N = 60; + export const FPSProbe = () => { const frameCount = React.useRef(0); const lastTime = React.useRef(undefined); + const reportCount = React.useRef(0); + const samples = React.useRef([]); const { gl, scene } = useThree(); React.useEffect(() => { @@ -77,6 +81,7 @@ export const FPSProbe = () => { if (now - lastTime.current >= 1000) { const elapsed = (now - lastTime.current) / 1000; const fps = frameCount.current / elapsed; + samples.current.push(fps); const { calls, triangles, points, lines } = gl.info.render; const { geometries, textures } = gl.info.memory; const sceneCounts = countSceneObjects(scene as Scene); @@ -103,6 +108,18 @@ export const FPSProbe = () => { .map(([key, value]) => `${key}: ${value}`) .join("\n"); console.log(linesToLog); + reportCount.current += 1; + const doReport = !(reportCount.current % REPORT_EVERY_N); + const average = Math.round(samples.current + .reduce((sum, sample) => sum + sample, 0) / samples.current.length); + const report = { + best: Math.round(Math.max(...samples.current)), + worst: Math.round(Math.min(...samples.current)), + average, + total: samples.current.length, + }; + doReport && window.logStore?.log("3D Garden FPS", report, "info"); + console.log(report); frameCount.current = 0; lastTime.current = now; } diff --git a/lib/tasks/api.rake b/lib/tasks/api.rake index af2f3e5bd8..4d0cd7e430 100644 --- a/lib/tasks/api.rake +++ b/lib/tasks/api.rake @@ -152,12 +152,17 @@ namespace :api do src = "node_modules/monaco-editor/min/vs" dst = "public/assets/monaco" lua_src = "node_modules/monaco-editor/esm/vs" - lua = "basic-languages/lua" - sh "mkdir -p public/assets/" - sh "cp -r #{src} #{dst}" - sh "rm -rf #{dst}/*language*" - sh "mkdir #{dst}/basic-languages" - sh "cp -r #{lua_src}/#{lua} #{dst}/#{lua}" + sh "mkdir -p public/assets/monaco" + sh "cp -r #{src}/assets #{dst}" + sh "cp -r #{src}/editor #{dst}" + sh "cp -r #{src}/basic-languages #{dst}" + sh "cp -r #{src}/loader.js #{dst}" + sh "cp -r #{src}/workers-*.js #{dst}" + sh "cp -r #{src}/monaco.contribution-*.js #{dst}" + sh "cp -r #{src}/editor.api-*.js #{dst}" + sh "cp -r #{src}/nls.messages-loader.js #{dst}" + sh "cp -r #{src}/lua-*.js #{dst}" + sh "cp -r #{lua_src}/basic-languages/lua #{dst}/basic-languages" end desc "Serve javascript assets (via Bun bundler)." diff --git a/package.json b/package.json index 48f88fcf5e..91f352d139 100644 --- a/package.json +++ b/package.json @@ -35,8 +35,8 @@ "mqtt": "mqtt/dist/mqtt.esm.js" }, "dependencies": { - "@blueprintjs/core": "6.9.1", - "@blueprintjs/select": "6.1.3", + "@blueprintjs/core": "6.10.0", + "@blueprintjs/select": "6.1.4", "@monaco-editor/react": "4.7.0", "@react-spring/three": "10.0.3", "@react-three/drei": "10.7.7", @@ -61,7 +61,7 @@ "farmbot": "15.9.3", "fengari": "0.1.5", "fengari-web": "0.1.4", - "i18next": "25.8.17", + "i18next": "25.8.18", "lodash": "4.17.23", "markdown-it": "14.1.1", "markdown-it-emoji": "3.0.0", @@ -80,7 +80,7 @@ "redux": "5.0.1", "redux-immutable-state-invariant": "2.1.0", "redux-thunk": "3.1.0", - "rollbar": "3.0.0", + "rollbar": "3.1.0", "suncalc": "1.9.0", "takeme": "0.12.0", "three": "0.183.2", @@ -89,7 +89,7 @@ }, "devDependencies": { "@eslint/js": "10.0.1", - "@happy-dom/global-registrator": "20.8.3", + "@happy-dom/global-registrator": "20.8.4", "@react-three/eslint-plugin": "0.1.2", "@testing-library/dom": "10.4.1", "@testing-library/jest-dom": "6.9.1", @@ -99,9 +99,9 @@ "@types/jest": "30.0.0", "@types/readable-stream": "4.0.23", "@types/suncalc": "1.9.2", - "@typescript-eslint/eslint-plugin": "8.57.0", - "@typescript-eslint/parser": "8.57.0", - "happy-dom": "20.8.3", + "@typescript-eslint/eslint-plugin": "8.57.1", + "@typescript-eslint/parser": "8.57.1", + "happy-dom": "20.8.4", "eslint": "10.0.3", "eslint-plugin-eslint-comments": "3.2.0", "eslint-plugin-import": "2.32.0",