diff --git a/package.json b/package.json index 3290203..13915c1 100644 --- a/package.json +++ b/package.json @@ -11,43 +11,40 @@ "eslint": "eslint ./src" }, "dependencies": { - "@babel/runtime": "^7.26.9", + "@babel/runtime": "^7.29.2", "@emoji-mart/data": "^1.2.1", "@emoji-mart/react": "^1.1.1", - "@tanstack/react-virtual": "3.2.0", - "@types/react-transition-group": "^4.4.10", - "dompurify": "^3.1.5", + "@radix-ui/react-popover": "^1.1.6", + "@radix-ui/react-slider": "^1.2.4", + "@tanstack/react-virtual": "3.13.24", + "dompurify": "^3.4.1", "emoji-mart": "^5.6.0", "emoji-toolkit": "10.0.0", - "framer-motion": "^11.2.12", - "react": "^19.2.4", - "react-bootstrap": "^2.10.10", - "react-dom": "^19.2.4", + "framer-motion": "^12.38.0", + "react": "^19.2.5", + "react-dom": "^19.2.5", "react-icons": "^5.5.0", - "react-slider": "^2.0.6", - "react-tiny-popover": "^8.1.6", - "react-youtube": "^10.1.0", + "react-player": "^2.16.0", "use-between": "^1.4.0" }, "devDependencies": { "@tailwindcss/forms": "^0.5.11", - "@tailwindcss/postcss": "^4.2.0", - "@types/node": "^25.3.0", + "@tailwindcss/postcss": "^4.2.4", + "@types/node": "^25.6.0", "@types/react": "^19.2.14", "@types/react-dom": "^19.2.3", - "@types/react-slider": "^1.3.6", - "@typescript-eslint/eslint-plugin": "^8.56.0", - "@typescript-eslint/parser": "^8.56.0", - "@vitejs/plugin-react": "^5.1.4", - "eslint": "^10.0.0", + "@typescript-eslint/eslint-plugin": "^8.59.1", + "@typescript-eslint/parser": "^8.59.1", + "@vitejs/plugin-react": "^6.0.1", + "eslint": "^10.2.1", "eslint-plugin-react": "^7.37.5", - "eslint-plugin-react-hooks": "^7.0.1", - "postcss": "^8.5.6", + "eslint-plugin-react-hooks": "^7.1.1", + "postcss": "^8.5.12", "postcss-nested": "^7.0.2", - "sass": "^1.97.3", - "tailwindcss": "^4.2.0", - "typescript": "^5.9.3", - "typescript-eslint": "^8.56.0", - "vite": "^8.0.8" + "sass": "^1.99.0", + "tailwindcss": "^4.2.4", + "typescript": "^6.0.3", + "typescript-eslint": "^8.59.1", + "vite": "^8.0.10" } } diff --git a/public/configuration/ui-config.example b/public/configuration/ui-config.example index 946e5e0..7510024 100644 --- a/public/configuration/ui-config.example +++ b/public/configuration/ui-config.example @@ -27,8 +27,8 @@ "guides.enabled": true, "toolbar.hide.quests": true, "catalog.style.new": true, - "show.google.ads": false, - "loginview": { + "show.google.ads": false, + "loginview": { "images": { "background": "${asset.url}/c_images/reception/stretch_blue.png", "background.colour": "#6eadc8", @@ -39,1503 +39,148 @@ "right.repeat": "${asset.url}/c_images/reception/US_top_right.png" } }, - "navigator.room.models": [ - { + "navigator.room.models": [{ "clubLevel": 0, "tileSize": 104, "name": "a" - }, - { + }, { "clubLevel": 0, "tileSize": 94, "name": "b" - }, - { + }, { "clubLevel": 0, "tileSize": 36, "name": "c" - }, - { + }, { "clubLevel": 0, "tileSize": 84, "name": "d" - }, - { + }, { "clubLevel": 0, "tileSize": 80, "name": "e" - }, - { + }, { "clubLevel": 0, "tileSize": 80, "name": "f" - }, - { + }, { "clubLevel": 0, "tileSize": 416, "name": "i" - }, - { + }, { "clubLevel": 0, "tileSize": 320, "name": "j" - }, - { + }, { "clubLevel": 0, "tileSize": 448, "name": "k" - }, - { + }, { "clubLevel": 0, "tileSize": 352, "name": "l" - }, - { + }, { "clubLevel": 0, "tileSize": 384, "name": "m" - }, - { + }, { "clubLevel": 0, "tileSize": 372, "name": "n" - }, - { + }, { "clubLevel": 1, "tileSize": 80, "name": "g" - }, - { + }, { "clubLevel": 1, "tileSize": 74, "name": "h" - }, - { + }, { "clubLevel": 1, "tileSize": 416, "name": "o" - }, - { + }, { "clubLevel": 1, "tileSize": 352, "name": "p" - }, - { + }, { "clubLevel": 1, "tileSize": 304, "name": "q" - }, - { + }, { "clubLevel": 1, "tileSize": 336, "name": "r" - }, - { + }, { "clubLevel": 1, "tileSize": 748, "name": "u" - }, - { + }, { "clubLevel": 1, "tileSize": 438, "name": "v" - }, - { + }, { "clubLevel": 2, "tileSize": 540, "name": "t" - }, - { + }, { "clubLevel": 2, "tileSize": 512, "name": "w" - }, - { + }, { "clubLevel": 2, "tileSize": 396, "name": "x" - }, - { + }, { "clubLevel": 2, "tileSize": 440, "name": "y" - }, - { + }, { "clubLevel": 2, "tileSize": 456, "name": "z" - }, - { + }, { "clubLevel": 2, "tileSize": 208, "name": "0" - }, - { + }, { "clubLevel": 2, "tileSize": 1009, "name": "1" - }, - { + }, { "clubLevel": 2, "tileSize": 1044, "name": "2" - }, - { + }, { "clubLevel": 2, "tileSize": 183, "name": "3" - }, - { + }, { "clubLevel": 2, "tileSize": 254, "name": "4" - }, - { + }, { "clubLevel": 2, "tileSize": 1024, "name": "5" - }, - { + }, { "clubLevel": 2, "tileSize": 801, "name": "6" - }, - { + }, { "clubLevel": 2, "tileSize": 354, "name": "7" - }, - { + }, { "clubLevel": 2, "tileSize": 888, "name": "8" - }, - { + }, { "clubLevel": 2, "tileSize": 926, "name": "9" } ], - "backgrounds.data": [ - { - "backgroundId": 0, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 1, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 2, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 3, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 4, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 5, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 6, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 7, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 8, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 9, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 10, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 11, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 12, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 13, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 14, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 15, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 16, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 17, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 18, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 19, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 20, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 21, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 22, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 23, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 24, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 25, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 26, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 27, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 28, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 29, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 30, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 31, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 32, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 33, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 34, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 35, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 36, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 37, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 38, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 39, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 40, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 41, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 42, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 43, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 44, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 45, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 46, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 47, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 48, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 49, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 50, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 51, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 52, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 53, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 54, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 55, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 56, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 57, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 58, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 59, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 60, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 61, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 62, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 63, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 64, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 65, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 66, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 67, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 68, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 69, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 70, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 71, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 72, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 73, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 74, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 75, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 76, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 77, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 78, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 79, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 80, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 81, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 82, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 83, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 84, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 85, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 86, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 87, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 88, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 89, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 90, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 91, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 92, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 93, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 94, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 95, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 96, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 97, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 98, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 99, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 100, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 101, - "minRank": 2, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "backgroundId": 102, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 103, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 104, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 105, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 106, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 107, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 108, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 109, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 110, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 111, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 112, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 113, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 114, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 115, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 116, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 117, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 118, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 119, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 120, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 121, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 122, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 123, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 124, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 125, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 126, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 127, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 128, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 129, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 130, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 131, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 132, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 133, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 134, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 135, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 136, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 137, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 138, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 139, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 140, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 141, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 142, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 143, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 144, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 145, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 146, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 147, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 148, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 149, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 150, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 151, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 152, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 153, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 154, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 155, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 156, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 157, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 158, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 159, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 160, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 161, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 162, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 163, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 164, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 165, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 166, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 167, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 168, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 169, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 170, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 171, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 172, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 173, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 174, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 175, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 176, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 177, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 178, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 179, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 180, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 181, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 182, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 183, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 184, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 185, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 186, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "backgroundId": 187, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - } - ], - "stands.data": [ - { - "standId": 0, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "standId": 1, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "standId": 2, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "standId": 3, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "standId": 4, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "standId": 5, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "standId": 6, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "standId": 7, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "standId": 8, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "standId": 9, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "standId": 10, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "standId": 11, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "standId": 12, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "standId": 13, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "standId": 14, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "standId": 15, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "standId": 16, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "standId": 17, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "standId": 18, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "standId": 19, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "standId": 20, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "standId": 21, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - } - ], - "overlays.data": [ - { - "overlayId": 0, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "overlayId": 1, - "minRank": 0, - "isHcOnly": false, - "isAmbassadorOnly": false - }, - { - "overlayId": 2, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "overlayId": 3, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "overlayId": 4, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "overlayId": 5, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "overlayId": 6, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "overlayId": 7, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - }, - { - "overlayId": 8, - "minRank": 0, - "isHcOnly": true, - "isAmbassadorOnly": false - } - ], "hotelview": { "room.pool": "791", "room.picnic": "2193", @@ -1615,379 +260,325 @@ "catalog.headers": false, "chat.input.maxlength": 100, "chat.styles.disabled": [], - "chat.styles": [ - { + "chat.styles": [{ "styleId": 0, "minRank": 0, "isSystemStyle": false, "isHcOnly": false, "isAmbassadorOnly": false - }, - { + }, { "styleId": 1, "minRank": 5, "isSystemStyle": true, "isHcOnly": false, "isAmbassadorOnly": false - }, - { + }, { "styleId": 2, "minRank": 5, "isSystemStyle": true, "isHcOnly": false, "isAmbassadorOnly": false - }, - { + }, { "styleId": 3, "minRank": 0, "isSystemStyle": false, "isHcOnly": false, "isAmbassadorOnly": false - }, - { + }, { "styleId": 4, "minRank": 0, "isSystemStyle": false, "isHcOnly": false, "isAmbassadorOnly": false - }, - { + }, { "styleId": 5, "minRank": 0, "isSystemStyle": false, "isHcOnly": false, "isAmbassadorOnly": false - }, - { + }, { "styleId": 6, "minRank": 0, "isSystemStyle": false, "isHcOnly": false, "isAmbassadorOnly": false - }, - { + }, { "styleId": 7, "minRank": 0, "isSystemStyle": false, "isHcOnly": false, "isAmbassadorOnly": false - }, - { + }, { "styleId": 8, "minRank": 5, "isSystemStyle": true, "isHcOnly": false, "isAmbassadorOnly": false - }, - { + }, { "styleId": 9, "minRank": 0, "isSystemStyle": false, "isHcOnly": true, "isAmbassadorOnly": false - }, - { + }, { "styleId": 10, "minRank": 0, "isSystemStyle": false, "isHcOnly": true, "isAmbassadorOnly": false - }, - { + }, { "styleId": 11, "minRank": 0, "isSystemStyle": false, "isHcOnly": true, "isAmbassadorOnly": false - }, - { + }, { "styleId": 12, "minRank": 0, "isSystemStyle": false, "isHcOnly": true, "isAmbassadorOnly": false - }, - { + }, { "styleId": 13, "minRank": 0, "isSystemStyle": false, "isHcOnly": true, "isAmbassadorOnly": false - }, - { + }, { "styleId": 14, "minRank": 0, "isSystemStyle": false, "isHcOnly": true, "isAmbassadorOnly": false - }, - { + }, { "styleId": 15, "minRank": 0, "isSystemStyle": false, "isHcOnly": true, "isAmbassadorOnly": false - }, - { + }, { "styleId": 16, "minRank": 0, "isSystemStyle": false, "isHcOnly": true, "isAmbassadorOnly": false - }, - { + }, { "styleId": 17, "minRank": 0, "isSystemStyle": false, "isHcOnly": true, "isAmbassadorOnly": false - }, - { + }, { "styleId": 18, "minRank": 0, "isSystemStyle": false, "isHcOnly": true, "isAmbassadorOnly": false - }, - { + }, { "styleId": 19, "minRank": 0, "isSystemStyle": false, "isHcOnly": true, "isAmbassadorOnly": false - }, - { + }, { "styleId": 20, "minRank": 0, "isSystemStyle": false, "isHcOnly": true, "isAmbassadorOnly": false - }, - { + }, { "styleId": 21, "minRank": 0, "isSystemStyle": false, "isHcOnly": true, "isAmbassadorOnly": false - }, - { + }, { "styleId": 22, "minRank": 0, "isSystemStyle": false, "isHcOnly": true, "isAmbassadorOnly": false - }, - { + }, { "styleId": 23, "minRank": 5, "isSystemStyle": false, "isHcOnly": false, "isAmbassadorOnly": false - }, - { + }, { "styleId": 24, "minRank": 0, "isSystemStyle": false, "isHcOnly": true, "isAmbassadorOnly": false - }, - { + }, { "styleId": 25, "minRank": 0, "isSystemStyle": false, "isHcOnly": true, "isAmbassadorOnly": false - }, - { + }, { "styleId": 26, "minRank": 0, "isSystemStyle": false, "isHcOnly": true, "isAmbassadorOnly": false - }, - { + }, { "styleId": 27, "minRank": 0, "isSystemStyle": false, "isHcOnly": true, "isAmbassadorOnly": false - }, - { + }, { "styleId": 28, "minRank": 0, "isSystemStyle": false, "isHcOnly": true, "isAmbassadorOnly": false - }, - { + }, { "styleId": 29, "minRank": 0, "isSystemStyle": false, "isHcOnly": true, "isAmbassadorOnly": false - }, - { + }, { "styleId": 30, "minRank": 5, "isSystemStyle": true, "isHcOnly": false, "isAmbassadorOnly": false - }, - { + }, { "styleId": 31, "minRank": 5, "isSystemStyle": true, "isHcOnly": false, "isAmbassadorOnly": false - }, - { + }, { "styleId": 32, "minRank": 0, "isSystemStyle": false, "isHcOnly": true, "isAmbassadorOnly": false - }, - { + }, { "styleId": 33, "minRank": 5, "isSystemStyle": true, "isHcOnly": false, "isAmbassadorOnly": false - }, - { + }, { "styleId": 34, "minRank": 5, "isSystemStyle": true, "isHcOnly": false, "isAmbassadorOnly": false - }, - { + }, { "styleId": 35, "minRank": 0, "isSystemStyle": false, "isHcOnly": true, "isAmbassadorOnly": false - }, - { + }, { "styleId": 36, "minRank": 0, "isSystemStyle": false, "isHcOnly": true, "isAmbassadorOnly": false - }, - { + }, { "styleId": 37, "minRank": 5, "isSystemStyle": false, "isHcOnly": false, "isAmbassadorOnly": true - }, - { + }, { "styleId": 38, "minRank": 0, "isSystemStyle": false, "isHcOnly": true, "isAmbassadorOnly": false - }, - { + }, { "styleId": 39, "minRank": 5, "isSystemStyle": false, "isHcOnly": false, "isAmbassadorOnly": true - }, - { + }, { "styleId": 40, "minRank": 5, "isSystemStyle": false, "isHcOnly": false, "isAmbassadorOnly": true - }, - { + }, { "styleId": 41, "minRank": 5, "isSystemStyle": false, "isHcOnly": false, "isAmbassadorOnly": true - }, - { + }, { "styleId": 42, "minRank": 5, "isSystemStyle": false, "isHcOnly": false, "isAmbassadorOnly": true - }, - { + }, { "styleId": 43, "minRank": 5, "isSystemStyle": false, "isHcOnly": false, "isAmbassadorOnly": true - }, - { + }, { "styleId": 44, "minRank": 5, "isSystemStyle": false, "isHcOnly": false, "isAmbassadorOnly": true - }, - { + }, { "styleId": 45, "minRank": 5, "isSystemStyle": false, "isHcOnly": false, "isAmbassadorOnly": true - }, - { + }, { "styleId": 46, "minRank": 5, "isSystemStyle": false, "isHcOnly": false, "isAmbassadorOnly": true - }, - { + }, { "styleId": 47, "minRank": 5, "isSystemStyle": false, "isHcOnly": false, "isAmbassadorOnly": true - }, - { + }, { "styleId": 48, "minRank": 5, "isSystemStyle": false, "isHcOnly": false, "isAmbassadorOnly": true - }, - { + }, { "styleId": 49, "minRank": 5, "isSystemStyle": false, "isHcOnly": false, "isAmbassadorOnly": true - }, - { + }, { "styleId": 50, "minRank": 5, "isSystemStyle": false, "isHcOnly": false, "isAmbassadorOnly": true - }, - { + }, { "styleId": 51, "minRank": 5, "isSystemStyle": false, "isHcOnly": false, "isAmbassadorOnly": true - }, - { + }, { "styleId": 52, "minRank": 5, "isSystemStyle": false, "isHcOnly": false, "isAmbassadorOnly": true - }, - { + }, { "styleId": 53, "minRank": 5, "isSystemStyle": false, @@ -1995,8 +586,7 @@ "isAmbassadorOnly": true } ], - "camera.available.effects": [ - { + "camera.available.effects": [{ "name": "dark_sepia", "colorMatrix": [ 0.4, @@ -2022,8 +612,7 @@ ], "minLevel": 0, "enabled": true - }, - { + }, { "name": "increase_saturation", "colorMatrix": [ 2, @@ -2049,8 +638,7 @@ ], "minLevel": 0, "enabled": true - }, - { + }, { "name": "increase_contrast", "colorMatrix": [ 1.5, @@ -2076,15 +664,13 @@ ], "minLevel": 0, "enabled": true - }, - { + }, { "name": "shadow_multiply_02", "colorMatrix": [], "minLevel": 0, "blendMode": 2, "enabled": true - }, - { + }, { "name": "color_1", "colorMatrix": [ 0.393, @@ -2110,8 +696,7 @@ ], "minLevel": 1, "enabled": true - }, - { + }, { "name": "hue_bright_sat", "colorMatrix": [ 1, @@ -2137,29 +722,25 @@ ], "minLevel": 1, "enabled": true - }, - { + }, { "name": "hearts_hardlight_02", "colorMatrix": [], "minLevel": 1, "blendMode": 9, "enabled": true - }, - { + }, { "name": "texture_overlay", "colorMatrix": [], "minLevel": 1, "blendMode": 4, "enabled": true - }, - { + }, { "name": "pinky_nrm", "colorMatrix": [], "minLevel": 1, "blendMode": 0, "enabled": true - }, - { + }, { "name": "color_2", "colorMatrix": [ 0.333, @@ -2185,8 +766,7 @@ ], "minLevel": 2, "enabled": true - }, - { + }, { "name": "night_vision", "colorMatrix": [ 0, @@ -2212,43 +792,37 @@ ], "minLevel": 2, "enabled": true - }, - { + }, { "name": "stars_hardlight_02", "colorMatrix": [], "minLevel": 2, "blendMode": 9, "enabled": true - }, - { + }, { "name": "coffee_mpl", "colorMatrix": [], "minLevel": 2, "blendMode": 2, "enabled": true - }, - { + }, { "name": "security_hardlight", "colorMatrix": [], "minLevel": 3, "blendMode": 9, "enabled": true - }, - { + }, { "name": "bluemood_mpl", "colorMatrix": [], "minLevel": 3, "blendMode": 2, "enabled": true - }, - { + }, { "name": "rusty_mpl", "colorMatrix": [], "minLevel": 3, "blendMode": 2, "enabled": true - }, - { + }, { "name": "decr_conrast", "colorMatrix": [ 0.5, @@ -2274,8 +848,7 @@ ], "minLevel": 4, "enabled": true - }, - { + }, { "name": "green_2", "colorMatrix": [ 0.5, @@ -2301,15 +874,13 @@ ], "minLevel": 4, "enabled": true - }, - { + }, { "name": "alien_hrd", "colorMatrix": [], "minLevel": 4, "blendMode": 9, "enabled": true - }, - { + }, { "name": "color_3", "colorMatrix": [ 0.609, @@ -2335,8 +906,7 @@ ], "minLevel": 5, "enabled": true - }, - { + }, { "name": "color_4", "colorMatrix": [ 0.8, @@ -2362,15 +932,13 @@ ], "minLevel": 5, "enabled": true - }, - { + }, { "name": "toxic_hrd", "colorMatrix": [], "minLevel": 5, "blendMode": 9, "enabled": true - }, - { + }, { "name": "hypersaturated", "colorMatrix": [ 2, @@ -2396,8 +964,7 @@ ], "minLevel": 6, "enabled": true - }, - { + }, { "name": "Yellow", "colorMatrix": [ 1, @@ -2423,15 +990,13 @@ ], "minLevel": 6, "enabled": true - }, - { + }, { "name": "misty_hrd", "colorMatrix": [], "minLevel": 6, "blendMode": 9, "enabled": true - }, - { + }, { "name": "x_ray", "colorMatrix": [ 0, @@ -2457,8 +1022,7 @@ ], "minLevel": 7, "enabled": true - }, - { + }, { "name": "decrease_saturation", "colorMatrix": [ 0.7, @@ -2484,64 +1048,55 @@ ], "minLevel": 7, "enabled": true - }, - { + }, { "name": "drops_mpl", "colorMatrix": [], "minLevel": 8, "blendMode": 2, "enabled": true - }, - { + }, { "name": "shiny_hrd", "colorMatrix": [], "minLevel": 9, "blendMode": 9, "enabled": true - }, - { + }, { "name": "glitter_hrd", "colorMatrix": [], "minLevel": 10, "blendMode": 9, "enabled": true - }, - { + }, { "name": "frame_gold", "colorMatrix": [], "minLevel": 10, "blendMode": 0, "enabled": true - }, - { + }, { "name": "frame_gray_4", "colorMatrix": [], "minLevel": 10, "blendMode": 0, "enabled": true - }, - { + }, { "name": "frame_black_2", "colorMatrix": [], "minLevel": 10, "blendMode": 0, "enabled": true - }, - { + }, { "name": "frame_wood_2", "colorMatrix": [], "minLevel": 10, "blendMode": 0, "enabled": true - }, - { + }, { "name": "finger_nrm", "colorMatrix": [], "minLevel": 10, "blendMode": 0, "enabled": true - }, - { + }, { "name": "color_5", "colorMatrix": [ 3.309, @@ -2567,8 +1122,7 @@ ], "minLevel": 10, "enabled": true - }, - { + }, { "name": "black_white_negative", "colorMatrix": [ -0.5, @@ -2594,8 +1148,7 @@ ], "minLevel": 10, "enabled": true - }, - { + }, { "name": "blue", "colorMatrix": [ 0.5, @@ -2621,8 +1174,7 @@ ], "minLevel": 10, "enabled": true - }, - { + }, { "name": "red", "colorMatrix": [ 0.5, @@ -2648,8 +1200,7 @@ ], "minLevel": 10, "enabled": true - }, - { + }, { "name": "green", "colorMatrix": [ 0.5, @@ -2786,4 +1337,4 @@ "image": "${image.library.url}/album1584/X1517.gif" } } -} \ No newline at end of file +} diff --git a/public/infostand_backgrounds.json b/public/infostand_backgrounds.json new file mode 100644 index 0000000..3608e73 --- /dev/null +++ b/public/infostand_backgrounds.json @@ -0,0 +1,712 @@ +{ + "backgrounds.data": [ + { + "backgroundId": 0 + }, + { + "backgroundId": 1 + }, + { + "backgroundId": 2 + }, + { + "backgroundId": 3 + }, + { + "backgroundId": 4 + }, + { + "backgroundId": 5 + }, + { + "backgroundId": 6 + }, + { + "backgroundId": 7 + }, + { + "backgroundId": 8 + }, + { + "backgroundId": 9 + }, + { + "backgroundId": 10 + }, + { + "backgroundId": 11 + }, + { + "backgroundId": 12 + }, + { + "backgroundId": 13 + }, + { + "backgroundId": 14 + }, + { + "backgroundId": 15 + }, + { + "backgroundId": 16 + }, + { + "backgroundId": 17 + }, + { + "backgroundId": 18 + }, + { + "backgroundId": 19 + }, + { + "backgroundId": 20 + }, + { + "backgroundId": 21 + }, + { + "backgroundId": 22 + }, + { + "backgroundId": 23 + }, + { + "backgroundId": 24 + }, + { + "backgroundId": 25 + }, + { + "backgroundId": 26 + }, + { + "backgroundId": 27 + }, + { + "backgroundId": 28 + }, + { + "backgroundId": 29 + }, + { + "backgroundId": 30 + }, + { + "backgroundId": 31 + }, + { + "backgroundId": 32 + }, + { + "backgroundId": 33 + }, + { + "backgroundId": 34 + }, + { + "backgroundId": 35 + }, + { + "backgroundId": 36 + }, + { + "backgroundId": 37 + }, + { + "backgroundId": 38 + }, + { + "backgroundId": 39 + }, + { + "backgroundId": 40 + }, + { + "backgroundId": 41 + }, + { + "backgroundId": 42 + }, + { + "backgroundId": 43 + }, + { + "backgroundId": 44 + }, + { + "backgroundId": 45 + }, + { + "backgroundId": 46 + }, + { + "backgroundId": 47 + }, + { + "backgroundId": 48 + }, + { + "backgroundId": 49 + }, + { + "backgroundId": 50 + }, + { + "backgroundId": 51 + }, + { + "backgroundId": 52 + }, + { + "backgroundId": 53 + }, + { + "backgroundId": 54 + }, + { + "backgroundId": 55 + }, + { + "backgroundId": 56 + }, + { + "backgroundId": 57 + }, + { + "backgroundId": 58 + }, + { + "backgroundId": 59 + }, + { + "backgroundId": 60 + }, + { + "backgroundId": 61 + }, + { + "backgroundId": 62 + }, + { + "backgroundId": 63 + }, + { + "backgroundId": 64 + }, + { + "backgroundId": 65 + }, + { + "backgroundId": 66 + }, + { + "backgroundId": 67 + }, + { + "backgroundId": 68 + }, + { + "backgroundId": 69 + }, + { + "backgroundId": 70 + }, + { + "backgroundId": 71 + }, + { + "backgroundId": 72 + }, + { + "backgroundId": 73 + }, + { + "backgroundId": 74 + }, + { + "backgroundId": 75 + }, + { + "backgroundId": 76 + }, + { + "backgroundId": 77 + }, + { + "backgroundId": 78 + }, + { + "backgroundId": 79 + }, + { + "backgroundId": 80 + }, + { + "backgroundId": 81 + }, + { + "backgroundId": 82 + }, + { + "backgroundId": 83 + }, + { + "backgroundId": 84 + }, + { + "backgroundId": 85 + }, + { + "backgroundId": 86 + }, + { + "backgroundId": 87 + }, + { + "backgroundId": 88 + }, + { + "backgroundId": 89 + }, + { + "backgroundId": 90 + }, + { + "backgroundId": 91 + }, + { + "backgroundId": 92 + }, + { + "backgroundId": 93 + }, + { + "backgroundId": 94 + }, + { + "backgroundId": 95 + }, + { + "backgroundId": 96 + }, + { + "backgroundId": 97 + }, + { + "backgroundId": 98 + }, + { + "backgroundId": 99 + }, + { + "backgroundId": 100 + }, + { + "backgroundId": 101 + }, + { + "backgroundId": 102 + }, + { + "backgroundId": 103 + }, + { + "backgroundId": 104 + }, + { + "backgroundId": 105 + }, + { + "backgroundId": 106 + }, + { + "backgroundId": 107 + }, + { + "backgroundId": 108 + }, + { + "backgroundId": 109 + }, + { + "backgroundId": 110 + }, + { + "backgroundId": 111 + }, + { + "backgroundId": 112 + }, + { + "backgroundId": 113 + }, + { + "backgroundId": 114 + }, + { + "backgroundId": 115 + }, + { + "backgroundId": 116 + }, + { + "backgroundId": 117 + }, + { + "backgroundId": 118 + }, + { + "backgroundId": 119 + }, + { + "backgroundId": 120 + }, + { + "backgroundId": 121 + }, + { + "backgroundId": 122 + }, + { + "backgroundId": 123 + }, + { + "backgroundId": 124 + }, + { + "backgroundId": 125 + }, + { + "backgroundId": 126 + }, + { + "backgroundId": 127 + }, + { + "backgroundId": 128 + }, + { + "backgroundId": 129 + }, + { + "backgroundId": 130 + }, + { + "backgroundId": 131 + }, + { + "backgroundId": 132 + }, + { + "backgroundId": 133 + }, + { + "backgroundId": 134 + }, + { + "backgroundId": 135 + }, + { + "backgroundId": 136 + }, + { + "backgroundId": 137 + }, + { + "backgroundId": 138 + }, + { + "backgroundId": 139 + }, + { + "backgroundId": 140 + }, + { + "backgroundId": 141 + }, + { + "backgroundId": 142 + }, + { + "backgroundId": 143 + }, + { + "backgroundId": 144 + }, + { + "backgroundId": 145 + }, + { + "backgroundId": 146 + }, + { + "backgroundId": 147 + }, + { + "backgroundId": 148 + }, + { + "backgroundId": 149 + }, + { + "backgroundId": 150 + }, + { + "backgroundId": 151 + }, + { + "backgroundId": 152 + }, + { + "backgroundId": 153 + }, + { + "backgroundId": 154 + }, + { + "backgroundId": 155 + }, + { + "backgroundId": 156 + }, + { + "backgroundId": 157 + }, + { + "backgroundId": 158 + }, + { + "backgroundId": 159 + }, + { + "backgroundId": 160 + }, + { + "backgroundId": 161 + }, + { + "backgroundId": 162 + }, + { + "backgroundId": 163 + }, + { + "backgroundId": 164 + }, + { + "backgroundId": 165 + }, + { + "backgroundId": 166 + }, + { + "backgroundId": 167 + }, + { + "backgroundId": 168 + }, + { + "backgroundId": 169 + }, + { + "backgroundId": 170 + }, + { + "backgroundId": 171 + }, + { + "backgroundId": 172 + }, + { + "backgroundId": 173 + }, + { + "backgroundId": 174 + }, + { + "backgroundId": 175 + }, + { + "backgroundId": 176 + }, + { + "backgroundId": 177 + }, + { + "backgroundId": 178 + }, + { + "backgroundId": 179 + }, + { + "backgroundId": 180 + }, + { + "backgroundId": 181 + }, + { + "backgroundId": 182 + }, + { + "backgroundId": 183 + }, + { + "backgroundId": 184 + }, + { + "backgroundId": 185 + }, + { + "backgroundId": 186 + }, + { + "backgroundId": 187 + } + ], + "stands.data": [ + { + "standId": 0 + }, + { + "standId": 1 + }, + { + "standId": 2 + }, + { + "standId": 3 + }, + { + "standId": 4 + }, + { + "standId": 5 + }, + { + "standId": 6 + }, + { + "standId": 7 + }, + { + "standId": 8 + }, + { + "standId": 9 + }, + { + "standId": 10 + }, + { + "standId": 11 + }, + { + "standId": 12 + }, + { + "standId": 13 + }, + { + "standId": 14 + }, + { + "standId": 15 + }, + { + "standId": 16 + }, + { + "standId": 17 + }, + { + "standId": 18 + }, + { + "standId": 19 + }, + { + "standId": 20 + }, + { + "standId": 21 + } + ], + "overlays.data": [ + { + "overlayId": 0 + }, + { + "overlayId": 1 + }, + { + "overlayId": 2 + }, + { + "overlayId": 3 + }, + { + "overlayId": 4 + }, + { + "overlayId": 5 + }, + { + "overlayId": 6 + }, + { + "overlayId": 7 + }, + { + "overlayId": 8 + } + ], + "cards.data": [ + { + "backgroundId": 1 + }, + { + "backgroundId": 2 + }, + { + "backgroundId": 3 + }, + { + "backgroundId": 4 + }, + { + "backgroundId": 5 + }, + { + "backgroundId": 6 + }, + { + "backgroundId": 7 + }, + { + "backgroundId": 8 + }, + { + "backgroundId": 9 + }, + { + "backgroundId": 10 + }, + { + "backgroundId": 11 + }, + { + "backgroundId": 12 + }, + { + "backgroundId": 13 + }, + { + "backgroundId": 14 + }, + { + "backgroundId": 15 + } + ] +} diff --git a/src/api/auth/accessToken.ts b/src/api/auth/accessToken.ts new file mode 100644 index 0000000..1d53575 --- /dev/null +++ b/src/api/auth/accessToken.ts @@ -0,0 +1,52 @@ +const STORAGE_KEY = 'nitro.access.token'; +const EXPIRES_KEY = 'nitro.access.token.exp'; + +export const setAccessToken = (token: string | null | undefined, expiresAt?: number | null): void => +{ + try + { + if(token && typeof token === 'string') + { + window.localStorage.setItem(STORAGE_KEY, token); + if(typeof expiresAt === 'number' && expiresAt > 0) window.localStorage.setItem(EXPIRES_KEY, String(expiresAt)); + else window.localStorage.removeItem(EXPIRES_KEY); + } + else + { + window.localStorage.removeItem(STORAGE_KEY); + window.localStorage.removeItem(EXPIRES_KEY); + } + } + catch {} +}; + +export const getAccessToken = (): string => +{ + try { return window.localStorage.getItem(STORAGE_KEY) ?? ''; } + catch { return ''; } +}; + +export const getAccessTokenExpiresAt = (): number => +{ + try + { + const raw = window.localStorage.getItem(EXPIRES_KEY); + if(!raw) return 0; + const value = parseInt(raw, 10); + return Number.isFinite(value) ? value : 0; + } + catch { return 0; } +}; + +export const clearAccessToken = (): void => +{ + setAccessToken(null); +}; + +export const persistAccessTokenFromPayload = (payload: Record | null | undefined): void => +{ + if(!payload) return; + const token = typeof payload.accessToken === 'string' ? payload.accessToken : ''; + const expiresAt = typeof payload.accessTokenExpiresAt === 'number' ? payload.accessTokenExpiresAt : null; + if(token) setAccessToken(token, expiresAt); +}; diff --git a/src/api/auth/index.ts b/src/api/auth/index.ts new file mode 100644 index 0000000..865e7c0 --- /dev/null +++ b/src/api/auth/index.ts @@ -0,0 +1 @@ +export * from './accessToken'; diff --git a/src/api/avatar/AvatarEditorThumbnailsHelper.ts b/src/api/avatar/AvatarEditorThumbnailsHelper.ts index c319d2a..5176436 100644 --- a/src/api/avatar/AvatarEditorThumbnailsHelper.ts +++ b/src/api/avatar/AvatarEditorThumbnailsHelper.ts @@ -224,12 +224,11 @@ export class AvatarEditorThumbnailsHelper const texture = avatarImage.processAsTexture(AvatarSetType.HEAD, false); const sprite = new NitroSprite(texture); - if(isDisabled) sprite.filters = [ AvatarEditorThumbnailsHelper.ALPHA_FILTER ]; - + const frame = AvatarEditorThumbnailsHelper.findOpaqueBoundsFrame(sprite, texture.width, texture.height); const imageUrl = await TextureUtils.generateImageUrl({ target: sprite, - frame: new NitroRectangle(0, 0, texture.width, texture.height) + frame }); sprite.destroy(); @@ -244,6 +243,49 @@ export class AvatarEditorThumbnailsHelper }); } + private static findOpaqueBoundsFrame(sprite: NitroSprite, fallbackWidth: number, fallbackHeight: number): NitroRectangle + { + try + { + const data = TextureUtils.getPixels(sprite); + if(!data) return new NitroRectangle(0, 0, fallbackWidth, fallbackHeight); + + const pixels = data.pixels as Uint8ClampedArray | Uint8Array; + const width = data.width; + const height = data.height; + if(!pixels || width <= 0 || height <= 0) return new NitroRectangle(0, 0, fallbackWidth, fallbackHeight); + const ALPHA_THRESHOLD = 8; + + let minX = width; + let minY = height; + let maxX = -1; + let maxY = -1; + + for(let y = 0; y < height; y++) + { + const rowStart = y * width * 4; + for(let x = 0; x < width; x++) + { + if(pixels[rowStart + (x * 4) + 3] > ALPHA_THRESHOLD) + { + if(x < minX) minX = x; + if(x > maxX) maxX = x; + if(y < minY) minY = y; + if(y > maxY) maxY = y; + } + } + } + + if(maxX < minX || maxY < minY) return new NitroRectangle(0, 0, fallbackWidth, fallbackHeight); + + return new NitroRectangle(minX, minY, (maxX - minX) + 1, (maxY - minY) + 1); + } + catch + { + return new NitroRectangle(0, 0, fallbackWidth, fallbackHeight); + } + } + private static sortByDrawOrder(a: IFigurePart, b: IFigurePart): number { const indexA = AvatarEditorThumbnailsHelper.DRAW_ORDER.indexOf(a.type); diff --git a/src/api/badges/CustomBadgeApi.ts b/src/api/badges/CustomBadgeApi.ts new file mode 100644 index 0000000..9e6eeca --- /dev/null +++ b/src/api/badges/CustomBadgeApi.ts @@ -0,0 +1,172 @@ +import { GetConfiguration, GetLocalizationManager } from '@nitrots/nitro-renderer'; +import { getAccessToken } from '../auth'; + +export interface CustomBadgeRecord +{ + badgeId: string; + badgeCode: string; + name: string; + description: string; + dateCreated: number; + dateEdit: number; + url: string; +} + +export interface CustomBadgeListResponse +{ + badges: CustomBadgeRecord[]; + max: number; + badgeWidth: number; + badgeHeight: number; + maxBadgeSizeBytes: number; + priceBadge?: number; + currencyType?: number; +} + +export interface CustomBadgeError +{ + error: string; + code?: string; +} + +const interpolate = (value: string): string => +{ + try { return GetConfiguration().interpolate(value); } + catch { return value; } +}; + +const getConfigUrl = (key: string, fallback: string): string => + interpolate(GetConfiguration().getValue(key, fallback)); + +const buildUrl = (key: string, fallback: string, badgeId?: string): string => +{ + const template = getConfigUrl(key, fallback); + if(!badgeId) return template; + if(template.includes('%badgeId%')) return template.replace(/%badgeId%/g, encodeURIComponent(badgeId)); + return template + (template.endsWith('/') ? '' : '/') + encodeURIComponent(badgeId); +}; + +const authHeaders = (): Record => +{ + const headers: Record = { + 'Accept': 'application/json', + 'X-Requested-With': 'NitroCustomBadges' + }; + const token = getAccessToken(); + if(token) headers['Authorization'] = `Bearer ${ token }`; + return headers; +}; + +const parseJson = async (response: Response): Promise => +{ + const text = await response.text(); + if(!text) return {} as T; + try { return JSON.parse(text) as T; } + catch { throw new Error('Invalid response from server.'); } +}; + +const throwOnError = async (response: Response): Promise => +{ + if(response.ok) return; + const payload = await parseJson(response); + const message = payload?.error || `Request failed (${ response.status }).`; + const err = new Error(message) as Error & { status: number; code?: string }; + err.status = response.status; + if(payload?.code) err.code = payload.code; + throw err; +}; + +export const fetchCustomBadges = async (): Promise => +{ + const url = buildUrl('badges.custom.list.endpoint', '/api/badges/custom'); + const response = await fetch(url, { method: 'GET', credentials: 'include', headers: authHeaders() }); + await throwOnError(response); + return parseJson(response); +}; + +export const createCustomBadge = async (body: { name: string; description: string; image: string }): Promise => +{ + const url = buildUrl('badges.custom.create.endpoint', '/api/badges/custom'); + const response = await fetch(url, { + method: 'POST', + credentials: 'include', + headers: { ...authHeaders(), 'Content-Type': 'application/json' }, + body: JSON.stringify(body) + }); + await throwOnError(response); + return parseJson(response); +}; + +export const updateCustomBadge = async (badgeId: string, body: { name: string; description: string; image: string }): Promise => +{ + const url = buildUrl('badges.custom.update.endpoint', '/api/badges/custom/%badgeId%', badgeId); + const response = await fetch(url, { + method: 'PUT', + credentials: 'include', + headers: { ...authHeaders(), 'Content-Type': 'application/json' }, + body: JSON.stringify(body) + }); + await throwOnError(response); + return parseJson(response); +}; + +export const deleteCustomBadge = async (badgeId: string): Promise => +{ + const url = buildUrl('badges.custom.delete.endpoint', '/api/badges/custom/%badgeId%', badgeId); + const response = await fetch(url, { method: 'DELETE', credentials: 'include', headers: authHeaders() }); + await throwOnError(response); +}; + +export const isCustomBadgeCode = (code: string | null | undefined): boolean => +{ + if(!code) return false; + return /^CUST[A-Z0-9]{5}-\d+$/.test(code); +}; + +let customBadgeTextsLoadPromise: Promise | null = null; + +const injectTextsIntoLocalization = (texts: Record | null | undefined): void => +{ + if(!texts) return; + let manager: ReturnType | null = null; + try { manager = GetLocalizationManager(); } + catch { return; } + if(!manager || typeof manager.setValue !== 'function') return; + for(const key of Object.keys(texts)) + { + const value = texts[key]; + if(typeof value === 'string') manager.setValue(key, value); + } +}; + +export const ensureCustomBadgeTexts = (): Promise => +{ + if(customBadgeTextsLoadPromise) return customBadgeTextsLoadPromise; + customBadgeTextsLoadPromise = (async () => + { + try + { + const url = buildUrl('badges.custom.texts.endpoint', '/api/badges/custom/texts'); + const response = await fetch(url, { method: 'GET', credentials: 'include', headers: { 'Accept': 'application/json' } }); + if(!response.ok) return; + const payload = await parseJson<{ texts: Record }>(response); + injectTextsIntoLocalization(payload.texts); + } + catch {} + })(); + return customBadgeTextsLoadPromise; +}; + +export const refreshCustomBadgeTexts = (): Promise => +{ + customBadgeTextsLoadPromise = null; + return ensureCustomBadgeTexts(); +}; + +export const setCustomBadgeText = (badgeId: string, name: string, description: string): void => +{ + injectTextsIntoLocalization({ + [`badge_name_${ badgeId }`]: name || badgeId, + [`badge_desc_${ badgeId }`]: description || '' + }); +}; diff --git a/src/api/badges/index.ts b/src/api/badges/index.ts new file mode 100644 index 0000000..75e2cd1 --- /dev/null +++ b/src/api/badges/index.ts @@ -0,0 +1 @@ +export * from './CustomBadgeApi'; diff --git a/src/api/index.ts b/src/api/index.ts index 0f11ac4..6bb1536 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -1,7 +1,9 @@ export * from './GetRendererVersion'; export * from './GetUIVersion'; export * from './achievements'; +export * from './auth'; export * from './avatar'; +export * from './badges'; export * from './camera'; export * from './campaign'; export * from './catalog'; diff --git a/src/api/room/widgets/AvatarInfoUser.ts b/src/api/room/widgets/AvatarInfoUser.ts index 6c2b3e8..2d3157e 100644 --- a/src/api/room/widgets/AvatarInfoUser.ts +++ b/src/api/room/widgets/AvatarInfoUser.ts @@ -23,6 +23,7 @@ export class AvatarInfoUser implements IAvatarInfo public backgroundId: number = 0; public standId: number = 0; public overlayId: number = 0; + public cardBackgroundId: number = 0; public webID: number = 0; public xp: number = 0; public userType: number = -1; diff --git a/src/api/room/widgets/AvatarInfoUtilities.ts b/src/api/room/widgets/AvatarInfoUtilities.ts index 96403bf..a2d0b45 100644 --- a/src/api/room/widgets/AvatarInfoUtilities.ts +++ b/src/api/room/widgets/AvatarInfoUtilities.ts @@ -191,6 +191,7 @@ export class AvatarInfoUtilities userInfo.backgroundId = userData.background; userInfo.standId = userData.stand; userInfo.overlayId = userData.overlay; + userInfo.cardBackgroundId = userData.cardBackground ?? 0; userInfo.achievementScore = userData.activityPoints; userInfo.webID = userData.webID; userInfo.roomIndex = userData.roomIndex; diff --git a/src/common/Slider.tsx b/src/common/Slider.tsx index 72fb74c..8cd7490 100644 --- a/src/common/Slider.tsx +++ b/src/common/Slider.tsx @@ -1,35 +1,148 @@ -import { FC } from 'react'; -import ReactSlider, { ReactSliderProps } from 'react-slider'; +import * as RadixSlider from '@radix-ui/react-slider'; +import { CSSProperties, FC, HTMLProps, ReactElement } from 'react'; +import { FaAngleLeft, FaAngleRight } from 'react-icons/fa'; import { Button } from './Button'; import { Flex } from './Flex'; -import { FaAngleLeft, FaAngleRight } from 'react-icons/fa'; -export interface SliderProps extends ReactSliderProps +export interface SliderThumbState { - disabledButton?: boolean; + index: number; + value: number | number[]; + valueNow: number; } +export interface SliderProps +{ + min?: number; + max?: number; + step?: number; + value?: number | number[]; + defaultValue?: number | number[]; + onChange?: (value: any, thumbIndex: number) => void; + disabled?: boolean; + disabledButton?: boolean; + invert?: boolean; + className?: string; + style?: CSSProperties; + trackClassName?: string; + thumbClassName?: string; + renderThumb?: (props: HTMLProps, state: SliderThumbState) => ReactElement; +} + +const toArray = (value: number | number[] | undefined): number[] => +{ + if(Array.isArray(value)) return value; + if(typeof value === 'number') return [ value ]; + + return [ 0 ]; +}; + +const cn = (...parts: (string | undefined | false)[]) => parts.filter(Boolean).join(' '); + export const Slider: FC = props => { - const { disabledButton, max, min, step, value, onChange, ...rest } = props; - const currentValue = Array.isArray(value) ? value[0] : ((typeof value === 'number') ? value : 0); + const { + disabledButton, + disabled, + max = 100, + min = 0, + step = 1, + value, + defaultValue, + onChange, + invert, + className, + style, + trackClassName, + thumbClassName, + renderThumb + } = props; + + const valueArr = toArray(value); + const currentValue = valueArr[0] ?? 0; const minimum = (typeof min === 'number') ? min : 0; const maximum = (typeof max === 'number') ? max : 0; const buttonStep = ((typeof step === 'number') && (step > 0)) ? step : 1; + const isRange = valueArr.length > 1; const roundToStep = (nextValue: number) => { - if(typeof buttonStep !== 'number') return nextValue; - const decimalStep = buttonStep.toString(); const precision = decimalStep.includes('.') ? (decimalStep.length - decimalStep.indexOf('.') - 1) : 0; return parseFloat(nextValue.toFixed(precision)); }; - return - { !disabledButton && } - - { !disabledButton && } - ; + const emit = (next: number[]) => + { + if(!onChange) return; + + if(isRange) onChange(next, 0); + else onChange(next[0], 0); + }; + + const stepDown = () => + { + const next = roundToStep(minimum < currentValue ? currentValue - buttonStep : minimum); + + emit([ next, ...valueArr.slice(1) ]); + }; + + const stepUp = () => + { + const next = roundToStep(maximum > currentValue ? currentValue + buttonStep : maximum); + + emit([ next, ...valueArr.slice(1) ]); + }; + + const renderThumbElement = (i: number) => + { + const baseProps: HTMLProps = { + key: i, + className: cn('thumb', `thumb-${ i }`, thumbClassName) + }; + + const state: SliderThumbState = { + index: i, + value: isRange ? valueArr : currentValue, + valueNow: valueArr[i] ?? 0 + }; + + return ( + + { renderThumb ? renderThumb(baseProps, state) :
} + + ); + }; + + return ( + + { !disabledButton && ( + + ) } + + + + + { valueArr.map((_, i) => renderThumbElement(i)) } + + { !disabledButton && ( + + ) } + + ); } diff --git a/src/common/layout/LayoutBadgeImageView.tsx b/src/common/layout/LayoutBadgeImageView.tsx index 75a6533..7162627 100644 --- a/src/common/layout/LayoutBadgeImageView.tsx +++ b/src/common/layout/LayoutBadgeImageView.tsx @@ -1,5 +1,6 @@ import { BadgeImageReadyEvent, GetEventDispatcher, GetSessionDataManager, NitroSprite, TextureUtils } from '@nitrots/nitro-renderer'; -import { CSSProperties, FC, useEffect, useMemo, useState } from 'react'; +import { CSSProperties, FC, useEffect, useMemo, useRef, useState } from 'react'; +import { createPortal } from 'react-dom'; import { GetConfigurationValue, LocalizeBadgeDescription, LocalizeBadgeName, LocalizeText } from '../../api'; import { Base, BaseProps } from '../Base'; @@ -17,6 +18,26 @@ export const LayoutBadgeImageView: FC = props => { const { badgeCode = null, isGroup = false, showInfo = false, customTitle = null, isGrayscale = false, scale = 1, classNames = [], style = {}, children = null, ...rest } = props; const [ imageElement, setImageElement ] = useState(null); + const [ tooltipPosition, setTooltipPosition ] = useState<{ top: number; left: number } | null>(null); + const badgeRef = useRef(null); + + const tooltipsEnabled = showInfo && GetConfigurationValue('badge.descriptions.enabled', true); + + const showTooltip = () => + { + if(!tooltipsEnabled || !badgeRef.current) return; + + const rect = badgeRef.current.getBoundingClientRect(); + const tooltipWidth = 210; + const gap = 10; + let left = rect.left - tooltipWidth - gap; + + if(left < gap) left = rect.right + gap; + + setTooltipPosition({ top: rect.top, left }); + }; + + const hideTooltip = () => setTooltipPosition(null); const getClassNames = useMemo(() => { @@ -116,12 +137,22 @@ export const LayoutBadgeImageView: FC = props => }, [ badgeCode, isGroup ]); return ( - - { (showInfo && GetConfigurationValue('badge.descriptions.enabled', true)) && - + + { tooltipsEnabled && tooltipPosition && createPortal( +
{ isGroup ? customTitle : LocalizeBadgeName(badgeCode) }
{ isGroup ? LocalizeText('group.badgepopup.body') : LocalizeBadgeDescription(badgeCode) }
- } +
, + document.body + ) } { children } ); diff --git a/src/common/transitions/TransitionAnimation.tsx b/src/common/transitions/TransitionAnimation.tsx index 8e34849..db90938 100644 --- a/src/common/transitions/TransitionAnimation.tsx +++ b/src/common/transitions/TransitionAnimation.tsx @@ -1,6 +1,6 @@ -import { FC, ReactNode, useEffect, useState } from 'react'; -import { Transition } from 'react-transition-group'; -import { getTransitionAnimationStyle } from './TransitionAnimationStyles'; +import { AnimatePresence, motion, Variants } from 'framer-motion'; +import { FC, ReactNode } from 'react'; +import { getTransitionVariants } from './TransitionAnimationStyles'; interface TransitionAnimationProps { @@ -15,38 +15,22 @@ export const TransitionAnimation: FC = props => { const { type = null, inProp = false, timeout = 300, className = null, children = null } = props; - const [ isChildrenVisible, setChildrenVisible ] = useState(false); - - useEffect(() => - { - let timeoutData: ReturnType = null; - - if(inProp) - { - setChildrenVisible(true); - } - else - { - timeoutData = setTimeout(() => - { - setChildrenVisible(false); - clearTimeout(timeout); - }, timeout); - } - - return () => - { - if(timeoutData) clearTimeout(timeoutData); - }; - }, [ inProp, timeout ]); + const variants: Variants = getTransitionVariants(type); + const duration = timeout / 1000; return ( - - { state => ( -
- { isChildrenVisible && children } -
+ + { inProp && ( + + { children } + ) } -
+ ); }; diff --git a/src/common/transitions/TransitionAnimationStyles.ts b/src/common/transitions/TransitionAnimationStyles.ts index feebdcc..ab7315e 100644 --- a/src/common/transitions/TransitionAnimationStyles.ts +++ b/src/common/transitions/TransitionAnimationStyles.ts @@ -1,136 +1,66 @@ -import { CSSProperties } from 'react'; -import { TransitionStatus } from 'react-transition-group'; -import { ENTERING, EXITING } from 'react-transition-group/Transition'; +import { Variants } from 'framer-motion'; import { TransitionAnimationTypes } from './TransitionAnimationTypes'; -export function getTransitionAnimationStyle(type: string, transition: TransitionStatus, timeout: number = 300): Partial +export function getTransitionVariants(type: string): Variants { switch(type) { case TransitionAnimationTypes.BOUNCE: - switch(transition) - { - default: - return {}; - case ENTERING: - return { - animationName: 'bounceIn', - animationDuration: `${ timeout }ms` - }; - case EXITING: - return { - animationName: 'bounceOut', - animationDuration: `${ timeout }ms` - }; - } + return { + hidden: { opacity: 0, scale: 0.3 }, + visible: { opacity: 1, scale: 1, transition: { type: 'spring', stiffness: 260, damping: 12 } }, + exit: { opacity: 0, scale: 0.3 } + }; case TransitionAnimationTypes.SLIDE_LEFT: - switch(transition) - { - default: - return {}; - case ENTERING: - return { - animationName: 'slideInLeft', - animationDuration: `${ timeout }ms` - }; - case EXITING: - return { - animationName: 'slideOutLeft', - animationDuration: `${ timeout }ms` - }; - } + return { + hidden: { opacity: 0, x: '-100%' }, + visible: { opacity: 1, x: 0 }, + exit: { opacity: 0, x: '-100%' } + }; case TransitionAnimationTypes.SLIDE_RIGHT: - switch(transition) - { - default: - return {}; - case ENTERING: - return { - animationName: 'slideInRight', - animationDuration: `${ timeout }ms` - }; - case EXITING: - return { - animationName: 'slideOutRight', - animationDuration: `${ timeout }ms` - }; - } + return { + hidden: { opacity: 0, x: '100%' }, + visible: { opacity: 1, x: 0 }, + exit: { opacity: 0, x: '100%' } + }; case TransitionAnimationTypes.FLIP_X: - switch(transition) - { - default: - return {}; - case ENTERING: - return { - animationName: 'flipInX', - animationDuration: `${ timeout }ms` - }; - case EXITING: - return { - animationName: 'flipOutX', - animationDuration: `${ timeout }ms` - }; - } + return { + hidden: { opacity: 0, rotateX: 90 }, + visible: { opacity: 1, rotateX: 0 }, + exit: { opacity: 0, rotateX: 90 } + }; case TransitionAnimationTypes.FADE_UP: - switch(transition) - { - default: - return {}; - case ENTERING: - return { - animationName: 'fadeInUp', - animationDuration: `${ timeout }ms` - }; - case EXITING: - return { - animationName: 'fadeOutDown', - animationDuration: `${ timeout }ms` - }; - } + return { + hidden: { opacity: 0, y: 20 }, + visible: { opacity: 1, y: 0 }, + exit: { opacity: 0, y: 20 } + }; case TransitionAnimationTypes.FADE_IN: - switch(transition) - { - default: - return {}; - case ENTERING: - return { - animationName: 'fadeIn', - animationDuration: `${ timeout }ms` - }; - case EXITING: - return { - animationName: 'fadeOut', - animationDuration: `${ timeout }ms` - }; - } + return { + hidden: { opacity: 0 }, + visible: { opacity: 1 }, + exit: { opacity: 0 } + }; case TransitionAnimationTypes.FADE_DOWN: - switch(transition) - { - default: - return {}; - case ENTERING: - return { - animationName: 'fadeInDown', - animationDuration: `${ timeout }ms` - }; - case EXITING: - return { - animationName: 'fadeOutUp', - animationDuration: `${ timeout }ms` - }; - } + return { + hidden: { opacity: 0, y: -20 }, + visible: { opacity: 1, y: 0 }, + exit: { opacity: 0, y: -20 } + }; case TransitionAnimationTypes.HEAD_SHAKE: - switch(transition) - { - default: - return {}; - case ENTERING: - return { - animationName: 'headShake', - animationDuration: `${ timeout }ms` - }; - } + return { + hidden: { x: 0 }, + visible: { + x: [ 0, -6, 5, -3, 2, 0 ], + transition: { duration: 0.5 } + }, + exit: { x: 0 } + }; } - return null; + return { + hidden: {}, + visible: {}, + exit: {} + }; } diff --git a/src/components/MainView.tsx b/src/components/MainView.tsx index 7611982..7861454 100644 --- a/src/components/MainView.tsx +++ b/src/components/MainView.tsx @@ -4,6 +4,8 @@ import { FC, useEffect, useState } from 'react'; import { useNitroEvent } from '../hooks'; import { AchievementsView } from './achievements/AchievementsView'; import { AvatarEditorView } from './avatar-editor'; +import { BadgeCreatorView } from './badge-creator'; +import { AvatarEffectsView } from './avatar-effects'; import { CameraWidgetView } from './camera/CameraWidgetView'; import { CampaignView } from './campaign/CampaignView'; import { CatalogView } from './catalog/CatalogView'; @@ -121,6 +123,8 @@ export const MainView: FC<{}> = props => + + diff --git a/src/components/avatar-editor/AvatarEditorModelView.tsx b/src/components/avatar-editor/AvatarEditorModelView.tsx index 612773d..1656996 100644 --- a/src/components/avatar-editor/AvatarEditorModelView.tsx +++ b/src/components/avatar-editor/AvatarEditorModelView.tsx @@ -89,13 +89,13 @@ export const AvatarEditorModelView: FC<{
{ advancedColorMode ? - : } + : }
} { (maxPaletteCount === 2) &&
{ advancedColorMode ? - : } + : }
}
diff --git a/src/components/avatar-editor/AvatarEditorView.tsx b/src/components/avatar-editor/AvatarEditorView.tsx index a150bec..e3197b5 100644 --- a/src/components/avatar-editor/AvatarEditorView.tsx +++ b/src/components/avatar-editor/AvatarEditorView.tsx @@ -78,7 +78,8 @@ export const AvatarEditorView: FC<{}> = props => return ( setIsVisible(false) } /> diff --git a/src/components/avatar-editor/figure-set/AvatarEditorFigureSetItemView.tsx b/src/components/avatar-editor/figure-set/AvatarEditorFigureSetItemView.tsx index 31c88a6..08c7c67 100644 --- a/src/components/avatar-editor/figure-set/AvatarEditorFigureSetItemView.tsx +++ b/src/components/avatar-editor/figure-set/AvatarEditorFigureSetItemView.tsx @@ -77,7 +77,7 @@ export const AvatarEditorFigureSetItemView: FC<{ itemActive={ isSelected } itemImage={ (!partItem.isClear && isHead) ? assetUrl : undefined } className={ `avatar-parts mx-auto${ isSelected ? ' part-selected' : '' }${ !partItem.isClear && isSellableNotOwned ? ' pet-sellable-locked' : '' }` } - style={ isHead ? { backgroundSize: '200%', backgroundPosition: 'center -32px' } : undefined } + style={ isHead ? { backgroundSize: 'auto 80%', backgroundPosition: 'center', imageRendering: 'pixelated' } : undefined } { ...rest } > { !partItem.isClear && assetUrl && !isHead && diff --git a/src/components/avatar-editor/figure-set/AvatarEditorFigureSetView.tsx b/src/components/avatar-editor/figure-set/AvatarEditorFigureSetView.tsx index 179f894..3def2bc 100644 --- a/src/components/avatar-editor/figure-set/AvatarEditorFigureSetView.tsx +++ b/src/components/avatar-editor/figure-set/AvatarEditorFigureSetView.tsx @@ -30,12 +30,12 @@ export const AvatarEditorFigureSetView: FC<{ }; return ( - columnCount={ columnCount } estimateSize={ estimateSize } itemRender={ (item: IAvatarEditorCategoryPartItem) => + columnCount={ columnCount } itemMinWidth={ 42 } rowGap={ 8 } estimateSize={ estimateSize } itemRender={ (item: IAvatarEditorCategoryPartItem) => { if(!item) return null; return ( - selectEditorPart(category.setType, item.partSet?.id ?? -1) } /> + selectEditorPart(category.setType, item.partSet?.id ?? -1) } /> ); } } items={ category.partItems } overscan={ columnCount } /> ); diff --git a/src/components/avatar-effects/AvatarEffectPreviewView.tsx b/src/components/avatar-effects/AvatarEffectPreviewView.tsx new file mode 100644 index 0000000..b68d7d0 --- /dev/null +++ b/src/components/avatar-effects/AvatarEffectPreviewView.tsx @@ -0,0 +1,76 @@ +import { GetRoomEngine, RoomPreviewer } from '@nitrots/nitro-renderer'; +import { CSSProperties, FC, useEffect, useState } from 'react'; +import { LayoutRoomPreviewerView } from '../../common'; + +interface AvatarEffectPreviewViewProps +{ + figure: string; + gender: string; + direction: number; + effect: number; + height?: number; + zoom?: number; +} + +export const AvatarEffectPreviewView: FC = props => +{ + const { figure = '', gender = 'M', direction = 4, effect = 0, height = 280, zoom = 1 } = props; + const [ roomPreviewer, setRoomPreviewer ] = useState(null); + + const renderHeight = Math.floor(height / zoom); + + useEffect(() => + { + const previewer = new RoomPreviewer(GetRoomEngine(), ++RoomPreviewer.PREVIEW_COUNTER); + setRoomPreviewer(previewer); + + return () => + { + previewer.dispose(); + setRoomPreviewer(null); + }; + }, []); + + useEffect(() => + { + if(!roomPreviewer || !figure) return; + + roomPreviewer.addAvatarIntoRoom(figure, effect); + roomPreviewer.updateObjectUserFigure(figure, gender); + }, [ roomPreviewer, figure, gender, effect ]); + + useEffect(() => + { + if(!roomPreviewer) return; + roomPreviewer.updateAvatarDirection(direction, direction); + }, [ roomPreviewer, direction ]); + + if(!roomPreviewer) return null; + + if(zoom === 1) + { + return ; + } + + const outerStyle: CSSProperties = { + position: 'absolute', + inset: 0, + overflow: 'hidden' + }; + + const innerStyle: CSSProperties = { + width: `${ 100 / zoom }%`, + height: `${ 100 / zoom }%`, + transform: `scale(${ zoom })`, + transformOrigin: 'top left', + imageRendering: 'pixelated' + }; + + return ( +
+
+ +
+
+ ); +}; diff --git a/src/components/avatar-effects/AvatarEffectsView.tsx b/src/components/avatar-effects/AvatarEffectsView.tsx new file mode 100644 index 0000000..14d4b89 --- /dev/null +++ b/src/components/avatar-effects/AvatarEffectsView.tsx @@ -0,0 +1,271 @@ +import { AddLinkEventTracker, AvatarDirectionAngle, AvatarEffectActivatedComposer, GetConfiguration, GetSessionDataManager, ILinkEventTracker, RemoveLinkEventTracker } from '@nitrots/nitro-renderer'; +import { ChangeEvent, FC, useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { FaChevronLeft, FaChevronRight, FaSearch } from 'react-icons/fa'; +import { LocalizeText, SendMessageComposer } from '../../api'; +import { Button, Column, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../common'; +import { AvatarEffectPreviewView } from './AvatarEffectPreviewView'; + +interface EffectMapEntry +{ + id: string; + lib: string; + type: string; + revision?: string | number; +} + +const DEFAULT_DIRECTION = 4; +const PAGE_SIZE = 50; + +export const AvatarEffectsView: FC<{}> = () => +{ + const [ isVisible, setIsVisible ] = useState(false); + const [ effects, setEffects ] = useState([]); + const [ loadError, setLoadError ] = useState(null); + const [ selectedId, setSelectedId ] = useState(0); + const [ direction, setDirection ] = useState(DEFAULT_DIRECTION); + const [ query, setQuery ] = useState(''); + const [ visibleCount, setVisibleCount ] = useState(PAGE_SIZE); + + useEffect(() => + { + const linkTracker: ILinkEventTracker = { + linkReceived: (url: string) => + { + const parts = url.split('/'); + if(parts.length < 2) return; + + switch(parts[1]) + { + case 'show': setIsVisible(true); return; + case 'hide': setIsVisible(false); return; + case 'toggle': setIsVisible(prev => !prev); return; + } + }, + eventUrlPrefix: 'avatar-effects/' + }; + + AddLinkEventTracker(linkTracker); + + return () => RemoveLinkEventTracker(linkTracker); + }, []); + + useEffect(() => + { + if(!isVisible || effects.length || loadError) return; + + const url = GetConfiguration().getValue('avatar.effectmap.url'); + if(!url) + { + setLoadError('Effect map URL is not configured.'); + return; + } + + let cancelled = false; + (async () => + { + try + { + const response = await fetch(url); + if(!response.ok) throw new Error(`HTTP ${ response.status }`); + const json = await response.json(); + if(cancelled) return; + + const list: EffectMapEntry[] = Array.isArray(json?.effects) + ? json.effects.filter((e: EffectMapEntry) => e?.type === 'fx' && /^\d+$/.test(String(e.id))) + : []; + + list.sort((a, b) => parseInt(a.id, 10) - parseInt(b.id, 10)); + setEffects(list); + } + catch(error) + { + if(!cancelled) setLoadError(String((error as Error).message ?? error)); + } + })(); + + return () => { cancelled = true; }; + }, [ isVisible, effects.length, loadError ]); + + const session = GetSessionDataManager(); + const figure = session?.figure ?? ''; + const gender = session?.gender ?? 'M'; + + const rotateFigure = useCallback((delta: number) => + { + setDirection(prev => + { + let next = prev + delta; + if(next < AvatarDirectionAngle.MIN_DIRECTION) next = AvatarDirectionAngle.MAX_DIRECTION; + if(next > AvatarDirectionAngle.MAX_DIRECTION) next = AvatarDirectionAngle.MIN_DIRECTION; + return next; + }); + }, []); + + const applySelectedEffect = useCallback(() => + { + if(!selectedId) return; + SendMessageComposer(new AvatarEffectActivatedComposer(selectedId)); + setIsVisible(false); + }, [ selectedId ]); + + const onClose = useCallback(() => setIsVisible(false), []); + + const filteredEffects = useMemo(() => + { + const trimmed = query.trim().toLowerCase(); + if(!trimmed) return effects; + return effects.filter(e => + e.id.toLowerCase().includes(trimmed) || + e.lib.toLowerCase().includes(trimmed)); + }, [ effects, query ]); + + const onQueryChange = useCallback((event: ChangeEvent) => + { + setQuery(event.target.value); + setVisibleCount(PAGE_SIZE); + }, []); + + const visibleEffects = filteredEffects.slice(0, visibleCount); + const hasMore = filteredEffects.length > visibleEffects.length; + const selectedEffect = selectedId ? effects.find(e => parseInt(e.id, 10) === selectedId) : null; + + const selectedRowRef = useRef(null); + + const jumpToSelected = useCallback(() => + { + if(!selectedId) return; + + const indexInFiltered = filteredEffects.findIndex(e => parseInt(e.id, 10) === selectedId); + const indexInAll = effects.findIndex(e => parseInt(e.id, 10) === selectedId); + + if(indexInFiltered === -1) + { + setQuery(''); + if(indexInAll >= 0 && indexInAll >= visibleCount) + { + setVisibleCount(Math.ceil((indexInAll + 1) / PAGE_SIZE) * PAGE_SIZE); + } + } + else if(indexInFiltered >= visibleCount) + { + setVisibleCount(Math.ceil((indexInFiltered + 1) / PAGE_SIZE) * PAGE_SIZE); + } + + requestAnimationFrame(() => + { + selectedRowRef.current?.scrollIntoView({ behavior: 'smooth', block: 'center' }); + }); + }, [ selectedId, filteredEffects, effects, visibleCount ]); + + if(!isVisible) return null; + + return ( + + + + +
+ +
+ + +
+ { selectedEffect && +
+
#{ parseInt(selectedEffect.id, 10) }
+
{ selectedEffect.lib }
+
+ } +
+ +
+ +
+ + +
+
+ { filteredEffects.length === effects.length ? `${ effects.length } effects` : `${ filteredEffects.length } of ${ effects.length }` } + { selectedId > 0 && + } +
+
+ { loadError &&
{ loadError }
} + { !loadError && !effects.length &&
{ LocalizeText('generic.loading') || 'Loading…' }
} + { !!effects.length && !filteredEffects.length && +
{ LocalizeText('generic.search.noresults') || 'No effects match your search.' }
+ } + { !!visibleEffects.length && +
    + { visibleEffects.map((effect, index) => + { + const id = parseInt(effect.id, 10); + const isSelected = (id === selectedId); + return ( +
  • + +
  • + ); + }) } + { hasMore && +
  • + +
  • + } +
+ } +
+
+
+
+ ); +}; diff --git a/src/components/avatar-effects/index.ts b/src/components/avatar-effects/index.ts new file mode 100644 index 0000000..17f1000 --- /dev/null +++ b/src/components/avatar-effects/index.ts @@ -0,0 +1,2 @@ +export * from './AvatarEffectPreviewView'; +export * from './AvatarEffectsView'; diff --git a/src/components/backgrounds/BackgroundsView.tsx b/src/components/backgrounds/BackgroundsView.tsx index 9782dd6..dc347f3 100644 --- a/src/components/backgrounds/BackgroundsView.tsx +++ b/src/components/backgrounds/BackgroundsView.tsx @@ -1,15 +1,10 @@ -import { GetSessionDataManager, HabboClubLevelEnum} from '@nitrots/nitro-renderer'; import { Dispatch, FC, SetStateAction, useCallback, useMemo, useState } from 'react'; -import { Base, Grid, Flex, NitroCardView, NitroCardHeaderView, NitroCardTabsView, NitroCardTabsItemView, NitroCardContentView, Text, LayoutCurrencyIcon } from '../../common'; +import { Base, Grid, Flex, NitroCardView, NitroCardHeaderView, NitroCardTabsView, NitroCardTabsItemView, NitroCardContentView, Text } from '../../common'; import { useRoom } from '../../hooks'; -import { GetClubMemberLevel, GetConfigurationValue } from '../../api'; +import { GetConfigurationValue } from '../../api'; -interface ItemData { +interface ItemData { id: number; - isHcOnly: boolean; - minRank: number; - isAmbassadorOnly: boolean; - selectable: boolean; } interface BackgroundsViewProps { @@ -20,9 +15,11 @@ interface BackgroundsViewProps { setSelectedStand: Dispatch>; selectedOverlay: number; setSelectedOverlay: Dispatch>; + selectedCardBackground: number; + setSelectedCardBackground: Dispatch>; } -const TABS = ['backgrounds', 'stands', 'overlays'] as const; +const TABS = ['backgrounds', 'stands', 'overlays', 'cards'] as const; type TabType = typeof TABS[number]; export const BackgroundsView: FC = ({ @@ -32,57 +29,49 @@ export const BackgroundsView: FC = ({ selectedStand, setSelectedStand, selectedOverlay, - setSelectedOverlay + setSelectedOverlay, + selectedCardBackground, + setSelectedCardBackground }) => { const [activeTab, setActiveTab] = useState('backgrounds'); const { roomSession } = useRoom(); - - const userData = useMemo(() => ({ - isHcMember: GetClubMemberLevel() >= HabboClubLevelEnum.CLUB, - securityLevel: GetSessionDataManager().canChangeName, - isAmbassador: GetSessionDataManager().isAmbassador - }), []); - const processData = useCallback((configData: any[], dataType: string): ItemData[] => { + const processData = useCallback((configData: any[], idField: string): ItemData[] => { if (!configData?.length) return []; - - return configData - .filter(item => { - const meetsRank = userData.securityLevel >= item.minRank; - const ambassadorEligible = !item.isAmbassadorOnly || userData.isAmbassador; - return item.isHcOnly || (meetsRank && ambassadorEligible); - }) - .map(item => ({ id: item[`${dataType}Id`], ...item, selectable: !item.isHcOnly || userData.isHcMember })); - }, [userData]); + + return configData.map(item => ({ id: item[idField] })); + }, []); const allData = useMemo(() => ({ - backgrounds: processData(GetConfigurationValue('backgrounds.data'), 'background'), - stands: processData(GetConfigurationValue('stands.data'), 'stand'), - overlays: processData(GetConfigurationValue('overlays.data'), 'overlay') + backgrounds: processData(GetConfigurationValue('backgrounds.data'), 'backgroundId'), + stands: processData(GetConfigurationValue('stands.data'), 'standId'), + overlays: processData(GetConfigurationValue('overlays.data'), 'overlayId'), + cards: processData(GetConfigurationValue('cards.data') || GetConfigurationValue('backgrounds.data'), 'backgroundId') }), [processData]); const handleSelection = useCallback((id: number) => { if (!roomSession) return; - const setters = { backgrounds: setSelectedBackground, stands: setSelectedStand, overlays: setSelectedOverlay }; - - const currentValues = { backgrounds: selectedBackground, stands: selectedStand, overlays: selectedOverlay }; + const setters = { backgrounds: setSelectedBackground, stands: setSelectedStand, overlays: setSelectedOverlay, cards: setSelectedCardBackground }; + + const currentValues = { backgrounds: selectedBackground, stands: selectedStand, overlays: selectedOverlay, cards: selectedCardBackground }; setters[activeTab](id); const newValues = { ...currentValues, [activeTab]: id }; - roomSession.sendBackgroundMessage( newValues.backgrounds, newValues.stands, newValues.overlays ); - }, [activeTab, roomSession, selectedBackground, selectedStand, selectedOverlay, setSelectedBackground, setSelectedStand, setSelectedOverlay]); + roomSession.sendBackgroundMessage( newValues.backgrounds, newValues.stands, newValues.overlays, newValues.cards ); + }, [activeTab, roomSession, selectedBackground, selectedStand, selectedOverlay, selectedCardBackground, setSelectedBackground, setSelectedStand, setSelectedOverlay, setSelectedCardBackground]); const renderItem = useCallback((item: ItemData, type: string) => ( item.selectable && handleSelection(item.id)} - className={item.selectable ? '' : 'non-selectable'} + onClick={() => handleSelection(item.id)} > - - {item.isHcOnly && } + ), [handleSelection]); @@ -103,7 +92,7 @@ export const BackgroundsView: FC = ({ Select an Option - {allData[activeTab].map(item => renderItem(item, activeTab.slice(0, -1)))} + {allData[activeTab].map(item => renderItem(item, activeTab === 'cards' ? 'card-background' : activeTab.slice(0, -1)))}
diff --git a/src/components/badge-creator/BadgeCreatorView.tsx b/src/components/badge-creator/BadgeCreatorView.tsx new file mode 100644 index 0000000..e8d9db1 --- /dev/null +++ b/src/components/badge-creator/BadgeCreatorView.tsx @@ -0,0 +1,629 @@ +import { AddLinkEventTracker, ILinkEventTracker, RemoveLinkEventTracker } from '@nitrots/nitro-renderer'; +import { FC, MouseEvent as ReactMouseEvent, useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { LocalizeText } from '../../api'; +import { createCustomBadge, CustomBadgeRecord, deleteCustomBadge, ensureCustomBadgeTexts, fetchCustomBadges, refreshCustomBadgeTexts, setCustomBadgeText, updateCustomBadge } from '../../api/badges'; +import { Button, Column, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../common'; +import { useNotification } from '../../hooks'; + +const t = (key: string, fallback: string, params?: string[], replacements?: string[]): string => +{ + try + { + const value = LocalizeText(key, params ?? null, replacements ?? null); + if(value && value !== key) return value; + } + catch {} + + if(!params || !replacements) return fallback; + let out = fallback; + for(let i = 0; i < params.length; i++) + { + if(replacements[i] !== undefined) out = out.replace('%' + params[i] + '%', replacements[i]); + } + return out; +}; + +const GRID_WIDTH = 40; +const GRID_HEIGHT = 40; +const PIXEL_DISPLAY_SIZE = 12; +const TRANSPARENT = 0; + +const PALETTE: number[] = [ + 0xFF000000, 0xFF4F4F4F, 0xFF808080, 0xFFB0B0B0, 0xFFD8D8D8, 0xFFFFFFFF, TRANSPARENT, 0xFF7B0000, + 0xFFBF0000, 0xFFFF0000, 0xFFFF7777, 0xFFFF7700, 0xFFFFAA00, 0xFFFFD700, 0xFFFFEB3B, 0xFF003E1F, + 0xFF006837, 0xFF00A653, 0xFF2BC93C, 0xFF00C8A0, 0xFF00BCFF, 0xFF2962FF, 0xFF1A237E, 0xFF4A0072, + 0xFF9C00B5, 0xFFE91E63, 0xFFFF80AB, 0xFF5D2E1A, 0xFF8B5A2B, 0xFFC28E5E, 0xFFF1D7B6, 0xFFE8C3A0 +]; + +const currencyName = (type: number): string => +{ + if(type === -1) return 'credits'; + if(type === 0) return 'duckets'; + if(type === 5) return 'diamonds'; + return `currency #${ type }`; +}; + +type Tool = 'paint' | 'erase' | 'picker' | 'fill'; + +const floodFill = (grid: Uint32Array, w: number, h: number, startX: number, startY: number, replacement: number): Uint32Array => +{ + if(startX < 0 || startY < 0 || startX >= w || startY >= h) return grid; + const startIdx = startY * w + startX; + const target = grid[startIdx]; + if(target === replacement) return grid; + + const next = new Uint32Array(grid.length); + next.set(grid); + + const stack: number[] = [ startIdx ]; + while(stack.length) + { + const idx = stack.pop() as number; + if(next[idx] !== target) continue; + next[idx] = replacement; + const x = idx % w; + const y = (idx - x) / w; + if(x > 0) stack.push(idx - 1); + if(x < w - 1) stack.push(idx + 1); + if(y > 0) stack.push(idx - w); + if(y < h - 1) stack.push(idx + w); + } + return next; +}; + +const argbToCss = (argb: number): string => +{ + if(argb === TRANSPARENT) return 'transparent'; + const a = ((argb >>> 24) & 0xff) / 255; + const r = (argb >>> 16) & 0xff; + const g = (argb >>> 8) & 0xff; + const b = argb & 0xff; + return `rgba(${ r }, ${ g }, ${ b }, ${ a })`; +}; + +const argbToHex = (argb: number): string => +{ + if(argb === TRANSPARENT) return '#000000'; + const r = (argb >>> 16) & 0xff; + const g = (argb >>> 8) & 0xff; + const b = argb & 0xff; + return '#' + [ r, g, b ].map(c => c.toString(16).padStart(2, '0')).join(''); +}; + +const hexToArgb = (hex: string): number => +{ + const match = /^#?([0-9a-f]{6})$/i.exec(hex || ''); + if(!match) return 0xFF000000; + return (0xFF000000 | parseInt(match[1], 16)) >>> 0; +}; + +const emptyGrid = (): Uint32Array => new Uint32Array(GRID_WIDTH * GRID_HEIGHT); + +const cloneGrid = (src: Uint32Array): Uint32Array => +{ + const copy = new Uint32Array(src.length); + copy.set(src); + return copy; +}; + +const gridToPngBase64 = async (grid: Uint32Array): Promise<{ b64: string; bytes: number }> => +{ + const canvas = document.createElement('canvas'); + canvas.width = GRID_WIDTH; + canvas.height = GRID_HEIGHT; + const ctx = canvas.getContext('2d'); + if(!ctx) throw new Error('Canvas not supported.'); + + const image = ctx.createImageData(GRID_WIDTH, GRID_HEIGHT); + for(let i = 0; i < grid.length; i++) + { + const argb = grid[i]; + const o = i * 4; + image.data[o] = (argb >>> 16) & 0xff; + image.data[o + 1] = (argb >>> 8) & 0xff; + image.data[o + 2] = argb & 0xff; + image.data[o + 3] = (argb >>> 24) & 0xff; + } + ctx.putImageData(image, 0, 0); + + const blob: Blob = await new Promise((resolve, reject) => canvas.toBlob(b => b ? resolve(b) : reject(new Error('PNG encode failed.')), 'image/png')); + const arrayBuffer = await blob.arrayBuffer(); + const bytes = arrayBuffer.byteLength; + let binary = ''; + const u8 = new Uint8Array(arrayBuffer); + for(let i = 0; i < u8.length; i++) binary += String.fromCharCode(u8[i]); + return { b64: window.btoa(binary), bytes }; +}; + +const loadGridFromUrl = (url: string): Promise => + new Promise((resolve, reject) => + { + const image = new Image(); + image.crossOrigin = 'anonymous'; + image.onload = () => + { + try + { + const canvas = document.createElement('canvas'); + canvas.width = GRID_WIDTH; + canvas.height = GRID_HEIGHT; + const ctx = canvas.getContext('2d'); + if(!ctx) return reject(new Error('Canvas not supported.')); + ctx.clearRect(0, 0, GRID_WIDTH, GRID_HEIGHT); + ctx.drawImage(image, 0, 0, GRID_WIDTH, GRID_HEIGHT); + const data = ctx.getImageData(0, 0, GRID_WIDTH, GRID_HEIGHT).data; + const grid = emptyGrid(); + for(let i = 0; i < grid.length; i++) + { + const o = i * 4; + const a = data[o + 3]; + if(a === 0) { grid[i] = 0; continue; } + grid[i] = ((a & 0xff) << 24) | ((data[o] & 0xff) << 16) | ((data[o + 1] & 0xff) << 8) | (data[o + 2] & 0xff); + } + resolve(grid); + } + catch(err) { reject(err); } + }; + image.onerror = () => reject(new Error('Could not load badge image (CORS?).')); + image.src = url + (url.includes('?') ? '&' : '?') + 't=' + Date.now(); + }); + +export const BadgeCreatorView: FC<{}> = () => +{ + const [ isVisible, setIsVisible ] = useState(false); + const [ grid, setGrid ] = useState(() => emptyGrid()); + const [ selectedColor, setSelectedColor ] = useState(PALETTE[0]); + const [ tool, setTool ] = useState('paint'); + const [ showGrid, setShowGrid ] = useState(true); + const [ name, setName ] = useState(''); + const [ description, setDescription ] = useState(''); + const [ editingBadgeId, setEditingBadgeId ] = useState(null); + const [ badges, setBadges ] = useState(null); + const [ pendingEditBadgeId, setPendingEditBadgeId ] = useState(null); + const [ maxBadges, setMaxBadges ] = useState(5); + const [ maxBytes, setMaxBytes ] = useState(40960); + const [ priceBadge, setPriceBadge ] = useState(0); + const [ currencyType, setCurrencyType ] = useState(-1); + const [ submitting, setSubmitting ] = useState(false); + const [ error, setError ] = useState(null); + + const { showConfirm } = useNotification(); + + const refresh = useCallback(async () => + { + try + { + const data = await fetchCustomBadges(); + setBadges(data.badges ?? []); + if(typeof data.max === 'number') setMaxBadges(data.max); + if(typeof data.maxBadgeSizeBytes === 'number') setMaxBytes(data.maxBadgeSizeBytes); + if(typeof data.priceBadge === 'number') setPriceBadge(data.priceBadge); + if(typeof data.currencyType === 'number') setCurrencyType(data.currencyType); + } + catch(err) + { + setBadges([]); + setError((err as Error)?.message || 'Could not load badges.'); + } + }, []); + + useEffect(() => + { + const tracker: ILinkEventTracker = { + linkReceived: (url: string) => + { + const parts = url.split('/'); + if(parts.length < 2) return; + switch(parts[1]) + { + case 'show': setIsVisible(true); return; + case 'hide': setIsVisible(false); return; + case 'toggle': setIsVisible(v => !v); return; + case 'edit': + if(!parts[2]) return; + setPendingEditBadgeId(parts[2]); + setIsVisible(true); + return; + } + }, + eventUrlPrefix: 'badge-creator/' + }; + AddLinkEventTracker(tracker); + return () => RemoveLinkEventTracker(tracker); + }, []); + + useEffect(() => { if(isVisible) { refresh(); ensureCustomBadgeTexts(); } }, [ isVisible, refresh ]); + + const resetEditor = useCallback(() => + { + setGrid(emptyGrid()); + setName(''); + setDescription(''); + setEditingBadgeId(null); + setError(null); + }, []); + + const startEdit = useCallback(async (badge: CustomBadgeRecord) => + { + setError(null); + setEditingBadgeId(badge.badgeId); + setName(badge.name || ''); + setDescription(badge.description || ''); + try + { + const loaded = await loadGridFromUrl(badge.url); + setGrid(loaded); + } + catch(err) + { + setError((err as Error)?.message || 'Could not load that badge.'); + setGrid(emptyGrid()); + } + }, []); + + useEffect(() => + { + if(!pendingEditBadgeId || !badges) return; + const target = badges.find(b => b.badgeId === pendingEditBadgeId); + if(!target) return; + setPendingEditBadgeId(null); + startEdit(target); + }, [ pendingEditBadgeId, badges, startEdit ]); + + const paintAt = useCallback((x: number, y: number, isClick: boolean) => + { + if(x < 0 || y < 0 || x >= GRID_WIDTH || y >= GRID_HEIGHT) return; + const idx = y * GRID_WIDTH + x; + + if(tool === 'picker') + { + const cell = grid[idx]; + if(cell !== TRANSPARENT) setSelectedColor(cell); + setTool('paint'); + return; + } + + if(tool === 'fill') + { + if(!isClick) return; + setGrid(floodFill(grid, GRID_WIDTH, GRID_HEIGHT, x, y, selectedColor)); + return; + } + + const value = (tool === 'erase') ? TRANSPARENT : selectedColor; + if(grid[idx] === value) return; + const next = cloneGrid(grid); + next[idx] = value; + setGrid(next); + }, [ grid, selectedColor, tool ]); + + const isDraggingRef = useRef(false); + const colorInputRef = useRef(null); + const mainCanvasRef = useRef(null); + const previewCanvasRef = useRef(null); + + useEffect(() => + { + const targets = [ mainCanvasRef.current, previewCanvasRef.current ]; + for(const canvas of targets) + { + if(!canvas) continue; + const ctx = canvas.getContext('2d'); + if(!ctx) continue; + const image = ctx.createImageData(GRID_WIDTH, GRID_HEIGHT); + const buffer = image.data; + for(let i = 0; i < grid.length; i++) + { + const v = grid[i]; + const o = i * 4; + buffer[o] = (v >>> 16) & 0xff; + buffer[o + 1] = (v >>> 8) & 0xff; + buffer[o + 2] = v & 0xff; + buffer[o + 3] = (v >>> 24) & 0xff; + } + ctx.putImageData(image, 0, 0); + } + }, [ grid, isVisible ]); + + const openColorPicker = useCallback(() => + { + const input = colorInputRef.current; + if(!input) return; + input.value = argbToHex(selectedColor); + input.click(); + }, [ selectedColor ]); + + const handleColorPicked = useCallback((event: React.ChangeEvent) => + { + setSelectedColor(hexToArgb(event.target.value)); + setTool('paint'); + }, []); + + const cellFromEvent = useCallback((event: ReactMouseEvent): { x: number; y: number } => + { + const rect = event.currentTarget.getBoundingClientRect(); + const x = Math.floor(((event.clientX - rect.left) / rect.width) * GRID_WIDTH); + const y = Math.floor(((event.clientY - rect.top) / rect.height) * GRID_HEIGHT); + return { x, y }; + }, []); + + const handleMouseDown = useCallback((event: ReactMouseEvent) => + { + if(event.button !== 0) return; + event.preventDefault(); + isDraggingRef.current = true; + const { x, y } = cellFromEvent(event); + paintAt(x, y, true); + }, [ cellFromEvent, paintAt ]); + + const handleMouseMove = useCallback((event: ReactMouseEvent) => + { + if(!isDraggingRef.current) return; + const { x, y } = cellFromEvent(event); + paintAt(x, y, false); + }, [ cellFromEvent, paintAt ]); + + useEffect(() => + { + const stopDrag = () => { isDraggingRef.current = false; }; + window.addEventListener('mouseup', stopDrag); + return () => window.removeEventListener('mouseup', stopDrag); + }, []); + + const clearCanvas = useCallback(() => setGrid(emptyGrid()), []); + + const copyColor = useCallback(() => setTool('picker'), []); + + const isEmpty = useMemo(() => + { + for(let i = 0; i < grid.length; i++) if(grid[i] !== 0) return false; + return true; + }, [ grid ]); + + const canCreateMore = (badges?.length ?? 0) < maxBadges; + + const handleSave = useCallback(async () => + { + if(submitting) return; + if(isEmpty) { setError(t('badgecreator.error.empty', 'Draw something first.')); return; } + if(!editingBadgeId && !canCreateMore) + { + setError(t('badgecreator.error.limit', 'You already have %max% custom badges.', [ 'max' ], [ String(maxBadges) ])); + return; + } + + setSubmitting(true); + setError(null); + try + { + const { b64, bytes } = await gridToPngBase64(grid); + if(bytes > maxBytes) + { + setError(t('badgecreator.error.too_large', `Image is too large (${ bytes } / %max% bytes).`, [ 'max' ], [ String(maxBytes) ])); + return; + } + const body = { name: name.trim(), description: description.trim(), image: b64 }; + const saved = editingBadgeId + ? await updateCustomBadge(editingBadgeId, body) + : await createCustomBadge(body); + if(saved && saved.badgeId) setCustomBadgeText(saved.badgeId, saved.name, saved.description); + await refresh(); + refreshCustomBadgeTexts(); + resetEditor(); + } + catch(err) + { + setError((err as Error)?.message || 'Could not save the badge.'); + } + finally + { + setSubmitting(false); + } + }, [ submitting, isEmpty, editingBadgeId, canCreateMore, maxBadges, grid, maxBytes, name, description, refresh, resetEditor ]); + + const handleDelete = useCallback((badge: CustomBadgeRecord) => + { + showConfirm( + t('badgecreator.delete.confirm', 'Delete "%name%"?', [ 'name' ], [ badge.name || badge.badgeId ]), + async () => + { + try + { + await deleteCustomBadge(badge.badgeId); + if(editingBadgeId === badge.badgeId) resetEditor(); + await refresh(); + refreshCustomBadgeTexts(); + } + catch(err) + { + setError((err as Error)?.message || 'Could not delete the badge.'); + } + }, + null, null, null, + t('badgecreator.delete.title', 'Delete badge') + ); + }, [ showConfirm, editingBadgeId, refresh, resetEditor ]); + + if(!isVisible) return null; + + return ( + + setIsVisible(false) } /> + + + +
+ +
+ + + + + + + + +
+ +
+ { t('badgecreator.palette', 'Palette') } +
+ { PALETTE.map((color, idx) => + { + const isTransparent = color === TRANSPARENT; + const isSelected = color === selectedColor; + return ( +
+
+ +
+ { argbToHex(selectedColor).toUpperCase() } + +
+
+
+ { t('badgecreator.preview', 'Preview') } +
+ +
+
+
+ { t('badgecreator.name', 'Name') } + setName(e.target.value) } /> +
+
+ { t('badgecreator.description', 'Description') } + setDescription(e.target.value) } /> +
+ { error && { error } } + { !editingBadgeId && priceBadge > 0 && + + { t('badgecreator.price', 'Cost: %price% %currency%', [ 'price', 'currency' ], [ String(priceBadge), currencyName(currencyType) ]) } + } + + + { editingBadgeId && + } + + + + + + { t('badgecreator.list.title', 'Your custom badges (%count%/%max%)', [ 'count', 'max' ], [ String(badges?.length ?? 0), String(maxBadges) ]) } + + { badges === null && { t('badgecreator.list.loading', 'Loading…') } } + { badges !== null && !badges.length && { t('badgecreator.list.empty', 'You haven\'t made any badges yet.') } } + { badges !== null && badges.map(badge => ( + + { + + { badge.name || badge.badgeId } + { badge.description && { badge.description } } + + + + + )) } + + + + ); +}; diff --git a/src/components/badge-creator/index.ts b/src/components/badge-creator/index.ts new file mode 100644 index 0000000..d12515e --- /dev/null +++ b/src/components/badge-creator/index.ts @@ -0,0 +1 @@ +export * from './BadgeCreatorView'; diff --git a/src/components/friends/views/friends-bar/FriendBarItemView.tsx b/src/components/friends/views/friends-bar/FriendBarItemView.tsx index 9e05f78..61a6d42 100644 --- a/src/components/friends/views/friends-bar/FriendBarItemView.tsx +++ b/src/components/friends/views/friends-bar/FriendBarItemView.tsx @@ -33,7 +33,7 @@ export const FriendBarItemView: FC<{ friend: MessengerFriend }> = props => { onClick={() => setVisible(prev => !prev)} >
-
{LocalizeText('friend.bar.find.title')}
+
{LocalizeText('friend.bar.find.title')}
@@ -45,10 +45,10 @@ export const FriendBarItemView: FC<{ friend: MessengerFriend }> = props => { transition={{ type: "spring", stiffness: 400, damping: 25 }} className="absolute bottom-[calc(100%+12px)] left-1/2 -translate-x-1/2 tbme-panel whitespace-nowrap z-[80] flex flex-col items-center gap-2 pointer-events-auto min-w-[170px]" > -
{LocalizeText('friend.bar.find.title')}
+
{LocalizeText('friend.bar.find.title')}
{LocalizeText('friend.bar.find.text')}
+ + +
columnCount={ 5 } estimateSize={ 50 } @@ -242,8 +317,12 @@ export const InventoryBadgeView: FC<{ filteredBadgeCodes?: string[] }> = props = onClick={ event => toggleBadge(selectedBadgeCode) }> { LocalizeText(isWearingBadge(selectedBadgeCode) ? 'inventory.badges.clearbadge' : 'inventory.badges.wearbadge') } + { isOwnCustomBadge(selectedBadgeCode) && + + + } { !isWearingBadge(selectedBadgeCode) && - + }
diff --git a/src/components/login/components/ForgotDialog.tsx b/src/components/login/components/ForgotDialog.tsx new file mode 100644 index 0000000..65cffa8 --- /dev/null +++ b/src/components/login/components/ForgotDialog.tsx @@ -0,0 +1,72 @@ +import { FC, FormEvent, useCallback, useState } from 'react'; +import { TurnstileWidget } from '../TurnstileWidget'; +import { t } from '../utils/i18n'; +import { DialogSharedProps } from './shared'; + +export interface ForgotDialogProps extends DialogSharedProps +{ + onSubmit: (body: { email: string; turnstileToken: string; }, onDialogReset: () => void) => void; +} + +export const ForgotDialog: FC = props => +{ + const { onCancel, onSubmit, submitting, error, info, turnstileEnabled, turnstileSiteKey } = props; + const [ email, setEmail ] = useState(''); + const [ localError, setLocalError ] = useState(null); + const [ turnstileToken, setTurnstileToken ] = useState(''); + const [ resetSignal, setResetSignal ] = useState(0); + + const resetWidget = useCallback(() => + { + setTurnstileToken(''); + setResetSignal(prev => prev + 1); + }, []); + + const handle = (event: FormEvent) => + { + event.preventDefault(); + setLocalError(null); + + if(!email.trim()) + { + setLocalError(t('nitro.login.error.missing_email', 'Please enter your email address.')); + return; + } + + onSubmit({ email: email.trim(), turnstileToken }, resetWidget); + }; + + return ( +
+
+
+
+ { t('nitro.login.forgot.title', 'Reset password') } + +
+
+
+ + setEmail(e.target.value) } /> +
+ { turnstileEnabled && + setTurnstileToken('') } + onError={ () => setTurnstileToken('') } + resetSignal={ resetSignal } + /> } + { (localError || error) &&
{ localError || error }
} + { info &&
{ info }
} +
+ +
+ +
+
+
+ ); +}; diff --git a/src/components/login/components/NewsWindow.tsx b/src/components/login/components/NewsWindow.tsx new file mode 100644 index 0000000..a7c05d3 --- /dev/null +++ b/src/components/login/components/NewsWindow.tsx @@ -0,0 +1,122 @@ +import { FC, useEffect, useState } from 'react'; +import { t } from '../utils/i18n'; +import { resolveNewsImage, resolveNewsLink } from '../utils/news'; + +interface NewsItem +{ + id: number; + title: string; + body: string; + image: string | null; + linkText: string; + linkUrl: string; +} + +interface NewsWindowProps { newsUrl: string; } + +const NEWS_AUTO_ADVANCE_MS = 10000; + +export const NewsWindow: FC = ({ newsUrl }) => +{ + const [ items, setItems ] = useState(null); + const [ failed, setFailed ] = useState(false); + const [ index, setIndex ] = useState(0); + const [ autoTick, setAutoTick ] = useState(0); + + useEffect(() => + { + if(!newsUrl) { setFailed(true); return; } + let cancelled = false; + fetch(newsUrl, { credentials: 'omit' }) + .then(async r => + { + if(!r.ok) throw new Error('status ' + r.status); + return r.json(); + }) + .then((json: unknown) => + { + if(cancelled) return; + const list = Array.isArray((json as { news?: unknown })?.news) + ? (json as { news: NewsItem[] }).news + : []; + setItems(list); + }) + .catch(() => { if(!cancelled) setFailed(true); }); + return () => { cancelled = true; }; + }, [ newsUrl ]); + + useEffect(() => + { + if(!items || items.length < 2) return; + const id = window.setTimeout(() => + { + setIndex(i => (i + 1) % items.length); + }, NEWS_AUTO_ADVANCE_MS); + return () => window.clearTimeout(id); + }, [ items, index, autoTick ]); + + if(failed) return null; + if(!items || !items.length) return null; + + const current = items[Math.min(index, items.length - 1)]; + const hasMany = items.length > 1; + const bumpAuto = () => setAutoTick(t => t + 1); + const prev = () => { setIndex(i => (i - 1 + items.length) % items.length); bumpAuto(); }; + const next = () => { setIndex(i => (i + 1) % items.length); bumpAuto(); }; + + const safeLinkUrl = resolveNewsLink(current.linkUrl); + const safeImageSrc = resolveNewsImage(current.image); + const openLink = () => + { + if(!safeLinkUrl) return; + window.open(safeLinkUrl, '_blank', 'noopener,noreferrer'); + }; + + return ( +
+
+ + + + + + +
+
+ { t('nitro.login.news.title', 'Hotel News') } +
+
+ { safeImageSrc && +
+ { { (e.currentTarget as HTMLImageElement).style.display = 'none'; } } + /> +
+ } +
{ current.title }
+ { current.body && +
{ current.body }
} + +
+ { current.linkText && safeLinkUrl + ? + : } + + { hasMany && +
+ + { index + 1 }/{ items.length } + +
+ } +
+
+
+
+
+ ); +}; diff --git a/src/components/login/components/RegisterDialog.tsx b/src/components/login/components/RegisterDialog.tsx new file mode 100644 index 0000000..b952c56 --- /dev/null +++ b/src/components/login/components/RegisterDialog.tsx @@ -0,0 +1,633 @@ +import { FC, FormEvent, useCallback, useEffect, useMemo, useState } from 'react'; +import { GetConfiguration } from '@nitrots/nitro-renderer'; +import { GetConfigurationValue } from '../../../api'; +import { TurnstileWidget } from '../TurnstileWidget'; +import { t } from '../utils/i18n'; +import { + buildFigureString, + buildImagingUrl, + buildPartPreviewUrl, + EMAIL_REGEX, + FALLBACK_DEFAULTS, + FALLBACK_HEX, + FigureData, + FigureSelection, + GenderKey, + PART_ROWS +} from '../utils/figure'; +import { DialogSharedProps } from './shared'; + +export interface RegisterDialogProps extends DialogSharedProps +{ + onSubmit: (body: { username: string; email: string; password: string; figure: string; gender: string; turnstileToken: string; templateId: number | null; }, onDialogReset: () => void) => void; + onCheckEmail: (email: string) => Promise<{ available: boolean; error?: string }>; + onCheckUsername: (username: string) => Promise<{ available: boolean; error?: string }>; + onCheckServer: () => Promise; + imagingUrl: string; + roomTemplatesUrl: string; +} + +type RegisterStep = 'credentials' | 'avatar' | 'room'; + +interface RoomTemplate { templateId: number; title: string; description: string; thumbnail: string; } + +export const RegisterDialog: FC = props => +{ + const { onCancel, onSubmit, onCheckEmail, onCheckUsername, onCheckServer, imagingUrl, roomTemplatesUrl, submitting, error, info, turnstileEnabled, turnstileSiteKey } = props; + + const [ step, setStep ] = useState('credentials'); + const [ email, setEmail ] = useState(''); + const [ password, setPassword ] = useState(''); + const [ confirm, setConfirm ] = useState(''); + const [ username, setUsername ] = useState(''); + const [ gender, setGender ] = useState('F'); + const [ selection, setSelection ] = useState(() => ({ ...FALLBACK_DEFAULTS.F })); + const [ localError, setLocalError ] = useState(null); + const [ checking, setChecking ] = useState(false); + const [ turnstileToken, setTurnstileToken ] = useState(''); + const [ resetSignal, setResetSignal ] = useState(0); + const [ serverReachable, setServerReachable ] = useState(null); + const [ pingingServer, setPingingServer ] = useState(false); + + const pingServer = useCallback(async () => + { + setPingingServer(true); + try + { + const ok = await onCheckServer(); + setServerReachable(ok); + return ok; + } + finally + { + setPingingServer(false); + } + }, [ onCheckServer ]); + + useEffect(() => + { + let cancelled = false; + (async () => + { + const ok = await onCheckServer(); + if(!cancelled) setServerReachable(ok); + })(); + return () => { cancelled = true; }; + }, [ onCheckServer ]); + + const resetWidget = useCallback(() => + { + setTurnstileToken(''); + setResetSignal(prev => prev + 1); + }, []); + + useEffect(() => { setLocalError(null); }, [ step ]); + + const [ roomTemplates, setRoomTemplates ] = useState(null); + const [ roomTemplatesError, setRoomTemplatesError ] = useState(null); + const [ selectedTemplateId, setSelectedTemplateId ] = useState(null); + + const [ figureData, setFigureData ] = useState(null); + const figureDataUrlRaw = GetConfigurationValue('avatar.figuredata.url', ''); + const figureDataUrl = useMemo(() => + { + if(!figureDataUrlRaw) return ''; + try { return GetConfiguration().interpolate(figureDataUrlRaw); } + catch { return figureDataUrlRaw; } + }, [ figureDataUrlRaw ]); + + useEffect(() => + { + if(step !== 'avatar' || figureData || !figureDataUrl) return; + let cancelled = false; + fetch(figureDataUrl, { credentials: 'omit' }) + .then(r => r.ok ? r.json() : null) + .then(json => { if(!cancelled && json) setFigureData(json as FigureData); }) + .catch(() => { }); + return () => { cancelled = true; }; + }, [ step, figureData, figureDataUrl ]); + + useEffect(() => + { + if(step !== 'room' || roomTemplates !== null || !roomTemplatesUrl) return; + let cancelled = false; + setRoomTemplatesError(null); + fetch(roomTemplatesUrl, { credentials: 'include' }) + .then(async r => { + if(!r.ok) throw new Error(`status ${ r.status }`); + return r.json(); + }) + .then(json => { + if(cancelled) return; + const list = Array.isArray((json as { templates?: unknown })?.templates) + ? (json as { templates: RoomTemplate[] }).templates + : []; + setRoomTemplates(list); + }) + .catch(() => { + if(cancelled) return; + setRoomTemplates([]); + setRoomTemplatesError(t('nitro.login.register.room.error', 'Could not load room options. You can still skip this step.')); + }); + return () => { cancelled = true; }; + }, [ step, roomTemplates, roomTemplatesUrl ]); + + const partOptions = useMemo(() => + { + const result: Record> = {}; + if(!figureData) return result; + for(const st of figureData.setTypes) + { + if(!PART_ROWS.includes(st.type)) continue; + const forGender = (g: GenderKey) => st.sets + .filter(s => s.selectable && s.club === 0 && (s.gender === g || s.gender === 'U')) + .map(s => s.id); + result[st.type] = { M: forGender('M'), F: forGender('F') }; + } + return result; + }, [ figureData ]); + + const paletteOptions = useMemo(() => + { + const result: Record = {}; + if(!figureData) return result; + for(const st of figureData.setTypes) + { + if(!PART_ROWS.includes(st.type)) continue; + const palette = figureData.palettes.find(p => p.id === st.paletteId); + if(!palette) { result[st.type] = []; continue; } + result[st.type] = palette.colors + .filter(c => c.selectable && c.club === 0) + .map(c => ({ id: c.id, hex: '#' + c.hexCode.toUpperCase() })); + } + return result; + }, [ figureData ]); + + const hexFor = useCallback((setType: string, colorId: number): string => + { + const list = paletteOptions[setType]; + if(list) + { + const found = list.find(c => c.id === colorId); + if(found) return found.hex; + } + return FALLBACK_HEX[colorId] || '#c9c9c9'; + }, [ paletteOptions ]); + + const [ hotLooks, setHotLooks ] = useState<{ gender: GenderKey; figure: string }[]>([]); + const [ hotLookIndex, setHotLookIndex ] = useState(-1); + + useEffect(() => + { + if(step !== 'avatar' || hotLooks.length) return; + let cancelled = false; + fetch('hotlooks.json', { credentials: 'omit' }) + .then(r => r.ok ? r.json() : null) + .then((json: unknown) => + { + if(cancelled || !Array.isArray(json)) return; + const parsed: { gender: GenderKey; figure: string }[] = []; + for(const entry of json as Record[]) + { + const rawGender = typeof entry._gender === 'string' ? entry._gender.toUpperCase() : ''; + const figure = typeof entry._figure === 'string' ? entry._figure : ''; + if((rawGender !== 'M' && rawGender !== 'F') || !figure) continue; + parsed.push({ gender: rawGender as GenderKey, figure }); + } + if(parsed.length) setHotLooks(parsed); + }) + .catch(() => { }); + return () => { cancelled = true; }; + }, [ step, hotLooks.length ]); + + const applyLook = useCallback((figure: string, lookGender: GenderKey) => + { + const next: FigureSelection = {}; + for(const setPart of figure.split('.')) + { + const bits = setPart.split('-'); + if(bits.length < 2) continue; + const setType = bits[0]; + const partId = parseInt(bits[1], 10); + if(!setType || Number.isNaN(partId)) continue; + const colors: number[] = []; + for(let i = 2; i < bits.length; i++) + { + const c = parseInt(bits[i], 10); + if(!Number.isNaN(c)) colors.push(c); + } + next[setType] = { partId, colors }; + } + + for(const setType of PART_ROWS) + { + if(!next[setType]) next[setType] = { ...FALLBACK_DEFAULTS[lookGender][setType] }; + } + setGender(lookGender); + setSelection(next); + }, []); + + const cycleHotLook = useCallback(() => + { + if(!hotLooks.length) return; + const nextIdx = (hotLookIndex + 1) % hotLooks.length; + setHotLookIndex(nextIdx); + const look = hotLooks[nextIdx]; + applyLook(look.figure, look.gender); + }, [ hotLooks, hotLookIndex, applyLook ]); + + const credentialsValid = + EMAIL_REGEX.test(email.trim()) && + password.length >= 8 && + password === confirm; + + const handleCredentialsNext = async (event: FormEvent) => + { + event.preventDefault(); + setLocalError(null); + + if(!email.trim() || !password || !confirm) + { + setLocalError(t('nitro.login.error.missing_fields', 'Please fill in every field.')); + return; + } + if(!EMAIL_REGEX.test(email.trim())) + { + setLocalError(t('nitro.login.error.invalid_email', 'Please enter a valid email address.')); + return; + } + if(password.length < 8) + { + setLocalError(t('nitro.login.error.password_too_short', 'Your password must be at least 8 characters.')); + return; + } + if(password !== confirm) + { + setLocalError(t('nitro.login.error.password_mismatch', 'Passwords do not match.')); + return; + } + + setChecking(true); + try + { + const serverOk = await pingServer(); + if(!serverOk) + { + setLocalError(t('nitro.login.error.server_offline', 'The gameserver is not running. Please try again later.')); + return; + } + const result = await onCheckEmail(email.trim()); + if(!result.available) + { + setLocalError(result.error || t('nitro.login.error.email_taken', 'This email is already in use.')); + return; + } + setStep('avatar'); + } + finally + { + setChecking(false); + } + }; + + const applyGender = (newGender: GenderKey) => + { + setGender(newGender); + setSelection({ ...FALLBACK_DEFAULTS[newGender] }); + setHotLookIndex(-1); + }; + + const getPartList = useCallback((setType: string): number[] => + { + const loaded = partOptions[setType]?.[gender]; + if(loaded && loaded.length) return loaded; + const fallback = FALLBACK_DEFAULTS[gender][setType]?.partId; + return fallback !== undefined ? [ fallback ] : []; + }, [ partOptions, gender ]); + + const getColorList = useCallback((setType: string): number[] => + { + const loaded = paletteOptions[setType]; + if(loaded && loaded.length) return loaded.map(c => c.id); + const fallback = FALLBACK_DEFAULTS[gender][setType]?.colors?.[0]; + return fallback !== undefined ? [ fallback ] : []; + }, [ paletteOptions, gender ]); + + const cyclePart = (setType: string, direction: 1 | -1) => + { + const options = getPartList(setType); + if(!options.length) return; + const current = selection[setType]?.partId ?? options[0]; + const idx = options.indexOf(current); + const nextIdx = ((idx === -1 ? 0 : idx) + direction + options.length) % options.length; + const colors = getColorList(setType); + setSelection(prev => ({ + ...prev, + [setType]: { + partId: options[nextIdx], + colors: prev[setType]?.colors ?? [ colors[0] ?? 0 ] + } + })); + }; + + const cycleColor = (setType: string, direction: 1 | -1) => + { + const colors = getColorList(setType); + if(!colors.length) return; + const currentColor = selection[setType]?.colors?.[0] ?? colors[0]; + const idx = colors.indexOf(currentColor); + const nextIdx = ((idx === -1 ? 0 : idx) + direction + colors.length) % colors.length; + const parts = getPartList(setType); + setSelection(prev => ({ + ...prev, + [setType]: { + partId: prev[setType]?.partId ?? parts[0], + colors: [ colors[nextIdx] ] + } + })); + }; + + const figure = buildFigureString(selection); + const previewSrc = buildImagingUrl(imagingUrl, figure, gender); + + const handleAvatarSubmit = async (event: FormEvent) => + { + event.preventDefault(); + setLocalError(null); + + const trimmed = username.trim(); + if(!trimmed) + { + setLocalError(t('nitro.login.error.missing_username', 'Please choose a Habbo name.')); + return; + } + if(trimmed.length < 3 || trimmed.length > 16) + { + setLocalError(t('nitro.login.error.username_length', 'Habbo name must be 3–16 characters.')); + return; + } + + if(turnstileEnabled && !turnstileToken) + { + setLocalError(t('nitro.login.error.turnstile', 'Please complete the security check.')); + return; + } + + setChecking(true); + try + { + const serverOk = await pingServer(); + if(!serverOk) + { + setLocalError(t('nitro.login.error.server_offline', 'The gameserver is not running. Please try again later.')); + return; + } + const result = await onCheckUsername(trimmed); + if(!result.available) + { + setLocalError(result.error || t('nitro.login.error.username_taken', 'This Habbo name is already taken.')); + return; + } + } + finally + { + setChecking(false); + } + + setStep('room'); + }; + + const submitRegistration = (templateId: number | null) => + { + onSubmit({ + username: username.trim(), + email: email.trim(), + password, + figure, + gender, + turnstileToken, + templateId + }, resetWidget); + }; + + const handleRoomSubmit = (event: FormEvent) => + { + event.preventDefault(); + setLocalError(null); + submitRegistration(selectedTemplateId); + }; + + const busy = submitting || checking || pingingServer; + const serverOffline = serverReachable === false; + + return ( +
+
+
+
+ { t('nitro.login.register.title', 'Habbo Details') } + +
+ + { step === 'credentials' && +
+
+ { t('nitro.login.register.intro.credentials', 'Let\'s create your account. Enter your email and pick a password — we\'ll check that email isn\'t already in use.') } +
+ { serverOffline && +
+ { t('nitro.login.server.offline.long', 'The gameserver isn\'t running right now, so new accounts can\'t be created. Please try again in a moment.') } + +
+ } +
+ + setEmail(e.target.value) } /> +
+
+ + setPassword(e.target.value) } /> +
+
+ + setConfirm(e.target.value) } /> +
+ { (localError || error) &&
{ localError || error }
} + { info &&
{ info }
} +
+ 1/3 + +
+
+ } + + { step === 'avatar' && +
+
+ { t('nitro.login.register.intro.avatar', 'Now it\'s time to make your own Habbo character! To make your own Habbo, please start by choosing your Habbo Name.') } +
+ { serverOffline && +
+ { t('nitro.login.server.offline.long', 'The gameserver isn\'t running right now, so new accounts can\'t be created. Please try again in a moment.') } + +
+ } +
+ setUsername(e.target.value) } /> +
+ +
+ + +
+ +
+
+ { PART_ROWS.map(setType => { + const partPreviewSrc = buildPartPreviewUrl(imagingUrl, setType, selection, gender); + return ( +
+ +
+ { { (e.currentTarget as HTMLImageElement).style.visibility = 'hidden'; } } /> +
+ +
+ ); + }) } +
+ +
+ Habbo preview { (e.currentTarget as HTMLImageElement).style.visibility = 'hidden'; } } /> +
+ +
+ { PART_ROWS.map(setType => { + const fallbackColor = FALLBACK_DEFAULTS[gender][setType]?.colors?.[0] ?? 0; + const currentColor = selection[setType]?.colors?.[0] ?? fallbackColor; + const swatchHex = hexFor(setType, currentColor); + return ( +
+ +
+ +
+ ); + }) } +
+
+ +
+ +
+ + { turnstileEnabled && + setTurnstileToken('') } + onError={ () => setTurnstileToken('') } + resetSignal={ resetSignal } + /> } + { (localError || error) &&
{ localError || error }
} + { info &&
{ info }
} + +
+ + 2/3 + +
+ + } + + { step === 'room' && +
+
+ { t('nitro.login.register.intro.room', 'Last step — pick a starter room, or skip and create your own later.') } +
+ { serverOffline && +
+ { t('nitro.login.server.offline.long', 'The gameserver isn\'t running right now, so new accounts can\'t be created. Please try again in a moment.') } + +
+ } + +
+ + + { roomTemplates === null &&
{ t('nitro.login.register.room.loading', 'Loading rooms…') }
} + + { roomTemplates !== null && roomTemplates.map(template => ( + + )) } +
+ + { roomTemplatesError &&
{ roomTemplatesError }
} + { (localError || error) &&
{ localError || error }
} + { info &&
{ info }
} + +
+ + 3/3 + +
+
+ } +
+
+
+ ); +}; diff --git a/src/components/login/components/shared.ts b/src/components/login/components/shared.ts new file mode 100644 index 0000000..53e30ed --- /dev/null +++ b/src/components/login/components/shared.ts @@ -0,0 +1,9 @@ +export interface DialogSharedProps +{ + onCancel: () => void; + submitting: boolean; + error: string | null; + info: string | null; + turnstileEnabled: boolean; + turnstileSiteKey: string; +} diff --git a/src/components/login/utils/ban.ts b/src/components/login/utils/ban.ts new file mode 100644 index 0000000..7c9b904 --- /dev/null +++ b/src/components/login/utils/ban.ts @@ -0,0 +1,32 @@ +export interface BanInfo +{ + type: 'account' | 'ip' | 'machine' | 'super' | string; + reason: string; + permanent: boolean; + expiresAt?: number; +} + +export const parseBan = (payload: Record): BanInfo | null => +{ + const raw = payload?.ban; + if(!raw || typeof raw !== 'object') return null; + const ban = raw as Record; + const type = typeof ban.type === 'string' ? ban.type : 'account'; + const reason = typeof ban.reason === 'string' ? ban.reason : ''; + const permanent = ban.permanent === true || ban.permanent === 'true'; + const expiresAt = typeof ban.expiresAt === 'number' ? ban.expiresAt : undefined; + return { type, reason, permanent, expiresAt }; +}; + +export const formatRemaining = (epochSeconds: number): string => +{ + const totalSeconds = Math.max(0, epochSeconds - Math.floor(Date.now() / 1000)); + const days = Math.floor(totalSeconds / 86400); + const hours = Math.floor((totalSeconds % 86400) / 3600); + const minutes = Math.floor((totalSeconds % 3600) / 60); + const seconds = totalSeconds % 60; + if(days > 0) return `${ days }d ${ hours }h ${ minutes }m`; + if(hours > 0) return `${ hours }h ${ minutes }m`; + if(minutes > 0) return `${ minutes }m ${ seconds }s`; + return `${ seconds }s`; +}; diff --git a/src/components/login/utils/figure.ts b/src/components/login/utils/figure.ts new file mode 100644 index 0000000..2743662 --- /dev/null +++ b/src/components/login/utils/figure.ts @@ -0,0 +1,106 @@ +export type GenderKey = 'M' | 'F'; + +export const PART_ROWS: string[] = [ 'hr', 'hd', 'ch', 'lg', 'sh' ]; + +export const FALLBACK_DEFAULTS: Record> = { + M: { + hr: { partId: 180, colors: [ 45 ] }, + hd: { partId: 180, colors: [ 1 ] }, + ch: { partId: 215, colors: [ 66 ] }, + lg: { partId: 270, colors: [ 82 ] }, + sh: { partId: 290, colors: [ 80 ] } + }, + F: { + hr: { partId: 515, colors: [ 45 ] }, + hd: { partId: 600, colors: [ 1 ] }, + ch: { partId: 660, colors: [ 100 ] }, + lg: { partId: 716, colors: [ 82 ] }, + sh: { partId: 725, colors: [ 61 ] } + } +}; + +export const FALLBACK_HEX: Record = { + 1: '#ffcb98', 8: '#f4ac54', 14: '#f5da88', 19: '#b87560', 20: '#9c543f', + 45: '#e8c498', 61: '#f1ece3', 66: '#96743d', 80: '#4f4d4d', 82: '#7f4f30', + 92: '#ececec', 100: '#c7ddff', 106: '#c6e6bd', 110: '#91a7c8', 143: '#ffffff' +}; + +export interface FigureColor { id: number; hexCode: string; club: number; selectable: boolean; } +export interface FigurePalette { id: number; colors: FigureColor[]; } +export interface FigureSet { id: number; gender: 'M' | 'F' | 'U'; club: number; selectable: boolean; } +export interface FigureSetType { type: string; paletteId: number; sets: FigureSet[]; } +export interface FigureData { palettes: FigurePalette[]; setTypes: FigureSetType[]; } + +export interface PartSelection { partId: number; colors: number[]; } +export type FigureSelection = Record; + +export const buildFigureString = (selection: FigureSelection): string => +{ + const seen = new Set(); + const parts: string[] = []; + const push = (setType: string) => + { + if(seen.has(setType)) return; + seen.add(setType); + const sel = selection[setType]; + if(!sel || sel.partId < 0) return; + const tail = (sel.colors && sel.colors.length) ? `-${ sel.colors.join('-') }` : ''; + parts.push(`${ setType }-${ sel.partId }${ tail }`); + }; + for(const setType of PART_ROWS) push(setType); + for(const setType of Object.keys(selection)) push(setType); + return parts.join('.'); +}; + +export const buildImagingUrl = (template: string, figure: string, gender: GenderKey): string => + template + .replace(/\{figure\}/g, encodeURIComponent(figure)) + .replace(/\{gender\}/g, gender) + .replace(/\{direction\}/g, '2'); + +const HEAD_ONLY_PARTS = new Set([ 'hr', 'hd' ]); + +export const buildPartPreviewUrl = ( + template: string, + setType: string, + selection: FigureSelection, + gender: GenderKey +): string => +{ + const defaults = FALLBACK_DEFAULTS[gender]; + const partSel = selection[setType] ?? defaults[setType]; + const tail = (partSel.colors && partSel.colors.length) ? `-${ partSel.colors.join('-') }` : ''; + const isHeadOnly = HEAD_ONLY_PARTS.has(setType); + + let parts: string[]; + if(isHeadOnly) + { + const hd = defaults.hd; + const pieces = new Map(); + pieces.set('hd', `hd-${ hd.partId }-${ hd.colors.join('-') }`); + pieces.set(setType, `${ setType }-${ partSel.partId }${ tail }`); + parts = Array.from(pieces.values()); + } + else + { + const hd = defaults.hd; + parts = [ + `hd-${ hd.partId }-${ hd.colors.join('-') }`, + `${ setType }-${ partSel.partId }${ tail }` + ]; + } + + const figure = parts.join('.'); + let url = template + .replace(/\{figure\}/g, encodeURIComponent(figure)) + .replace(/\{gender\}/g, gender) + .replace(/\{direction\}/g, '2'); + + url = url.replace(/size=l/, 'size=s').replace(/size=m/, 'size=s'); + if(!/size=/.test(url)) url += (url.includes('?') ? '&' : '?') + 'size=s'; + if(isHeadOnly && !/headonly=/.test(url)) url += '&headonly=1'; + + return url; +}; + +export const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; diff --git a/src/components/login/utils/i18n.ts b/src/components/login/utils/i18n.ts new file mode 100644 index 0000000..58f88f8 --- /dev/null +++ b/src/components/login/utils/i18n.ts @@ -0,0 +1,27 @@ +import { GetConfiguration } from '@nitrots/nitro-renderer'; +import { LocalizeText } from '../../../api'; + +export const t = (key: string, fallback: string, params?: string[], replacements?: string[]): string => +{ + try + { + const value = LocalizeText(key, params ?? null, replacements ?? null); + if(value && value !== key) return value; + } + catch {} + + if(!params || !replacements) return fallback; + let out = fallback; + for(let i = 0; i < params.length; i++) + { + if(replacements[i] !== undefined) out = out.replace('%' + params[i] + '%', replacements[i]); + } + return out; +}; + +export const interpolate = (value: string | null | undefined): string => +{ + if(!value) return ''; + try { return GetConfiguration().interpolate(value); } + catch { return value; } +}; diff --git a/src/components/login/utils/lockState.ts b/src/components/login/utils/lockState.ts new file mode 100644 index 0000000..ef5a946 --- /dev/null +++ b/src/components/login/utils/lockState.ts @@ -0,0 +1,23 @@ +export const LOCK_KEY = 'nitro.login.lock'; +export const MAX_ATTEMPTS = 5; +export const LOCK_WINDOW_MS = 60_000; +export const LOCK_DURATION_MS = 2 * 60_000; + +export type AttemptState = { attempts: number; firstAt: number; lockedUntil: number }; + +export const readLock = (): AttemptState => +{ + try + { + const raw = sessionStorage.getItem(LOCK_KEY); + if(!raw) return { attempts: 0, firstAt: 0, lockedUntil: 0 }; + return JSON.parse(raw); + } + catch { return { attempts: 0, firstAt: 0, lockedUntil: 0 }; } +}; + +export const writeLock = (state: AttemptState) => +{ + try { sessionStorage.setItem(LOCK_KEY, JSON.stringify(state)); } + catch { } +}; diff --git a/src/components/login/utils/news.ts b/src/components/login/utils/news.ts new file mode 100644 index 0000000..0fa0c82 --- /dev/null +++ b/src/components/login/utils/news.ts @@ -0,0 +1,50 @@ +/** + * Accepts a URL (http/https, protocol-relative, or site-relative), + * a data URL with an image mime type, or a raw base64 image payload. + * Anything else (including data:text/html, javascript:, etc.) is rejected + * to keep an admin-set DB value from becoming an XSS / phishing vector. + */ +export const resolveNewsImage = (raw: string | null | undefined): string => +{ + const value = (raw ?? '').trim(); + if(!value) return ''; + if(/^https?:\/\//i.test(value)) return value; + if(value.startsWith('//')) return window.location.protocol + value; + if(value.startsWith('/')) + { + try { return new URL(value, window.location.origin).href; } + catch { return window.location.origin + value; } + } + if(value.startsWith('data:')) + { + return /^data:image\/[a-z0-9.+-]+[,;]/i.test(value) ? value : ''; + } + + const stripped = value.replace(/\s+/g, ''); + if(!/^[A-Za-z0-9+/=]+$/.test(stripped)) return ''; + let mime = 'image/png'; + if(stripped.startsWith('/9j/')) mime = 'image/jpeg'; + else if(stripped.startsWith('R0lGOD')) mime = 'image/gif'; + else if(stripped.startsWith('UklGR')) mime = 'image/webp'; + else if(stripped.startsWith('PHN2Zy') || stripped.startsWith('PD94bWw')) mime = 'image/svg+xml'; + else if(stripped.startsWith('iVBORw0KGgo')) mime = 'image/png'; + return `data:${ mime };base64,${ stripped }`; +}; + +/** + * Rejects anything that isn't an http(s) URL or a same-origin path so a + * malicious DB value can't be a `javascript:` / `data:` / `file:` link. + */ +export const resolveNewsLink = (raw: string | null | undefined): string => +{ + const value = (raw ?? '').trim(); + if(!value) return ''; + try + { + const url = new URL(value, window.location.href); + const proto = url.protocol.toLowerCase(); + if(proto !== 'http:' && proto !== 'https:') return ''; + return url.href; + } + catch { return ''; } +}; diff --git a/src/components/navigator/views/search/NavigatorSearchResultItemInfoView.tsx b/src/components/navigator/views/search/NavigatorSearchResultItemInfoView.tsx index 645e5c9..40cc451 100644 --- a/src/components/navigator/views/search/NavigatorSearchResultItemInfoView.tsx +++ b/src/components/navigator/views/search/NavigatorSearchResultItemInfoView.tsx @@ -1,7 +1,7 @@ import { RoomDataParser, RoomSettingsComposer, UpdateHomeRoomMessageComposer } from '@nitrots/nitro-renderer'; +import * as Popover from '@radix-ui/react-popover'; import React, { FC, useRef, useState } from 'react'; import { FaUser } from 'react-icons/fa'; -import { ArrowContainer, Popover } from 'react-tiny-popover'; import { GetGroupInformation, GetSessionDataManager, GetUserProfile, LocalizeText, ReportType, SendMessageComposer, ToggleFavoriteRoom } from '../../../../api'; import { Column, Flex, LayoutBadgeImageView, LayoutRoomThumbnailView, NitroCardContentView, Text, UserProfileIconView } from '../../../../common'; import { useHelp, useNavigator } from '../../../../hooks'; @@ -26,6 +26,12 @@ export const NavigatorSearchResultItemInfoView: FC + { + if(!isControlled) setInternalVisible(open); + if(!open && setIsPopoverActive) setIsPopoverActive(false); + }; + const getUserCounterColor = () => { const num: number = (100 * (roomData.userCount / roomData.maxUserCount)); @@ -88,17 +94,22 @@ export const NavigatorSearchResultItemInfoView: FC ( - + + +
{ if(!isControlled) setInternalVisible(true); } } + onMouseLeave={ () => { if(!isControlled) setInternalVisible(false); } } + /> + + + e.stopPropagation() }> @@ -173,24 +184,9 @@ export const NavigatorSearchResultItemInfoView: FC } - - ) } - isOpen={ popoverOpen } - onClickOutside={ () => - { - if(!isControlled) setInternalVisible(false); - if(setIsPopoverActive) setIsPopoverActive(false); - } } - padding={ 10 } - positions={ [ 'right', 'left', 'top', 'bottom' ] } - > -
{ if(!isControlled) setInternalVisible(true); } } - onMouseLeave={ () => { if(!isControlled) setInternalVisible(false); } } - /> - + + + + ); }; diff --git a/src/components/purse/views/CurrencyView.tsx b/src/components/purse/views/CurrencyView.tsx index 9f72158..47c07ab 100644 --- a/src/components/purse/views/CurrencyView.tsx +++ b/src/components/purse/views/CurrencyView.tsx @@ -1,5 +1,4 @@ import { FC, useMemo } from 'react'; -import { OverlayTrigger, Tooltip } from 'react-bootstrap'; import { LocalizeFormattedNumber, LocalizeShortNumber } from '../../../api'; import { Flex, LayoutCurrencyIcon, Text } from '../../../common'; @@ -17,23 +16,22 @@ export const CurrencyView: FC = props => const element = useMemo(() => { return ( - + { short ? LocalizeShortNumber(amount) : LocalizeFormattedNumber(amount) } ); }, [ amount, short, type ]); if(!short) return element; - + return ( - - { LocalizeFormattedNumber(amount) } - - }> +
{ element } - +
+ { LocalizeFormattedNumber(amount) } +
+
); } diff --git a/src/components/room/widgets/avatar-info/infostand/InfoStandBadgeSlotView.tsx b/src/components/room/widgets/avatar-info/infostand/InfoStandBadgeSlotView.tsx index 267f535..c66609d 100644 --- a/src/components/room/widgets/avatar-info/infostand/InfoStandBadgeSlotView.tsx +++ b/src/components/room/widgets/avatar-info/infostand/InfoStandBadgeSlotView.tsx @@ -1,4 +1,5 @@ import { FC, useCallback, useEffect, useRef, useState } from 'react'; +import { createPortal } from 'react-dom'; import { FaPlus } from 'react-icons/fa'; import { GetConfigurationValue, LocalizeText } from '../../../../../api'; import { LayoutBadgeImageView } from '../../../../../common'; @@ -15,7 +16,8 @@ const BadgeMiniPicker: FC<{ onSelect: (badgeCode: string) => void; onClose: () => void; activeBadgeCodes: (string | null)[]; -}> = ({ onSelect, onClose, activeBadgeCodes }) => + position: { top: number; left: number }; +}> = ({ onSelect, onClose, activeBadgeCodes, position }) => { const { badgeCodes = [], requestBadges = null } = useInventoryBadges(); const ref = useRef(null); @@ -43,10 +45,11 @@ const BadgeMiniPicker: FC<{ return () => document.removeEventListener('mousedown', handleClickOutside); }, [ onClose ]); - return ( + return createPortal(
e.stopPropagation() }> ) } -
+
, + document.body ); }; @@ -83,7 +87,9 @@ export const InfoStandBadgeSlotView: FC = ({ slotIndex, const [ isDragOver, setIsDragOver ] = useState(false); const [ isDragging, setIsDragging ] = useState(false); const [ justDropped, setJustDropped ] = useState(false); - const [ showPicker, setShowPicker ] = useState(false); + const [ pickerPosition, setPickerPosition ] = useState<{ top: number; left: number } | null>(null); + const slotRef = useRef(null); + const showPicker = pickerPosition !== null; const hookInitialized = activeBadgeCodes.length > 0; @@ -152,9 +158,17 @@ export const InfoStandBadgeSlotView: FC = ({ slotIndex, const handleSlotClick = useCallback(() => { - if(!isOwnUser || badgeCode) return; + if(!isOwnUser || badgeCode || !slotRef.current) return; - setShowPicker(true); + const rect = slotRef.current.getBoundingClientRect(); + const pickerWidth = 180; + const gap = 8; + let left = rect.right + gap; + + if((left + pickerWidth) > (window.innerWidth - gap)) left = rect.left - pickerWidth - gap; + if(left < gap) left = gap; + + setPickerPosition({ top: rect.top, left }); }, [ isOwnUser, badgeCode ]); const handleDoubleClick = useCallback(() => @@ -167,12 +181,13 @@ export const InfoStandBadgeSlotView: FC = ({ slotIndex, const handlePickerSelect = useCallback((code: string) => { setBadgeAtSlot(code, slotIndex); - setShowPicker(false); + setPickerPosition(null); }, [ setBadgeAtSlot, slotIndex ]); return (
= ({ slotIndex, { showPicker && ( setShowPicker(false) } + onClose={ () => setPickerPosition(null) } onSelect={ handlePickerSelect } + position={ pickerPosition } /> ) }
diff --git a/src/components/room/widgets/avatar-info/infostand/InfoStandWidgetFurniView.tsx b/src/components/room/widgets/avatar-info/infostand/InfoStandWidgetFurniView.tsx index d415a1b..f396c28 100644 --- a/src/components/room/widgets/avatar-info/infostand/InfoStandWidgetFurniView.tsx +++ b/src/components/room/widgets/avatar-info/infostand/InfoStandWidgetFurniView.tsx @@ -1,4 +1,4 @@ -import { CrackableDataType, CreateLinkEvent, FurnitureFloorUpdateEvent, GetRoomEngine, GetSoundManager, GroupInformationComposer, GroupInformationEvent, NowPlayingEvent, RoomControllerLevel, RoomObjectCategory, RoomObjectOperationType, RoomObjectVariable, RoomWidgetEnumItemExtradataParameter, RoomWidgetFurniInfoUsagePolicyEnum, SetObjectDataMessageComposer, SongInfoReceivedEvent, StringDataType, UpdateFurniturePositionComposer } from '@nitrots/nitro-renderer'; +import { CrackableDataType, CreateLinkEvent, FurnitureFloorUpdateEvent, GetRoomEngine, GetSessionDataManager, GetSoundManager, GroupInformationComposer, GroupInformationEvent, NowPlayingEvent, RoomControllerLevel, RoomObjectCategory, RoomObjectOperationType, RoomObjectVariable, RoomWidgetEnumItemExtradataParameter, RoomWidgetFurniInfoUsagePolicyEnum, SetObjectDataMessageComposer, SongInfoReceivedEvent, StringDataType, UpdateFurniturePositionComposer } from '@nitrots/nitro-renderer'; import { FC, useCallback, useEffect, useMemo, useState } from 'react'; import { FaCrosshairs, FaRulerVertical, FaTimes } from 'react-icons/fa'; import { GrFormNextLink, GrRotateLeft, GrRotateRight } from 'react-icons/gr'; @@ -585,19 +585,20 @@ export const InfoStandWidgetFurniView: FC = props onClick={ () => setDropdownOpen(!dropdownOpen) }> { dropdownOpen ? `${LocalizeText('widget.furni.present.close')} Buildtools` : `${LocalizeText('navigator.roomsettings.doormode.open')} Buildtools` } - + if(typeId) window.dispatchEvent(new CustomEvent('furni-editor:open', { detail: { spriteId: typeId } })); + } }> + Edit Furni + } { dropdownOpen &&
{ /* Left panel: position + rotation */ } diff --git a/src/components/room/widgets/avatar-info/infostand/InfoStandWidgetUserView.tsx b/src/components/room/widgets/avatar-info/infostand/InfoStandWidgetUserView.tsx index 698ed30..6ecb092 100644 --- a/src/components/room/widgets/avatar-info/infostand/InfoStandWidgetUserView.tsx +++ b/src/components/room/widgets/avatar-info/infostand/InfoStandWidgetUserView.tsx @@ -24,12 +24,14 @@ export const InfoStandWidgetUserView: FC = props = const [backgroundId, setBackgroundId] = useState(null); const [standId, setStandId] = useState(null); const [overlayId, setOverlayId] = useState(null); + const [cardBackgroundId, setCardBackgroundId] = useState(null); const [isVisible, setIsVisible] = useState(false); const { roomSession = null } = useRoom(); const infostandBackgroundClass = `background-${backgroundId ?? 'default'}`; const infostandStandClass = `stand-${standId ?? 'default'}`; const infostandOverlayClass = `overlay-${overlayId ?? 'default'}`; + const infostandCardBackgroundClass = cardBackgroundId ? `card-background-${cardBackgroundId}` : ''; const handleProfileClick = useCallback(() => { GetUserProfile(avatarInfo.webID); }, [avatarInfo.webID]); const handleEditClick = useCallback((event: React.MouseEvent) => { event.stopPropagation(); setIsVisible(prev => !prev); }, []); @@ -96,6 +98,7 @@ export const InfoStandWidgetUserView: FC = props = newValue.backgroundId = event.backgroundId; newValue.standId = event.standId; newValue.overlayId = event.overlayId; + newValue.cardBackgroundId = event.cardBackgroundId ?? 0; return newValue; }); }); @@ -130,16 +133,12 @@ export const InfoStandWidgetUserView: FC = props = setBackgroundId(avatarInfo.backgroundId); setStandId(avatarInfo.standId); setOverlayId(avatarInfo.overlayId); + setCardBackgroundId(avatarInfo.cardBackgroundId ?? 0); SendMessageComposer(new UserRelationshipsComposer(avatarInfo.webID)); return () => { - setIsEditingMotto(false); - setMotto(null); setRelationships(null); - setBackgroundId(null); - setStandId(null); - setOverlayId(null); }; }, [avatarInfo]); @@ -147,7 +146,7 @@ export const InfoStandWidgetUserView: FC = props = return ( <> - +
@@ -292,6 +291,8 @@ export const InfoStandWidgetUserView: FC = props = setSelectedStand={setStandId} selectedOverlay={overlayId} setSelectedOverlay={setOverlayId} + selectedCardBackground={cardBackgroundId} + setSelectedCardBackground={setCardBackgroundId} />
)} diff --git a/src/components/room/widgets/avatar-info/menu/AvatarInfoWidgetOwnAvatarView.tsx b/src/components/room/widgets/avatar-info/menu/AvatarInfoWidgetOwnAvatarView.tsx index 4eb0756..1ad76e2 100644 --- a/src/components/room/widgets/avatar-info/menu/AvatarInfoWidgetOwnAvatarView.tsx +++ b/src/components/room/widgets/avatar-info/menu/AvatarInfoWidgetOwnAvatarView.tsx @@ -55,6 +55,9 @@ export const AvatarInfoWidgetOwnAvatarView: FC processAction('change_looks') }> { LocalizeText('widget.memenu.myclothes') } + processAction('avatar_effect') }> + { LocalizeText('product.type.effect') } + { (HasHabboClub() && !isRidingHorse) && processAction('dance_menu') }> diff --git a/src/components/room/widgets/chat-input/ChatInputEmojiSelectorView.tsx b/src/components/room/widgets/chat-input/ChatInputEmojiSelectorView.tsx index f547e46..bd2dcae 100644 --- a/src/components/room/widgets/chat-input/ChatInputEmojiSelectorView.tsx +++ b/src/components/room/widgets/chat-input/ChatInputEmojiSelectorView.tsx @@ -1,7 +1,7 @@ import data from '@emoji-mart/data'; import Picker from '@emoji-mart/react'; +import * as Popover from '@radix-ui/react-popover'; import { FC, useState } from 'react'; -import { Popover } from 'react-tiny-popover'; interface ChatInputEmojiSelectorViewProps { @@ -19,19 +19,16 @@ export const ChatInputEmojiSelectorView: FC = p setSelectorVisible(false); }; - const toggleSelector = () => setSelectorVisible(prev => !prev); - return ( -
- } - isOpen={ selectorVisible } - positions={ [ 'top' ] } - onClickOutside={ () => setSelectorVisible(false) } - > -
🙂
-
-
+ + +
🙂
+
+ + + + + +
); }; diff --git a/src/components/room/widgets/chat-input/ChatInputStyleSelectorView.tsx b/src/components/room/widgets/chat-input/ChatInputStyleSelectorView.tsx index 2a6d165..ec089c3 100644 --- a/src/components/room/widgets/chat-input/ChatInputStyleSelectorView.tsx +++ b/src/components/room/widgets/chat-input/ChatInputStyleSelectorView.tsx @@ -1,5 +1,5 @@ +import * as Popover from '@radix-ui/react-popover'; import { FC, useState } from 'react'; -import { ArrowContainer, Popover } from 'react-tiny-popover'; import { Flex, Grid, NitroCardContentView } from '../../../../common'; interface ChatInputStyleSelectorViewProps @@ -21,20 +21,17 @@ export const ChatInputStyleSelectorView: FC = p }; return ( - ( - + +
+
+
+ + + @@ -47,15 +44,9 @@ export const ChatInputStyleSelectorView: FC = p ))} - - )} - > -
setSelectorVisible(v => !v)} - > -
-
- + + + + ); -}; \ No newline at end of file +}; diff --git a/src/components/room/widgets/furniture/FurnitureYoutubeDisplayView.tsx b/src/components/room/widgets/furniture/FurnitureYoutubeDisplayView.tsx index f2375ca..82a4b8c 100644 --- a/src/components/room/widgets/furniture/FurnitureYoutubeDisplayView.tsx +++ b/src/components/room/widgets/furniture/FurnitureYoutubeDisplayView.tsx @@ -1,6 +1,5 @@ -import { FC, useEffect, useState } from 'react'; -import YouTube, { Options } from 'react-youtube'; -import { YouTubePlayer } from 'youtube-player/dist/types'; +import { FC, useRef } from 'react'; +import ReactPlayer from 'react-player/youtube'; import { LocalizeText, YoutubeVideoPlaybackStateEnum } from '../../../../api'; import { AutoGrid, AutoGridProps, LayoutGridItem, NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../common'; import { useFurnitureYoutubeWidget } from '../../../../hooks'; @@ -12,71 +11,24 @@ interface FurnitureYoutubeDisplayViewProps extends AutoGridProps export const FurnitureYoutubeDisplayView: FC<{}> = FurnitureYoutubeDisplayViewProps => { - const [ player, setPlayer ] = useState(null); const { objectId = -1, videoId = null, videoStart = 0, videoEnd = 0, currentVideoState = null, selectedVideo = null, playlists = [], onClose = null, previous = null, next = null, pause = null, play = null, selectVideo = null } = useFurnitureYoutubeWidget(); + const playerRef = useRef(null); - const onStateChange = (event: { target: YouTubePlayer; data: number }) => + const handlePlay = () => { - try - { - setPlayer(event.target); - - if(objectId === -1) return; - - switch(event.target.getPlayerState()) - { - case -1: - case 1: - if(currentVideoState !== 1) play(); - return; - case 2: - if(currentVideoState !== 2) pause(); - } - } - catch(err) {} + if(objectId === -1) return; + if(currentVideoState !== YoutubeVideoPlaybackStateEnum.PLAYING) play(); }; - useEffect(() => + const handlePause = () => { - if((currentVideoState === null) || !player) return; - - try - { - if((currentVideoState === YoutubeVideoPlaybackStateEnum.PLAYING) && (player.getPlayerState() !== YoutubeVideoPlaybackStateEnum.PLAYING)) - { - player.playVideo(); - - return; - } - - if((currentVideoState === YoutubeVideoPlaybackStateEnum.PAUSED) && (player.getPlayerState() !== YoutubeVideoPlaybackStateEnum.PAUSED)) - { - player.pauseVideo(); - - return; - } - } - catch(err) - { - setPlayer(null); - } - }, [ currentVideoState, player ]); + if(objectId === -1) return; + if(currentVideoState !== YoutubeVideoPlaybackStateEnum.PAUSED) pause(); + }; if(objectId === -1) return null; - const youtubeOptions: Options = { - height: '375', - width: '500', - playerVars: { - autoplay: 1, - disablekb: 1, - controls: 0, - origin: window.origin, - modestbranding: 1, - start: videoStart, - end: videoEnd - } - }; + const playing = (currentVideoState === null) ? true : (currentVideoState === YoutubeVideoPlaybackStateEnum.PLAYING); return ( @@ -85,7 +37,26 @@ export const FurnitureYoutubeDisplayView: FC<{}> = FurnitureYoutubeDisplayViewPr
{ (videoId && videoId.length > 0) && - setPlayer(event.target) } onStateChange={ onStateChange } /> + } { (!videoId || videoId.length === 0) &&
{ LocalizeText('widget.furni.video_viewer.no_videos') }
diff --git a/src/components/toolbar/ToolbarMeView.tsx b/src/components/toolbar/ToolbarMeView.tsx index 642e519..79fa576 100644 --- a/src/components/toolbar/ToolbarMeView.tsx +++ b/src/components/toolbar/ToolbarMeView.tsx @@ -32,7 +32,7 @@ export const ToolbarMeView: FC + { (GetConfigurationValue('guides.enabled') && useGuideTool) &&
DispatchUiEvent(new GuideToolEvent(GuideToolEvent.TOGGLE_GUIDE_TOOL)) } /> }
CreateLinkEvent('achievements/toggle') }> @@ -42,6 +42,7 @@ export const ToolbarMeView: FC GetUserProfile(GetSessionDataManager().userId) } />
CreateLinkEvent('navigator/search/myworld_view') } />
CreateLinkEvent('avatar-editor/toggle') } /> +
CreateLinkEvent('badge-creator/toggle') } title={ LocalizeText('toolbar.icon.label.badge_creator') } />
CreateLinkEvent('user-settings/toggle') } />
CreateLinkEvent('groupforum/toggle') } title={ LocalizeText('toolbar.icon.label.forums') } /> { children } diff --git a/src/components/toolbar/YouTubePlayerView.tsx b/src/components/toolbar/YouTubePlayerView.tsx index 39e8e76..5f1c89c 100644 --- a/src/components/toolbar/YouTubePlayerView.tsx +++ b/src/components/toolbar/YouTubePlayerView.tsx @@ -1,6 +1,6 @@ import { ControlYoutubeDisplayPlaybackMessageComposer, YouTubeRoomBroadcastEvent, YouTubeRoomPlayComposer, YouTubeRoomSettingsEvent, YouTubeRoomWatchersEvent, YouTubeRoomWatchingComposer } from "@nitrots/nitro-renderer"; import { FC, useEffect, useRef, useState } from "react"; -import YouTube from "react-youtube"; +import ReactPlayer from "react-player/youtube"; import { GetRoomSession, getYoutubeRoomEnabled, GetSessionDataManager, LocalizeText, SendMessageComposer, YoutubeVideoPlaybackStateEnum } from "../../api"; import { NitroCardContentView, NitroCardHeaderView, NitroCardView, LayoutAvatarImageView } from "../../common"; import { useFurnitureYoutubeWidget, useMessageEvent } from "../../hooks"; @@ -35,7 +35,7 @@ export const YouTubePlayerView: FC<{}> = () => { const [playlist, setPlaylist] = useState([]); const [history, setHistory] = useState([]); const [showVolumeSlider, setShowVolumeSlider] = useState(true); - const playerRef = useRef(null); + const playerRef = useRef(null); const { objectId: youtubeObjectId, videoId: roomVideoId, currentVideoState, hasControl } = useFurnitureYoutubeWidget(); const [spectators, setSpectators] = useState< { id: number; name: string; look: string }[] >([]); const [broadcastVideo, setBroadcastVideo] = useState(""); @@ -310,22 +310,22 @@ export const YouTubePlayerView: FC<{}> = () => { )} {videoId ? ( - { playerRef.current = ref; }} + url={`https://www.youtube.com/watch?v=${videoId}`} + width="100%" + height={isFullscreen ? "100%" : 280} + playing + muted={isMuted} + loop={isLooping} + volume={Math.max(0, Math.min(1, volume / 100))} + config={{ playerVars: { autoplay: 1, - volume: volume, - muted: isMuted ? 1 : 0, loop: isLooping ? 1 : 0, }, }} - onReady={(e) => { - playerRef.current = e.target; - addToHistory(videoId); - }} + onReady={() => addToHistory(videoId)} /> ) : (
diff --git a/src/components/user-profile/UserContainerView.tsx b/src/components/user-profile/UserContainerView.tsx index 0425e2f..851ccf6 100644 --- a/src/components/user-profile/UserContainerView.tsx +++ b/src/components/user-profile/UserContainerView.tsx @@ -18,6 +18,7 @@ export const UserContainerView: FC<{ const infostandBackgroundClass = `background-${userProfile.backgroundId ?? 'default'}`; const infostandStandClass = `stand-${userProfile.standId ?? 'default'}`; const infostandOverlayClass = `overlay-${userProfile.overlayId ?? 'default'}`; + const profileCardBgClass = userProfile.cardBackgroundId ? `card-background-${userProfile.cardBackgroundId}` : ''; const addFriend = () => { setRequestSent(true); @@ -31,7 +32,7 @@ export const UserContainerView: FC<{ }, [ userProfile ]); return ( -
+
diff --git a/src/css/backgrounds/BackgroundsView.css b/src/css/backgrounds/BackgroundsView.css index 5b67a48..1aa6114 100644 --- a/src/css/backgrounds/BackgroundsView.css +++ b/src/css/backgrounds/BackgroundsView.css @@ -78,6 +78,656 @@ background: none; } +.profile-card-background { + background-repeat: repeat; + background-position: top left; + background-size: auto; + &.card-background-0 { + background-image: url('@/assets/images/backgrounds/background/bg_0.png'); + } + &.card-background-1 { + background-image: url('@/assets/images/backgrounds/background/bg_1.png'); + } + &.card-background-2 { + background-image: url('@/assets/images/backgrounds/background/bg_2.png'); + } + &.card-background-3 { + background-image: url('@/assets/images/backgrounds/background/bg_3.png'); + } + &.card-background-4 { + background-image: url('@/assets/images/backgrounds/background/bg_4.png'); + } + &.card-background-5 { + background-image: url('@/assets/images/backgrounds/background/bg_5.png'); + } + &.card-background-6 { + background-image: url('@/assets/images/backgrounds/background/bg_6.png'); + } + &.card-background-7 { + background-image: url('@/assets/images/backgrounds/background/bg_7.png'); + } + &.card-background-8 { + background-image: url('@/assets/images/backgrounds/background/bg_8.png'); + } + &.card-background-9 { + background-image: url('@/assets/images/backgrounds/background/bg_9.png'); + } + &.card-background-10 { + background-image: url('@/assets/images/backgrounds/background/bg_10.png'); + } + &.card-background-11 { + background-image: url('@/assets/images/backgrounds/background/bg_11.png'); + } + &.card-background-12 { + background-image: url('@/assets/images/backgrounds/background/bg_12.png'); + } + &.card-background-13 { + background-image: url('@/assets/images/backgrounds/background/bg_13.png'); + } + &.card-background-14 { + background-image: url('@/assets/images/backgrounds/background/bg_14.png'); + } + &.card-background-15 { + background-image: url('@/assets/images/backgrounds/background/bg_15.png'); + } + &.card-background-16 { + background-image: url('@/assets/images/backgrounds/background/bg_16.png'); + } + &.card-background-17 { + background-image: url('@/assets/images/backgrounds/background/bg_17.png'); + } + &.card-background-18 { + background-image: url('@/assets/images/backgrounds/background/bg_18.png'); + } + &.card-background-19 { + background-image: url('@/assets/images/backgrounds/background/bg_19.png'); + } + &.card-background-20 { + background-image: url('@/assets/images/backgrounds/background/bg_20.png'); + } + &.card-background-21 { + background-image: url('@/assets/images/backgrounds/background/bg_21.png'); + } + &.card-background-22 { + background-image: url('@/assets/images/backgrounds/background/bg_22.png'); + } + &.card-background-23 { + background-image: url('@/assets/images/backgrounds/background/bg_23.png'); + } + &.card-background-24 { + background-image: url('@/assets/images/backgrounds/background/bg_24.png'); + } + &.card-background-25 { + background-image: url('@/assets/images/backgrounds/background/bg_25.png'); + } + &.card-background-26 { + background-image: url('@/assets/images/backgrounds/background/bg_26.png'); + } + &.card-background-27 { + background-image: url('@/assets/images/backgrounds/background/bg_27.png'); + } + &.card-background-28 { + background-image: url('@/assets/images/backgrounds/background/bg_28.png'); + } + &.card-background-29 { + background-image: url('@/assets/images/backgrounds/background/bg_29.png'); + } + &.card-background-30 { + background-image: url('@/assets/images/backgrounds/background/bg_30.png'); + } + &.card-background-31 { + background-image: url('@/assets/images/backgrounds/background/bg_31.png'); + } + &.card-background-32 { + background-image: url('@/assets/images/backgrounds/background/bg_32.png'); + } + &.card-background-33 { + background-image: url('@/assets/images/backgrounds/background/bg_33.png'); + } + &.card-background-34 { + background-image: url('@/assets/images/backgrounds/background/bg_34.png'); + } + &.card-background-35 { + background-image: url('@/assets/images/backgrounds/background/bg_35.png'); + } + &.card-background-36 { + background-image: url('@/assets/images/backgrounds/background/bg_36.gif'); + } + &.card-background-37 { + background-image: url('@/assets/images/backgrounds/background/bg_37.png'); + } + &.card-background-38 { + background-image: url('@/assets/images/backgrounds/background/bg_38.png'); + } + &.card-background-39 { + background-image: url('@/assets/images/backgrounds/background/bg_39.png'); + } + &.card-background-40 { + background-image: url('@/assets/images/backgrounds/background/bg_40.png'); + } + &.card-background-41 { + background-image: url('@/assets/images/backgrounds/background/bg_41.png'); + } + &.card-background-42 { + background-image: url('@/assets/images/backgrounds/background/bg_42.png'); + } + &.card-background-43 { + background-image: url('@/assets/images/backgrounds/background/bg_43.png'); + } + &.card-background-44 { + background-image: url('@/assets/images/backgrounds/background/bg_44.png'); + } + &.card-background-45 { + background-image: url('@/assets/images/backgrounds/background/bg_45.png'); + } + &.card-background-46 { + background-image: url('@/assets/images/backgrounds/background/bg_46.png'); + } + &.card-background-47 { + background-image: url('@/assets/images/backgrounds/background/bg_47.png'); + } + &.card-background-48 { + background-image: url('@/assets/images/backgrounds/background/bg_48.png'); + } + &.card-background-49 { + background-image: url('@/assets/images/backgrounds/background/bg_49.png'); + } + &.card-background-50 { + background-image: url('@/assets/images/backgrounds/background/bg_50.png'); + } + &.card-background-51 { + background-image: url('@/assets/images/backgrounds/background/bg_51.gif'); + } + &.card-background-52 { + background-image: url('@/assets/images/backgrounds/background/bg_52.gif'); + } + &.card-background-53 { + background-image: url('@/assets/images/backgrounds/background/bg_53.gif'); + } + &.card-background-54 { + background-image: url('@/assets/images/backgrounds/background/bg_54.gif'); + } + &.card-background-55 { + background-image: url('@/assets/images/backgrounds/background/bg_55.gif'); + } + &.card-background-56 { + background-image: url('@/assets/images/backgrounds/background/bg_56.gif'); + } + &.card-background-57 { + background-image: url('@/assets/images/backgrounds/background/bg_57.gif'); + } + &.card-background-58 { + background-image: url('@/assets/images/backgrounds/background/bg_58.gif'); + } + &.card-background-59 { + background-image: url('@/assets/images/backgrounds/background/bg_59.gif'); + } + &.card-background-60 { + background-image: url('@/assets/images/backgrounds/background/bg_60.gif'); + } + &.card-background-61 { + background-image: url('@/assets/images/backgrounds/background/bg_61.gif'); + } + &.card-background-62 { + background-image: url('@/assets/images/backgrounds/background/bg_62.gif'); + } + &.card-background-63 { + background-image: url('@/assets/images/backgrounds/background/bg_63.gif'); + } + &.card-background-64 { + background-image: url('@/assets/images/backgrounds/background/bg_64.gif'); + } + &.card-background-65 { + background-image: url('@/assets/images/backgrounds/background/bg_65.gif'); + } + &.card-background-66 { + background-image: url('@/assets/images/backgrounds/background/bg_66.gif'); + } + &.card-background-67 { + background-image: url('@/assets/images/backgrounds/background/bg_67.gif'); + } + &.card-background-68 { + background-image: url('@/assets/images/backgrounds/background/bg_68.gif'); + } + &.card-background-69 { + background-image: url('@/assets/images/backgrounds/background/bg_69.gif'); + } + &.card-background-70 { + background-image: url('@/assets/images/backgrounds/background/bg_70.gif'); + } + &.card-background-71 { + background-image: url('@/assets/images/backgrounds/background/bg_71.gif'); + } + &.card-background-72 { + background-image: url('@/assets/images/backgrounds/background/bg_72.gif'); + } + &.card-background-73 { + background-image: url('@/assets/images/backgrounds/background/bg_73.gif'); + } + &.card-background-74 { + background-image: url('@/assets/images/backgrounds/background/bg_74.gif'); + } + &.card-background-75 { + background-image: url('@/assets/images/backgrounds/background/bg_75.gif'); + } + &.card-background-76 { + background-image: url('@/assets/images/backgrounds/background/bg_76.gif'); + } + &.card-background-77 { + background-image: url('@/assets/images/backgrounds/background/bg_77.gif'); + } + &.card-background-78 { + background-image: url('@/assets/images/backgrounds/background/bg_78.gif'); + } + &.card-background-79 { + background-image: url('@/assets/images/backgrounds/background/bg_79.gif'); + } + &.card-background-80 { + background-image: url('@/assets/images/backgrounds/background/bg_80.gif'); + } + &.card-background-81 { + background-image: url('@/assets/images/backgrounds/background/bg_81.gif'); + } + &.card-background-82 { + background-image: url('@/assets/images/backgrounds/background/bg_82.gif'); + } + &.card-background-83 { + background-image: url('@/assets/images/backgrounds/background/bg_83.gif'); + } + &.card-background-84 { + background-image: url('@/assets/images/backgrounds/background/bg_84.gif'); + } + &.card-background-85 { + background-image: url('@/assets/images/backgrounds/background/bg_85.gif'); + } + &.card-background-86 { + background-image: url('@/assets/images/backgrounds/background/bg_86.png'); + } + &.card-background-87 { + background-image: url('@/assets/images/backgrounds/background/bg_87.gif'); + } + &.card-background-88 { + background-image: url('@/assets/images/backgrounds/background/bg_88.gif'); + } + &.card-background-89 { + background-image: url('@/assets/images/backgrounds/background/bg_89.gif'); + } + &.card-background-90 { + background-image: url('@/assets/images/backgrounds/background/bg_90.gif'); + } + &.card-background-91 { + background-image: url('@/assets/images/backgrounds/background/bg_91.gif'); + } + &.card-background-92 { + background-image: url('@/assets/images/backgrounds/background/bg_92.gif'); + } + &.card-background-93 { + background-image: url('@/assets/images/backgrounds/background/bg_93.gif'); + } + &.card-background-94 { + background-image: url('@/assets/images/backgrounds/background/bg_94.gif'); + } + &.card-background-95 { + background-image: url('@/assets/images/backgrounds/background/bg_95.gif'); + } + &.card-background-96 { + background-image: url('@/assets/images/backgrounds/background/bg_96.gif'); + } + &.card-background-97 { + background-image: url('@/assets/images/backgrounds/background/bg_97.gif'); + } + &.card-background-98 { + background-image: url('@/assets/images/backgrounds/background/bg_98.gif'); + } + &.card-background-99 { + background-image: url('@/assets/images/backgrounds/background/bg_99.gif'); + } + &.card-background-100 { + background-image: url('@/assets/images/backgrounds/background/bg_100.gif'); + } + &.card-background-101 { + background-image: url('@/assets/images/backgrounds/background/bg_101.png'); + } + &.card-background-102 { + background-image: url('@/assets/images/backgrounds/background/bg_102.gif'); + } + &.card-background-103 { + background-image: url('@/assets/images/backgrounds/background/bg_103.gif'); + } + &.card-background-104 { + background-image: url('@/assets/images/backgrounds/background/bg_104.gif'); + } + &.card-background-105 { + background-image: url('@/assets/images/backgrounds/background/bg_105.gif'); + } + &.card-background-106 { + background-image: url('@/assets/images/backgrounds/background/bg_106.gif'); + } + &.card-background-107 { + background-image: url('@/assets/images/backgrounds/background/bg_107.gif'); + } + &.card-background-108 { + background-image: url('@/assets/images/backgrounds/background/bg_108.gif'); + } + &.card-background-109 { + background-image: url('@/assets/images/backgrounds/background/bg_109.gif'); + } + &.card-background-110 { + background-image: url('@/assets/images/backgrounds/background/bg_110.gif'); + } + &.card-background-111 { + background-image: url('@/assets/images/backgrounds/background/bg_111.gif'); + } + &.card-background-112 { + background-image: url('@/assets/images/backgrounds/background/bg_112.gif'); + } + &.card-background-113 { + background-image: url('@/assets/images/backgrounds/background/bg_113.gif'); + } + &.card-background-114 { + background-image: url('@/assets/images/backgrounds/background/bg_114.gif'); + } + &.card-background-115 { + background-image: url('@/assets/images/backgrounds/background/bg_115.gif'); + } + &.card-background-116 { + background-image: url('@/assets/images/backgrounds/background/bg_116.gif'); + } + &.card-background-117 { + background-image: url('@/assets/images/backgrounds/background/bg_117.gif'); + } + &.card-background-118 { + background-image: url('@/assets/images/backgrounds/background/bg_118.gif'); + } + &.card-background-119 { + background-image: url('@/assets/images/backgrounds/background/bg_119.gif'); + } + &.card-background-120 { + background-image: url('@/assets/images/backgrounds/background/bg_120.gif'); + } + &.card-background-121 { + background-image: url('@/assets/images/backgrounds/background/bg_121.gif'); + } + &.card-background-122 { + background-image: url('@/assets/images/backgrounds/background/bg_122.gif'); + } + &.card-background-123 { + background-image: url('@/assets/images/backgrounds/background/bg_123.gif'); + } + &.card-background-124 { + background-image: url('@/assets/images/backgrounds/background/bg_124.gif'); + } + &.card-background-125 { + background-image: url('@/assets/images/backgrounds/background/bg_125.gif'); + } + &.card-background-126 { + background-image: url('@/assets/images/backgrounds/background/bg_126.gif'); + } + &.card-background-127 { + background-image: url('@/assets/images/backgrounds/background/bg_127.gif'); + } + &.card-background-128 { + background-image: url('@/assets/images/backgrounds/background/bg_128.gif'); + } + &.card-background-129 { + background-image: url('@/assets/images/backgrounds/background/bg_129.gif'); + } + &.card-background-130 { + background-image: url('@/assets/images/backgrounds/background/bg_130.gif'); + } + &.card-background-131 { + background-image: url('@/assets/images/backgrounds/background/bg_131.gif'); + } + &.card-background-132 { + background-image: url('@/assets/images/backgrounds/background/bg_132.gif'); + } + &.card-background-133 { + background-image: url('@/assets/images/backgrounds/background/bg_133.gif'); + } + &.card-background-134 { + background-image: url('@/assets/images/backgrounds/background/bg_134.gif'); + } + &.card-background-135 { + background-image: url('@/assets/images/backgrounds/background/bg_135.gif'); + } + &.card-background-136 { + background-image: url('@/assets/images/backgrounds/background/bg_136.gif'); + } + &.card-background-137 { + background-image: url('@/assets/images/backgrounds/background/bg_137.gif'); + } + &.card-background-138 { + background-image: url('@/assets/images/backgrounds/background/bg_138.gif'); + } + &.card-background-139 { + background-image: url('@/assets/images/backgrounds/background/bg_139.gif'); + } + &.card-background-140 { + background-image: url('@/assets/images/backgrounds/background/bg_140.gif'); + } + &.card-background-141 { + background-image: url('@/assets/images/backgrounds/background/bg_141.gif'); + } + &.card-background-142 { + background-image: url('@/assets/images/backgrounds/background/bg_142.gif'); + } + &.card-background-143 { + background-image: url('@/assets/images/backgrounds/background/bg_143.gif'); + } + &.card-background-144 { + background-image: url('@/assets/images/backgrounds/background/bg_144.gif'); + } + &.card-background-145 { + background-image: url('@/assets/images/backgrounds/background/bg_145.gif'); + } + &.card-background-146 { + background-image: url('@/assets/images/backgrounds/background/bg_146.gif'); + } + &.card-background-147 { + background-image: url('@/assets/images/backgrounds/background/bg_147.gif'); + } + &.card-background-148 { + background-image: url('@/assets/images/backgrounds/background/bg_148.gif'); + } + &.card-background-149 { + background-image: url('@/assets/images/backgrounds/background/bg_149.gif'); + } + &.card-background-150 { + background-image: url('@/assets/images/backgrounds/background/bg_150.gif'); + } + &.card-background-151 { + background-image: url('@/assets/images/backgrounds/background/bg_151.gif'); + } + &.card-background-152 { + background-image: url('@/assets/images/backgrounds/background/bg_152.gif'); + } + &.card-background-153 { + background-image: url('@/assets/images/backgrounds/background/bg_153.gif'); + } + &.card-background-154 { + background-image: url('@/assets/images/backgrounds/background/bg_154.gif'); + } + &.card-background-155 { + background-image: url('@/assets/images/backgrounds/background/bg_155.gif'); + } + &.card-background-156 { + background-image: url('@/assets/images/backgrounds/background/bg_156.gif'); + } + &.card-background-157 { + background-image: url('@/assets/images/backgrounds/background/bg_157.gif'); + } + &.card-background-158 { + background-image: url('@/assets/images/backgrounds/background/bg_158.gif'); + } + &.card-background-159 { + background-image: url('@/assets/images/backgrounds/background/bg_159.gif'); + } + &.card-background-160 { + background-image: url('@/assets/images/backgrounds/background/bg_160.gif'); + } + &.card-background-161 { + background-image: url('@/assets/images/backgrounds/background/bg_161.gif'); + } + &.card-background-162 { + background-image: url('@/assets/images/backgrounds/background/bg_162.gif'); + } + &.card-background-163 { + background-image: url('@/assets/images/backgrounds/background/bg_163.gif'); + } + &.card-background-164 { + background-image: url('@/assets/images/backgrounds/background/bg_164.gif'); + } + &.card-background-165 { + background-image: url('@/assets/images/backgrounds/background/bg_165.gif'); + } + &.card-background-166 { + background-image: url('@/assets/images/backgrounds/background/bg_166.gif'); + } + &.card-background-167 { + background-image: url('@/assets/images/backgrounds/background/bg_167.gif'); + } + &.card-background-168 { + background-image: url('@/assets/images/backgrounds/background/bg_168.gif'); + } + &.card-background-169 { + background-image: url('@/assets/images/backgrounds/background/bg_169.gif'); + } + &.card-background-170 { + background-image: url('@/assets/images/backgrounds/background/bg_170.png'); + } + &.card-background-171 { + background-image: url('@/assets/images/backgrounds/background/bg_171.png'); + } + &.card-background-172 { + background-image: url('@/assets/images/backgrounds/background/bg_172.png'); + } + &.card-background-173 { + background-image: url('@/assets/images/backgrounds/background/bg_173.png'); + } + &.card-background-174 { + background-image: url('@/assets/images/backgrounds/background/bg_174.png'); + } + &.card-background-175 { + background-image: url('@/assets/images/backgrounds/background/bg_175.png'); + } + &.card-background-176 { + background-image: url('@/assets/images/backgrounds/background/bg_176.png'); + } + &.card-background-177 { + background-image: url('@/assets/images/backgrounds/background/bg_177.gif'); + } + &.card-background-178 { + background-image: url('@/assets/images/backgrounds/background/bg_178.png'); + } + &.card-background-179 { + background-image: url('@/assets/images/backgrounds/background/bg_179.png'); + } + &.card-background-180 { + background-image: url('@/assets/images/backgrounds/background/bg_180.png'); + } + &.card-background-181 { + background-image: url('@/assets/images/backgrounds/background/bg_181.png'); + } + &.card-background-182 { + background-image: url('@/assets/images/backgrounds/background/bg_182.png'); + } + &.card-background-183 { + background-image: url('@/assets/images/backgrounds/background/bg_183.png'); + } + &.card-background-184 { + background-image: url('@/assets/images/backgrounds/background/bg_184.png'); + } + &.card-background-185 { + background-image: url('@/assets/images/backgrounds/background/bg_185.png'); + } + &.card-background-186 { + background-image: url('@/assets/images/backgrounds/background/bg_186.png'); + } + &.card-background-187 { + background-image: url('@/assets/images/backgrounds/background/bg_187.gif'); + } +} + +.profile-card-background.card-background-1 { + background: linear-gradient(135deg, #ff6b6b 0%, #ee5a52 100%); + background-repeat: no-repeat; + background-size: cover; +} +.profile-card-background.card-background-2 { + background: linear-gradient(135deg, #4ecdc4 0%, #44a8a3 100%); + background-repeat: no-repeat; + background-size: cover; +} +.profile-card-background.card-background-3 { + background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); + background-repeat: no-repeat; + background-size: cover; +} +.profile-card-background.card-background-4 { + background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); + background-repeat: no-repeat; + background-size: cover; +} +.profile-card-background.card-background-5 { + background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%); + background-repeat: no-repeat; + background-size: cover; +} +.profile-card-background.card-background-6 { + background: linear-gradient(135deg, #fa709a 0%, #fee140 100%); + background-repeat: no-repeat; + background-size: cover; +} +.profile-card-background.card-background-7 { + background: linear-gradient(135deg, #5ee7df 0%, #b490ca 100%); + background-repeat: no-repeat; + background-size: cover; +} +.profile-card-background.card-background-8 { + background: linear-gradient(135deg, #243949 0%, #517fa4 100%); + background-repeat: no-repeat; + background-size: cover; +} +.profile-card-background.card-background-9 { + background-image: repeating-linear-gradient(45deg, #ff6b9d 0 10px, #c06c84 10px 20px); + background-color: #c06c84; + background-size: auto; +} +.profile-card-background.card-background-10 { + background-image: repeating-linear-gradient(90deg, #2b5876 0 8px, #4e4376 8px 16px); + background-color: #2b5876; + background-size: auto; +} +.profile-card-background.card-background-11 { + background-image: radial-gradient(circle, #ffd54f 1.5px, transparent 2px); + background-color: #2c3e50; + background-size: 12px 12px; + background-repeat: repeat; +} +.profile-card-background.card-background-12 { + background-image: linear-gradient(45deg, #1a1a2e 25%, transparent 25%), linear-gradient(-45deg, #1a1a2e 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #1a1a2e 75%), linear-gradient(-45deg, transparent 75%, #1a1a2e 75%); + background-color: #16213e; + background-size: 16px 16px; + background-position: 0 0, 0 8px, 8px -8px, -8px 0; + background-repeat: repeat; +} +.profile-card-background.card-background-13 { + background: linear-gradient(135deg, #232526 0%, #414345 100%); + background-repeat: no-repeat; + background-size: cover; +} +.profile-card-background.card-background-14 { + background: linear-gradient(135deg, #56ab2f 0%, #a8e063 100%); + background-repeat: no-repeat; + background-size: cover; +} +.profile-card-background.card-background-15 { + background-image: linear-gradient(0deg, transparent 49%, rgba(255,255,255,0.08) 49% 51%, transparent 51%), linear-gradient(90deg, transparent 49%, rgba(255,255,255,0.08) 49% 51%, transparent 51%); + background-color: #1a1a2e; + background-size: 24px 24px; + background-repeat: repeat; +} + .profile-background { background-repeat: no-repeat; background-position: center; diff --git a/src/css/chat/Chats.css b/src/css/chat/Chats.css index 48334a5..43f093f 100644 --- a/src/css/chat/Chats.css +++ b/src/css/chat/Chats.css @@ -9,7 +9,7 @@ &.type-0 { - // normal + /* normal */ .message { font-weight: 400; } @@ -17,7 +17,7 @@ &.type-1 { - // whisper + /* whisper */ .message { font-weight: 400; font-style: italic; @@ -27,7 +27,7 @@ &.type-2 { - // shout + /* shout */ .message { font-weight: 700; } diff --git a/src/css/icons/icons.css b/src/css/icons/icons.css index 7b85ad0..54cced7 100644 --- a/src/css/icons/icons.css +++ b/src/css/icons/icons.css @@ -143,6 +143,15 @@ height: 30px; } +.nitro-icon.icon-me-badge-creator { + background-image: url("data:image/svg+xml;utf8,"); + background-repeat: no-repeat; + background-position: center; + background-size: 30px 30px; + width: 32px; + height: 32px; +} + .nitro-icon.icon-me-settings { background-image: url("@/assets/images/toolbar/icons/me-menu/cog.png"); width: 28px; diff --git a/src/css/index.css b/src/css/index.css index 2d45b84..8875e5d 100644 --- a/src/css/index.css +++ b/src/css/index.css @@ -1856,7 +1856,7 @@ body { position: relative; aspect-ratio: 1; width: 100%; - max-width: 42px; + max-width: 64px; border-radius: 0.3rem !important; overflow: hidden !important; background-color: #e9e8e4; diff --git a/src/css/login/LoginView.css b/src/css/login/LoginView.css index 3c1badb..b251f13 100644 --- a/src/css/login/LoginView.css +++ b/src/css/login/LoginView.css @@ -1,3 +1,25 @@ +@font-face { + font-family: Volter; + font-weight: normal; + font-style: normal; + src: url("@/assets/webfonts/Volter.ttf") format("truetype"); +} + +@font-face { + font-family: Volter; + font-weight: bold; + font-style: normal; + src: url("@/assets/webfonts/Volter-b.ttf") format("truetype"); +} + +.nitro-login-view, +.nitro-login-view * { + font-family: Volter, "Volter (Goldfish)", monospace; + -webkit-font-smoothing: none; + -moz-osx-font-smoothing: grayscale; + font-smooth: never; +} + .nitro-login-view { position: fixed; inset: 0; @@ -325,6 +347,33 @@ text-align: center; } +.nitro-login-card .error-line.ban-message { + display: flex; + flex-direction: column; + gap: 3px; + padding: 8px 10px; + text-align: left; + line-height: 1.35; +} + +.nitro-login-card .error-line.ban-message .ban-title { + font-size: 12px; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.3px; +} + +.nitro-login-card .error-line.ban-message .ban-status { + font-size: 11px; + font-variant-numeric: tabular-nums; +} + +.nitro-login-card .error-line.ban-message .ban-reason { + font-size: 11px; + font-style: italic; + word-break: break-word; +} + .nitro-login-card .register-card-body a { color: #134b6e; text-decoration: underline; @@ -659,3 +708,446 @@ } } +/* ─── Login News Window (Habbo flavour) ─── */ + +.nitro-login-view .login-news-stack { + position: absolute; + top: 25%; + left: 8vw; + transform: translateY(-50%); + display: flex; + flex-direction: column; + width: 388px; + z-index: 50; + pointer-events: auto; +} + +.nitro-login-view .news-card-wrapper { + position: relative; + animation: news-pop-in 0.45s cubic-bezier(0.34, 1.56, 0.64, 1) both; +} + +.nitro-login-view .news-card-wrapper > .nitro-login-card.nitro-news-card { + position: relative; + overflow: visible; + border-width: 3px; + padding-top: 22px; + background: linear-gradient(180deg, #b9d4e3 0%, #a2bfd1 60%, #93b3c8 100%); + box-shadow: + inset 0 2px rgba(255, 255, 255, 0.5), + inset 0 -2px rgba(0, 0, 0, 0.12), + 0 6px 14px rgba(0, 0, 0, 0.35), + 0 0 0 4px rgba(63, 106, 133, 0.0); + animation: news-glow 3.2s ease-in-out infinite; +} + +/* Yellow Habbo-style ribbon title */ +.nitro-login-card.nitro-news-card .card-title.news-ribbon { + position: absolute; + top: -14px; + left: -10px; + right: -10px; + margin: 0; + padding: 6px 12px; + background: linear-gradient(180deg, #ffe27a 0%, #ffc742 50%, #f0a812 100%); + color: #5a3a00; + text-shadow: 0 1px rgba(255, 255, 255, 0.55); + border: 2px solid #8a5a00; + border-radius: 6px; + box-shadow: + inset 0 1px rgba(255, 255, 255, 0.7), + inset 0 -2px rgba(0, 0, 0, 0.15), + 0 3px 0 rgba(0, 0, 0, 0.2); + font-size: 13px; + font-weight: 800; + letter-spacing: 0.6px; + text-transform: uppercase; + text-align: center; + z-index: 2; +} + +/* Pennant tails on the ribbon */ +.nitro-login-card.nitro-news-card .card-title.news-ribbon::before, +.nitro-login-card.nitro-news-card .card-title.news-ribbon::after { + content: ""; + position: absolute; + bottom: -6px; + width: 12px; + height: 12px; + background: #c47800; + border: 2px solid #8a5a00; + z-index: -1; +} + +.nitro-login-card.nitro-news-card .card-title.news-ribbon::before { + left: -2px; + clip-path: polygon(0 0, 100% 0, 100% 100%); + transform: rotate(0deg); +} + +.nitro-login-card.nitro-news-card .card-title.news-ribbon::after { + right: -2px; + clip-path: polygon(0 0, 100% 0, 0 100%); +} + +.nitro-login-card.nitro-news-card .news-ribbon-text { + display: inline-block; + animation: news-ribbon-wobble 4s ease-in-out infinite; +} + +/* "NEW!" star badge */ +.nitro-login-view .news-new-badge { + position: absolute; + top: -28px; + right: -24px; + width: 78px; + height: 78px; + background: + radial-gradient(circle at 35% 30%, #fff7c2 0%, #ffd23a 45%, #d97c00 100%); + color: #5a1900; + font-weight: 900; + font-size: 11px; + letter-spacing: 0; + text-transform: uppercase; + text-shadow: 0 1px rgba(255, 255, 255, 0.6); + display: flex; + align-items: center; + justify-content: center; + border: 2px solid #8a3a00; + box-shadow: + inset 0 2px rgba(255, 255, 255, 0.55), + inset 0 -2px rgba(0, 0, 0, 0.2), + 0 3px 6px rgba(0, 0, 0, 0.35); + clip-path: polygon( + 50% 0%, 61% 35%, 98% 35%, 68% 57%, + 79% 91%, 50% 70%, 21% 91%, 32% 57%, + 2% 35%, 39% 35% + ); + z-index: 4; + animation: news-badge-spin 2.8s ease-in-out infinite; + pointer-events: none; +} + +.nitro-login-view .news-new-badge span { + transform: rotate(-10deg); + display: inline-block; + line-height: 1; + white-space: nowrap; +} + +/* Sparkles around the card */ +.nitro-login-view .news-sparkle { + position: absolute; + color: #fff5b0; + text-shadow: + 0 0 6px rgba(255, 220, 120, 0.9), + 0 0 12px rgba(255, 200, 60, 0.6); + pointer-events: none; + z-index: 3; + user-select: none; + font-weight: 700; +} + +.nitro-login-view .news-sparkle-1 { + top: -8px; + left: 18px; + font-size: 14px; + animation: news-sparkle 2.1s ease-in-out infinite; + animation-delay: 0s; +} + +.nitro-login-view .news-sparkle-2 { + top: 38%; + left: -12px; + font-size: 12px; + animation: news-sparkle 2.4s ease-in-out infinite; + animation-delay: 0.6s; +} + +.nitro-login-view .news-sparkle-3 { + bottom: -6px; + right: 36px; + font-size: 16px; + animation: news-sparkle 2.7s ease-in-out infinite; + animation-delay: 1.1s; +} + +/* Body */ +.nitro-login-card.nitro-news-card .card-body.news-body { + gap: 8px; + font-size: 12px; + color: #0a2e45; +} + +.nitro-login-card.nitro-news-card .news-image { + position: relative; + display: flex; + align-items: center; + justify-content: center; + border: 2px solid #3f6a85; + border-radius: 4px; + background: + repeating-linear-gradient( + 45deg, + rgba(255, 255, 255, 0.15) 0 6px, + rgba(255, 255, 255, 0) 6px 12px + ), + linear-gradient(180deg, #cfe1ee 0%, #a8c5d6 100%); + overflow: hidden; + box-shadow: + inset 0 2px rgba(255, 255, 255, 0.6), + inset 0 -2px rgba(0, 0, 0, 0.15); + max-height: 150px; + transition: transform 0.25s ease; +} + +.nitro-login-card.nitro-news-card .news-image:hover { + transform: translateY(-1px) scale(1.01); +} + +.nitro-login-card.nitro-news-card .news-image::after { + content: ""; + position: absolute; + inset: 0; + pointer-events: none; + background: linear-gradient(180deg, rgba(255, 255, 255, 0.35) 0%, rgba(255, 255, 255, 0) 35%); +} + +.nitro-login-card.nitro-news-card .news-image img { + max-width: 100%; + max-height: 146px; + width: auto; + height: auto; + display: block; + image-rendering: pixelated; + image-rendering: -moz-crisp-edges; + position: relative; + z-index: 1; +} + +.nitro-login-card.nitro-news-card .news-headline { + font-weight: 800; + font-size: 13px; + line-height: 1.25; + color: #0a2e45; + text-shadow: 0 1px rgba(255, 255, 255, 0.5); + letter-spacing: 0.2px; + border-bottom: 1px dashed rgba(63, 106, 133, 0.4); + padding-bottom: 4px; +} + +.nitro-login-card.nitro-news-card .news-text { + font-size: 11px; + line-height: 1.45; + color: #103e5d; + white-space: pre-line; + word-break: break-word; + max-height: 120px; + overflow-y: auto; + padding-right: 2px; +} + +.nitro-login-card.nitro-news-card .news-text::-webkit-scrollbar { + width: 6px; +} + +.nitro-login-card.nitro-news-card .news-text::-webkit-scrollbar-thumb { + background: rgba(63, 106, 133, 0.6); + border-radius: 3px; +} + +.nitro-login-card.nitro-news-card .news-footer { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; + margin-top: 4px; +} + +.nitro-login-card.nitro-news-card .news-link-button { + padding: 4px 14px; + font-size: 11px; + font-weight: 800; + background: linear-gradient(180deg, #ffe27a 0%, #ffc742 60%, #f0a812 100%); + color: #5a3a00; + border: 1px solid #8a5a00; + text-shadow: 0 1px rgba(255, 255, 255, 0.45); + box-shadow: + inset 0 1px rgba(255, 255, 255, 0.7), + inset 0 -1px rgba(0, 0, 0, 0.15), + 0 2px 0 rgba(0, 0, 0, 0.2); + transition: transform 0.12s ease, box-shadow 0.12s ease; +} + +.nitro-login-card.nitro-news-card .news-link-button:hover { + background: linear-gradient(180deg, #fff0a8 0%, #ffd45c 60%, #f7b822 100%); + transform: translateY(-1px); + box-shadow: + inset 0 1px rgba(255, 255, 255, 0.8), + inset 0 -1px rgba(0, 0, 0, 0.15), + 0 3px 0 rgba(0, 0, 0, 0.25); +} + +.nitro-login-card.nitro-news-card .news-link-button:active { + transform: translateY(1px); + box-shadow: + inset 0 1px rgba(0, 0, 0, 0.15), + 0 0 0 rgba(0, 0, 0, 0); +} + +.nitro-login-card.nitro-news-card .news-pager { + display: flex; + align-items: center; + gap: 6px; + margin-left: auto; +} + +.nitro-login-card.nitro-news-card .news-pager .arrow-btn { + transition: transform 0.12s ease; +} + +.nitro-login-card.nitro-news-card .news-pager .arrow-btn:hover { + transform: scale(1.15); +} + +.nitro-login-card.nitro-news-card .news-counter { + font-size: 11px; + color: #134b6e; + font-weight: 700; + font-variant-numeric: tabular-nums; + min-width: 28px; + text-align: center; + text-shadow: 0 1px rgba(255, 255, 255, 0.4); +} + +@keyframes news-pop-in { + 0% { opacity: 0; transform: scale(0.85) translateY(8px); } + 60% { opacity: 1; transform: scale(1.04) translateY(0); } + 100% { opacity: 1; transform: scale(1) translateY(0); } +} + +@keyframes news-glow { + 0%, 100% { box-shadow: + inset 0 2px rgba(255, 255, 255, 0.5), + inset 0 -2px rgba(0, 0, 0, 0.12), + 0 6px 14px rgba(0, 0, 0, 0.35), + 0 0 0 0 rgba(255, 210, 60, 0.0); } + 50% { box-shadow: + inset 0 2px rgba(255, 255, 255, 0.5), + inset 0 -2px rgba(0, 0, 0, 0.12), + 0 6px 14px rgba(0, 0, 0, 0.35), + 0 0 18px 4px rgba(255, 210, 60, 0.45); } +} + +@keyframes news-ribbon-wobble { + 0%, 100% { transform: rotate(0deg) translateY(0); } + 25% { transform: rotate(-1.2deg) translateY(-1px); } + 75% { transform: rotate(1.2deg) translateY(1px); } +} + +@keyframes news-badge-spin { + 0%, 100% { transform: rotate(-8deg) scale(1); } + 50% { transform: rotate(8deg) scale(1.08); } +} + +@keyframes news-sparkle { + 0%, 100% { opacity: 0.2; transform: scale(0.7) rotate(0deg); } + 50% { opacity: 1; transform: scale(1.2) rotate(20deg); } +} + +@media (prefers-reduced-motion: reduce) { + .nitro-login-view .news-card-wrapper, + .nitro-login-view .news-card-wrapper > .nitro-login-card.nitro-news-card, + .nitro-login-view .news-new-badge, + .nitro-login-view .news-sparkle, + .nitro-login-card.nitro-news-card .news-ribbon-text { + animation: none !important; + } +} + +@media (max-width: 900px) { + .nitro-login-view .login-news-stack { + display: none; + } +} + +/* ─── Cloud intro (plays once per session) ─── */ + +.login-intro-clouds { + position: fixed; + inset: 0; + z-index: 1000; + pointer-events: none; + overflow: hidden; + animation: cloud-overlay-fade 2.8s linear forwards; +} + +.intro-cloud-bank { + position: absolute; + left: -10%; + width: 120%; + height: 70%; + display: flex; + align-items: center; + justify-content: space-around; + will-change: transform; +} + +.intro-cloud-bank-top { + top: -70%; + animation: cloud-bank-top 2.8s cubic-bezier(0.65, 0, 0.35, 1) forwards; +} + +.intro-cloud-bank-bottom { + bottom: -70%; + animation: cloud-bank-bottom 2.8s cubic-bezier(0.65, 0, 0.35, 1) forwards; +} + +.intro-cloud-puff { + flex-shrink: 0; + background: + radial-gradient(ellipse at 45% 38%, #ffffff 0%, #fbfdff 35%, rgba(247, 251, 255, 0.85) 60%, rgba(255, 255, 255, 0) 78%); + filter: drop-shadow(0 8px 14px rgba(140, 175, 205, 0.35)); + border-radius: 50%; +} + +.intro-cloud-bank-top .intro-cloud-puff { + align-self: flex-end; +} + +.intro-cloud-bank-bottom .intro-cloud-puff { + align-self: flex-start; +} + +.intro-cloud-puff-1 { width: 360px; height: 320px; transform: translateY(-10px); } +.intro-cloud-puff-2 { width: 260px; height: 240px; transform: translateY(20px); } +.intro-cloud-puff-3 { width: 420px; height: 380px; transform: translateY(-30px); } +.intro-cloud-puff-4 { width: 300px; height: 280px; transform: translateY(15px); } +.intro-cloud-puff-5 { width: 340px; height: 300px; transform: translateY(-5px); } + +@keyframes cloud-bank-top { + 0% { transform: translateY(0); } + 35% { transform: translateY(105%); } + 55% { transform: translateY(105%); } + 100% { transform: translateY(-10%); } +} + +@keyframes cloud-bank-bottom { + 0% { transform: translateY(0); } + 35% { transform: translateY(-105%); } + 55% { transform: translateY(-105%); } + 100% { transform: translateY(10%); } +} + +@keyframes cloud-overlay-fade { + 0%, 88% { opacity: 1; } + 100% { opacity: 0; } +} + +@media (prefers-reduced-motion: reduce) { + .login-intro-clouds, + .intro-cloud-bank-top, + .intro-cloud-bank-bottom { + animation-duration: 0.4s !important; + } +} diff --git a/src/layout/InfiniteGrid.tsx b/src/layout/InfiniteGrid.tsx index 147ae01..41a087d 100644 --- a/src/layout/InfiniteGrid.tsx +++ b/src/layout/InfiniteGrid.tsx @@ -10,19 +10,54 @@ type Props = { overscan?: number; estimateSize?: number; squareItems?: boolean; + itemMinWidth?: number; + rowGap?: number; itemRender?: (item: T, index?: number) => ReactElement; } +const GRID_GAP_PX = 4; + const InfiniteGridRoot = (props: Props) => { - const { items = [], columnCount = 4, overscan = 5, estimateSize = 45, squareItems = false, itemRender = null } = props; + const { items = [], columnCount: columnCountProp = 4, overscan = 5, estimateSize = 45, squareItems = false, itemMinWidth = null, rowGap = null, itemRender = null } = props; const parentRef = useRef(null); + const [ measuredColumnCount, setMeasuredColumnCount ] = useState(columnCountProp); + + const columnCount = (itemMinWidth && itemMinWidth > 0) ? measuredColumnCount : columnCountProp; + const rowsContainerClassName = (rowGap !== null) ? 'flex flex-col w-full relative' : 'flex flex-col w-full *:pb-1 relative'; + + useEffect(() => + { + if(!itemMinWidth || itemMinWidth <= 0) return; + + const element = parentRef.current; + if(!element) return; + + const recompute = () => + { + const width = element.clientWidth; + const cols = Math.max(1, Math.floor((width + GRID_GAP_PX) / (itemMinWidth + GRID_GAP_PX))); + setMeasuredColumnCount(prev => prev === cols ? prev : cols); + }; + + recompute(); + + const observer = new ResizeObserver(recompute); + observer.observe(element); + + return () => observer.disconnect(); + }, [ itemMinWidth ]); + + const autoFillStyle = (itemMinWidth && itemMinWidth > 0) + ? { gridTemplateColumns: `repeat(auto-fill, ${ itemMinWidth }px)` } + : null; + const fixedColsClass = (itemMinWidth && itemMinWidth > 0) ? '' : `grid-cols-${ columnCountProp }`; if(squareItems) { return (
-
+
{ items.map((item, index) => { if(!item) return ; @@ -78,7 +113,7 @@ const InfiniteGridRoot = (props: Props) => ref={ parentRef } className="overflow-y-auto size-full">
@@ -86,10 +121,12 @@ const InfiniteGridRoot = (props: Props) =>
{ Array.from(Array(columnCount)).map((e, i) => diff --git a/yarn.lock b/yarn.lock index 4c4c563..872d873 100644 --- a/yarn.lock +++ b/yarn.lock @@ -21,7 +21,7 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.29.0.tgz#00d03e8c0ac24dd9be942c5370990cbe1f17d88d" integrity sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg== -"@babel/core@^7.24.4", "@babel/core@^7.29.0": +"@babel/core@^7.24.4": version "7.29.0" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.29.0.tgz#5286ad785df7f79d656e88ce86e650d16ca5f322" integrity sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA== @@ -86,11 +86,6 @@ "@babel/helper-validator-identifier" "^7.28.5" "@babel/traverse" "^7.28.6" -"@babel/helper-plugin-utils@^7.27.1": - version "7.28.6" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz#6f13ea251b68c8532e985fd532f28741a8af9ac8" - integrity sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug== - "@babel/helper-string-parser@^7.27.1": version "7.27.1" resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz#54da796097ab19ce67ed9f88b47bb2ec49367687" @@ -114,28 +109,14 @@ "@babel/template" "^7.28.6" "@babel/types" "^7.29.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.24.4", "@babel/parser@^7.28.6", "@babel/parser@^7.29.0": +"@babel/parser@^7.24.4", "@babel/parser@^7.28.6", "@babel/parser@^7.29.0": version "7.29.2" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.2.tgz#58bd50b9a7951d134988a1ae177a35ef9a703ba1" integrity sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA== dependencies: "@babel/types" "^7.29.0" -"@babel/plugin-transform-react-jsx-self@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz#af678d8506acf52c577cac73ff7fe6615c85fc92" - integrity sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-react-jsx-source@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz#dcfe2c24094bb757bf73960374e7c55e434f19f0" - integrity sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/runtime@^7.24.7", "@babel/runtime@^7.26.0", "@babel/runtime@^7.26.9", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.8.7": +"@babel/runtime@^7.29.2": version "7.29.2" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.29.2.tgz#9a6e2d05f4b6692e1801cd4fb176ad823930ed5e" integrity sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g== @@ -162,7 +143,7 @@ "@babel/types" "^7.29.0" debug "^4.3.1" -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.28.2", "@babel/types@^7.28.6", "@babel/types@^7.29.0": +"@babel/types@^7.28.6", "@babel/types@^7.29.0": version "7.29.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.29.0.tgz#9f5b1e838c446e72cf3cd4b918152b8c605e37c7" integrity sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A== @@ -170,25 +151,25 @@ "@babel/helper-string-parser" "^7.27.1" "@babel/helper-validator-identifier" "^7.28.5" -"@emnapi/core@^1.8.1": - version "1.9.1" - resolved "https://registry.yarnpkg.com/@emnapi/core/-/core-1.9.1.tgz#2143069c744ca2442074f8078462e51edd63c7bd" - integrity sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA== +"@emnapi/core@1.10.0", "@emnapi/core@^1.8.1": + version "1.10.0" + resolved "https://registry.yarnpkg.com/@emnapi/core/-/core-1.10.0.tgz#380ccc8f2412ea22d1d972df7f8ee23a3b9c7467" + integrity sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw== dependencies: - "@emnapi/wasi-threads" "1.2.0" + "@emnapi/wasi-threads" "1.2.1" tslib "^2.4.0" -"@emnapi/runtime@^1.8.1": - version "1.9.1" - resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.9.1.tgz#115ff2a0d589865be6bd8e9d701e499c473f2a8d" - integrity sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA== +"@emnapi/runtime@1.10.0", "@emnapi/runtime@^1.8.1": + version "1.10.0" + resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.10.0.tgz#4b260c0d3534204e98c6110b8db1a987d26ec87c" + integrity sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA== dependencies: tslib "^2.4.0" -"@emnapi/wasi-threads@1.2.0", "@emnapi/wasi-threads@^1.1.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@emnapi/wasi-threads/-/wasi-threads-1.2.0.tgz#a19d9772cc3d195370bf6e2a805eec40aa75e18e" - integrity sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg== +"@emnapi/wasi-threads@1.2.1", "@emnapi/wasi-threads@^1.1.0": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz#28fed21a1ba1ce797c44a070abc94d42f3ae8548" + integrity sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w== dependencies: tslib "^2.4.0" @@ -202,136 +183,6 @@ resolved "https://registry.yarnpkg.com/@emoji-mart/react/-/react-1.1.1.tgz#ddad52f93a25baf31c5383c3e7e4c6e05554312a" integrity sha512-NMlFNeWgv1//uPsvLxvGQoIerPuVdXwK/EUek8OOkJ6wVOWPUizRBJU0hDqWZCOROVpfBgCemaC3m6jDOXi03g== -"@esbuild/aix-ppc64@0.27.4": - version "0.27.4" - resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.27.4.tgz#4c585002f7ad694d38fe0e8cbf5cfd939ccff327" - integrity sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q== - -"@esbuild/android-arm64@0.27.4": - version "0.27.4" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.27.4.tgz#7625d0952c3b402d3ede203a16c9f2b78f8a4827" - integrity sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw== - -"@esbuild/android-arm@0.27.4": - version "0.27.4" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.27.4.tgz#9a0cf1d12997ec46dddfb32ce67e9bca842381ac" - integrity sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ== - -"@esbuild/android-x64@0.27.4": - version "0.27.4" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.27.4.tgz#06e1fdc6283fccd6bc6aadd6754afce6cf96f42e" - integrity sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw== - -"@esbuild/darwin-arm64@0.27.4": - version "0.27.4" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.27.4.tgz#6c550ee6c0273bcb0fac244478ff727c26755d80" - integrity sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ== - -"@esbuild/darwin-x64@0.27.4": - version "0.27.4" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.27.4.tgz#ed7a125e9f25ce0091b9aff783ee943f6ba6cb86" - integrity sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw== - -"@esbuild/freebsd-arm64@0.27.4": - version "0.27.4" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.4.tgz#597dc8e7161dba71db4c1656131c1f1e9d7660c6" - integrity sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw== - -"@esbuild/freebsd-x64@0.27.4": - version "0.27.4" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.27.4.tgz#ea171f9f4f00efaa8e9d3fe8baa1b75d757d1b36" - integrity sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ== - -"@esbuild/linux-arm64@0.27.4": - version "0.27.4" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.27.4.tgz#e52d57f202369386e6dbcb3370a17a0491ab1464" - integrity sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA== - -"@esbuild/linux-arm@0.27.4": - version "0.27.4" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.27.4.tgz#5e0c0b634908adbce0a02cebeba8b3acac263fb6" - integrity sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg== - -"@esbuild/linux-ia32@0.27.4": - version "0.27.4" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.27.4.tgz#5f90f01f131652473ec06b038a14c49683e14ec7" - integrity sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA== - -"@esbuild/linux-loong64@0.27.4": - version "0.27.4" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.27.4.tgz#63bacffdb99574c9318f9afbd0dd4fff76a837e3" - integrity sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA== - -"@esbuild/linux-mips64el@0.27.4": - version "0.27.4" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.27.4.tgz#c4b6952eca6a8efff67fee3671a3536c8e67b7eb" - integrity sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw== - -"@esbuild/linux-ppc64@0.27.4": - version "0.27.4" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.27.4.tgz#6dea67d3d98c6986f1b7769e4f1848e5ae47ad58" - integrity sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA== - -"@esbuild/linux-riscv64@0.27.4": - version "0.27.4" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.27.4.tgz#9ad2b4c3c0502c6bada9c81997bb56c597853489" - integrity sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw== - -"@esbuild/linux-s390x@0.27.4": - version "0.27.4" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.27.4.tgz#c43d3cfd073042ca6f5c52bb9bc313ed2066ce28" - integrity sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA== - -"@esbuild/linux-x64@0.27.4": - version "0.27.4" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.27.4.tgz#45fa173e0591ac74d80d3cf76704713e14e2a4a6" - integrity sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA== - -"@esbuild/netbsd-arm64@0.27.4": - version "0.27.4" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.4.tgz#366b0ef40cdb986fc751cbdad16e8c25fe1ba879" - integrity sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q== - -"@esbuild/netbsd-x64@0.27.4": - version "0.27.4" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.27.4.tgz#e985d49a3668fd2044343071d52e1ae815112b3e" - integrity sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg== - -"@esbuild/openbsd-arm64@0.27.4": - version "0.27.4" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.4.tgz#6fb4ab7b73f7e5572ce5ec9cf91c13ff6dd44842" - integrity sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow== - -"@esbuild/openbsd-x64@0.27.4": - version "0.27.4" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.27.4.tgz#641f052040a0d79843d68898f5791638a026d983" - integrity sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ== - -"@esbuild/openharmony-arm64@0.27.4": - version "0.27.4" - resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.4.tgz#fc1d33eac9d81ae0a433b3ed1dd6171a20d4e317" - integrity sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg== - -"@esbuild/sunos-x64@0.27.4": - version "0.27.4" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.27.4.tgz#af2cd5ca842d6d057121f66a192d4f797de28f53" - integrity sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g== - -"@esbuild/win32-arm64@0.27.4": - version "0.27.4" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.27.4.tgz#78ec7e59bb06404583d4c9511e621db31c760de3" - integrity sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg== - -"@esbuild/win32-ia32@0.27.4": - version "0.27.4" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.27.4.tgz#0e616aa488b7ee5d2592ab070ff9ec06a9fddf11" - integrity sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw== - -"@esbuild/win32-x64@0.27.4": - version "0.27.4" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.27.4.tgz#1f7ba71a3d6155d44a6faa8dbe249c62ab3e408c" - integrity sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg== - "@eslint-community/eslint-utils@^4.8.0", "@eslint-community/eslint-utils@^4.9.1": version "4.9.1" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz#4e90af67bc51ddee6cdef5284edf572ec376b595" @@ -344,55 +195,90 @@ resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.2.tgz#bccdf615bcf7b6e8db830ec0b8d21c9a25de597b" integrity sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew== -"@eslint/config-array@^0.23.3": - version "0.23.3" - resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.23.3.tgz#3f4a93dd546169c09130cbd10f2415b13a20a219" - integrity sha512-j+eEWmB6YYLwcNOdlwQ6L2OsptI/LO6lNBuLIqe5R7RetD658HLoF+Mn7LzYmAWWNNzdC6cqP+L6r8ujeYXWLw== +"@eslint/config-array@^0.23.5": + version "0.23.5" + resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.23.5.tgz#56e86d243049195d8acc0c06a1b3dfdc3fa3de95" + integrity sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA== dependencies: - "@eslint/object-schema" "^3.0.3" + "@eslint/object-schema" "^3.0.5" debug "^4.3.1" minimatch "^10.2.4" -"@eslint/config-helpers@^0.5.3": - version "0.5.3" - resolved "https://registry.yarnpkg.com/@eslint/config-helpers/-/config-helpers-0.5.3.tgz#721fe6bbb90d74b0c80d6ff2428e5bbcb002becb" - integrity sha512-lzGN0onllOZCGroKJmRwY6QcEHxbjBw1gwB8SgRSqK8YbbtEXMvKynsXc3553ckIEBxsbMBU7oOZXKIPGZNeZw== +"@eslint/config-helpers@^0.5.5": + version "0.5.5" + resolved "https://registry.yarnpkg.com/@eslint/config-helpers/-/config-helpers-0.5.5.tgz#ae16134e4792ac5fbdc533548a24ac1ea9f7f3ae" + integrity sha512-eIJYKTCECbP/nsKaaruF6LW967mtbQbsw4JTtSVkUQc9MneSkbrgPJAbKl9nWr0ZeowV8BfsarBmPpBzGelA2w== dependencies: - "@eslint/core" "^1.1.1" + "@eslint/core" "^1.2.1" -"@eslint/core@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@eslint/core/-/core-1.1.1.tgz#450f3d2be2d463ccd51119544092256b4e88df32" - integrity sha512-QUPblTtE51/7/Zhfv8BDwO0qkkzQL7P/aWWbqcf4xWLEYn1oKjdO0gglQBB4GAsu7u6wjijbCmzsUTy6mnk6oQ== +"@eslint/core@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@eslint/core/-/core-1.2.1.tgz#c1da7cd1b82fa8787f98b5629fb811848a1b63ce" + integrity sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ== dependencies: "@types/json-schema" "^7.0.15" -"@eslint/object-schema@^3.0.3": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-3.0.3.tgz#5bf671e52e382e4adc47a9906f2699374637db6b" - integrity sha512-iM869Pugn9Nsxbh/YHRqYiqd23AmIbxJOcpUMOuWCVNdoQJ5ZtwL6h3t0bcZzJUlC3Dq9jCFCESBZnX0GTv7iQ== +"@eslint/object-schema@^3.0.5": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-3.0.5.tgz#88e9bf4d11d2b19c082e78ebe7ce88724a5eb091" + integrity sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw== -"@eslint/plugin-kit@^0.6.1": - version "0.6.1" - resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.6.1.tgz#eb9e6689b56ce8bc1855bb33090e63f3fc115e8e" - integrity sha512-iH1B076HoAshH1mLpHMgwdGeTs0CYwL0SPMkGuSebZrwBp16v415e9NZXg2jtrqPVQjf6IANe2Vtlr5KswtcZQ== +"@eslint/plugin-kit@^0.7.1": + version "0.7.1" + resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.7.1.tgz#c4125fd015eceeb09b793109fdbcd4dd0a02d346" + integrity sha512-rZAP3aVgB9ds9KOeUSL+zZ21hPmo8dh6fnIFwRQj5EAZl9gzR7wxYbYXYysAM8CTqGmUGyp2S4kUdV17MnGuWQ== dependencies: - "@eslint/core" "^1.1.1" + "@eslint/core" "^1.2.1" levn "^0.4.1" -"@humanfs/core@^0.19.1": - version "0.19.1" - resolved "https://registry.yarnpkg.com/@humanfs/core/-/core-0.19.1.tgz#17c55ca7d426733fe3c561906b8173c336b40a77" - integrity sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA== +"@floating-ui/core@^1.7.5": + version "1.7.5" + resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.7.5.tgz#d4af157a03330af5a60e69da7a4692507ada0622" + integrity sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ== + dependencies: + "@floating-ui/utils" "^0.2.11" + +"@floating-ui/dom@^1.7.6": + version "1.7.6" + resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.7.6.tgz#f915bba5abbb177e1f227cacee1b4d0634b187bf" + integrity sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ== + dependencies: + "@floating-ui/core" "^1.7.5" + "@floating-ui/utils" "^0.2.11" + +"@floating-ui/react-dom@^2.0.0": + version "2.1.8" + resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.1.8.tgz#5fb5a20d10aafb9505f38c24f38d00c8e1598893" + integrity sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A== + dependencies: + "@floating-ui/dom" "^1.7.6" + +"@floating-ui/utils@^0.2.11": + version "0.2.11" + resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.11.tgz#a269e055e40e2f45873bae9d1a2fdccbd314ea3f" + integrity sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg== + +"@humanfs/core@^0.19.2": + version "0.19.2" + resolved "https://registry.yarnpkg.com/@humanfs/core/-/core-0.19.2.tgz#a8272ca03b2acf492670222b2320b6c421bfde60" + integrity sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA== + dependencies: + "@humanfs/types" "^0.15.0" "@humanfs/node@^0.16.6": - version "0.16.7" - resolved "https://registry.yarnpkg.com/@humanfs/node/-/node-0.16.7.tgz#822cb7b3a12c5a240a24f621b5a2413e27a45f26" - integrity sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ== + version "0.16.8" + resolved "https://registry.yarnpkg.com/@humanfs/node/-/node-0.16.8.tgz#8f800cccc13f4f8cd3116e2d9c0a94939da3e3ed" + integrity sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ== dependencies: - "@humanfs/core" "^0.19.1" + "@humanfs/core" "^0.19.2" + "@humanfs/types" "^0.15.0" "@humanwhocodes/retry" "^0.4.0" +"@humanfs/types@^0.15.0": + version "0.15.0" + resolved "https://registry.yarnpkg.com/@humanfs/types/-/types-0.15.0.tgz#f2a09f62012390b2bff3fc6fb248ddec8c09a090" + integrity sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q== + "@humanwhocodes/module-importer@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" @@ -437,13 +323,18 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" -"@napi-rs/wasm-runtime@^1.1.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.2.tgz#e25454b4d44cfabd21d1bc801705359870e33ecc" - integrity sha512-sNXv5oLJ7ob93xkZ1XnxisYhGYXfaG9f65/ZgYuAu3qt7b3NadcOEhLvx28hv31PgX8SZJRYrAIPQilQmFpLVw== +"@napi-rs/wasm-runtime@^1.1.1", "@napi-rs/wasm-runtime@^1.1.4": + version "1.1.4" + resolved "https://registry.yarnpkg.com/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz#a46bbfedc29751b7170c5d23bc1d8ee8c7e3c1e1" + integrity sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow== dependencies: "@tybys/wasm-util" "^0.10.1" +"@oxc-project/types@=0.127.0": + version "0.127.0" + resolved "https://registry.yarnpkg.com/@oxc-project/types/-/types-0.127.0.tgz#8374fcdfb4a641861218daa5700c447c00b66663" + integrity sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ== + "@parcel/watcher-android-arm64@2.5.6": version "2.5.6" resolved "https://registry.yarnpkg.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz#5f32e0dba356f4ac9a11068d2a5c134ca3ba6564" @@ -533,183 +424,308 @@ "@parcel/watcher-win32-ia32" "2.5.6" "@parcel/watcher-win32-x64" "2.5.6" -"@popperjs/core@^2.11.8": - version "2.11.8" - resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" - integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== +"@radix-ui/number@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@radix-ui/number/-/number-1.1.1.tgz#7b2c9225fbf1b126539551f5985769d0048d9090" + integrity sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g== -"@react-aria/ssr@^3.5.0": - version "3.9.10" - resolved "https://registry.yarnpkg.com/@react-aria/ssr/-/ssr-3.9.10.tgz#7fdc09e811944ce0df1d7e713de1449abd7435e6" - integrity sha512-hvTm77Pf+pMBhuBm760Li0BVIO38jv1IBws1xFm1NoL26PU+fe+FMW5+VZWyANR6nYL65joaJKZqOdTQMkO9IQ== +"@radix-ui/primitive@1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.1.3.tgz#e2dbc13bdc5e4168f4334f75832d7bdd3e2de5ba" + integrity sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg== + +"@radix-ui/react-arrow@1.1.7": + version "1.1.7" + resolved "https://registry.yarnpkg.com/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz#e14a2657c81d961598c5e72b73dd6098acc04f09" + integrity sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w== dependencies: - "@swc/helpers" "^0.5.0" + "@radix-ui/react-primitive" "2.1.3" -"@restart/hooks@^0.4.9": - version "0.4.16" - resolved "https://registry.yarnpkg.com/@restart/hooks/-/hooks-0.4.16.tgz#95ae8ac1cc7e2bd4fed5e39800ff85604c6d59fb" - integrity sha512-f7aCv7c+nU/3mF7NWLtVVr0Ra80RqsO89hO72r+Y/nvQr5+q0UFGkocElTH6MJApvReVh6JHUFYn2cw1WdHF3w== +"@radix-ui/react-collection@1.1.7": + version "1.1.7" + resolved "https://registry.yarnpkg.com/@radix-ui/react-collection/-/react-collection-1.1.7.tgz#d05c25ca9ac4695cc19ba91f42f686e3ea2d9aec" + integrity sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw== dependencies: - dequal "^2.0.3" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-slot" "1.2.3" -"@restart/hooks@^0.5.0": - version "0.5.1" - resolved "https://registry.yarnpkg.com/@restart/hooks/-/hooks-0.5.1.tgz#6776b3859e33aea72b23b81fc47021edf17fd247" - integrity sha512-EMoH04NHS1pbn07iLTjIjgttuqb7qu4+/EyhAx27MHpoENcB2ZdSsLTNxmKD+WEPnZigo62Qc8zjGnNxoSE/5Q== +"@radix-ui/react-compose-refs@1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz#a2c4c47af6337048ee78ff6dc0d090b390d2bb30" + integrity sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg== + +"@radix-ui/react-context@1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.1.2.tgz#61628ef269a433382c364f6f1e3788a6dc213a36" + integrity sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA== + +"@radix-ui/react-direction@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-direction/-/react-direction-1.1.1.tgz#39e5a5769e676c753204b792fbe6cf508e550a14" + integrity sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw== + +"@radix-ui/react-dismissable-layer@1.1.11": + version "1.1.11" + resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz#e33ab6f6bdaa00f8f7327c408d9f631376b88b37" + integrity sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg== dependencies: - dequal "^2.0.3" + "@radix-ui/primitive" "1.1.3" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-use-callback-ref" "1.1.1" + "@radix-ui/react-use-escape-keydown" "1.1.1" -"@restart/ui@^1.9.4": - version "1.9.4" - resolved "https://registry.yarnpkg.com/@restart/ui/-/ui-1.9.4.tgz#9d61f56f2647f5ab8a33d87b278b9ce183511a26" - integrity sha512-N4C7haUc3vn4LTwVUPlkJN8Ach/+yIMvRuTVIhjilNHqegY60SGLrzud6errOMNJwSnmYFnt1J0H/k8FE3A4KA== +"@radix-ui/react-focus-guards@1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz#2a5669e464ad5fde9f86d22f7fdc17781a4dfa7f" + integrity sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw== + +"@radix-ui/react-focus-scope@1.1.7": + version "1.1.7" + resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz#dfe76fc103537d80bf42723a183773fd07bfb58d" + integrity sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw== dependencies: - "@babel/runtime" "^7.26.0" - "@popperjs/core" "^2.11.8" - "@react-aria/ssr" "^3.5.0" - "@restart/hooks" "^0.5.0" - "@types/warning" "^3.0.3" - dequal "^2.0.3" - dom-helpers "^5.2.0" - uncontrollable "^8.0.4" - warning "^4.0.3" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-use-callback-ref" "1.1.1" -"@rolldown/pluginutils@1.0.0-rc.3": - version "1.0.0-rc.3" - resolved "https://registry.yarnpkg.com/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz#8a88cc92a0f741befc7bc109cb1a4c6b9408e1c5" - integrity sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q== - -"@rollup/rollup-android-arm-eabi@4.60.1": - version "4.60.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.1.tgz#043f145716234529052ef9e1ce1d847ffbe9e674" - integrity sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA== - -"@rollup/rollup-android-arm64@4.60.1": - version "4.60.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.1.tgz#023e1bd146e7519087dfd9e8b29e4cf9f8ecd35c" - integrity sha512-YjG/EwIDvvYI1YvYbHvDz/BYHtkY4ygUIXHnTdLhG+hKIQFBiosfWiACWortsKPKU/+dUwQQCKQM3qrDe8c9BA== - -"@rollup/rollup-darwin-arm64@4.60.1": - version "4.60.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.1.tgz#55ccb5487c02419954c57a7a80602885d616e1ee" - integrity sha512-mjCpF7GmkRtSJwon+Rq1N8+pI+8l7w5g9Z3vWj4T7abguC4Czwi3Yu/pFaLvA3TTeMVjnu3ctigusqWUfjZzvw== - -"@rollup/rollup-darwin-x64@4.60.1": - version "4.60.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.1.tgz#254b65404b14488c83225e88b8819376ad71a784" - integrity sha512-haZ7hJ1JT4e9hqkoT9R/19XW2QKqjfJVv+i5AGg57S+nLk9lQnJ1F/eZloRO3o9Scy9CM3wQ9l+dkXtcBgN5Ew== - -"@rollup/rollup-freebsd-arm64@4.60.1": - version "4.60.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.1.tgz#6377ff38c052c76fcaffb7b2728d3172fe676fe6" - integrity sha512-czw90wpQq3ZsAVBlinZjAYTKduOjTywlG7fEeWKUA7oCmpA8xdTkxZZlwNJKWqILlq0wehoZcJYfBvOyhPTQ6w== - -"@rollup/rollup-freebsd-x64@4.60.1": - version "4.60.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.1.tgz#ba3902309d088eaf7139b916f09b7140b28b406d" - integrity sha512-KVB2rqsxTHuBtfOeySEyzEOB7ltlB/ux38iu2rBQzkjbwRVlkhAGIEDiiYnO2kFOkJp+Z7pUXKyrRRFuFUKt+g== - -"@rollup/rollup-linux-arm-gnueabihf@4.60.1": - version "4.60.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.1.tgz#e011b9a14638267e53b446286e838dbdaf53f167" - integrity sha512-L+34Qqil+v5uC0zEubW7uByo78WOCIrBvci69E7sFASRl0X7b/MB6Cqd1lky/CtcSVTydWa2WZwFuWexjS5o6g== - -"@rollup/rollup-linux-arm-musleabihf@4.60.1": - version "4.60.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.1.tgz#0bce9ce9a009490abd28fd922dd97ed521311afe" - integrity sha512-n83O8rt4v34hgFzlkb1ycniJh7IR5RCIqt6mz1VRJD6pmhRi0CXdmfnLu9dIUS6buzh60IvACM842Ffb3xd6Gg== - -"@rollup/rollup-linux-arm64-gnu@4.60.1": - version "4.60.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.1.tgz#6f6cfbbf324fbb4ceff213abdf7f322fd45d25ff" - integrity sha512-Nql7sTeAzhTAja3QXeAI48+/+GjBJ+QmAH13snn0AJSNL50JsDqotyudHyMbO2RbJkskbMbFJfIJKWA6R1LCJQ== - -"@rollup/rollup-linux-arm64-musl@4.60.1": - version "4.60.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.1.tgz#f7cb3eecaea9c151ef77342af05f38ae924bf795" - integrity sha512-+pUymDhd0ys9GcKZPPWlFiZ67sTWV5UU6zOJat02M1+PiuSGDziyRuI/pPue3hoUwm2uGfxdL+trT6Z9rxnlMA== - -"@rollup/rollup-linux-loong64-gnu@4.60.1": - version "4.60.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.1.tgz#499bfac6bb669fd88bb664357bf6be996a28b92f" - integrity sha512-VSvgvQeIcsEvY4bKDHEDWcpW4Yw7BtlKG1GUT4FzBUlEKQK0rWHYBqQt6Fm2taXS+1bXvJT6kICu5ZwqKCnvlQ== - -"@rollup/rollup-linux-loong64-musl@4.60.1": - version "4.60.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.1.tgz#127dfac08764764396bbe04453c545d38a3ab518" - integrity sha512-4LqhUomJqwe641gsPp6xLfhqWMbQV04KtPp7/dIp0nzPxAkNY1AbwL5W0MQpcalLYk07vaW9Kp1PBhdpZYYcEw== - -"@rollup/rollup-linux-ppc64-gnu@4.60.1": - version "4.60.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.1.tgz#6a72f4d95852aac18326c5bf708393e8f3a41b70" - integrity sha512-tLQQ9aPvkBxOc/EUT6j3pyeMD6Hb8QF2BTBnCQWP/uu1lhc9AIrIjKnLYMEroIz/JvtGYgI9dF3AxHZNaEH0rw== - -"@rollup/rollup-linux-ppc64-musl@4.60.1": - version "4.60.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.1.tgz#ba8674666b00d6f9066cb9a5771a8430c34d2de6" - integrity sha512-RMxFhJwc9fSXP6PqmAz4cbv3kAyvD1etJFjTx4ONqFP9DkTkXsAMU4v3Vyc5BgzC+anz7nS/9tp4obsKfqkDHg== - -"@rollup/rollup-linux-riscv64-gnu@4.60.1": - version "4.60.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.1.tgz#17cc38b2a71e302547cad29bcf78d0db2618c922" - integrity sha512-QKgFl+Yc1eEk6MmOBfRHYF6lTxiiiV3/z/BRrbSiW2I7AFTXoBFvdMEyglohPj//2mZS4hDOqeB0H1ACh3sBbg== - -"@rollup/rollup-linux-riscv64-musl@4.60.1": - version "4.60.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.1.tgz#e36a41e2d8bd247331bd5cfc13b8c951d33454a2" - integrity sha512-RAjXjP/8c6ZtzatZcA1RaQr6O1TRhzC+adn8YZDnChliZHviqIjmvFwHcxi4JKPSDAt6Uhf/7vqcBzQJy0PDJg== - -"@rollup/rollup-linux-s390x-gnu@4.60.1": - version "4.60.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.1.tgz#1687265f1f4bdea0726c761a58c2db9933609d68" - integrity sha512-wcuocpaOlaL1COBYiA89O6yfjlp3RwKDeTIA0hM7OpmhR1Bjo9j31G1uQVpDlTvwxGn2nQs65fBFL5UFd76FcQ== - -"@rollup/rollup-linux-x64-gnu@4.60.1": - version "4.60.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.1.tgz#56a6a0d9076f2a05a976031493b24a20ddcc0e77" - integrity sha512-77PpsFQUCOiZR9+LQEFg9GClyfkNXj1MP6wRnzYs0EeWbPcHs02AXu4xuUbM1zhwn3wqaizle3AEYg5aeoohhg== - -"@rollup/rollup-linux-x64-musl@4.60.1": - version "4.60.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.1.tgz#bc240ebb5b9fd8d41ca8a80cb458452e8c187e0f" - integrity sha512-5cIATbk5vynAjqqmyBjlciMJl1+R/CwX9oLk/EyiFXDWd95KpHdrOJT//rnUl4cUcskrd0jCCw3wpZnhIHdD9w== - -"@rollup/rollup-openbsd-x64@4.60.1": - version "4.60.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.1.tgz#6f80d48a006c4b2ffa7724e95a3e33f6975872af" - integrity sha512-cl0w09WsCi17mcmWqqglez9Gk8isgeWvoUZ3WiJFYSR3zjBQc2J5/ihSjpl+VLjPqjQ/1hJRcqBfLjssREQILw== - -"@rollup/rollup-openharmony-arm64@4.60.1": - version "4.60.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.1.tgz#8f6db6f70d0a48abd833b263cd6dd3e7199c4c0e" - integrity sha512-4Cv23ZrONRbNtbZa37mLSueXUCtN7MXccChtKpUnQNgF010rjrjfHx3QxkS2PI7LqGT5xXyYs1a7LbzAwT0iCA== - -"@rollup/rollup-win32-arm64-msvc@4.60.1": - version "4.60.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.1.tgz#b68989bfa815d0b3d4e302ecd90bda744438b177" - integrity sha512-i1okWYkA4FJICtr7KpYzFpRTHgy5jdDbZiWfvny21iIKky5YExiDXP+zbXzm3dUcFpkEeYNHgQ5fuG236JPq0g== - -"@rollup/rollup-win32-ia32-msvc@4.60.1": - version "4.60.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.1.tgz#c098e45338c50f22f1b288476354f025b746285b" - integrity sha512-u09m3CuwLzShA0EYKMNiFgcjjzwqtUMLmuCJLeZWjjOYA3IT2Di09KaxGBTP9xVztWyIWjVdsB2E9goMjZvTQg== - -"@rollup/rollup-win32-x64-gnu@4.60.1": - version "4.60.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.1.tgz#2c9e15be155b79d05999953b1737b2903842e903" - integrity sha512-k+600V9Zl1CM7eZxJgMyTUzmrmhB/0XZnF4pRypKAlAgxmedUA+1v9R+XOFv56W4SlHEzfeMtzujLJD22Uz5zg== - -"@rollup/rollup-win32-x64-msvc@4.60.1": - version "4.60.1" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.1.tgz#23b860113e9f87eea015d1fa3a4240a52b42fcd4" - integrity sha512-lWMnixq/QzxyhTV6NjQJ4SFo1J6PvOX8vUx5Wb4bBPsEb+8xZ89Bz6kOXpfXj9ak9AHTQVQzlgzBEc1SyM27xQ== - -"@swc/helpers@^0.5.0": - version "0.5.20" - resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.20.tgz#d1d0f1e18ff6592c96a4931b4031298619129585" - integrity sha512-2egEBHUMasdypIzrprsu8g+OEVd7Vp2MM3a2eVlM/cyFYto0nGz5BX5BTgh/ShZZI9ed+ozEq+Ngt+rgmUs8tw== +"@radix-ui/react-id@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-1.1.1.tgz#1404002e79a03fe062b7e3864aa01e24bd1471f7" + integrity sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg== dependencies: - tslib "^2.8.0" + "@radix-ui/react-use-layout-effect" "1.1.1" + +"@radix-ui/react-popover@^1.1.6": + version "1.1.15" + resolved "https://registry.yarnpkg.com/@radix-ui/react-popover/-/react-popover-1.1.15.tgz#9c852f93990a687ebdc949b2c3de1f37cdc4c5d5" + integrity sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA== + dependencies: + "@radix-ui/primitive" "1.1.3" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-dismissable-layer" "1.1.11" + "@radix-ui/react-focus-guards" "1.1.3" + "@radix-ui/react-focus-scope" "1.1.7" + "@radix-ui/react-id" "1.1.1" + "@radix-ui/react-popper" "1.2.8" + "@radix-ui/react-portal" "1.1.9" + "@radix-ui/react-presence" "1.1.5" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-slot" "1.2.3" + "@radix-ui/react-use-controllable-state" "1.2.2" + aria-hidden "^1.2.4" + react-remove-scroll "^2.6.3" + +"@radix-ui/react-popper@1.2.8": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@radix-ui/react-popper/-/react-popper-1.2.8.tgz#a79f39cdd2b09ab9fb50bf95250918422c4d9602" + integrity sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw== + dependencies: + "@floating-ui/react-dom" "^2.0.0" + "@radix-ui/react-arrow" "1.1.7" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-use-callback-ref" "1.1.1" + "@radix-ui/react-use-layout-effect" "1.1.1" + "@radix-ui/react-use-rect" "1.1.1" + "@radix-ui/react-use-size" "1.1.1" + "@radix-ui/rect" "1.1.1" + +"@radix-ui/react-portal@1.1.9": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.1.9.tgz#14c3649fe48ec474ac51ed9f2b9f5da4d91c4472" + integrity sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ== + dependencies: + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-use-layout-effect" "1.1.1" + +"@radix-ui/react-presence@1.1.5": + version "1.1.5" + resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.1.5.tgz#5d8f28ac316c32f078afce2996839250c10693db" + integrity sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ== + dependencies: + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-use-layout-effect" "1.1.1" + +"@radix-ui/react-primitive@2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz#db9b8bcff49e01be510ad79893fb0e4cda50f1bc" + integrity sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ== + dependencies: + "@radix-ui/react-slot" "1.2.3" + +"@radix-ui/react-slider@^1.2.4": + version "1.3.6" + resolved "https://registry.yarnpkg.com/@radix-ui/react-slider/-/react-slider-1.3.6.tgz#409453110b8f34ca00972750b80cd792f0b23a8c" + integrity sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw== + dependencies: + "@radix-ui/number" "1.1.1" + "@radix-ui/primitive" "1.1.3" + "@radix-ui/react-collection" "1.1.7" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-direction" "1.1.1" + "@radix-ui/react-primitive" "2.1.3" + "@radix-ui/react-use-controllable-state" "1.2.2" + "@radix-ui/react-use-layout-effect" "1.1.1" + "@radix-ui/react-use-previous" "1.1.1" + "@radix-ui/react-use-size" "1.1.1" + +"@radix-ui/react-slot@1.2.3": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-1.2.3.tgz#502d6e354fc847d4169c3bc5f189de777f68cfe1" + integrity sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A== + dependencies: + "@radix-ui/react-compose-refs" "1.1.2" + +"@radix-ui/react-use-callback-ref@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz#62a4dba8b3255fdc5cc7787faeac1c6e4cc58d40" + integrity sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg== + +"@radix-ui/react-use-controllable-state@1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz#905793405de57d61a439f4afebbb17d0645f3190" + integrity sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg== + dependencies: + "@radix-ui/react-use-effect-event" "0.0.2" + "@radix-ui/react-use-layout-effect" "1.1.1" + +"@radix-ui/react-use-effect-event@0.0.2": + version "0.0.2" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz#090cf30d00a4c7632a15548512e9152217593907" + integrity sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA== + dependencies: + "@radix-ui/react-use-layout-effect" "1.1.1" + +"@radix-ui/react-use-escape-keydown@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz#b3fed9bbea366a118f40427ac40500aa1423cc29" + integrity sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g== + dependencies: + "@radix-ui/react-use-callback-ref" "1.1.1" + +"@radix-ui/react-use-layout-effect@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz#0c4230a9eed49d4589c967e2d9c0d9d60a23971e" + integrity sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ== + +"@radix-ui/react-use-previous@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz#1a1ad5568973d24051ed0af687766f6c7cb9b5b5" + integrity sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ== + +"@radix-ui/react-use-rect@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz#01443ca8ed071d33023c1113e5173b5ed8769152" + integrity sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w== + dependencies: + "@radix-ui/rect" "1.1.1" + +"@radix-ui/react-use-size@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz#6de276ffbc389a537ffe4316f5b0f24129405b37" + integrity sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ== + dependencies: + "@radix-ui/react-use-layout-effect" "1.1.1" + +"@radix-ui/rect@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@radix-ui/rect/-/rect-1.1.1.tgz#78244efe12930c56fd255d7923865857c41ac8cb" + integrity sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw== + +"@rolldown/binding-android-arm64@1.0.0-rc.17": + version "1.0.0-rc.17" + resolved "https://registry.yarnpkg.com/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.17.tgz#0a502a88c39d0ffa81aa30b561dade6f6217dcc5" + integrity sha512-s70pVGhw4zqGeFnXWvAzJDlvxhlRollagdCCKRgOsgUOH3N1l0LIxf83AtGzmb5SiVM4Hjl5HyarMRfdfj3DaQ== + +"@rolldown/binding-darwin-arm64@1.0.0-rc.17": + version "1.0.0-rc.17" + resolved "https://registry.yarnpkg.com/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.17.tgz#8b7f05ac9000ab19161a79a0346b1b64a1bc7ba3" + integrity sha512-4ksWc9n0mhlZpZ9PMZgTGjeOPRu8MB1Z3Tz0Mo02eWfWCHMW1zN82Qz/pL/rC+yQa+8ZnutMF0JjJe7PjwasYw== + +"@rolldown/binding-darwin-x64@1.0.0-rc.17": + version "1.0.0-rc.17" + resolved "https://registry.yarnpkg.com/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.17.tgz#f8b465b3a4e992053890b162f1ae19e4f1719a6a" + integrity sha512-SUSDOI6WwUVNcWxd02QEBjLdY1VPHvlEkw6T/8nYG322iYWCTxRb1vzk4E+mWWYehTp7ERibq54LSJGjmouOsw== + +"@rolldown/binding-freebsd-x64@1.0.0-rc.17": + version "1.0.0-rc.17" + resolved "https://registry.yarnpkg.com/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.17.tgz#a8281e14fa9c243fe22dc2d0e54900e66b31935e" + integrity sha512-hwnz3nw9dbJ05EDO/PvcjaaewqqDy7Y1rn1UO81l8iIK1GjenME75dl16ajbvSSMfv66WXSRCYKIqfgq2KCfxw== + +"@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.17": + version "1.0.0-rc.17" + resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.17.tgz#cd29cf869ddd4fac8d6929abf94b91ddb0494650" + integrity sha512-IS+W7epTcwANmFSQFrS1SivEXHtl1JtuQA9wlxrZTcNi6mx+FDOYrakGevvvTwgj2JvWiK8B29/qD9BELZPyXQ== + +"@rolldown/binding-linux-arm64-gnu@1.0.0-rc.17": + version "1.0.0-rc.17" + resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.17.tgz#91c331236ec3728366218d61a62f0bd226546c6c" + integrity sha512-e6usGaHKW5BMNZOymS1UcEYGowQMWcgZ71Z17Sl/h2+ZziNJ1a9n3Zvcz6LdRyIW5572wBCTH/Z+bKuZouGk9Q== + +"@rolldown/binding-linux-arm64-musl@1.0.0-rc.17": + version "1.0.0-rc.17" + resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.17.tgz#80108957db752e7826836e22240e56b8140e9684" + integrity sha512-b/CgbwAJpmrRLp02RPfhbudf5tZnN9nsPWK82znefso832etkem8H7FSZwxrOI9djcdTP7U6YfNhbRnh7djErg== + +"@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.17": + version "1.0.0-rc.17" + resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.17.tgz#1dce51148cbc6bab3c3f9157b5323d2a31aac924" + integrity sha512-4EII1iNGRUN5WwGbF/kOh/EIkoDN9HsupgLQoXfY+D1oyJm7/F4t5PYU5n8SWZgG0FEwakyM8pGgwcBYruGTlA== + +"@rolldown/binding-linux-s390x-gnu@1.0.0-rc.17": + version "1.0.0-rc.17" + resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.17.tgz#d4a0d2e01d8d441e4ac3af3fa68eec17a7d0e9cd" + integrity sha512-AH8oq3XqQo4IibpVXvPeLDI5pzkpYn0WiZAfT05kFzoJ6tQNzwRdDYQ45M8I/gslbodRZwW8uxLhbSBbkv96rA== + +"@rolldown/binding-linux-x64-gnu@1.0.0-rc.17": + version "1.0.0-rc.17" + resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.17.tgz#0ac8b3139cefeea798ad147f30ea70572b133af1" + integrity sha512-cLnjV3xfo7KslbU41Z7z8BH/E1y5mzUYzAqih1d1MDaIGZRCMqTijqLv76/P7fyHuvUcfGsIpqCdddbxLLK9rA== + +"@rolldown/binding-linux-x64-musl@1.0.0-rc.17": + version "1.0.0-rc.17" + resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.17.tgz#2af61bee087571728f58f1c47734bbbd41dd7050" + integrity sha512-0phclDw1spsL7dUB37sIARuis2tAgomCJXAHZlpt8PXZ4Ba0dRP1e+66lsRqrfhISeN9bEGNjQs+T/Fbd7oYGw== + +"@rolldown/binding-openharmony-arm64@1.0.0-rc.17": + version "1.0.0-rc.17" + resolved "https://registry.yarnpkg.com/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.17.tgz#56c1afbf6c592819abf47b4a983987dc288b30c1" + integrity sha512-0ag/hEgXOwgw4t8QyQvUCxvEg+V0KBcA6YuOx9g0r02MprutRF5dyljgm3EmR02O292UX7UeS6HzWHAl6KgyhA== + +"@rolldown/binding-wasm32-wasi@1.0.0-rc.17": + version "1.0.0-rc.17" + resolved "https://registry.yarnpkg.com/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.17.tgz#5d112ff4dd0d268a60fb4e0eb3077e3ea2531f0d" + integrity sha512-LEXei6vo0E5wTGwpkJ4KoT3OZJRnglwldt5ziLzOlc6qqb55z4tWNq2A+PFqCJuvWWdP53CVhG1Z9NtToDPJrA== + dependencies: + "@emnapi/core" "1.10.0" + "@emnapi/runtime" "1.10.0" + "@napi-rs/wasm-runtime" "^1.1.4" + +"@rolldown/binding-win32-arm64-msvc@1.0.0-rc.17": + version "1.0.0-rc.17" + resolved "https://registry.yarnpkg.com/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.17.tgz#5125a85222d64a543201d28e16a395cc45bf4d17" + integrity sha512-gUmyzBl3SPMa6hrqFUth9sVfcLBlYsbMzBx5PlexMroZStgzGqlZ26pYG89rBb45Mnia+oil6YAIFeEWGWhoZA== + +"@rolldown/binding-win32-x64-msvc@1.0.0-rc.17": + version "1.0.0-rc.17" + resolved "https://registry.yarnpkg.com/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.17.tgz#fc6b78e759a0bb2054b5c0a3489da12b2cae54b4" + integrity sha512-3hkiolcUAvPB9FLb3UZdfjVVNWherN1f/skkGWJP/fgSQhYUZpSIRr0/I8ZK9TkF3F7kxvJAk0+IcKvPHk9qQg== + +"@rolldown/pluginutils@1.0.0-rc.17": + version "1.0.0-rc.17" + resolved "https://registry.yarnpkg.com/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.17.tgz#a89b30833fb628bc834fe2e89fea93a2da9fa69a" + integrity sha512-n8iosDOt6Ig1UhJ2AYqoIhHWh/isz0xpicHTzpKBeotdVsTEcxsSA/i3EVM7gQAj0rU27OLAxCjzlj15IWY7bg== + +"@rolldown/pluginutils@1.0.0-rc.7": + version "1.0.0-rc.7" + resolved "https://registry.yarnpkg.com/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.7.tgz#0414869467f0e471a6515d4f506c85fde867e022" + integrity sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA== "@tailwindcss/forms@^0.5.11": version "0.5.11" @@ -718,10 +734,10 @@ dependencies: mini-svg-data-uri "^1.2.3" -"@tailwindcss/node@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@tailwindcss/node/-/node-4.2.2.tgz#840e904226dc1b379609de8a72323fc211568993" - integrity sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA== +"@tailwindcss/node@4.2.4": + version "4.2.4" + resolved "https://registry.yarnpkg.com/@tailwindcss/node/-/node-4.2.4.tgz#1f7fc0c1741037ded1fa92fbe62a786a197771ce" + integrity sha512-Ai7+yQPxz3ddrDQzFfBKdHEVBg0w3Zl83jnjuwxnZOsnH9pGn93QHQtpU0p/8rYWxvbFZHneni6p1BSLK4DkGA== dependencies: "@jridgewell/remapping" "^2.3.5" enhanced-resolve "^5.19.0" @@ -729,57 +745,57 @@ lightningcss "1.32.0" magic-string "^0.30.21" source-map-js "^1.2.1" - tailwindcss "4.2.2" + tailwindcss "4.2.4" -"@tailwindcss/oxide-android-arm64@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.2.tgz#61d9ec5c18394fe7a972e99e19e6065e833da77c" - integrity sha512-dXGR1n+P3B6748jZO/SvHZq7qBOqqzQ+yFrXpoOWWALWndF9MoSKAT3Q0fYgAzYzGhxNYOoysRvYlpixRBBoDg== +"@tailwindcss/oxide-android-arm64@4.2.4": + version "4.2.4" + resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.4.tgz#d533e52ee98d58f55d1d4753774251513ba8a911" + integrity sha512-e7MOr1SAn9U8KlZzPi1ZXGZHeC5anY36qjNwmZv9pOJ8E4Q6jmD1vyEHkQFmNOIN7twGPEMXRHmitN4zCMN03g== -"@tailwindcss/oxide-darwin-arm64@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.2.tgz#9ad7b141789dae235c85d2f7874592bf869f636e" - integrity sha512-iq9Qjr6knfMpZHj55/37ouZeykwbDqF21gPFtfnhCCKGDcPI/21FKC9XdMO/XyBM7qKORx6UIhGgg6jLl7BZlg== +"@tailwindcss/oxide-darwin-arm64@4.2.4": + version "4.2.4" + resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.4.tgz#2a6250aa7d8791fc1b5797e64e09e51da57514a6" + integrity sha512-tSC/Kbqpz/5/o/C2sG7QvOxAKqyd10bq+ypZNf+9Fi2TvbVbv1zNpcEptcsU7DPROaSbVgUXmrzKhurFvo5eDg== -"@tailwindcss/oxide-darwin-x64@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.2.tgz#a5899f1fbe55c4eddcbc871b835d5183ba34658c" - integrity sha512-BlR+2c3nzc8f2G639LpL89YY4bdcIdUmiOOkv2GQv4/4M0vJlpXEa0JXNHhCHU7VWOKWT/CjqHdTP8aUuDJkuw== +"@tailwindcss/oxide-darwin-x64@4.2.4": + version "4.2.4" + resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.4.tgz#d647299812946b6ab5140c61a334c8ebc8d877de" + integrity sha512-yPyUXn3yO/ufR6+Kzv0t4fCg2qNr90jxXc5QqBpjlPNd0NqyDXcmQb/6weunH/MEDXW5dhyEi+agTDiqa3WsGg== -"@tailwindcss/oxide-freebsd-x64@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.2.tgz#76185bb1bea9af915a5b9f465323861646587e21" - integrity sha512-YUqUgrGMSu2CDO82hzlQ5qSb5xmx3RUrke/QgnoEx7KvmRJHQuZHZmZTLSuuHwFf0DJPybFMXMYf+WJdxHy/nQ== +"@tailwindcss/oxide-freebsd-x64@4.2.4": + version "4.2.4" + resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.4.tgz#019b7fce37aaf5ddfed0f231c536108292e87ffb" + integrity sha512-BoMIB4vMQtZsXdGLVc2z+P9DbETkiopogfWZKbWwM8b/1Vinbs4YcUwo+kM/KeLkX3Ygrf4/PsRndKaYhS8Eiw== -"@tailwindcss/oxide-linux-arm-gnueabihf@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.2.tgz#74c17c69b2015f7600d566ab0990aaac8701128e" - integrity sha512-FPdhvsW6g06T9BWT0qTwiVZYE2WIFo2dY5aCSpjG/S/u1tby+wXoslXS0kl3/KXnULlLr1E3NPRRw0g7t2kgaQ== +"@tailwindcss/oxide-linux-arm-gnueabihf@4.2.4": + version "4.2.4" + resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.4.tgz#c88a95d69095e84f811b302daa66f5287ad8ce0f" + integrity sha512-7pIHBLTHYRAlS7V22JNuTh33yLH4VElwKtB3bwchK/UaKUPpQ0lPQiOWcbm4V3WP2I6fNIJ23vABIvoy2izdwA== -"@tailwindcss/oxide-linux-arm64-gnu@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.2.tgz#38a846d9d5795bc3b57951172044d8dbb3c79aa6" - integrity sha512-4og1V+ftEPXGttOO7eCmW7VICmzzJWgMx+QXAJRAhjrSjumCwWqMfkDrNu1LXEQzNAwz28NCUpucgQPrR4S2yw== +"@tailwindcss/oxide-linux-arm64-gnu@4.2.4": + version "4.2.4" + resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.4.tgz#1292f1c222994bfe4a5e990ac0a701de6487dd02" + integrity sha512-+E4wxJ0ZGOzSH325reXTWB48l42i93kQqMvDyz5gqfRzRZ7faNhnmvlV4EPGJU3QJM/3Ab5jhJ5pCRUsKn6OQw== -"@tailwindcss/oxide-linux-arm64-musl@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.2.tgz#f4cc4129c17d3f2bcb01efef4d7a2f381e5e3f53" - integrity sha512-oCfG/mS+/+XRlwNjnsNLVwnMWYH7tn/kYPsNPh+JSOMlnt93mYNCKHYzylRhI51X+TbR+ufNhhKKzm6QkqX8ag== +"@tailwindcss/oxide-linux-arm64-musl@4.2.4": + version "4.2.4" + resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.4.tgz#afb6492b22616f0d9d3346d39c1a6e285f994a08" + integrity sha512-bBADEGAbo4ASnppIziaQJelekCxdMaxisrk+fB7Thit72IBnALp9K6ffA2G4ruj90G9XRS2VQ6q2bCKbfFV82g== -"@tailwindcss/oxide-linux-x64-gnu@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.2.tgz#7c4a00b0829e12736bd72ec74e1c08205448cc2e" - integrity sha512-rTAGAkDgqbXHNp/xW0iugLVmX62wOp2PoE39BTCGKjv3Iocf6AFbRP/wZT/kuCxC9QBh9Pu8XPkv/zCZB2mcMg== +"@tailwindcss/oxide-linux-x64-gnu@4.2.4": + version "4.2.4" + resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.4.tgz#400b0ccfc53937c7804ed8e0e9652b42bd86f2eb" + integrity sha512-7Mx25E4WTfnht0TVRTyC00j3i0M+EeFe7wguMDTlX4mRxafznw0CA8WJkFjWYH5BlgELd1kSjuU2JiPnNZbJDA== -"@tailwindcss/oxide-linux-x64-musl@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.2.tgz#711756d7bbe97e221fc041b63a4f385b85ba4321" - integrity sha512-XW3t3qwbIwiSyRCggeO2zxe3KWaEbM0/kW9e8+0XpBgyKU4ATYzcVSMKteZJ1iukJ3HgHBjbg9P5YPRCVUxlnQ== +"@tailwindcss/oxide-linux-x64-musl@4.2.4": + version "4.2.4" + resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.4.tgz#5c23c476e5de4ed9cd6ab39c2718b9a4be2bbb2b" + integrity sha512-2wwJRF7nyhOR0hhHoChc04xngV3iS+akccHTGtz965FwF0up4b2lOdo6kI1EbDaEXKgvcrFBYcYQQ/rrnWFVfA== -"@tailwindcss/oxide-wasm32-wasi@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.2.tgz#ed6d28567b7abb8505f824457c236d2cd07ee18e" - integrity sha512-eKSztKsmEsn1O5lJ4ZAfyn41NfG7vzCg496YiGtMDV86jz1q/irhms5O0VrY6ZwTUkFy/EKG3RfWgxSI3VbZ8Q== +"@tailwindcss/oxide-wasm32-wasi@4.2.4": + version "4.2.4" + resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.4.tgz#21b7f53ba7c6c03f26ccb8cef5d09f5c2973ae5e" + integrity sha512-FQsqApeor8Fo6gUEklzmaa9994orJZZDBAlQpK2Mq+DslRKFJeD6AjHpBQ0kZFQohVr8o85PPh8eOy86VlSCmw== dependencies: "@emnapi/core" "^1.8.1" "@emnapi/runtime" "^1.8.1" @@ -788,56 +804,56 @@ "@tybys/wasm-util" "^0.10.1" tslib "^2.8.1" -"@tailwindcss/oxide-win32-arm64-msvc@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.2.tgz#f2d0360e5bc06fe201537fb08193d3780e7dd24f" - integrity sha512-qPmaQM4iKu5mxpsrWZMOZRgZv1tOZpUm+zdhhQP0VhJfyGGO3aUKdbh3gDZc/dPLQwW4eSqWGrrcWNBZWUWaXQ== +"@tailwindcss/oxide-win32-arm64-msvc@4.2.4": + version "4.2.4" + resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.4.tgz#13bc1cf3818e3345a965d36b40c237817124d070" + integrity sha512-L9BXqxC4ToVgwMFqj3pmZRqyHEztulpUJzCxUtLjobMCzTPsGt1Fa9enKbOpY2iIyVtaHNeNvAK8ERP/64sqGQ== -"@tailwindcss/oxide-win32-x64-msvc@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.2.tgz#10fc71b73883f9c3999b5b8c338fd96a45240dcb" - integrity sha512-1T/37VvI7WyH66b+vqHj/cLwnCxt7Qt3WFu5Q8hk65aOvlwAhs7rAp1VkulBJw/N4tMirXjVnylTR72uI0HGcA== +"@tailwindcss/oxide-win32-x64-msvc@4.2.4": + version "4.2.4" + resolved "https://registry.yarnpkg.com/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.4.tgz#5476dbbbf6b8934d58452340cec737fdaa5ec8c6" + integrity sha512-ESlKG0EpVJQwRjXDDa9rLvhEAh0mhP1sF7sap9dNZT0yyl9SAG6T7gdP09EH0vIv0UNTlo6jPWyujD6559fZvw== -"@tailwindcss/oxide@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@tailwindcss/oxide/-/oxide-4.2.2.tgz#c6534cb4b22650df605a58258235523a6abd7de8" - integrity sha512-qEUA07+E5kehxYp9BVMpq9E8vnJuBHfJEC0vPC5e7iL/hw7HR61aDKoVoKzrG+QKp56vhNZe4qwkRmMC0zDLvg== +"@tailwindcss/oxide@4.2.4": + version "4.2.4" + resolved "https://registry.yarnpkg.com/@tailwindcss/oxide/-/oxide-4.2.4.tgz#e2ca51d04e8ad94d569222fa727de479b097db39" + integrity sha512-9El/iI069DKDSXwTvB9J4BwdO5JhRrOweGaK25taBAvBXyXqJAX+Jqdvs8r8gKpsI/1m0LeJLyQYTf/WLrBT1Q== optionalDependencies: - "@tailwindcss/oxide-android-arm64" "4.2.2" - "@tailwindcss/oxide-darwin-arm64" "4.2.2" - "@tailwindcss/oxide-darwin-x64" "4.2.2" - "@tailwindcss/oxide-freebsd-x64" "4.2.2" - "@tailwindcss/oxide-linux-arm-gnueabihf" "4.2.2" - "@tailwindcss/oxide-linux-arm64-gnu" "4.2.2" - "@tailwindcss/oxide-linux-arm64-musl" "4.2.2" - "@tailwindcss/oxide-linux-x64-gnu" "4.2.2" - "@tailwindcss/oxide-linux-x64-musl" "4.2.2" - "@tailwindcss/oxide-wasm32-wasi" "4.2.2" - "@tailwindcss/oxide-win32-arm64-msvc" "4.2.2" - "@tailwindcss/oxide-win32-x64-msvc" "4.2.2" + "@tailwindcss/oxide-android-arm64" "4.2.4" + "@tailwindcss/oxide-darwin-arm64" "4.2.4" + "@tailwindcss/oxide-darwin-x64" "4.2.4" + "@tailwindcss/oxide-freebsd-x64" "4.2.4" + "@tailwindcss/oxide-linux-arm-gnueabihf" "4.2.4" + "@tailwindcss/oxide-linux-arm64-gnu" "4.2.4" + "@tailwindcss/oxide-linux-arm64-musl" "4.2.4" + "@tailwindcss/oxide-linux-x64-gnu" "4.2.4" + "@tailwindcss/oxide-linux-x64-musl" "4.2.4" + "@tailwindcss/oxide-wasm32-wasi" "4.2.4" + "@tailwindcss/oxide-win32-arm64-msvc" "4.2.4" + "@tailwindcss/oxide-win32-x64-msvc" "4.2.4" -"@tailwindcss/postcss@^4.2.0": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@tailwindcss/postcss/-/postcss-4.2.2.tgz#56570116b136f32c135357544fec6776a6a49dfd" - integrity sha512-n4goKQbW8RVXIbNKRB/45LzyUqN451deQK0nzIeauVEqjlI49slUlgKYJM2QyUzap/PcpnS7kzSUmPb1sCRvYQ== +"@tailwindcss/postcss@^4.2.4": + version "4.2.4" + resolved "https://registry.yarnpkg.com/@tailwindcss/postcss/-/postcss-4.2.4.tgz#548ed07584a41411574e8b1ec5f1543d09c439a4" + integrity sha512-wgAVj6nUWAolAu8YFvzT2cTBIElWHkjZwFYovF+xsqKsW2ADxM/X2opxj5NsF/qVccAOjRNe8X2IdPzMsWyHTg== dependencies: "@alloc/quick-lru" "^5.2.0" - "@tailwindcss/node" "4.2.2" - "@tailwindcss/oxide" "4.2.2" + "@tailwindcss/node" "4.2.4" + "@tailwindcss/oxide" "4.2.4" postcss "^8.5.6" - tailwindcss "4.2.2" + tailwindcss "4.2.4" -"@tanstack/react-virtual@3.2.0": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@tanstack/react-virtual/-/react-virtual-3.2.0.tgz#fb70f9c6baee753a5a0f7618ac886205d5a02af9" - integrity sha512-OEdMByf2hEfDa6XDbGlZN8qO6bTjlNKqjM3im9JG+u3mCL8jALy0T/67oDI001raUUPh1Bdmfn4ZvPOV5knpcg== +"@tanstack/react-virtual@3.13.24": + version "3.13.24" + resolved "https://registry.yarnpkg.com/@tanstack/react-virtual/-/react-virtual-3.13.24.tgz#77af3d5dcf77358d805b7b3b06d3221af7bd3f6f" + integrity sha512-aIJvz5OSkhNIhZIpYivrxrPTKYsjW9Uzy+sP/mx0S3sev2HyvPb7xmjbYvokzEpfgYHy/HjzJ2zFAETuUfgCpg== dependencies: - "@tanstack/virtual-core" "3.2.0" + "@tanstack/virtual-core" "3.14.0" -"@tanstack/virtual-core@3.2.0": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@tanstack/virtual-core/-/virtual-core-3.2.0.tgz#874d36135e4badce2719e7bdc556ce240cbaff14" - integrity sha512-P5XgYoAw/vfW65byBbJQCw+cagdXDT/qH6wmABiLt4v4YBT2q2vqCOhihe+D1Nt325F/S/0Tkv6C5z0Lv+VBQQ== +"@tanstack/virtual-core@3.14.0": + version "3.14.0" + resolved "https://registry.yarnpkg.com/@tanstack/virtual-core/-/virtual-core-3.14.0.tgz#c8839d0d702b8af47c0e57d4ab72fc3ba8bbf3da" + integrity sha512-JLANqGy/D6k4Ujmh8Tr25lGimuOXNiaVyXaCAZS0W+1390sADdGnyUdSWNIfd49gebtIxGMij4IktRVzrdr12Q== "@tybys/wasm-util@^0.10.1": version "0.10.1" @@ -846,45 +862,12 @@ dependencies: tslib "^2.4.0" -"@types/babel__core@^7.20.5": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" - integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== - dependencies: - "@babel/parser" "^7.20.7" - "@babel/types" "^7.20.7" - "@types/babel__generator" "*" - "@types/babel__template" "*" - "@types/babel__traverse" "*" - -"@types/babel__generator@*": - version "7.27.0" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.27.0.tgz#b5819294c51179957afaec341442f9341e4108a9" - integrity sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg== - dependencies: - "@babel/types" "^7.0.0" - -"@types/babel__template@*": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f" - integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== - dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" - -"@types/babel__traverse@*": - version "7.28.0" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.28.0.tgz#07d713d6cce0d265c9849db0cbe62d3f61f36f74" - integrity sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q== - dependencies: - "@babel/types" "^7.28.2" - "@types/esrecurse@^4.3.1": version "4.3.1" resolved "https://registry.yarnpkg.com/@types/esrecurse/-/esrecurse-4.3.1.tgz#6f636af962fbe6191b830bd676ba5986926bccec" integrity sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw== -"@types/estree@1.0.8", "@types/estree@^1.0.6", "@types/estree@^1.0.8": +"@types/estree@^1.0.6", "@types/estree@^1.0.8": version "1.0.8" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e" integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== @@ -894,36 +877,19 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== -"@types/node@^25.3.0": - version "25.5.0" - resolved "https://registry.yarnpkg.com/@types/node/-/node-25.5.0.tgz#5c99f37c443d9ccc4985866913f1ed364217da31" - integrity sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw== +"@types/node@^25.6.0": + version "25.6.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-25.6.0.tgz#4e09bad9b469871f2d0f68140198cbd714f4edca" + integrity sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ== dependencies: - undici-types "~7.18.0" - -"@types/prop-types@^15.7.12": - version "15.7.15" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.15.tgz#e6e5a86d602beaca71ce5163fadf5f95d70931c7" - integrity sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw== + undici-types "~7.19.0" "@types/react-dom@^19.2.3": version "19.2.3" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-19.2.3.tgz#c1e305d15a52a3e508d54dca770d202cb63abf2c" integrity sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ== -"@types/react-slider@^1.3.6": - version "1.3.6" - resolved "https://registry.yarnpkg.com/@types/react-slider/-/react-slider-1.3.6.tgz#6f5602be93ab1cb3d273428c87aa227ad2ff68ff" - integrity sha512-RS8XN5O159YQ6tu3tGZIQz1/9StMLTg/FCIPxwqh2gwVixJnlfIodtVx+fpXVMZHe7A58lAX1Q4XTgAGOQaCQg== - dependencies: - "@types/react" "*" - -"@types/react-transition-group@^4.4.10", "@types/react-transition-group@^4.4.6": - version "4.4.12" - resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.12.tgz#b5d76568485b02a307238270bfe96cb51ee2a044" - integrity sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w== - -"@types/react@*", "@types/react@>=16.9.11", "@types/react@^19.2.14": +"@types/react@^19.2.14": version "19.2.14" resolved "https://registry.yarnpkg.com/@types/react/-/react-19.2.14.tgz#39604929b5e3957e3a6fa0001dafb17c7af70bad" integrity sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w== @@ -935,118 +901,108 @@ resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.7.tgz#baccb07a970b91707df3a3e8ba6896c57ead2d11" integrity sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw== -"@types/warning@^3.0.3": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/warning/-/warning-3.0.4.tgz#ebc0c83180dc83994d902bbd51ab0af8a445b1f9" - integrity sha512-CqN8MnISMwQbLJXO3doBAV4Yw9hx9/Pyr2rZ78+NfaCnhyRA/nKrpyk6E7mKw17ZOaQdLpK9GiUjrqLzBlN3sg== - -"@typescript-eslint/eslint-plugin@8.58.0", "@typescript-eslint/eslint-plugin@^8.56.0": - version "8.58.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.58.0.tgz#ad40e492f1931f46da1bd888e52b9e56df9063aa" - integrity sha512-RLkVSiNuUP1C2ROIWfqX+YcUfLaSnxGE/8M+Y57lopVwg9VTYYfhuz15Yf1IzCKgZj6/rIbYTmJCUSqr76r0Wg== +"@typescript-eslint/eslint-plugin@8.59.1", "@typescript-eslint/eslint-plugin@^8.59.1": + version "8.59.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.59.1.tgz#781bc6f9002982cfaf75a185240e24ad7276628a" + integrity sha512-BOziFIfE+6osHO9FoJG4zjoHUcvI7fTNBSpdAwrNH0/TLvzjsk2oo8XSSOT2HhqUyhZPfHv4UOffoJ9oEEQ7Ag== dependencies: "@eslint-community/regexpp" "^4.12.2" - "@typescript-eslint/scope-manager" "8.58.0" - "@typescript-eslint/type-utils" "8.58.0" - "@typescript-eslint/utils" "8.58.0" - "@typescript-eslint/visitor-keys" "8.58.0" + "@typescript-eslint/scope-manager" "8.59.1" + "@typescript-eslint/type-utils" "8.59.1" + "@typescript-eslint/utils" "8.59.1" + "@typescript-eslint/visitor-keys" "8.59.1" ignore "^7.0.5" natural-compare "^1.4.0" ts-api-utils "^2.5.0" -"@typescript-eslint/parser@8.58.0", "@typescript-eslint/parser@^8.56.0": - version "8.58.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.58.0.tgz#da04ece1967b6c2fe8f10c3473dabf3825795ef7" - integrity sha512-rLoGZIf9afaRBYsPUMtvkDWykwXwUPL60HebR4JgTI8mxfFe2cQTu3AGitANp4b9B2QlVru6WzjgB2IzJKiCSA== +"@typescript-eslint/parser@8.59.1", "@typescript-eslint/parser@^8.59.1": + version "8.59.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.59.1.tgz#835d20a62350659a082a1ae2a60b822c40488905" + integrity sha512-HDQH9O/47Dxi1ceDhBXdaldtf/WV9yRYMjbjCuNk3qnaTD564qwv61Y7+gTxwxRKzSrgO5uhtw584igXVuuZkA== dependencies: - "@typescript-eslint/scope-manager" "8.58.0" - "@typescript-eslint/types" "8.58.0" - "@typescript-eslint/typescript-estree" "8.58.0" - "@typescript-eslint/visitor-keys" "8.58.0" + "@typescript-eslint/scope-manager" "8.59.1" + "@typescript-eslint/types" "8.59.1" + "@typescript-eslint/typescript-estree" "8.59.1" + "@typescript-eslint/visitor-keys" "8.59.1" debug "^4.4.3" -"@typescript-eslint/project-service@8.58.0": - version "8.58.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.58.0.tgz#66ceda0aabf7427aec3e2713fa43eb278dead2aa" - integrity sha512-8Q/wBPWLQP1j16NxoPNIKpDZFMaxl7yWIoqXWYeWO+Bbd2mjgvoF0dxP2jKZg5+x49rgKdf7Ck473M8PC3V9lg== +"@typescript-eslint/project-service@8.59.1": + version "8.59.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.59.1.tgz#49efe87c37ef84262f23df8bf62fdc56698ca6fe" + integrity sha512-+MuHQlHiEr00Of/IQbE/MmEoi44znZHbR/Pz7Opq4HryUOlRi+/44dro9Ycy8Fyo+/024IWtw8m4JUMCGTYxDg== dependencies: - "@typescript-eslint/tsconfig-utils" "^8.58.0" - "@typescript-eslint/types" "^8.58.0" + "@typescript-eslint/tsconfig-utils" "^8.59.1" + "@typescript-eslint/types" "^8.59.1" debug "^4.4.3" -"@typescript-eslint/scope-manager@8.58.0": - version "8.58.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.58.0.tgz#e304142775e49a1b7ac3c8bf2536714447c72cab" - integrity sha512-W1Lur1oF50FxSnNdGp3Vs6P+yBRSmZiw4IIjEeYxd8UQJwhUF0gDgDD/W/Tgmh73mxgEU3qX0Bzdl/NGuSPEpQ== +"@typescript-eslint/scope-manager@8.59.1": + version "8.59.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.59.1.tgz#ed90d054fc3db2d0c81464db3a953a94fb85bb58" + integrity sha512-LwuHQI4pDOYVKvmH2dkaJo6YZCSgouVgnS/z7yBPKBMvgtBvyLqiLy9Z6b7+m/TRcX1NFYUqZetI5Y+aT4GEfg== dependencies: - "@typescript-eslint/types" "8.58.0" - "@typescript-eslint/visitor-keys" "8.58.0" + "@typescript-eslint/types" "8.59.1" + "@typescript-eslint/visitor-keys" "8.59.1" -"@typescript-eslint/tsconfig-utils@8.58.0", "@typescript-eslint/tsconfig-utils@^8.58.0": - version "8.58.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.58.0.tgz#c5a8edb21f31e0fdee565724e1b984171c559482" - integrity sha512-doNSZEVJsWEu4htiVC+PR6NpM+pa+a4ClH9INRWOWCUzMst/VA9c4gXq92F8GUD1rwhNvRLkgjfYtFXegXQF7A== +"@typescript-eslint/tsconfig-utils@8.59.1", "@typescript-eslint/tsconfig-utils@^8.59.1": + version "8.59.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.1.tgz#ba2a779a444f1d5cb92a606f9b209d239fd4cab1" + integrity sha512-/0nEyPbX7gRsk0Uwfe4ALwwgxuA66d/l2mhRDNlAvaj4U3juhUtJNq0DsY8M2AYwwb9rEq2hrC3IcIcEt++iJA== -"@typescript-eslint/type-utils@8.58.0": - version "8.58.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.58.0.tgz#ce0e72cd967ffbbe8de322db6089bd4374be352f" - integrity sha512-aGsCQImkDIqMyx1u4PrVlbi/krmDsQUs4zAcCV6M7yPcPev+RqVlndsJy9kJ8TLihW9TZ0kbDAzctpLn5o+lOg== +"@typescript-eslint/type-utils@8.59.1": + version "8.59.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.59.1.tgz#9c83d3f2ed9187a815e8120f72c08317e513e409" + integrity sha512-klWPBR2ciQHS3f++ug/mVnWKPjBUo7icEL3FAO1lhAR1Z1i5NQYZ1EannMSRYcq5qCv5wNALlXr6fksRHyYl7w== dependencies: - "@typescript-eslint/types" "8.58.0" - "@typescript-eslint/typescript-estree" "8.58.0" - "@typescript-eslint/utils" "8.58.0" + "@typescript-eslint/types" "8.59.1" + "@typescript-eslint/typescript-estree" "8.59.1" + "@typescript-eslint/utils" "8.59.1" debug "^4.4.3" ts-api-utils "^2.5.0" -"@typescript-eslint/types@8.58.0", "@typescript-eslint/types@^8.58.0": - version "8.58.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.58.0.tgz#e94ae7abdc1c6530e71183c1007b61fa93112a5a" - integrity sha512-O9CjxypDT89fbHxRfETNoAnHj/i6IpRK0CvbVN3qibxlLdo5p5hcLmUuCCrHMpxiWSwKyI8mCP7qRNYuOJ0Uww== +"@typescript-eslint/types@8.59.1", "@typescript-eslint/types@^8.59.1": + version "8.59.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.59.1.tgz#c1d014d3f03a97e0113a8899fc9d4e45a7fb0ca9" + integrity sha512-ZDCjgccSdYPw5Bxh+my4Z0lJU96ZDN7jbBzvmEn0FZx3RtU1C7VWl6NbDx94bwY3V5YsgwRzJPOgeY2Q/nLG8A== -"@typescript-eslint/typescript-estree@8.58.0": - version "8.58.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.58.0.tgz#ed233faa8e2f2a2e1357c3e7d553d6465a0ee59a" - integrity sha512-7vv5UWbHqew/dvs+D3e1RvLv1v2eeZ9txRHPnEEBUgSNLx5ghdzjHa0sgLWYVKssH+lYmV0JaWdoubo0ncGYLA== +"@typescript-eslint/typescript-estree@8.59.1": + version "8.59.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.1.tgz#4391fadf98a22c869c5b6522dbf4e491e53e351a" + integrity sha512-OUd+vJS05sSkOip+BkZ/2NS8RMxrAAJemsC6vU3kmfLyeaJT0TftHkV9mcx2107MmsBVXXexhVu4F0TZXyMl4g== dependencies: - "@typescript-eslint/project-service" "8.58.0" - "@typescript-eslint/tsconfig-utils" "8.58.0" - "@typescript-eslint/types" "8.58.0" - "@typescript-eslint/visitor-keys" "8.58.0" + "@typescript-eslint/project-service" "8.59.1" + "@typescript-eslint/tsconfig-utils" "8.59.1" + "@typescript-eslint/types" "8.59.1" + "@typescript-eslint/visitor-keys" "8.59.1" debug "^4.4.3" minimatch "^10.2.2" semver "^7.7.3" tinyglobby "^0.2.15" ts-api-utils "^2.5.0" -"@typescript-eslint/utils@8.58.0": - version "8.58.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.58.0.tgz#21a74a7963b0d288b719a4121c7dd555adaab3c3" - integrity sha512-RfeSqcFeHMHlAWzt4TBjWOAtoW9lnsAGiP3GbaX9uVgTYYrMbVnGONEfUCiSss+xMHFl+eHZiipmA8WkQ7FuNA== +"@typescript-eslint/utils@8.59.1": + version "8.59.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.59.1.tgz#cf6204d69701bbbc5b150f98c18aeef0a42c10bd" + integrity sha512-3pIeoXhCeYH9FSCBI8P3iNwJlGuzPlYKkTlen2O9T1DSeeg8UG8jstq6BLk+Mda0qup7mgk4z4XL4OzRaxZ8LA== dependencies: "@eslint-community/eslint-utils" "^4.9.1" - "@typescript-eslint/scope-manager" "8.58.0" - "@typescript-eslint/types" "8.58.0" - "@typescript-eslint/typescript-estree" "8.58.0" + "@typescript-eslint/scope-manager" "8.59.1" + "@typescript-eslint/types" "8.59.1" + "@typescript-eslint/typescript-estree" "8.59.1" -"@typescript-eslint/visitor-keys@8.58.0": - version "8.58.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.58.0.tgz#2abd55a4be70fd55967aceaba4330b9ba9f45189" - integrity sha512-XJ9UD9+bbDo4a4epraTwG3TsNPeiB9aShrUneAVXy8q4LuwowN+qu89/6ByLMINqvIMeI9H9hOHQtg/ijrYXzQ== +"@typescript-eslint/visitor-keys@8.59.1": + version "8.59.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.1.tgz#b5cba576287a3eeb0b400b62813189abcc3f976a" + integrity sha512-LdDNl6C5iJExcM0Yh0PwAIBb9PrSiCsWamF/JyEZawm3kFDnRoaq3LGE4bpyRao/fWeGKKyw7icx0YxrLFC5Cg== dependencies: - "@typescript-eslint/types" "8.58.0" + "@typescript-eslint/types" "8.59.1" eslint-visitor-keys "^5.0.0" -"@vitejs/plugin-react@^5.1.4": - version "5.2.0" - resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-5.2.0.tgz#108bd0f566f288ce3566982df4eff137ded7b15f" - integrity sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw== +"@vitejs/plugin-react@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-6.0.1.tgz#d9113b71a0a592714913eafd9e5e63bcafd0ff15" + integrity sha512-l9X/E3cDb+xY3SWzlG1MOGt2usfEHGMNIaegaUGFsLkb3RCn/k8/TOXBcab+OndDI4TBtktT8/9BwwW8Vi9KUQ== dependencies: - "@babel/core" "^7.29.0" - "@babel/plugin-transform-react-jsx-self" "^7.27.1" - "@babel/plugin-transform-react-jsx-source" "^7.27.1" - "@rolldown/pluginutils" "1.0.0-rc.3" - "@types/babel__core" "^7.20.5" - react-refresh "^0.18.0" + "@rolldown/pluginutils" "1.0.0-rc.7" acorn-jsx@^5.3.2: version "5.3.2" @@ -1059,15 +1015,22 @@ acorn@^8.16.0: integrity sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw== ajv@^6.14.0: - version "6.14.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.14.0.tgz#fd067713e228210636ebb08c60bd3765d6dbe73a" - integrity sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw== + version "6.15.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.15.0.tgz#07e982c74626167aa7a2495c53817892d7139492" + integrity sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw== dependencies: fast-deep-equal "^3.1.1" fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.4.1" uri-js "^4.2.2" +aria-hidden@^1.2.4: + version "1.2.6" + resolved "https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.2.6.tgz#73051c9b088114c795b1ea414e9c0fff874ffc1a" + integrity sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA== + dependencies: + tslib "^2.0.0" + array-buffer-byte-length@^1.0.1, array-buffer-byte-length@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz#384d12a37295aec3769ab022ad323a18a51ccf8b" @@ -1151,17 +1114,6 @@ async-function@^1.0.0: resolved "https://registry.yarnpkg.com/async-function/-/async-function-1.0.0.tgz#509c9fca60eaf85034c6829838188e4e4c8ffb2b" integrity sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA== -autoprefixer@^10.4.24: - version "10.4.27" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.27.tgz#51ea301a5c3c5f8642f8e564759c4f573be486f2" - integrity sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA== - dependencies: - browserslist "^4.28.1" - caniuse-lite "^1.0.30001774" - fraction.js "^5.3.4" - picocolors "^1.1.1" - postcss-value-parser "^4.2.0" - available-typed-arrays@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846" @@ -1180,14 +1132,14 @@ balanced-match@^4.0.2: integrity sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA== baseline-browser-mapping@^2.10.12: - version "2.10.13" - resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.10.13.tgz#5a154cc4589193015a274e3d18319b0d76b9224e" - integrity sha512-BL2sTuHOdy0YT1lYieUxTw/QMtPBC3pmlJC6xk8BBYVv6vcw3SGdKemQ+Xsx9ik2F/lYDO9tqsFQH1r9PFuHKw== + version "2.10.23" + resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.10.23.tgz#3a1a55d1a691a8c8d74688af7f1fd17eac23c184" + integrity sha512-xwVXGqevyKPsiuQdLj+dZMVjidjJV508TBqexND5HrF89cGdCYCJFB3qhcxRHSeMctdCfbR1jrxBajhDy7o29g== brace-expansion@^1.1.7: - version "1.1.13" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.13.tgz#d37875c01dc9eff988dd49d112a57cb67b54efe6" - integrity sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w== + version "1.1.14" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.14.tgz#d9de602370d91347cd9ddad1224d4fd701eb348b" + integrity sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g== dependencies: balanced-match "^1.0.0" concat-map "0.0.1" @@ -1199,7 +1151,7 @@ brace-expansion@^5.0.5: dependencies: balanced-match "^4.0.2" -browserslist@^4.24.0, browserslist@^4.28.1: +browserslist@^4.24.0: version "4.28.2" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.2.tgz#f50b65362ef48974ca9f50b3680566d786b811d2" integrity sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg== @@ -1210,7 +1162,7 @@ browserslist@^4.24.0, browserslist@^4.28.1: node-releases "^2.0.36" update-browserslist-db "^1.2.3" -call-bind-apply-helpers@^1.0.0, call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: +call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6" integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== @@ -1218,14 +1170,14 @@ call-bind-apply-helpers@^1.0.0, call-bind-apply-helpers@^1.0.1, call-bind-apply- es-errors "^1.3.0" function-bind "^1.1.2" -call-bind@^1.0.7, call-bind@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.8.tgz#0736a9660f537e3388826f440d5ec45f744eaa4c" - integrity sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww== +call-bind@^1.0.7, call-bind@^1.0.8, call-bind@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.9.tgz#39a644700c80bc7d0ca9102fc6d1d43b2fd7eee7" + integrity sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ== dependencies: - call-bind-apply-helpers "^1.0.0" - es-define-property "^1.0.0" - get-intrinsic "^1.2.4" + call-bind-apply-helpers "^1.0.2" + es-define-property "^1.0.1" + get-intrinsic "^1.3.0" set-function-length "^1.2.2" call-bound@^1.0.2, call-bound@^1.0.3, call-bound@^1.0.4: @@ -1236,10 +1188,10 @@ call-bound@^1.0.2, call-bound@^1.0.3, call-bound@^1.0.4: call-bind-apply-helpers "^1.0.2" get-intrinsic "^1.3.0" -caniuse-lite@^1.0.30001774, caniuse-lite@^1.0.30001782: - version "1.0.30001784" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001784.tgz#bdf9733a0813ccfb5ab4d02f2127e62ee4c6b718" - integrity sha512-WU346nBTklUV9YfUl60fqRbU5ZqyXlqvo1SgigE1OAXK5bFL8LL9q1K7aap3N739l4BvNqnkm3YrGHiY9sfUQw== +caniuse-lite@^1.0.30001782: + version "1.0.30001791" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001791.tgz#dfb93d85c40ad380c57123e72e10f3c575786b51" + integrity sha512-yk0l/YSrOnFZk3UROpDLQD9+kC1l4meK/wed583AXrzoarMGJcbRi2Q4RaUYbKxYAsZ8sWmaSa/DsLmdBeI1vQ== chokidar@^4.0.0: version "4.0.3" @@ -1248,11 +1200,6 @@ chokidar@^4.0.0: dependencies: readdirp "^4.0.1" -classnames@^2.3.2: - version "2.5.1" - resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.5.1.tgz#ba774c614be0f016da105c858e7159eae8e7687b" - integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow== - concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -1277,7 +1224,7 @@ cssesc@^3.0.0: resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -csstype@^3.0.2, csstype@^3.2.2: +csstype@^3.2.2: version "3.2.3" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.2.3.tgz#ec48c0f3e993e50648c86da559e2610995cf989a" integrity sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ== @@ -1309,14 +1256,7 @@ data-view-byte-offset@^1.0.1: es-errors "^1.3.0" is-data-view "^1.0.1" -debug@^2.6.6: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.4.3: +debug@^4.1.0, debug@^4.3.1, debug@^4.3.2, debug@^4.4.3: version "4.4.3" resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a" integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== @@ -1328,6 +1268,11 @@ deep-is@^0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== +deepmerge@^4.0.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== + define-data-property@^1.0.1, define-data-property@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" @@ -1346,16 +1291,16 @@ define-properties@^1.1.3, define-properties@^1.2.1: has-property-descriptors "^1.0.0" object-keys "^1.1.1" -dequal@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" - integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== - detect-libc@^2.0.3: version "2.1.2" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.1.2.tgz#689c5dcdc1900ef5583a4cb9f6d7b473742074ad" integrity sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ== +detect-node-es@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/detect-node-es/-/detect-node-es-1.1.0.tgz#163acdf643330caa0b4cd7c21e7ee7755d6fa493" + integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ== + doctrine@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" @@ -1363,18 +1308,10 @@ doctrine@^2.1.0: dependencies: esutils "^2.0.2" -dom-helpers@^5.0.1, dom-helpers@^5.2.0, dom-helpers@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902" - integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA== - dependencies: - "@babel/runtime" "^7.8.7" - csstype "^3.0.2" - -dompurify@^3.1.5: - version "3.3.3" - resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.3.3.tgz#680cae8af3e61320ddf3666a3bc843f7b291b2b6" - integrity sha512-Oj6pzI2+RqBfFG+qOaOLbFXLQ90ARpcGG6UePL82bJLtdsa6CYJD7nmiU8MW9nQNOtCHV3lZ/Bzq1X0QYbBZCA== +dompurify@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.4.1.tgz#521d04483ac12631b2aedf434a5f5390933b8789" + integrity sha512-JahakDAIg1gyOm7dlgWSDjV4n7Ip2PKR55NIT6jrMfIgLFgWo81vdr1/QGqWtFNRqXP9UV71oVePtjqS2ebnPw== optionalDependencies: "@types/trusted-types" "^2.0.7" @@ -1388,9 +1325,9 @@ dunder-proto@^1.0.0, dunder-proto@^1.0.1: gopd "^1.2.0" electron-to-chromium@^1.5.328: - version "1.5.330" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.330.tgz#0efe031938fc8fc82126162a7bd466ba7e24cd38" - integrity sha512-jFNydB5kFtYUobh4IkWUnXeyDbjf/r9gcUEXe1xcrcUxIGfTdzPXA+ld6zBRbwvgIGVzDll/LTIiDztEtckSnA== + version "1.5.344" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.344.tgz#6437cc08a7d9b914a98120e182f37793c9eaffd4" + integrity sha512-4MxfbmNDm+KPh066EZy+eUnkcDPcZ35wNmOWzFuh/ijvHsve6kbLTLURy88uCNK5FbpN+yk2nQY6BYh1GEt+wg== emoji-mart@^5.6.0: version "5.6.0" @@ -1403,17 +1340,17 @@ emoji-toolkit@10.0.0: integrity sha512-GkIAvgutEVbkqcT2HjBzV002SWvpdNaT3aP9q/YjQ6hlgDq8HhE9GcqxWkyYkRRQnLADGpwDoj1heTw9KzO9wQ== enhanced-resolve@^5.19.0: - version "5.20.1" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.20.1.tgz#eeeb3966bea62c348c40a0cc9e7912e2557d0be0" - integrity sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA== + version "5.21.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.21.0.tgz#bb8e6fabaf74930de70e61397798750429e5b1ae" + integrity sha512-otxSQPw4lkOZWkHpB3zaEQs6gWYEsmX4xQF68ElXC/TWvGxGMSGOvoNbaLXm6/cS/fSfHtsEdw90y20PCd+sCA== dependencies: graceful-fs "^4.2.4" - tapable "^2.3.0" + tapable "^2.3.3" -es-abstract@^1.17.5, es-abstract@^1.23.2, es-abstract@^1.23.3, es-abstract@^1.23.5, es-abstract@^1.23.6, es-abstract@^1.23.9, es-abstract@^1.24.0, es-abstract@^1.24.1: - version "1.24.1" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.24.1.tgz#f0c131ed5ea1bb2411134a8dd94def09c46c7899" - integrity sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw== +es-abstract@^1.17.5, es-abstract@^1.23.2, es-abstract@^1.23.3, es-abstract@^1.23.5, es-abstract@^1.23.6, es-abstract@^1.23.9, es-abstract@^1.24.0, es-abstract@^1.24.2: + version "1.24.2" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.24.2.tgz#2dbd38c180735ee983f77585140a2706a963ed9a" + integrity sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg== dependencies: array-buffer-byte-length "^1.0.2" arraybuffer.prototype.slice "^1.0.4" @@ -1481,14 +1418,14 @@ es-errors@^1.3.0: integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== es-iterator-helpers@^1.2.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/es-iterator-helpers/-/es-iterator-helpers-1.3.1.tgz#3be0f4e63438d6c5a1fb5f33b891aaad3f7dae06" - integrity sha512-zWwRvqWiuBPr0muUG/78cW3aHROFCNIQ3zpmYDpwdbnt2m+xlNyRWpHBpa2lJjSBit7BQ+RXA1iwbSmu5yJ/EQ== + version "1.3.2" + resolved "https://registry.yarnpkg.com/es-iterator-helpers/-/es-iterator-helpers-1.3.2.tgz#8f4ff1f3603cbd09fbdb72c747a679779a65cc7f" + integrity sha512-HVLACW1TppGYjJ8H6/jqH/pqOtKRw6wMlrB23xfExmFWxFquAIWCmwoLsOyN96K4a5KbmOf5At9ZUO3GZbetAw== dependencies: - call-bind "^1.0.8" + call-bind "^1.0.9" call-bound "^1.0.4" define-properties "^1.2.1" - es-abstract "^1.24.1" + es-abstract "^1.24.2" es-errors "^1.3.0" es-set-tostringtag "^2.1.0" function-bind "^1.1.2" @@ -1501,7 +1438,6 @@ es-iterator-helpers@^1.2.1: internal-slot "^1.1.0" iterator.prototype "^1.1.5" math-intrinsics "^1.1.0" - safe-array-concat "^1.1.3" es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: version "1.1.1" @@ -1536,38 +1472,6 @@ es-to-primitive@^1.3.0: is-date-object "^1.0.5" is-symbol "^1.0.4" -esbuild@^0.27.0: - version "0.27.4" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.27.4.tgz#b9591dd7e0ab803a11c9c3b602850403bef22f00" - integrity sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ== - optionalDependencies: - "@esbuild/aix-ppc64" "0.27.4" - "@esbuild/android-arm" "0.27.4" - "@esbuild/android-arm64" "0.27.4" - "@esbuild/android-x64" "0.27.4" - "@esbuild/darwin-arm64" "0.27.4" - "@esbuild/darwin-x64" "0.27.4" - "@esbuild/freebsd-arm64" "0.27.4" - "@esbuild/freebsd-x64" "0.27.4" - "@esbuild/linux-arm" "0.27.4" - "@esbuild/linux-arm64" "0.27.4" - "@esbuild/linux-ia32" "0.27.4" - "@esbuild/linux-loong64" "0.27.4" - "@esbuild/linux-mips64el" "0.27.4" - "@esbuild/linux-ppc64" "0.27.4" - "@esbuild/linux-riscv64" "0.27.4" - "@esbuild/linux-s390x" "0.27.4" - "@esbuild/linux-x64" "0.27.4" - "@esbuild/netbsd-arm64" "0.27.4" - "@esbuild/netbsd-x64" "0.27.4" - "@esbuild/openbsd-arm64" "0.27.4" - "@esbuild/openbsd-x64" "0.27.4" - "@esbuild/openharmony-arm64" "0.27.4" - "@esbuild/sunos-x64" "0.27.4" - "@esbuild/win32-arm64" "0.27.4" - "@esbuild/win32-ia32" "0.27.4" - "@esbuild/win32-x64" "0.27.4" - escalade@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" @@ -1578,10 +1482,10 @@ escape-string-regexp@^4.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -eslint-plugin-react-hooks@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.0.1.tgz#66e258db58ece50723ef20cc159f8aa908219169" - integrity sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA== +eslint-plugin-react-hooks@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.1.1.tgz#e6742cad75d970c0a3f30d7d3fa80a4784f55927" + integrity sha512-f2I7Gw6JbvCexzIInuSbZpfdQ44D7iqdWX01FKLvrPgqxoE7oMj8clOfto8U6vYiz4yd5oKu39rRSVOe1zRu0g== dependencies: "@babel/core" "^7.24.4" "@babel/parser" "^7.24.4" @@ -1633,17 +1537,17 @@ eslint-visitor-keys@^5.0.0, eslint-visitor-keys@^5.0.1: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz#9e3c9489697824d2d4ce3a8ad12628f91e9f59be" integrity sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA== -eslint@^10.0.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-10.1.0.tgz#9ca98e654e642ab2e1af6d1e9d8613857ac341b4" - integrity sha512-S9jlY/ELKEUwwQnqWDO+f+m6sercqOPSqXM5Go94l7DOmxHVDgmSFGWEzeE/gwgTAr0W103BWt0QLe/7mabIvA== +eslint@^10.2.1: + version "10.2.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-10.2.1.tgz#224b2a6caeb34473eddcf918762363e2e063222a" + integrity sha512-wiyGaKsDgqXvF40P8mDwiUp/KQjE1FdrIEJsM8PZ3XCiniTMXS3OHWWUe5FI5agoCnr8x4xPrTDZuxsBlNHl+Q== dependencies: "@eslint-community/eslint-utils" "^4.8.0" "@eslint-community/regexpp" "^4.12.2" - "@eslint/config-array" "^0.23.3" - "@eslint/config-helpers" "^0.5.3" - "@eslint/core" "^1.1.1" - "@eslint/plugin-kit" "^0.6.1" + "@eslint/config-array" "^0.23.5" + "@eslint/config-helpers" "^0.5.5" + "@eslint/core" "^1.2.1" + "@eslint/plugin-kit" "^0.7.1" "@humanfs/node" "^0.16.6" "@humanwhocodes/module-importer" "^1.0.1" "@humanwhocodes/retry" "^0.4.2" @@ -1702,7 +1606,7 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -fast-deep-equal@3.1.3, fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== @@ -1757,21 +1661,16 @@ for-each@^0.3.3, for-each@^0.3.5: dependencies: is-callable "^1.2.7" -fraction.js@^5.3.4: - version "5.3.4" - resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-5.3.4.tgz#8c0fcc6a9908262df4ed197427bdeef563e0699a" - integrity sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ== - -framer-motion@^11.2.12: - version "11.18.2" - resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-11.18.2.tgz#0c6bd05677f4cfd3b3bdead4eb5ecdd5ed245718" - integrity sha512-5F5Och7wrvtLVElIpclDT0CBzMVg3dL22B64aZwHtsIY8RB4mXICLrkajK4G9R+ieSAGcgrLeae2SeUTg2pr6w== +framer-motion@^12.38.0: + version "12.38.0" + resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-12.38.0.tgz#cf28e072a95942881ca4e33fd33be41192fd146b" + integrity sha512-rFYkY/pigbcswl1XQSb7q424kSTQ8q6eAC+YUsSKooHQYuLdzdHjrt6uxUC+PRAO++q5IS7+TamgIw1AphxR+g== dependencies: - motion-dom "^11.18.1" - motion-utils "^11.18.1" + motion-dom "^12.38.0" + motion-utils "^12.36.0" tslib "^2.4.0" -fsevents@~2.3.2, fsevents@~2.3.3: +fsevents@~2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== @@ -1824,6 +1723,11 @@ get-intrinsic@^1.2.4, get-intrinsic@^1.2.5, get-intrinsic@^1.2.6, get-intrinsic@ hasown "^2.0.2" math-intrinsics "^1.1.0" +get-nonce@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/get-nonce/-/get-nonce-1.0.1.tgz#fdf3f0278073820d2ce9426c18f07481b1e0cdf3" + integrity sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q== + get-proto@^1.0.0, get-proto@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1" @@ -1856,11 +1760,6 @@ globalthis@^1.0.4: define-properties "^1.2.1" gopd "^1.0.1" -globrex@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098" - integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg== - gopd@^1.0.1, gopd@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" @@ -1903,9 +1802,9 @@ has-tostringtag@^1.0.2: has-symbols "^1.0.3" hasown@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" - integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== + version "2.0.3" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.3.tgz#5e5c2b15b60370a4c7930c383dfb76bf17bc403c" + integrity sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg== dependencies: function-bind "^1.1.2" @@ -1950,13 +1849,6 @@ internal-slot@^1.1.0: hasown "^2.0.2" side-channel "^1.1.0" -invariant@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== - dependencies: - loose-envify "^1.0.0" - is-array-buffer@^3.0.4, is-array-buffer@^3.0.5: version "3.0.5" resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.5.tgz#65742e1e687bd2cc666253068fd8707fe4d44280" @@ -2272,7 +2164,7 @@ lightningcss-win32-x64-msvc@1.32.0: resolved "https://registry.yarnpkg.com/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz#141aa5605645064928902bb4af045fa7d9f4220a" integrity sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q== -lightningcss@1.32.0: +lightningcss@1.32.0, lightningcss@^1.32.0: version "1.32.0" resolved "https://registry.yarnpkg.com/lightningcss/-/lightningcss-1.32.0.tgz#b85aae96486dcb1bf49a7c8571221273f4f1e4a9" integrity sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ== @@ -2303,7 +2195,7 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" -loose-envify@^1.0.0, loose-envify@^1.4.0: +loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -2329,6 +2221,11 @@ math-intrinsics@^1.1.0: resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9" integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== +memoize-one@^5.1.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e" + integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q== + mini-svg-data-uri@^1.2.3: version "1.4.4" resolved "https://registry.yarnpkg.com/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz#8ab0aabcdf8c29ad5693ca595af19dd2ead09939" @@ -2348,22 +2245,17 @@ minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" -motion-dom@^11.18.1: - version "11.18.1" - resolved "https://registry.yarnpkg.com/motion-dom/-/motion-dom-11.18.1.tgz#e7fed7b7dc6ae1223ef1cce29ee54bec826dc3f2" - integrity sha512-g76KvA001z+atjfxczdRtw/RXOM3OMSdd1f4DL77qCTF/+avrRJiawSG4yDibEQ215sr9kpinSlX2pCTJ9zbhw== +motion-dom@^12.38.0: + version "12.38.0" + resolved "https://registry.yarnpkg.com/motion-dom/-/motion-dom-12.38.0.tgz#9ef3253ea0fb28b6757588327073848d940e9aab" + integrity sha512-pdkHLD8QYRp8VfiNLb8xIBJis1byQ9gPT3Jnh2jqfFtAsWUA3dEepDlsWe/xMpO8McV+VdpKVcp+E+TGJEtOoA== dependencies: - motion-utils "^11.18.1" + motion-utils "^12.36.0" -motion-utils@^11.18.1: - version "11.18.1" - resolved "https://registry.yarnpkg.com/motion-utils/-/motion-utils-11.18.1.tgz#671227669833e991c55813cf337899f41327db5b" - integrity sha512-49Kt+HKjtbJKLtgO/LKj9Ld+6vw9BjH5d9sc40R/kVyH8GLAXgT42M2NnuPcJNuA3s9ZfZBUcwIgpmZWGEE+hA== - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== +motion-utils@^12.36.0: + version "12.36.0" + resolved "https://registry.yarnpkg.com/motion-utils/-/motion-utils-12.36.0.tgz#cff2df2a28c3fe53a3de7e0103ba7f73ff7d77a7" + integrity sha512-eHWisygbiwVvf6PZ1vhaHCLamvkSbPIeAYxWUuL3a2PD/TROgE7FvfHWTIH4vMl798QLfMw15nRqIaRDXTlYRg== ms@^2.1.3: version "2.1.3" @@ -2396,9 +2288,9 @@ node-exports-info@^1.6.0: semver "^6.3.1" node-releases@^2.0.36: - version "2.0.36" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.36.tgz#99fd6552aaeda9e17c4713b57a63964a2e325e9d" - integrity sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA== + version "2.0.38" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.38.tgz#791569b9e4424a044e12c3abfad418ed83ce9947" + integrity sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw== object-assign@^4.1.1: version "4.1.1" @@ -2512,7 +2404,7 @@ picocolors@^1.1.1: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== -picomatch@^4.0.3: +picomatch@^4.0.3, picomatch@^4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.4.tgz#fd6f5e00a143086e074dffe4c924b8fb293b0589" integrity sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A== @@ -2537,15 +2429,10 @@ postcss-selector-parser@^7.0.0: cssesc "^3.0.0" util-deprecate "^1.0.2" -postcss-value-parser@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" - integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== - -postcss@^8.5.6: - version "8.5.8" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.8.tgz#6230ecc8fb02e7a0f6982e53990937857e13f399" - integrity sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg== +postcss@^8.5.10, postcss@^8.5.12, postcss@^8.5.6: + version "8.5.12" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.12.tgz#cd0c0f667f7cb0521e2313234ea6e707a9ec1ddb" + integrity sha512-W62t/Se6rA0Az3DfCL0AqJwXuKwBeYg6nOaIgzP+xZ7N5BFCI7DYi1qs6ygUYT6rvfi6t9k65UMLJC+PHZpDAA== dependencies: nanoid "^3.3.11" picocolors "^1.1.1" @@ -2556,15 +2443,7 @@ prelude-ls@^1.2.1: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== -prop-types-extra@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/prop-types-extra/-/prop-types-extra-1.1.1.tgz#58c3b74cbfbb95d304625975aa2f0848329a010b" - integrity sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew== - dependencies: - react-is "^16.3.2" - warning "^4.0.0" - -prop-types@15.8.1, prop-types@^15.6.2, prop-types@^15.8.1: +prop-types@^15.7.2, prop-types@^15.8.1: version "15.8.1" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== @@ -2578,87 +2457,70 @@ punycode@^2.1.0: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== -react-bootstrap@^2.10.10: - version "2.10.10" - resolved "https://registry.yarnpkg.com/react-bootstrap/-/react-bootstrap-2.10.10.tgz#be0b0d951a69987152d75c0e6986c80425efdf21" - integrity sha512-gMckKUqn8aK/vCnfwoBpBVFUGT9SVQxwsYrp9yDHt0arXMamxALerliKBxr1TPbntirK/HGrUAHYbAeQTa9GHQ== - dependencies: - "@babel/runtime" "^7.24.7" - "@restart/hooks" "^0.4.9" - "@restart/ui" "^1.9.4" - "@types/prop-types" "^15.7.12" - "@types/react-transition-group" "^4.4.6" - classnames "^2.3.2" - dom-helpers "^5.2.1" - invariant "^2.2.4" - prop-types "^15.8.1" - prop-types-extra "^1.1.0" - react-transition-group "^4.4.5" - uncontrollable "^7.2.1" - warning "^4.0.3" - -react-dom@^19.2.4: - version "19.2.4" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-19.2.4.tgz#6fac6bd96f7db477d966c7ec17c1a2b1ad8e6591" - integrity sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ== +react-dom@^19.2.5: + version "19.2.5" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-19.2.5.tgz#b8768b10837d0b8e9ca5b9e2d58dff3d880ea25e" + integrity sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag== dependencies: scheduler "^0.27.0" +react-fast-compare@^3.0.1: + version "3.2.2" + resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49" + integrity sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ== + react-icons@^5.5.0: version "5.6.0" resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-5.6.0.tgz#27bcc4acbc836e762548d76041cf9b9fef4e3837" integrity sha512-RH93p5ki6LfOiIt0UtDyNg/cee+HLVR6cHHtW3wALfo+eOHTp8RnU2kRkI6E+H19zMIs03DyxUG/GfZMOGvmiA== -react-is@^16.13.1, react-is@^16.3.2: +react-is@^16.13.1: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -react-lifecycles-compat@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" - integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== - -react-refresh@^0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.18.0.tgz#2dce97f4fe932a4d8142fa1630e475c1729c8062" - integrity sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw== - -react-slider@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/react-slider/-/react-slider-2.0.6.tgz#8c7ff0301211f7c3ff32aa0163b33bdab6258559" - integrity sha512-gJxG1HwmuMTJ+oWIRCmVWvgwotNCbByTwRkFZC6U4MBsHqJBmxwbYRJUmxy4Tke1ef8r9jfXjgkmY/uHOCEvbA== +react-player@^2.16.0: + version "2.16.1" + resolved "https://registry.yarnpkg.com/react-player/-/react-player-2.16.1.tgz#f157600bd04a641d9a2c53685235d34dcfabac6b" + integrity sha512-mxP6CqjSWjidtyDoMOSHVPdhX0pY16aSvw5fVr44EMaT7X5Xz46uQ4b/YBm1v2x+3hHkB9PmjEEkmbHb9PXQ4w== dependencies: - prop-types "^15.8.1" + deepmerge "^4.0.0" + load-script "^1.0.0" + memoize-one "^5.1.1" + prop-types "^15.7.2" + react-fast-compare "^3.0.1" -react-tiny-popover@^8.1.6: - version "8.1.6" - resolved "https://registry.yarnpkg.com/react-tiny-popover/-/react-tiny-popover-8.1.6.tgz#82fad10eb8f0d8197ce0944031fd03a524b78c29" - integrity sha512-jeZnGqHxb5TX7pCzpqLoVJned7DTVnLrLoCQQGFTyvlxXB/QUaet7O0krG22t5FReMBH035SLnzThKvk8tIfsg== - -react-transition-group@^4.4.5: - version "4.4.5" - resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1" - integrity sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g== +react-remove-scroll-bar@^2.3.7: + version "2.3.8" + resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz#99c20f908ee467b385b68a3469b4a3e750012223" + integrity sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q== dependencies: - "@babel/runtime" "^7.5.5" - dom-helpers "^5.0.1" - loose-envify "^1.4.0" - prop-types "^15.6.2" + react-style-singleton "^2.2.2" + tslib "^2.0.0" -react-youtube@^10.1.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/react-youtube/-/react-youtube-10.1.0.tgz#7e5670c764f12eb408166e8eb438d788dc64e8b5" - integrity sha512-ZfGtcVpk0SSZtWCSTYOQKhfx5/1cfyEW1JN/mugGNfAxT3rmVJeMbGpA9+e78yG21ls5nc/5uZJETE3cm3knBg== +react-remove-scroll@^2.6.3: + version "2.7.2" + resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.7.2.tgz#6442da56791117661978ae99cd29be9026fecca0" + integrity sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q== dependencies: - fast-deep-equal "3.1.3" - prop-types "15.8.1" - youtube-player "5.5.2" + react-remove-scroll-bar "^2.3.7" + react-style-singleton "^2.2.3" + tslib "^2.1.0" + use-callback-ref "^1.3.3" + use-sidecar "^1.1.3" -react@^19.2.4: - version "19.2.4" - resolved "https://registry.yarnpkg.com/react/-/react-19.2.4.tgz#438e57baa19b77cb23aab516cf635cd0579ee09a" - integrity sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ== +react-style-singleton@^2.2.2, react-style-singleton@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/react-style-singleton/-/react-style-singleton-2.2.3.tgz#4265608be69a4d70cfe3047f2c6c88b2c3ace388" + integrity sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ== + dependencies: + get-nonce "^1.0.0" + tslib "^2.0.0" + +react@^19.2.5: + version "19.2.5" + resolved "https://registry.yarnpkg.com/react/-/react-19.2.5.tgz#c888ab8b8ef33e2597fae8bdb2d77edbdb42858b" + integrity sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA== readdirp@^4.0.1: version "4.1.2" @@ -2703,48 +2565,38 @@ resolve@^2.0.0-next.5: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -rollup@^4.43.0: - version "4.60.1" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.60.1.tgz#b4aa2bcb3a5e1437b5fad40d43fe42d4bde7a42d" - integrity sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w== +rolldown@1.0.0-rc.17: + version "1.0.0-rc.17" + resolved "https://registry.yarnpkg.com/rolldown/-/rolldown-1.0.0-rc.17.tgz#c524fc22f6bb37b5588aec862ab1ee11382610f3" + integrity sha512-ZrT53oAKrtA4+YtBWPQbtPOxIbVDbxT0orcYERKd63VJTF13zPcgXTvD4843L8pcsI7M6MErt8QtON6lrB9tyA== dependencies: - "@types/estree" "1.0.8" + "@oxc-project/types" "=0.127.0" + "@rolldown/pluginutils" "1.0.0-rc.17" optionalDependencies: - "@rollup/rollup-android-arm-eabi" "4.60.1" - "@rollup/rollup-android-arm64" "4.60.1" - "@rollup/rollup-darwin-arm64" "4.60.1" - "@rollup/rollup-darwin-x64" "4.60.1" - "@rollup/rollup-freebsd-arm64" "4.60.1" - "@rollup/rollup-freebsd-x64" "4.60.1" - "@rollup/rollup-linux-arm-gnueabihf" "4.60.1" - "@rollup/rollup-linux-arm-musleabihf" "4.60.1" - "@rollup/rollup-linux-arm64-gnu" "4.60.1" - "@rollup/rollup-linux-arm64-musl" "4.60.1" - "@rollup/rollup-linux-loong64-gnu" "4.60.1" - "@rollup/rollup-linux-loong64-musl" "4.60.1" - "@rollup/rollup-linux-ppc64-gnu" "4.60.1" - "@rollup/rollup-linux-ppc64-musl" "4.60.1" - "@rollup/rollup-linux-riscv64-gnu" "4.60.1" - "@rollup/rollup-linux-riscv64-musl" "4.60.1" - "@rollup/rollup-linux-s390x-gnu" "4.60.1" - "@rollup/rollup-linux-x64-gnu" "4.60.1" - "@rollup/rollup-linux-x64-musl" "4.60.1" - "@rollup/rollup-openbsd-x64" "4.60.1" - "@rollup/rollup-openharmony-arm64" "4.60.1" - "@rollup/rollup-win32-arm64-msvc" "4.60.1" - "@rollup/rollup-win32-ia32-msvc" "4.60.1" - "@rollup/rollup-win32-x64-gnu" "4.60.1" - "@rollup/rollup-win32-x64-msvc" "4.60.1" - fsevents "~2.3.2" + "@rolldown/binding-android-arm64" "1.0.0-rc.17" + "@rolldown/binding-darwin-arm64" "1.0.0-rc.17" + "@rolldown/binding-darwin-x64" "1.0.0-rc.17" + "@rolldown/binding-freebsd-x64" "1.0.0-rc.17" + "@rolldown/binding-linux-arm-gnueabihf" "1.0.0-rc.17" + "@rolldown/binding-linux-arm64-gnu" "1.0.0-rc.17" + "@rolldown/binding-linux-arm64-musl" "1.0.0-rc.17" + "@rolldown/binding-linux-ppc64-gnu" "1.0.0-rc.17" + "@rolldown/binding-linux-s390x-gnu" "1.0.0-rc.17" + "@rolldown/binding-linux-x64-gnu" "1.0.0-rc.17" + "@rolldown/binding-linux-x64-musl" "1.0.0-rc.17" + "@rolldown/binding-openharmony-arm64" "1.0.0-rc.17" + "@rolldown/binding-wasm32-wasi" "1.0.0-rc.17" + "@rolldown/binding-win32-arm64-msvc" "1.0.0-rc.17" + "@rolldown/binding-win32-x64-msvc" "1.0.0-rc.17" safe-array-concat@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.1.3.tgz#c9e54ec4f603b0bbb8e7e5007a5ee7aecd1538c3" - integrity sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q== + version "1.1.4" + resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.1.4.tgz#a54cc9b61a57f33b42abad3cbdda3a2b38cc5719" + integrity sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg== dependencies: - call-bind "^1.0.8" - call-bound "^1.0.2" - get-intrinsic "^1.2.6" + call-bind "^1.0.9" + call-bound "^1.0.4" + get-intrinsic "^1.3.0" has-symbols "^1.1.0" isarray "^2.0.5" @@ -2765,10 +2617,10 @@ safe-regex-test@^1.1.0: es-errors "^1.3.0" is-regex "^1.2.1" -sass@^1.97.3: - version "1.98.0" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.98.0.tgz#924ce85a3745ccaccd976262fdc1bc0c13aa8e57" - integrity sha512-+4N/u9dZ4PrgzGgPlKnaaRQx64RO0JBKs9sDhQ2pLgN6JQZ25uPQZKQYaBJU48Kd5BxgXoJ4e09Dq7nMcOUW3A== +sass@^1.99.0: + version "1.99.0" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.99.0.tgz#ff9d1594da4886249dfaafabbeea2dea2dc74b26" + integrity sha512-kgW13M54DUB7IsIRM5LvJkNlpH+WhMpooUcaWGFARkF1Tc82v9mIWkCbCYf+MBvpIUBSeSOTilpZjEPr2VYE6Q== dependencies: chokidar "^4.0.0" immutable "^5.1.5" @@ -2835,12 +2687,12 @@ shebang-regex@^3.0.0: integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== side-channel-list@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.0.tgz#10cb5984263115d3b7a0e336591e290a830af8ad" - integrity sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA== + version "1.0.1" + resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.1.tgz#c2e0b5a14a540aebee3bbc6c3f8666cc9b509127" + integrity sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w== dependencies: es-errors "^1.3.0" - object-inspect "^1.13.3" + object-inspect "^1.13.4" side-channel-map@^1.0.1: version "1.0.1" @@ -2874,11 +2726,6 @@ side-channel@^1.1.0: side-channel-map "^1.0.1" side-channel-weakmap "^1.0.2" -sister@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/sister/-/sister-3.0.2.tgz#bb3e39f07b1f75bbe1945f29a27ff1e5a2f26be4" - integrity sha512-p19rtTs+NksBRKW9qn0UhZ8/TUI9BPw9lmtHny+Y3TinWlOa9jWh9xB0AtPSdmOy49NJJJSSe0Ey4C7h0TrcYA== - "source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" @@ -2956,35 +2803,30 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -tailwindcss@4.2.2, tailwindcss@^4.2.0: - version "4.2.2" - resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-4.2.2.tgz#688fb0751c8ca9044e890546510a2ee817308e87" - integrity sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q== +tailwindcss@4.2.4, tailwindcss@^4.2.4: + version "4.2.4" + resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-4.2.4.tgz#f7e3090edb22d56394db4d68e6464d2628dc2aa9" + integrity sha512-HhKppgO81FQof5m6TEnuBWCZGgfRAWbaeOaGT00KOy/Pf/j6oUihdvBpA7ltCeAvZpFhW3j0PTclkxsd4IXYDA== -tapable@^2.3.0: - version "2.3.2" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.2.tgz#86755feabad08d82a26b891db044808c6ad00f15" - integrity sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA== +tapable@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.3.tgz#5da7c9992c46038221267985ab28421a8879f160" + integrity sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A== -tinyglobby@^0.2.15: - version "0.2.15" - resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.15.tgz#e228dd1e638cea993d2fdb4fcd2d4602a79951c2" - integrity sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ== +tinyglobby@^0.2.15, tinyglobby@^0.2.16: + version "0.2.16" + resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.16.tgz#1c3b7eb953fce42b226bc5a1ee06428281aff3d6" + integrity sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg== dependencies: fdir "^6.5.0" - picomatch "^4.0.3" + picomatch "^4.0.4" ts-api-utils@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-2.5.0.tgz#4acd4a155e22734990a5ed1fe9e97f113bcb37c1" integrity sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA== -tsconfck@^3.0.3: - version "3.1.6" - resolved "https://registry.yarnpkg.com/tsconfck/-/tsconfck-3.1.6.tgz#da1f0b10d82237ac23422374b3fce1edb23c3ead" - integrity sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w== - -tslib@^2.4.0, tslib@^2.8.0, tslib@^2.8.1: +tslib@^2.0.0, tslib@^2.1.0, tslib@^2.4.0, tslib@^2.8.1: version "2.8.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== @@ -3041,20 +2883,20 @@ typed-array-length@^1.0.7: possible-typed-array-names "^1.0.0" reflect.getprototypeof "^1.0.6" -typescript-eslint@^8.56.0: - version "8.58.0" - resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.58.0.tgz#5758b1b68ae7ec05d756b98c63a1f6953a01172b" - integrity sha512-e2TQzKfaI85fO+F3QywtX+tCTsu/D3WW5LVU6nz8hTFKFZ8yBJ6mSYRpXqdR3mFjPWmO0eWsTa5f+UpAOe/FMA== +typescript-eslint@^8.59.1: + version "8.59.1" + resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.59.1.tgz#244a9fcbf27057ebbc2281d408239f1861b55b78" + integrity sha512-xqDcFVBmlrltH64lklOVp1wYxgJr6LVdg3NamBgH2OOQDLFdTKfIZXF5PfghrnXQKXZGTQs8tr1vL7fJvq8CTQ== dependencies: - "@typescript-eslint/eslint-plugin" "8.58.0" - "@typescript-eslint/parser" "8.58.0" - "@typescript-eslint/typescript-estree" "8.58.0" - "@typescript-eslint/utils" "8.58.0" + "@typescript-eslint/eslint-plugin" "8.59.1" + "@typescript-eslint/parser" "8.59.1" + "@typescript-eslint/typescript-estree" "8.59.1" + "@typescript-eslint/utils" "8.59.1" -typescript@^5.9.3: - version "5.9.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.3.tgz#5b4f59e15310ab17a216f5d6cf53ee476ede670f" - integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw== +typescript@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-6.0.3.tgz#90251dc007916e972786cb94d74d15b185577d21" + integrity sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw== unbox-primitive@^1.1.0: version "1.1.0" @@ -3066,25 +2908,10 @@ unbox-primitive@^1.1.0: has-symbols "^1.1.0" which-boxed-primitive "^1.1.1" -uncontrollable@^7.2.1: - version "7.2.1" - resolved "https://registry.yarnpkg.com/uncontrollable/-/uncontrollable-7.2.1.tgz#1fa70ba0c57a14d5f78905d533cf63916dc75738" - integrity sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ== - dependencies: - "@babel/runtime" "^7.6.3" - "@types/react" ">=16.9.11" - invariant "^2.2.4" - react-lifecycles-compat "^3.0.4" - -uncontrollable@^8.0.4: - version "8.0.4" - resolved "https://registry.yarnpkg.com/uncontrollable/-/uncontrollable-8.0.4.tgz#a0a8307f638795162fafd0550f4a1efa0f8c5eb6" - integrity sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ== - -undici-types@~7.18.0: - version "7.18.2" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.18.2.tgz#29357a89e7b7ca4aef3bf0fd3fd0cd73884229e9" - integrity sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w== +undici-types@~7.19.0: + version "7.19.2" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.19.2.tgz#1b67fc26d0f157a0cba3a58a5b5c1e2276b8ba2a" + integrity sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg== update-browserslist-db@^1.2.3: version "1.2.3" @@ -3106,41 +2933,39 @@ use-between@^1.4.0: resolved "https://registry.yarnpkg.com/use-between/-/use-between-1.4.0.tgz#d1e3b95095be2c2305709c15ed5265ee6c692935" integrity sha512-MpLUnRHxZd3CNa5EeXaMadK1+oSd2Kst57WfU15TQbsLu3vgMcfh4gjAJWKaox02pOf+7Lx1ZHK5tMXHEVH1Qw== +use-callback-ref@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.3.3.tgz#98d9fab067075841c5b2c6852090d5d0feabe2bf" + integrity sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg== + dependencies: + tslib "^2.0.0" + +use-sidecar@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.1.3.tgz#10e7fd897d130b896e2c546c63a5e8233d00efdb" + integrity sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ== + dependencies: + detect-node-es "^1.1.0" + tslib "^2.0.0" + util-deprecate@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== -vite-tsconfig-paths@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/vite-tsconfig-paths/-/vite-tsconfig-paths-6.1.1.tgz#d5c28cba79c89ebf76489ef1040024b21df6da3a" - integrity sha512-2cihq7zliibCCZ8P9cKJrQBkfgdvcFkOOc3Y02o3GWUDLgqjWsZudaoiuOwO/gzTzy17cS5F7ZPo4bsnS4DGkg== +vite@^8.0.10: + version "8.0.10" + resolved "https://registry.yarnpkg.com/vite/-/vite-8.0.10.tgz#fb31868526ec874101fac084172a2cdc6776319b" + integrity sha512-rZuUu9j6J5uotLDs+cAA4O5H4K1SfPliUlQwqa6YEwSrWDZzP4rhm00oJR5snMewjxF5V/K3D4kctsUTsIU9Mw== dependencies: - debug "^4.1.1" - globrex "^0.1.2" - tsconfck "^3.0.3" - -vite@^7.3.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/vite/-/vite-7.3.1.tgz#7f6cfe8fb9074138605e822a75d9d30b814d6507" - integrity sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA== - dependencies: - esbuild "^0.27.0" - fdir "^6.5.0" - picomatch "^4.0.3" - postcss "^8.5.6" - rollup "^4.43.0" - tinyglobby "^0.2.15" + lightningcss "^1.32.0" + picomatch "^4.0.4" + postcss "^8.5.10" + rolldown "1.0.0-rc.17" + tinyglobby "^0.2.16" optionalDependencies: fsevents "~2.3.3" -warning@^4.0.0, warning@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" - integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== - dependencies: - loose-envify "^1.0.0" - which-boxed-primitive@^1.1.0, which-boxed-primitive@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz#d76ec27df7fa165f18d5808374a5fe23c29b176e" @@ -3216,15 +3041,6 @@ yocto-queue@^0.1.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== -youtube-player@5.5.2: - version "5.5.2" - resolved "https://registry.yarnpkg.com/youtube-player/-/youtube-player-5.5.2.tgz#052b86b1eabe21ff331095ffffeae285fa7f7cb5" - integrity sha512-ZGtsemSpXnDky2AUYWgxjaopgB+shFHgXVpiJFeNB5nWEugpW1KWYDaHKuLqh2b67r24GtP6HoSW5swvf0fFIQ== - dependencies: - debug "^2.6.6" - load-script "^1.0.0" - sister "^3.0.0" - "zod-validation-error@^3.5.0 || ^4.0.0": version "4.0.2" resolved "https://registry.yarnpkg.com/zod-validation-error/-/zod-validation-error-4.0.2.tgz#bc605eba49ce0fcd598c127fee1c236be3f22918"