feat: 官网首页 liquid-glass 与布局优化,并改进批量邮件发信体验
All checks were successful
Build and Deploy Front / deploy (push) Successful in 8m13s
All checks were successful
Build and Deploy Front / deploy (push) Successful in 8m13s
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
c2861157af
commit
0910538e6b
@ -49,6 +49,7 @@
|
|||||||
"@codemirror/theme-one-dark": "^6.1.3",
|
"@codemirror/theme-one-dark": "^6.1.3",
|
||||||
"@codemirror/view": "^6.39.17",
|
"@codemirror/view": "^6.39.17",
|
||||||
"@fontsource/zcool-qingke-huangyou": "^5.3.0",
|
"@fontsource/zcool-qingke-huangyou": "^5.3.0",
|
||||||
|
"@glass-sdk/liquid-glass": "~0.0.2",
|
||||||
"@handsontable/vue3": "^16.2.0",
|
"@handsontable/vue3": "^16.2.0",
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@vueuse/core": "^9.3.0",
|
"@vueuse/core": "^9.3.0",
|
||||||
|
|||||||
275
pnpm-lock.yaml
generated
275
pnpm-lock.yaml
generated
@ -39,6 +39,9 @@ importers:
|
|||||||
'@fontsource/zcool-qingke-huangyou':
|
'@fontsource/zcool-qingke-huangyou':
|
||||||
specifier: ^5.3.0
|
specifier: ^5.3.0
|
||||||
version: 5.3.0
|
version: 5.3.0
|
||||||
|
'@glass-sdk/liquid-glass':
|
||||||
|
specifier: ~0.0.2
|
||||||
|
version: 0.0.2(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
|
||||||
'@handsontable/vue3':
|
'@handsontable/vue3':
|
||||||
specifier: ^16.2.0
|
specifier: ^16.2.0
|
||||||
version: 16.2.0(handsontable@16.2.0)(vue@3.5.18(typescript@4.9.5))
|
version: 16.2.0(handsontable@16.2.0)(vue@3.5.18(typescript@4.9.5))
|
||||||
@ -443,6 +446,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==}
|
resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
|
'@babel/runtime@8.1.0':
|
||||||
|
resolution: {integrity: sha512-MQye/pU7gzXerMzlhScFNH1u4Je6rR8cqJWSgAfD+rIwbbtwG8tVDegoI7sWfcXkfVRW09G7vk2vjxGIuKFfwg==}
|
||||||
|
|
||||||
'@babel/template@7.27.2':
|
'@babel/template@7.27.2':
|
||||||
resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==}
|
resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
@ -455,6 +461,33 @@ packages:
|
|||||||
resolution: {integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==}
|
resolution: {integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
|
'@base-ui/react@1.9.0':
|
||||||
|
resolution: {integrity: sha512-S8CSYosASBKtpL8SWUfS78rFElfLijiCgA7oHOK22jCJ95FULsYyKwBNFOgudt0RA+/7yNc7F81bOvQnRgbBiQ==}
|
||||||
|
engines: {node: '>=14.0.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@date-fns/tz': ^1.2.0
|
||||||
|
'@types/react': ^17 || ^18 || ^19
|
||||||
|
date-fns: ^4.0.0
|
||||||
|
react: ^17 || ^18 || ^19
|
||||||
|
react-dom: ^17 || ^18 || ^19
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@date-fns/tz':
|
||||||
|
optional: true
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
date-fns:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@base-ui/utils@0.5.0':
|
||||||
|
resolution: {integrity: sha512-dYGGcEttjkYiMoa5nHm8vLaJ2UcuTWxo3BFAwOYXeRg/q7UVVvA6cacEIXEs3FgBfK1CGtW1ptElqs7wsx+t9A==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': ^17 || ^18 || ^19
|
||||||
|
react: ^17 || ^18 || ^19
|
||||||
|
react-dom: ^17 || ^18 || ^19
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@braintree/sanitize-url@7.1.2':
|
'@braintree/sanitize-url@7.1.2':
|
||||||
resolution: {integrity: sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==}
|
resolution: {integrity: sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==}
|
||||||
|
|
||||||
@ -929,15 +962,36 @@ packages:
|
|||||||
'@floating-ui/core@1.7.4':
|
'@floating-ui/core@1.7.4':
|
||||||
resolution: {integrity: sha512-C3HlIdsBxszvm5McXlB8PeOEWfBhcGBTZGkGlWc2U0KFY5IwG5OQEuQ8rq52DZmcHDlPLd+YFBK+cZcytwIFWg==}
|
resolution: {integrity: sha512-C3HlIdsBxszvm5McXlB8PeOEWfBhcGBTZGkGlWc2U0KFY5IwG5OQEuQ8rq52DZmcHDlPLd+YFBK+cZcytwIFWg==}
|
||||||
|
|
||||||
|
'@floating-ui/core@1.8.0':
|
||||||
|
resolution: {integrity: sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==}
|
||||||
|
|
||||||
'@floating-ui/dom@1.7.5':
|
'@floating-ui/dom@1.7.5':
|
||||||
resolution: {integrity: sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg==}
|
resolution: {integrity: sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg==}
|
||||||
|
|
||||||
|
'@floating-ui/dom@1.8.0':
|
||||||
|
resolution: {integrity: sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==}
|
||||||
|
|
||||||
|
'@floating-ui/react-dom@2.1.9':
|
||||||
|
resolution: {integrity: sha512-JDjEFGCpImxDCA7JJKviA0M9+RtmJdj0m/NVU5IMgBK+AmZouAQQ7/+2GLH0GXXY0YMw9oXPB8hKdbPYg5QLYg==}
|
||||||
|
peerDependencies:
|
||||||
|
react: '>=16.8.0'
|
||||||
|
react-dom: '>=16.8.0'
|
||||||
|
|
||||||
'@floating-ui/utils@0.2.10':
|
'@floating-ui/utils@0.2.10':
|
||||||
resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==}
|
resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==}
|
||||||
|
|
||||||
|
'@floating-ui/utils@0.2.12':
|
||||||
|
resolution: {integrity: sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==}
|
||||||
|
|
||||||
'@fontsource/zcool-qingke-huangyou@5.3.0':
|
'@fontsource/zcool-qingke-huangyou@5.3.0':
|
||||||
resolution: {integrity: sha512-6/ld8x/knq1NjDQxLSyg9pDnBPOmtWDb30ZTFk+n8OxfkBoUvPAxh3aV/6+UFGmA5CekJfcgpUwd2/x/weLvSQ==}
|
resolution: {integrity: sha512-6/ld8x/knq1NjDQxLSyg9pDnBPOmtWDb30ZTFk+n8OxfkBoUvPAxh3aV/6+UFGmA5CekJfcgpUwd2/x/weLvSQ==}
|
||||||
|
|
||||||
|
'@glass-sdk/liquid-glass@0.0.2':
|
||||||
|
resolution: {integrity: sha512-bDVDBXj6Cw++U0k9fcrSPEexnVnj/S4BjxF1t7NVQqW8La1gSVtxzPl9dG2VQxKs7Ik9kWR8Zi32JzyggI5Seg==}
|
||||||
|
peerDependencies:
|
||||||
|
react: '>=19.0.0'
|
||||||
|
react-dom: '>=19.0.0'
|
||||||
|
|
||||||
'@handsontable/pikaday@1.0.0':
|
'@handsontable/pikaday@1.0.0':
|
||||||
resolution: {integrity: sha512-1VN6N38t5/DcjJ7y7XUYrDx1LuzvvzlrFdBdMG90Qo1xc8+LXHqbWbsTEm5Ec5gXTEbDEO53vUT35R+2COmOyg==}
|
resolution: {integrity: sha512-1VN6N38t5/DcjJ7y7XUYrDx1LuzvvzlrFdBdMG90Qo1xc8+LXHqbWbsTEm5Ec5gXTEbDEO53vUT35R+2COmOyg==}
|
||||||
|
|
||||||
@ -1027,12 +1081,24 @@ packages:
|
|||||||
'@lezer/xml@1.0.6':
|
'@lezer/xml@1.0.6':
|
||||||
resolution: {integrity: sha512-CdDwirL0OEaStFue/66ZmFSeppuL6Dwjlk8qk153mSQwiSH/Dlri4GNymrNWnUmPl2Um7QfV1FO9KFUyX3Twww==}
|
resolution: {integrity: sha512-CdDwirL0OEaStFue/66ZmFSeppuL6Dwjlk8qk153mSQwiSH/Dlri4GNymrNWnUmPl2Um7QfV1FO9KFUyX3Twww==}
|
||||||
|
|
||||||
|
'@lisse/core@0.7.3':
|
||||||
|
resolution: {integrity: sha512-WJWGskrOInlIs+DqK1CfAHNIjWBJ8t4AtM1cPn5RZfu2OmQumBdNGAhFuaIg+tgpibqP17GSwEiMq/fT+NCoIw==}
|
||||||
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
'@marijn/find-cluster-break@1.0.2':
|
'@marijn/find-cluster-break@1.0.2':
|
||||||
resolution: {integrity: sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==}
|
resolution: {integrity: sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==}
|
||||||
|
|
||||||
'@mermaid-js/parser@1.2.0':
|
'@mermaid-js/parser@1.2.0':
|
||||||
resolution: {integrity: sha512-oYPyv8A4As1yH5Bx+04iQEQxXuIQDe0GKCNSRgao6z8AM9jixXIfP0vsppRLvGf+nKIOb9/LdpWA4YuJiVvESA==}
|
resolution: {integrity: sha512-oYPyv8A4As1yH5Bx+04iQEQxXuIQDe0GKCNSRgao6z8AM9jixXIfP0vsppRLvGf+nKIOb9/LdpWA4YuJiVvESA==}
|
||||||
|
|
||||||
|
'@modelcontextprotocol/core@2.0.0':
|
||||||
|
resolution: {integrity: sha512-pJCEwGG7Lfr/+PQp9ZTwKXNeO5wzbfKL7H3MYpCorM4oFBoQrdjnBgEoqG+RjhsvS1FKrDbKux+M1HhlnGWqcA==}
|
||||||
|
engines: {node: '>=20'}
|
||||||
|
|
||||||
|
'@modelcontextprotocol/server@2.0.0':
|
||||||
|
resolution: {integrity: sha512-YhHWdHfpFMQfd0prsEnxKeS3Qz3ytIGmsS0sth4KDjnacIT7hxk6hXHkJ9KysxlkvTM+WZAtQbbcUhdoP4Hvtw==}
|
||||||
|
engines: {node: '>=20'}
|
||||||
|
|
||||||
'@mrmlnc/readdir-enhanced@2.2.1':
|
'@mrmlnc/readdir-enhanced@2.2.1':
|
||||||
resolution: {integrity: sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==}
|
resolution: {integrity: sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
@ -1841,6 +1907,26 @@ packages:
|
|||||||
'@upsetjs/venn.js@2.0.0':
|
'@upsetjs/venn.js@2.0.0':
|
||||||
resolution: {integrity: sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw==}
|
resolution: {integrity: sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw==}
|
||||||
|
|
||||||
|
'@vgpu/adapter-mock@0.5.0':
|
||||||
|
resolution: {integrity: sha512-YtgXOFn1qI+8oTJenG2wWbQPA28V0CfE5UJs5Xqbt6qyR/xaZ5LHH2XWTwFcjnqn2b1xQCyTatJCMyyOdweUnw==}
|
||||||
|
|
||||||
|
'@vgpu/adapter-node@0.5.0':
|
||||||
|
resolution: {integrity: sha512-lgzqFcLDejwRgwlaNStzkwLNU9b4aN2OoPpWqT1UyPmK521BSw2OIQKzAuDIkzNlREla6KNC12G6bthhOzZKzw==}
|
||||||
|
|
||||||
|
'@vgpu/core@0.5.0':
|
||||||
|
resolution: {integrity: sha512-z80DHRHViv6+FKKkPzggEtT1ZZs/WCKRQbzJuwYdA135DZaSbCMoRK4anhM+I/nOHuDpf7H3xjkwE6rfolWZUw==}
|
||||||
|
|
||||||
|
'@vgpu/wgsl-std@0.5.0':
|
||||||
|
resolution: {integrity: sha512-NjMyJxwy4evFNCSqFQy4EqAbZ7iU+NUyJYyG9tLUhbdDLzBmfZlk1S3PyRZ9olBFFfEiVW2JNVw10maPKLEs1A==}
|
||||||
|
|
||||||
|
'@vgpu/wgsl@0.5.0':
|
||||||
|
resolution: {integrity: sha512-PDlDJem7J28C9bk+vPy2kYZEoW8+nYIx2oN4nu7/WF2V7ETx32BtmWcawwMbhiu/CVsobFafML0h0eqLRBNa3Q==}
|
||||||
|
peerDependencies:
|
||||||
|
'@vgpu/adapter-node': '>=0.1.6 <1.0.0 || ^0.5.0-rc.0'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@vgpu/adapter-node':
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@vitejs/plugin-vue-jsx@2.1.1':
|
'@vitejs/plugin-vue-jsx@2.1.1':
|
||||||
resolution: {integrity: sha512-JgDhxstQlwnHBvZ1BSnU5mbmyQ14/t5JhREc6YH5kWyu2QdAAOsLF6xgHoIWarj8tddaiwFrNzLbWJPudpXKYA==}
|
resolution: {integrity: sha512-JgDhxstQlwnHBvZ1BSnU5mbmyQ14/t5JhREc6YH5kWyu2QdAAOsLF6xgHoIWarj8tddaiwFrNzLbWJPudpXKYA==}
|
||||||
engines: {node: ^14.18.0 || >=16.0.0}
|
engines: {node: ^14.18.0 || >=16.0.0}
|
||||||
@ -1947,6 +2033,9 @@ packages:
|
|||||||
'@vueuse/shared@9.13.0':
|
'@vueuse/shared@9.13.0':
|
||||||
resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==}
|
resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==}
|
||||||
|
|
||||||
|
'@webgpu/types@0.1.74':
|
||||||
|
resolution: {integrity: sha512-lgiI4hbuLcI9unnm2cL/tvCaQU45dp0xcLWJh5uB/9MBGvIA4F8XIk7nSiBeg+K4xWGYwgZKn80LmERI5CxoTA==}
|
||||||
|
|
||||||
'@wtto00/html2canvas@1.4.3':
|
'@wtto00/html2canvas@1.4.3':
|
||||||
resolution: {integrity: sha512-jwsb+xL8N+gjrSNABSaFdxmWtE4c7RNFjP20lo1G7gs63Qqo1phhxVBTzxc/apDVh6LgXsU2l5bwKtXd9uz65w==}
|
resolution: {integrity: sha512-jwsb+xL8N+gjrSNABSaFdxmWtE4c7RNFjP20lo1G7gs63Qqo1phhxVBTzxc/apDVh6LgXsU2l5bwKtXd9uz65w==}
|
||||||
engines: {node: '>=8.0.0'}
|
engines: {node: '>=8.0.0'}
|
||||||
@ -5469,6 +5558,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==}
|
resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
pixelmatch@7.2.0:
|
||||||
|
resolution: {integrity: sha512-xhcb4yHu9sM/G7foGzoLtXYcC0zHEaOXXjRKhGup0fw78Nf2Tkiapv4EQyMzrbcmQPsllAI7DbFY2UT7PlI9Pg==}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
pkg-types@1.3.1:
|
pkg-types@1.3.1:
|
||||||
resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==}
|
resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==}
|
||||||
|
|
||||||
@ -5479,6 +5572,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==}
|
resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==}
|
||||||
engines: {node: '>=10.13.0'}
|
engines: {node: '>=10.13.0'}
|
||||||
|
|
||||||
|
pngjs@7.0.0:
|
||||||
|
resolution: {integrity: sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==}
|
||||||
|
engines: {node: '>=14.19.0'}
|
||||||
|
|
||||||
pngquant-bin@6.0.1:
|
pngquant-bin@6.0.1:
|
||||||
resolution: {integrity: sha512-Q3PUyolfktf+hYio6wsg3SanQzEU/v8aICg/WpzxXcuCMRb7H2Q81okfpcEztbMvw25ILjd3a87doj2N9kvbpQ==}
|
resolution: {integrity: sha512-Q3PUyolfktf+hYio6wsg3SanQzEU/v8aICg/WpzxXcuCMRb7H2Q81okfpcEztbMvw25ILjd3a87doj2N9kvbpQ==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@ -5679,6 +5776,15 @@ packages:
|
|||||||
raf@3.4.1:
|
raf@3.4.1:
|
||||||
resolution: {integrity: sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==}
|
resolution: {integrity: sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==}
|
||||||
|
|
||||||
|
react-dom@19.3.1:
|
||||||
|
resolution: {integrity: sha512-Y0bARz53lhEC1NMCASs0/j+faB/zqt3R8hpvg1e8+61ZVJ4UL0UdC4cBbXfZMcIuhrfgeILTLe+ZeBCavQPtKQ==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^19.3.1
|
||||||
|
|
||||||
|
react@19.3.1:
|
||||||
|
resolution: {integrity: sha512-QNhWdt7nrgVWWQG58QuGsAR3jv3Hbe4mb4vz7w2csnHavciZJgda1CPNaldF6eVxv90ud3jUXpKlHL69gO38yw==}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
read-pkg-up@1.0.1:
|
read-pkg-up@1.0.1:
|
||||||
resolution: {integrity: sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==}
|
resolution: {integrity: sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@ -5791,6 +5897,9 @@ packages:
|
|||||||
require-main-filename@2.0.0:
|
require-main-filename@2.0.0:
|
||||||
resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==}
|
resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==}
|
||||||
|
|
||||||
|
reselect@5.3.0:
|
||||||
|
resolution: {integrity: sha512-XGoLeRAVzUTcJ1qkxPQhDJyIZ5d6zzZD9nT7AEZOaaU9UbWclhycElmhO+VD5bFeLuzhPBaOV2oXC8uG35ZSpg==}
|
||||||
|
|
||||||
reserved-words@0.1.2:
|
reserved-words@0.1.2:
|
||||||
resolution: {integrity: sha512-0S5SrIUJ9LfpbVl4Yzij6VipUdafHrOTzvmfazSw/jeZrZtQK303OPZW+obtkaw7jQlTQppy0UvZWm9872PbRw==}
|
resolution: {integrity: sha512-0S5SrIUJ9LfpbVl4Yzij6VipUdafHrOTzvmfazSw/jeZrZtQK303OPZW+obtkaw7jQlTQppy0UvZWm9872PbRw==}
|
||||||
|
|
||||||
@ -6044,6 +6153,9 @@ packages:
|
|||||||
sax@1.4.1:
|
sax@1.4.1:
|
||||||
resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==}
|
resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==}
|
||||||
|
|
||||||
|
scheduler@0.28.0:
|
||||||
|
resolution: {integrity: sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw==}
|
||||||
|
|
||||||
screenfull@5.2.0:
|
screenfull@5.2.0:
|
||||||
resolution: {integrity: sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==}
|
resolution: {integrity: sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@ -6919,6 +7031,11 @@ packages:
|
|||||||
resolution: {integrity: sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A==}
|
resolution: {integrity: sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A==}
|
||||||
engines: {node: '>= 4'}
|
engines: {node: '>= 4'}
|
||||||
|
|
||||||
|
use-sync-external-store@1.7.0:
|
||||||
|
resolution: {integrity: sha512-6L+EeigHMQhdaIPNIFUKwfWJSwWFQ8gJbJ2DLOs5sDIegTwR9fRxvnM3uciHKjIZhFz+KAv2emhWMRvDmMcY8A==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||||
|
|
||||||
use@3.1.1:
|
use@3.1.1:
|
||||||
resolution: {integrity: sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==}
|
resolution: {integrity: sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@ -6966,6 +7083,15 @@ packages:
|
|||||||
resolution: {integrity: sha512-KoJRp8V2EsmeW2pg33CVEOEfGDTmcVLL0wk0fOQJjgXfAunciPylOueKovuzlbWSrTQap1UzgNn8xr5zbBsnPA==}
|
resolution: {integrity: sha512-KoJRp8V2EsmeW2pg33CVEOEfGDTmcVLL0wk0fOQJjgXfAunciPylOueKovuzlbWSrTQap1UzgNn8xr5zbBsnPA==}
|
||||||
engines: {node: '>=18.18.0'}
|
engines: {node: '>=18.18.0'}
|
||||||
|
|
||||||
|
vgpu@0.5.0:
|
||||||
|
resolution: {integrity: sha512-isQfMHRTysYFfT8UWTzqQI/ROw2L7lVkj7xoUJlvIF6FjYxBNS/YNG7qp3tZ7ZvZZ3uwYjso+geQv/bEq5Hl3w==}
|
||||||
|
hasBin: true
|
||||||
|
peerDependencies:
|
||||||
|
three: '>=0.180.0 <0.200.0'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
three:
|
||||||
|
optional: true
|
||||||
|
|
||||||
vite-plugin-compression@0.5.1:
|
vite-plugin-compression@0.5.1:
|
||||||
resolution: {integrity: sha512-5QJKBDc+gNYVqL/skgFAP81Yuzo9R+EAf19d+EtsMF/i8kFUpNi3J/H01QD3Oo8zBQn+NzoCIFkpPLynoOzaJg==}
|
resolution: {integrity: sha512-5QJKBDc+gNYVqL/skgFAP81Yuzo9R+EAf19d+EtsMF/i8kFUpNi3J/H01QD3Oo8zBQn+NzoCIFkpPLynoOzaJg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -7152,12 +7278,18 @@ packages:
|
|||||||
w3c-keyname@2.2.8:
|
w3c-keyname@2.2.8:
|
||||||
resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==}
|
resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==}
|
||||||
|
|
||||||
|
webgpu@0.4.0:
|
||||||
|
resolution: {integrity: sha512-F5pimn3Aoi0zWjuRdiVs5TnrUwSzD2lESBohsIUsqyitWkGRQlXU2fhV6ycXlQTa1bvAf3sjqiUpBEpmSQ5ptA==}
|
||||||
|
|
||||||
webidl-conversions@3.0.1:
|
webidl-conversions@3.0.1:
|
||||||
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
|
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
|
||||||
|
|
||||||
webpack-virtual-modules@0.6.2:
|
webpack-virtual-modules@0.6.2:
|
||||||
resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==}
|
resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==}
|
||||||
|
|
||||||
|
wgpu-matrix@3.4.2:
|
||||||
|
resolution: {integrity: sha512-IfZFbG7olEYBD76VCZy2TzqM57GKy3LT++AZh37tMHPPByO6R2h61zXGBZFNPi2IzxNivNi8y5dvze5PjaczjA==}
|
||||||
|
|
||||||
whatwg-url@5.0.0:
|
whatwg-url@5.0.0:
|
||||||
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
|
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
|
||||||
|
|
||||||
@ -7325,6 +7457,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
zod@4.6.7:
|
||||||
|
resolution: {integrity: sha512-g8W2D2kU6a8untc053fX1uVBKzM7yqAxW/3zwk83+6RyF2+SKOuV+c0wBDhUwzV1PaGapmZH+rmcUzPf+3CGwg==}
|
||||||
|
|
||||||
zrender@5.6.1:
|
zrender@5.6.1:
|
||||||
resolution: {integrity: sha512-OFXkDJKcrlx5su2XbzJvj/34Q3m6PvyCZkVPHGYpcCJ52ek4U/ymZyfuV1nKE23AyBJ51E/6Yr0mhZ7xGTO4ag==}
|
resolution: {integrity: sha512-OFXkDJKcrlx5su2XbzJvj/34Q3m6PvyCZkVPHGYpcCJ52ek4U/ymZyfuV1nKE23AyBJ51E/6Yr0mhZ7xGTO4ag==}
|
||||||
|
|
||||||
@ -7517,6 +7652,8 @@ snapshots:
|
|||||||
|
|
||||||
'@babel/runtime@7.28.6': {}
|
'@babel/runtime@7.28.6': {}
|
||||||
|
|
||||||
|
'@babel/runtime@8.1.0': {}
|
||||||
|
|
||||||
'@babel/template@7.27.2':
|
'@babel/template@7.27.2':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/code-frame': 7.27.1
|
'@babel/code-frame': 7.27.1
|
||||||
@ -7540,6 +7677,25 @@ snapshots:
|
|||||||
'@babel/helper-string-parser': 7.27.1
|
'@babel/helper-string-parser': 7.27.1
|
||||||
'@babel/helper-validator-identifier': 7.27.1
|
'@babel/helper-validator-identifier': 7.27.1
|
||||||
|
|
||||||
|
'@base-ui/react@1.9.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 8.1.0
|
||||||
|
'@base-ui/utils': 0.5.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
|
||||||
|
'@floating-ui/react-dom': 2.1.9(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
|
||||||
|
'@floating-ui/utils': 0.2.12
|
||||||
|
react: 19.3.1
|
||||||
|
react-dom: 19.3.1(react@19.3.1)
|
||||||
|
use-sync-external-store: 1.7.0(react@19.3.1)
|
||||||
|
|
||||||
|
'@base-ui/utils@0.5.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1)':
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 8.1.0
|
||||||
|
'@floating-ui/utils': 0.2.12
|
||||||
|
react: 19.3.1
|
||||||
|
react-dom: 19.3.1(react@19.3.1)
|
||||||
|
reselect: 5.3.0
|
||||||
|
use-sync-external-store: 1.7.0(react@19.3.1)
|
||||||
|
|
||||||
'@braintree/sanitize-url@7.1.2': {}
|
'@braintree/sanitize-url@7.1.2': {}
|
||||||
|
|
||||||
'@bufbuild/protobuf@2.10.1': {}
|
'@bufbuild/protobuf@2.10.1': {}
|
||||||
@ -7955,15 +8111,46 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@floating-ui/utils': 0.2.10
|
'@floating-ui/utils': 0.2.10
|
||||||
|
|
||||||
|
'@floating-ui/core@1.8.0':
|
||||||
|
dependencies:
|
||||||
|
'@floating-ui/utils': 0.2.12
|
||||||
|
|
||||||
'@floating-ui/dom@1.7.5':
|
'@floating-ui/dom@1.7.5':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@floating-ui/core': 1.7.4
|
'@floating-ui/core': 1.7.4
|
||||||
'@floating-ui/utils': 0.2.10
|
'@floating-ui/utils': 0.2.10
|
||||||
|
|
||||||
|
'@floating-ui/dom@1.8.0':
|
||||||
|
dependencies:
|
||||||
|
'@floating-ui/core': 1.8.0
|
||||||
|
'@floating-ui/utils': 0.2.12
|
||||||
|
|
||||||
|
'@floating-ui/react-dom@2.1.9(react-dom@19.3.1(react@19.3.1))(react@19.3.1)':
|
||||||
|
dependencies:
|
||||||
|
'@floating-ui/dom': 1.8.0
|
||||||
|
react: 19.3.1
|
||||||
|
react-dom: 19.3.1(react@19.3.1)
|
||||||
|
|
||||||
'@floating-ui/utils@0.2.10': {}
|
'@floating-ui/utils@0.2.10': {}
|
||||||
|
|
||||||
|
'@floating-ui/utils@0.2.12': {}
|
||||||
|
|
||||||
'@fontsource/zcool-qingke-huangyou@5.3.0': {}
|
'@fontsource/zcool-qingke-huangyou@5.3.0': {}
|
||||||
|
|
||||||
|
'@glass-sdk/liquid-glass@0.0.2(react-dom@19.3.1(react@19.3.1))(react@19.3.1)':
|
||||||
|
dependencies:
|
||||||
|
'@base-ui/react': 1.9.0(react-dom@19.3.1(react@19.3.1))(react@19.3.1)
|
||||||
|
'@lisse/core': 0.7.3
|
||||||
|
react: 19.3.1
|
||||||
|
react-dom: 19.3.1(react@19.3.1)
|
||||||
|
vgpu: 0.5.0
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@date-fns/tz'
|
||||||
|
- '@types/react'
|
||||||
|
- date-fns
|
||||||
|
- supports-color
|
||||||
|
- three
|
||||||
|
|
||||||
'@handsontable/pikaday@1.0.0': {}
|
'@handsontable/pikaday@1.0.0': {}
|
||||||
|
|
||||||
'@handsontable/vue3@16.2.0(handsontable@16.2.0)(vue@3.5.18(typescript@4.9.5))':
|
'@handsontable/vue3@16.2.0(handsontable@16.2.0)(vue@3.5.18(typescript@4.9.5))':
|
||||||
@ -8078,12 +8265,23 @@ snapshots:
|
|||||||
'@lezer/highlight': 1.2.3
|
'@lezer/highlight': 1.2.3
|
||||||
'@lezer/lr': 1.4.8
|
'@lezer/lr': 1.4.8
|
||||||
|
|
||||||
|
'@lisse/core@0.7.3': {}
|
||||||
|
|
||||||
'@marijn/find-cluster-break@1.0.2': {}
|
'@marijn/find-cluster-break@1.0.2': {}
|
||||||
|
|
||||||
'@mermaid-js/parser@1.2.0':
|
'@mermaid-js/parser@1.2.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@chevrotain/types': 11.1.2
|
'@chevrotain/types': 11.1.2
|
||||||
|
|
||||||
|
'@modelcontextprotocol/core@2.0.0':
|
||||||
|
dependencies:
|
||||||
|
zod: 4.6.7
|
||||||
|
|
||||||
|
'@modelcontextprotocol/server@2.0.0':
|
||||||
|
dependencies:
|
||||||
|
'@modelcontextprotocol/core': 2.0.0
|
||||||
|
zod: 4.6.7
|
||||||
|
|
||||||
'@mrmlnc/readdir-enhanced@2.2.1':
|
'@mrmlnc/readdir-enhanced@2.2.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
call-me-maybe: 1.0.2
|
call-me-maybe: 1.0.2
|
||||||
@ -8907,6 +9105,33 @@ snapshots:
|
|||||||
d3-selection: 3.0.0
|
d3-selection: 3.0.0
|
||||||
d3-transition: 3.0.1(d3-selection@3.0.0)
|
d3-transition: 3.0.1(d3-selection@3.0.0)
|
||||||
|
|
||||||
|
'@vgpu/adapter-mock@0.5.0(@vgpu/adapter-node@0.5.0)':
|
||||||
|
dependencies:
|
||||||
|
'@vgpu/core': 0.5.0(@vgpu/adapter-node@0.5.0)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@vgpu/adapter-node'
|
||||||
|
|
||||||
|
'@vgpu/adapter-node@0.5.0':
|
||||||
|
dependencies:
|
||||||
|
'@vgpu/core': 0.5.0(@vgpu/adapter-node@0.5.0)
|
||||||
|
webgpu: 0.4.0
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
|
'@vgpu/core@0.5.0(@vgpu/adapter-node@0.5.0)':
|
||||||
|
dependencies:
|
||||||
|
'@vgpu/wgsl': 0.5.0(@vgpu/adapter-node@0.5.0)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@vgpu/adapter-node'
|
||||||
|
|
||||||
|
'@vgpu/wgsl-std@0.5.0': {}
|
||||||
|
|
||||||
|
'@vgpu/wgsl@0.5.0(@vgpu/adapter-node@0.5.0)':
|
||||||
|
dependencies:
|
||||||
|
'@vgpu/wgsl-std': 0.5.0
|
||||||
|
optionalDependencies:
|
||||||
|
'@vgpu/adapter-node': 0.5.0
|
||||||
|
|
||||||
'@vitejs/plugin-vue-jsx@2.1.1(vite@6.3.5(@types/node@20.5.1)(jiti@1.21.7)(less@4.4.0)(sass-embedded@1.93.3)(sass@1.93.3)(sugarss@2.0.0)(tsx@4.20.3))(vue@3.5.18(typescript@4.9.5))':
|
'@vitejs/plugin-vue-jsx@2.1.1(vite@6.3.5(@types/node@20.5.1)(jiti@1.21.7)(less@4.4.0)(sass-embedded@1.93.3)(sass@1.93.3)(sugarss@2.0.0)(tsx@4.20.3))(vue@3.5.18(typescript@4.9.5))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/core': 7.28.0
|
'@babel/core': 7.28.0
|
||||||
@ -9090,6 +9315,8 @@ snapshots:
|
|||||||
- '@vue/composition-api'
|
- '@vue/composition-api'
|
||||||
- vue
|
- vue
|
||||||
|
|
||||||
|
'@webgpu/types@0.1.74': {}
|
||||||
|
|
||||||
'@wtto00/html2canvas@1.4.3':
|
'@wtto00/html2canvas@1.4.3':
|
||||||
dependencies:
|
dependencies:
|
||||||
css-line-break: 2.1.0
|
css-line-break: 2.1.0
|
||||||
@ -12931,6 +13158,10 @@ snapshots:
|
|||||||
|
|
||||||
pinkie@2.0.4: {}
|
pinkie@2.0.4: {}
|
||||||
|
|
||||||
|
pixelmatch@7.2.0:
|
||||||
|
dependencies:
|
||||||
|
pngjs: 7.0.0
|
||||||
|
|
||||||
pkg-types@1.3.1:
|
pkg-types@1.3.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
confbox: 0.1.8
|
confbox: 0.1.8
|
||||||
@ -12945,6 +13176,8 @@ snapshots:
|
|||||||
|
|
||||||
pngjs@5.0.0: {}
|
pngjs@5.0.0: {}
|
||||||
|
|
||||||
|
pngjs@7.0.0: {}
|
||||||
|
|
||||||
pngquant-bin@6.0.1:
|
pngquant-bin@6.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
bin-build: 3.0.0
|
bin-build: 3.0.0
|
||||||
@ -13129,6 +13362,13 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
performance-now: 2.1.0
|
performance-now: 2.1.0
|
||||||
|
|
||||||
|
react-dom@19.3.1(react@19.3.1):
|
||||||
|
dependencies:
|
||||||
|
react: 19.3.1
|
||||||
|
scheduler: 0.28.0
|
||||||
|
|
||||||
|
react@19.3.1: {}
|
||||||
|
|
||||||
read-pkg-up@1.0.1:
|
read-pkg-up@1.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
find-up: 1.1.2
|
find-up: 1.1.2
|
||||||
@ -13293,6 +13533,8 @@ snapshots:
|
|||||||
|
|
||||||
require-main-filename@2.0.0: {}
|
require-main-filename@2.0.0: {}
|
||||||
|
|
||||||
|
reselect@5.3.0: {}
|
||||||
|
|
||||||
reserved-words@0.1.2: {}
|
reserved-words@0.1.2: {}
|
||||||
|
|
||||||
resize-detector@0.3.0: {}
|
resize-detector@0.3.0: {}
|
||||||
@ -13535,6 +13777,8 @@ snapshots:
|
|||||||
sax@1.4.1:
|
sax@1.4.1:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
scheduler@0.28.0: {}
|
||||||
|
|
||||||
screenfull@5.2.0: {}
|
screenfull@5.2.0: {}
|
||||||
|
|
||||||
scroll-into-view-if-needed@2.2.31:
|
scroll-into-view-if-needed@2.2.31:
|
||||||
@ -14610,6 +14854,10 @@ snapshots:
|
|||||||
|
|
||||||
url-to-options@1.0.1: {}
|
url-to-options@1.0.1: {}
|
||||||
|
|
||||||
|
use-sync-external-store@1.7.0(react@19.3.1):
|
||||||
|
dependencies:
|
||||||
|
react: 19.3.1
|
||||||
|
|
||||||
use@3.1.1: {}
|
use@3.1.1: {}
|
||||||
|
|
||||||
util-deprecate@1.0.2: {}
|
util-deprecate@1.0.2: {}
|
||||||
@ -14680,6 +14928,22 @@ snapshots:
|
|||||||
- typescript
|
- typescript
|
||||||
- utf-8-validate
|
- utf-8-validate
|
||||||
|
|
||||||
|
vgpu@0.5.0:
|
||||||
|
dependencies:
|
||||||
|
'@modelcontextprotocol/server': 2.0.0
|
||||||
|
'@vgpu/adapter-mock': 0.5.0(@vgpu/adapter-node@0.5.0)
|
||||||
|
'@vgpu/adapter-node': 0.5.0
|
||||||
|
'@vgpu/core': 0.5.0(@vgpu/adapter-node@0.5.0)
|
||||||
|
'@vgpu/wgsl': 0.5.0(@vgpu/adapter-node@0.5.0)
|
||||||
|
'@vgpu/wgsl-std': 0.5.0
|
||||||
|
'@webgpu/types': 0.1.74
|
||||||
|
pixelmatch: 7.2.0
|
||||||
|
pngjs: 7.0.0
|
||||||
|
wgpu-matrix: 3.4.2
|
||||||
|
zod: 4.6.7
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
vite-plugin-compression@0.5.1(vite@6.3.5(@types/node@20.5.1)(jiti@1.21.7)(less@4.4.0)(sass-embedded@1.93.3)(sass@1.93.3)(sugarss@2.0.0)(tsx@4.20.3)):
|
vite-plugin-compression@0.5.1(vite@6.3.5(@types/node@20.5.1)(jiti@1.21.7)(less@4.4.0)(sass-embedded@1.93.3)(sass@1.93.3)(sugarss@2.0.0)(tsx@4.20.3)):
|
||||||
dependencies:
|
dependencies:
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
@ -14893,10 +15157,19 @@ snapshots:
|
|||||||
|
|
||||||
w3c-keyname@2.2.8: {}
|
w3c-keyname@2.2.8: {}
|
||||||
|
|
||||||
|
webgpu@0.4.0:
|
||||||
|
dependencies:
|
||||||
|
'@webgpu/types': 0.1.74
|
||||||
|
debug: 4.4.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
|
||||||
webidl-conversions@3.0.1: {}
|
webidl-conversions@3.0.1: {}
|
||||||
|
|
||||||
webpack-virtual-modules@0.6.2: {}
|
webpack-virtual-modules@0.6.2: {}
|
||||||
|
|
||||||
|
wgpu-matrix@3.4.2: {}
|
||||||
|
|
||||||
whatwg-url@5.0.0:
|
whatwg-url@5.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
tr46: 0.0.3
|
tr46: 0.0.3
|
||||||
@ -15076,6 +15349,8 @@ snapshots:
|
|||||||
|
|
||||||
yocto-queue@0.1.0: {}
|
yocto-queue@0.1.0: {}
|
||||||
|
|
||||||
|
zod@4.6.7: {}
|
||||||
|
|
||||||
zrender@5.6.1:
|
zrender@5.6.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
tslib: 2.3.0
|
tslib: 2.3.0
|
||||||
|
|||||||
@ -4451,6 +4451,33 @@ export default {
|
|||||||
'system.batchEmail.logSendFail': 'failed - {msg}',
|
'system.batchEmail.logSendFail': 'failed - {msg}',
|
||||||
'system.batchEmail.logSendDone': 'Done: {total} total, {successCount} ok, {failCount} failed',
|
'system.batchEmail.logSendDone': 'Done: {total} total, {successCount} ok, {failCount} failed',
|
||||||
'system.batchEmail.msgSendDone': 'Done: {successCount} succeeded, {failCount} failed',
|
'system.batchEmail.msgSendDone': 'Done: {successCount} succeeded, {failCount} failed',
|
||||||
|
'system.batchEmail.accountReady': 'Mailbox ready · {account}',
|
||||||
|
'system.batchEmail.accountNotReady': 'Mailbox not configured — set it up before sending',
|
||||||
|
'system.batchEmail.templateEdit': 'Edit template',
|
||||||
|
'system.batchEmail.placeholderInsertHint': 'Click to insert a placeholder at the subject/body cursor',
|
||||||
|
'system.batchEmail.sendProgressTitle': 'Batch send progress',
|
||||||
|
'system.batchEmail.sendProgressMeta': '{current}/{total} processed · {success} ok · {fail} failed',
|
||||||
|
'system.batchEmail.sendProgressCurrent': 'Current: {email}',
|
||||||
|
'system.batchEmail.sendConfirmTitle': 'Confirm batch send',
|
||||||
|
'system.batchEmail.sendConfirmOk': 'Send now',
|
||||||
|
'system.batchEmail.sendConfirmAccount': 'From',
|
||||||
|
'system.batchEmail.sendConfirmCount': 'Recipients',
|
||||||
|
'system.batchEmail.sendConfirmHint': 'Messages are sent one by one with the current template. You can cancel remaining sends; already sent emails cannot be recalled.',
|
||||||
|
'system.batchEmail.cancelSend': 'Cancel remaining',
|
||||||
|
'system.batchEmail.sendFailList': 'Failures ({n})',
|
||||||
|
'system.batchEmail.copyFailList': 'Copy list',
|
||||||
|
'system.batchEmail.msgCopyFailOk': 'Failure list copied',
|
||||||
|
'system.batchEmail.errCopyFail': 'Copy failed — select the text manually',
|
||||||
|
'system.batchEmail.failInvalidEmail': 'Invalid email',
|
||||||
|
'system.batchEmail.failEmptyBody': 'Empty body',
|
||||||
|
'system.batchEmail.msgSendCancelled': 'Cancelled: {successCount} ok, {failCount} failed',
|
||||||
|
'system.batchEmail.replacePreview': 'Placeholder preview',
|
||||||
|
'system.batchEmail.replacePreviewEmpty': 'Add recipients to preview placeholder replacement',
|
||||||
|
'system.batchEmail.replacePreviewManual': 'Based on {email} (manual emails leave order/track placeholders empty)',
|
||||||
|
'system.batchEmail.replacePreviewSample': 'Preview using first recipient {email}',
|
||||||
|
'system.batchEmail.confirmSwitchTplTitle': 'Switch template?',
|
||||||
|
'system.batchEmail.confirmSwitchTplBody': 'Subject/body were edited. Switching will discard unsaved changes.',
|
||||||
|
'system.batchEmail.removeRecipient': 'Remove this email',
|
||||||
|
|
||||||
// System - Announcement
|
// System - Announcement
|
||||||
'system.announcement.search.placeholder': 'Search title or content',
|
'system.announcement.search.placeholder': 'Search title or content',
|
||||||
|
|||||||
@ -4475,6 +4475,33 @@ export default {
|
|||||||
'system.batchEmail.logSendFail': '收件人, 发送失败 - {msg}',
|
'system.batchEmail.logSendFail': '收件人, 发送失败 - {msg}',
|
||||||
'system.batchEmail.logSendDone': '结束发送: 共发送{total}封邮箱, 成功{successCount}, 失败{failCount}',
|
'system.batchEmail.logSendDone': '结束发送: 共发送{total}封邮箱, 成功{successCount}, 失败{failCount}',
|
||||||
'system.batchEmail.msgSendDone': '发送完成:成功 {successCount},失败 {failCount}',
|
'system.batchEmail.msgSendDone': '发送完成:成功 {successCount},失败 {failCount}',
|
||||||
|
'system.batchEmail.accountReady': '邮箱已配置 · {account}',
|
||||||
|
'system.batchEmail.accountNotReady': '邮箱未配置,发送前请先完成设置',
|
||||||
|
'system.batchEmail.templateEdit': '模板编辑',
|
||||||
|
'system.batchEmail.placeholderInsertHint': '点击插入占位符(插入到主题或正文光标处)',
|
||||||
|
'system.batchEmail.sendProgressTitle': '批量发送进度',
|
||||||
|
'system.batchEmail.sendProgressMeta': '已处理 {current}/{total} · 成功 {success} · 失败 {fail}',
|
||||||
|
'system.batchEmail.sendProgressCurrent': '当前:{email}',
|
||||||
|
'system.batchEmail.sendConfirmTitle': '确认批量发送',
|
||||||
|
'system.batchEmail.sendConfirmOk': '确认发送',
|
||||||
|
'system.batchEmail.sendConfirmAccount': '发件账号',
|
||||||
|
'system.batchEmail.sendConfirmCount': '收件人数',
|
||||||
|
'system.batchEmail.sendConfirmHint': '将按当前模板逐一发送,发送过程可取消;已发出的邮件无法撤回。',
|
||||||
|
'system.batchEmail.cancelSend': '取消剩余',
|
||||||
|
'system.batchEmail.sendFailList': '失败明细({n})',
|
||||||
|
'system.batchEmail.copyFailList': '复制明细',
|
||||||
|
'system.batchEmail.msgCopyFailOk': '失败明细已复制',
|
||||||
|
'system.batchEmail.errCopyFail': '复制失败,请手动选择文本',
|
||||||
|
'system.batchEmail.failInvalidEmail': '邮箱无效',
|
||||||
|
'system.batchEmail.failEmptyBody': '正文为空',
|
||||||
|
'system.batchEmail.msgSendCancelled': '已取消:成功 {successCount},失败 {failCount}',
|
||||||
|
'system.batchEmail.replacePreview': '替换预览',
|
||||||
|
'system.batchEmail.replacePreviewEmpty': '添加收件人后,可预览占位符替换效果',
|
||||||
|
'system.batchEmail.replacePreviewManual': '基于 {email}(手动邮箱无单号/轨迹时,对应占位符会为空)',
|
||||||
|
'system.batchEmail.replacePreviewSample': '基于首个收件人 {email} 的替换效果',
|
||||||
|
'system.batchEmail.confirmSwitchTplTitle': '切换模板?',
|
||||||
|
'system.batchEmail.confirmSwitchTplBody': '当前主题/正文已修改,切换将覆盖未保存的内容。',
|
||||||
|
'system.batchEmail.removeRecipient': '移除该邮箱',
|
||||||
|
|
||||||
// 系统 - 公告通知
|
// 系统 - 公告通知
|
||||||
'system.announcement.search.placeholder': '搜索标题或正文',
|
'system.announcement.search.placeholder': '搜索标题或正文',
|
||||||
|
|||||||
@ -11,8 +11,8 @@
|
|||||||
IconCopy,
|
IconCopy,
|
||||||
IconSettings,
|
IconSettings,
|
||||||
} from '@arco-design/web-vue/es/icon';
|
} from '@arco-design/web-vue/es/icon';
|
||||||
import SlidingTabs from '@/components/SlidingTabs/index.vue';
|
|
||||||
import ExcelFileIcon from '@/components/icons/ExcelFileIcon.vue';
|
import ExcelFileIcon from '@/components/icons/ExcelFileIcon.vue';
|
||||||
|
import SlidingTabs from '@/components/SlidingTabs/index.vue';
|
||||||
import CustomTemplateModal from './components/CustomTemplateModal.vue';
|
import CustomTemplateModal from './components/CustomTemplateModal.vue';
|
||||||
import SelectDeclarationSkuModal from './components/SelectDeclarationSkuModal.vue';
|
import SelectDeclarationSkuModal from './components/SelectDeclarationSkuModal.vue';
|
||||||
import FormLabelWithPreview from '@/views/channel/salesProducts/components/FormLabelWithPreview.vue';
|
import FormLabelWithPreview from '@/views/channel/salesProducts/components/FormLabelWithPreview.vue';
|
||||||
@ -5777,6 +5777,7 @@ import SelectDeclarationSkuModal from './components/SelectDeclarationSkuModal.vu
|
|||||||
min-width: 0;
|
min-width: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5787,6 +5788,22 @@ import SelectDeclarationSkuModal from './components/SelectDeclarationSkuModal.vu
|
|||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:deep(.t-tab[aria-selected='true'] .t-tab__label) {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
width: 6px;
|
||||||
|
height: 6px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #22c55e;
|
||||||
|
box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.18);
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.place-order-pane {
|
.place-order-pane {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
|
|||||||
@ -367,6 +367,9 @@ void main() {
|
|||||||
const w = Math.max(1, Math.floor(rect.width * scale));
|
const w = Math.max(1, Math.floor(rect.width * scale));
|
||||||
const h = Math.max(1, Math.floor(rect.height * scale));
|
const h = Math.max(1, Math.floor(rect.height * scale));
|
||||||
renderer.setSize(w, h);
|
renderer.setSize(w, h);
|
||||||
|
// OGL setSize writes pixel style width/height; keep CSS 100% so parent resize always fills.
|
||||||
|
canvas.style.width = '100%';
|
||||||
|
canvas.style.height = '100%';
|
||||||
const res = mu.iResolution.value;
|
const res = mu.iResolution.value;
|
||||||
res[0] = gl.drawingBufferWidth;
|
res[0] = gl.drawingBufferWidth;
|
||||||
res[1] = gl.drawingBufferHeight;
|
res[1] = gl.drawingBufferHeight;
|
||||||
|
|||||||
@ -1,33 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="ai-advisor-shell" :class="{ 'ai-history-open': historyOpen }">
|
<div
|
||||||
<div class="ai-shell-bg" aria-hidden="true">
|
id="ai-advisor-shell"
|
||||||
<GradientWaves
|
:class="{ 'ai-history-open': historyOpen }"
|
||||||
class="ai-shell-bg__waves"
|
>
|
||||||
horizon-color="#023e8a"
|
|
||||||
wave-color="#0077b6"
|
|
||||||
crest-color="#caf0f8"
|
|
||||||
:speed="0.34"
|
|
||||||
:amplitude="3.3"
|
|
||||||
:wave-scale="0.72"
|
|
||||||
:wave-ratio="0.82"
|
|
||||||
:swell="42"
|
|
||||||
:turbulence="26"
|
|
||||||
:tilt="1.08"
|
|
||||||
:zoom="0.92"
|
|
||||||
:height="4.8"
|
|
||||||
:fog-depth="22"
|
|
||||||
detail="low"
|
|
||||||
:brightness="1.08"
|
|
||||||
:opacity="1.0"
|
|
||||||
:mouse-interaction="true"
|
|
||||||
:parallax-strength="0.4"
|
|
||||||
:grain="false"
|
|
||||||
:fps="30"
|
|
||||||
:render-scale="0.72"
|
|
||||||
:max-dpr="1.25"
|
|
||||||
/>
|
|
||||||
<div class="ai-shell-bg__veil" aria-hidden="true"></div>
|
|
||||||
</div>
|
|
||||||
<div class="ai-advisor-layout">
|
<div class="ai-advisor-layout">
|
||||||
<div class="ai-advisor-app">
|
<div class="ai-advisor-app">
|
||||||
<div v-if="chatting" class="ai-stage-tools">
|
<div v-if="chatting" class="ai-stage-tools">
|
||||||
@ -57,7 +32,7 @@
|
|||||||
<div class="ai-welcome__intro">
|
<div class="ai-welcome__intro">
|
||||||
<h2 class="ai-welcome-title" :aria-label="shortTitle ? copy.titleShort : copy.title">
|
<h2 class="ai-welcome-title" :aria-label="shortTitle ? copy.titleShort : copy.title">
|
||||||
<span class="ai-welcome-title__brand" aria-hidden="true">
|
<span class="ai-welcome-title__brand" aria-hidden="true">
|
||||||
IDE<span class="ai-welcome-title__dot">.</span>
|
IDE<span class="ai-welcome-title__dot"> · </span>
|
||||||
</span>
|
</span>
|
||||||
<TextType
|
<TextType
|
||||||
v-if="titleAnimate"
|
v-if="titleAnimate"
|
||||||
@ -128,7 +103,11 @@
|
|||||||
v-for="door in primaryDoors"
|
v-for="door in primaryDoors"
|
||||||
:key="door.id"
|
:key="door.id"
|
||||||
type="button"
|
type="button"
|
||||||
class="ai-intent-door is-primary"
|
class="ai-intent-door is-primary lg-surface"
|
||||||
|
:class="{
|
||||||
|
'is-glass-ready': glassReady,
|
||||||
|
'is-glass-fallback': glassFallback,
|
||||||
|
}"
|
||||||
:disabled="busy"
|
:disabled="busy"
|
||||||
@click="onHomeDoor(door)"
|
@click="onHomeDoor(door)"
|
||||||
>
|
>
|
||||||
@ -149,25 +128,25 @@
|
|||||||
v-for="door in growthDoors"
|
v-for="door in growthDoors"
|
||||||
:key="door.id"
|
:key="door.id"
|
||||||
type="button"
|
type="button"
|
||||||
class="ai-intent-door"
|
class="ai-intent-door lg-surface"
|
||||||
:class="{
|
:class="{
|
||||||
'is-agent-tall': door.id === 'agent',
|
'is-glass-ready': glassReady,
|
||||||
'is-growth-wide': door.id === 'newcomer',
|
'is-glass-fallback': glassFallback,
|
||||||
}"
|
}"
|
||||||
:disabled="busy"
|
:disabled="busy"
|
||||||
@click="onHomeDoor(door)"
|
@click="onHomeDoor(door)"
|
||||||
>
|
>
|
||||||
|
<span class="ai-intent-door__head">
|
||||||
<span class="ai-intent-door__icon">
|
<span class="ai-intent-door__icon">
|
||||||
<SiteIllusIcon :name="door.icon" />
|
<SiteIllusIcon :name="door.icon" />
|
||||||
</span>
|
</span>
|
||||||
<span class="ai-intent-door__copy">
|
|
||||||
<span class="ai-intent-door__title">{{
|
<span class="ai-intent-door__title">{{
|
||||||
isZh ? door.zh.title : door.en.title
|
isZh ? door.zh.title : door.en.title
|
||||||
}}</span>
|
}}</span>
|
||||||
|
</span>
|
||||||
<span class="ai-intent-door__hint">{{
|
<span class="ai-intent-door__hint">{{
|
||||||
isZh ? door.zh.hint : door.en.hint
|
isZh ? door.zh.hint : door.en.hint
|
||||||
}}</span>
|
}}</span>
|
||||||
</span>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -287,7 +266,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, defineAsyncComponent, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue';
|
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue';
|
||||||
import SiteComposer from './SiteComposer.vue';
|
import SiteComposer from './SiteComposer.vue';
|
||||||
import SitePartnerMarquee from './SitePartnerMarquee.vue';
|
import SitePartnerMarquee from './SitePartnerMarquee.vue';
|
||||||
import SiteMessageCard from './SiteMessageCard.vue';
|
import SiteMessageCard from './SiteMessageCard.vue';
|
||||||
@ -295,8 +274,7 @@
|
|||||||
import TextType from './TextType.vue';
|
import TextType from './TextType.vue';
|
||||||
import { HOME_DOORS, HERO_STATS, SITE_FOLLOWUP_INTENTS, WELCOME_COPY } from './lib/site-welcome';
|
import { HOME_DOORS, HERO_STATS, SITE_FOLLOWUP_INTENTS, WELCOME_COPY } from './lib/site-welcome';
|
||||||
import { ROUTE_DEST_PRESETS } from './lib/portal-catalog';
|
import { ROUTE_DEST_PRESETS } from './lib/portal-catalog';
|
||||||
|
import { SITE_GLASS_PANEL_OPTS, useSiteLiquidGlass } from './lib/site-liquid-glass';
|
||||||
const GradientWaves = defineAsyncComponent(() => import('./GradientWaves.vue'));
|
|
||||||
|
|
||||||
export type SiteChatMessage = {
|
export type SiteChatMessage = {
|
||||||
role: 'user' | 'assistant';
|
role: 'user' | 'assistant';
|
||||||
@ -342,11 +320,35 @@
|
|||||||
choice: [payload: { id: string; label: string; flowId: string }];
|
choice: [payload: { id: string; label: string; flowId: string }];
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
const siteGlass = useSiteLiquidGlass();
|
||||||
|
const glassReady = computed(() => !!siteGlass?.ready.value);
|
||||||
|
const glassFallback = computed(() => !!siteGlass?.fallback.value);
|
||||||
|
let removeGlassSurfaces: Array<() => void> = [];
|
||||||
|
|
||||||
|
function teardownLiquidGlass() {
|
||||||
|
removeGlassSurfaces.forEach((remove) => remove());
|
||||||
|
removeGlassSurfaces = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
async function setupLiquidGlass() {
|
||||||
|
await nextTick();
|
||||||
|
if (!siteGlass || props.chatting) return;
|
||||||
|
teardownLiquidGlass();
|
||||||
|
const doorSurfaces = Array.from(
|
||||||
|
document.querySelectorAll<HTMLElement>(
|
||||||
|
'#ai-advisor-shell .ai-welcome__command .ai-intent-door.lg-surface',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
removeGlassSurfaces = doorSurfaces.map((el) =>
|
||||||
|
siteGlass.registerSurface(el, SITE_GLASS_PANEL_OPTS),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const copy = computed(() => (props.isZh ? WELCOME_COPY.zh : WELCOME_COPY.en));
|
const copy = computed(() => (props.isZh ? WELCOME_COPY.zh : WELCOME_COPY.en));
|
||||||
const homeDests = ROUTE_DEST_PRESETS.filter((item) => item.id !== 'all');
|
const homeDests = ROUTE_DEST_PRESETS.filter((item) => item.id !== 'all');
|
||||||
const primaryDoors = HOME_DOORS.filter((d) => d.primary);
|
const primaryDoors = HOME_DOORS.filter((d) => d.primary);
|
||||||
const growthDoors = HOME_DOORS.filter((d) => !d.primary);
|
const growthDoors = HOME_DOORS.filter((d) => !d.primary);
|
||||||
// 首屏即按视口决定短标题,避免挂载后再切导致 TextType 卡住只剩「IDE.」
|
// 首屏即按视口决定短标题,避免挂载后再切导致 TextType 卡住只剩品牌前缀
|
||||||
const shortTitle = ref(
|
const shortTitle = ref(
|
||||||
typeof window !== 'undefined' && window.matchMedia('(max-width: 640px)').matches,
|
typeof window !== 'undefined' && window.matchMedia('(max-width: 640px)').matches,
|
||||||
);
|
);
|
||||||
@ -397,16 +399,30 @@
|
|||||||
titleAnimate.value = !mqReduce?.matches;
|
titleAnimate.value = !mqReduce?.matches;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.chatting,
|
||||||
|
async (chatting) => {
|
||||||
|
if (chatting) {
|
||||||
|
teardownLiquidGlass();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await nextTick();
|
||||||
|
void setupLiquidGlass();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
mqNarrow = window.matchMedia('(max-width: 640px)');
|
mqNarrow = window.matchMedia('(max-width: 640px)');
|
||||||
mqReduce = window.matchMedia('(prefers-reduced-motion: reduce)');
|
mqReduce = window.matchMedia('(prefers-reduced-motion: reduce)');
|
||||||
syncMediaPrefs();
|
syncMediaPrefs();
|
||||||
mqNarrow.addEventListener('change', syncMediaPrefs);
|
mqNarrow.addEventListener('change', syncMediaPrefs);
|
||||||
mqReduce.addEventListener('change', syncMediaPrefs);
|
mqReduce.addEventListener('change', syncMediaPrefs);
|
||||||
|
void setupLiquidGlass();
|
||||||
});
|
});
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
mqNarrow?.removeEventListener('change', syncMediaPrefs);
|
mqNarrow?.removeEventListener('change', syncMediaPrefs);
|
||||||
mqReduce?.removeEventListener('change', syncMediaPrefs);
|
mqReduce?.removeEventListener('change', syncMediaPrefs);
|
||||||
|
teardownLiquidGlass();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -29,12 +29,7 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<li ref="dockRef" class="site-nav-dock">
|
<li ref="dockRef" class="site-nav-dock">
|
||||||
<span class="site-nav-dock__glass" aria-hidden="true"></span>
|
<span class="site-nav-dock__glass" aria-hidden="true"></span>
|
||||||
<span
|
<span ref="sliderRef" class="site-nav-dock__slider" aria-hidden="true"></span>
|
||||||
class="site-nav-dock__slider"
|
|
||||||
:class="{ 'is-ready': sliderReady }"
|
|
||||||
:style="sliderStyle"
|
|
||||||
aria-hidden="true"
|
|
||||||
></span>
|
|
||||||
<a
|
<a
|
||||||
v-for="item in items"
|
v-for="item in items"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
@ -210,61 +205,61 @@
|
|||||||
];
|
];
|
||||||
|
|
||||||
const dockRef = ref<HTMLElement | null>(null);
|
const dockRef = ref<HTMLElement | null>(null);
|
||||||
const sliderReady = ref(false);
|
const sliderRef = ref<HTMLElement | null>(null);
|
||||||
const sliderStyle = ref<Record<string, string>>({
|
|
||||||
left: '0px',
|
|
||||||
width: '0px',
|
|
||||||
opacity: '0',
|
|
||||||
});
|
|
||||||
const sliderPos = { x: 0, w: 0 };
|
|
||||||
let resizeObserver: ResizeObserver | null = null;
|
|
||||||
let sliderRaf = 0;
|
|
||||||
|
|
||||||
const SLIDER_INSET = 4;
|
const SLIDER_INSET = 4;
|
||||||
|
const sliderPos = { x: 0, w: 0, visible: false };
|
||||||
|
let sliderReady = false;
|
||||||
|
let sliderRaf = 0;
|
||||||
|
let resizeObserver: ResizeObserver | null = null;
|
||||||
|
let mqNarrow: MediaQueryList | null = null;
|
||||||
|
let mqReduce: MediaQueryList | null = null;
|
||||||
|
|
||||||
|
function paintSlider(x: number, w: number, visible: boolean, animate: boolean) {
|
||||||
|
const el = sliderRef.value;
|
||||||
|
if (!el) return;
|
||||||
|
|
||||||
|
const reduce = !!mqReduce?.matches;
|
||||||
|
const canAnimate = animate && sliderReady && sliderPos.visible && !reduce && sliderPos.w > 0;
|
||||||
|
el.style.transition = canAnimate
|
||||||
|
? 'transform 0.28s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.18s ease'
|
||||||
|
: 'none';
|
||||||
|
el.style.width = `${w}px`;
|
||||||
|
el.style.transform = `translate3d(${x}px, 0, 0)`;
|
||||||
|
el.style.opacity = visible ? '1' : '0';
|
||||||
|
|
||||||
function applySlider(x: number, w: number, opacity = '1') {
|
|
||||||
sliderPos.x = x;
|
sliderPos.x = x;
|
||||||
sliderPos.w = w;
|
sliderPos.w = w;
|
||||||
sliderStyle.value = {
|
sliderPos.visible = visible;
|
||||||
left: `${x}px`,
|
|
||||||
width: `${w}px`,
|
if (!sliderReady && visible) {
|
||||||
opacity,
|
requestAnimationFrame(() => {
|
||||||
};
|
sliderReady = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateSlider(animate: boolean) {
|
function updateSlider(animate: boolean) {
|
||||||
const dock = dockRef.value;
|
const dock = dockRef.value;
|
||||||
const active = dock?.querySelector<HTMLElement>('.site-nav-dock__item.is-active');
|
const active = dock?.querySelector<HTMLElement>('.site-nav-dock__item.is-active');
|
||||||
if (!dock || !active || window.matchMedia('(max-width: 1279px)').matches) {
|
if (!dock || !active || mqNarrow?.matches) {
|
||||||
sliderStyle.value = { ...sliderStyle.value, opacity: '0' };
|
paintSlider(sliderPos.x, sliderPos.w, false, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const x = active.offsetLeft + SLIDER_INSET;
|
const x = active.offsetLeft + SLIDER_INSET;
|
||||||
const w = Math.max(active.offsetWidth - SLIDER_INSET * 2, 0);
|
const w = Math.max(active.offsetWidth - SLIDER_INSET * 2, 0);
|
||||||
const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
if (
|
||||||
|
animate &&
|
||||||
// 首帧或关动画:先贴到位再开 transition,避免初次跳动
|
Math.abs(sliderPos.x - x) < 0.5 &&
|
||||||
if (!animate || !sliderReady.value || sliderPos.w <= 0 || reduceMotion) {
|
Math.abs(sliderPos.w - w) < 0.5 &&
|
||||||
sliderReady.value = false;
|
sliderPos.visible
|
||||||
applySlider(x, w);
|
) {
|
||||||
requestAnimationFrame(() => {
|
|
||||||
sliderReady.value = true;
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
paintSlider(x, w, true, animate);
|
||||||
if (Math.abs(sliderPos.x - x) < 0.5 && Math.abs(sliderPos.w - w) < 0.5) {
|
|
||||||
applySlider(x, w);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 单段滑移:left/width 一次到位,交给 CSS 缓动
|
function syncSlider(animate: boolean) {
|
||||||
applySlider(x, w);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function syncSlider(animate: boolean) {
|
|
||||||
await nextTick();
|
|
||||||
if (sliderRaf) cancelAnimationFrame(sliderRaf);
|
if (sliderRaf) cancelAnimationFrame(sliderRaf);
|
||||||
sliderRaf = requestAnimationFrame(() => {
|
sliderRaf = requestAnimationFrame(() => {
|
||||||
sliderRaf = 0;
|
sliderRaf = 0;
|
||||||
@ -273,17 +268,20 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onViewportResize() {
|
function onViewportResize() {
|
||||||
updateSlider(false);
|
sliderReady = false;
|
||||||
|
syncSlider(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
void hydrateSession();
|
void hydrateSession();
|
||||||
void syncSlider(false);
|
mqNarrow = window.matchMedia('(max-width: 1279px)');
|
||||||
if (typeof ResizeObserver !== 'undefined') {
|
mqReduce = window.matchMedia('(prefers-reduced-motion: reduce)');
|
||||||
|
void nextTick(() => syncSlider(false));
|
||||||
|
if (typeof ResizeObserver !== 'undefined' && dockRef.value) {
|
||||||
resizeObserver = new ResizeObserver(onViewportResize);
|
resizeObserver = new ResizeObserver(onViewportResize);
|
||||||
if (dockRef.value) resizeObserver.observe(dockRef.value);
|
resizeObserver.observe(dockRef.value);
|
||||||
}
|
}
|
||||||
window.addEventListener('resize', onViewportResize);
|
window.addEventListener('resize', onViewportResize, { passive: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
@ -301,8 +299,9 @@
|
|||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => [props.nav, props.isZh] as const,
|
() => [props.nav, props.isZh] as const,
|
||||||
() => {
|
async () => {
|
||||||
void syncSlider(true);
|
await nextTick();
|
||||||
|
syncSlider(true);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,13 +1,55 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="official-site"
|
ref="glassSceneEl"
|
||||||
|
class="official-site lg-scene"
|
||||||
:class="{
|
:class="{
|
||||||
'is-routes-open': panel === 'routes',
|
'is-routes-open': panel === 'routes',
|
||||||
'is-services-open': panel === 'services',
|
'is-services-open': panel === 'services',
|
||||||
'is-topic-open': panel === 'pricing' || panel === 'about' || panel === 'contact',
|
'is-topic-open': panel === 'pricing' || panel === 'about' || panel === 'contact',
|
||||||
|
'is-glass-ready': glass.ready.value,
|
||||||
|
'is-glass-fallback': glass.fallback.value,
|
||||||
}"
|
}"
|
||||||
@click.capture="onOfficialLoginCapture"
|
@click.capture="onOfficialLoginCapture"
|
||||||
>
|
>
|
||||||
|
<!--
|
||||||
|
lg-content 会被 liquid-glass 在 resize 时改写 left/right/宽高;
|
||||||
|
波浪放在固定视口 __paint 层,避免缩窗后右侧留白。
|
||||||
|
-->
|
||||||
|
<div
|
||||||
|
ref="glassContentEl"
|
||||||
|
class="ai-shell-bg lg-content"
|
||||||
|
data-layout="overlay"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<div class="ai-shell-bg__paint">
|
||||||
|
<GradientWaves
|
||||||
|
class="ai-shell-bg__waves"
|
||||||
|
horizon-color="#023e8a"
|
||||||
|
wave-color="#0077b6"
|
||||||
|
crest-color="#caf0f8"
|
||||||
|
:speed="0.34"
|
||||||
|
:amplitude="3.3"
|
||||||
|
:wave-scale="0.72"
|
||||||
|
:wave-ratio="0.82"
|
||||||
|
:swell="42"
|
||||||
|
:turbulence="26"
|
||||||
|
:tilt="1.08"
|
||||||
|
:zoom="0.92"
|
||||||
|
:height="4.8"
|
||||||
|
:fog-depth="22"
|
||||||
|
detail="low"
|
||||||
|
:brightness="1.08"
|
||||||
|
:opacity="1.0"
|
||||||
|
:mouse-interaction="true"
|
||||||
|
:parallax-strength="0.4"
|
||||||
|
:grain="false"
|
||||||
|
:fps="30"
|
||||||
|
:render-scale="0.72"
|
||||||
|
:max-dpr="1.25"
|
||||||
|
/>
|
||||||
|
<div class="ai-shell-bg__veil" aria-hidden="true"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<SiteHeader
|
<SiteHeader
|
||||||
:nav="nav"
|
:nav="nav"
|
||||||
:is-zh="isZh"
|
:is-zh="isZh"
|
||||||
@ -91,7 +133,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue';
|
import { computed, defineAsyncComponent, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import SiteHeader from './SiteHeader.vue';
|
import SiteHeader from './SiteHeader.vue';
|
||||||
import SiteAdvisorShell from './SiteAdvisorShell.vue';
|
import SiteAdvisorShell from './SiteAdvisorShell.vue';
|
||||||
@ -105,12 +147,18 @@
|
|||||||
warmupOfficialLogin,
|
warmupOfficialLogin,
|
||||||
} from './lib/site-urls';
|
} from './lib/site-urls';
|
||||||
import { shouldOpenWecomDirect, WECOM_KF_URL } from './lib/site-wecom';
|
import { shouldOpenWecomDirect, WECOM_KF_URL } from './lib/site-wecom';
|
||||||
|
import { provideSiteLiquidGlass } from './lib/site-liquid-glass';
|
||||||
import { useSiteAdvisor } from './useSiteAdvisor';
|
import { useSiteAdvisor } from './useSiteAdvisor';
|
||||||
import './styles/vendor.css';
|
import './styles/vendor.css';
|
||||||
import './styles/icons.css';
|
import './styles/icons.css';
|
||||||
import './styles/main.css';
|
import './styles/main.css';
|
||||||
import './styles/ai-advisor.css';
|
import './styles/ai-advisor.css';
|
||||||
|
|
||||||
|
const GradientWaves = defineAsyncComponent(() => import('./GradientWaves.vue'));
|
||||||
|
const glass = provideSiteLiquidGlass();
|
||||||
|
const glassSceneEl = ref<HTMLElement | null>(null);
|
||||||
|
const glassContentEl = ref<HTMLElement | null>(null);
|
||||||
|
|
||||||
type PanelId = 'routes' | 'services' | 'pricing' | 'about' | 'contact' | null;
|
type PanelId = 'routes' | 'services' | 'pricing' | 'about' | 'contact' | null;
|
||||||
const NAV_PANELS: PanelId[] = ['routes', 'services', 'pricing', 'about', 'contact'];
|
const NAV_PANELS: PanelId[] = ['routes', 'services', 'pricing', 'about', 'contact'];
|
||||||
|
|
||||||
@ -378,9 +426,15 @@
|
|||||||
if (hash === '9610' || hash === 'services') openPanel('services');
|
if (hash === '9610' || hash === 'services') openPanel('services');
|
||||||
else if (NAV_PANELS.includes(hash as PanelId)) openPanel(hash as Exclude<PanelId, null>);
|
else if (NAV_PANELS.includes(hash as PanelId)) openPanel(hash as Exclude<PanelId, null>);
|
||||||
else if (hash) nav.value = hash;
|
else if (hash) nav.value = hash;
|
||||||
|
void nextTick(() => {
|
||||||
|
if (glassSceneEl.value && glassContentEl.value) {
|
||||||
|
glass.init(glassSceneEl.value, glassContentEl.value);
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
|
glass.dispose();
|
||||||
window.removeEventListener('keydown', onKeydown);
|
window.removeEventListener('keydown', onKeydown);
|
||||||
window.removeEventListener('resize', syncHeaderOffset);
|
window.removeEventListener('resize', syncHeaderOffset);
|
||||||
window.removeEventListener('resize', syncVisualViewport);
|
window.removeEventListener('resize', syncVisualViewport);
|
||||||
@ -395,7 +449,9 @@
|
|||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.official-site {
|
.official-site {
|
||||||
|
position: relative;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
|
isolation: isolate;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
@ -419,7 +475,7 @@
|
|||||||
|
|
||||||
.site-fade-enter-active,
|
.site-fade-enter-active,
|
||||||
.site-fade-leave-active {
|
.site-fade-leave-active {
|
||||||
transition: opacity 0.32s cubic-bezier(0.22, 1, 0.36, 1);
|
transition: opacity 0.22s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-fade-enter-from,
|
.site-fade-enter-from,
|
||||||
@ -430,9 +486,8 @@
|
|||||||
.site-sheet-enter-active,
|
.site-sheet-enter-active,
|
||||||
.site-sheet-leave-active {
|
.site-sheet-leave-active {
|
||||||
transition:
|
transition:
|
||||||
opacity 0.34s cubic-bezier(0.22, 1, 0.36, 1),
|
opacity 0.24s cubic-bezier(0.22, 1, 0.36, 1),
|
||||||
transform 0.4s cubic-bezier(0.22, 1, 0.36, 1),
|
transform 0.28s cubic-bezier(0.22, 1, 0.36, 1);
|
||||||
filter 0.34s cubic-bezier(0.22, 1, 0.36, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-sheet-leave-active {
|
.site-sheet-leave-active {
|
||||||
@ -441,25 +496,21 @@
|
|||||||
|
|
||||||
.site-sheet-enter-from {
|
.site-sheet-enter-from {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
filter: blur(2px);
|
transform: translateX(-50%) translateY(-8px);
|
||||||
transform: translateX(-50%) translateY(-10px);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-sheet-leave-to {
|
.site-sheet-leave-to {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
filter: blur(1px);
|
transform: translateX(-50%) translateY(-4px);
|
||||||
transform: translateX(-50%) translateY(-6px);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 780px) {
|
@media (max-width: 780px) {
|
||||||
.site-sheet-enter-from {
|
.site-sheet-enter-from {
|
||||||
filter: none;
|
transform: translateY(12px);
|
||||||
transform: translateY(16px);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-sheet-leave-to {
|
.site-sheet-leave-to {
|
||||||
filter: none;
|
transform: translateY(8px);
|
||||||
transform: translateY(10px);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
231
src/views/site/lib/site-liquid-glass.ts
Normal file
231
src/views/site/lib/site-liquid-glass.ts
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
import { inject, provide, ref, type InjectionKey, type Ref } from 'vue';
|
||||||
|
import {
|
||||||
|
attachSelectionLens,
|
||||||
|
createGlassScene,
|
||||||
|
type GlassSceneController,
|
||||||
|
type SurfaceOptions,
|
||||||
|
} from '@glass-sdk/liquid-glass/dom';
|
||||||
|
import '@glass-sdk/liquid-glass/styles.css';
|
||||||
|
|
||||||
|
export type SiteGlassSurfaceOpts = SurfaceOptions;
|
||||||
|
|
||||||
|
type QueuedJob =
|
||||||
|
| { kind: 'surface'; el: HTMLElement; opts?: SiteGlassSurfaceOpts; setRemove: (fn: () => void) => void }
|
||||||
|
| { kind: 'indicator'; el: HTMLElement; opts?: SiteGlassSurfaceOpts; setRemove: (fn: () => void) => void };
|
||||||
|
|
||||||
|
export type SiteLiquidGlassApi = {
|
||||||
|
ready: Ref<boolean>;
|
||||||
|
fallback: Ref<boolean>;
|
||||||
|
init: (root: HTMLElement, content: HTMLElement) => void;
|
||||||
|
registerSurface: (el: HTMLElement | null | undefined, opts?: SiteGlassSurfaceOpts) => () => void;
|
||||||
|
registerTabIndicator: (el: HTMLElement | null | undefined, opts?: SiteGlassSurfaceOpts) => () => void;
|
||||||
|
dispose: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
const SITE_LIQUID_GLASS_KEY: InjectionKey<SiteLiquidGlassApi> = Symbol('site-liquid-glass');
|
||||||
|
|
||||||
|
/** 履约 / 权益门卡:低折射 + 关闭 fluid,减轻矮卡左右竖边光学校弯 */
|
||||||
|
export const SITE_GLASS_PANEL_OPTS: SiteGlassSurfaceOpts = {
|
||||||
|
material: 'clear',
|
||||||
|
appearance: 'light',
|
||||||
|
radius: 12,
|
||||||
|
refraction: 20,
|
||||||
|
fluid: false,
|
||||||
|
interactive: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SITE_GLASS_TABS_OPTS: SiteGlassSurfaceOpts = {
|
||||||
|
material: 'clear',
|
||||||
|
appearance: 'light',
|
||||||
|
radius: 'capsule',
|
||||||
|
refraction: 56,
|
||||||
|
interactive: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SITE_GLASS_TAB_INDICATOR_OPTS: SiteGlassSurfaceOpts = {
|
||||||
|
material: 'clear',
|
||||||
|
appearance: 'light',
|
||||||
|
radius: 'capsule',
|
||||||
|
refraction: 40,
|
||||||
|
interactive: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Welcome input — frosted glass, no tint */
|
||||||
|
export const SITE_GLASS_COMPOSER_OPTS: SiteGlassSurfaceOpts = {
|
||||||
|
material: 'regular',
|
||||||
|
appearance: 'light',
|
||||||
|
radius: 12,
|
||||||
|
refraction: 32,
|
||||||
|
fluid: true,
|
||||||
|
interactive: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
export function provideSiteLiquidGlass(): SiteLiquidGlassApi {
|
||||||
|
const ready = ref(false);
|
||||||
|
const fallback = ref(false);
|
||||||
|
|
||||||
|
let scene: GlassSceneController | null = null;
|
||||||
|
let removers: Array<() => void> = [];
|
||||||
|
let queue: QueuedJob[] = [];
|
||||||
|
let readyObserver: MutationObserver | null = null;
|
||||||
|
let fallbackTimer: number | null = null;
|
||||||
|
const trackedSurfaces = new Set<HTMLElement>();
|
||||||
|
|
||||||
|
function clearFallbackTimer() {
|
||||||
|
if (fallbackTimer != null) {
|
||||||
|
window.clearTimeout(fallbackTimer);
|
||||||
|
fallbackTimer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isClipReady(el: HTMLElement) {
|
||||||
|
return !!el.getAttribute('style')?.includes('clip-path');
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncReady() {
|
||||||
|
if ([...trackedSurfaces].some(isClipReady)) {
|
||||||
|
ready.value = true;
|
||||||
|
fallback.value = false;
|
||||||
|
clearFallbackTimer();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function observeSurface(el: HTMLElement) {
|
||||||
|
trackedSurfaces.add(el);
|
||||||
|
if (!readyObserver) {
|
||||||
|
readyObserver = new MutationObserver(() => {
|
||||||
|
syncReady();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
readyObserver.observe(el, { attributes: true, attributeFilter: ['style'] });
|
||||||
|
}
|
||||||
|
|
||||||
|
function bindSurface(el: HTMLElement, opts?: SiteGlassSurfaceOpts) {
|
||||||
|
if (!scene) return () => undefined;
|
||||||
|
const remove = scene.addSurface(el, opts);
|
||||||
|
observeSurface(el);
|
||||||
|
syncReady();
|
||||||
|
return () => {
|
||||||
|
trackedSurfaces.delete(el);
|
||||||
|
remove();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function bindIndicator(el: HTMLElement, opts?: SiteGlassSurfaceOpts) {
|
||||||
|
if (!scene) return () => undefined;
|
||||||
|
const removeSurface = bindSurface(el, opts ?? SITE_GLASS_TAB_INDICATOR_OPTS);
|
||||||
|
const removeAnimator = scene.addAnimator(attachSelectionLens(el, () => 'full'));
|
||||||
|
return () => {
|
||||||
|
removeAnimator();
|
||||||
|
removeSurface();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function enqueue(
|
||||||
|
kind: 'surface' | 'indicator',
|
||||||
|
el: HTMLElement,
|
||||||
|
opts?: SiteGlassSurfaceOpts,
|
||||||
|
) {
|
||||||
|
let removeFn = () => undefined;
|
||||||
|
let flushed = false;
|
||||||
|
const job: QueuedJob = {
|
||||||
|
kind,
|
||||||
|
el,
|
||||||
|
opts,
|
||||||
|
setRemove: (fn) => {
|
||||||
|
flushed = true;
|
||||||
|
removeFn = fn;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
queue.push(job);
|
||||||
|
return () => {
|
||||||
|
if (!flushed) {
|
||||||
|
queue = queue.filter((item) => item !== job);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
removeFn();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function registerSurface(el: HTMLElement | null | undefined, opts?: SiteGlassSurfaceOpts) {
|
||||||
|
if (!el) return () => undefined;
|
||||||
|
if (scene) {
|
||||||
|
const remove = bindSurface(el, opts);
|
||||||
|
removers.push(remove);
|
||||||
|
return remove;
|
||||||
|
}
|
||||||
|
return enqueue('surface', el, opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
function registerTabIndicator(el: HTMLElement | null | undefined, opts?: SiteGlassSurfaceOpts) {
|
||||||
|
if (!el) return () => undefined;
|
||||||
|
if (scene) {
|
||||||
|
const remove = bindIndicator(el, opts);
|
||||||
|
removers.push(remove);
|
||||||
|
return remove;
|
||||||
|
}
|
||||||
|
return enqueue('indicator', el, opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
function init(root: HTMLElement, content: HTMLElement) {
|
||||||
|
if (scene) return;
|
||||||
|
|
||||||
|
fallbackTimer = window.setTimeout(() => {
|
||||||
|
if (!ready.value) fallback.value = true;
|
||||||
|
}, 2200);
|
||||||
|
|
||||||
|
scene = createGlassScene(root, {
|
||||||
|
maxSurfaces: 16,
|
||||||
|
onDiagnostic: (diagnostic) => {
|
||||||
|
if (diagnostic.error) {
|
||||||
|
fallback.value = true;
|
||||||
|
ready.value = false;
|
||||||
|
} else if (diagnostic.maps > 0) {
|
||||||
|
syncReady();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
scene.setContent(content);
|
||||||
|
|
||||||
|
for (const job of queue) {
|
||||||
|
const remove =
|
||||||
|
job.kind === 'indicator' ? bindIndicator(job.el, job.opts) : bindSurface(job.el, job.opts);
|
||||||
|
job.setRemove(remove);
|
||||||
|
removers.push(remove);
|
||||||
|
}
|
||||||
|
queue = [];
|
||||||
|
syncReady();
|
||||||
|
}
|
||||||
|
|
||||||
|
function dispose() {
|
||||||
|
clearFallbackTimer();
|
||||||
|
readyObserver?.disconnect();
|
||||||
|
readyObserver = null;
|
||||||
|
removers.forEach((remove) => remove());
|
||||||
|
removers = [];
|
||||||
|
queue = [];
|
||||||
|
trackedSurfaces.clear();
|
||||||
|
scene?.dispose();
|
||||||
|
scene = null;
|
||||||
|
ready.value = false;
|
||||||
|
fallback.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const api: SiteLiquidGlassApi = {
|
||||||
|
ready,
|
||||||
|
fallback,
|
||||||
|
init,
|
||||||
|
registerSurface,
|
||||||
|
registerTabIndicator,
|
||||||
|
dispose,
|
||||||
|
};
|
||||||
|
|
||||||
|
provide(SITE_LIQUID_GLASS_KEY, api);
|
||||||
|
return api;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useSiteLiquidGlass(): SiteLiquidGlassApi | null {
|
||||||
|
return inject(SITE_LIQUID_GLASS_KEY, null);
|
||||||
|
}
|
||||||
@ -1,8 +1,8 @@
|
|||||||
export const WELCOME_COPY = {
|
export const WELCOME_COPY = {
|
||||||
en: {
|
en: {
|
||||||
title: 'IDE. Your cross-border logistics advisor',
|
title: 'IDE · One-stop cross-border logistics advisor',
|
||||||
titleShort: 'IDE. Logistics advisor',
|
titleShort: 'IDE · Logistics advisor',
|
||||||
titleRest: ' Your cross-border logistics advisor',
|
titleRest: 'One-stop cross-border logistics advisor',
|
||||||
titleRestShort: 'Logistics advisor',
|
titleRestShort: 'Logistics advisor',
|
||||||
placeholder: 'e.g. 5 kg general cargo to the US, how many days?',
|
placeholder: 'e.g. 5 kg general cargo to the US, how many days?',
|
||||||
sendLabel: 'Ask',
|
sendLabel: 'Ask',
|
||||||
@ -26,9 +26,9 @@ export const WELCOME_COPY = {
|
|||||||
fallback: 'Quotes are in the customer system after you register. You can also talk to an advisor.',
|
fallback: 'Quotes are in the customer system after you register. You can also talk to an advisor.',
|
||||||
},
|
},
|
||||||
zh: {
|
zh: {
|
||||||
title: 'IDE.您身边的跨境物流顾问',
|
title: 'IDE · 一站式跨境物流顾问',
|
||||||
titleShort: 'IDE.跨境物流顾问',
|
titleShort: 'IDE · 跨境物流顾问',
|
||||||
titleRest: '您身边的跨境物流顾问',
|
titleRest: '一站式跨境物流顾问',
|
||||||
titleRestShort: '跨境物流顾问',
|
titleRestShort: '跨境物流顾问',
|
||||||
placeholder: '例如:发美国普货,5kg,要几天',
|
placeholder: '例如:发美国普货,5kg,要几天',
|
||||||
sendLabel: '提问',
|
sendLabel: '提问',
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user