diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 7a4b9eb433cbb1f2318175722714c1b182774200..c6e5a1dd5b2fa946548b00254225469f2f15bee9 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -4,48 +4,49 @@ module.exports = { browser: true, es2021: true, }, - extends: [ - 'airbnb-base', - "eslint:recommended", - "plugin:react/recommended", - 'plugin:prettier/recommended', - 'plugin:@typescript-eslint/recommended', - ], + extends: ['airbnb-base', 'prettier', 'plugin:@typescript-eslint/recommended'], parser: '@typescript-eslint/parser', parserOptions: { - parser: '@typescript-eslint/parser', - ecmaFeatures: { - jsx: true, - }, ecmaVersion: 'latest', sourceType: 'module', }, - plugins: ['@typescript-eslint', 'unused-imports'], + plugins: ['prettier', '@typescript-eslint', 'unused-imports'], rules: { + 'prettier/prettier': 'error', + 'arrow-body-style': 'off', + 'prefer-arrow-callback': 'off', 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', - 'no-undef': [0], - 'no-plusplus': ['error', { allowForLoopAfterthoughts: true }], // 禁止使用++,-- - 'class-methods-use-this': [0], // 强制未使用到 this 的对象方法改为静态 - 'prefer-destructuring': [0], - 'import/no-unresolved': [0], - 'unused-imports/no-unused-imports': 'error', + 'no-new': [0], + 'no-continue': [0], + '@typescript-eslint/no-empty-interface': 'off', + 'no-use-before-define': [0], + 'no-restricted-syntax': [0], + 'no-empty-function': [0], + 'no-useless-constructor': [0], // 禁止空的构造函数 + 'no-param-reassign': [0], // 禁止修改传入函数的参数 'no-underscore-dangle': [0], // 禁止使用下划线开头的变量名 - 'consistent-return': [0], // return 后面是否允许省略 - 'func-names': [0], // 函数表达式必须有名字 - 'import/extensions': [0], // 引入文件时必须制定后缀 - 'import/prefer-default-export': [0], // 关闭首选默认导出 - 'vue/no-setup-props-destructure': [0], - 'vue/require-default-prop': [0], // props 非必填参数必须给默认值 - 'no-unused-vars': ['error', { argsIgnorePattern: '^_' }], + 'no-plusplus': ['error', { allowForLoopAfterthoughts: true }], // 禁止使用 ++,-- + 'consistent-return': [0], // 函数可以有不同类型返回值 + 'class-methods-use-this': [0], // 方法内未使用此方法时,强制定义为静态方法 + 'import/prefer-default-export': [0], // 一个模块只能有默认导出,不可以有多个导出 + 'import/no-unresolved': [0], // 不允许未解决的模块 + 'import/extensions': [0], // 不允许导入文件时不带后缀 + 'unused-imports/no-unused-imports': 'error', '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }], '@typescript-eslint/no-inferrable-types': [0], + '@typescript-eslint/no-non-null-assertion': [0], '@typescript-eslint/no-explicit-any': ['error'], - 'no-param-reassign': [0], - 'no-useless-constructor': [0], - 'no-empty-function': [0], - 'no-restricted-syntax': [0], - // react 相关不适配 preact 的规则关掉 - 'react/react-in-jsx-scope': [0] + '@typescript-eslint/explicit-function-return-type': 'error', // 要求函数和类方法的显式返回类型 + '@typescript-eslint/explicit-module-boundary-types': 'error', // 要求导出函数和类的公共类方法的显式返回和参数类型 + 'import/no-extraneous-dependencies': [ + 0, + { + devDependencies: true, + peerDependencies: true, + // optionalDependencies: true, + // bundledDependencies: true + }, + ], }, }; diff --git a/package.json b/package.json index 89342ed18c6e82c8546aef0c85dd0a58014efc49..6c8ab14e8104afe3fdb7cdcb70ddfce28b6c6878 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "@ibiz-template-plugin/mob-ai-chat", + "name": "@ibiz-template-plugin/ibiz-mob-ai-chat", "version": "0.0.39", "description": "iBiz 移动端AI交互框插件", "type": "module", @@ -17,7 +17,6 @@ "author": "iBiz", "license": "MIT", "scripts": { - "dev": "vite", "build": "vite build", "build:watch": "vite build --watch", "preview": "vite preview", @@ -29,28 +28,20 @@ }, "dependencies": { "@ibiz-template/scss-utils": "^0.0.2", - "@preact/signals": "^1.2.1", - "@tiptap/core": "^3.11.1", - "@tiptap/extension-document": "^3.11.1", - "@tiptap/extension-file-handler": "^3.11.1", - "@tiptap/extension-image": "^3.11.1", - "@tiptap/extension-paragraph": "^3.11.1", - "@tiptap/extension-text": "^3.11.1", - "@tiptap/extensions": "^3.11.1", - "@tiptap/pm": "^3.11.1", "autosize": "^6.0.1", - "cherry-markdown": "^0.8.26", "interactjs": "^1.10.19", "qx-util": "^0.4.8", "path-browserify": "^1.0.1", - "preact": "^10.18.1", - "react-tabs": "^6.0.2", - "vite-plugin-libcss": "^1.1.1" + "cherry-markdown": "^0.8.26", + "vite-plugin-libcss": "^1.1.1", + "vant": "^4.7.2", + "vue": "^3.3.8" }, "devDependencies": { "@commitlint/cli": "^18.2.0", "@commitlint/config-conventional": "^18.1.0", - "@preact/preset-vite": "^2.6.0", + "@vitejs/plugin-vue": "^4.6.2", + "@vitejs/plugin-vue-jsx": "^3.1.0", "@qx-chitanda/vite-plugin-lib-legacy": "^4.1.1", "@types/autosize": "^4.0.2", "@types/lodash-es": "^4.17.10", @@ -68,7 +59,7 @@ "eslint-plugin-react": "^7.33.2", "eslint-plugin-unused-imports": "^3.0.0", "husky": "^8.0.3", - "lint-staged": "^15.0.2", + "lint-staged": "^15.0.2", "prettier": "^3.0.3", "sass": "^1.69.5", "stylelint": "^15.11.0", @@ -85,6 +76,8 @@ "vue-tsc": "^1.8.22" }, "peerDependencies": { + "vue": "^3.3.8", + "vant": "^4.7.2", "cherry-markdown": "^0.8.26", "interactjs": "^1.10.19", "qx-util": "^0.4.8" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d8c37ac7c7e7879b32d3a54dc4a5b24611c8f725..78d92f828b151834d05d316b6a33c48efed46e58 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,57 +8,30 @@ dependencies: '@ibiz-template/scss-utils': specifier: ^0.0.2 version: 0.0.2 - '@preact/signals': - specifier: ^1.2.1 - version: 1.3.2(preact@10.27.2) - '@tiptap/core': - specifier: ^3.11.1 - version: 3.12.0(@tiptap/pm@3.12.0) - '@tiptap/extension-document': - specifier: ^3.11.1 - version: 3.12.0(@tiptap/core@3.12.0) - '@tiptap/extension-file-handler': - specifier: ^3.11.1 - version: 3.12.0(@tiptap/core@3.12.0)(@tiptap/extension-text-style@3.12.0)(@tiptap/pm@3.12.0) - '@tiptap/extension-image': - specifier: ^3.11.1 - version: 3.12.0(@tiptap/core@3.12.0) - '@tiptap/extension-paragraph': - specifier: ^3.11.1 - version: 3.12.0(@tiptap/core@3.12.0) - '@tiptap/extension-text': - specifier: ^3.11.1 - version: 3.12.0(@tiptap/core@3.12.0) - '@tiptap/extensions': - specifier: ^3.11.1 - version: 3.12.0(@tiptap/core@3.12.0)(@tiptap/pm@3.12.0) - '@tiptap/pm': - specifier: ^3.11.1 - version: 3.12.0 autosize: specifier: ^6.0.1 version: 6.0.1 cherry-markdown: specifier: ^0.8.26 - version: 0.8.58 + version: 0.8.26 interactjs: specifier: ^1.10.19 version: 1.10.27 path-browserify: specifier: ^1.0.1 version: 1.0.1 - preact: - specifier: ^10.18.1 - version: 10.27.2 qx-util: specifier: ^0.4.8 version: 0.4.8 - react-tabs: - specifier: ^6.0.2 - version: 6.1.0(react@19.1.1) + vant: + specifier: ^4.7.2 + version: 4.7.2(vue@3.3.8) vite-plugin-libcss: specifier: ^1.1.1 version: 1.1.2(vite@4.5.14) + vue: + specifier: ^3.3.8 + version: 3.3.8(typescript@5.9.2) devDependencies: '@commitlint/cli': @@ -67,9 +40,6 @@ devDependencies: '@commitlint/config-conventional': specifier: ^18.1.0 version: 18.6.3 - '@preact/preset-vite': - specifier: ^2.6.0 - version: 2.10.2(@babel/core@7.28.4)(preact@10.27.2)(vite@4.5.14) '@qx-chitanda/vite-plugin-lib-legacy': specifier: ^4.1.1 version: 4.1.1(terser@5.44.0)(vite@4.5.14) @@ -97,6 +67,12 @@ devDependencies: '@typescript-eslint/parser': specifier: ^6.9.1 version: 6.21.0(eslint@8.57.1)(typescript@5.9.2) + '@vitejs/plugin-vue': + specifier: ^4.6.2 + version: 4.6.2(vite@4.5.14)(vue@3.3.8) + '@vitejs/plugin-vue-jsx': + specifier: ^3.1.0 + version: 3.1.0(vite@4.5.14)(vue@3.3.8) eslint: specifier: ^8.52.0 version: 8.57.1 @@ -217,6 +193,17 @@ packages: jsesc: 3.1.0 dev: true + /@babel/generator@7.28.5: + resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + dev: true + /@babel/helper-annotate-as-pure@7.27.3: resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} engines: {node: '>=6.9.0'} @@ -253,6 +240,24 @@ packages: - supports-color dev: true + /@babel/helper-create-class-features-plugin@7.28.5(@babel/core@7.28.4): + resolution: {integrity: sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.4) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.28.5 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/helper-create-regexp-features-plugin@7.27.1(@babel/core@7.28.4): resolution: {integrity: sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ==} engines: {node: '>=6.9.0'} @@ -295,6 +300,16 @@ packages: - supports-color dev: true + /@babel/helper-member-expression-to-functions@7.28.5: + resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/helper-module-imports@7.27.1: resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} engines: {node: '>=6.9.0'} @@ -352,9 +367,9 @@ packages: '@babel/core': ^7.0.0 dependencies: '@babel/core': 7.28.4 - '@babel/helper-member-expression-to-functions': 7.27.1 + '@babel/helper-member-expression-to-functions': 7.28.5 '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/traverse': 7.28.4 + '@babel/traverse': 7.28.5 transitivePeerDependencies: - supports-color dev: true @@ -372,11 +387,14 @@ packages: /@babel/helper-string-parser@7.27.1: resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} - dev: true /@babel/helper-validator-identifier@7.27.1: resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} engines: {node: '>=6.9.0'} + + /@babel/helper-validator-identifier@7.28.5: + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} dev: true /@babel/helper-validator-option@7.27.1: @@ -409,6 +427,13 @@ packages: hasBin: true dependencies: '@babel/types': 7.28.4 + + /@babel/parser@7.28.5: + resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.28.5 dev: true /@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1(@babel/core@7.28.4): @@ -510,6 +535,16 @@ packages: '@babel/helper-plugin-utils': 7.27.1 dev: true + /@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.4): + resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-plugin-utils': 7.27.1 + dev: true + /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.28.4): resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} engines: {node: '>=6.9.0'} @@ -982,34 +1017,6 @@ packages: '@babel/helper-plugin-utils': 7.27.1 dev: true - /@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.28.4): - resolution: {integrity: sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.28.4 - '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.4) - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.28.4): - resolution: {integrity: sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.28.4 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-module-imports': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.4) - '@babel/types': 7.28.4 - transitivePeerDependencies: - - supports-color - dev: true - /@babel/plugin-transform-regenerator@7.28.4(@babel/core@7.28.4): resolution: {integrity: sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==} engines: {node: '>=6.9.0'} @@ -1094,6 +1101,22 @@ packages: '@babel/helper-plugin-utils': 7.27.1 dev: true + /@babel/plugin-transform-typescript@7.28.5(@babel/core@7.28.4): + resolution: {integrity: sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.4) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.4) + transitivePeerDependencies: + - supports-color + dev: true + /@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.28.4): resolution: {integrity: sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==} engines: {node: '>=6.9.0'} @@ -1253,12 +1276,34 @@ packages: - supports-color dev: true + /@babel/traverse@7.28.5: + resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/types': 7.28.5 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/types@7.28.4: resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 + + /@babel/types@7.28.5: + resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 dev: true /@braintree/sanitize-url@6.0.4: @@ -1946,73 +1991,6 @@ packages: engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} dev: true - /@preact/preset-vite@2.10.2(@babel/core@7.28.4)(preact@10.27.2)(vite@4.5.14): - resolution: {integrity: sha512-K9wHlJOtkE+cGqlyQ5v9kL3Ge0Ql4LlIZjkUTL+1zf3nNdF88F9UZN6VTV8jdzBX9Fl7WSzeNMSDG7qECPmSmg==} - peerDependencies: - '@babel/core': 7.x - vite: 2.x || 3.x || 4.x || 5.x || 6.x || 7.x - dependencies: - '@babel/core': 7.28.4 - '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.4) - '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.28.4) - '@prefresh/vite': 2.4.10(preact@10.27.2)(vite@4.5.14) - '@rollup/pluginutils': 4.2.1 - babel-plugin-transform-hook-names: 1.0.2(@babel/core@7.28.4) - debug: 4.4.3 - picocolors: 1.1.1 - vite: 4.5.14(@types/node@20.19.17)(sass@1.93.2)(terser@5.44.0) - vite-prerender-plugin: 0.5.12(vite@4.5.14) - transitivePeerDependencies: - - preact - - supports-color - dev: true - - /@preact/signals-core@1.12.1: - resolution: {integrity: sha512-BwbTXpj+9QutoZLQvbttRg5x3l5468qaV2kufh+51yha1c53ep5dY4kTuZR35+3pAZxpfQerGJiQqg34ZNZ6uA==} - dev: false - - /@preact/signals@1.3.2(preact@10.27.2): - resolution: {integrity: sha512-naxcJgUJ6BTOROJ7C3QML7KvwKwCXQJYTc5L/b0eEsdYgPB6SxwoQ1vDGcS0Q7GVjAenVq/tXrybVdFShHYZWg==} - peerDependencies: - preact: 10.x - dependencies: - '@preact/signals-core': 1.12.1 - preact: 10.27.2 - dev: false - - /@prefresh/babel-plugin@0.5.2: - resolution: {integrity: sha512-AOl4HG6dAxWkJ5ndPHBgBa49oo/9bOiJuRDKHLSTyH+Fd9x00shTXpdiTj1W41l6oQIwUOAgJeHMn4QwIDpHkA==} - dev: true - - /@prefresh/core@1.5.7(preact@10.27.2): - resolution: {integrity: sha512-AsyeitiPwG7UkT0mqgKzIDuydmYSKtBlzXEb5ymzskvxewcmVGRjQkcHDy6PCNBT7soAyHpQ0mPgXX4IeyOlUg==} - peerDependencies: - preact: ^10.0.0 || ^11.0.0-0 - dependencies: - preact: 10.27.2 - dev: true - - /@prefresh/utils@1.2.1: - resolution: {integrity: sha512-vq/sIuN5nYfYzvyayXI4C2QkprfNaHUQ9ZX+3xLD8nL3rWyzpxOm1+K7RtMbhd+66QcaISViK7amjnheQ/4WZw==} - dev: true - - /@prefresh/vite@2.4.10(preact@10.27.2)(vite@4.5.14): - resolution: {integrity: sha512-lt+ODASOtXRWaPplp7/DlrgAaInnQYNvcpCglQBMx2OeJPyZ4IqPRaxsK77w96mWshjYwkqTsRSHoAM7aAn0ow==} - peerDependencies: - preact: ^10.4.0 || ^11.0.0-0 - vite: '>=2.0.0' - dependencies: - '@babel/core': 7.28.4 - '@prefresh/babel-plugin': 0.5.2 - '@prefresh/core': 1.5.7(preact@10.27.2) - '@prefresh/utils': 1.2.1 - '@rollup/pluginutils': 4.2.1 - preact: 10.27.2 - vite: 4.5.14(@types/node@20.19.17)(sass@1.93.2)(terser@5.44.0) - transitivePeerDependencies: - - supports-color - dev: true - /@qx-chitanda/vite-plugin-lib-legacy@4.1.1(terser@5.44.0)(vite@4.5.14): resolution: {integrity: sha512-TKyVqfaiWB/dqOi/T2sLIlfQoqKquPcQQZsKzbVOjveJMNyaFcXBclwjLXhIE8MgzigJ1FLOF25Hrgk3NqhIDA==} engines: {node: ^14.18.0 || >=16.0.0} @@ -2033,10 +2011,6 @@ packages: - supports-color dev: true - /@remirror/core-constants@3.0.0: - resolution: {integrity: sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==} - dev: false - /@rollup/pluginutils@4.2.1: resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} engines: {node: '>= 8.0.0'} @@ -2111,99 +2085,6 @@ packages: - '@types/node' dev: true - /@tiptap/core@3.12.0(@tiptap/pm@3.12.0): - resolution: {integrity: sha512-yy5LHOHgdR5Z3bID9g6Hj6IofqBw8HIHtT8E3SYZXnEWBUhsoXpJVAukXv0wWEZmIbae5PpQYIuklw/QXw26Pw==} - peerDependencies: - '@tiptap/pm': ^3.12.0 - dependencies: - '@tiptap/pm': 3.12.0 - dev: false - - /@tiptap/extension-document@3.12.0(@tiptap/core@3.12.0): - resolution: {integrity: sha512-dxRXot8sC9gBKGs99ehSS1UfWAH48mBrFMF8xlayPKuc75IO8GRen78uU8h73FLlKip5TDqRZUpBU3/d3WlBxQ==} - peerDependencies: - '@tiptap/core': ^3.12.0 - dependencies: - '@tiptap/core': 3.12.0(@tiptap/pm@3.12.0) - dev: false - - /@tiptap/extension-file-handler@3.12.0(@tiptap/core@3.12.0)(@tiptap/extension-text-style@3.12.0)(@tiptap/pm@3.12.0): - resolution: {integrity: sha512-mjfXj9DDNLy3LRiqNOd+KxXO8MVjIn8zRNHCcPIQJOpgkWktSv1C7zy/FL89aZTbHdkwF7yskREVoV3nTBp98g==} - peerDependencies: - '@tiptap/core': ^3.12.0 - '@tiptap/extension-text-style': ^3.12.0 - '@tiptap/pm': ^3.12.0 - dependencies: - '@tiptap/core': 3.12.0(@tiptap/pm@3.12.0) - '@tiptap/extension-text-style': 3.12.0(@tiptap/core@3.12.0) - '@tiptap/pm': 3.12.0 - dev: false - - /@tiptap/extension-image@3.12.0(@tiptap/core@3.12.0): - resolution: {integrity: sha512-E+nQmMaHdR5SFDuIZUEdfaaNmRuO47V2KQIIOUT6BIxXkArixaKIIz/BKtzYq4pKySkHWL1niYe5lfZWVmEXaw==} - peerDependencies: - '@tiptap/core': ^3.12.0 - dependencies: - '@tiptap/core': 3.12.0(@tiptap/pm@3.12.0) - dev: false - - /@tiptap/extension-paragraph@3.12.0(@tiptap/core@3.12.0): - resolution: {integrity: sha512-J8HPJajgV0cIkA4wK7wBNJSpiNmi5Vd/Ii94hi6wpCbIdMMkfj8ngeXzVjVO/6Hpm2Xyr21OPbv2g3I6pgVAGA==} - peerDependencies: - '@tiptap/core': ^3.12.0 - dependencies: - '@tiptap/core': 3.12.0(@tiptap/pm@3.12.0) - dev: false - - /@tiptap/extension-text-style@3.12.0(@tiptap/core@3.12.0): - resolution: {integrity: sha512-VjA7p34EKivogIW8z4EWCMu+1iDrzPcf1oUWPBMdD2OTISY2iNJT2RLmZTMtRSdlZHz4vCWlbBwfKHoFT/ba5g==} - peerDependencies: - '@tiptap/core': ^3.12.0 - dependencies: - '@tiptap/core': 3.12.0(@tiptap/pm@3.12.0) - dev: false - - /@tiptap/extension-text@3.12.0(@tiptap/core@3.12.0): - resolution: {integrity: sha512-7AlIYbmEeT3zAYCWrPTunaZkyIWriJtEAmUzURlQVVKmNv6kCTyJcqX7N0Db8z8Z19UFHaVAODL8yXYde4QB/w==} - peerDependencies: - '@tiptap/core': ^3.12.0 - dependencies: - '@tiptap/core': 3.12.0(@tiptap/pm@3.12.0) - dev: false - - /@tiptap/extensions@3.12.0(@tiptap/core@3.12.0)(@tiptap/pm@3.12.0): - resolution: {integrity: sha512-N5ahZfeTBWROTNHFLmTW7sa6ZrZwvp/jJHyH7tcetXT+509vHVhX7yPoiLDt0fnXIDW7JrWI7jbRRmcKf79I2w==} - peerDependencies: - '@tiptap/core': ^3.12.0 - '@tiptap/pm': ^3.12.0 - dependencies: - '@tiptap/core': 3.12.0(@tiptap/pm@3.12.0) - '@tiptap/pm': 3.12.0 - dev: false - - /@tiptap/pm@3.12.0: - resolution: {integrity: sha512-A2Hs6fdd9nFyIzdmJ9zoJvVuGsdwbQB+QA0TgBMTWwjyTRilpMeIhMX2qXNDzPFVy2aS4+QjvIpcHeArfbJ2bQ==} - dependencies: - prosemirror-changeset: 2.3.1 - prosemirror-collab: 1.3.1 - prosemirror-commands: 1.7.1 - prosemirror-dropcursor: 1.8.2 - prosemirror-gapcursor: 1.4.0 - prosemirror-history: 1.5.0 - prosemirror-inputrules: 1.5.1 - prosemirror-keymap: 1.2.3 - prosemirror-markdown: 1.13.2 - prosemirror-menu: 1.2.5 - prosemirror-model: 1.25.4 - prosemirror-schema-basic: 1.2.4 - prosemirror-schema-list: 1.5.1 - prosemirror-state: 1.4.4 - prosemirror-tables: 1.8.1 - prosemirror-trailing-node: 3.0.0(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.4) - prosemirror-transform: 1.10.5 - prosemirror-view: 1.41.4 - dev: false - /@tootallnate/once@2.0.0: resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} engines: {node: '>= 10'} @@ -2247,10 +2128,6 @@ packages: resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} dev: true - /@types/linkify-it@5.0.0: - resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} - dev: false - /@types/lodash-es@4.17.12: resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} dependencies: @@ -2261,17 +2138,6 @@ packages: resolution: {integrity: sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==} dev: true - /@types/markdown-it@14.1.2: - resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} - dependencies: - '@types/linkify-it': 5.0.0 - '@types/mdurl': 2.0.0 - dev: false - - /@types/mdurl@2.0.0: - resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} - dev: false - /@types/minimist@1.2.5: resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} dev: true @@ -2449,6 +2315,45 @@ packages: resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} dev: true + /@vant/popperjs@1.3.0: + resolution: {integrity: sha512-hB+czUG+aHtjhaEmCJDuXOep0YTZjdlRR+4MSmIFnkCQIxJaXLQdSsR90XWvAI2yvKUI7TCGqR8pQg2RtvkMHw==} + dev: false + + /@vant/use@1.6.0(vue@3.3.8): + resolution: {integrity: sha512-PHHxeAASgiOpSmMjceweIrv2AxDZIkWXyaczksMoWvKV2YAYEhoizRuk/xFnKF+emUIi46TsQ+rvlm/t2BBCfA==} + peerDependencies: + vue: ^3.0.0 + dependencies: + vue: 3.3.8(typescript@5.9.2) + dev: false + + /@vitejs/plugin-vue-jsx@3.1.0(vite@4.5.14)(vue@3.3.8): + resolution: {integrity: sha512-w9M6F3LSEU5kszVb9An2/MmXNxocAnUb3WhRr8bHlimhDrXNt6n6D2nJQR3UXpGlZHh/EsgouOHCsM8V3Ln+WA==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.0.0 || ^5.0.0 + vue: ^3.0.0 + dependencies: + '@babel/core': 7.28.4 + '@babel/plugin-transform-typescript': 7.28.5(@babel/core@7.28.4) + '@vue/babel-plugin-jsx': 1.5.0(@babel/core@7.28.4) + vite: 4.5.14(@types/node@20.19.17)(sass@1.93.2)(terser@5.44.0) + vue: 3.3.8(typescript@5.9.2) + transitivePeerDependencies: + - supports-color + dev: true + + /@vitejs/plugin-vue@4.6.2(vite@4.5.14)(vue@3.3.8): + resolution: {integrity: sha512-kqf7SGFoG+80aZG6Pf+gsZIVvGSCKE98JbiWqcCV9cThtg91Jav0yvYFC9Zb+jKetNGF6ZKeoaxgZfND21fWKw==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.0.0 || ^5.0.0 + vue: ^3.2.25 + dependencies: + vite: 4.5.14(@types/node@20.19.17)(sass@1.93.2)(terser@5.44.0) + vue: 3.3.8(typescript@5.9.2) + dev: true + /@volar/language-core@1.11.1: resolution: {integrity: sha512-dOcNn3i9GgZAcJt43wuaEykSluAuOkQgzni1cuxLxTV0nJKanQztp7FxyswdRILaKH+P2XZMPRp2S4MV/pElCw==} dependencies: @@ -2468,6 +2373,55 @@ packages: path-browserify: 1.0.1 dev: true + /@vue/babel-helper-vue-transform-on@1.5.0: + resolution: {integrity: sha512-0dAYkerNhhHutHZ34JtTl2czVQHUNWv6xEbkdF5W+Yrv5pCWsqjeORdOgbtW2I9gWlt+wBmVn+ttqN9ZxR5tzA==} + dev: true + + /@vue/babel-plugin-jsx@1.5.0(@babel/core@7.28.4): + resolution: {integrity: sha512-mneBhw1oOqCd2247O0Yw/mRwC9jIGACAJUlawkmMBiNmL4dGA2eMzuNZVNqOUfYTa6vqmND4CtOPzmEEEqLKFw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + peerDependenciesMeta: + '@babel/core': + optional: true + dependencies: + '@babel/core': 7.28.4 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.4) + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 + '@vue/babel-helper-vue-transform-on': 1.5.0 + '@vue/babel-plugin-resolve-type': 1.5.0(@babel/core@7.28.4) + '@vue/shared': 3.5.25 + transitivePeerDependencies: + - supports-color + dev: true + + /@vue/babel-plugin-resolve-type@1.5.0(@babel/core@7.28.4): + resolution: {integrity: sha512-Wm/60o+53JwJODm4Knz47dxJnLDJ9FnKnGZJbUUf8nQRAtt6P+undLUAVU3Ha33LxOJe6IPoifRQ6F/0RrU31w==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/core': 7.28.4 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/parser': 7.28.4 + '@vue/compiler-sfc': 3.5.25 + transitivePeerDependencies: + - supports-color + dev: true + + /@vue/compiler-core@3.3.8: + resolution: {integrity: sha512-hN/NNBUECw8SusQvDSqqcVv6gWq8L6iAktUR0UF3vGu2OhzRqcOiAno0FmBJWwxhYEXRlQJT5XnoKsVq1WZx4g==} + dependencies: + '@babel/parser': 7.28.4 + '@vue/shared': 3.3.8 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + /@vue/compiler-core@3.5.22: resolution: {integrity: sha512-jQ0pFPmZwTEiRNSb+i9Ow/I/cHv2tXYqsnHKKyCQ08irI2kdF5qmYedmF8si8mA7zepUFmJ2hqzS8CQmNOWOkQ==} dependencies: @@ -2478,6 +2432,22 @@ packages: source-map-js: 1.2.1 dev: true + /@vue/compiler-core@3.5.25: + resolution: {integrity: sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==} + dependencies: + '@babel/parser': 7.28.5 + '@vue/shared': 3.5.25 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + dev: true + + /@vue/compiler-dom@3.3.8: + resolution: {integrity: sha512-+PPtv+p/nWDd0AvJu3w8HS0RIm/C6VGBIRe24b9hSyNWOAPEUosFZ5diwawwP8ip5sJ8n0Pe87TNNNHnvjs0FQ==} + dependencies: + '@vue/compiler-core': 3.3.8 + '@vue/shared': 3.3.8 + /@vue/compiler-dom@3.5.22: resolution: {integrity: sha512-W8RknzUM1BLkypvdz10OVsGxnMAuSIZs9Wdx1vzA3mL5fNMN15rhrSCLiTm6blWeACwUwizzPVqGJgOGBEN/hA==} dependencies: @@ -2485,6 +2455,54 @@ packages: '@vue/shared': 3.5.22 dev: true + /@vue/compiler-dom@3.5.25: + resolution: {integrity: sha512-4We0OAcMZsKgYoGlMjzYvaoErltdFI2/25wqanuTu+S4gismOTRTBPi4IASOjxWdzIwrYSjnqONfKvuqkXzE2Q==} + dependencies: + '@vue/compiler-core': 3.5.25 + '@vue/shared': 3.5.25 + dev: true + + /@vue/compiler-sfc@3.3.8: + resolution: {integrity: sha512-WMzbUrlTjfYF8joyT84HfwwXo+8WPALuPxhy+BZ6R4Aafls+jDBnSz8PDz60uFhuqFbl3HxRfxvDzrUf3THwpA==} + dependencies: + '@babel/parser': 7.28.4 + '@vue/compiler-core': 3.3.8 + '@vue/compiler-dom': 3.3.8 + '@vue/compiler-ssr': 3.3.8 + '@vue/reactivity-transform': 3.3.8 + '@vue/shared': 3.3.8 + estree-walker: 2.0.2 + magic-string: 0.30.19 + postcss: 8.5.6 + source-map-js: 1.2.1 + + /@vue/compiler-sfc@3.5.25: + resolution: {integrity: sha512-PUgKp2rn8fFsI++lF2sO7gwO2d9Yj57Utr5yEsDf3GNaQcowCLKL7sf+LvVFvtJDXUp/03+dC6f2+LCv5aK1ag==} + dependencies: + '@babel/parser': 7.28.5 + '@vue/compiler-core': 3.5.25 + '@vue/compiler-dom': 3.5.25 + '@vue/compiler-ssr': 3.5.25 + '@vue/shared': 3.5.25 + estree-walker: 2.0.2 + magic-string: 0.30.21 + postcss: 8.5.6 + source-map-js: 1.2.1 + dev: true + + /@vue/compiler-ssr@3.3.8: + resolution: {integrity: sha512-hXCqQL/15kMVDBuoBYpUnSYT8doDNwsjvm3jTefnXr+ytn294ySnT8NlsFHmTgKNjwpuFy7XVV8yTeLtNl/P6w==} + dependencies: + '@vue/compiler-dom': 3.3.8 + '@vue/shared': 3.3.8 + + /@vue/compiler-ssr@3.5.25: + resolution: {integrity: sha512-ritPSKLBcParnsKYi+GNtbdbrIE1mtuFEJ4U1sWeuOMlIziK5GtOL85t5RhsNy4uWIXPgk+OUdpnXiTdzn8o3A==} + dependencies: + '@vue/compiler-dom': 3.5.25 + '@vue/shared': 3.5.25 + dev: true + /@vue/language-core@1.8.27(typescript@5.9.2): resolution: {integrity: sha512-L8Kc27VdQserNaCUNiSFdDl9LWT24ly8Hpwf1ECy3aFb9m6bDhBGQYOujDm21N7EW3moKIOKEanQwe1q5BK+mA==} peerDependencies: @@ -2496,7 +2514,7 @@ packages: '@volar/language-core': 1.11.1 '@volar/source-map': 1.11.1 '@vue/compiler-dom': 3.5.22 - '@vue/shared': 3.5.22 + '@vue/shared': 3.5.25 computeds: 0.0.1 minimatch: 9.0.5 muggle-string: 0.3.1 @@ -2505,10 +2523,52 @@ packages: vue-template-compiler: 2.7.16 dev: true + /@vue/reactivity-transform@3.3.8: + resolution: {integrity: sha512-49CvBzmZNtcHua0XJ7GdGifM8GOXoUMOX4dD40Y5DxI3R8OUhMlvf2nvgUAcPxaXiV5MQQ1Nwy09ADpnLQUqRw==} + dependencies: + '@babel/parser': 7.28.4 + '@vue/compiler-core': 3.3.8 + '@vue/shared': 3.3.8 + estree-walker: 2.0.2 + magic-string: 0.30.19 + + /@vue/reactivity@3.3.8: + resolution: {integrity: sha512-ctLWitmFBu6mtddPyOKpHg8+5ahouoTCRtmAHZAXmolDtuZXfjL2T3OJ6DL6ezBPQB1SmMnpzjiWjCiMYmpIuw==} + dependencies: + '@vue/shared': 3.3.8 + + /@vue/runtime-core@3.3.8: + resolution: {integrity: sha512-qurzOlb6q26KWQ/8IShHkMDOuJkQnQcTIp1sdP4I9MbCf9FJeGVRXJFr2mF+6bXh/3Zjr9TDgURXrsCr9bfjUw==} + dependencies: + '@vue/reactivity': 3.3.8 + '@vue/shared': 3.3.8 + + /@vue/runtime-dom@3.3.8: + resolution: {integrity: sha512-Noy5yM5UIf9UeFoowBVgghyGGPIDPy1Qlqt0yVsUdAVbqI8eeMSsTqBtauaEoT2UFXUk5S64aWVNJN4MJ2vRdA==} + dependencies: + '@vue/runtime-core': 3.3.8 + '@vue/shared': 3.3.8 + csstype: 3.2.3 + + /@vue/server-renderer@3.3.8(vue@3.3.8): + resolution: {integrity: sha512-zVCUw7RFskvPuNlPn/8xISbrf0zTWsTSdYTsUTN1ERGGZGVnRxM2QZ3x1OR32+vwkkCm0IW6HmJ49IsPm7ilLg==} + peerDependencies: + vue: 3.3.8 + dependencies: + '@vue/compiler-ssr': 3.3.8 + '@vue/shared': 3.3.8 + vue: 3.3.8(typescript@5.9.2) + + /@vue/shared@3.3.8: + resolution: {integrity: sha512-8PGwybFwM4x8pcfgqEQFy70NaQxASvOC5DJwLQfpArw1UDfUXrJkdxD3BhVTMS+0Lef/TU7YO0Jvr0jJY8T+mw==} + /@vue/shared@3.5.22: resolution: {integrity: sha512-F4yc6palwq3TT0u+FYf0Ns4Tfl9GRFURDN2gWG7L1ecIaS/4fCIuFOjMTnCyjsu/OK6vaDKLCrGAa+KvvH+h4w==} dev: true + /@vue/shared@3.5.25: + resolution: {integrity: sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==} + /JSONStream@1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} hasBin: true @@ -2617,6 +2677,7 @@ packages: /argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + dev: true /array-buffer-byte-length@1.0.2: resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} @@ -2784,14 +2845,6 @@ packages: - supports-color dev: true - /babel-plugin-transform-hook-names@1.0.2(@babel/core@7.28.4): - resolution: {integrity: sha512-5gafyjyyBTTdX/tQQ0hRgu4AhNHG/hqWi0ZZmg2xvs2FgRkJXzDNKBZCyoYqgFkovfDrgM8OoKg8karoUvWeCw==} - peerDependencies: - '@babel/core': ^7.12.10 - dependencies: - '@babel/core': 7.28.4 - dev: true - /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -2804,10 +2857,6 @@ packages: hasBin: true dev: true - /boolbase@1.0.0: - resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - dev: true - /brace-expansion@1.1.12: resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} dependencies: @@ -2921,13 +2970,12 @@ packages: engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} dev: true - /cherry-markdown@0.8.58: - resolution: {integrity: sha512-/UV1+qyv7X+TVKQMimuh0oiDf/Ysdp3KfJZtGfVLYSYjlrTnTkmbZ2bTQO/NUgTlNaQbyOsanBkw9U2VwHUzMA==} + /cherry-markdown@0.8.26: + resolution: {integrity: sha512-Cjl69gKq8wSVyN0YKZd/FGExkdPvCg0Z8353VDohan9ksjBs3x3LSuZwM3/HjzRlcP27bxDoB23z4lN2BWi5WQ==} engines: {node: '>=14'} dependencies: '@types/codemirror': 0.0.108 '@types/dompurify': 2.4.0 - crypto-js: 4.2.0 jsdom: 19.0.0 optionalDependencies: mermaid: 9.4.3 @@ -2968,11 +3016,6 @@ packages: wrap-ansi: 7.0.0 dev: true - /clsx@2.1.1: - resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} - engines: {node: '>=6'} - dev: false - /color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -3126,10 +3169,6 @@ packages: typescript: 5.9.2 dev: true - /crelt@1.0.6: - resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==} - dev: false - /cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -3139,25 +3178,11 @@ packages: which: 2.0.2 dev: true - /crypto-js@4.2.0: - resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} - dev: false - /css-functions-list@3.2.3: resolution: {integrity: sha512-IQOkD3hbR5KrN93MtcYuad6YPuTSUhntLHDuLEbFWE+ff2/XSZNdZG+LcbbIW5AXKg/WFIfYItIzVoHngHXZzA==} engines: {node: '>=12 || >=16'} dev: true - /css-select@5.2.2: - resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} - dependencies: - boolbase: 1.0.0 - css-what: 6.2.2 - domhandler: 5.0.3 - domutils: 3.2.2 - nth-check: 2.1.1 - dev: true - /css-tree@2.3.1: resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} @@ -3166,11 +3191,6 @@ packages: source-map-js: 1.2.1 dev: true - /css-what@6.2.2: - resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} - engines: {node: '>= 6'} - dev: true - /cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} @@ -3192,6 +3212,9 @@ packages: cssom: 0.3.8 dev: false + /csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + /cytoscape-cose-bilkent@4.1.0(cytoscape@3.33.1): resolution: {integrity: sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==} requiresBuild: true @@ -3581,8 +3604,8 @@ packages: is-data-view: 1.0.2 dev: true - /dayjs@1.11.18: - resolution: {integrity: sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==} + /dayjs@1.11.19: + resolution: {integrity: sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==} requiresBuild: true dev: false optional: true @@ -3698,18 +3721,6 @@ packages: esutils: 2.0.3 dev: true - /dom-serializer@2.0.0: - resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} - dependencies: - domelementtype: 2.3.0 - domhandler: 5.0.3 - entities: 4.5.0 - dev: true - - /domelementtype@2.3.0: - resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} - dev: true - /domexception@4.0.0: resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==} engines: {node: '>=12'} @@ -3718,27 +3729,12 @@ packages: webidl-conversions: 7.0.0 dev: false - /domhandler@5.0.3: - resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} - engines: {node: '>= 4'} - dependencies: - domelementtype: 2.3.0 - dev: true - /dompurify@2.4.3: resolution: {integrity: sha512-q6QaLcakcRjebxjg8/+NP+h0rPfatOgOzc46Fst9VAA3jF2ApfKBNKMzdP4DYTqtUMXSCd5pRS/8Po/OmoCHZQ==} requiresBuild: true dev: false optional: true - /domutils@3.2.2: - resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} - dependencies: - dom-serializer: 2.0.0 - domelementtype: 2.3.0 - domhandler: 5.0.3 - dev: true - /dot-prop@5.3.0: resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} engines: {node: '>=8'} @@ -3775,6 +3771,7 @@ packages: /entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} + dev: true /environment@1.1.0: resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} @@ -3945,6 +3942,7 @@ packages: /escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} + dev: true /escodegen@2.1.0: resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} @@ -4222,7 +4220,6 @@ packages: /estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} - dev: true /esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} @@ -4360,8 +4357,8 @@ packages: is-callable: 1.2.7 dev: true - /form-data@4.0.4: - resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} + /form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} engines: {node: '>= 6'} dependencies: asynckit: 0.4.0 @@ -5032,6 +5029,7 @@ packages: /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + dev: true /js-yaml@4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} @@ -5058,12 +5056,12 @@ packages: decimal.js: 10.6.0 domexception: 4.0.0 escodegen: 2.1.0 - form-data: 4.0.4 + form-data: 4.0.5 html-encoding-sniffer: 3.0.0 http-proxy-agent: 5.0.0 https-proxy-agent: 5.0.1 is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.22 + nwsapi: 2.2.23 parse5: 6.0.1 saxes: 5.0.1 symbol-tree: 3.2.4 @@ -5196,12 +5194,6 @@ packages: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} dev: true - /linkify-it@5.0.0: - resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} - dependencies: - uc.micro: 2.1.0 - dev: false - /lint-staged@15.5.2: resolution: {integrity: sha512-YUSOLq9VeRNAo/CTaVmhGDKG+LBtA8KF1X4K5+ykMSwWST1vDxJRB2kv2COgLb1fvpCo+A/y9A0G0znNVmdx4w==} engines: {node: '>=18.12.0'} @@ -5331,6 +5323,7 @@ packages: hasBin: true dependencies: js-tokens: 4.0.0 + dev: true /lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} @@ -5349,6 +5342,11 @@ packages: resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==} dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + + /magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 dev: true /map-obj@1.0.1: @@ -5361,18 +5359,6 @@ packages: engines: {node: '>=8'} dev: true - /markdown-it@14.1.0: - resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} - hasBin: true - dependencies: - argparse: 2.0.1 - entities: 4.5.0 - linkify-it: 5.0.0 - mdurl: 2.0.0 - punycode.js: 2.3.1 - uc.micro: 2.1.0 - dev: false - /math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} @@ -5385,10 +5371,6 @@ packages: resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} dev: true - /mdurl@2.0.0: - resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} - dev: false - /meow@10.1.5: resolution: {integrity: sha512-/d+PQ4GKmGvM9Bee/DPa8z3mXs/pkvJE2KEThngVNOqtmljC6K7NMPxtc2JeZYTmpWb9k/TmxjeL18ez3h7vCw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -5448,7 +5430,7 @@ packages: cytoscape-fcose: 2.2.0(cytoscape@3.33.1) d3: 7.9.0 dagre-d3-es: 7.0.9 - dayjs: 1.11.18 + dayjs: 1.11.19 dompurify: 2.4.3 elkjs: 0.8.2 khroma: 2.1.0 @@ -5559,13 +5541,6 @@ packages: requiresBuild: true optional: true - /node-html-parser@6.1.13: - resolution: {integrity: sha512-qIsTMOY4C/dAa5Q5vsobRpOOvPfC4pB61UVW2uSwZNUp0QU/jCekTal1vMmbO0DgdHeLUJpv/ARmDqErVxA3Sg==} - dependencies: - css-select: 5.2.2 - he: 1.2.0 - dev: true - /node-releases@2.0.21: resolution: {integrity: sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==} dev: true @@ -5614,19 +5589,14 @@ packages: path-key: 4.0.0 dev: true - /nth-check@2.1.1: - resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - dependencies: - boolbase: 1.0.0 - dev: true - - /nwsapi@2.2.22: - resolution: {integrity: sha512-ujSMe1OWVn55euT1ihwCI1ZcAaAU3nxUiDwfDQldc51ZXaB9m2AyOn6/jh1BLe2t/G8xd6uKG1UBF2aZJeg2SQ==} + /nwsapi@2.2.23: + resolution: {integrity: sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==} dev: false /object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} + dev: true /object-inspect@1.13.4: resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} @@ -5728,10 +5698,6 @@ packages: word-wrap: 1.2.5 dev: true - /orderedmap@2.1.1: - resolution: {integrity: sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==} - dev: false - /own-keys@1.0.1: resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} engines: {node: '>= 0.4'} @@ -5913,9 +5879,6 @@ packages: picocolors: 1.1.1 source-map-js: 1.2.1 - /preact@10.27.2: - resolution: {integrity: sha512-5SYSgFKSyhCbk6SrXyMpqjb5+MQBgfvEKE/OC+PujcY34sOpqtr+0AZQtPYx5IA6VxynQ7rUPCtKzyovpj9Bpg==} - /prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -5940,149 +5903,7 @@ packages: loose-envify: 1.4.0 object-assign: 4.1.1 react-is: 16.13.1 - - /prosemirror-changeset@2.3.1: - resolution: {integrity: sha512-j0kORIBm8ayJNl3zQvD1TTPHJX3g042et6y/KQhZhnPrruO8exkTgG8X+NRpj7kIyMMEx74Xb3DyMIBtO0IKkQ==} - dependencies: - prosemirror-transform: 1.10.5 - dev: false - - /prosemirror-collab@1.3.1: - resolution: {integrity: sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==} - dependencies: - prosemirror-state: 1.4.4 - dev: false - - /prosemirror-commands@1.7.1: - resolution: {integrity: sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==} - dependencies: - prosemirror-model: 1.25.4 - prosemirror-state: 1.4.4 - prosemirror-transform: 1.10.5 - dev: false - - /prosemirror-dropcursor@1.8.2: - resolution: {integrity: sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==} - dependencies: - prosemirror-state: 1.4.4 - prosemirror-transform: 1.10.5 - prosemirror-view: 1.41.4 - dev: false - - /prosemirror-gapcursor@1.4.0: - resolution: {integrity: sha512-z00qvurSdCEWUIulij/isHaqu4uLS8r/Fi61IbjdIPJEonQgggbJsLnstW7Lgdk4zQ68/yr6B6bf7sJXowIgdQ==} - dependencies: - prosemirror-keymap: 1.2.3 - prosemirror-model: 1.25.4 - prosemirror-state: 1.4.4 - prosemirror-view: 1.41.4 - dev: false - - /prosemirror-history@1.5.0: - resolution: {integrity: sha512-zlzTiH01eKA55UAf1MEjtssJeHnGxO0j4K4Dpx+gnmX9n+SHNlDqI2oO1Kv1iPN5B1dm5fsljCfqKF9nFL6HRg==} - dependencies: - prosemirror-state: 1.4.4 - prosemirror-transform: 1.10.5 - prosemirror-view: 1.41.4 - rope-sequence: 1.3.4 - dev: false - - /prosemirror-inputrules@1.5.1: - resolution: {integrity: sha512-7wj4uMjKaXWAQ1CDgxNzNtR9AlsuwzHfdFH1ygEHA2KHF2DOEaXl1CJfNPAKCg9qNEh4rum975QLaCiQPyY6Fw==} - dependencies: - prosemirror-state: 1.4.4 - prosemirror-transform: 1.10.5 - dev: false - - /prosemirror-keymap@1.2.3: - resolution: {integrity: sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==} - dependencies: - prosemirror-state: 1.4.4 - w3c-keyname: 2.2.8 - dev: false - - /prosemirror-markdown@1.13.2: - resolution: {integrity: sha512-FPD9rHPdA9fqzNmIIDhhnYQ6WgNoSWX9StUZ8LEKapaXU9i6XgykaHKhp6XMyXlOWetmaFgGDS/nu/w9/vUc5g==} - dependencies: - '@types/markdown-it': 14.1.2 - markdown-it: 14.1.0 - prosemirror-model: 1.25.4 - dev: false - - /prosemirror-menu@1.2.5: - resolution: {integrity: sha512-qwXzynnpBIeg1D7BAtjOusR+81xCp53j7iWu/IargiRZqRjGIlQuu1f3jFi+ehrHhWMLoyOQTSRx/IWZJqOYtQ==} - dependencies: - crelt: 1.0.6 - prosemirror-commands: 1.7.1 - prosemirror-history: 1.5.0 - prosemirror-state: 1.4.4 - dev: false - - /prosemirror-model@1.25.4: - resolution: {integrity: sha512-PIM7E43PBxKce8OQeezAs9j4TP+5yDpZVbuurd1h5phUxEKIu+G2a+EUZzIC5nS1mJktDJWzbqS23n1tsAf5QA==} - dependencies: - orderedmap: 2.1.1 - dev: false - - /prosemirror-schema-basic@1.2.4: - resolution: {integrity: sha512-ELxP4TlX3yr2v5rM7Sb70SqStq5NvI15c0j9j/gjsrO5vaw+fnnpovCLEGIcpeGfifkuqJwl4fon6b+KdrODYQ==} - dependencies: - prosemirror-model: 1.25.4 - dev: false - - /prosemirror-schema-list@1.5.1: - resolution: {integrity: sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==} - dependencies: - prosemirror-model: 1.25.4 - prosemirror-state: 1.4.4 - prosemirror-transform: 1.10.5 - dev: false - - /prosemirror-state@1.4.4: - resolution: {integrity: sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==} - dependencies: - prosemirror-model: 1.25.4 - prosemirror-transform: 1.10.5 - prosemirror-view: 1.41.4 - dev: false - - /prosemirror-tables@1.8.1: - resolution: {integrity: sha512-DAgDoUYHCcc6tOGpLVPSU1k84kCUWTWnfWX3UDy2Delv4ryH0KqTD6RBI6k4yi9j9I8gl3j8MkPpRD/vWPZbug==} - dependencies: - prosemirror-keymap: 1.2.3 - prosemirror-model: 1.25.4 - prosemirror-state: 1.4.4 - prosemirror-transform: 1.10.5 - prosemirror-view: 1.41.4 - dev: false - - /prosemirror-trailing-node@3.0.0(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.4): - resolution: {integrity: sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==} - peerDependencies: - prosemirror-model: ^1.22.1 - prosemirror-state: ^1.4.2 - prosemirror-view: ^1.33.8 - dependencies: - '@remirror/core-constants': 3.0.0 - escape-string-regexp: 4.0.0 - prosemirror-model: 1.25.4 - prosemirror-state: 1.4.4 - prosemirror-view: 1.41.4 - dev: false - - /prosemirror-transform@1.10.5: - resolution: {integrity: sha512-RPDQCxIDhIBb1o36xxwsaeAvivO8VLJcgBtzmOwQ64bMtsVFh5SSuJ6dWSxO1UsHTiTXPCgQm3PDJt7p6IOLbw==} - dependencies: - prosemirror-model: 1.25.4 - dev: false - - /prosemirror-view@1.41.4: - resolution: {integrity: sha512-WkKgnyjNncri03Gjaz3IFWvCAE94XoiEgvtr0/r2Xw7R8/IjK3sKLSiDoCHWcsXSAinVaKlGRZDvMCsF1kbzjA==} - dependencies: - prosemirror-model: 1.25.4 - prosemirror-state: 1.4.4 - prosemirror-transform: 1.10.5 - dev: false + dev: true /psl@1.15.0: resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} @@ -6090,11 +5911,6 @@ packages: punycode: 2.3.1 dev: false - /punycode.js@2.3.1: - resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} - engines: {node: '>=6'} - dev: false - /punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -6123,21 +5939,7 @@ packages: /react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - - /react-tabs@6.1.0(react@19.1.1): - resolution: {integrity: sha512-6QtbTRDKM+jA/MZTTefvigNxo0zz+gnBTVFw2CFVvq+f2BuH0nF0vDLNClL045nuTAdOoK/IL1vTP0ZLX0DAyQ==} - peerDependencies: - react: ^18.0.0 || ^19.0.0 - dependencies: - clsx: 2.1.1 - prop-types: 15.8.1 - react: 19.1.1 - dev: false - - /react@19.1.1: - resolution: {integrity: sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==} - engines: {node: '>=0.10.0'} - dev: false + dev: true /read-pkg-up@7.0.1: resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} @@ -6373,10 +6175,6 @@ packages: optionalDependencies: fsevents: 2.3.3 - /rope-sequence@1.3.4: - resolution: {integrity: sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==} - dev: false - /run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} dependencies: @@ -6567,12 +6365,6 @@ packages: engines: {node: '>=14'} dev: true - /simple-code-frame@1.3.0: - resolution: {integrity: sha512-MB4pQmETUBlNs62BBeRjIFGeuy/x6gGKh7+eRUemn1rCFhqo7K+4slPqsyizCbcbYLnaYqaoZ2FWsZ/jN06D8w==} - dependencies: - kolorist: 1.8.0 - dev: true - /slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} @@ -6617,11 +6409,6 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} - /source-map@0.7.6: - resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} - engines: {node: '>= 12'} - dev: true - /spdx-correct@3.2.0: resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} dependencies: @@ -6659,11 +6446,6 @@ packages: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} dev: true - /stack-trace@1.0.0-pre2: - resolution: {integrity: sha512-2ztBJRek8IVofG9DBJqdy2N5kulaacX30Nz7xmkYF6ale9WBVmIy6mFBchvGX7Vx/MyjBhx+Rcxqrj+dbOnQ6A==} - engines: {node: '>=16'} - dev: true - /stop-iteration-iterator@1.1.0: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} @@ -7224,11 +7006,6 @@ packages: resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==} engines: {node: '>=14.17'} hasBin: true - dev: true - - /uc.micro@2.1.0: - resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} - dev: false /unbox-primitive@1.1.0: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} @@ -7323,6 +7100,17 @@ packages: engines: {node: '>= 0.10'} dev: true + /vant@4.7.2(vue@3.3.8): + resolution: {integrity: sha512-rRVyEA8HwDKaHDLnT8x9pHv2bYfziKO76yH13Us2aUMEhx5AM/rNDJIMz0mn4G4pTKRR/UTkuqk3kVFf1Mn0wA==} + peerDependencies: + vue: ^3.0.0 + dependencies: + '@vant/popperjs': 1.3.0 + '@vant/use': 1.6.0(vue@3.3.8) + '@vue/shared': 3.5.25 + vue: 3.3.8(typescript@5.9.2) + dev: false + /vite-plugin-dts@3.9.1(@types/node@20.19.17)(typescript@5.9.2)(vite@4.5.14): resolution: {integrity: sha512-rVp2KM9Ue22NGWB8dNtWEr+KekN3rIgz1tWD050QnRGlriUCmaDwa7qA5zDEjbXg5lAXhYMSBJtx3q3hQIJZSg==} engines: {node: ^14.18.0 || >=16.0.0} @@ -7370,20 +7158,6 @@ packages: vite: 4.5.14(@types/node@20.19.17)(sass@1.93.2)(terser@5.44.0) dev: false - /vite-prerender-plugin@0.5.12(vite@4.5.14): - resolution: {integrity: sha512-EiwhbMn+flg14EysbLTmZSzq8NGTxhytgK3bf4aGRF1evWLGwZiHiUJ1KZDvbxgKbMf2pG6fJWGEa3UZXOnR1g==} - peerDependencies: - vite: 5.x || 6.x || 7.x - dependencies: - kolorist: 1.8.0 - magic-string: 0.30.19 - node-html-parser: 6.1.13 - simple-code-frame: 1.3.0 - source-map: 0.7.6 - stack-trace: 1.0.0-pre2 - vite: 4.5.14(@types/node@20.19.17)(sass@1.93.2)(terser@5.44.0) - dev: true - /vite@4.5.14(@types/node@20.19.17)(sass@1.93.2)(terser@5.44.0): resolution: {integrity: sha512-+v57oAaoYNnO3hIu5Z/tJRZjq5aHM2zDve9YZ8HngVHbhk66RStobhb1sqPMIPEleV6cNKYK4eGrAbE9Ulbl2g==} engines: {node: ^14.18.0 || >=16.0.0} @@ -7440,6 +7214,21 @@ packages: typescript: 5.9.2 dev: true + /vue@3.3.8(typescript@5.9.2): + resolution: {integrity: sha512-5VSX/3DabBikOXMsxzlW8JyfeLKlG9mzqnWgLQLty88vdZL7ZJgrdgBOmrArwxiLtmS+lNNpPcBYqrhE6TQW5w==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@vue/compiler-dom': 3.3.8 + '@vue/compiler-sfc': 3.3.8 + '@vue/runtime-dom': 3.3.8 + '@vue/server-renderer': 3.3.8(vue@3.3.8) + '@vue/shared': 3.3.8 + typescript: 5.9.2 + /w3c-hr-time@1.0.2: resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==} deprecated: Use your platform's native performance.now() and performance.timeOrigin. @@ -7447,10 +7236,6 @@ packages: browser-process-hrtime: 1.0.0 dev: false - /w3c-keyname@2.2.8: - resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} - dev: false - /w3c-xmlserializer@3.0.0: resolution: {integrity: sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==} engines: {node: '>=12'} diff --git a/src/app.scss b/src/app.scss deleted file mode 100644 index f4de6b68d7794dfbe6bd70ea3fba2b1d1928c450..0000000000000000000000000000000000000000 --- a/src/app.scss +++ /dev/null @@ -1,9 +0,0 @@ -@import 'cherry-markdown/dist/cherry-markdown.css'; - -body { - position: relative; - width: 100vw; - height: 100vh; - padding: 0; - margin: 0; -} diff --git a/src/app.tsx b/src/app.tsx deleted file mode 100644 index 49d805e6bb54fe21acf945a241f3e547995add23..0000000000000000000000000000000000000000 --- a/src/app.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import './app.scss'; -import { chat } from './controller'; -import { createUUID } from './utils'; - -export function App() { - const onClick = () => { - const ai = chat.create({ - async question(question): Promise { - const id = createUUID(); - return new Promise(resolve => { - setTimeout(() => { - ai.addMessage({ - messageid: id, - state: 20, - role: 'ASSISTANT', - content: '# 标题', - type: 'DEFAULT', - }); - - setTimeout(() => { - ai.addMessage({ - messageid: id, - state: 20, - role: 'ASSISTANT', - content: '\n\n# 标题2', - type: 'DEFAULT', - }); - - setTimeout(() => { - ai.addMessage({ - messageid: id, - state: 20, - role: 'ASSISTANT', - content: '\n\n# 标题3', - type: 'DEFAULT', - }); - - setTimeout(() => { - ai.addMessage({ - messageid: id, - state: 20, - role: 'ASSISTANT', - content: '\n\n# 标题4', - type: 'DEFAULT', - }); - - setTimeout(() => { - ai.addMessage({ - messageid: id, - state: 20, - role: 'ASSISTANT', - content: '\n\n# markdown', - type: 'DEFAULT', - }); - resolve(true); - }, 500); - }, 500); - }, 500); - }, 500); - }, 500); - }); - }, - }); - }; - - return ( - <> - - - ); -} diff --git a/src/components/chat-back-bottom/chat-back-bottom.scss b/src/components/chat-back-bottom/chat-back-bottom.scss deleted file mode 100644 index 4425071040d298b1f65aeb949eccc6fc69d4fd27..0000000000000000000000000000000000000000 --- a/src/components/chat-back-bottom/chat-back-bottom.scss +++ /dev/null @@ -1,26 +0,0 @@ -@include b(chat-back-bottom) { - position: absolute; - z-index: 5; - display: none; - align-items: center; - justify-content: center; - width: 32px; - height: 32px; - font-size: getCssVar(font-size, header, 6); - color: getCssVar(ai-chat, color, 2); - cursor: pointer; - background-color: getCssVar(ai-chat, background, color, 2); - border-radius: getCssVar(border-radius, circle); - - &:hover { - background-color: getCssVar(ai-chat, hover, background, color, 2); - } - - @include e(icon) { - font-size: 20px; - } - - @include when(visible) { - display: flex; - } -} \ No newline at end of file diff --git a/src/components/chat-back-bottom/chat-back-bottom.tsx b/src/components/chat-back-bottom/chat-back-bottom.tsx deleted file mode 100644 index d993736ea3062223ead88cca0abb48f152facf1f..0000000000000000000000000000000000000000 --- a/src/components/chat-back-bottom/chat-back-bottom.tsx +++ /dev/null @@ -1,119 +0,0 @@ -import { useSignal } from '@preact/signals'; -import { useEffect, useMemo } from 'preact/hooks'; -import { Namespace } from '../../utils'; -import { ArrowDownOutlineSvg } from '../../icons'; -import './chat-back-bottom.scss'; - -export interface ChatBackBottomProps { - /** - * @description 右侧距离 - * @type {number} - * @memberof ChatBackBottomProps - */ - right: number; - - /** - * @description 底部距离 - * @type {number} - * @memberof ChatBackBottomProps - */ - bottom: number; - - /** - * @description 滚动目标 - * @type {string} - * @memberof ChatBackBottomProps - */ - target: string; - - /** - * @description 滚动高度达到此参数值才出现 - * @type {number} - * @memberof ChatBackBottomProps - */ - visibilityHeight?: number; - /** - * 点击事件 - * - * @memberof ChatBackBottomProps - */ - onClick?: () => void; -} - -export function throttle( - fn: (...args: unknown[]) => void | Promise, - wait: number, -): (...args: unknown[]) => void { - let timer: unknown = null; - return function (this: unknown, ...args: unknown[]): void { - if (!timer) { - timer = setTimeout(() => { - fn.apply(this, args); - timer = null; - }, wait); - } - }; -} - -export const ChatBackBottom = (props: ChatBackBottomProps) => { - // 是否显示 - const visible = useSignal(false); - - // 按钮样式 - const buttonStyle = useSignal({}); - - const ns = new Namespace('chat-back-bottom'); - - const container = useSignal(null); - - const handleScroll = () => { - if (container.value) { - const visibilityHeight = props.visibilityHeight || 200; - const scrollBottom = - container.value.scrollHeight - - container.value.scrollTop - - container.value.offsetHeight; - visible.value = scrollBottom >= visibilityHeight; - } - }; - - const handleClick = () => { - if (container.value) { - container.value.scrollTo({ - top: container.value.scrollHeight, - behavior: 'smooth', - }); - props.onClick?.(); - } - }; - - const handleScrollThrottled = throttle(handleScroll, 300); - - useMemo(() => { - buttonStyle.value = { - right: `${props.right}px`, - bottom: `${props.bottom}px`, - }; - }, [props.right, props.bottom]); - - useEffect(() => { - if (props.target) { - const el = document.querySelector(props.target) ?? undefined; - if (el) { - container.value = el; - el.addEventListener('scroll', handleScrollThrottled); - handleScroll(); - } - } - }, []); - - return ( -
- -
- ); -}; diff --git a/src/components/chat-container/chat-container.scss b/src/components/chat-container/chat-container.scss index 62b2fea07bafd75f9c50db3a73a479db5f041156..85c7e1b5c035cbdd3f1f664355a2cc6c2dfcebb0 100644 --- a/src/components/chat-container/chat-container.scss +++ b/src/components/chat-container/chat-container.scss @@ -5,155 +5,84 @@ $ai-chat: ( 'border-color': #e5e5e5, 'background-color': #fff, 'background-color-light': #f8fafb, + // 倒角 + 'border-radius': 5px, // 禁用态 'disabled-color': rgb(59 59 59 / 60%), - // 悬浮态 - 'hover-color': #3b3b3b, - 'hover-background-color': #e9e9e9, - 'hover-border-color': #e5e5e5, - // 默认圆角 - 'border-radius': 5px, // 样式2 - 'color-2': #4d6bfe, - 'background-color-2': rgb(219 234 254), - 'hover-background-color-2': #c3daf8, - 'scroll-bar-width': 8px, - 'scroll-bar-height': 8px, - 'scroll-bar-radius': 4px, + 'color-2': #fff, + 'background-color-2': linear-gradient(135deg, #667eea 0%, #764ba2 100%) ); -@include b(chat-container) { +@include b('chat-container') { @include set-component-css-var('ai-chat', $ai-chat); - @include e(dialog) { - position: absolute; - z-index: 1000; + position: absolute; + top: 0; + left: 0; + display: flex; + flex-direction: column; + width: 100%; + height: 100%; + background-color: getCssVar('ai-chat', 'background-color'); + + @include e('header') { display: flex; - flex-direction: column; - background-color: #{getCssVar('ai-chat', 'background-color')}; - border: 1px solid #{getCssVar('ai-chat', 'border-color')}; - border-radius: #{getCssVar('ai-chat', 'border-radius')}; - - * { - box-sizing: border-box; - } - - svg { - display: inline-block; - width: 1em; - height: 1em; - font-size: 1.5em; /* 设置字体大小 */ - vertical-align: middle; - fill: currentcolor; - } - @include when(hidden) { - display: none; + flex-shrink: 0; + gap: 0.75rem; + align-items: center; + justify-content: space-between; + padding: 1rem; + color: #fff; + background-image: linear-gradient( + to right, + oklch(0.623 0.214 259.815deg) 0%, + oklch(0.558 0.288 302.321deg) 100% + ); + box-shadow: + rgb(0 0 0 / 0%) 0 0 0 0, + rgb(0 0 0 / 0%) 0 0 0 0, + rgb(0 0 0 / 0%) 0 0 0; + + @include m(left) { + display: flex; + gap: 0.75rem; + align-items: center; } - } - @include e(toolbar) { - position: absolute; - bottom: 162px; - left: 50%; - gap: 8px 4px; - justify-content: center; - width: max-content; - min-height: 48px; - margin: 0; - transform: translateX(-50%); - @include when(has-materials) { - bottom: 222px; + @include m(icon) { + display: flex; + align-items: center; + justify-content: center; + width: 2.5rem; + height: 2.5rem; + background-color: oklab(0.999994 0.0000455678 0.0000200868 / 20%); + border-radius: 50%; + + svg { + width: 1.5rem; + height: 1.5rem; + } } - } - *::-webkit-scrollbar { - width: getCssVar('ai-chat', 'scroll-bar-width'); - height: getCssVar('ai-chat', 'scroll-bar-height'); + @include m(caption) { + font-size: 1.25rem; + font-weight: 600; + } } - *::-webkit-scrollbar-thumb { - border-radius: getCssVar('ai-chat', 'scroll-bar-radius'); + @include e('content') { + flex-grow: 1; + min-height: 0; + background-color: #fbf9fa; } -} - -@include b(chat-container-header) { - display: flex; - flex-shrink: 0; - align-items: center; - justify-content: space-between; - height: 60px; - padding: 4px; - cursor: move; - border-bottom: 1px solid #{getCssVar('ai-chat', 'border-color')}; -} -@include b(chat-container-header-caption) { - padding: 0 6px 0 16px; - font-size: 18px; - font-weight: 800; -} - -@include b(chat-container-header-action-wrapper) { - display: flex; - gap: 6px; - align-items: center; - height: 100%; - padding: 0 6px; - - @include e(action-item) { + @include e('footer') { flex-shrink: 0; - padding: 3px; - font-size: 12px; - color: #{getCssVar('ai-chat', 'color')}; - border-radius: #{getCssVar('ai-chat', 'border-radius')}; - - &:hover { - color: #{getCssVar('ai-chat', 'hover-color')}; - cursor: pointer; - background-color: #{getCssVar('ai-chat', 'hover-background-color')}; - } - } -} - -@include b(chat-container-main) { - display: flex; - height: calc(100% - 60px); -} - -@include b(chat-container-main__left) { - flex-shrink: 0; - width: 200px; - height: 100%; - border-right: 1px solid #{getCssVar('ai-chat', 'border-color')}; -} - -@include b(chat-container-main__right) { - position: relative; - display: flex; - flex-direction: column; - flex-grow: 1; - height: 100%; - - .#{bem(chat-messages)} { - padding-bottom: 48px; + border-top: 1px solid oklch(0.928 0.006 264.531deg); + box-shadow: + rgb(0 0 0 / 0%) 0 0 0 0, + rgb(0 0 0 / 0%) 0 0 0 0, + rgb(0 0 0 / 0%) 0 0 0; } } - -@include b(chat-container-main__default) { - display: flex; - flex-direction: column; - flex-grow: 1; - height: calc(100% - 60px); -} - -@include b(chat-container-content) { - position: relative; - flex-grow: 1; - overflow: hidden; -} - -@include b(chat-container-footer) { - flex-shrink: 0; - padding: 3px 6px; - border-top: 1px solid #{getCssVar('ai-chat', 'border-color')}; -} diff --git a/src/components/chat-container/chat-container.tsx b/src/components/chat-container/chat-container.tsx index 813dae690a5c0c577c646eeac83d9a8faf2c3bf1..2a318334dc80194c95e7cc597a569a55ca7b25e3 100644 --- a/src/components/chat-container/chat-container.tsx +++ b/src/components/chat-container/chat-container.tsx @@ -1,716 +1,111 @@ -/* eslint-disable no-unused-vars */ -/* eslint-disable @typescript-eslint/no-unused-vars */ -/* eslint-disable @typescript-eslint/no-explicit-any */ -/* eslint-disable @typescript-eslint/ban-types */ -import { Component, createContext, createRef } from 'preact'; -import interact from 'interactjs'; -import { Namespace, isWithinBounds, limitDraggable } from '../../utils'; -import { ChatMessages } from '../chat-messages/chat-messages'; -import { ChatInput } from '../chat-input/chat-input'; -import { AiChatController, AiTopicController } from '../../controller'; -import { - CloseSvg, - MinimizeSvg, - FullScreenSvg, - CloseFullScreenSvg, -} from '../../icons'; -import { AIChatConst } from '../../constants'; +import { PropType, defineComponent } from 'vue'; +import { Namespace } from '../../utils'; import { IAutoClose, IChatToolbarItem, IChatContainerOptions, } from '../../interface'; -import { ChatTopics } from '../chat-topics/chat-topics'; -import { ChatToolbar } from '../chat-toolbar/chat-toolbar'; -import { ChatMinimize } from '../chat-minimize/chat-minimize'; +import { AI } from '../../icon'; +import { ChatMessages, ChatInput } from '../../components'; +import { AIChatController, AITopicController } from '../../controller'; import './chat-container.scss'; -export interface ChatContainerProps { - /** - * 呈现模式 - * - * @author tony001 - * @date 2025-02-23 16:02:00 - * @type {('DEFAULT' | 'TOPIC')} - */ - mode: 'DEFAULT' | 'TOPIC'; - - /** - * 是否允许回填 - * - * @author tony001 - * @date 2025-03-10 16:03:08 - * @type {boolean} - */ - enableBackFill?: boolean; - - /** - * ai话题控制器 - * - * @author tony001 - * @date 2025-02-23 16:02:38 - * @type {AiTopicController} - */ - aiTopic: AiTopicController; - /** - * 聊天控制器 - * - * @author tony001 - * @date 2025-02-23 16:02:24 - * @type {AiChatController} - */ - aiChat: AiChatController; - - /** - * 隐藏话题侧边栏 - */ - hideTopicSidebar: boolean; - - /** - * 关闭聊天窗口 - * - * @author chitanda - * @date 2023-10-15 19:10:35 - */ - close: () => void; - - /** - * 全屏行为 - * - * @memberof ChatContainerProps - */ - fullscreen: (target: boolean) => void; - - /** - * 最小化行为 - * - * @memberof ChatContainerProps - */ - minimize: (target: boolean) => void; - - /** - * 标题 - * - * @type {string} - * @memberof ChatContainerProps - */ - caption?: string; - - /** - * 内容工具项 - * - * @type {IChatToolbarItem[]} - * @memberof ChatContainerProps - */ - contentToolbarItems?: IChatToolbarItem[]; - - /** - * 底部工具项 - * - * @type {IChatToolbarItem[]} - * @memberof ChatContainerProps - */ - footerToolbarItems?: IChatToolbarItem[]; - - /** - * 提问区工具栏 - * - * @author tony001 - * @date 2025-02-28 16:02:51 - * @type {IChatToolbarItem[]} - */ - questionToolbarItems?: IChatToolbarItem[]; - - /** - * AI容器呈现 - * - * @author tony001 - * @date 2025-03-03 16:03:06 - * @type {IChatContainerOptions} - */ - containerOptions?: IChatContainerOptions; - - /** - * 自动关闭 - * - * @type {IAutoClose} - * @memberof ChatContainerProps - */ - autoClose?: IAutoClose; - - /** - * @description AI窗口的打开模式 - * - default:默认;minimize:最小化;autoexpand:自动展开 - * @type {('default' | 'minimize' | 'autoexpand')} - * @memberof IChat - */ - openMode?: 'default' | 'minimize' | 'autoexpand'; -} -/** - * 容器状态 - */ -interface ChatContainerState { - /** - * 全屏状态 - * - * @author ljx - * @date 2024-05-07 15:10:31 - */ - isFullScreen: boolean; - - /** - * 最小化 - * - * @type {boolean} - * @memberof ChatContainerState - */ - isMinimize: boolean; - - /** - * 是否启用最小化 - * - * @type {boolean} - * @memberof ChatContainerState - */ - enableAIMinimize: boolean; -} - -// zIndex上下文接口 -interface ContainerContext { - zIndex: number; - enableBackFill: boolean; -} - -// zIndex上下文 -export const ContainerContext = createContext({ - zIndex: 10, - enableBackFill: true, -}); - -/** - * 聊天窗口容器,可拖拽,可缩放 - * - * @author chitanda - * @date 2023-10-13 17:10:37 - * @export - * @class ChatContainer - * @extends {Component} - */ -export class ChatContainer extends Component< - ChatContainerProps, - ChatContainerState -> { - constructor(props: ChatContainerProps | undefined) { - super(props); - // 初始化状态 - this.state = { - isFullScreen: false, - isMinimize: !!( - props?.openMode === 'minimize' || props?.openMode === 'autoexpand' - ), - enableAIMinimize: props?.containerOptions?.enableAIMinimize === true, +export const ChatContainer = defineComponent({ + props: { + enableBackFill: { + type: Boolean, + default: true, + }, + aiTopic: { + type: Object as PropType, + required: true, + }, + aiChat: { + type: Object as PropType, + required: true, + }, + caption: { + type: String, + default: 'AI助手', + }, + contentToolbarItems: { + type: Array as PropType, + }, + footerToolbarItems: { + type: Array as PropType, + }, + questionToolbarItems: { + type: Array as PropType, + }, + containerOptions: { + type: Object as PropType, + }, + autoClose: { + type: Object as PropType, + }, + }, + emits: { + close: () => true, + }, + setup(props, { emit }) { + const ns = new Namespace('chat-container'); + const zIndex = props.containerOptions?.zIndex || 10; + + /** + * @description 关闭 + */ + const onClose = (): void => { + emit('close'); }; - props?.aiChat.evt.on('onCompleteMessage', () => { + props.aiChat.evt.on('onCompleteMessage', () => { // 窗口自动关闭 if (props.autoClose) { const { mode, duration = 3 } = props.autoClose; switch (mode) { - case 'minimize': - this.minimize(); - break; case 'close': - this.close(); + onClose(); break; case 'closetime': setTimeout(() => { - this.close(); + onClose; }, duration * 1000); break; default: break; } } - - // 窗口的打开模式,请求结束后自动打开 - if (props.openMode === 'autoexpand') { - this.exitMinimize(); - } }); - } - - ns = new Namespace('chat-container'); - containerRef = createRef(); - - dragHandle = createRef(); - - /** - * 窗口样式数据 - * - * @memberof ChatContainer - */ - data = { - side: { - y: 0, - height: 1, - width: 750 / window.innerWidth, - x: (window.innerWidth - 750) / window.innerWidth, - }, - window: { - y: 0, - width: 750 / window.innerWidth, - height: 750 / window.innerHeight, - x: (window.innerWidth - 750) / window.innerWidth, - }, - minWidth: 500, - minHeight: 300, - showMode: 'side', - }; - - /** - * 是否禁止拖动 - * - 拖拽边时应禁止拖动 - * @type {boolean} - * @memberof ChatContainer - */ - disabled: boolean = false; - - /** - * 最小化是否在拖拽中 - * - 在拖拽时不应触发点击事件 - * @type {boolean} - * @memberof ChatContainer - */ - isDragging: boolean = false; - - /** - * 容器上下文 - * - * @author tony001 - * @date 2025-03-03 16:03:44 - * @type {ContainerContext} - */ - containerContext: ContainerContext = { - zIndex: this.props.containerOptions?.zIndex || 10, - enableBackFill: - this.props?.enableBackFill !== undefined && - this.props?.enableBackFill !== null - ? this.props?.enableBackFill - : true, - }; - - /** - * 计算AI窗口样式 - * - * @return {*} - * @memberof ChatContainer - */ - calcWindowStyle() { - const data = - this.data.showMode === 'window' ? this.data.window : this.data.side; return { - left: `${data.x * 100}%`, - top: `${data.y * 100}%`, - width: `${data.width * 100}%`, - height: `${data.height * 100}%`, - minWidth: `${this.data.minWidth}px`, - minHeight: `${this.data.minHeight}px`, - 'z-index': this.props.containerOptions?.zIndex?.toString() || '10', + ns, + zIndex, + onClose, }; - } - - /** - * 计算靠边模式样式 - * - * @param {('left' | 'right')} side - * @memberof ChatContainer - */ - calcSideModeStyle(side: 'left' | 'right'): void { - Object.assign(this.data, { - side: { - y: 0, - x: side === 'left' ? 0 : (window.innerWidth - 750) / window.innerWidth, - height: 1, - width: 750 / window.innerWidth, - }, - showMode: 'side', - }); - } - - /** - * 设置样式 - * - * @memberof ChatContainer - */ - setStyle(): void { - Object.assign(this.containerRef.current!.style, this.calcWindowStyle()); - localStorage.setItem(AIChatConst.STYLE_CACHE, JSON.stringify(this.data)); - } - - /** - * 吸附边缘(窗口模式) - * - 靠近窗口上下边缘(20px) - 自动吸附 - * - 靠近窗口左右边缘(20px) - 靠边模式 - * @memberof ChatContainer - */ - snapToEdge(): void { - const snapWidth = 20 / window.innerWidth; - const snapHeight = 20 / window.innerHeight; - const { x, y, width, height } = this.data.window; - // 靠边模式 - if (x < snapWidth || x + width > 1 - snapWidth) { - this.calcSideModeStyle(x < snapWidth ? 'left' : 'right'); - } else { - // 吸附模式 - if (y < snapHeight) this.data.window.y = 0; - if (y + height > 1 - snapHeight) this.data.window.y = 1 - height; - } - this.setStyle(); - } - - /** - * 注册对话框拖拽 - * - * @memberof ChatContainer - */ - registerDragDialog(): void { - this.dragHandle.current!.onmousedown = (e: MouseEvent): void => { - if (this.state.isFullScreen) return; - // 禁止选择文本,避免拖动时出现选择效果 - document.body.style.userSelect = 'none'; - const offsetX = e.clientX - this.containerRef.current!.offsetLeft; - const offsetY = e.clientY - this.containerRef.current!.offsetTop; - const onMouseMove = (evt: MouseEvent): void => { - if (this.disabled) return; - // 如果是靠边模式进行拖拽,立即变为窗口模式 - this.data.showMode = 'window'; - const { x, y } = limitDraggable( - evt.clientX - offsetX, - evt.clientY - offsetY, - this.data.window.width, - this.data.window.height, - ); - Object.assign(this.data.window, { x, y }); - this.setStyle(); - }; - - const onMouseUp = (): void => { - // 恢复选择文本功能 - document.body.style.userSelect = ''; - document.removeEventListener('mousemove', onMouseMove); - document.removeEventListener('mouseup', onMouseUp); - if (this.disabled) return; - this.snapToEdge(); - }; - - document.addEventListener('mousemove', onMouseMove); - document.addEventListener('mouseup', onMouseUp); - }; - } - - /** - * 注册对话框边界拖拽 - * - * @memberof ChatContainer - */ - registerDragDialogBorder(): void { - // 注册窗口大小变更 - interact(this.containerRef.current!).resizable({ - // 可拖拽的边缘 - edges: { - top: true, - right: true, - bottom: true, - left: true, - }, - margin: 6, - modifiers: [ - // 保持在父对象内部 - interact.modifiers.restrictEdges({ outer: document.body }), - // 缩放最小宽度 - interact.modifiers.restrictSize({ - min: { width: this.data.minWidth, height: this.data.minHeight }, - }), - ], - inertia: true, - listeners: { - move: event => { - if (this.state.isFullScreen) return; - const data = - this.data.showMode === 'side' ? this.data.side : this.data.window; - data.x = event.rect.left / window.innerWidth; - data.y = event.rect.top / window.innerHeight; - data.width = event.rect.width / window.innerWidth; - data.height = event.rect.height / window.innerHeight; - this.setStyle(); - }, - start: () => { - // 禁止选择文本,避免拖动时出现选择效果 - this.disabled = true; - document.body.style.userSelect = 'none'; - }, - end: () => { - // 恢复选择文本功能 - this.disabled = false; - document.body.style.userSelect = ''; - }, - }, - }); - } - - /** - * 处理全屏改变 - * - * @memberof ChatContainer - */ - handleFullScreenChange(): void { - this.setState({ isFullScreen: document.fullscreenElement !== null }); - } - - componentDidMount(): void { - this.handleFullScreenChange = this.handleFullScreenChange.bind(this); - const cache = localStorage.getItem(AIChatConst.STYLE_CACHE); - if (cache) { - const data = JSON.parse(cache); - if ( - data.side && - isWithinBounds(data.side) && - data.window && - isWithinBounds(data.window) - ) - Object.assign(this.data, data); - } - this.setStyle(); - this.registerDragDialog(); - this.registerDragDialogBorder(); - document.addEventListener('fullscreenchange', this.handleFullScreenChange); - } - - componentWillUnmount(): void { - document.removeEventListener( - 'fullscreenchange', - this.handleFullScreenChange, - ); - } - - /** - * 关闭聊天窗口 - * - * @author chitanda - * @date 2023-10-15 19:10:31 - */ - close(): void { - this.props.close(); - } - - /** - * 全屏 - * - * @author ljx - * @date 2024-05-07 15:10:31 - */ - fullScreen(): void { - const container = this.containerRef.current; - if (container) { - container.requestFullscreen(); - this.props.fullscreen(true); - } - } - - /** - * 关闭全屏 - * - * @author ljx - * @date 2024-05-07 15:10:31 - */ - closeFullScreen(): void { - if (this.state.isFullScreen) { - document?.exitFullscreen(); - this.props.fullscreen(false); - this.setStyle(); - } - } - - /** - * 最小化 - * - * @memberof ChatContainer - */ - minimize(): void { - this.closeFullScreen(); - this.setState({ isMinimize: true }); - this.props.minimize(true); - } - - /** - * 退出最小化 - * - * @memberof ChatContainer - */ - exitMinimize(): void { - this.setState({ isMinimize: false }); - this.props.minimize(false); - } - - /** - * 阻止冒泡 - * - 防止点击头部行为时误触发拖动监听 - * @param {MouseEvent} evt - * @memberof ChatContainer - */ - stopPropagation(evt: MouseEvent): void { - evt.stopPropagation(); - } - + }, render() { return ( - -
-
-
-
- {this.props.caption || 'AI助手'} -
-
- {this.state.enableAIMinimize && ( -
- -
- )} - {this.state.isFullScreen ? ( -
- -
- ) : ( -
- -
- )} -
- -
-
-
- {this.props.mode === 'TOPIC' ? ( -
- {!this.props.hideTopicSidebar && ( -
- -
- )} -
-
- -
- 0, - )}`} - controller={this.props.aiChat} - items={this.props.footerToolbarItems} - /> -
- -
-
-
- ) : ( -
-
- -
- 0, - )}`} - controller={this.props.aiChat} - items={this.props.footerToolbarItems} - /> -
- -
-
- )} +
+
+
+
{AI}
+
{this.caption}
-
+
+
+ +
+
+
- +
); - } -} + }, +}); diff --git a/src/components/chat-editor/chat-editor.scss b/src/components/chat-editor/chat-editor.scss deleted file mode 100644 index b1829eb2140854378b7e9705c2e39a9611320953..0000000000000000000000000000000000000000 --- a/src/components/chat-editor/chat-editor.scss +++ /dev/null @@ -1,44 +0,0 @@ -@include b(chat-editor) { - .ProseMirror { - height: 6em; - padding: 6px; - overflow: hidden auto; - font-size: 16px; - color: #{getCssVar('ai-chat', 'color')}; - background-color: #{getCssVar('ai-chat', 'background-color')}; - outline: none; - - // 设置滚动条样式 - &::-webkit-scrollbar { - width: getCssVar('ai-chat', 'scroll-bar-width'); - height: getCssVar('ai-chat', 'scroll-bar-height'); - } - - // 滚动条轨道 - &::-webkit-scrollbar-thumb { - background-color: getCssVar(color, fill, 2); - border-radius: #{getCssVar('ai-chat', 'border-radius')}; - } - - p { - padding: 0; - margin: 0; - } - } - - img { - width: 100px; - height: 100px; - padding: 2px; - user-select: auto; - } - - @include m(disabled) { - cursor: not-allowed; - - > div { - pointer-events: none; - } - } -} - diff --git a/src/components/chat-editor/chat-editor.tsx b/src/components/chat-editor/chat-editor.tsx deleted file mode 100644 index c01937ef7380b26fad5d21e1209453523d2bb74a..0000000000000000000000000000000000000000 --- a/src/components/chat-editor/chat-editor.tsx +++ /dev/null @@ -1,208 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import { useEffect, useRef } from 'preact/hooks'; -import { Editor } from '@tiptap/core'; -import Document from '@tiptap/extension-document'; -import Text from '@tiptap/extension-text'; -import Paragraph from '@tiptap/extension-paragraph'; -import { UndoRedo } from '@tiptap/extensions'; -import Image from '@tiptap/extension-image'; -import FileHandler from '@tiptap/extension-file-handler'; -import { Namespace } from '../../utils'; -import { AiChatController } from '../../controller'; -import './chat-editor.scss'; - -export interface ChatEditorProps { - /** - * @description 聊天控制器 - * @type {AiChatController} - * @memberof ChatEditorProps - */ - c: AiChatController; - /** - * @description 编辑器值 - * @type {string} - * @memberof ChatEditorProps - */ - value: string; - /** - * @description 是否禁用 - * @type {boolean} - * @memberof ChatEditorProps - */ - disabled: boolean; - /** - * @description 编辑器创建事件 - * @memberof ChatEditorProps - */ - onCreate: (editor: Editor) => void; - /** - * @description 值改变事件 - * @memberof ChatEditorProps - */ - onChange: (value: string) => void; - /** - * @description 键盘输入事件 - * @memberof ChatEditorProps - */ - onKeyDown: (e: KeyboardEvent) => boolean | void; -} - -const ns = new Namespace('chat-editor'); - -export const ChatEditor = ({ - c, - value, - disabled, - onCreate, - onChange, - onKeyDown, -}: ChatEditorProps) => { - // 编辑器引用 - const editorRef = useRef(null); - // 编辑器元素引用 - const editorElementRef = useRef(null); - - useEffect(() => { - if (!editorElementRef.current) return; - - const uploadHeaders = (window as any).ibiz.util.file.getUploadHeaders(); - - const { uploadUrl, downloadUrl } = ( - window as any - ).ibiz.util.file.calcFileUpDownUrl( - c.context, - c.params, - {}, - { enableNoAccess: true }, - ); - - // 上传文件 - const uploadFile = async ( - file: Blob, - ): Promise<{ name: string; url: string }> => { - const formData = new FormData(); - formData.append('file', file); - const res = await (window as any).ibiz.net.axios({ - url: uploadUrl, - method: 'post', - headers: uploadHeaders, - data: formData, - }); - const data = res.data; - if (!data) return { name: '', url: '' }; - const url = downloadUrl.replace('%fileId%', data.fileid); - return { name: data.name, url }; - }; - - const editor = new Editor({ - element: editorElementRef.current, - extensions: [ - Document, - Text.extend({ - addKeyboardShortcuts() { - return { - 'Mod-Enter': () => { - editorRef.current?.commands.enter(); - editorRef.current?.commands.scrollIntoView(); - return true; - }, - 'Shift-Enter': () => { - editorRef.current?.commands.enter(); - editorRef.current?.commands.scrollIntoView(); - return true; - }, - }; - }, - }), - Paragraph, - UndoRedo, - Image.configure({ - inline: true, - allowBase64: true, - HTMLAttributes: { - draggable: 'false', - }, - }).extend({ - draggable: false, - }), - FileHandler.configure({ - onDrop: async (currentEditor, files) => { - files = files.filter(file => file.type.startsWith('image/')); - if (!files.length) return; - const uploadedFiles = await Promise.all( - files.map(file => uploadFile(file)), - ); - if (currentEditor.isDestroyed) return; - currentEditor - .chain() - .deleteSelection() - .insertContentAt( - currentEditor.state.selection.from, - uploadedFiles.map(file => ({ - type: 'image', - attrs: { - src: file.url, - alt: file.name, - }, - })), - ) - .focus() - .scrollIntoView() - .run(); - }, - onPaste: async (currentEditor, files) => { - files = files.filter(file => file.type.startsWith('image/')); - if (!files.length) return; - const uploadedFiles = await Promise.all( - files.map(file => uploadFile(file)), - ); - if (currentEditor.isDestroyed) return; - currentEditor - .chain() - .deleteSelection() - .insertContentAt( - currentEditor.state.selection.from, - uploadedFiles.map(file => ({ - type: 'image', - attrs: { - src: file.url, - alt: file.name, - }, - })), - ) - .focus() - .scrollIntoView() - .run(); - }, - }), - ], - content: value || '', - editorProps: { - handleKeyDown: (_view, event) => { - return onKeyDown(event); - }, - }, - onUpdate: () => { - onChange(editor.getHTML()); - }, - onCreate: () => { - onCreate(editor); - }, - }); - - editorRef.current = editor; - - return () => { - if (editorRef.current) { - editorRef.current.destroy(); - editorRef.current = null; - } - }; - }, []); - - return ( -
-
-
- ); -}; diff --git a/src/components/chat-input-material-item/chat-input-material-item.scss b/src/components/chat-input-material-item/chat-input-material-item.scss deleted file mode 100644 index 5baee5c32152cf912343a21a644c37713a6d97be..0000000000000000000000000000000000000000 --- a/src/components/chat-input-material-item/chat-input-material-item.scss +++ /dev/null @@ -1,30 +0,0 @@ -@include b(chat-input-material-item) { - position: relative; - width: 200px; - height: 60px; - padding: 8px; - color: #{getCssVar('ai-chat', 'color')}; - background-color: #{getCssVar('ai-chat', 'background-color')}; - border: 1px solid #{getCssVar('ai-chat', 'border-color')}; - border-radius: #{getCssVar('ai-chat', 'border-radius')}; - - &:hover { - color: #{getCssVar('ai-chat', 'hover-color')}; - cursor: pointer; - background-color: #{getCssVar('ai-chat', 'hover-background-color')}; - @include b(chat-input-material-item__icon) { - opacity: 1; - } - } - - @include when(disabled) { - pointer-events: none; - } -} - -@include b(chat-input-material-item__icon) { - position: absolute; - top: -4px; - right: -4px; - opacity: 0; -} \ No newline at end of file diff --git a/src/components/chat-input-material-item/chat-input-material-item.tsx b/src/components/chat-input-material-item/chat-input-material-item.tsx deleted file mode 100644 index 62d202809bc003c3100fc569abd90e433059c1ce..0000000000000000000000000000000000000000 --- a/src/components/chat-input-material-item/chat-input-material-item.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import { h } from 'preact'; -import { AiChatController } from '../../controller'; -import { Namespace } from '../../utils'; -import { IMaterial } from '../../interface'; -import { OssfileMaterial } from './ossfile-material/ossfile-material'; -import { CommonMaterial } from './common-material/common-material'; -import { MaterialRemoveSvg } from '../../icons'; -import './chat-input-material-item.scss'; - -const ns = new Namespace('chat-input-material-item'); - -export interface ChatInputMaterialtemProps { - /** - * 聊天控制器 - * - * @author tony001 - * @date 2025-02-28 15:02:04 - * @type {AiChatController} - */ - controller: AiChatController; - - /** - * 素材对象 - * - * @author tony001 - * @date 2025-02-28 15:02:45 - * @type {IMaterial} - */ - material: IMaterial; - - /** - * 禁用状态 - * - * @author tony001 - * @date 2025-03-03 14:03:26 - * @type {boolean} - */ - disabled: boolean; -} - -export const ChatInputMaterialtem = (props: ChatInputMaterialtemProps) => { - const { material } = props; - - let com = null; - - switch (material.type) { - case 'ossfile': - com = OssfileMaterial; - break; - default: - com = CommonMaterial; - } - - const removeMaterialtem = () => { - props.controller.deleteMaterial(material); - }; - - return ( -
-
- -
- {h(com, { - material, - controller: props.controller, - })} -
- ); -}; diff --git a/src/components/chat-input-material-item/common-material/common-material.scss b/src/components/chat-input-material-item/common-material/common-material.scss deleted file mode 100644 index a6b148e56363cf0a9628411ef7c8dc4079741ea7..0000000000000000000000000000000000000000 --- a/src/components/chat-input-material-item/common-material/common-material.scss +++ /dev/null @@ -1,37 +0,0 @@ -@include b(common-material) { - display: flex; - width: 100%; - height: 100%; -} - -@include b(common-material-left) { - display: flex; - align-items: center; - justify-content: center; - font-size: 18px; -} - -@include b(common-material-right) { - width: calc(100% - 24px); - height: 100%; - padding-left: 8px; -} - -@include b(common-material__name) { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -@include b(common-material__metadata) { - display: flex; - gap: 8px; - align-items: center; - font-size: 14px; - - > div{ - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } -} \ No newline at end of file diff --git a/src/components/chat-input-material-item/common-material/common-material.tsx b/src/components/chat-input-material-item/common-material/common-material.tsx deleted file mode 100644 index 6971529ee89667e8cfdafe679cc832bb661062d4..0000000000000000000000000000000000000000 --- a/src/components/chat-input-material-item/common-material/common-material.tsx +++ /dev/null @@ -1,68 +0,0 @@ -/* eslint-disable no-nested-ternary */ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import { useComputed } from '@preact/signals'; -import { AiChatController } from '../../../controller'; -import { IMaterial } from '../../../interface'; -import { Namespace } from '../../../utils'; -import { DefaultMaterialSvg } from '../../../icons'; -import { isSvg } from '../../../utils/util/util'; -import './common-material.scss'; - -export interface CommonMaterialProps { - controller: AiChatController; - material: IMaterial; -} - -const ns = new Namespace('common-material'); - -export const CommonMaterial = (props: CommonMaterialProps) => { - const targetToolbarItem = props.controller.opts.questionToolbarItems?.find( - item => { - return item.id === (props.material.metadata as any).actionId; - }, - ); - - const content = useComputed(() => { - return (props.material.metadata as any).name; - }); - - return ( -
-
- {targetToolbarItem && targetToolbarItem.icon ? ( - typeof targetToolbarItem.icon === 'function' ? ( - targetToolbarItem.icon() - ) : ( - targetToolbarItem.icon?.showIcon && ( - <> - {targetToolbarItem.icon?.cssClass ? ( - - ) : targetToolbarItem.icon?.imagePath ? ( - isSvg(targetToolbarItem.icon.imagePath) ? ( -
- ) : ( - - ) - ) : null} - - ) - ) - ) : ( - - )} -
-
-
- {content} -
-
-
{targetToolbarItem?.label || '素材资源'}
-
-
-
- ); -}; diff --git a/src/components/chat-input-material-item/ossfile-material/ossfile-material.scss b/src/components/chat-input-material-item/ossfile-material/ossfile-material.scss deleted file mode 100644 index 9102ac3c8501961f94381246e1acd0ac00113395..0000000000000000000000000000000000000000 --- a/src/components/chat-input-material-item/ossfile-material/ossfile-material.scss +++ /dev/null @@ -1,36 +0,0 @@ -@include b(ossfile-material) { - display: flex; - width: 100%; - height: 100%; -} - -@include b(ossfile-material-left) { - display: flex; - align-items: center; - justify-content: center; -} - -@include b(ossfile-material-right) { - width: calc(100% - 24px); - height: 100%; - padding-left: 8px; -} - -@include b(ossfile-material__name) { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -@include b(ossfile-material__metadata) { - display: flex; - gap: 8px; - align-items: center; - font-size: 14px; - - > div{ - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } -} \ No newline at end of file diff --git a/src/components/chat-input-material-item/ossfile-material/ossfile-material.tsx b/src/components/chat-input-material-item/ossfile-material/ossfile-material.tsx deleted file mode 100644 index aa6c46ed4fd042ece1f1eb232dee413381866ab8..0000000000000000000000000000000000000000 --- a/src/components/chat-input-material-item/ossfile-material/ossfile-material.tsx +++ /dev/null @@ -1,63 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import { useComputed } from '@preact/signals'; -import { AiChatController } from '../../../controller'; -import { IMaterial } from '../../../interface'; -import { Namespace } from '../../../utils'; -import './ossfile-material.scss'; -import { FileSvg } from '../../../icons'; - -export interface OssfileMaterialProps { - controller: AiChatController; - material: IMaterial; -} - -const ns = new Namespace('ossfile-material'); - -export const OssfileMaterial = (props: OssfileMaterialProps) => { - const content = useComputed(() => (props.material.data as any).name); - const size = useComputed(() => (props.material.metadata as any).size); - const state = useComputed(() => { - const tempState = (props.material.metadata as any).state; - if (tempState === 'successed') { - return '上传成功'; - } - if (tempState === 'uploading') { - return '上传中'; - } - if (tempState === 'failed') { - return '上传失败'; - } - return '未知状态'; - }); - - const stateColor = useComputed(() => { - const tempState = (props.material.metadata as any).state; - switch (tempState) { - case 'successed': - return '#1890ff'; // 蓝色 - case 'uploading': - return '#52c41a'; // 绿色 - case 'failed': - return '#ff4d4f'; // 红色 - default: - return '#ff4d4f'; // 未知状态红色 - } - }); - - return ( -
-
- -
-
-
- {content} -
-
-
{size}B
-
{state}
-
-
-
- ); -}; diff --git a/src/components/chat-input-material/chat-input-material.scss b/src/components/chat-input-material/chat-input-material.scss deleted file mode 100644 index a0bff4a55f2da29047b413fd648ca3872720ce23..0000000000000000000000000000000000000000 --- a/src/components/chat-input-material/chat-input-material.scss +++ /dev/null @@ -1,5 +0,0 @@ -@include b(chat-input-material) { - display: flex; - flex-wrap: wrap; - gap: 8px; -} \ No newline at end of file diff --git a/src/components/chat-input-material/chat-input-material.tsx b/src/components/chat-input-material/chat-input-material.tsx deleted file mode 100644 index bd8eddfeb273523cce3554c34f37a4428b343179..0000000000000000000000000000000000000000 --- a/src/components/chat-input-material/chat-input-material.tsx +++ /dev/null @@ -1,35 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import { AiChatController } from '../../controller'; -import { Namespace } from '../../utils'; -import { ChatInputMaterialtem } from '../chat-input-material-item/chat-input-material-item'; -import './chat-input-material.scss'; - -export interface ChatInputMaterialProps { - /** - * 聊天实例 - * - * @author tony001 - * @date 2025-02-27 17:02:50 - * @type {AiChatController} - */ - controller: AiChatController; -} - -const ns = new Namespace('chat-input-material'); -export const ChatInputMaterial = (props: ChatInputMaterialProps) => { - const materials = props.controller.materials; - return ( -
- {materials.value.map(material => { - return ( - - ); - })} -
- ); -}; diff --git a/src/components/chat-input/chat-input.scss b/src/components/chat-input/chat-input.scss index e19d7a06dbcba873b6cd43d99281c414287fa8b1..303070e582f58d340a5241f1fb538e44bced3cdd 100644 --- a/src/components/chat-input/chat-input.scss +++ b/src/components/chat-input/chat-input.scss @@ -1,92 +1,61 @@ -@include b(chat-input-material-wrapper) { - max-height: 72px; - padding: 4px; - overflow: hidden auto; - font-size: 16px; - color: var(--ibiz-ai-chat-color); - background-color: var(--ibiz-ai-chat-background-color); -} - -@include b(chat-input-main-wrapper) { - border: 1px solid #{getCssVar('ai-chat', 'border-color')}; - border-radius: #{getCssVar('ai-chat', 'border-radius')}; -} - -@include b(chat-input-action-wrapper) { - display: flex; - align-items: center; - justify-content: space-between; - width: 100%; - height: 40px; -} - -@include b(chat-input-left-action-wrapper) { +@include b('chat-input') { display: flex; - flex: 1; + gap: 0.75rem; align-items: center; - width: calc(100% - 96px); - padding: 6px; -} - -@include b(chat-input-right-action-wrapper) { - display: flex; - gap: 6px; - align-items: center; - padding: 6px; - color: #{getCssVar('ai-chat', 'color')}; - - @include e(action-item) { - padding: 3px; - font-size: 12px; - border-radius: #{getCssVar('ai-chat', 'border-radius')}; - - &:hover { - color: #{getCssVar('ai-chat', 'hover-color')}; - cursor: pointer; - background-color: #{getCssVar('ai-chat', 'hover-background-color')}; + padding: 1rem; + + @include e('icon') { + display: flex; + flex-shrink: 0; + align-items: center; + justify-content: center; + width: 2.75rem; + height: 2.75rem; + color: #4a5565; + background-color: #f6f3f4; + border-radius: 50%; + + svg { + width: 1.25rem; + height: 1.25rem; } - - @include when(disabled) { - color: #{getCssVar('ai-chat', 'disabled-color')}; + + @include when('disabled') { + color: #99a1af; pointer-events: none; + background-color: #ebe6e7; } - } -} - -@include b(chat-input-pop-actions) { - width: 160px; - min-height: 48px; - padding: 8px; -} -@include b(chat-input-pop-action-item) { - display: flex; - align-items: center; - padding: 8px; - margin-bottom: 4px; - line-height: 22px; - cursor: pointer; - border-radius: 4px; - transition: background-color .2s; + @include when('recording') { + color: #fff; + background-color: #fb2c36; + } - &:hover { - background-color: var(--ibiz-color-fill-0); + @include m('send') { + &:not(.is-disabled) { + color: #fff; + background-image: linear-gradient( + to right, + oklch(0.623 0.214 259.815deg) 0%, + oklch(0.558 0.288 302.321deg) 100% + ); + } + } } -} - -@include b(chat-input-pop-action-item-icon) { - width: 18px; - height: 18px; - margin-right: 8px; - font-size: 18px; - color: #{getCssVar('ai-chat', 'color')}; - pointer-events: none; + @include e('input') { + flex-grow: 1; + max-height: 8rem; + resize: none; + background-color: #f6f3f4; + border-radius: 1rem; + padding: 0.75rem 1.25rem; + border: none; + &:focus { + border: 1px solid #2b7fff; + } + &::placeholder { + font-size: 1rem; + } + } } - -@include b(chat-input-pop-action-item-title) { - font-size: 14px; - line-height: 22px; - color: #{getCssVar('ai-chat', 'color')}; - pointer-events: none; -} \ No newline at end of file diff --git a/src/components/chat-input/chat-input.tsx b/src/components/chat-input/chat-input.tsx index 9dd316ac351ef58ce6f62a676ce9e56147e27a57..43f5a07ab5c2bc765198e2431980fa0144a17b28 100644 --- a/src/components/chat-input/chat-input.tsx +++ b/src/components/chat-input/chat-input.tsx @@ -1,336 +1,126 @@ -/* eslint-disable import/no-extraneous-dependencies */ -/* eslint-disable no-nested-ternary */ -/* eslint-disable no-unused-vars */ -/* eslint-disable @typescript-eslint/no-unused-vars */ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import { useCallback, useContext, useRef, useState } from 'preact/compat'; -import { useComputed, useSignal } from '@preact/signals'; -import { Editor } from '@tiptap/core'; +import { PropType, computed, defineComponent, onMounted, ref } from 'vue'; import { Namespace } from '../../utils'; -import { - AudioSvg, - PaperclipSvg, - RecordingSvg, - SendSvg, - FileSvg, - StopCircleSvg, -} from '../../icons'; -import { AiChatController, AIMaterialFactory } from '../../controller'; -import { ChatInputMaterial } from '../chat-input-material/chat-input-material'; -import { Popup } from '../popup/popup'; import { IChatToolbarItem } from '../../interface'; -import { isSvg } from '../../utils/util/util'; -import { ContainerContext } from '../chat-container/chat-container'; -import { ChatEditor } from '../chat-editor/chat-editor'; -import { CommonSelect } from '../common'; +import { AIChatController } from '../../controller'; +import { Send, OpenVoice, CloseVoice } from '../../icon'; import './chat-input.scss'; -export interface ChatInputProps { - /** - * 单实例聊天总控 - * - * @author chitanda - * @date 2023-10-13 17:10:43 - * @type {AiChatController} - */ - controller: AiChatController; - - /** - * 提问区交互工具栏 - * - * @author tony001 - * @date 2025-02-28 16:02:58 - * @type {IChatToolbarItem[]} - */ - questionToolbarItems?: IChatToolbarItem[]; -} - -const ns = new Namespace('chat-input'); - -// 语音识别构造器 -const SpeechRecognition = - (window as any).SpeechRecognition || (window as any).webkitSpeechRecognition; - -export const ChatInput = (props: ChatInputProps) => { - const [isPopupOpen, setIsPopupOpen] = useState(false); - - const containerContext = useContext(ContainerContext); - - const input = props.controller.input; - - // 是否正在语音输入 - const recording = useSignal(false); - - // 语音识别实例 - const recognition = useRef(); - - // 编辑器引用 - const editorRef = useRef(null); - - if (SpeechRecognition && !recognition.current) { - recognition.current = new SpeechRecognition(); - - recognition.current.onstart = () => { - recording.value = true; - }; - - recognition.current.onend = () => { - recording.value = false; - }; - - recognition.current.onresult = (e: any) => { - const transcript = e.results?.[0]?.[0]?.transcript; - if (transcript) { - editorRef.current?.commands.insertContent(transcript); +export const ChatInput = defineComponent({ + props: { + controller: { + type: Object as PropType, + required: true, + }, + toolbarItems: { + type: Array as PropType, + }, + }, + setup(props) { + const ns = new Namespace('chat-input'); + + // 消息 + const message = ref(''); + + // 语音识别中 + const recording = ref(false); + + // 语音识别实例 + const recognition = ref(); + + // 消息请求中 + const isLoading = computed(() => props.controller.isLoading.value); + + /** + * @description 初始化语音识别 + */ + const onInitRecognition = (): void => { + // 语音识别构造器 + const SpeechRecognition = + (window as any).SpeechRecognition || + (window as any).webkitSpeechRecognition; + if (SpeechRecognition) { + recognition.value = new SpeechRecognition(); + recognition.value.onstart = () => { + recording.value = true; + }; + + recognition.value.onend = () => { + recording.value = false; + }; + + recognition.value.onresult = e => { + const transcript = e.results?.[0]?.[0]?.transcript; + console.log('语音内容', transcript); + }; } }; - } - // 处理语音输入按钮点击事件 - const handleRecordButtonClick = () => { - if (recognition.current && !recording.value) { - recognition.current.start(); - } - }; - // html转md - const html2md = (html: string): string => { - const doc = new DOMParser().parseFromString(html, 'text/html'); - - function walk(node: Node): string { - if (node.nodeType === Node.TEXT_NODE) { - return node.textContent || ''; - } - if (node.nodeType !== Node.ELEMENT_NODE) return ''; - const el = node as Element; - const tag = el.tagName.toLowerCase(); - const children = Array.from(el.childNodes) - .map(childNode => walk(childNode)) - .join(''); - switch (tag) { - case 'p': - return `${children}\n`; - case 'img': { - const src = el.getAttribute('src') || ''; - const alt = el.getAttribute('alt') || ''; - return src ? `\n![${alt}](${src})\n` : ''; - } - default: - return node.textContent || ''; + onMounted(() => { + onInitRecognition(); + }); + + /** + * @description 发送消息 + * @returns {*} {Promise} + */ + const onSendMessage = async (): Promise => { + // 加载中时就终止消息 + if (isLoading.value) { + await props.controller.abortQuestion(); + } else { + const value = message.value; + message.value = ''; + await props.controller.question(value); } - } - const md = Array.from(doc.body.childNodes) - .map(walk) - .join('') - .replace(/\n+/g, '\n') - .replace(/^\n|\n$/g, ''); - return md; - }; - - const isDisableSend = useComputed(() => html2md(input.value).length <= 0); - - const question = useCallback(async () => { - try { - const inputTxt = html2md(input.value); - input.value = ''; - editorRef.current?.chain().clearContent().run(); - await props.controller.question(inputTxt); - } catch (err) { - console.error(err); - } finally { - if (editorRef.current && !editorRef.current.isDestroyed) { - editorRef.current.chain().focus().run(); - } - } - }, [input]); - - const stopQuestion = useCallback(async () => { - try { - props.controller.abortQuestion(); - } catch (error) { - console.error(error); - } - }, [input]); - - const onKeyDown = (e: KeyboardEvent) => { - if (e.code === 'Enter' && !e.isComposing) { - if (e.shiftKey === false) { - question(); - return true; - } - } - }; - - /** - * 文件上传 - * - * @author tony001 - * @date 2025-02-28 17:02:20 - */ - const uploadFile = async (event: MouseEvent) => { - const materialHelper = AIMaterialFactory.getMaterialHelper( - 'ossfile', - props.controller, - ); - await materialHelper.excuteAction(event); - setIsPopupOpen(false); - }; - - /** - * 通用问答 - * - * @author tony001 - * @date 2025-02-28 17:02:41 - * @param {IChatToolbarItem} item - */ - const commonQuestion = async (event: MouseEvent, item: IChatToolbarItem) => { - const materialHelper = AIMaterialFactory.getMaterialHelper( - 'common', - props.controller, - ); - await materialHelper.excuteAction(event, item); - setIsPopupOpen(false); - }; + }; - /** - * 设置激活AI代理 - * @param agentID - */ - const setActiveAIAgent = (agentID: string) => { - props.controller.setActiveAIAgentID(agentID); - }; + /** + * @description 语音识别 + */ + const onSpeechRecognition = (): void => { + if (!recognition.value) return; + recording.value ? recognition.value.end() : recognition.value.start(); + }; - return ( -
-
- -
-
- { - editorRef.current = editor; - }} - onChange={value => { - input.value = value; - }} - onKeyDown={onKeyDown} - > -
-
- { - setActiveAIAgent(value); - }} - placeholder={'Auto'} - disabled={!props.controller.enableAIAgentChange} - > -
-
-
- -
{ - uploadFile(e); - }} - > - - - - - 文件资料 - -
- {props.questionToolbarItems?.map(item => { - return ( -
{ - commonQuestion(e, item); - }} - > - - {typeof item.icon === 'function' - ? item.icon() - : item.icon?.showIcon && ( - <> - {item.icon?.cssClass ? ( - - ) : item.icon?.imagePath ? ( - isSvg(item.icon.imagePath) ? ( -
- ) : ( - - ) - ) : null} - - )} - - - {item.label} - -
- ); - })} -
- } - position='top-left' - isOpen={isPopupOpen} - onToggleOpen={setIsPopupOpen} - > - -
-
-
- {recording.value ? : } -
- {props.controller.isLoading.value ? ( -
- -
- ) : ( -
- -
- )} -
+ return { + ns, + message, + isLoading, + recording, + onSendMessage, + onSpeechRecognition, + }; + }, + render() { + return ( +
+
+ {this.recording ? CloseVoice : OpenVoice} +
+