diff --git a/package-lock.json b/package-lock.json index ec3fbd9..76f5425 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,7 @@ }, "devDependencies": { "@vitejs/plugin-vue": "^5.1.3", - "vite": "^5.4.3" + "vite": "^7.1.6" } }, "node_modules/@babel/helper-string-parser": { @@ -73,348 +73,419 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.10.tgz", + "integrity": "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==", "cpu": [ "ppc64" ], + "license": "MIT", "optional": true, "os": [ "aix" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.10.tgz", + "integrity": "sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==", "cpu": [ "arm" ], + "license": "MIT", "optional": true, "os": [ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.10.tgz", + "integrity": "sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.10.tgz", + "integrity": "sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.10.tgz", + "integrity": "sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.10.tgz", + "integrity": "sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.10.tgz", + "integrity": "sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.10.tgz", + "integrity": "sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.10.tgz", + "integrity": "sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==", "cpu": [ "arm" ], + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.10.tgz", + "integrity": "sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.10.tgz", + "integrity": "sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==", "cpu": [ "ia32" ], + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.10.tgz", + "integrity": "sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==", "cpu": [ "loong64" ], + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.10.tgz", + "integrity": "sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==", "cpu": [ "mips64el" ], + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.10.tgz", + "integrity": "sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==", "cpu": [ "ppc64" ], + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.10.tgz", + "integrity": "sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==", "cpu": [ "riscv64" ], + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.10.tgz", + "integrity": "sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==", "cpu": [ "s390x" ], + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.10.tgz", + "integrity": "sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.10.tgz", + "integrity": "sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==", "cpu": [ - "x64" + "arm64" ], + "license": "MIT", "optional": true, "os": [ "netbsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.10.tgz", + "integrity": "sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==", "cpu": [ "x64" ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.10.tgz", + "integrity": "sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==", + "cpu": [ + "arm64" + ], + "license": "MIT", "optional": true, "os": [ "openbsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.10.tgz", + "integrity": "sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==", "cpu": [ "x64" ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.10.tgz", + "integrity": "sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.10.tgz", + "integrity": "sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==", + "cpu": [ + "x64" + ], + "license": "MIT", "optional": true, "os": [ "sunos" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.10.tgz", + "integrity": "sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.10.tgz", + "integrity": "sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==", "cpu": [ "ia32" ], + "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.10.tgz", + "integrity": "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@floating-ui/core": { @@ -739,9 +810,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz", - "integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==", + "version": "4.50.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.50.2.tgz", + "integrity": "sha512-uLN8NAiFVIRKX9ZQha8wy6UUs06UNSZ32xj6giK/rmMXAgKahwExvK6SsmgU5/brh4w/nSgj8e0k3c1HBQpa0A==", "cpu": [ "arm" ], @@ -752,9 +823,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz", - "integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==", + "version": "4.50.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.50.2.tgz", + "integrity": "sha512-oEouqQk2/zxxj22PNcGSskya+3kV0ZKH+nQxuCCOGJ4oTXBdNTbv+f/E3c74cNLeMO1S5wVWacSws10TTSB77g==", "cpu": [ "arm64" ], @@ -765,9 +836,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz", - "integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==", + "version": "4.50.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.50.2.tgz", + "integrity": "sha512-OZuTVTpj3CDSIxmPgGH8en/XtirV5nfljHZ3wrNwvgkT5DQLhIKAeuFSiwtbMto6oVexV0k1F1zqURPKf5rI1Q==", "cpu": [ "arm64" ], @@ -778,9 +849,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz", - "integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==", + "version": "4.50.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.50.2.tgz", + "integrity": "sha512-Wa/Wn8RFkIkr1vy1k1PB//VYhLnlnn5eaJkfTQKivirOvzu5uVd2It01ukeQstMursuz7S1bU+8WW+1UPXpa8A==", "cpu": [ "x64" ], @@ -790,10 +861,36 @@ "darwin" ] }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.50.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.50.2.tgz", + "integrity": "sha512-QkzxvH3kYN9J1w7D1A+yIMdI1pPekD+pWx7G5rXgnIlQ1TVYVC6hLl7SOV9pi5q9uIDF9AuIGkuzcbF7+fAhow==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.50.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.50.2.tgz", + "integrity": "sha512-dkYXB0c2XAS3a3jmyDkX4Jk0m7gWLFzq1C3qUnJJ38AyxIF5G/dyS4N9B30nvFseCfgtCEdbYFhk0ChoCGxPog==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz", - "integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==", + "version": "4.50.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.50.2.tgz", + "integrity": "sha512-9VlPY/BN3AgbukfVHAB8zNFWB/lKEuvzRo1NKev0Po8sYFKx0i+AQlCYftgEjcL43F2h9Ui1ZSdVBc4En/sP2w==", "cpu": [ "arm" ], @@ -804,9 +901,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz", - "integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==", + "version": "4.50.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.50.2.tgz", + "integrity": "sha512-+GdKWOvsifaYNlIVf07QYan1J5F141+vGm5/Y8b9uCZnG/nxoGqgCmR24mv0koIWWuqvFYnbURRqw1lv7IBINw==", "cpu": [ "arm" ], @@ -817,9 +914,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz", - "integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==", + "version": "4.50.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.50.2.tgz", + "integrity": "sha512-df0Eou14ojtUdLQdPFnymEQteENwSJAdLf5KCDrmZNsy1c3YaCNaJvYsEUHnrg+/DLBH612/R0xd3dD03uz2dg==", "cpu": [ "arm64" ], @@ -830,9 +927,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz", - "integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==", + "version": "4.50.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.50.2.tgz", + "integrity": "sha512-iPeouV0UIDtz8j1YFR4OJ/zf7evjauqv7jQ/EFs0ClIyL+by++hiaDAfFipjOgyz6y6xbDvJuiU4HwpVMpRFDQ==", "cpu": [ "arm64" ], @@ -842,10 +939,23 @@ "linux" ] }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz", - "integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==", + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.50.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.50.2.tgz", + "integrity": "sha512-OL6KaNvBopLlj5fTa5D5bau4W82f+1TyTZRr2BdnfsrnQnmdxh4okMxR2DcDkJuh4KeoQZVuvHvzuD/lyLn2Kw==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.50.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.50.2.tgz", + "integrity": "sha512-I21VJl1w6z/K5OTRl6aS9DDsqezEZ/yKpbqlvfHbW0CEF5IL8ATBMuUx6/mp683rKTK8thjs/0BaNrZLXetLag==", "cpu": [ "ppc64" ], @@ -856,9 +966,22 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz", - "integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==", + "version": "4.50.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.50.2.tgz", + "integrity": "sha512-Hq6aQJT/qFFHrYMjS20nV+9SKrXL2lvFBENZoKfoTH2kKDOJqff5OSJr4x72ZaG/uUn+XmBnGhfr4lwMRrmqCQ==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.50.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.50.2.tgz", + "integrity": "sha512-82rBSEXRv5qtKyr0xZ/YMF531oj2AIpLZkeNYxmKNN6I2sVE9PGegN99tYDLK2fYHJITL1P2Lgb4ZXnv0PjQvw==", "cpu": [ "riscv64" ], @@ -869,9 +992,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz", - "integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==", + "version": "4.50.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.50.2.tgz", + "integrity": "sha512-4Q3S3Hy7pC6uaRo9gtXUTJ+EKo9AKs3BXKc2jYypEcMQ49gDPFU2P1ariX9SEtBzE5egIX6fSUmbmGazwBVF9w==", "cpu": [ "s390x" ], @@ -882,9 +1005,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz", - "integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==", + "version": "4.50.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.50.2.tgz", + "integrity": "sha512-9Jie/At6qk70dNIcopcL4p+1UirusEtznpNtcq/u/C5cC4HBX7qSGsYIcG6bdxj15EYWhHiu02YvmdPzylIZlA==", "cpu": [ "x64" ], @@ -895,9 +1018,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz", - "integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==", + "version": "4.50.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.50.2.tgz", + "integrity": "sha512-HPNJwxPL3EmhzeAnsWQCM3DcoqOz3/IC6de9rWfGR8ZCuEHETi9km66bH/wG3YH0V3nyzyFEGUZeL5PKyy4xvw==", "cpu": [ "x64" ], @@ -907,10 +1030,23 @@ "linux" ] }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.50.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.50.2.tgz", + "integrity": "sha512-nMKvq6FRHSzYfKLHZ+cChowlEkR2lj/V0jYj9JnGUVPL2/mIeFGmVM2mLaFeNa5Jev7W7TovXqXIG2d39y1KYA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz", - "integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==", + "version": "4.50.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.50.2.tgz", + "integrity": "sha512-eFUvvnTYEKeTyHEijQKz81bLrUQOXKZqECeiWH6tb8eXXbZk+CXSG2aFrig2BQ/pjiVRj36zysjgILkqarS2YA==", "cpu": [ "arm64" ], @@ -921,9 +1057,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz", - "integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==", + "version": "4.50.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.50.2.tgz", + "integrity": "sha512-cBaWmXqyfRhH8zmUxK3d3sAhEWLrtMjWBRwdMMHJIXSjvjLKvv49adxiEz+FJ8AP90apSDDBx2Tyd/WylV6ikA==", "cpu": [ "ia32" ], @@ -934,9 +1070,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz", - "integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==", + "version": "4.50.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.50.2.tgz", + "integrity": "sha512-APwKy6YUhvZaEoHyM+9xqmTpviEI+9eL7LoCH+aLcvWYHJ663qG5zx7WzWZY+a9qkg5JtzcMyJ9z0WtQBMDmgA==", "cpu": [ "x64" ], @@ -982,9 +1118,9 @@ } }, "node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "license": "MIT" }, "node_modules/@types/web-bluetooth": { @@ -1220,40 +1356,44 @@ } }, "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.10.tgz", + "integrity": "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==", "hasInstallScript": true, + "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, "engines": { - "node": ">=12" + "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" + "@esbuild/aix-ppc64": "0.25.10", + "@esbuild/android-arm": "0.25.10", + "@esbuild/android-arm64": "0.25.10", + "@esbuild/android-x64": "0.25.10", + "@esbuild/darwin-arm64": "0.25.10", + "@esbuild/darwin-x64": "0.25.10", + "@esbuild/freebsd-arm64": "0.25.10", + "@esbuild/freebsd-x64": "0.25.10", + "@esbuild/linux-arm": "0.25.10", + "@esbuild/linux-arm64": "0.25.10", + "@esbuild/linux-ia32": "0.25.10", + "@esbuild/linux-loong64": "0.25.10", + "@esbuild/linux-mips64el": "0.25.10", + "@esbuild/linux-ppc64": "0.25.10", + "@esbuild/linux-riscv64": "0.25.10", + "@esbuild/linux-s390x": "0.25.10", + "@esbuild/linux-x64": "0.25.10", + "@esbuild/netbsd-arm64": "0.25.10", + "@esbuild/netbsd-x64": "0.25.10", + "@esbuild/openbsd-arm64": "0.25.10", + "@esbuild/openbsd-x64": "0.25.10", + "@esbuild/openharmony-arm64": "0.25.10", + "@esbuild/sunos-x64": "0.25.10", + "@esbuild/win32-arm64": "0.25.10", + "@esbuild/win32-ia32": "0.25.10", + "@esbuild/win32-x64": "0.25.10" } }, "node_modules/estree-walker": { @@ -1262,11 +1402,29 @@ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "license": "MIT" }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -1331,6 +1489,18 @@ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "license": "ISC" }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/pinia": { "version": "2.1.7", "resolved": "https://registry.npmjs.org/pinia/-/pinia-2.1.7.tgz", @@ -1482,12 +1652,12 @@ } }, "node_modules/rollup": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.0.tgz", - "integrity": "sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==", + "version": "4.50.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.50.2.tgz", + "integrity": "sha512-BgLRGy7tNS9H66aIMASq1qSYbAAJV6Z6WR4QYTvj5FgF15rZ/ympT1uixHXwzbZUBDbkvqUI1KR0fH1FhMaQ9w==", "license": "MIT", "dependencies": { - "@types/estree": "1.0.6" + "@types/estree": "1.0.8" }, "bin": { "rollup": "dist/bin/rollup" @@ -1497,22 +1667,27 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.24.0", - "@rollup/rollup-android-arm64": "4.24.0", - "@rollup/rollup-darwin-arm64": "4.24.0", - "@rollup/rollup-darwin-x64": "4.24.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.24.0", - "@rollup/rollup-linux-arm-musleabihf": "4.24.0", - "@rollup/rollup-linux-arm64-gnu": "4.24.0", - "@rollup/rollup-linux-arm64-musl": "4.24.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.24.0", - "@rollup/rollup-linux-riscv64-gnu": "4.24.0", - "@rollup/rollup-linux-s390x-gnu": "4.24.0", - "@rollup/rollup-linux-x64-gnu": "4.24.0", - "@rollup/rollup-linux-x64-musl": "4.24.0", - "@rollup/rollup-win32-arm64-msvc": "4.24.0", - "@rollup/rollup-win32-ia32-msvc": "4.24.0", - "@rollup/rollup-win32-x64-msvc": "4.24.0", + "@rollup/rollup-android-arm-eabi": "4.50.2", + "@rollup/rollup-android-arm64": "4.50.2", + "@rollup/rollup-darwin-arm64": "4.50.2", + "@rollup/rollup-darwin-x64": "4.50.2", + "@rollup/rollup-freebsd-arm64": "4.50.2", + "@rollup/rollup-freebsd-x64": "4.50.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.50.2", + "@rollup/rollup-linux-arm-musleabihf": "4.50.2", + "@rollup/rollup-linux-arm64-gnu": "4.50.2", + "@rollup/rollup-linux-arm64-musl": "4.50.2", + "@rollup/rollup-linux-loong64-gnu": "4.50.2", + "@rollup/rollup-linux-ppc64-gnu": "4.50.2", + "@rollup/rollup-linux-riscv64-gnu": "4.50.2", + "@rollup/rollup-linux-riscv64-musl": "4.50.2", + "@rollup/rollup-linux-s390x-gnu": "4.50.2", + "@rollup/rollup-linux-x64-gnu": "4.50.2", + "@rollup/rollup-linux-x64-musl": "4.50.2", + "@rollup/rollup-openharmony-arm64": "4.50.2", + "@rollup/rollup-win32-arm64-msvc": "4.50.2", + "@rollup/rollup-win32-ia32-msvc": "4.50.2", + "@rollup/rollup-win32-x64-msvc": "4.50.2", "fsevents": "~2.3.2" } }, @@ -1537,6 +1712,22 @@ "resolved": "https://registry.npmjs.org/three/-/three-0.168.0.tgz", "integrity": "sha512-6m6jXtDwMJEK/GGMbAOTSAmxNdzKvvBzgd7q8bE/7Tr6m7PaBh5kKLrN7faWtlglXbzj7sVba48Idwx+NRsZXw==" }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -1549,20 +1740,23 @@ "integrity": "sha512-38JRbJ4Fj94VmnC7G/J/5n5SC7Ab46OM5iNtSstB/ko3l1b5g7ALt4qzHFgGciFkyiRNtDXtLNb+VsxtMSE77A==" }, "node_modules/vite": { - "version": "5.4.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.9.tgz", - "integrity": "sha512-20OVpJHh0PAM0oSOELa5GaZNWeDjcAvQjGXy2Uyr+Tp+/D2/Hdz6NLgpJLsarPTA2QJ6v8mX2P1ZfbsSKvdMkg==", + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.6.tgz", + "integrity": "sha512-SRYIB8t/isTwNn8vMB3MR6E+EQZM/WG1aKmmIUCfDXfVvKfc20ZpamngWHKzAmmu9ppsgxsg4b2I7c90JZudIQ==", "license": "MIT", "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" + "esbuild": "^0.25.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": "^20.19.0 || >=22.12.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" @@ -1571,19 +1765,25 @@ "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" }, "peerDependenciesMeta": { "@types/node": { "optional": true }, + "jiti": { + "optional": true + }, "less": { "optional": true }, @@ -1604,6 +1804,12 @@ }, "terser": { "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true } } }, diff --git a/package.json b/package.json index 99976e0..6a387f9 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,6 @@ }, "devDependencies": { "@vitejs/plugin-vue": "^5.1.3", - "vite": "^5.4.3" + "vite": "^7.1.6" } } diff --git a/public/composer.lock b/public/composer.lock index 2d2eb27..08f41ec 100644 --- a/public/composer.lock +++ b/public/composer.lock @@ -120,16 +120,16 @@ }, { "name": "composer/semver", - "version": "3.4.3", + "version": "3.4.4", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12" + "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", - "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "url": "https://api.github.com/repos/composer/semver/zipball/198166618906cb2de69b95d7d47e5fa8aa1b2b95", + "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95", "shasum": "" }, "require": { @@ -181,7 +181,7 @@ "support": { "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.4.3" + "source": "https://github.com/composer/semver/tree/3.4.4" }, "funding": [ { @@ -191,13 +191,9 @@ { "url": "https://github.com/composer", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" } ], - "time": "2024-09-19T14:15:21+00:00" + "time": "2025-08-20T19:15:30+00:00" }, { "name": "filp/whoops", @@ -272,22 +268,22 @@ }, { "name": "getkirby/cms", - "version": "5.0.4", + "version": "5.1.1", "source": { "type": "git", "url": "https://github.com/getkirby/kirby.git", - "reference": "c9708e5c648fbc3ee381114ceae8876d4ca4f9a1" + "reference": "fb11f5e3ec422e948fb1a52f16988335bb3489b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/getkirby/kirby/zipball/c9708e5c648fbc3ee381114ceae8876d4ca4f9a1", - "reference": "c9708e5c648fbc3ee381114ceae8876d4ca4f9a1", + "url": "https://api.github.com/repos/getkirby/kirby/zipball/fb11f5e3ec422e948fb1a52f16988335bb3489b4", + "reference": "fb11f5e3ec422e948fb1a52f16988335bb3489b4", "shasum": "" }, "require": { "christian-riesen/base32": "1.6.0", "claviska/simpleimage": "4.2.1", - "composer/semver": "3.4.3", + "composer/semver": "3.4.4", "ext-ctype": "*", "ext-curl": "*", "ext-dom": "*", @@ -305,9 +301,9 @@ "michelf/php-smartypants": "1.8.1", "php": "~8.2.0 || ~8.3.0 || ~8.4.0", "phpmailer/phpmailer": "6.10.0", - "symfony/polyfill-intl-idn": "1.32.0", - "symfony/polyfill-mbstring": "1.32.0", - "symfony/yaml": "7.3.2" + "symfony/polyfill-intl-idn": "1.33.0", + "symfony/polyfill-mbstring": "1.33.0", + "symfony/yaml": "7.3.3" }, "replace": { "symfony/polyfill-php72": "*" @@ -317,6 +313,7 @@ "ext-apcu": "Support for the Apcu cache driver", "ext-exif": "Support for exif information from images", "ext-fileinfo": "Improved mime type detection for files", + "ext-imagick": "Improved thumbnail generation", "ext-intl": "Improved i18n number formatting", "ext-memcached": "Support for the Memcached cache driver", "ext-redis": "Support for the Redis cache driver", @@ -372,7 +369,7 @@ "type": "custom" } ], - "time": "2025-08-19T07:39:58+00:00" + "time": "2025-09-16T13:06:53+00:00" }, { "name": "getkirby/composer-installer", @@ -935,7 +932,7 @@ }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.32.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", @@ -998,7 +995,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.32.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.33.0" }, "funding": [ { @@ -1009,6 +1006,10 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" @@ -1103,7 +1104,7 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.32.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", @@ -1164,7 +1165,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.32.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" }, "funding": [ { @@ -1175,6 +1176,10 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" @@ -1184,16 +1189,16 @@ }, { "name": "symfony/yaml", - "version": "v7.3.2", + "version": "v7.3.3", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "b8d7d868da9eb0919e99c8830431ea087d6aae30" + "reference": "d4f4a66866fe2451f61296924767280ab5732d9d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/b8d7d868da9eb0919e99c8830431ea087d6aae30", - "reference": "b8d7d868da9eb0919e99c8830431ea087d6aae30", + "url": "https://api.github.com/repos/symfony/yaml/zipball/d4f4a66866fe2451f61296924767280ab5732d9d", + "reference": "d4f4a66866fe2451f61296924767280ab5732d9d", "shasum": "" }, "require": { @@ -1236,7 +1241,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v7.3.2" + "source": "https://github.com/symfony/yaml/tree/v7.3.3" }, "funding": [ { @@ -1256,7 +1261,7 @@ "type": "tidelift" } ], - "time": "2025-07-10T08:47:49+00:00" + "time": "2025-08-27T11:34:33+00:00" } ], "packages-dev": [], diff --git a/public/kirby/cacert.pem b/public/kirby/cacert.pem index 0dee453..f04c551 100644 --- a/public/kirby/cacert.pem +++ b/public/kirby/cacert.pem @@ -1,7 +1,7 @@ ## ## Bundle of CA Root Certificates ## -## Certificate data from Mozilla as of: Tue Aug 12 03:12:01 2025 GMT +## Certificate data from Mozilla as of: Tue Sep 9 03:12:01 2025 GMT ## ## Find updated versions here: https://curl.se/docs/caextract.html ## @@ -16,7 +16,7 @@ ## Just configure this file as the SSLCACertificateFile. ## ## Conversion done with mk-ca-bundle.pl version 1.29. -## SHA256: c185b859c19b05f104c50e1b0b2a6c775149a1d9bb731d414d73b1722892a66c +## SHA256: 0078e6bdd280fd89e1b883174387aae84b3eae2ee263416a5f8a14ee7f179ae9 ## diff --git a/public/kirby/composer.json b/public/kirby/composer.json index d629846..1c4dbb9 100644 --- a/public/kirby/composer.json +++ b/public/kirby/composer.json @@ -3,7 +3,7 @@ "description": "The Kirby core", "license": "proprietary", "type": "kirby-cms", - "version": "5.0.4", + "version": "5.1.1", "keywords": [ "kirby", "cms", @@ -38,15 +38,15 @@ "ext-openssl": "*", "christian-riesen/base32": "1.6.0", "claviska/simpleimage": "4.2.1", - "composer/semver": "3.4.3", + "composer/semver": "3.4.4", "filp/whoops": "2.18.4", "getkirby/composer-installer": "^1.2.1", "laminas/laminas-escaper": "2.17.0", "michelf/php-smartypants": "1.8.1", "phpmailer/phpmailer": "6.10.0", - "symfony/polyfill-intl-idn": "1.32.0", - "symfony/polyfill-mbstring": "1.32.0", - "symfony/yaml": "7.3.2" + "symfony/polyfill-intl-idn": "1.33.0", + "symfony/polyfill-mbstring": "1.33.0", + "symfony/yaml": "7.3.3" }, "replace": { "symfony/polyfill-php72": "*" @@ -56,6 +56,7 @@ "ext-apcu": "Support for the Apcu cache driver", "ext-exif": "Support for exif information from images", "ext-fileinfo": "Improved mime type detection for files", + "ext-imagick": "Improved thumbnail generation", "ext-intl": "Improved i18n number formatting", "ext-memcached": "Support for the Memcached cache driver", "ext-redis": "Support for the Redis cache driver", diff --git a/public/kirby/composer.lock b/public/kirby/composer.lock index a9a7b86..29f7601 100644 --- a/public/kirby/composer.lock +++ b/public/kirby/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "dcb9ca6ed7a038f2028aba54fada5f7b", + "content-hash": "8d08002d38005e6ec1ff6a97deac20e2", "packages": [ { "name": "christian-riesen/base32", @@ -120,16 +120,16 @@ }, { "name": "composer/semver", - "version": "3.4.3", + "version": "3.4.4", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12" + "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", - "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "url": "https://api.github.com/repos/composer/semver/zipball/198166618906cb2de69b95d7d47e5fa8aa1b2b95", + "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95", "shasum": "" }, "require": { @@ -181,7 +181,7 @@ "support": { "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.4.3" + "source": "https://github.com/composer/semver/tree/3.4.4" }, "funding": [ { @@ -191,13 +191,9 @@ { "url": "https://github.com/composer", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" } ], - "time": "2024-09-19T14:15:21+00:00" + "time": "2025-08-20T19:15:30+00:00" }, { "name": "filp/whoops", @@ -693,7 +689,7 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.32.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", @@ -752,7 +748,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.32.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0" }, "funding": [ { @@ -763,6 +759,10 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" @@ -772,7 +772,7 @@ }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.32.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", @@ -835,7 +835,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.32.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.33.0" }, "funding": [ { @@ -846,6 +846,10 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" @@ -855,7 +859,7 @@ }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.32.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", @@ -916,7 +920,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.32.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0" }, "funding": [ { @@ -927,6 +931,10 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" @@ -936,7 +944,7 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.32.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", @@ -997,7 +1005,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.32.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" }, "funding": [ { @@ -1008,6 +1016,10 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" @@ -1017,16 +1029,16 @@ }, { "name": "symfony/yaml", - "version": "v7.3.2", + "version": "v7.3.3", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "b8d7d868da9eb0919e99c8830431ea087d6aae30" + "reference": "d4f4a66866fe2451f61296924767280ab5732d9d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/b8d7d868da9eb0919e99c8830431ea087d6aae30", - "reference": "b8d7d868da9eb0919e99c8830431ea087d6aae30", + "url": "https://api.github.com/repos/symfony/yaml/zipball/d4f4a66866fe2451f61296924767280ab5732d9d", + "reference": "d4f4a66866fe2451f61296924767280ab5732d9d", "shasum": "" }, "require": { @@ -1069,7 +1081,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v7.3.2" + "source": "https://github.com/symfony/yaml/tree/v7.3.3" }, "funding": [ { @@ -1089,7 +1101,7 @@ "type": "tidelift" } ], - "time": "2025-07-10T08:47:49+00:00" + "time": "2025-08-27T11:34:33+00:00" } ], "packages-dev": [], diff --git a/public/kirby/config/areas/account/dialogs.php b/public/kirby/config/areas/account/dialogs.php index eef1440..fbdf0e8 100644 --- a/public/kirby/config/areas/account/dialogs.php +++ b/public/kirby/config/areas/account/dialogs.php @@ -5,101 +5,61 @@ use Kirby\Panel\UserTotpEnableDialog; $dialogs = require __DIR__ . '/../users/dialogs.php'; return [ - // change email 'account.changeEmail' => [ + ...$dialogs['user.changeEmail'], 'pattern' => '(account)/changeEmail', - 'load' => $dialogs['user.changeEmail']['load'], - 'submit' => $dialogs['user.changeEmail']['submit'], ], - - // change language 'account.changeLanguage' => [ + ...$dialogs['user.changeLanguage'], 'pattern' => '(account)/changeLanguage', - 'load' => $dialogs['user.changeLanguage']['load'], - 'submit' => $dialogs['user.changeLanguage']['submit'], ], - - // change name 'account.changeName' => [ + ...$dialogs['user.changeName'], 'pattern' => '(account)/changeName', - 'load' => $dialogs['user.changeName']['load'], - 'submit' => $dialogs['user.changeName']['submit'], ], - - // change password 'account.changePassword' => [ + ...$dialogs['user.changePassword'], 'pattern' => '(account)/changePassword', - 'load' => $dialogs['user.changePassword']['load'], - 'submit' => $dialogs['user.changePassword']['submit'], ], - - // change role 'account.changeRole' => [ + ...$dialogs['user.changeRole'], 'pattern' => '(account)/changeRole', - 'load' => $dialogs['user.changeRole']['load'], - 'submit' => $dialogs['user.changeRole']['submit'], ], - - // delete 'account.delete' => [ + ...$dialogs['user.delete'], 'pattern' => '(account)/delete', - 'load' => $dialogs['user.delete']['load'], - 'submit' => $dialogs['user.delete']['submit'], ], - - // account fields dialogs 'account.fields' => [ - 'pattern' => '(account)/files/(:any)/fields/(:any)/(:all?)', - 'load' => $dialogs['user.fields']['load'], - 'submit' => $dialogs['user.fields']['submit'] + ...$dialogs['user.fields'], + 'pattern' => '(account)/fields/(:any)/(:all?)', ], - - // change file name 'account.file.changeName' => [ + ...$dialogs['user.file.changeName'], 'pattern' => '(account)/files/(:any)/changeName', - 'load' => $dialogs['user.file.changeName']['load'], - 'submit' => $dialogs['user.file.changeName']['submit'], ], - - // change file sort 'account.file.changeSort' => [ + ...$dialogs['user.file.changeSort'], 'pattern' => '(account)/files/(:any)/changeSort', - 'load' => $dialogs['user.file.changeSort']['load'], - 'submit' => $dialogs['user.file.changeSort']['submit'], ], - - // change file template 'account.file.changeTemplate' => [ + ...$dialogs['user.file.changeTemplate'], 'pattern' => '(account)/files/(:any)/changeTemplate', - 'load' => $dialogs['user.file.changeTemplate']['load'], - 'submit' => $dialogs['user.file.changeTemplate']['submit'], ], - - // delete 'account.file.delete' => [ + ...$dialogs['user.file.delete'], 'pattern' => '(account)/files/(:any)/delete', - 'load' => $dialogs['user.file.delete']['load'], - 'submit' => $dialogs['user.file.delete']['submit'], ], - - // account file fields dialogs 'account.file.fields' => [ + ...$dialogs['user.file.fields'], 'pattern' => '(account)/files/(:any)/fields/(:any)/(:all?)', - 'load' => $dialogs['user.file.fields']['load'], - 'submit' => $dialogs['user.file.fields']['submit'] ], - - // account enable TOTP 'account.totp.enable' => [ 'pattern' => '(account)/totp/enable', 'load' => fn () => (new UserTotpEnableDialog())->load(), 'submit' => fn () => (new UserTotpEnableDialog())->submit() ], - - // account disable TOTP 'account.totp.disable' => [ 'pattern' => '(account)/totp/disable', - 'load' => $dialogs['user.totp.disable']['load'], - 'submit' => $dialogs['user.totp.disable']['submit'] + ...$dialogs['user.totp.disable'], ], ]; diff --git a/public/kirby/config/areas/account/drawers.php b/public/kirby/config/areas/account/drawers.php index 01bb0b6..714d6c5 100644 --- a/public/kirby/config/areas/account/drawers.php +++ b/public/kirby/config/areas/account/drawers.php @@ -3,17 +3,12 @@ $drawers = require __DIR__ . '/../users/drawers.php'; return [ - // account fields drawers 'account.fields' => [ - 'pattern' => '(account)/files/(:any)/fields/(:any)/(:all?)', - 'load' => $drawers['user.fields']['load'], - 'submit' => $drawers['user.fields']['submit'] + ...$drawers['user.fields'], + 'pattern' => '(account)/fields/(:any)/(:all?)', ], - - // account file fields drawers 'account.file.fields' => [ + ...$drawers['user.file.fields'], 'pattern' => '(account)/files/(:any)/fields/(:any)/(:all?)', - 'load' => $drawers['user.file.fields']['load'], - 'submit' => $drawers['user.file.fields']['submit'] ], ]; diff --git a/public/kirby/config/areas/account/dropdowns.php b/public/kirby/config/areas/account/dropdowns.php index 6d115d5..6011c30 100644 --- a/public/kirby/config/areas/account/dropdowns.php +++ b/public/kirby/config/areas/account/dropdowns.php @@ -4,19 +4,19 @@ $dropdowns = require __DIR__ . '/../users/dropdowns.php'; return [ 'account' => [ + ...$dropdowns['user'], 'pattern' => '(account)', - 'options' => $dropdowns['user']['options'] ], 'account.languages' => [ + ...$dropdowns['user.languages'], 'pattern' => '(account)/languages', - 'options' => $dropdowns['user.languages']['options'] ], 'account.file' => [ + ...$dropdowns['user.file'], 'pattern' => '(account)/files/(:any)', - 'options' => $dropdowns['user.file']['options'] ], 'account.file.languages' => [ + ...$dropdowns['user.file.languages'], 'pattern' => '(account)/files/(:any)/languages', - 'options' => $files['language'] ] ]; diff --git a/public/kirby/config/areas/lab/drawers.php b/public/kirby/config/areas/lab/drawers.php index d1e515b..eea790d 100644 --- a/public/kirby/config/areas/lab/drawers.php +++ b/public/kirby/config/areas/lab/drawers.php @@ -16,12 +16,14 @@ return [ ]; } + $doc = Doc::factory($component); + return [ 'component' => 'k-lab-docs-drawer', 'props' => [ 'icon' => 'book', 'title' => $component, - 'docs' => Doc::factory($component)->toArray() + 'docs' => $doc->toArray() ] ]; }, diff --git a/public/kirby/config/areas/site/dialogs.php b/public/kirby/config/areas/site/dialogs.php index 6b2a881..c9033c9 100644 --- a/public/kirby/config/areas/site/dialogs.php +++ b/public/kirby/config/areas/site/dialogs.php @@ -20,8 +20,6 @@ $fields = require __DIR__ . '/../fields/dialogs.php'; $files = require __DIR__ . '/../files/dialogs.php'; return [ - - // change page position 'page.changeSort' => [ 'pattern' => 'pages/(:any)/changeSort', 'load' => function (string $id) { @@ -61,7 +59,6 @@ return [ } ], - // change page status 'page.changeStatus' => [ 'pattern' => 'pages/(:any)/changeStatus', 'load' => function (string $id) { @@ -140,7 +137,6 @@ return [ } ], - // change template 'page.changeTemplate' => [ 'pattern' => 'pages/(:any)/changeTemplate', 'load' => function (string $id) { @@ -187,7 +183,6 @@ return [ } ], - // change title 'page.changeTitle' => [ 'pattern' => 'pages/(:any)/changeTitle', 'load' => function (string $id) { @@ -282,7 +277,6 @@ return [ } ], - // create a new page 'page.create' => [ 'pattern' => 'pages/create', 'load' => function () { @@ -293,6 +287,7 @@ return [ slug: $request->get('slug'), template: $request->get('template'), title: $request->get('title'), + uuid: $request->get('uuid'), viewId: $request->get('view'), ); @@ -306,6 +301,7 @@ return [ slug: $request->get('slug'), template: $request->get('template'), title: $request->get('title'), + uuid: $request->get('uuid'), viewId: $request->get('view'), ); @@ -313,7 +309,6 @@ return [ } ], - // delete page 'page.delete' => [ 'pattern' => 'pages/(:any)/delete', 'load' => function (string $id) { @@ -385,7 +380,6 @@ return [ } ], - // duplicate page 'page.duplicate' => [ 'pattern' => 'pages/(:any)/duplicate', 'load' => function (string $id) { @@ -474,49 +468,31 @@ return [ } ], - // page field dialogs 'page.fields' => [ - 'pattern' => '(pages/.*?)/fields/(:any)/(:all?)', - 'load' => $fields['model']['load'], - 'submit' => $fields['model']['submit'] + ...$fields['model'], + 'pattern' => '(pages/[^/]+)/fields/(:any)/(:all?)', ], - - // change filename 'page.file.changeName' => [ - 'pattern' => '(pages/.*?)/files/(:any)/changeName', - 'load' => $files['changeName']['load'], - 'submit' => $files['changeName']['submit'], + ...$files['changeName'], + 'pattern' => '(pages/[^/]+)/files/(:any)/changeName', ], - - // change sort 'page.file.changeSort' => [ - 'pattern' => '(pages/.*?)/files/(:any)/changeSort', - 'load' => $files['changeSort']['load'], - 'submit' => $files['changeSort']['submit'], + ...$files['changeSort'], + 'pattern' => '(pages/[^/]+)/files/(:any)/changeSort', ], - - // change template 'page.file.changeTemplate' => [ - 'pattern' => '(pages/.*?)/files/(:any)/changeTemplate', - 'load' => $files['changeTemplate']['load'], - 'submit' => $files['changeTemplate']['submit'], + ...$files['changeTemplate'], + 'pattern' => '(pages/[^/]+)/files/(:any)/changeTemplate', ], - - // delete 'page.file.delete' => [ - 'pattern' => '(pages/.*?)/files/(:any)/delete', - 'load' => $files['delete']['load'], - 'submit' => $files['delete']['submit'], + ...$files['delete'], + 'pattern' => '(pages/[^/]+)/files/(:any)/delete', ], - - // page file field dialogs 'page.file.fields' => [ - 'pattern' => '(pages/.*?)/files/(:any)/fields/(:any)/(:all?)', - 'load' => $fields['file']['load'], - 'submit' => $fields['file']['submit'], + ...$fields['file'], + 'pattern' => '(pages/[^/]+)/files/(:any)/fields/(:any)/(:all?)', ], - // move page 'page.move' => [ 'pattern' => 'pages/(:any)/move', 'load' => function (string $id) { @@ -553,7 +529,6 @@ return [ } ], - // change site title 'site.changeTitle' => [ 'pattern' => 'site/changeTitle', 'load' => function () { @@ -583,49 +558,31 @@ return [ } ], - // site field dialogs 'site.fields' => [ + ...$fields['model'], 'pattern' => '(site)/fields/(:any)/(:all?)', - 'load' => $fields['model']['load'], - 'submit' => $fields['model']['submit'], ], - - // change filename 'site.file.changeName' => [ + ...$files['changeName'], 'pattern' => '(site)/files/(:any)/changeName', - 'load' => $files['changeName']['load'], - 'submit' => $files['changeName']['submit'], ], - - // change sort 'site.file.changeSort' => [ + ...$files['changeSort'], 'pattern' => '(site)/files/(:any)/changeSort', - 'load' => $files['changeSort']['load'], - 'submit' => $files['changeSort']['submit'], ], - - // change template 'site.file.changeTemplate' => [ + ...$files['changeTemplate'], 'pattern' => '(site)/files/(:any)/changeTemplate', - 'load' => $files['changeTemplate']['load'], - 'submit' => $files['changeTemplate']['submit'], ], - - // delete 'site.file.delete' => [ + ...$files['delete'], 'pattern' => '(site)/files/(:any)/delete', - 'load' => $files['delete']['load'], - 'submit' => $files['delete']['submit'], ], - - // site file field dialogs 'site.file.fields' => [ + ...$fields['file'], 'pattern' => '(site)/files/(:any)/fields/(:any)/(:all?)', - 'load' => $fields['file']['load'], - 'submit' => $fields['file']['submit'], ], - // content changes 'changes' => [ 'pattern' => 'changes', 'load' => function () { diff --git a/public/kirby/config/areas/site/drawers.php b/public/kirby/config/areas/site/drawers.php index 7bdf4da..86d2162 100644 --- a/public/kirby/config/areas/site/drawers.php +++ b/public/kirby/config/areas/site/drawers.php @@ -3,31 +3,20 @@ $fields = require __DIR__ . '/../fields/drawers.php'; return [ - // page field drawers 'page.fields' => [ - 'pattern' => '(pages/.*?)/fields/(:any)/(:all?)', - 'load' => $fields['model']['load'], - 'submit' => $fields['model']['submit'] + ...$fields['model'], + 'pattern' => '(pages/[^/]+)/fields/(:any)/(:all?)', ], - - // page file field drawers 'page.file.fields' => [ - 'pattern' => '(pages/.*?)/files/(:any)/fields/(:any)/(:all?)', - 'load' => $fields['file']['load'], - 'submit' => $fields['file']['submit'], + ...$fields['file'], + 'pattern' => '(pages/[^/]+)/files/(:any)/fields/(:any)/(:all?)', ], - - // site field drawers 'site.fields' => [ + ...$fields['model'], 'pattern' => '(site)/fields/(:any)/(:all?)', - 'load' => $fields['model']['load'], - 'submit' => $fields['model']['submit'], ], - - // site file field drawers 'site.file.fields' => [ + ...$fields['file'], 'pattern' => '(site)/files/(:any)/fields/(:any)/(:all?)', - 'load' => $fields['file']['load'], - 'submit' => $fields['file']['submit'], ], ]; diff --git a/public/kirby/config/areas/site/dropdowns.php b/public/kirby/config/areas/site/dropdowns.php index 207e028..363b4b0 100644 --- a/public/kirby/config/areas/site/dropdowns.php +++ b/public/kirby/config/areas/site/dropdowns.php @@ -21,11 +21,11 @@ return [ } ], 'page.file' => [ - 'pattern' => '(pages/.*?)/files/(:any)', + 'pattern' => '(pages/[^/]+)/files/(:any)', 'options' => $files['file'] ], 'page.file.languages' => [ - 'pattern' => '(pages/.*?)/files/(:any)/languages', + 'pattern' => '(pages/[^/]+)/files/(:any)/languages', 'options' => $files['language'] ], 'site.languages' => [ diff --git a/public/kirby/config/areas/system/dialogs.php b/public/kirby/config/areas/system/dialogs.php index db8b7a5..8421a5f 100644 --- a/public/kirby/config/areas/system/dialogs.php +++ b/public/kirby/config/areas/system/dialogs.php @@ -57,6 +57,28 @@ return [ // @codeCoverageIgnoreEnd } ], + 'license/remove' => [ + 'load' => function () { + return [ + 'component' => 'k-remove-dialog', + 'props' => [ + 'text' => I18n::translate('license.remove.text'), + 'size' => 'medium', + 'submitButton' => [ + 'icon' => 'trash', + 'text' => I18n::translate('remove'), + 'theme' => 'negative', + ], + ] + ]; + }, + 'submit' => function () { + // @codeCoverageIgnoreStart + App::instance()->system()->license()->delete(); + return true; + // @codeCoverageIgnoreEnd + } + ], // license registration 'registration' => [ 'load' => function () { diff --git a/public/kirby/config/areas/users/dialogs.php b/public/kirby/config/areas/users/dialogs.php index 555d38d..afadefc 100644 --- a/public/kirby/config/areas/users/dialogs.php +++ b/public/kirby/config/areas/users/dialogs.php @@ -15,8 +15,6 @@ $fields = require __DIR__ . '/../fields/dialogs.php'; $files = require __DIR__ . '/../files/dialogs.php'; return [ - - // create 'user.create' => [ 'pattern' => 'users/create', 'load' => function () { @@ -79,7 +77,6 @@ return [ } ], - // change email 'user.changeEmail' => [ 'pattern' => 'users/(:any)/changeEmail', 'load' => function (string $id) { @@ -114,7 +111,6 @@ return [ } ], - // change language 'user.changeLanguage' => [ 'pattern' => 'users/(:any)/changeLanguage', 'load' => function (string $id) { @@ -147,7 +143,6 @@ return [ } ], - // change name 'user.changeName' => [ 'pattern' => 'users/(:any)/changeName', 'load' => function (string $id) { @@ -179,7 +174,6 @@ return [ } ], - // change password 'user.changePassword' => [ 'pattern' => 'users/(:any)/changePassword', 'load' => function (string $id) { @@ -245,7 +239,6 @@ return [ } ], - // change role 'user.changeRole' => [ 'pattern' => 'users/(:any)/changeRole', 'load' => function (string $id) { @@ -282,7 +275,6 @@ return [ } ], - // delete 'user.delete' => [ 'pattern' => 'users/(:any)/delete', 'load' => function (string $id) { @@ -324,49 +316,36 @@ return [ } ], - // user field dialogs 'user.fields' => [ - 'pattern' => '(users/.*?)/fields/(:any)/(:all?)', - 'load' => $fields['model']['load'], - 'submit' => $fields['model']['submit'] + ...$fields['model'], + 'pattern' => '(users/[^/]+)/fields/(:any)/(:all?)', ], - // change file name 'user.file.changeName' => [ - 'pattern' => '(users/.*?)/files/(:any)/changeName', - 'load' => $files['changeName']['load'], - 'submit' => $files['changeName']['submit'], + ...$files['changeName'], + 'pattern' => '(users/[^/]+)/files/(:any)/changeName', ], - // change file sort 'user.file.changeSort' => [ - 'pattern' => '(users/.*?)/files/(:any)/changeSort', - 'load' => $files['changeSort']['load'], - 'submit' => $files['changeSort']['submit'], + ...$files['changeSort'], + 'pattern' => '(users/[^/]+)/files/(:any)/changeSort', ], - // change file template 'user.file.changeTemplate' => [ - 'pattern' => '(users/.*?)/files/(:any)/changeTemplate', - 'load' => $files['changeTemplate']['load'], - 'submit' => $files['changeTemplate']['submit'], + ...$files['changeTemplate'], + 'pattern' => '(users/[^/]+)/files/(:any)/changeTemplate', ], - // delete file 'user.file.delete' => [ - 'pattern' => '(users/.*?)/files/(:any)/delete', - 'load' => $files['delete']['load'], - 'submit' => $files['delete']['submit'], + ...$files['delete'], + 'pattern' => '(users/[^/]+)/files/(:any)/delete', ], - // user file fields dialogs 'user.file.fields' => [ - 'pattern' => '(users/.*?)/files/(:any)/fields/(:any)/(:all?)', - 'load' => $fields['file']['load'], - 'submit' => $fields['file']['submit'] + ...$fields['file'], + 'pattern' => '(users/[^/]+)/files/(:any)/fields/(:any)/(:all?)', ], - // user disable TOTP 'user.totp.disable' => [ 'pattern' => 'users/(:any)/totp/disable', 'load' => fn (string $id) => (new UserTotpDisableDialog($id))->load(), diff --git a/public/kirby/config/areas/users/drawers.php b/public/kirby/config/areas/users/drawers.php index 10d6bd1..de1f9e8 100644 --- a/public/kirby/config/areas/users/drawers.php +++ b/public/kirby/config/areas/users/drawers.php @@ -3,16 +3,12 @@ $fields = require __DIR__ . '/../fields/drawers.php'; return [ - // user field drawers 'user.fields' => [ - 'pattern' => '(users/.*?)/fields/(:any)/(:all?)', - 'load' => $fields['model']['load'], - 'submit' => $fields['model']['submit'] + ...$fields['model'], + 'pattern' => '(users/[^/]+)/fields/(:any)/(:all?)', ], - // user file fields drawers 'user.file.fields' => [ - 'pattern' => '(users/.*?)/files/(:any)/fields/(:any)/(:all?)', - 'load' => $fields['file']['load'], - 'submit' => $fields['file']['submit'] + ...$fields['file'], + 'pattern' => '(users/[^/]+)/files/(:any)/fields/(:any)/(:all?)', ], ]; diff --git a/public/kirby/config/areas/users/dropdowns.php b/public/kirby/config/areas/users/dropdowns.php index d3d2569..6ab5556 100644 --- a/public/kirby/config/areas/users/dropdowns.php +++ b/public/kirby/config/areas/users/dropdowns.php @@ -19,11 +19,11 @@ return [ } ], 'user.file' => [ - 'pattern' => '(users/.*?)/files/(:any)', + 'pattern' => '(users/[^/]+)/files/(:any)', 'options' => $files['file'] ], 'user.file.languages' => [ - 'pattern' => '(users/.*?)/files/(:any)/languages', + 'pattern' => '(users/[^/]+)/files/(:any)/languages', 'options' => $files['language'] ] ]; diff --git a/public/kirby/config/areas/users/views.php b/public/kirby/config/areas/users/views.php index cf4cb7e..1f99eda 100644 --- a/public/kirby/config/areas/users/views.php +++ b/public/kirby/config/areas/users/views.php @@ -2,8 +2,9 @@ use Kirby\Cms\App; use Kirby\Cms\Find; +use Kirby\Panel\Collector\UsersCollector; use Kirby\Panel\Ui\Buttons\ViewButtons; -use Kirby\Toolkit\Escape; +use Kirby\Panel\Ui\Item\UserItem; return [ 'users' => [ @@ -31,29 +32,17 @@ return [ }, 'roles' => array_values($roles), 'users' => function () use ($kirby, $role) { - $users = $kirby->users(); + $collector = new UsersCollector( + limit: 20, + page: $kirby->request()->get('page', 1), + role: $role, + sortBy: 'username asc', + ); - if (empty($role) === false) { - $users = $users->role($role); - } - - // sort users alphabetically - $users = $users->sortBy('username', 'asc'); - - // paginate - $users = $users->paginate([ - 'limit' => 20, - 'page' => $kirby->request()->get('page') - ]); + $users = $collector->models(paginated: true); return [ - 'data' => $users->values(fn ($user) => [ - 'id' => $user->id(), - 'image' => $user->panel()->image(), - 'info' => Escape::html($user->role()->title()), - 'link' => $user->panel()->url(true), - 'text' => Escape::html($user->username()) - ]), + 'data' => $users->values(fn ($user) => (new UserItem(user: $user))->props()), 'pagination' => $users->pagination()->toArray() ]; }, diff --git a/public/kirby/config/components.php b/public/kirby/config/components.php index f95ecfa..012e084 100644 --- a/public/kirby/config/components.php +++ b/public/kirby/config/components.php @@ -421,10 +421,7 @@ return [ // support UUIDs if ( $path !== null && - ( - Uuid::is($path, 'page') === true || - Uuid::is($path, 'file') === true - ) + Uuid::is($path, ['page', 'file']) === true ) { $model = Uuid::for($path)->model(); diff --git a/public/kirby/config/fields/object.php b/public/kirby/config/fields/object.php index d795d28..f10516f 100644 --- a/public/kirby/config/fields/object.php +++ b/public/kirby/config/fields/object.php @@ -50,7 +50,7 @@ return [ return []; } - return $this->form()->fields()->toArray(); + return $this->form()->fields()->toProps(); }, 'value' => function () { $data = Data::decode($this->value, 'yaml'); diff --git a/public/kirby/config/fields/structure.php b/public/kirby/config/fields/structure.php index 3fb05d2..1b6ede0 100644 --- a/public/kirby/config/fields/structure.php +++ b/public/kirby/config/fields/structure.php @@ -19,6 +19,13 @@ return [ 'icon' => null, 'placeholder' => null, + /** + * Whether to enable batch editing + */ + 'batch' => function (bool $batch = false) { + return $batch; + }, + /** * Optional columns definition to only show selected fields in the structure table. */ @@ -105,7 +112,7 @@ return [ return []; } - return $this->form()->fields()->toArray(); + return $this->form()->fields()->toProps(); }, 'columns' => function () { $columns = []; diff --git a/public/kirby/config/fields/users.php b/public/kirby/config/fields/users.php index f30f6ab..4533bba 100644 --- a/public/kirby/config/fields/users.php +++ b/public/kirby/config/fields/users.php @@ -63,12 +63,12 @@ return [ $users = []; $kirby = App::instance(); - foreach (Data::decode($value, 'yaml') as $email) { - if (is_array($email) === true) { - $email = $email['email'] ?? null; + foreach (Data::decode($value, 'yaml') as $id) { + if (is_array($id) === true) { + $id = $id['uuid'] ?? $id['id'] ?? $id['email'] ?? null; } - if ($email !== null && ($user = $kirby->user($email))) { + if ($id !== null && ($user = $kirby->user($id))) { $users[] = $this->userResponse($user); } } diff --git a/public/kirby/config/sections/files.php b/public/kirby/config/sections/files.php index 254e684..b362849 100644 --- a/public/kirby/config/sections/files.php +++ b/public/kirby/config/sections/files.php @@ -1,7 +1,9 @@ function () { return $this->parentModel(); }, + 'collector' => function () { + return $this->collector ??= new FilesCollector( + flip: $this->flip(), + limit: $this->limit(), + page: $this->page() ?? 1, + parent: $this->parent(), + query: $this->query(), + search: $this->searchterm(), + sortBy: $this->sortBy(), + template: $this->template(), + ); + }, 'models' => function () { - if ($this->query !== null) { - $files = $this->parent->query($this->query, Files::class) ?? new Files([]); - } else { - $files = $this->parent->files(); - } - - // filter files by template - $files = $files->template($this->template); - - // filter out all protected and hidden files - $files = $files->filter('isListable', true); - - // search - if ($this->search === true && empty($this->searchterm()) === false) { - $files = $files->search($this->searchterm()); - - // disable flip and sortBy while searching - // to show most relevant results - $this->flip = false; - $this->sortBy = null; - } - - // sort - if ($this->sortBy) { - $files = $files->sort(...$files::sortArgs($this->sortBy)); - } else { - $files = $files->sorted(); - } - - // flip - if ($this->flip === true) { - $files = $files->flip(); - } - - return $files; + return $this->collector()->models(); }, 'modelsPaginated' => function () { - // apply the default pagination - return $this->models()->paginate([ - 'page' => $this->page, - 'limit' => $this->limit, - 'method' => 'none' // the page is manually provided - ]); + return $this->collector()->models(paginated: true); }, 'files' => function () { return $this->models; }, 'data' => function () { - $data = []; + $data = []; + $dragTextIsAbsolute = $this->model->is($this->parent) === false; foreach ($this->modelsPaginated() as $file) { - $panel = $file->panel(); - $permissions = $file->permissions(); - - $item = [ - 'dragText' => $panel->dragText( - // the drag text needs to be absolute - // when the files come from a different parent model - absolute: $this->model->is($this->parent) === false - ), - 'extension' => $file->extension(), - 'filename' => $file->filename(), - 'id' => $file->id(), - 'image' => $panel->image( - $this->image, - $this->layout === 'table' ? 'list' : $this->layout - ), - 'info' => $file->toSafeString($this->info ?? false), - 'link' => $panel->url(true), - 'mime' => $file->mime(), - 'parent' => $file->parent()->panel()->path(), - 'permissions' => [ - 'delete' => $permissions->can('delete'), - 'sort' => $permissions->can('sort'), - ], - 'template' => $file->template(), - 'text' => $file->toSafeString($this->text), - 'url' => $file->url(), - ]; + $item = (new FileItem( + file: $file, + dragTextIsAbsolute: $dragTextIsAbsolute, + image: $this->image, + layout: $this->layout, + info: $this->info, + text: $this->text, + ))->props(); if ($this->layout === 'table') { $item = $this->columnsValues($item, $file); @@ -185,26 +141,16 @@ return [ return false; } - // count all uploaded files - $max = $this->max ? $this->max - $this->total : null; - $multiple = !$max || $max > 1; - $template = $this->template === 'default' ? null : $this->template; + $settings = new Upload( + api: $this->parent->apiUrl(true) . '/files', + accept: $this->accept, + max: $this->max ? $this->max - $this->total : null, + preview: $this->image, + sort: $this->sortable === true ? $this->total + 1 : null, + template: $this->template, + ); - return [ - 'accept' => $this->accept, - 'multiple' => $multiple, - 'max' => $max, - 'api' => $this->parent->apiUrl(true) . '/files', - 'preview' => $this->image, - 'attributes' => [ - // TODO: an edge issue that needs to be solved: - // if multiple users load the same section - // at the same time and upload a file, - // uploaded files have the same sort number - 'sort' => $this->sortable === true ? $this->total + 1 : null, - 'template' => $template - ] - ]; + return $settings->props(); } ], // @codeCoverageIgnoreStart diff --git a/public/kirby/config/sections/mixins/search.php b/public/kirby/config/sections/mixins/search.php index 0791152..05fb50f 100644 --- a/public/kirby/config/sections/mixins/search.php +++ b/public/kirby/config/sections/mixins/search.php @@ -13,7 +13,11 @@ return [ ], 'methods' => [ 'searchterm' => function (): string|null { - return App::instance()->request()->get('searchterm'); + if ($this->search() === true) { + return App::instance()->request()->get('searchterm') ?? null; + } + + return null; } ] ]; diff --git a/public/kirby/config/sections/pages.php b/public/kirby/config/sections/pages.php index fe3d47c..cfa39aa 100644 --- a/public/kirby/config/sections/pages.php +++ b/public/kirby/config/sections/pages.php @@ -5,6 +5,8 @@ use Kirby\Cms\Page; use Kirby\Cms\Pages; use Kirby\Cms\Site; use Kirby\Exception\InvalidArgumentException; +use Kirby\Panel\Collector\PagesCollector; +use Kirby\Panel\Ui\Item\PageItem; use Kirby\Toolkit\A; use Kirby\Toolkit\I18n; @@ -85,83 +87,28 @@ return [ return $parent; }, + 'collector' => function () { + return $this->collector ??= new PagesCollector( + limit: $this->limit(), + page: $this->page() ?? 1, + parent: $this->parent(), + query: $this->query(), + status: $this->status(), + templates: $this->templates(), + templatesIgnore: $this->templatesIgnore(), + search: $this->searchterm(), + sortBy: $this->sortBy(), + flip: $this->flip() + ); + }, 'models' => function () { - if ($this->query !== null) { - $pages = $this->parent->query($this->query, Pages::class) ?? new Pages([]); - } else { - $pages = match ($this->status) { - 'draft' => $this->parent->drafts(), - 'listed' => $this->parent->children()->listed(), - 'published' => $this->parent->children(), - 'unlisted' => $this->parent->children()->unlisted(), - default => $this->parent->childrenAndDrafts() - }; - } - - // filters pages that are protected and not in the templates list - // internal `filter()` method used instead of foreach loop that previously included `unset()` - // because `unset()` is updating the original data, `filter()` is just filtering - // also it has been tested that there is no performance difference - // even in 0.1 seconds on 100k virtual pages - $pages = $pages->filter(function ($page) { - // remove all protected and hidden pages - if ($page->isListable() === false) { - return false; - } - - $intendedTemplate = $page->intendedTemplate()->name(); - - // filter by all set templates - if ( - $this->templates && - in_array($intendedTemplate, $this->templates, true) === false - ) { - return false; - } - - // exclude by all ignored templates - if ( - $this->templatesIgnore && - in_array($intendedTemplate, $this->templatesIgnore, true) === true - ) { - return false; - } - - return true; - }); - - // search - if ($this->search === true && empty($this->searchterm()) === false) { - $pages = $pages->search($this->searchterm()); - - // disable flip and sortBy while searching - // to show most relevant results - $this->flip = false; - $this->sortBy = null; - } - - // sort - if ($this->sortBy) { - $pages = $pages->sort(...$pages::sortArgs($this->sortBy)); - } - - // flip - if ($this->flip === true) { - $pages = $pages->flip(); - } - - return $pages; + return $this->collector()->models(); }, 'modelsPaginated' => function () { - // pagination - return $this->models()->paginate([ - 'page' => $this->page, - 'limit' => $this->limit, - 'method' => 'none' // the page is manually provided - ]); + return $this->collector()->models(paginated: true); }, 'pages' => function () { - return $this->models; + return $this->models(); }, 'total' => function () { return $this->models()->count(); @@ -170,30 +117,13 @@ return [ $data = []; foreach ($this->modelsPaginated() as $page) { - $panel = $page->panel(); - $permissions = $page->permissions(); - - $item = [ - 'dragText' => $panel->dragText(), - 'id' => $page->id(), - 'image' => $panel->image( - $this->image, - $this->layout === 'table' ? 'list' : $this->layout - ), - 'info' => $page->toSafeString($this->info ?? false), - 'link' => $panel->url(true), - 'parent' => $page->parentId(), - 'permissions' => [ - 'delete' => $permissions->can('delete'), - 'changeSlug' => $permissions->can('changeSlug'), - 'changeStatus' => $permissions->can('changeStatus'), - 'changeTitle' => $permissions->can('changeTitle'), - 'sort' => $permissions->can('sort'), - ], - 'status' => $page->status(), - 'template' => $page->intendedTemplate()->name(), - 'text' => $page->toSafeString($this->text), - ]; + $item = (new PageItem( + page: $page, + image: $this->image, + layout: $this->layout, + info: $this->info, + text: $this->text, + ))->props(); if ($this->layout === 'table') { $item = $this->columnsValues($item, $page); diff --git a/public/kirby/config/sections/stats.php b/public/kirby/config/sections/stats.php index 86efe96..f5e06fd 100644 --- a/public/kirby/config/sections/stats.php +++ b/public/kirby/config/sections/stats.php @@ -1,6 +1,6 @@ [ @@ -10,20 +10,8 @@ return [ /** * Array or query string for reports. Each report needs a `label` and `value` and can have additional `info`, `link`, `icon` and `theme` settings. */ - 'reports' => function ($reports = null) { - if ($reports === null) { - return []; - } - - if (is_string($reports) === true) { - $reports = $this->model()->query($reports); - } - - if (is_array($reports) === false) { - return []; - } - - return $reports; + 'reports' => function (array|string|null $reports = null) { + return $reports ?? []; }, /** * The size of the report cards. Available sizes: `tiny`, `small`, `medium`, `large` @@ -33,36 +21,18 @@ return [ } ], 'computed' => [ - 'reports' => function () { - $reports = []; - $model = $this->model(); - $toString = fn ($value) => $value === null ? null : $model->toString($value); - - foreach ($this->reports as $report) { - if (is_string($report) === true) { - $report = $model->query($report); - } - - if (is_array($report) === false) { - continue; - } - - $info = $report['info'] ?? null; - $label = $report['label'] ?? null; - $link = $report['link'] ?? null; - $value = $report['value'] ?? null; - - $reports[] = [ - 'icon' => $toString($report['icon'] ?? null), - 'info' => $toString(I18n::translate($info, $info)), - 'label' => $toString(I18n::translate($label, $label)), - 'link' => $toString(I18n::translate($link, $link)), - 'theme' => $toString($report['theme'] ?? null), - 'value' => $toString(I18n::translate($value, $value)) - ]; - } - - return $reports; + 'stats' => function (): Stats { + return $this->stats ??= Stats::from( + model: $this->model(), + reports: $this->reports(), + size: $this->size() + ); + }, + 'reports' => function (): array { + return $this->stats->reports(); + }, + 'size' => function (): string { + return $this->stats->size(); } ] ]; diff --git a/public/kirby/config/tags.php b/public/kirby/config/tags.php index 9f98127..05272b6 100644 --- a/public/kirby/config/tags.php +++ b/public/kirby/config/tags.php @@ -206,11 +206,8 @@ return [ // if value is a UUID, resolve to page/file model // and use the URL as value - if ( - Uuid::is($tag->value, 'page') === true || - Uuid::is($tag->value, 'file') === true - ) { - $tag->value = Uuid::for($tag->value)->model()?->url(); + if (Uuid::is($tag->value, ['page', 'file']) === true) { + $tag->value = Uuid::for($tag->value)?->toUrl(); } // if url is empty, throw exception or link to the error page diff --git a/public/kirby/i18n/translations/en.json b/public/kirby/i18n/translations/en.json index 7efbc30..49aebef 100644 --- a/public/kirby/i18n/translations/en.json +++ b/public/kirby/i18n/translations/en.json @@ -376,6 +376,7 @@ "field.structure.delete.confirm": "Do you really want to delete this row?", "field.structure.delete.confirm.all": "Do you really want to delete all entries?", + "field.structure.delete.confirm.selected": "Do you really want to delete the selected entries?", "field.structure.empty": "No entries yet", "field.users.empty": "No users selected yet", @@ -474,6 +475,7 @@ "license.code": "Code", "license.code.help": "You received your license code after the purchase via email. Please copy and paste it here.", "license.code.label": "Please enter your license code", + "license.remove.text": "
Removing the license will irreversibly delete the license file from this site. You can then activate this site with a different license key or re-register the same license key if the domain remains the same.
To change the domain associated with the license, please contact the Kirby team. Read more →
", "license.status.active.info": "Includes new major versions until {date}", "license.status.active.label": "Valid license", "license.status.demo.info": "This is a demo installation", diff --git a/public/kirby/i18n/translations/ko.json b/public/kirby/i18n/translations/ko.json index e29a4a6..a01a5c9 100644 --- a/public/kirby/i18n/translations/ko.json +++ b/public/kirby/i18n/translations/ko.json @@ -22,7 +22,7 @@ "copy.all": "모두 복사", "copy.success": "복사되었습니다. ({count})", "copy.success.multiple": "복사되었습니다. ({count})", - "copy.url": "Copy URL", + "copy.url": "URL 복사", "create": "등록", "custom": "개인화", @@ -92,23 +92,23 @@ "error.cache.type.invalid": "캐시 형식(({type})이 올바르지 않습니다.", - "error.content.lock.delete": "The version is locked and cannot be deleted", - "error.content.lock.move": "The source version is locked and cannot be moved", - "error.content.lock.publish": "This version is already published", - "error.content.lock.replace": "The version is locked and cannot be replaced", - "error.content.lock.update": "The version is locked and cannot be updated", + "error.content.lock.delete": "잠긴 버전은 삭제할 수 없습니다.", + "error.content.lock.move": "잠긴 버전은 이동할 수 없습니다.", + "error.content.lock.publish": "이미 발행되었습니다.", + "error.content.lock.replace": "잠긴 버전은 교체할 수 없습니다.", + "error.content.lock.update": "잠긴 버전은 업데이트할 수 없습니다.", - "error.entries.max.plural": "You must not add more than {max} entries", - "error.entries.max.singular": "You must not add more than one entry", - "error.entries.min.plural": "You must add at least {min} entries", - "error.entries.min.singular": "You must add at least one entry", - "error.entries.supports": "\"{type}\" field type is not supported for the entries field", + "error.entries.max.plural": "엔트리를 {max}개 이상 추가할 수 없습니다.", + "error.entries.max.singular": "엔트리를 하나 이상 추가할 수 없습니다.", + "error.entries.min.plural": "엔트리를 {min}개 이상 추가하세요.", + "error.entries.min.singular": "엔트리를 하나 이상 추가하세요.", + "error.entries.supports": "{type} 필드 타입은 지원하지 않습니다.", "error.entries.validation": "{index}번째 필드({field})에 오류가 있습니다.", "error.email.preset.notFound": "기본 이메일 주소({name})가 없습니다.", "error.field.converter.invalid": "컨버터({converter})가 올바르지 않습니다.", - "error.field.link.options": "Invalid options: {options}", + "error.field.link.options": "설정({options})이 올바르지 않습니다.", "error.field.type.missing": "필드({name}): 필드 타입({type})이 없습니다.", "error.file.changeName.empty": "이름을 입력하세요.", @@ -116,7 +116,7 @@ "error.file.changeTemplate.invalid": "파일({id}) 템플릿을 다음 템플릿({template})으로 변경할 수 없습니다. (valid: \"{blueprints}\")", "error.file.changeTemplate.permission": "파일({id}) 템플릿을 변경할 수 없습니다.", - "error.file.delete.multiple": "Not all files could be deleted. Try each remaining file individually to see the specific error that prevents deletion.", + "error.file.delete.multiple": "모든 파일을 삭제할 수 없습니다. 각 파일을 확인하세요.", "error.file.duplicate": "파일명이 같은 파일({filename})이 있습니다.", "error.file.extension.forbidden": "이 확장자({extension})는 업로드할 수 없습니다.", "error.file.extension.invalid": "확장자({extension})가 올바르지 않습니다.", @@ -135,7 +135,7 @@ "error.file.name.missing": "파일명을 입력하세요.", "error.file.notFound": "파일({filename})이 없습니다.", "error.file.orientation": "이미지의 비율({orientation})을 확인하세요.", - "error.file.sort.permission": "You are not allowed to change the sorting of \"{filename}\"", + "error.file.sort.permission": "파일({filename})을 정렬할 권한이 없습니다.", "error.file.type.forbidden": "이 형식({type})의 파일을 업로드할 권한이 없습니다.", "error.file.type.invalid": "파일 형식({type})이 올바르지 않습니다.", "error.file.undefined": "\ud30c\uc77c\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.", @@ -179,7 +179,7 @@ "error.page.delete": "페이지({slug})를 삭제할 수 없습니다.", "error.page.delete.confirm": "페이지를 삭제하려면 페이지의 제목을 입력하세요.", "error.page.delete.hasChildren": "하위 페이지가 있는 페이지는 삭제할 수 없습니다.", - "error.page.delete.multiple": "Not all pages could be deleted. Try each remaining page individually to see the specific error that prevents deletion.", + "error.page.delete.multiple": "모든 페이지를 삭제할 수 없습니다. 각 페이지를 확인하세요.", "error.page.delete.permission": "페이지({slug})를 삭제할 권한이 없습니다.", "error.page.draft.duplicate": "고유 주소({slug})가 같은 초안 페이지가 있습니다.", "error.page.duplicate": "고유 주소({slug})가 같은 페이지가 있습니다.", @@ -187,7 +187,7 @@ "error.page.move.ancestor": "해당 페이지로 이동할 수 없습니다.", "error.page.move.directory": "페이지 디렉토리는 이동할 수 없습니다.", "error.page.move.duplicate": "고유 주소({slug})가 같은 서브 페이지가 있습니다.", - "error.page.move.noSections": "The page \"{parent}\" cannot be a parent of any page because it lacks any pages sections in its blueprint", + "error.page.move.noSections": "부모 페이지({parent})의 블루프린트에 해당 섹션이 없습니다.", "error.page.move.notFound": "이동된 페이지를 찾을 수 없습니다.", "error.page.move.permission": "페이지({slug})를 이동할 권한이 없습니다.", "error.page.move.template": "이 템플릿({template})은 이 페이지({parent})의 서브 페이지로 이동할 수 없습니다.", @@ -317,9 +317,9 @@ "field.blocks.heading.name": "제목", "field.blocks.heading.text": "제목", "field.blocks.heading.placeholder": "제목", - "field.blocks.figure.back.plain": "Plain", - "field.blocks.figure.back.pattern.light": "Pattern (light)", - "field.blocks.figure.back.pattern.dark": "Pattern (dark)", + "field.blocks.figure.back.plain": "플레인", + "field.blocks.figure.back.pattern.light": "패턴(밝음)", + "field.blocks.figure.back.pattern.dark": "패턴(어두움)", "field.blocks.image.alt": "대체 텍스트", "field.blocks.image.caption": "캡션", "field.blocks.image.crop": "자르기", @@ -360,7 +360,7 @@ "field.entries.empty": "항목이 없습니다.", "field.files.empty": "선택한 파일이 없습니다.", - "field.files.empty.single": "No file selected yet", + "field.files.empty.single": "선택한 파일이 없습니다.", "field.layout.change": "레이아웃 변경", "field.layout.delete": "레이아웃 삭제", @@ -372,14 +372,14 @@ "field.object.empty": "정보가 없습니다.", "field.pages.empty": "선택한 페이지가 없습니다.", - "field.pages.empty.single": "No page selected yet", + "field.pages.empty.single": "선택한 페이지가 없습니다.", "field.structure.delete.confirm": "이 항목을 삭제할까요?", "field.structure.delete.confirm.all": "모든 항목을 삭제할까요?", "field.structure.empty": "항목이 없습니다.", "field.users.empty": "선택한 사용자가 없습니다.", - "field.users.empty.single": "No user selected yet", + "field.users.empty.single": "선택한 사용자가 없습니다.", "fields.empty": "필드가 없습니다.", @@ -394,17 +394,17 @@ "file.sort": "순서 변경", "files": "파일", - "files.delete.confirm.selected": "Do you really want to delete the selected files? This action cannot be undone.", + "files.delete.confirm.selected": "선택한 파일을 삭제할까요?", "files.empty": "파일이 없습니다.", "filter": "필터", - "form.discard": "Discard changes", - "form.discard.confirm": "Do you really want to discard all your changes?", - "form.locked": "This content is disabled for you as it is currently edited by another user", - "form.unsaved": "The current changes have not yet been saved", - "form.preview": "Preview changes", - "form.preview.draft": "Preview draft", + "form.discard": "저장되지 않은 항목이 있습니다.", + "form.discard.confirm": "저장되지 않은 내용을 삭제할까요?", + "form.locked": "다른 사용자가 편집 중입니다.", + "form.unsaved": "변경 사항이 저장되지 않았습니다.", + "form.preview": "변경 사항 미리 보기", + "form.preview.draft": "초안 미리 보기", "hide": "숨기기", "hour": "시", @@ -449,12 +449,12 @@ "language.variables.empty": "번역이 없습니다.", "language.variable.delete.confirm": "변수({key})를 삭제할까요?", - "language.variable.entries": "Values", - "language.variable.entries.help": "Each string will be used for its matching count, e.g. three strings will match in order to counts0, 1, 2 and more. Use the {count} placeholder to insert the actual count.",
+ "language.variable.entries": "값",
+ "language.variable.entries.help": "각 문자열은 해당하는 개수에 맞게 사용됩니다. 예를 들어 세 개의 문자열은 0, 1, 2 및 그 이상의 개수에 순서대로 대응합니다. 실제 개수를 표시하려면 {Count}를 사용하세요.",
"language.variable.key": "키",
- "language.variable.multiple": "Countable?",
- "language.variable.multiple.text": "Use different translation strings",
- "language.variable.multiple.help": "You can use different values depending on a count you pass along with the language variable, allowing you to create dynamic translations, e.g. singular and plural.",
+ "language.variable.multiple": "셀 수 있나요?",
+ "language.variable.multiple.text": "다른 번역 문자열을 사용하세요.",
+ "language.variable.multiple.help": "언어 변수와 함께 전달하는 개수에 따라 다른 값을 사용할 수 있으므로 단수형이나 복수형 같은 동적 번역을 구현할 수 있습니다.",
"language.variable.notFound": "변수를 찾을 수 없습니다.",
"language.variable.value": "값",
@@ -486,8 +486,8 @@
"license.status.missing.bubble": "사이트를 공개합니다.",
"license.status.missing.info": "유효한 라이선스가 없습니다.",
"license.status.missing.label": "라이선스를 활성화하세요.",
- "license.status.unknown.info": "The license status is unknown",
- "license.status.unknown.label": "Unknown",
+ "license.status.unknown.info": "라이선스 상태를 알 수 없습니다.",
+ "license.status.unknown.label": "알 수 없음",
"license.manage": "라이선스 관리",
"license.purchased": "구입했습니다.",
"license.success": "Kirby와 함께해주셔서 감사합니다.",
@@ -500,9 +500,9 @@
"lock.unsaved": "저장되지 않은 항목이 있습니다.",
"lock.unsaved.empty": "모든 페이지를 저장했습니다.",
- "lock.unsaved.files": "Unsaved files",
- "lock.unsaved.pages": "Unsaved pages",
- "lock.unsaved.users": "Unsaved accounts",
+ "lock.unsaved.files": "저장되지 않은 파일이 있습니다.",
+ "lock.unsaved.pages": "저장되지 않은 페이지가 있습니다.",
+ "lock.unsaved.users": "저장되지 않은 계정이 있습니다.",
"lock.isLocked": "사용자({email})의 변경 사항이 저장되지 않았습니다.",
"lock.unlock": "잠금 해제",
"lock.unlock.submit": "사용자({email})의 저장되지 않은 변경 사항을 해제하고 덮어쓰기",
@@ -609,7 +609,7 @@
"page.status.unlisted.description": "오직 URL을 통해 접근할 수 있습니다.",
"pages": "페이지",
- "pages.delete.confirm.selected": "Do you really want to delete the selected pages? This action cannot be undone.",
+ "pages.delete.confirm.selected": "선택한 페이지를 삭제할까요?",
"pages.empty": "페이지가 없습니다.",
"pages.status.draft": "초안",
"pages.status.listed": "발행",
@@ -627,7 +627,7 @@
"prev": "이전",
"preview": "미리 보기",
- "publish": "Publish",
+ "publish": "발행",
"published": "발행",
"remove": "삭제",
@@ -649,9 +649,9 @@
"role.nobody.title": "사용자가 없습니다.",
"save": "\uc800\uc7a5",
- "saved": "Saved",
+ "saved": "저장했습니다.",
"search": "검색",
- "searching": "Searching",
+ "searching": "검색 중",
"search.min": "{min}자 이상 입력하세요.",
"search.all": "모든 결과({count}) 보기",
"search.results.none": "해당하는 결과가 없습니다.",
@@ -684,9 +684,9 @@
"system.issues.git": "/.git 폴더의 권한을 확인하세요.",
"system.issues.https": "HTTPS를 권장합니다.",
"system.issues.kirby": "/kirby 폴더의 권한을 확인하세요.",
- "system.issues.local": "The site is running locally with relaxed security checks",
+ "system.issues.local": "이 사이트는 로컬에서 구동 중입니다.",
"system.issues.site": "/site 폴더의 권한을 확인하세요.",
- "system.issues.vue.compiler": "The Vue template compiler is enabled",
+ "system.issues.vue.compiler": "Vue 템플릿 컴파일러를 활성화했습니다.",
"system.issues.vulnerability.kirby": "설치한 시스템에 취약점이 있습니다.\n심각도: {severity}\n{description}",
"system.issues.vulnerability.plugin": "설치한 플러그인({plugin})에 취약점이 있습니다.\n심각도: {severity}\n{ description }",
"system.updateStatus": "업데이트 상태",
@@ -703,10 +703,10 @@
"tel.placeholder": "+49123456789",
"template": "\ud15c\ud50c\ub9bf",
- "theme": "Theme",
- "theme.light": "Lights on",
- "theme.dark": "Lights off",
- "theme.automatic": "Match system default",
+ "theme": "테마",
+ "theme.light": "밝게",
+ "theme.dark": "어둡게",
+ "theme.automatic": "시스템 기본값과 일치",
"title": "제목",
"today": "오늘",
@@ -766,7 +766,7 @@
"user.changeLanguage": "언어 변경",
"user.changeName": "사용자명 변경",
"user.changePassword": "암호 변경",
- "user.changePassword.current": "Your current password",
+ "user.changePassword.current": "현재 암호",
"user.changePassword.new": "새 암호",
"user.changePassword.new.confirm": "새 암호 확인",
"user.changeRole": "역할 변경",
@@ -778,13 +778,13 @@
"users": "사용자",
"version": "버전",
- "version.changes": "Changed version",
- "version.compare": "Compare versions",
+ "version.changes": "버전 변경",
+ "version.compare": "버전을 교체했습니다.",
"version.current": "현재 버전",
"version.latest": "최신 버전",
"versionInformation": "버전 정보",
- "view": "View",
+ "view": "뷰",
"view.account": "계정",
"view.installation": "\uc124\uce58",
"view.languages": "언어",
diff --git a/public/kirby/i18n/translations/nl.json b/public/kirby/i18n/translations/nl.json
index 1e04eb5..1a51a82 100644
--- a/public/kirby/i18n/translations/nl.json
+++ b/public/kirby/i18n/translations/nl.json
@@ -449,12 +449,12 @@
"language.variables.empty": "Nog geen vertalingen",
"language.variable.delete.confirm": "Weet je zeker dat je de variabele voor {key} wil verwijderen?",
- "language.variable.entries": "Values",
- "language.variable.entries.help": "Each string will be used for its matching count, e.g. three strings will match in order to counts 0, 1, 2 and more. Use the {count} placeholder to insert the actual count.",
+ "language.variable.entries": "Waardes",
+ "language.variable.entries.help": "Elke regel wordt gebruikt voor het bijbehorende aantal, bijvoorbeeld drie regels komen overeen met de aantallen 0, 1, 2 en meer. Gebruik de placeholder {count} om het werkelijke aantal in te voegen.",
"language.variable.key": "Key",
- "language.variable.multiple": "Countable?",
- "language.variable.multiple.text": "Use different translation strings",
- "language.variable.multiple.help": "You can use different values depending on a count you pass along with the language variable, allowing you to create dynamic translations, e.g. singular and plural.",
+ "language.variable.multiple": "Telbaar?",
+ "language.variable.multiple.text": "Gebruik verschillende vertalingen",
+ "language.variable.multiple.help": "Je kan verschillende waarden gebruiken, afhankelijk van een getal dat je samen met de taalvariabele doorgeeft, waardoor je dynamische vertalingen kan maken, bijvoorbeeld enkelvoud en meervoud.",
"language.variable.notFound": "De variabele kan niet gevonden worden",
"language.variable.value": "Waarde",
diff --git a/public/kirby/src/Cms/App.php b/public/kirby/src/Cms/App.php
index 4777671..2896e4d 100644
--- a/public/kirby/src/Cms/App.php
+++ b/public/kirby/src/Cms/App.php
@@ -443,15 +443,15 @@ class App
array $arguments = [],
string $contentType = 'html'
): array {
- $name = basename(strtolower($name));
+ $name = strtolower($name);
$data = [];
// always use the site controller as defaults, if available
- $site = $this->controllerLookup('site', $contentType);
- $site ??= $this->controllerLookup('site');
-
- if ($site !== null) {
- $data = (array)$site->call($this, $arguments);
+ // (unless the controller is a snippet controller)
+ if (strpos($name, '/') === false) {
+ $site = $this->controllerLookup('site', $contentType);
+ $site ??= $this->controllerLookup('site');
+ $data = (array)$site?->call($this, $arguments) ?? [];
}
// try to find a specific representation controller
@@ -460,14 +460,10 @@ class App
// let's try the html controller instead
$controller ??= $this->controllerLookup($name);
- if ($controller !== null) {
- return [
- ...$data,
- ...(array)$controller->call($this, $arguments)
- ];
- }
-
- return $data;
+ return [
+ ...$data,
+ ...(array)$controller?->call($this, $arguments) ?? []
+ ];
}
/**
@@ -482,7 +478,11 @@ class App
}
// controller from site root
- $controller = Controller::load($this->root('controllers') . '/' . $name . '.php', $this->root('controllers'));
+ $controller = Controller::load(
+ file: $this->root('controllers') . '/' . $name . '.php',
+ in: $this->root('controllers')
+ );
+
// controller from extension
$controller ??= $this->extension('controllers', $name);
@@ -580,7 +580,16 @@ class App
$visitor = $this->visitor();
foreach ($visitor->acceptedLanguages() as $acceptedLang) {
- $closure = static function ($language) use ($acceptedLang) {
+ // Find locale matches (e.g. en_GB => en_GB)
+ $matchLocale = function ($language) use ($acceptedLang) {
+ $languageLocale = $language->locale(LC_ALL);
+ $acceptedLocale = $acceptedLang->locale();
+
+ return Str::substr($languageLocale, 0, 5) === Str::substr($acceptedLocale, 0, 5);
+ };
+
+ // Find language matches (e.g. en_GB => en)
+ $matchLanguage = function ($language) use ($acceptedLang) {
$languageLocale = $language->locale(LC_ALL);
$acceptedLocale = $acceptedLang->locale();
@@ -589,7 +598,11 @@ class App
$acceptedLocale === Str::substr($languageLocale, 0, 2);
};
- if ($language = $languages->filter($closure)?->first()) {
+ if ($language = $languages->filter($matchLocale)?->first()) {
+ return $language;
+ }
+
+ if ($language = $languages->filter($matchLanguage)?->first()) {
return $language;
}
}
@@ -768,15 +781,7 @@ class App
// Responses
if ($input instanceof Response) {
- $data = $input->toArray();
-
- // inject headers from the global response configuration
- // lazily (only if they are not already set);
- // the case-insensitive nature of headers will be
- // handled by PHP's `header()` function
- $data['headers'] = [...$response->headers(), ...$data['headers']];
-
- return new Response($data);
+ return $response->send($input);
}
// Pages
diff --git a/public/kirby/src/Cms/AppTranslations.php b/public/kirby/src/Cms/AppTranslations.php
index 2dfe918..c7bdd6a 100644
--- a/public/kirby/src/Cms/AppTranslations.php
+++ b/public/kirby/src/Cms/AppTranslations.php
@@ -88,6 +88,12 @@ trait AppTranslations
*/
public function panelLanguage(): string
{
+ $translation = $this->request()->get('translation');
+
+ if ($translation !== null && $this->translations()->find($translation)) {
+ return $translation;
+ }
+
if ($this->multilang() === true) {
$defaultCode = $this->defaultLanguage()->code();
diff --git a/public/kirby/src/Cms/Core.php b/public/kirby/src/Cms/Core.php
index bd8f051..569189b 100644
--- a/public/kirby/src/Cms/Core.php
+++ b/public/kirby/src/Cms/Core.php
@@ -12,6 +12,7 @@ use Kirby\Cms\Auth\TotpChallenge;
use Kirby\Form\Field\BlocksField;
use Kirby\Form\Field\EntriesField;
use Kirby\Form\Field\LayoutField;
+use Kirby\Form\Field\StatsField;
use Kirby\Panel\Ui\FilePreviews\AudioFilePreview;
use Kirby\Panel\Ui\FilePreviews\ImageFilePreview;
use Kirby\Panel\Ui\FilePreviews\PdfFilePreview;
@@ -270,6 +271,7 @@ class Core
'range' => $this->root . '/fields/range.php',
'select' => $this->root . '/fields/select.php',
'slug' => $this->root . '/fields/slug.php',
+ 'stats' => StatsField::class,
'structure' => $this->root . '/fields/structure.php',
'tags' => $this->root . '/fields/tags.php',
'tel' => $this->root . '/fields/tel.php',
diff --git a/public/kirby/src/Cms/File.php b/public/kirby/src/Cms/File.php
index ebb9969..6bb33d8 100644
--- a/public/kirby/src/Cms/File.php
+++ b/public/kirby/src/Cms/File.php
@@ -31,6 +31,7 @@ use Kirby\Toolkit\Str;
* @license https://getkirby.com/license
*
* @use \Kirby\Cms\HasSiblings<\Kirby\Cms\Files>
+ * @method \Kirby\Uuid\FileUuid uuid()
*/
class File extends ModelWithContent
{
@@ -513,7 +514,7 @@ class File extends ModelWithContent
*/
public function permalink(): string|null
{
- return $this->uuid()?->url();
+ return $this->uuid()?->toPermalink();
}
/**
diff --git a/public/kirby/src/Cms/LanguageVariable.php b/public/kirby/src/Cms/LanguageVariable.php
index 669c07b..935a598 100644
--- a/public/kirby/src/Cms/LanguageVariable.php
+++ b/public/kirby/src/Cms/LanguageVariable.php
@@ -116,6 +116,15 @@ class LanguageVariable
return $this->key;
}
+ /**
+ * Returns the parent language
+ * @since 5.1.0
+ */
+ public function language(): Language
+ {
+ return $this->language;
+ }
+
/**
* Sets a new value for the language variable
*/
diff --git a/public/kirby/src/Cms/License.php b/public/kirby/src/Cms/License.php
index 7685ebb..e005b45 100644
--- a/public/kirby/src/Cms/License.php
+++ b/public/kirby/src/Cms/License.php
@@ -30,6 +30,8 @@ class License
protected const SALT = 'kwAHMLyLPBnHEskzH9pPbJsBxQhKXZnX';
+ protected App $kirby;
+
// cache
protected LicenseStatus $status;
protected LicenseType $type;
@@ -50,6 +52,8 @@ class License
if ($email !== null) {
$this->email = $this->normalizeEmail($email);
}
+
+ $this->kirby = App::instance();
}
/**
@@ -100,6 +104,15 @@ class License
return $this->date !== null ? Str::date(strtotime($this->date), $format, $handler) : null;
}
+ /**
+ * Deletes the license file if it exists
+ * @since 5.1.0
+ */
+ public function delete(): bool
+ {
+ return F::remove($this->root());
+ }
+
/**
* Returns the activation domain if available
*/
@@ -179,7 +192,7 @@ class License
}
// get release date of current major version
- $major = Str::before(App::instance()->version(), '.');
+ $major = Str::before($this->kirby->version(), '.');
$release = strtotime(static::HISTORY[$major] ?? '');
// if there's no matching version in the history
@@ -219,7 +232,7 @@ class License
}
// compare domains
- if ($this->normalizeDomain(App::instance()->system()->indexUrl()) !== $this->normalizeDomain($this->domain)) {
+ if ($this->normalizeDomain($this->kirby->system()->indexUrl()) !== $this->normalizeDomain($this->domain)) {
return false;
}
@@ -236,7 +249,7 @@ class License
}
// get the public key
- $pubKey = F::read(App::instance()->root('kirby') . '/kirby.pub');
+ $pubKey = F::read($this->kirby->root('kirby') . '/kirby.pub');
// verify the license signature
$data = json_encode($this->signatureData());
@@ -328,7 +341,7 @@ class License
public static function read(): static
{
try {
- $license = Json::read(App::instance()->root('license'));
+ $license = Json::read(static::root());
} catch (Throwable) {
return new static();
}
@@ -409,6 +422,15 @@ class License
// @codeCoverageIgnoreEnd
}
+ /**
+ * Returns the root path to the license file
+ * @since 5.1.0
+ */
+ public static function root(): string
+ {
+ return App::instance()->root('license');
+ }
+
/**
* Saves the license in the config folder
*/
@@ -420,11 +442,11 @@ class License
);
}
- // where to store the license file
- $file = App::instance()->root('license');
-
// save the license information
- return Json::write($file, $this->content());
+ return Json::write(
+ file: $this->root(),
+ data: $this->content()
+ );
}
/**
diff --git a/public/kirby/src/Cms/Page.php b/public/kirby/src/Cms/Page.php
index 4c667c7..a764ed1 100644
--- a/public/kirby/src/Cms/Page.php
+++ b/public/kirby/src/Cms/Page.php
@@ -30,6 +30,7 @@ use Throwable;
* @license https://getkirby.com/license
*
* @use \Kirby\Cms\HasSiblings<\Kirby\Cms\Pages>
+ * @method \Kirby\Uuid\PageUuid uuid()
*/
class Page extends ModelWithContent
{
@@ -871,7 +872,7 @@ class Page extends ModelWithContent
*/
public function permalink(): string|null
{
- return $this->uuid()?->url();
+ return $this->uuid()?->toPermalink();
}
/**
diff --git a/public/kirby/src/Cms/PageActions.php b/public/kirby/src/Cms/PageActions.php
index ba959d5..f864616 100644
--- a/public/kirby/src/Cms/PageActions.php
+++ b/public/kirby/src/Cms/PageActions.php
@@ -865,6 +865,9 @@ trait PageActions
'template' => $this->intendedTemplate()->name(),
]);
+ // remove the media directory
+ Dir::remove($this->mediaRoot());
+
// actually do it on disk
if ($this->exists() === true) {
if (Dir::move($this->root(), $page->root()) !== true) {
diff --git a/public/kirby/src/Cms/Responder.php b/public/kirby/src/Cms/Responder.php
index 5bd9802..a6eade0 100644
--- a/public/kirby/src/Cms/Responder.php
+++ b/public/kirby/src/Cms/Responder.php
@@ -4,6 +4,7 @@ namespace Kirby\Cms;
use Kirby\Exception\InvalidArgumentException;
use Kirby\Filesystem\Mime;
+use Kirby\Http\Response as HttpResponse;
use Kirby\Toolkit\Str;
use Stringable;
@@ -337,8 +338,15 @@ class Responder implements Stringable
/**
* Creates and returns the response object from the config
*/
- public function send(string|null $body = null): Response
+ public function send(HttpResponse|string|null $body = null): HttpResponse
{
+ if ($body instanceof HttpResponse) {
+ // inject headers from the responder into the response
+ // (only if they are not already set);
+ $body->setHeaderFallbacks($this->headers());
+ return $body;
+ }
+
if ($body !== null) {
$this->body($body);
}
diff --git a/public/kirby/src/Cms/Site.php b/public/kirby/src/Cms/Site.php
index 6333401..6b5a2a5 100644
--- a/public/kirby/src/Cms/Site.php
+++ b/public/kirby/src/Cms/Site.php
@@ -20,6 +20,8 @@ use Kirby\Toolkit\A;
* @link https://getkirby.com
* @copyright Bastian Allgeier
* @license https://getkirby.com/license
+ *
+ * @method \Kirby\Uuid\SiteUuid uuid()
*/
class Site extends ModelWithContent
{
diff --git a/public/kirby/src/Cms/User.php b/public/kirby/src/Cms/User.php
index 9cd8161..6f749e0 100644
--- a/public/kirby/src/Cms/User.php
+++ b/public/kirby/src/Cms/User.php
@@ -26,6 +26,7 @@ use SensitiveParameter;
* @license https://getkirby.com/license
*
* @use \Kirby\Cms\HasSiblings<\Kirby\Cms\Users>
+ * @method \Kirby\Uuid\UserUuid uuid()
*/
class User extends ModelWithContent
{
diff --git a/public/kirby/src/Filesystem/Mime.php b/public/kirby/src/Filesystem/Mime.php
index 7ddc9ac..aa23c63 100644
--- a/public/kirby/src/Filesystem/Mime.php
+++ b/public/kirby/src/Filesystem/Mime.php
@@ -99,7 +99,7 @@ class Mime
'tgz' => ['application/x-tar', 'application/x-gzip-compressed'],
'tif' => 'image/tiff',
'tiff' => 'image/tiff',
- 'wav' => 'audio/x-wav',
+ 'wav' => ['audio/wav', 'audio/x-wav', 'audio/vnd.wave', 'audio/wave'],
'wbxml' => 'application/wbxml',
'webm' => ['video/webm', 'audio/webm'],
'webp' => 'image/webp',
diff --git a/public/kirby/src/Form/Field/StatsField.php b/public/kirby/src/Form/Field/StatsField.php
new file mode 100644
index 0000000..4d7b8d8
--- /dev/null
+++ b/public/kirby/src/Form/Field/StatsField.php
@@ -0,0 +1,74 @@
+
+ * @link https://getkirby.com
+ * @copyright Bastian Allgeier
+ * @license https://getkirby.com/license
+ * @since 5.1.0
+ */
+class StatsField extends FieldClass
+{
+ /**
+ * Array or query string for reports. Each report needs a `label` and `value` and can have additional `info`, `link`, `icon` and `theme` settings.
+ */
+ protected array|string $reports;
+
+ /**
+ * The size of the report cards. Available sizes: `tiny`, `small`, `medium`, `large`
+ */
+ protected string $size;
+
+ /**
+ * Cache for the Stats UI component
+ */
+ protected Stats $stats;
+
+ public function __construct(array $params)
+ {
+ parent::__construct($params);
+
+ $this->reports = $params['reports'] ?? [];
+ $this->size = $params['size'] ?? 'large';
+ }
+
+ public function hasValue(): bool
+ {
+ return false;
+ }
+
+ public function reports(): array
+ {
+ return $this->stats()->reports();
+ }
+
+ public function size(): string
+ {
+ return $this->stats()->size();
+ }
+
+ public function stats(): Stats
+ {
+ return $this->stats ??= Stats::from(
+ model: $this->model,
+ reports: $this->reports,
+ size: $this->size
+ );
+ }
+
+ public function props(): array
+ {
+ return [
+ ...parent::props(),
+ ...$this->stats()->props()
+ ];
+ }
+}
diff --git a/public/kirby/src/Form/FieldClass.php b/public/kirby/src/Form/FieldClass.php
index 1c5d2ef..6844821 100644
--- a/public/kirby/src/Form/FieldClass.php
+++ b/public/kirby/src/Form/FieldClass.php
@@ -4,7 +4,6 @@ namespace Kirby\Form;
use Kirby\Cms\HasSiblings;
use Kirby\Toolkit\I18n;
-use Kirby\Toolkit\Str;
/**
* Abstract field class to be used instead
@@ -22,24 +21,24 @@ use Kirby\Toolkit\Str;
abstract class FieldClass
{
use HasSiblings;
+ use Mixin\After;
use Mixin\Api;
+ use Mixin\Autofocus;
+ use Mixin\Before;
+ use Mixin\Help;
+ use Mixin\Icon;
+ use Mixin\Label;
use Mixin\Model;
+ use Mixin\Placeholder;
use Mixin\Translatable;
use Mixin\Validation;
use Mixin\Value;
use Mixin\When;
+ use Mixin\Width;
- protected string|null $after;
- protected bool $autofocus;
- protected string|null $before;
protected bool $disabled;
- protected string|null $help;
- protected string|null $icon;
- protected string|null $label;
protected string|null $name;
- protected string|null $placeholder;
protected Fields $siblings;
- protected string|null $width;
public function __construct(
protected array $params = []
@@ -75,21 +74,6 @@ abstract class FieldClass
return $this->params[$param] ?? null;
}
- public function after(): string|null
- {
- return $this->stringTemplate($this->after);
- }
-
- public function autofocus(): bool
- {
- return $this->autofocus;
- }
-
- public function before(): string|null
- {
- return $this->stringTemplate($this->before);
- }
-
/**
* Returns optional dialog routes for the field
*/
@@ -114,33 +98,11 @@ abstract class FieldClass
return [];
}
- /**
- * Optional help text below the field
- */
- public function help(): string|null
- {
- if (empty($this->help) === false) {
- $help = $this->stringTemplate($this->help);
- $help = $this->kirby()->kirbytext($help);
- return $help;
- }
-
- return null;
- }
-
protected function i18n(string|array|null $param = null): string|null
{
return empty($param) === false ? I18n::translate($param, $param) : null;
}
- /**
- * Optional icon that will be shown at the end of the field
- */
- public function icon(): string|null
- {
- return $this->icon;
- }
-
public function id(): string
{
return $this->name();
@@ -156,16 +118,6 @@ abstract class FieldClass
return false;
}
- /**
- * The field label can be set as string or associative array with translations
- */
- public function label(): string
- {
- return $this->stringTemplate(
- $this->label ?? Str::ucfirst($this->name())
- );
- }
-
/**
* Returns the field name
*/
@@ -182,14 +134,6 @@ abstract class FieldClass
return $this->params;
}
- /**
- * Optional placeholder value that will be shown when the field is empty
- */
- public function placeholder(): string|null
- {
- return $this->stringTemplate($this->placeholder);
- }
-
/**
* Define the props that will be sent to
* the Vue component
@@ -217,67 +161,21 @@ abstract class FieldClass
];
}
- protected function setAfter(array|string|null $after = null): void
- {
- $this->after = $this->i18n($after);
- }
-
- protected function setAutofocus(bool $autofocus = false): void
- {
- $this->autofocus = $autofocus;
- }
-
- protected function setBefore(array|string|null $before = null): void
- {
- $this->before = $this->i18n($before);
- }
-
protected function setDisabled(bool $disabled = false): void
{
$this->disabled = $disabled;
}
- protected function setHelp(array|string|null $help = null): void
- {
- $this->help = $this->i18n($help);
- }
-
- protected function setIcon(string|null $icon = null): void
- {
- $this->icon = $icon;
- }
-
- protected function setLabel(array|string|null $label = null): void
- {
- $this->label = $this->i18n($label);
- }
-
protected function setName(string|null $name = null): void
{
$this->name = strtolower($name ?? $this->type());
}
- protected function setPlaceholder(array|string|null $placeholder = null): void
- {
- $this->placeholder = $this->i18n($placeholder);
- }
-
protected function setSiblings(Fields|null $siblings = null): void
{
$this->siblings = $siblings ?? new Fields([$this]);
}
- /**
- * Setter for the field width
- */
- protected function setWidth(string|null $width = null): void
- {
- $this->width = $width;
- }
-
- /**
- * Returns all sibling fields for the HasSiblings trait
- */
protected function siblingsCollection(): Fields
{
return $this->siblings;
@@ -314,13 +212,4 @@ abstract class FieldClass
{
return lcfirst(basename(str_replace(['\\', 'Field'], ['/', ''], static::class)));
}
-
- /**
- * Returns the width of the field in
- * the Panel grid
- */
- public function width(): string
- {
- return $this->width ?? '1/1';
- }
}
diff --git a/public/kirby/src/Form/Mixin/After.php b/public/kirby/src/Form/Mixin/After.php
new file mode 100644
index 0000000..3199ddc
--- /dev/null
+++ b/public/kirby/src/Form/Mixin/After.php
@@ -0,0 +1,21 @@
+stringTemplate($this->after);
+ }
+
+ protected function setAfter(array|string|null $after = null): void
+ {
+ $this->after = $this->i18n($after);
+ }
+}
diff --git a/public/kirby/src/Form/Mixin/Autofocus.php b/public/kirby/src/Form/Mixin/Autofocus.php
new file mode 100644
index 0000000..2b57688
--- /dev/null
+++ b/public/kirby/src/Form/Mixin/Autofocus.php
@@ -0,0 +1,21 @@
+autofocus;
+ }
+
+ protected function setAutofocus(bool $autofocus = false): void
+ {
+ $this->autofocus = $autofocus;
+ }
+}
diff --git a/public/kirby/src/Form/Mixin/Before.php b/public/kirby/src/Form/Mixin/Before.php
new file mode 100644
index 0000000..4335a65
--- /dev/null
+++ b/public/kirby/src/Form/Mixin/Before.php
@@ -0,0 +1,21 @@
+stringTemplate($this->before);
+ }
+
+ protected function setBefore(array|string|null $before = null): void
+ {
+ $this->before = $this->i18n($before);
+ }
+}
diff --git a/public/kirby/src/Form/Mixin/EmptyState.php b/public/kirby/src/Form/Mixin/EmptyState.php
index 6f7d72a..a553648 100644
--- a/public/kirby/src/Form/Mixin/EmptyState.php
+++ b/public/kirby/src/Form/Mixin/EmptyState.php
@@ -4,6 +4,9 @@ namespace Kirby\Form\Mixin;
trait EmptyState
{
+ /**
+ * Sets the text for the empty state box
+ */
protected string|null $empty;
protected function setEmpty(string|array|null $empty = null): void
diff --git a/public/kirby/src/Form/Mixin/Help.php b/public/kirby/src/Form/Mixin/Help.php
new file mode 100644
index 0000000..790e9eb
--- /dev/null
+++ b/public/kirby/src/Form/Mixin/Help.php
@@ -0,0 +1,34 @@
+
+ * @link https://getkirby.com
+ * @copyright Bastian Allgeier
+ * @license https://opensource.org/licenses/MIT
+ */
+trait Help
+{
+ /**
+ * Optional help text below the field
+ */
+ protected string|null $help;
+
+ public function help(): string|null
+ {
+ if (empty($this->help) === false) {
+ $help = $this->stringTemplate($this->help);
+ $help = $this->kirby()->kirbytext($help);
+ return $help;
+ }
+
+ return null;
+ }
+
+ protected function setHelp(array|string|null $help = null): void
+ {
+ $this->help = $this->i18n($help);
+ }
+}
diff --git a/public/kirby/src/Form/Mixin/Icon.php b/public/kirby/src/Form/Mixin/Icon.php
new file mode 100644
index 0000000..b8a5491
--- /dev/null
+++ b/public/kirby/src/Form/Mixin/Icon.php
@@ -0,0 +1,28 @@
+
+ * @link https://getkirby.com
+ * @copyright Bastian Allgeier
+ * @license https://opensource.org/licenses/MIT
+ */
+trait Icon
+{
+ /**
+ * Optional icon that will be shown at the end of the field
+ */
+ protected string|null $icon;
+
+ public function icon(): string|null
+ {
+ return $this->icon;
+ }
+
+ protected function setIcon(string|null $icon = null): void
+ {
+ $this->icon = $icon;
+ }
+}
diff --git a/public/kirby/src/Form/Mixin/Label.php b/public/kirby/src/Form/Mixin/Label.php
new file mode 100644
index 0000000..3691459
--- /dev/null
+++ b/public/kirby/src/Form/Mixin/Label.php
@@ -0,0 +1,32 @@
+
+ * @link https://getkirby.com
+ * @copyright Bastian Allgeier
+ * @license https://opensource.org/licenses/MIT
+ */
+trait Label
+{
+ /**
+ * The field label can be set as string or associative array with translations
+ */
+ protected string|null $label;
+
+ public function label(): string|null
+ {
+ return $this->stringTemplate(
+ $this->label ?? Str::ucfirst($this->name())
+ );
+ }
+
+ protected function setLabel(array|string|null $label = null): void
+ {
+ $this->label = $this->i18n($label);
+ }
+}
diff --git a/public/kirby/src/Form/Mixin/Max.php b/public/kirby/src/Form/Mixin/Max.php
index 1641917..07706a3 100644
--- a/public/kirby/src/Form/Mixin/Max.php
+++ b/public/kirby/src/Form/Mixin/Max.php
@@ -4,6 +4,9 @@ namespace Kirby\Form\Mixin;
trait Max
{
+ /**
+ * Sets the maximum number of allowed items in the field
+ */
protected int|null $max;
public function max(): int|null
diff --git a/public/kirby/src/Form/Mixin/Min.php b/public/kirby/src/Form/Mixin/Min.php
index 9f5977e..ba875c4 100644
--- a/public/kirby/src/Form/Mixin/Min.php
+++ b/public/kirby/src/Form/Mixin/Min.php
@@ -4,6 +4,9 @@ namespace Kirby\Form\Mixin;
trait Min
{
+ /**
+ * Sets the minimum number of required items in the field
+ */
protected int|null $min;
public function min(): int|null
diff --git a/public/kirby/src/Form/Mixin/Placeholder.php b/public/kirby/src/Form/Mixin/Placeholder.php
new file mode 100644
index 0000000..0692627
--- /dev/null
+++ b/public/kirby/src/Form/Mixin/Placeholder.php
@@ -0,0 +1,30 @@
+
+ * @link https://getkirby.com
+ * @copyright Bastian Allgeier
+ * @license https://opensource.org/licenses/MIT
+ */
+trait Placeholder
+{
+ /**
+ * Optional placeholder value that will be shown when the field is empty
+ */
+ protected array|string|null $placeholder;
+
+ public function placeholder(): string|null
+ {
+ return $this->stringTemplate(
+ $this->placeholder
+ );
+ }
+
+ protected function setPlaceholder(array|string|null $placeholder = null): void
+ {
+ $this->placeholder = $this->i18n($placeholder);
+ }
+}
diff --git a/public/kirby/src/Form/Mixin/Translatable.php b/public/kirby/src/Form/Mixin/Translatable.php
index bc36a65..a71a6fd 100644
--- a/public/kirby/src/Form/Mixin/Translatable.php
+++ b/public/kirby/src/Form/Mixin/Translatable.php
@@ -13,6 +13,9 @@ use Kirby\Cms\Language;
*/
trait Translatable
{
+ /**
+ * Should the field be translatable?
+ */
protected bool $translate = true;
/**
@@ -29,17 +32,11 @@ trait Translatable
return true;
}
- /**
- * Set the translatable status
- */
protected function setTranslate(bool $translate = true): void
{
$this->translate = $translate;
}
- /**
- * Should the field be translatable?
- */
public function translate(): bool
{
return $this->translate;
diff --git a/public/kirby/src/Form/Mixin/Validation.php b/public/kirby/src/Form/Mixin/Validation.php
index cd69a0c..58e9ad9 100644
--- a/public/kirby/src/Form/Mixin/Validation.php
+++ b/public/kirby/src/Form/Mixin/Validation.php
@@ -18,6 +18,9 @@ use Kirby\Toolkit\V;
*/
trait Validation
{
+ /**
+ * If `true`, the field has to be filled in correctly to be saved.
+ */
protected bool $required;
/**
@@ -94,9 +97,6 @@ trait Validation
return $this->errors() === [];
}
- /**
- * Getter for the required property
- */
public function required(): bool
{
return $this->required;
diff --git a/public/kirby/src/Form/Mixin/Value.php b/public/kirby/src/Form/Mixin/Value.php
index 3dd3423..5da8567 100644
--- a/public/kirby/src/Form/Mixin/Value.php
+++ b/public/kirby/src/Form/Mixin/Value.php
@@ -13,7 +13,14 @@ use Kirby\Cms\Language;
*/
trait Value
{
+ /**
+ * Default value for the field, which will be used when a page/file/user is created
+ */
protected mixed $default = null;
+
+ /**
+ * The value of the field
+ */
protected mixed $value = null;
/**
diff --git a/public/kirby/src/Form/Mixin/When.php b/public/kirby/src/Form/Mixin/When.php
index 1bc18c9..f0952a6 100644
--- a/public/kirby/src/Form/Mixin/When.php
+++ b/public/kirby/src/Form/Mixin/When.php
@@ -11,6 +11,11 @@ namespace Kirby\Form\Mixin;
*/
trait When
{
+ /**
+ * Conditions when the field will be shown
+ *
+ * @since 3.1.0
+ */
protected array|null $when = null;
/**
@@ -40,17 +45,11 @@ trait When
return true;
}
- /**
- * Setter for the `when` condition
- */
protected function setWhen(array|null $when = null): void
{
$this->when = $when;
}
- /**
- * Returns the `when` condition of the field
- */
public function when(): array|null
{
return $this->when;
diff --git a/public/kirby/src/Form/Mixin/Width.php b/public/kirby/src/Form/Mixin/Width.php
new file mode 100644
index 0000000..6366ea6
--- /dev/null
+++ b/public/kirby/src/Form/Mixin/Width.php
@@ -0,0 +1,29 @@
+
+ * @link https://getkirby.com
+ * @copyright Bastian Allgeier
+ * @license https://opensource.org/licenses/MIT
+ */
+trait Width
+{
+ /**
+ * The width of the field in the field grid.
+ * Available widths: `1/1`, `1/2`, `1/3`, `1/4`, `2/3`, `3/4`
+ */
+ protected string|null $width;
+
+ protected function setWidth(string|null $width = null): void
+ {
+ $this->width = $width;
+ }
+
+ public function width(): string
+ {
+ return $this->width ?? '1/1';
+ }
+}
diff --git a/public/kirby/src/Http/Cookie.php b/public/kirby/src/Http/Cookie.php
index 468a311..fa0c010 100644
--- a/public/kirby/src/Http/Cookie.php
+++ b/public/kirby/src/Http/Cookie.php
@@ -222,7 +222,6 @@ class Cookie
protected static function trackUsage(string $key): void
{
// lazily request the instance for non-CMS use cases
- $kirby = App::instance(null, true);
- $kirby?->response()->usesCookie($key);
+ App::instance(lazy: true)?->response()->usesCookie($key);
}
}
diff --git a/public/kirby/src/Http/Environment.php b/public/kirby/src/Http/Environment.php
index dd8eee5..1672f75 100644
--- a/public/kirby/src/Http/Environment.php
+++ b/public/kirby/src/Http/Environment.php
@@ -13,13 +13,13 @@ use Kirby\Toolkit\Str;
* secure host and base URL detection, as
* well as loading the dedicated
* environment options.
- * @since 3.7.0
*
* @package Kirby Http
* @author Bastian Allgeier
Advice for developers and administrators:
- Change the PHP version to one supported by your version of Kirby
+ Change the PHP version to one supported by your version of Kirby