Tsumugii24 commited on
Commit
f7161fa
1 Parent(s): ffaddbb

initial commit

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +1 -0
  2. .gitignore +163 -0
  3. Dockerfile +15 -0
  4. LICENSE +21 -0
  5. README.md +123 -6
  6. app.py +935 -0
  7. assets/chatbot.png +0 -0
  8. assets/favicon.ico +0 -0
  9. assets/generate_image.png +3 -0
  10. assets/html/appearance_switcher.html +6 -0
  11. assets/html/billing_info.html +9 -0
  12. assets/html/chatbot_header_btn.html +72 -0
  13. assets/html/chatbot_more.html +72 -0
  14. assets/html/close_btn.html +5 -0
  15. assets/html/footer.html +1 -0
  16. assets/html/func_nav.html +78 -0
  17. assets/html/header_title.html +11 -0
  18. assets/html/update.html +29 -0
  19. assets/html/web_config.html +23 -0
  20. assets/icon.png +0 -0
  21. assets/javascript/ChuanhuChat.js +463 -0
  22. assets/javascript/Kelpy-Codos.js +76 -0
  23. assets/javascript/chat-history.js +71 -0
  24. assets/javascript/chat-list.js +88 -0
  25. assets/javascript/external-scripts.js +2 -0
  26. assets/javascript/fake-gradio.js +116 -0
  27. assets/javascript/file-input.js +114 -0
  28. assets/javascript/localization.js +39 -0
  29. assets/javascript/message-button.js +195 -0
  30. assets/javascript/sliders.js +26 -0
  31. assets/javascript/updater.js +243 -0
  32. assets/javascript/user-info.js +70 -0
  33. assets/javascript/utils.js +132 -0
  34. assets/javascript/webui.js +333 -0
  35. assets/stylesheet/ChuanhuChat.css +1234 -0
  36. assets/stylesheet/chatbot.css +395 -0
  37. assets/stylesheet/custom-components.css +405 -0
  38. assets/stylesheet/markdown.css +62 -0
  39. assets/stylesheet/override-gradio.css +157 -0
  40. assets/user.png +0 -0
  41. config.json +12 -0
  42. config.zhipu.json +16 -0
  43. config/config.json +8 -0
  44. config/config.py +30 -0
  45. config_example.json +38 -0
  46. docs//350/257/227/350/266/243/344/274/264/350/241/214.png +0 -0
  47. history/1111.json +18 -0
  48. history/1111.md +2 -0
  49. history/对话历史记录.json +18 -0
  50. history/对话历史记录.md +2 -0
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ assets/generate_image.png filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py,cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ #Pipfile.lock
96
+
97
+ # poetry
98
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
102
+ #poetry.lock
103
+
104
+ # pdm
105
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
106
+ #pdm.lock
107
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
108
+ # in version control.
109
+ # https://pdm.fming.dev/#use-with-ide
110
+ .pdm.toml
111
+
112
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
113
+ __pypackages__/
114
+
115
+ # Celery stuff
116
+ celerybeat-schedule
117
+ celerybeat.pid
118
+
119
+ # SageMath parsed files
120
+ *.sage.py
121
+
122
+ # Environments
123
+ .env
124
+ .venv
125
+ env/
126
+ venv/
127
+ ENV/
128
+ env.bak/
129
+ venv.bak/
130
+
131
+ # Spyder project settings
132
+ .spyderproject
133
+ .spyproject
134
+
135
+ # Rope project settings
136
+ .ropeproject
137
+
138
+ # mkdocs documentation
139
+ /site
140
+
141
+ # mypy
142
+ .mypy_cache/
143
+ .dmypy.json
144
+ dmypy.json
145
+
146
+ # Pyre type checker
147
+ .pyre/
148
+
149
+ # pytype static type analyzer
150
+ .pytype/
151
+
152
+ # Cython debug symbols
153
+ cython_debug/
154
+
155
+ # PyCharm
156
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
157
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
158
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
159
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
160
+ .idea/
161
+
162
+ # VSCode
163
+ .vscode/
Dockerfile ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.9 as builder
2
+ RUN apt-get update && apt-get install -y build-essential
3
+ COPY requirements.txt .
4
+ COPY requirements_advanced.txt .
5
+ RUN pip install --user -r requirements.txt
6
+ # RUN pip install --user -r requirements_advanced.txt
7
+
8
+ FROM python:3.9
9
+ MAINTAINER iskoldt
10
+ COPY --from=builder /root/.local /root/.local
11
+ ENV PATH=/root/.local/bin:$PATH
12
+ COPY . /app
13
+ WORKDIR /app
14
+ ENV dockerrun yes
15
+ CMD ["python3", "-u", "main.py", "2>&1", "|", "tee", "/var/log/application.log"]
LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Tsumugii
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
README.md CHANGED
@@ -1,13 +1,130 @@
1
  ---
2
  title: PoetryChat
3
- emoji: 👁
4
- colorFrom: yellow
5
- colorTo: red
6
  sdk: gradio
7
- sdk_version: 4.36.1
8
  app_file: app.py
9
- pinned: false
10
  license: mit
 
11
  ---
12
 
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
  title: PoetryChat
3
+ emoji: 🤗
4
+ colorFrom: indigo
5
+ colorTo: indigo
6
  sdk: gradio
7
+ sdk_version: 3.43.2
8
  app_file: app.py
9
+ pinned: true
10
  license: mit
11
+
12
  ---
13
 
14
+
15
+
16
+ <div align="center"><h1>PoetryChat🖼️</h1></div>
17
+
18
+ </div>
19
+
20
+ [![License Apache 2.0](https://img.shields.io/badge/license-mit-blue.svg)](LICENSE)
21
+ [![python_version](https://img.shields.io/badge/Python-3.10%2B-green.svg)](requirements.txt)
22
+
23
+ <div align="center"><h2>Description</h2></div>
24
+
25
+ &emsp;&emsp;Powered by Large Language Models, PoetryChat ...
26
+
27
+
28
+
29
+ </div>
30
+
31
+ <div align="center"><h2>Demonstration</h2></div>
32
+
33
+ ![诗趣伴行](./docs/诗趣伴行.png)
34
+
35
+ &emsp;&emsp;You can easily and directly experience the our demo online on `HuggingFace` now. Click here for Online Experience 👉 [PoetryChat - a Hugging Face Space by Tsumugii](https://huggingface.co/spaces/Tsumugii/PoetryChat)
36
+
37
+ </div>
38
+
39
+ <div align="center"><h2>Todo</h2></div>
40
+
41
+ - [ ] Complete the Gradio Interface and UI design
42
+ - [ ] Add team members brief introduction
43
+ - [ ] Add a gif demonstration
44
+ - [ ] Deploy the demo on HuggingFace
45
+ - [ ] RAG layer
46
+ - [ ] LLM Agent layer
47
+ - [ ] Application layer
48
+
49
+
50
+
51
+
52
+
53
+ </div>
54
+
55
+ <div align="center"><h2>Quick Start</h2></div>
56
+
57
+ <details open>
58
+ <summary><h4>Installation</h4></summary>
59
+
60
+
61
+ &emsp;&emsp;First of all, please make sure that you have already installed `conda` as Python runtime environment. And `miniconda` is strongly recommended.
62
+
63
+ &emsp;&emsp;1. create a virtual `conda` environment for the demo 😆
64
+
65
+ ```bash
66
+ $ conda create -n poetrychat python==3.10 # poetrychat is the name of your environment
67
+ $ conda activate poetrychat
68
+ ```
69
+
70
+ &emsp;&emsp;2. Install essential `requirements` by run the following command in the `CLI` 😊
71
+
72
+ ```bash
73
+ $ git clone https://github.com/Antony-Zhang/PoetryChat && cd PoetryChat && git checkout poetryChat2.0
74
+ $ pip install -r requirements.txt
75
+ ```
76
+
77
+ <details open>
78
+ <summary><h4>Preparation</h4></summary>
79
+
80
+
81
+ &emsp;&emsp;1. open `.env.example` and fill your own `API Keys` in the **corresponding place** if you want to use certain LLM, then **rename** the file into `.env`
82
+
83
+ ```
84
+ OPENAI_API_KEY = ""
85
+ OPENAI_URL_BASE = ""
86
+ ```
87
+
88
+ &emsp;&emsp;2. xxx
89
+
90
+
91
+
92
+
93
+
94
+
95
+
96
+
97
+
98
+ </div>
99
+
100
+ <div align="center"><h2>References</h2></div>
101
+
102
+ 1. [Gradio Official Documents](https://www.gradio.app/)
103
+ 2. [LIC·2024 语言与智能技术竞赛_飞桨大赛-飞桨AI Studio星河社区](https://aistudio.baidu.com/competition/detail/1171/0/introduction)
104
+ 3. [PoetryChat: 一个面向不同年龄段的交互式LLM古诗学习助手](https://github.com/Antony-Zhang/PoetryChat)
105
+ 4. [Tsumugii24/WonderWhy (github.com)](https://github.com/Tsumugii24/WonderWhy)
106
+
107
+
108
+
109
+
110
+
111
+ </div>
112
+
113
+ <div align="center"><h2>Acknowledgements</h2></div>
114
+
115
+ &emsp;&emsp;***I would like to express my sincere gratitude to my teammates for their efforts and supports throughout the development of this project. Their expertise and insightful feedback played a crucial role in shaping the direction of the project.***
116
+
117
+ - 姜舒凡 [@Tsumugii24](https://github.com/Tsumugii24)
118
+
119
+ - 朱嘉辉 [@jiaohui](https://github.com/jiaohuix)
120
+
121
+ - 陈思州 [@jjyaoao](https://github.com/jjyaoao)
122
+
123
+
124
+
125
+ </div>
126
+
127
+ <div align="center"><h2>Contact</h2></div>
128
+
129
+ Feel free to open GitHub issues or directly send me a mail if you have any questions about this project.
130
+
app.py ADDED
@@ -0,0 +1,935 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ @author:XuMing(xuming624@qq.com)
4
+ @description:
5
+ """
6
+ import gradio as gr
7
+ from loguru import logger
8
+ # import appbuilder
9
+ import time
10
+ import os
11
+
12
+ from src.config import (
13
+ http_proxy,
14
+ hide_history_when_not_logged_in,
15
+ chat_name_method_index,
16
+ my_api_key,
17
+ multi_api_key,
18
+ server_name,
19
+ server_port,
20
+ share,
21
+ config_file,
22
+ api_host,
23
+ authflag,
24
+ dockerflag,
25
+ show_api_billing,
26
+ latex_delimiters_set,
27
+ user_avatar,
28
+ bot_avatar,
29
+ autobrowser,
30
+ update_doc_config,
31
+ )
32
+ from src.gradio_patch import reg_patch
33
+ from src.models import get_model
34
+ from src.overwrites import (
35
+ postprocess,
36
+ postprocess_chat_messages,
37
+ reload_javascript,
38
+ get_html,
39
+ )
40
+ from src.presets import (
41
+ MODEL_ALIASES,
42
+ MODELS,
43
+ HISTORY_NAME_METHODS,
44
+ small_and_beautiful_theme,
45
+ CONCURRENT_COUNT,
46
+ TITLE,
47
+ HIDE_MY_KEY,
48
+ DEFAULT_MODEL,
49
+ REPLY_LANGUAGES,
50
+ INITIAL_SYSTEM_PROMPT,
51
+ ENABLE_STREAMING_OPTION,
52
+ DESCRIPTION,
53
+ favicon_path,
54
+ API_HOST,
55
+ HISTORY_DIR,
56
+ assets_path,
57
+ )
58
+ from src.utils import (
59
+ delete_chat_history,
60
+ filter_history,
61
+ get_history_list,
62
+ auto_name_chat_history,
63
+ get_template_dropdown,
64
+ rename_chat_history,
65
+ init_history_list,
66
+ get_first_history_name,
67
+ setup_wizard,
68
+ auth_from_conf,
69
+ get_geoip,
70
+ get_template_names,
71
+ load_template,
72
+ get_history_names,
73
+ reset,
74
+ predict,
75
+ interrupt,
76
+ retry,
77
+ i18n,
78
+ dislike,
79
+ toggle_like_btn_visibility,
80
+ set_key,
81
+ set_single_turn,
82
+ hide_middle_chars,
83
+ set_system_prompt,
84
+ start_outputing,
85
+ set_token_upper_limit,
86
+ set_temperature,
87
+ set_user_identifier,
88
+ set_top_p,
89
+ delete_first_conversation,
90
+ delete_last_conversation,
91
+ set_n_choices,
92
+ set_logit_bias,
93
+ load_chat_history,
94
+ end_outputing,
95
+ set_max_tokens,
96
+ reset_default,
97
+ reset_textbox,
98
+ set_stop_sequence,
99
+ set_presence_penalty,
100
+ set_frequency_penalty,
101
+ upload_chat_history,
102
+ export_markdown,
103
+ billing_info,
104
+ get_template_content,
105
+ like,
106
+ transfer_input,
107
+ handle_file_upload,
108
+ handle_summarize_index,
109
+ )
110
+
111
+ reg_patch()
112
+
113
+ gr.Chatbot._postprocess_chat_messages = postprocess_chat_messages
114
+ gr.Chatbot.postprocess = postprocess
115
+
116
+ # 设置环境变量和默认应用ID
117
+ os.environ["APPBUILDER_TOKEN"] = "bce-v3/ALTAK-QwuihwYsMjA5jBiIBVfJP/51f962e086efb6f3a2332414360552bae5f3958d"
118
+ APPBUILDER_APPID_DEFAULT = "2ef66c07-b4ac-4fb7-adf9-a76b5c80b2b5"
119
+ APPBUILDER_APPID_CHILD = "c2de7a91-e17e-4d31-becf-b5d014156de7"
120
+ APPBUILDER_APPID_STUDENT = "93ea3085-0e79-40f0-8e3d-f47381af427a"
121
+
122
+ def on_mode_change(mode):
123
+ return f"已选择模式:{mode}"
124
+
125
+ # def generate_image_from_text(prompt, width=1024, height=1024, image_num=1):
126
+ # import appbuilder
127
+ # os.environ["APPBUILDER_TOKEN"] = "bce-v3/ALTAK-QwuihwYsMjA5jBiIBVfJP/51f962e086efb6f3a2332414360552bae5f3958d"
128
+ # text2Image = appbuilder.Text2Image()
129
+ # content_data = {"prompt": prompt, "width": width, "height": height, "image_num": image_num}
130
+ # msg = appbuilder.Message(content_data)
131
+ # out = text2Image.run(msg)
132
+ # return out.content['img_urls']
133
+
134
+ # def generate_image(prompt):
135
+ # img_urls = generate_image_from_text(prompt)
136
+ # return img_urls[0] # 假设只生成一张图片
137
+
138
+ def generate_local_image(prompt):
139
+ # 模拟生成图片并保存到本地路径
140
+ # 在实际应用中,你需要调用你的图像生成函数并保存图像
141
+ # 这里我们假设生成的图像保存在 `generated_image.png`
142
+ local_image_path = "assets/generate_image.png"
143
+
144
+ # 模拟生成图片保存
145
+ # 这里你可以替换为实际的图像生成逻辑
146
+ # from PIL import Image, ImageDraw, ImageFont
147
+ # image = Image.new('RGB', (1024, 1024), color = (73, 109, 137))
148
+ # d = ImageDraw.Draw(image)
149
+ # d.text((10,10), prompt, fill=(255,255,0))
150
+ # image.save(local_image_path)
151
+ time.sleep(6)
152
+ return local_image_path
153
+
154
+ def respond(query, app_selection, chat_history):
155
+ # 根据用户选择设置应用ID
156
+ if app_selection == "成人模式":
157
+ app_id = APPBUILDER_APPID_DEFAULT
158
+ elif app_selection == "儿童模式":
159
+ app_id = APPBUILDER_APPID_CHILD
160
+ elif app_selection == "学生模式":
161
+ app_id = APPBUILDER_APPID_STUDENT
162
+
163
+ # 初始化应用
164
+ # builder = appbuilder.AppBuilderClient(app_id)
165
+
166
+ # 创建会话ID
167
+ # conversation_id = builder.create_conversation()
168
+
169
+ # 执行对话
170
+ # msg = builder.run(conversation_id, query)
171
+
172
+ # chat_history.append((query, msg.content.answer))
173
+ time.sleep(2)
174
+ return "", chat_history
175
+
176
+ # # 创建独立的模式切换模块
177
+ # def mode_switch_ui():
178
+ # with gr.Tab(label=i18n("切换模式")):
179
+ # gr.Markdown(i18n("# 选择运行模式 ⚙️"), elem_id="mode-selection-info")
180
+ # with gr.Accordion(i18n("模式切换"), open=True):
181
+ # mode_selection = gr.Radio(
182
+ # choices=["默认模式", "成人模式", "儿童模式", "学生模式"],
183
+ # label=i18n("运行模式"),
184
+ # value="默认模式"
185
+ # )
186
+ # return mode_selection
187
+
188
+
189
+
190
+ with gr.Blocks(theme=small_and_beautiful_theme) as demo:
191
+ user_name = gr.Textbox("", visible=False)
192
+ # 激活/logout路由
193
+ logout_hidden_btn = gr.LogoutButton(visible=False)
194
+ promptTemplates = gr.State(load_template(get_template_names()[0], mode=2))
195
+ user_question = gr.State("")
196
+ assert type(my_api_key) == str
197
+ user_api_key = gr.State(my_api_key)
198
+ current_model = gr.State()
199
+ # mode_selection = mode_switch_ui()
200
+
201
+ topic = gr.State(i18n("未命名对话历史记录"))
202
+
203
+ with gr.Row(elem_id="chuanhu-header"):
204
+ gr.HTML(get_html("header_title.html").format(
205
+ app_title=TITLE), elem_id="app-title")
206
+ status_display = gr.Markdown(get_geoip, elem_id="status-display")
207
+ with gr.Row(elem_id="float-display"):
208
+ user_info = gr.Markdown(
209
+ value="getting user info...", elem_id="user-info")
210
+
211
+ with gr.Row(equal_height=True, elem_id="chuanhu-body"):
212
+
213
+ with gr.Column(elem_id="menu-area"):
214
+ with gr.Column(elem_id="chuanhu-history"):
215
+ with gr.Box():
216
+ with gr.Row(elem_id="chuanhu-history-header"):
217
+ with gr.Row(elem_id="chuanhu-history-search-row"):
218
+ with gr.Column(min_width=150, scale=2):
219
+ historySearchTextbox = gr.Textbox(show_label=False, container=False, placeholder=i18n(
220
+ "搜索(支持正则)..."), lines=1, elem_id="history-search-tb")
221
+ with gr.Column(min_width=52, scale=1, elem_id="gr-history-header-btns"):
222
+ uploadFileBtn = gr.UploadButton(
223
+ interactive=True, label="", file_types=[".json"], elem_id="gr-history-upload-btn")
224
+ historyRefreshBtn = gr.Button("", elem_id="gr-history-refresh-btn")
225
+
226
+ with gr.Row(elem_id="chuanhu-history-body"):
227
+ with gr.Column(scale=6, elem_id="history-select-wrap"):
228
+ historySelectList = gr.Radio(
229
+ label=i18n("从列表中加载对话"),
230
+ choices=get_history_names(),
231
+ value=get_first_history_name(),
232
+ # multiselect=False,
233
+ container=False,
234
+ elem_id="history-select-dropdown"
235
+ )
236
+ with gr.Row(visible=False):
237
+ with gr.Column(min_width=42, scale=1):
238
+ historyDeleteBtn = gr.Button(
239
+ "🗑️", elem_id="gr-history-delete-btn")
240
+ with gr.Column(min_width=42, scale=1):
241
+ historyDownloadBtn = gr.Button(
242
+ "⏬", elem_id="gr-history-download-btn")
243
+ with gr.Column(min_width=42, scale=1):
244
+ historyMarkdownDownloadBtn = gr.Button(
245
+ "⤵️", elem_id="gr-history-mardown-download-btn")
246
+ with gr.Row(visible=False):
247
+ with gr.Column(scale=6):
248
+ saveFileName = gr.Textbox(
249
+ show_label=True,
250
+ placeholder=i18n("设置文件名: 默认为.json,可选为.md"),
251
+ label=i18n("设置保存文件名"),
252
+ value=i18n("对话历史记录"),
253
+ elem_classes="no-container"
254
+ # container=False,
255
+ )
256
+ with gr.Column(scale=1):
257
+ renameHistoryBtn = gr.Button(
258
+ i18n("💾 保存对话"), elem_id="gr-history-save-btn")
259
+ exportMarkdownBtn = gr.Button(
260
+ i18n("📝 导出为 Markdown"), elem_id="gr-markdown-export-btn")
261
+
262
+ with gr.Column(elem_id="chuanhu-menu-footer"):
263
+ with gr.Row(elem_id="chuanhu-func-nav"):
264
+ gr.HTML(get_html("func_nav.html"))
265
+ # gr.HTML(get_html("footer.html").format(versions=versions_html()), elem_id="footer")
266
+ # gr.Markdown(CHUANHU_DESCRIPTION, elem_id="chuanhu-author")
267
+
268
+ with gr.Column(elem_id="chuanhu-area", scale=5):
269
+ with gr.Column(elem_id="chatbot-area"):
270
+ with gr.Row(elem_id="chatbot-header"):
271
+ # 获取模型的别名列表
272
+ MODEL_ALIASES_LIST = list(MODEL_ALIASES.values())
273
+ DEFAULT_MODEL_ALIAS = MODEL_ALIASES["gpt-3.5-turbo"]
274
+
275
+ model_select_dropdown = gr.Dropdown(
276
+ label=i18n("选择模型"), choices=MODEL_ALIASES_LIST, multiselect=False, value=DEFAULT_MODEL_ALIAS,
277
+ interactive=True,
278
+ show_label=False, container=False, elem_id="model-select-dropdown"
279
+ )
280
+ lora_select_dropdown = gr.Dropdown(
281
+ label=i18n("选择LoRA模型"), choices=[], multiselect=False, interactive=True,
282
+ container=False, visible=False,
283
+ )
284
+ gr.HTML(get_html("chatbot_header_btn.html").format(
285
+ json_label=i18n("历史记录(JSON)"),
286
+ md_label=i18n("导出为 Markdown")
287
+ ), elem_id="chatbot-header-btn-bar")
288
+ with gr.Row():
289
+ chatbot = gr.Chatbot(
290
+ label="ChatGPT",
291
+ elem_id="chuanhu-chatbot",
292
+ latex_delimiters=latex_delimiters_set,
293
+ sanitize_html=False,
294
+ # height=700,
295
+ show_label=False,
296
+ avatar_images=[user_avatar, bot_avatar],
297
+ show_share_button=False,
298
+ )
299
+ with gr.Row(elem_id="chatbot-footer"):
300
+ with gr.Box(elem_id="chatbot-input-box"):
301
+ with gr.Row(elem_id="chatbot-input-row"):
302
+ gr.HTML(get_html("chatbot_more.html").format(
303
+ single_turn_label=i18n("单轮对话"),
304
+ websearch_label=i18n("在线搜索"),
305
+ upload_file_label=i18n("上传文件"),
306
+ uploaded_files_label=i18n("知识库文件"),
307
+ uploaded_files_tip=i18n("在工具箱中管理知识库文件")
308
+ ))
309
+ with gr.Row(elem_id="chatbot-input-tb-row"):
310
+ with gr.Column(min_width=225, scale=12):
311
+ user_input = gr.Textbox(
312
+ elem_id="user-input-tb",
313
+ show_label=False,
314
+ placeholder=i18n("在这里输入"),
315
+ elem_classes="no-container",
316
+ max_lines=5,
317
+ # container=False
318
+ )
319
+ with gr.Column(min_width=42, scale=1, elem_id="chatbot-ctrl-btns"):
320
+ submitBtn = gr.Button(
321
+ value="", variant="primary", elem_id="submit-btn")
322
+ cancelBtn = gr.Button(
323
+ value="", variant="secondary", visible=False, elem_id="cancel-btn")
324
+ # Note: Buttons below are set invisible in UI. But they are used in JS.
325
+ with gr.Row(elem_id="chatbot-buttons", visible=False):
326
+ with gr.Column(min_width=120, scale=1):
327
+ emptyBtn = gr.Button(
328
+ i18n("🧹 新的对话"), elem_id="empty-btn"
329
+ )
330
+ with gr.Column(min_width=120, scale=1):
331
+ retryBtn = gr.Button(
332
+ i18n("🔄 重新生成"), elem_id="gr-retry-btn")
333
+ with gr.Column(min_width=120, scale=1):
334
+ delFirstBtn = gr.Button(i18n("🗑️ 删除最旧对话"))
335
+ with gr.Column(min_width=120, scale=1):
336
+ delLastBtn = gr.Button(
337
+ i18n("🗑️ 删除最新对话"), elem_id="gr-dellast-btn")
338
+ with gr.Row(visible=False) as like_dislike_area:
339
+ with gr.Column(min_width=20, scale=1):
340
+ likeBtn = gr.Button(
341
+ "👍", elem_id="gr-like-btn")
342
+ with gr.Column(min_width=20, scale=1):
343
+ dislikeBtn = gr.Button(
344
+ "👎", elem_id="gr-dislike-btn")
345
+
346
+ with gr.Column(elem_id="toolbox-area", scale=1):
347
+ # For CSS setting, there is an extra box. Don't remove it.
348
+ with gr.Box(elem_id="chuanhu-toolbox"):
349
+ with gr.Row():
350
+ gr.Markdown("## " + i18n("工具箱"))
351
+ gr.HTML(get_html("close_btn.html").format(
352
+ obj="toolbox"), elem_classes="close-btn")
353
+ with gr.Tabs(elem_id="chuanhu-toolbox-tabs"):
354
+ with gr.Tab(label=i18n("主题")):
355
+ with gr.Accordion(label=i18n("模型"), open=not HIDE_MY_KEY, visible=not HIDE_MY_KEY):
356
+ keyTxt = gr.Textbox(
357
+ show_label=True,
358
+ placeholder=f"Your API-key...",
359
+ value=hide_middle_chars(user_api_key.value),
360
+ type="password",
361
+ visible=not HIDE_MY_KEY,
362
+ label="API-Key",
363
+ elem_id="api-key"
364
+ )
365
+ if multi_api_key:
366
+ usageTxt = gr.Markdown(i18n(
367
+ "多账号模式已开启,无需输入key,可直接开始对话"), elem_id="usage-display",
368
+ elem_classes="insert-block", visible=show_api_billing)
369
+ else:
370
+ usageTxt = gr.Markdown(i18n(
371
+ "**发送消息** 或 **提交key** 以显示额度"), elem_id="usage-display",
372
+ elem_classes="insert-block", visible=show_api_billing)
373
+ gr.Markdown("---", elem_classes="hr-line", visible=not HIDE_MY_KEY)
374
+ with gr.Accordion(label="讨论主题展示", open=True):
375
+ systemPromptTxt = gr.Textbox(
376
+ show_label=True,
377
+ placeholder=i18n("在这里输入System Prompt..."),
378
+ label="古诗词",
379
+ value=INITIAL_SYSTEM_PROMPT,
380
+ lines=8
381
+ )
382
+ retain_system_prompt_checkbox = gr.Checkbox(
383
+ label=i18n("新建对话保留当前讨论主题"), value=False, visible=True,
384
+ elem_classes="switch-checkbox")
385
+ with gr.Accordion(label=i18n("加载自定义讨论主题"), open=False):
386
+ with gr.Column():
387
+ with gr.Row():
388
+ with gr.Column(scale=6):
389
+ templateFileSelectDropdown = gr.Dropdown(
390
+ label=i18n("选择Prompt模板集合文件"),
391
+ choices=get_template_names(),
392
+ multiselect=False,
393
+ value=get_template_names()[0],
394
+ container=False,
395
+ )
396
+ with gr.Column(scale=1):
397
+ templateRefreshBtn = gr.Button(
398
+ i18n("🔄 刷新"))
399
+ with gr.Row():
400
+ with gr.Column():
401
+ templateSelectDropdown = gr.Dropdown(
402
+ label=i18n("从Prompt模板中加载"),
403
+ choices=load_template(
404
+ get_template_names()[
405
+ 0], mode=1
406
+ ),
407
+ multiselect=False,
408
+ container=False,
409
+ )
410
+ gr.Markdown("---", elem_classes="hr-line")
411
+ with gr.Accordion(label=i18n("知识库"), open=True, elem_id="gr-kb-accordion", visible=True):
412
+ use_websearch_checkbox = gr.Checkbox(label=i18n(
413
+ "使用在线搜索"), value=False, elem_classes="switch-checkbox", elem_id="gr-websearch-cb",
414
+ visible=False)
415
+ index_files = gr.Files(label=i18n(
416
+ "上传"), type="file",
417
+ file_types=[".pdf", ".docx", ".pptx", ".epub", ".xlsx", ".txt", "text", "image"],
418
+ elem_id="upload-index-file")
419
+ two_column = gr.Checkbox(label=i18n(
420
+ "双栏pdf"), value=False)
421
+ summarize_btn = gr.Button(i18n("总结"), visible=False)
422
+
423
+ with gr.Tab(label=i18n("模式")): # 将标题修改为“模式”
424
+ gr.Markdown(i18n("# 选择运行模式 ⚙️"),
425
+ elem_id="mode-selection-info")
426
+ with gr.Accordion(i18n("模式切换"), open=True):
427
+ mode_selection = gr.Radio(choices=["默认模式", "成人模式", "儿童模式", "学生模式"], label=i18n("运行模式"), value="默认模式")
428
+ submit_button = gr.Button(i18n("确认选择"))
429
+ result = gr.Textbox(label="选择结果")
430
+ submit_button.click(on_mode_change, inputs=mode_selection, outputs=result)
431
+ gr.Markdown("### 智能图片生成")
432
+ # 添加文本输入框用于输入生成图片的文本
433
+ image_output = gr.Image(label="古诗文意象图")
434
+ text_input = gr.Textbox(label="你的描述")
435
+ generate_button = gr.Button("生成图片")
436
+
437
+ # 绑定按钮点击事件
438
+ # generate_button.click(generate_image, inputs=text_input, outputs=image_output)
439
+ # 做一个假本地返回效果
440
+ generate_button.click(generate_local_image, inputs=text_input, outputs=image_output)
441
+
442
+
443
+ # with gr.Tab(label=i18n("参数")):
444
+ # gr.Markdown(i18n("# ⚠️ 务必谨慎更改 ⚠️"),
445
+ # elem_id="advanced-warning")
446
+ # with gr.Accordion(i18n("参数"), open=True):
447
+ temperature_slider = gr.Slider(
448
+ minimum=-0,
449
+ maximum=2.0,
450
+ value=1.0,
451
+ step=0.1,
452
+ interactive=True,
453
+ label="temperature",
454
+ visible=False
455
+ )
456
+ top_p_slider = gr.Slider(
457
+ minimum=-0,
458
+ maximum=1.0,
459
+ value=1.0,
460
+ step=0.05,
461
+ interactive=True,
462
+ label="top-p",
463
+ visible=False
464
+ )
465
+ n_choices_slider = gr.Slider(
466
+ minimum=1,
467
+ maximum=10,
468
+ value=1,
469
+ step=1,
470
+ interactive=True,
471
+ label="n choices",
472
+ visible=False
473
+ )
474
+ stop_sequence_txt = gr.Textbox(
475
+ show_label=True,
476
+ placeholder=i18n("停止符,用英文逗号隔开..."),
477
+ label="stop",
478
+ value="",
479
+ lines=1,
480
+ visible=False
481
+ )
482
+ max_context_length_slider = gr.Slider(
483
+ minimum=1,
484
+ maximum=32768,
485
+ value=2000,
486
+ step=1,
487
+ interactive=True,
488
+ label="max context",
489
+ visible=False
490
+ )
491
+ max_generation_slider = gr.Slider(
492
+ minimum=1,
493
+ maximum=32768,
494
+ value=1000,
495
+ step=1,
496
+ interactive=True,
497
+ label="max generations",
498
+ visible=False
499
+ )
500
+ presence_penalty_slider = gr.Slider(
501
+ minimum=-2.0,
502
+ maximum=2.0,
503
+ value=0.0,
504
+ step=0.01,
505
+ interactive=True,
506
+ label="presence penalty",
507
+ visible=False
508
+ )
509
+ frequency_penalty_slider = gr.Slider(
510
+ minimum=-2.0,
511
+ maximum=2.0,
512
+ value=0.0,
513
+ step=0.01,
514
+ interactive=True,
515
+ label="frequency penalty",
516
+ visible=False
517
+ )
518
+ logit_bias_txt = gr.Textbox(
519
+ show_label=True,
520
+ placeholder=f"word:likelihood",
521
+ label="logit bias",
522
+ value="",
523
+ lines=1,
524
+ visible=False
525
+ )
526
+ user_identifier_txt = gr.Textbox(
527
+ show_label=True,
528
+ placeholder=i18n("用于定位滥用行为"),
529
+ label=i18n("用户标识符"),
530
+ value=user_name.value,
531
+ lines=1,
532
+ visible=False
533
+ )
534
+ with gr.Tab(label=i18n("关于")):
535
+ gr.Markdown("#### " + i18n("PoetryChat Github地址"))
536
+ gr.Markdown(DESCRIPTION)
537
+
538
+ with gr.Row(elem_id="popup-wrapper"):
539
+ with gr.Box(elem_id="chuanhu-popup"):
540
+ with gr.Box(elem_id="chuanhu-setting"):
541
+ with gr.Row():
542
+ gr.Markdown("## " + i18n("设置"))
543
+ gr.HTML(get_html("close_btn.html").format(
544
+ obj="box"), elem_classes="close-btn")
545
+ with gr.Tabs(elem_id="chuanhu-setting-tabs"):
546
+ with gr.Tab(label=i18n("高级")):
547
+ gr.HTML(get_html("appearance_switcher.html").format(
548
+ label=i18n("切换亮暗色主题")), elem_classes="insert-block", visible=False)
549
+ use_streaming_checkbox = gr.Checkbox(
550
+ label=i18n("实时传输回答"), value=True, visible=ENABLE_STREAMING_OPTION,
551
+ elem_classes="switch-checkbox"
552
+ )
553
+ language_select_dropdown = gr.Dropdown(
554
+ label=i18n("选择回复语言(针对搜索&索引功能)"),
555
+ choices=REPLY_LANGUAGES,
556
+ multiselect=False,
557
+ value=REPLY_LANGUAGES[0],
558
+ visible=False,
559
+ )
560
+ name_chat_method = gr.Dropdown(
561
+ label=i18n("对话命名方式"),
562
+ choices=HISTORY_NAME_METHODS,
563
+ multiselect=False,
564
+ interactive=True,
565
+ value=HISTORY_NAME_METHODS[chat_name_method_index],
566
+ )
567
+ single_turn_checkbox = gr.Checkbox(label=i18n(
568
+ "单轮对话"), value=False, elem_classes="switch-checkbox", elem_id="gr-single-session-cb",
569
+ visible=False)
570
+ # checkUpdateBtn = gr.Button(i18n("🔄 检查更新..."), visible=check_update)
571
+ logout_btn = gr.Button(i18n("退出用户"), variant="primary", visible=authflag)
572
+
573
+ with gr.Tab(i18n("网络")):
574
+ gr.Markdown(
575
+ i18n("⚠️ 为保证API-Key安全,请在配置文件`config.json`中修改网络设置"),
576
+ elem_id="netsetting-warning")
577
+ default_btn = gr.Button(i18n("🔙 恢复默认网络设置"))
578
+ # 网络代理
579
+ proxyTxt = gr.Textbox(
580
+ show_label=True,
581
+ placeholder=i18n("未设置代理..."),
582
+ label=i18n("代理地址"),
583
+ value=http_proxy,
584
+ lines=1,
585
+ interactive=False,
586
+ # container=False,
587
+ elem_classes="view-only-textbox no-container",
588
+ )
589
+ # changeProxyBtn = gr.Button(i18n("🔄 设置代理地址"))
590
+
591
+ # 优先展示自定义的api_host
592
+ apihostTxt = gr.Textbox(
593
+ show_label=True,
594
+ placeholder="api.openai.com",
595
+ label="OpenAI API-Host",
596
+ value=api_host or API_HOST,
597
+ lines=1,
598
+ interactive=False,
599
+ # container=False,
600
+ elem_classes="view-only-textbox no-container",
601
+ )
602
+
603
+ with gr.Tab(label=i18n("关于"), elem_id="about-tab"):
604
+ gr.Markdown("# " + i18n("PoetryChat"))
605
+ gr.Markdown(DESCRIPTION, elem_id="description")
606
+
607
+ with gr.Box(elem_id="web-config", visible=False):
608
+ gr.HTML(get_html('web_config.html').format(
609
+ enableCheckUpdate_config=False,
610
+ hideHistoryWhenNotLoggedIn_config=hide_history_when_not_logged_in,
611
+ forView_i18n=i18n("仅供查看"),
612
+ deleteConfirm_i18n_pref=i18n("你真的要删除 "),
613
+ deleteConfirm_i18n_suff=i18n(" 吗?"),
614
+ usingLatest_i18n=i18n("您使用的就是最新版!"),
615
+ updatingMsg_i18n=i18n("正在尝试更新..."),
616
+ updateSuccess_i18n=i18n("更新成功,请重启本程序"),
617
+ updateFailure_i18n=i18n(
618
+ "更新失败,请尝试[手动更新](https://github.com/shibing624/chatgpt-webui/"),
619
+ regenerate_i18n=i18n("重新生成"),
620
+ deleteRound_i18n=i18n("删除这轮问答"),
621
+ renameChat_i18n=i18n("重命名该对话"),
622
+ validFileName_i18n=i18n("请输入有效的文件名,不要包含以下特殊字符:"),
623
+ clearFileHistoryMsg_i18n=i18n("⚠️请先删除知识库中的历史文件,再尝试上传!"),
624
+ dropUploadMsg_i18n=i18n("释放文件以上传"),
625
+ ))
626
+ with gr.Box(elem_id="fake-gradio-components", visible=False):
627
+ changeSingleSessionBtn = gr.Button(
628
+ visible=False, elem_classes="invisible-btn", elem_id="change-single-session-btn")
629
+ changeOnlineSearchBtn = gr.Button(
630
+ visible=False, elem_classes="invisible-btn", elem_id="change-online-search-btn")
631
+ historySelectBtn = gr.Button(
632
+ visible=False, elem_classes="invisible-btn", elem_id="history-select-btn") # Not used
633
+
634
+
635
+ def create_greeting(request: gr.Request):
636
+ if hasattr(request, "username") and request.username:
637
+ logger.info(f"Get User Name: {request.username}")
638
+ user_info, user_name = gr.Markdown.update(
639
+ value=f"User: {request.username}"), request.username
640
+ else:
641
+ user_info, user_name = gr.Markdown.update(
642
+ value=f"", visible=False), ""
643
+ current_model = get_model(
644
+ model_name=MODELS[DEFAULT_MODEL], access_key=my_api_key, user_name=user_name)[0]
645
+ if not hide_history_when_not_logged_in or user_name:
646
+ loaded_stuff = current_model.auto_load()
647
+ else:
648
+ loaded_stuff = [gr.update(), gr.update(), gr.Chatbot.update(label=MODELS[DEFAULT_MODEL]),
649
+ current_model.single_turn, current_model.temperature, current_model.top_p,
650
+ current_model.n_choices, current_model.stop_sequence, current_model.token_upper_limit,
651
+ current_model.max_generation_token, current_model.presence_penalty,
652
+ current_model.frequency_penalty, current_model.logit_bias, current_model.user_identifier]
653
+ return user_info, user_name, current_model, toggle_like_btn_visibility(
654
+ DEFAULT_MODEL), *loaded_stuff, init_history_list(user_name, prepend=current_model.history_file_path[:-5])
655
+
656
+
657
+ demo.load(create_greeting, inputs=None, outputs=[
658
+ user_info, user_name, current_model, like_dislike_area, saveFileName, systemPromptTxt, chatbot,
659
+ single_turn_checkbox, temperature_slider, top_p_slider, n_choices_slider, stop_sequence_txt,
660
+ max_context_length_slider, max_generation_slider, presence_penalty_slider, frequency_penalty_slider,
661
+ logit_bias_txt, user_identifier_txt, historySelectList], api_name="load")
662
+ chatgpt_predict_args = dict(
663
+ fn=predict,
664
+ inputs=[
665
+ current_model,
666
+ user_question,
667
+ chatbot,
668
+ use_streaming_checkbox,
669
+ use_websearch_checkbox,
670
+ index_files,
671
+ language_select_dropdown,
672
+ ],
673
+ outputs=[chatbot, status_display],
674
+ show_progress=True,
675
+ )
676
+
677
+ start_outputing_args = dict(
678
+ fn=start_outputing,
679
+ inputs=[],
680
+ outputs=[submitBtn, cancelBtn],
681
+ show_progress=True,
682
+ )
683
+
684
+ end_outputing_args = dict(
685
+ fn=end_outputing, inputs=[], outputs=[submitBtn, cancelBtn]
686
+ )
687
+
688
+ reset_textbox_args = dict(
689
+ fn=reset_textbox, inputs=[], outputs=[user_input]
690
+ )
691
+
692
+ transfer_input_args = dict(
693
+ fn=transfer_input, inputs=[user_input], outputs=[
694
+ user_question, user_input, submitBtn, cancelBtn], show_progress=True
695
+ )
696
+
697
+ get_usage_args = dict(
698
+ fn=billing_info, inputs=[current_model], outputs=[
699
+ usageTxt], show_progress=False
700
+ )
701
+
702
+ load_history_from_file_args = dict(
703
+ fn=load_chat_history,
704
+ inputs=[current_model, historySelectList],
705
+ outputs=[saveFileName, systemPromptTxt, chatbot, single_turn_checkbox, temperature_slider, top_p_slider,
706
+ n_choices_slider, stop_sequence_txt, max_context_length_slider, max_generation_slider,
707
+ presence_penalty_slider, frequency_penalty_slider, logit_bias_txt, user_identifier_txt],
708
+ )
709
+
710
+ refresh_history_args = dict(
711
+ fn=get_history_list, inputs=[user_name], outputs=[historySelectList]
712
+ )
713
+
714
+ auto_name_chat_history_args = dict(
715
+ fn=auto_name_chat_history,
716
+ inputs=[current_model, name_chat_method, user_question, chatbot, single_turn_checkbox],
717
+ outputs=[historySelectList],
718
+ show_progress=False,
719
+ )
720
+
721
+ # Chatbot
722
+ cancelBtn.click(interrupt, [current_model], [])
723
+
724
+ user_input.submit(
725
+ **transfer_input_args).then(
726
+ **chatgpt_predict_args).then(
727
+ **end_outputing_args).then(
728
+ **auto_name_chat_history_args)
729
+ user_input.submit(**get_usage_args)
730
+
731
+ submitBtn.click(**transfer_input_args).then(
732
+ **chatgpt_predict_args, api_name="predict").then(
733
+ **end_outputing_args).then(
734
+ **auto_name_chat_history_args)
735
+ submitBtn.click(**get_usage_args)
736
+ index_files.upload(handle_file_upload, [current_model, index_files, chatbot, language_select_dropdown], [
737
+ index_files, chatbot, status_display])
738
+ summarize_btn.click(handle_summarize_index, [
739
+ current_model, index_files, chatbot, language_select_dropdown], [chatbot, status_display])
740
+ emptyBtn.click(
741
+ reset,
742
+ inputs=[current_model, retain_system_prompt_checkbox],
743
+ outputs=[chatbot, status_display, historySelectList, systemPromptTxt, single_turn_checkbox, temperature_slider,
744
+ top_p_slider, n_choices_slider, stop_sequence_txt, max_context_length_slider, max_generation_slider,
745
+ presence_penalty_slider, frequency_penalty_slider, logit_bias_txt, user_identifier_txt],
746
+ show_progress=True,
747
+ _js='(a,b)=>{return clearChatbot(a,b);}',
748
+ )
749
+
750
+ retryBtn.click(**start_outputing_args).then(
751
+ retry,
752
+ [
753
+ current_model,
754
+ chatbot,
755
+ use_streaming_checkbox,
756
+ use_websearch_checkbox,
757
+ index_files,
758
+ language_select_dropdown,
759
+ ],
760
+ [chatbot, status_display],
761
+ show_progress=True,
762
+ ).then(**end_outputing_args)
763
+ retryBtn.click(**get_usage_args)
764
+
765
+ delFirstBtn.click(
766
+ delete_first_conversation,
767
+ [current_model],
768
+ [status_display],
769
+ )
770
+
771
+ delLastBtn.click(
772
+ delete_last_conversation,
773
+ [current_model, chatbot],
774
+ [chatbot, status_display],
775
+ show_progress=False
776
+ )
777
+
778
+ likeBtn.click(
779
+ like,
780
+ [current_model],
781
+ [status_display],
782
+ show_progress=False
783
+ )
784
+
785
+ dislikeBtn.click(
786
+ dislike,
787
+ [current_model],
788
+ [status_display],
789
+ show_progress=False
790
+ )
791
+ two_column.change(update_doc_config, [two_column], None)
792
+
793
+ # LLM Models
794
+ keyTxt.change(set_key, [current_model, keyTxt], [
795
+ user_api_key, status_display], api_name="set_key").then(**get_usage_args)
796
+ keyTxt.submit(**get_usage_args)
797
+ single_turn_checkbox.change(
798
+ set_single_turn, [current_model, single_turn_checkbox], None, show_progress=False)
799
+ model_select_dropdown.change(get_model,
800
+ [model_select_dropdown, lora_select_dropdown, user_api_key, temperature_slider,
801
+ top_p_slider, systemPromptTxt, user_name, current_model], [
802
+ current_model, status_display, chatbot, lora_select_dropdown, user_api_key,
803
+ keyTxt], show_progress=True, api_name="get_model")
804
+ model_select_dropdown.change(toggle_like_btn_visibility, [model_select_dropdown], [
805
+ like_dislike_area], show_progress=False)
806
+ lora_select_dropdown.change(get_model,
807
+ [model_select_dropdown, lora_select_dropdown, user_api_key, temperature_slider,
808
+ top_p_slider, systemPromptTxt, user_name, current_model],
809
+ [current_model, status_display, chatbot], show_progress=True)
810
+
811
+ # Template
812
+ systemPromptTxt.change(set_system_prompt, [
813
+ current_model, systemPromptTxt], None)
814
+ templateRefreshBtn.click(get_template_dropdown, None, [
815
+ templateFileSelectDropdown])
816
+ templateFileSelectDropdown.input(
817
+ load_template,
818
+ [templateFileSelectDropdown],
819
+ [promptTemplates, templateSelectDropdown],
820
+ show_progress=True,
821
+ )
822
+ templateSelectDropdown.change(
823
+ get_template_content,
824
+ [promptTemplates, templateSelectDropdown, systemPromptTxt],
825
+ [systemPromptTxt],
826
+ show_progress=True,
827
+ )
828
+
829
+ # S&L
830
+ renameHistoryBtn.click(
831
+ rename_chat_history,
832
+ [current_model, saveFileName, chatbot],
833
+ [historySelectList],
834
+ show_progress=True,
835
+ _js='(a,b,c,d)=>{return saveChatHistory(a,b,c,d);}'
836
+ )
837
+ exportMarkdownBtn.click(
838
+ export_markdown,
839
+ [current_model, saveFileName, chatbot],
840
+ [],
841
+ show_progress=True,
842
+ )
843
+ historyRefreshBtn.click(**refresh_history_args)
844
+ historyDeleteBtn.click(delete_chat_history, [current_model, historySelectList],
845
+ [status_display, historySelectList, chatbot],
846
+ _js='(a,b,c)=>{return showConfirmationDialog(a, b, c);}').then(
847
+ reset,
848
+ inputs=[current_model, retain_system_prompt_checkbox],
849
+ outputs=[chatbot, status_display, historySelectList, systemPromptTxt],
850
+ show_progress=True,
851
+ _js='(a,b)=>{return clearChatbot(a,b);}',
852
+ )
853
+ historySelectList.input(**load_history_from_file_args)
854
+ uploadFileBtn.upload(upload_chat_history, [current_model, uploadFileBtn], [
855
+ saveFileName, systemPromptTxt, chatbot, single_turn_checkbox, temperature_slider, top_p_slider,
856
+ n_choices_slider, stop_sequence_txt, max_context_length_slider, max_generation_slider, presence_penalty_slider,
857
+ frequency_penalty_slider, logit_bias_txt, user_identifier_txt]).then(**refresh_history_args)
858
+ historyDownloadBtn.click(None, [
859
+ user_name, historySelectList], None, _js='(a,b)=>{return downloadHistory(a,b,".json");}')
860
+ historyMarkdownDownloadBtn.click(None, [
861
+ user_name, historySelectList], None, _js='(a,b)=>{return downloadHistory(a,b,".md");}')
862
+ historySearchTextbox.input(
863
+ filter_history,
864
+ [user_name, historySearchTextbox],
865
+ [historySelectList]
866
+ )
867
+
868
+ # Advanced
869
+ temperature_slider.input(
870
+ set_temperature, [current_model, temperature_slider], None, show_progress=False)
871
+ top_p_slider.input(set_top_p, [current_model, top_p_slider], None, show_progress=False)
872
+ n_choices_slider.input(
873
+ set_n_choices, [current_model, n_choices_slider], None, show_progress=False)
874
+ stop_sequence_txt.input(
875
+ set_stop_sequence, [current_model, stop_sequence_txt], None, show_progress=False)
876
+ max_context_length_slider.input(
877
+ set_token_upper_limit, [current_model, max_context_length_slider], None, show_progress=False)
878
+ max_generation_slider.input(
879
+ set_max_tokens, [current_model, max_generation_slider], None, show_progress=False)
880
+ presence_penalty_slider.input(
881
+ set_presence_penalty, [current_model, presence_penalty_slider], None, show_progress=False)
882
+ frequency_penalty_slider.input(
883
+ set_frequency_penalty, [current_model, frequency_penalty_slider], None, show_progress=False)
884
+ logit_bias_txt.input(
885
+ set_logit_bias, [current_model, logit_bias_txt], None, show_progress=False)
886
+ user_identifier_txt.input(set_user_identifier, [
887
+ current_model, user_identifier_txt], None, show_progress=False)
888
+
889
+ default_btn.click(
890
+ reset_default, [], [apihostTxt, proxyTxt, status_display], show_progress=True
891
+ )
892
+
893
+ # Invisible elements
894
+ changeSingleSessionBtn.click(
895
+ fn=lambda value: gr.Checkbox.update(value=value),
896
+ inputs=[single_turn_checkbox],
897
+ outputs=[single_turn_checkbox],
898
+ _js='(a)=>{return bgChangeSingleSession(a);}'
899
+ )
900
+ changeOnlineSearchBtn.click(
901
+ fn=lambda value: gr.Checkbox.update(value=value),
902
+ inputs=[use_websearch_checkbox],
903
+ outputs=[use_websearch_checkbox],
904
+ _js='(a)=>{return bgChangeOnlineSearch(a);}'
905
+ )
906
+ historySelectBtn.click( # This is an experimental feature... Not actually used.
907
+ fn=load_chat_history,
908
+ inputs=[current_model, historySelectList],
909
+ outputs=[saveFileName, systemPromptTxt, chatbot, single_turn_checkbox, temperature_slider, top_p_slider,
910
+ n_choices_slider, stop_sequence_txt, max_context_length_slider, max_generation_slider,
911
+ presence_penalty_slider, frequency_penalty_slider, logit_bias_txt, user_identifier_txt],
912
+ _js='(a,b)=>{return bgSelectHistory(a,b);}'
913
+ )
914
+ logout_btn.click(
915
+ fn=None,
916
+ inputs=[],
917
+ outputs=[],
918
+ _js='self.location="/logout"'
919
+ )
920
+
921
+ demo.title = TITLE
922
+
923
+ if __name__ == "__main__":
924
+ reload_javascript()
925
+ setup_wizard()
926
+ demo.queue(concurrency_count=CONCURRENT_COUNT).launch(
927
+ allowed_paths=[HISTORY_DIR, assets_path],
928
+ server_name=server_name,
929
+ server_port=server_port,
930
+ share=share,
931
+ blocked_paths=[config_file],
932
+ auth=auth_from_conf if authflag else None,
933
+ favicon_path=favicon_path,
934
+ inbrowser=autobrowser and not dockerflag,
935
+ )
assets/chatbot.png ADDED
assets/favicon.ico ADDED
assets/generate_image.png ADDED

Git LFS Details

  • SHA256: 0252771bc3b39b07a0a0d76ac6ed307bb3c702c001bff0df499d1c0f2c98a4ab
  • Pointer size: 132 Bytes
  • Size of remote file: 1.59 MB
assets/html/appearance_switcher.html ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ <div class="switch-checkbox" id="apSwitch">
2
+ <label class="apSwitch">
3
+ <input type="checkbox" id="apSwitch-checkbox" data-testid="checkbox" />
4
+ <span class="apSwitch-span">{label}</span>
5
+ </label>
6
+ </div>
assets/html/billing_info.html ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ <b>{label}</b>
2
+ <div class="progress-bar">
3
+ <div class="progress" style="width: {usage_percent}%;">
4
+ <span class="progress-text">{usage_percent}%</span>
5
+ </div>
6
+ </div>
7
+ <div style="display: flex; justify-content: space-between;">
8
+ <span>${rounded_usage}</span><span>${usage_limit}</span>
9
+ </div>
assets/html/chatbot_header_btn.html ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div id="header-btn-groups">
2
+ <div class="btn-bar-group" style="margin-left: -12px;">
3
+ <span class="show-on-gpt">
4
+ <button id="chuanhu-training-btn" onclick="openTrainingBox()" class="chuanhu-ui-btn" style="visibility: hidden">
5
+ <!-- <svg width="24px" height="24px" viewBox="0 0 45.297 28.8394" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
6
+ <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
7
+ <g fill="currentColor" fill-rule="nonzero">
8
+ <path d="M0,23.4288 C0,27.0248 1.8307,28.8394 5.45907,28.8394 L39.8379,28.8394 C43.4663,28.8394 45.297,27.0248 45.297,23.4288 L45.297,5.41055 C45.297,1.81453 43.4663,0 39.8379,0 L9.91219,0 C6.82641,0 5.13938,1.74422 4.24945,4.43907 L0.618281,15.4643 C0.1875,16.7405 0,17.8041 0,19.4644 L0,23.4288 Z M17.6306,14.2226 L17.6306,8.14923 C17.6306,7.09126 18.2522,6.46969 19.3263,6.46969 L36.3459,6.46969 C37.4201,6.46969 38.0344,7.09126 38.0344,8.14923 L38.0344,14.2226 C38.0344,15.2498 37.4201,15.8714 36.3459,15.8714 L19.3263,15.8714 C18.2522,15.8714 17.6306,15.2498 17.6306,14.2226 Z M6.14415,15.8714 C5.12415,15.8714 4.63102,15.0713 5.01259,13.8724 L7.02539,7.75805 C7.27758,6.97805 7.66875,6.46969 8.95946,6.46969 L11.2486,6.46969 C12.3066,6.46969 12.9443,7.09126 12.9443,8.14923 L12.9443,14.2226 C12.9443,15.2498 12.3066,15.8714 11.2486,15.8714 L6.14415,15.8714 Z" fill-opacity="0.85"></path>
9
+ </g>
10
+ </g>
11
+ </svg> -->
12
+ <svg width="24px" height="24px" viewBox="0 0 21.4889 22.038" version="1.1" xmlns="http://www.w3.org/2000/svg">
13
+ <g transform-origin="center" transform="scale(0.85)">
14
+ <path d="M1.1492 20.81C2.69607 22.3569 4.95779 22.3803 6.51638 20.5991C8.18045 18.7006 10.0672 15.1381 12.6922 12.5131C14.6961 10.5092 17.1101 12.3959 19.8875 9.75923C21.0711 8.63423 21.7039 7.02876 21.4226 5.88032L17.8015 6.87642C17.2976 7.00532 16.8992 6.66548 16.7234 6.05611L16.4539 5.14204C16.2781 4.53267 16.5125 4.04048 17.0164 3.89986L20.6258 2.9272C20.532 2.57564 20.1922 2.09517 19.782 1.67329C17.6258-0.553269 14.0281-0.494675 11.9539 1.47407C8.86013 4.40376 11.1687 7.49751 9.23513 9.43111C6.80935 11.8569 3.24685 13.7788 1.34842 15.4428C-0.432835 17.0014-0.397679 19.2631 1.1492 20.81ZM2.13357 19.8256C1.17263 18.8413 1.17263 17.3881 2.30935 16.4038C4.19607 14.7514 8.00467 12.6303 10.2195 10.4155C12.5867 8.04829 10.0086 5.16548 12.9617 2.45845C14.4617 1.06392 17.1804 1.00532 18.8914 2.59907L19.2429 1.9897L16.7351 2.64595C15.3523 3.00923 14.7429 4.07564 15.1531 5.51704L15.4109 6.40767C15.8797 8.01314 16.8054 8.45845 18.0594 8.11861L20.6609 7.41548L20.0398 7.09907C19.8406 7.75532 19.4773 8.3647 18.9617 8.86861C16.7351 11.0483 14.075 9.17329 11.7078 11.5288C9.30545 13.9194 7.20779 17.7514 5.55545 19.6499C4.54763 20.81 3.09451 20.81 2.13357 19.8256ZM13.0086 9.09126L15.0125 8.5522C15.1883 8.50532 15.2937 8.31782 15.2469 8.11861C15.2 7.94282 15.0242 7.82564 14.825 7.88423L12.8328 8.42329C12.657 8.47017 12.5515 8.65767 12.5867 8.84517C12.6219 9.04439 12.8211 9.13814 13.0086 9.09126ZM12.7625 8.08345L14.7429 7.55611C14.9304 7.50923 15.0359 7.32173 14.989 7.12251C14.9422 6.93501 14.7429 6.82954 14.5672 6.87642L12.575 7.41548C12.3875 7.46236 12.282 7.66157 12.3289 7.82564C12.3875 8.03657 12.5633 8.14204 12.7625 8.08345ZM12.5164 7.07564L14.4969 6.54829C14.6844 6.50142 14.7898 6.31392 14.7429 6.1147C14.6961 5.9272 14.4969 5.82173 14.3211 5.86861L12.3289 6.40767C12.1414 6.45454 12.0359 6.65376 12.0828 6.81782C12.1414 7.02876 12.3172 7.13423 12.5164 7.07564ZM16.5242 10.5444L17.4265 10.3452L16.3133 6.22017L15.4109 6.40767ZM3.80935 19.3217C4.44217 19.3217 4.96951 18.8061 4.96951 18.1616C4.96951 17.5288 4.44217 17.0014 3.80935 17.0014C3.16482 17.0014 2.63748 17.5288 2.63748 18.1616C2.63748 18.8061 3.16482 19.3217 3.80935 19.3217Z" fill="currentColor" fill-opacity="0.85"/>
15
+ </g>
16
+ </svg>
17
+ </button>
18
+ </span>
19
+ </div>
20
+
21
+ <div class="btn-bar-group">
22
+ <button id="new-chat-btn" onclick="newChatClick()" class="chuanhu-ui-btn">
23
+ <!-- <svg width="24px" height="24px" viewBox="0 0 41.3058 37.9805" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
24
+ <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
25
+ <g fill-rule="nonzero">
26
+ <path d="M7.85906,37.9732 C10.2516,37.9732 15.1013,35.6613 18.7802,33.1193 C31.3151,33.6708 41.3058,26.4138 41.3058,16.6013 C41.3058,7.42008 32.1359,0 20.6529,0 C9.17883,0 0,7.42008 0,16.6013 C0,22.5973 3.85266,27.9152 9.65789,30.6202 C8.82141,32.2172 7.33664,34.2469 6.52195,35.292 C5.57226,36.5116 6.08883,37.9732 7.85906,37.9732 Z M9.48751,35.2875 C9.34688,35.336 9.30727,35.2334 9.40829,35.1089 C10.392,33.8965 11.858,32.0149 12.5182,30.7552 C12.9734,29.9184 12.8473,29.1593 11.8221,28.6863 C6.06376,26.0217 2.68407,21.6335 2.68407,16.6013 C2.68407,8.91657 10.6542,2.66954 20.6529,2.66954 C30.6677,2.66954 38.6217,8.91657 38.6217,16.6013 C38.6217,24.2698 30.6677,30.5241 20.6529,30.5241 C20.1642,30.5241 19.5356,30.495 18.747,30.4659 C18.0687,30.4587 17.5069,30.66 16.9006,31.1402 C14.4764,32.7921 11.1403,34.7288 9.48751,35.2875 Z" fill-opacity="0.85" fill="currentColor"></path>
27
+ <path d="M12.233,16.7468 C12.233,17.5238 12.7908,18.0816 13.6235,18.0816 L19.2947,18.0816 L19.2947,23.7778 C19.2947,24.5855 19.8525,25.1522 20.6295,25.1522 C21.4371,25.1522 22.0111,24.5927 22.0111,23.7778 L22.0111,18.0816 L27.7146,18.0816 C28.515,18.0816 29.0817,17.5238 29.0817,16.7468 C29.0817,15.9391 28.5223,15.3652 27.7146,15.3652 L22.0111,15.3652 L22.0111,9.67782 C22.0111,8.85399 21.4371,8.28727 20.6295,8.28727 C19.8525,8.28727 19.2947,8.86125 19.2947,9.67782 L19.2947,15.3652 L13.6235,15.3652 C12.7835,15.3652 12.233,15.9391 12.233,16.7468 Z" fill-opacity="0.85" fill="currentColor"></path>
28
+ </g>
29
+ </g>
30
+ </svg> -->
31
+ <svg width="24px" height="24px" viewBox="0 0 15.0076 15.0274" version="1.1" xmlns="http://www.w3.org/2000/svg">
32
+ <g transform-origin="center" transform="scale(0.75)">
33
+ <path d="M0 7.50785C0 7.89996 0.328243 8.23184 0.723986 8.23184L6.78387 8.23184L6.78387 14.2917C6.78387 14.6794 7.11574 15.0157 7.50785 15.0157C7.89996 15.0157 8.22375 14.6794 8.22375 14.2917L8.22375 8.23184L14.2917 8.23184C14.6794 8.23184 15.0076 7.89996 15.0076 7.50785C15.0076 7.11574 14.6794 6.78387 14.2917 6.78387L8.22375 6.78387L8.22375 0.723986C8.22375 0.336329 7.89996 0 7.50785 0C7.11574 0 6.78387 0.336329 6.78387 0.723986L6.78387 6.78387L0.723986 6.78387C0.328243 6.78387 0 7.11574 0 7.50785Z" fill="currentColor" fill-opacity="0.85"/>
34
+ </g>
35
+ </svg>
36
+ </button>
37
+
38
+ <div class="nav-item-dropdown">
39
+ <button id="export-chat-btn" onclick="" class="chuanhu-ui-btn dropdown-trigger">
40
+ <svg width="24px" height="24px" viewBox="0 0 16.4883 25.0898" version="1.1" xmlns="http://www.w3.org/2000/svg">
41
+ <g stroke="none" fill="currentColor" fill-rule="nonzero" transform-origin="center" transform="scale(1.1)">
42
+ <path d="M13.5,7.39453 C15.5039,7.39453 16.4883,8.37891 16.4883,10.3477 L16.4883,19.3594 C16.4883,21.3281 15.5039,22.3125 13.5,22.3125 L2.98828,22.3125 C0.996094,22.3125 0,21.3281 0,19.3594 L0,10.3477 C0,8.37891 0.996094,7.39453 2.98828,7.39453 L5.554,7.394 L5.554,9.093 L3.01172,9.09375 C2.21760235,9.09375 1.74528291,9.49859318 1.69246372,10.2789831 L1.6875,10.4297 L1.6875,19.2773 C1.6875,20.168 2.16797,20.6133 3.01172,20.6133 L13.4766,20.6133 C14.3086,20.6133 14.8008,20.168 14.8008,19.2773 L14.8008,10.4297 C14.8008,9.55078 14.3086,9.09375 13.4766,9.09375 L10.921,9.093 L10.921,7.394 Z" fill-opacity="0.85"></path>
43
+ <path d="M8.23828,15.0469 C8.69531,15.0469 9.08203,14.6719 9.08203,14.2266 L9.08203,5.08594 L9.01172,3.67969 L9.50391,4.21875 L10.793,5.61328 C10.9453,5.77734 11.1562,5.85938 11.3555,5.85938 C11.8008,5.85938 12.1289,5.55469 12.1289,5.13281 C12.1289,4.89844 12.0352,4.73438 11.8711,4.58203 L8.84766,1.6875 C8.63672,1.47656 8.46094,1.40625 8.23828,1.40625 C8.02734,1.40625 7.85156,1.47656 7.62891,1.6875 L4.60547,4.58203 C4.45312,4.73438 4.35938,4.89844 4.35938,5.13281 C4.35938,5.55469 4.67578,5.85938 5.12109,5.85938 C5.32031,5.85938 5.54297,5.77734 5.69531,5.61328 L6.98438,4.21875 L7.47656,3.67969 L7.40625,5.08594 L7.40625,14.2266 C7.40625,14.6719 7.79297,15.0469 8.23828,15.0469 Z" fill-opacity="0.85"></path>
44
+ </g>
45
+ </svg>
46
+ </button>
47
+ <div class="dropdown-menu">
48
+ <div class="dropdown-menu-item">
49
+ <button onclick="jsonDownloadClick()">{json_label}</button>
50
+ </div>
51
+ <div class="dropdown-menu-item">
52
+ <button onclick="mdDownloadClick()">{md_label}</button>
53
+ </div>
54
+ </div>
55
+ </div>
56
+
57
+ <button id="open-toolbox-btn" onclick="toolboxClick()" class="chuanhu-ui-btn">
58
+ <!-- <svg width="24px" height="24px" viewBox="0 0 33.5163 33.5705" version="1.1" xmlns="http://www.w3.org/2000/svg">
59
+ <g stroke="none" fill="currentColor" fill-rule="nonzero" transform-origin="center" transform="scale(0.8)">
60
+ <path d="M5.58422,33.5705 L27.9321,33.5705 C31.6493,33.5705 33.5163,31.6889 33.5163,28.0348 L33.5163,5.57367 C33.5163,1.91953 31.6493,0.0379686 27.9321,0.0379686 L5.58422,0.0379686 C1.8832,0.0379686 0,1.905 0,5.57367 L0,28.0348 C0,31.7034 1.8832,33.5705 5.58422,33.5705 Z M5.6311,30.9495 C3.67477,30.9495 2.60485,29.928 2.60485,27.907 L2.60485,5.70141 C2.60485,3.69657 3.67477,2.65899 5.6311,2.65899 L27.8852,2.65899 C29.8125,2.65899 30.9115,3.69657 30.9115,5.70141 L30.9115,27.907 C30.9115,29.928 29.8125,30.9495 27.8852,30.9495 L5.6311,30.9495 Z" fill-opacity="0.85"></path>
61
+ <path d="M7.69266,12.7402 L17.3438,12.7402 L17.3438,10.572 L7.69266,10.572 C7.07907,10.572 6.60047,11.0505 6.60047,11.648 C6.60047,12.2616 7.07907,12.7402 7.69266,12.7402 Z M20.021,15.3488 C22.0545,15.3488 23.704,13.683 23.704,11.6334 C23.704,9.6 22.0545,7.9343 20.021,7.9343 C17.9876,7.9343 16.3219,9.6 16.3219,11.6334 C16.3219,13.683 17.9876,15.3488 20.021,15.3488 Z M20.021,13.5841 C18.922,13.5841 18.0865,12.7179 18.0865,11.6262 C18.0865,10.5345 18.922,9.69165 20.021,9.69165 C21.0966,9.69165 21.9483,10.5345 21.9483,11.6262 C21.9483,12.7179 21.0966,13.5841 20.021,13.5841 Z M22.5487,12.7402 L25.8884,12.7402 C26.4534,12.7402 26.932,12.2616 26.932,11.648 C26.932,11.0505 26.4534,10.572 25.8884,10.572 L22.5487,10.572 L22.5487,12.7402 Z M25.8237,20.5158 L16.1726,20.5158 L16.1726,22.6913 L25.8237,22.6913 C26.4534,22.6913 26.932,22.2054 26.932,21.608 C26.932,21.0016 26.4534,20.5158 25.8237,20.5158 Z M13.4953,17.9145 C11.4781,17.9145 9.81962,19.5802 9.81962,21.6225 C9.81962,23.6559 11.4781,25.3216 13.4953,25.3216 C15.5288,25.3216 17.1945,23.6559 17.1945,21.6225 C17.1945,19.5802 15.5288,17.9145 13.4953,17.9145 Z M13.4953,19.6791 C14.5943,19.6791 15.4298,20.538 15.4298,21.6298 C15.4298,22.7288 14.5943,23.5643 13.4953,23.5643 C12.4198,23.5643 11.5842,22.7288 11.5842,21.6298 C11.5842,20.538 12.4198,19.6791 13.4953,19.6791 Z M10.9838,20.5158 L7.64415,20.5158 C7.07907,20.5158 6.60047,21.0016 6.60047,21.608 C6.60047,22.2054 7.07907,22.6913 7.64415,22.6913 L10.9838,22.6913 L10.9838,20.5158 Z" fill-opacity="0.85" transform="translate(16.7662, 16.628) scale(-1, 1) translate(-16.7662, -16.628)"></path>
62
+ </g>
63
+ </svg> -->
64
+ <svg width="24px" height="24px" viewBox="0 0 17.0977 17.0977" viewBox="0 0 17.0742 17.0977" version="1.1" xmlns="http://www.w3.org/2000/svg">
65
+ <g transform-origin="center" transform="scale(0.82)" fill="currentColor" fill-rule="nonzero" fill-opacity="0.82">
66
+ <path d="M2.98828,17.0977 L14.0859,17.0977 C16.0898,17.0977 17.0742,16.1133 17.0742,14.1445 L17.0742,2.96484 C17.0742,0.996094 16.0898,0.0117188 14.0859,0.0117188 L2.98828,0.0117188 C0.996094,0.0117188 0,0.996094 0,2.96484 L0,14.1445 C0,16.1133 0.996094,17.0977 2.98828,17.0977 Z M3.01172,15.3984 C2.16797,15.3984 1.6875,14.9531 1.6875,14.0625 L1.6875,3.04688 C1.6875,2.16797 2.16797,1.71094 3.01172,1.71094 L14.0625,1.71094 C14.9062,1.71094 15.3867,2.16797 15.3867,3.04688 L15.3867,14.0625 C15.3867,14.9531 14.9062,15.3984 14.0625,15.3984 L3.01172,15.3984 Z"></path>
67
+ <path d="M4.34766,6.66797 L8.67188,6.66797 L8.67188,5.29688 L4.34766,5.29688 C3.96094,5.29688 3.65625,5.60156 3.65625,5.97656 C3.65625,6.36328 3.96094,6.66797 4.34766,6.66797 Z M9.89062,7.86328 C10.9219,7.86328 11.7539,7.01953 11.7539,5.97656 C11.7539,4.94531 10.9219,4.10156 9.89062,4.10156 C8.85938,4.10156 8.01562,4.94531 8.01562,5.97656 C8.01562,7.01953 8.85938,7.86328 9.89062,7.86328 Z M9.89062,6.83203 C9.41016,6.83203 9.04688,6.45703 9.04688,5.97656 C9.04688,5.49609 9.41016,5.13281 9.89062,5.13281 C10.3594,5.13281 10.7344,5.49609 10.7344,5.97656 C10.7344,6.45703 10.3594,6.83203 9.89062,6.83203 Z M11.0273,6.66797 L12.7734,6.66797 C13.125,6.66797 13.4297,6.36328 13.4297,5.97656 C13.4297,5.60156 13.125,5.29688 12.7734,5.29688 L11.0273,5.29688 L11.0273,6.66797 Z M12.7266,10.207 L8.40234,10.207 L8.40234,11.5781 L12.7266,11.5781 C13.125,11.5781 13.4297,11.2734 13.4297,10.8984 C13.4297,10.5117 13.125,10.207 12.7266,10.207 Z M7.18359,9.01172 C6.16406,9.01172 5.32031,9.85547 5.32031,10.8984 C5.32031,11.9297 6.16406,12.7734 7.18359,12.7734 C8.21484,12.7734 9.05859,11.9297 9.05859,10.8984 C9.05859,9.85547 8.21484,9.01172 7.18359,9.01172 Z M7.18359,10.043 C7.66406,10.043 8.02734,10.418 8.02734,10.8984 C8.02734,11.3789 7.66406,11.7422 7.18359,11.7422 C6.71484,11.7422 6.35156,11.3789 6.35156,10.8984 C6.35156,10.418 6.71484,10.043 7.18359,10.043 Z M6.05859,10.207 L4.3125,10.207 C3.96094,10.207 3.65625,10.5117 3.65625,10.8984 C3.65625,11.2734 3.96094,11.5781 4.3125,11.5781 L6.05859,11.5781 L6.05859,10.207 Z" transform="translate(8.543, 8.4375) scale(-1, 1) translate(-8.543, -8.4375)"></path>
68
+ </g>
69
+ </svg>
70
+ </button>
71
+ </div>
72
+ </div>
assets/html/chatbot_more.html ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div>
2
+ <div id="chatbot-input-more-area">
3
+ <span class="chatbot-input-more-label-group">
4
+ <div class="switch-checkbox">
5
+ <label>
6
+ <input type="checkbox" name="single-session-cb" data-testid="checkbox" style="transform: scale(0.8); margin: 0;">
7
+ <span class="chatbot-input-more-span">{single_turn_label}</span>
8
+ </label>
9
+ </div>
10
+
11
+ <div class="switch-checkbox">
12
+ <label>
13
+ <input type="checkbox" name="online-search-cb" data-testid="checkbox" style="transform: scale(0.8); margin: 0;">
14
+ <span class="chatbot-input-more-span">{websearch_label}</span>
15
+ </label>
16
+ </div>
17
+ </span>
18
+
19
+ <span class="chatbot-input-more-label-group">
20
+ <div class="chatbot-input-more-btn last-btn">
21
+ <label class="may-disable-label">
22
+ <div id="uploaded-files-btn" onclick="showKnowledgeBase();">
23
+ <span class="chatbot-input-more-span tooltip-toggle" aria-label="{uploaded_files_tip}">{uploaded_files_label}</span>
24
+ <span class="chatbot-input-more-icon" id="uploaded-files-count"></span>
25
+ </div>
26
+ <button id="upload-files-btn">
27
+ <span class="chatbot-input-more-span">{upload_file_label}</span>
28
+ <span class="chatbot-input-more-icon">
29
+ <svg width="18px" height="22px" viewBox="0 0 17.6625708 22" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
30
+ <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
31
+ <g fill="currentColor" fill-rule="nonzero">
32
+ <path d="M10.6020285,2.51882667 C11.4362625,2.51882667 11.8921676,2.64807396 12.4438001,3.21682942 L16.9677143,7.80362991 C17.5473088,8.39718377 17.6625708,8.80801259 17.6625708,9.74013504 L17.6625708,17.0701838 C17.6625708,18.6697194 16.8588053,19.4835978 15.2701606,19.4835978 L9.30367012,19.4838726 C9.50801444,19.132339 9.67081559,18.754537 9.78494219,18.3575337 L15.2149282,18.3578162 C16.0814028,18.3578162 16.5329428,17.8954285 16.5329428,17.0499579 L16.5329428,9.75491554 L11.9107944,9.75491554 C10.9798389,9.75491554 10.4963609,9.29343541 10.4963609,8.34048196 L10.4963609,3.64458667 L6.87556994,3.64458667 C6.00213732,3.64458667 5.55375219,4.12267974 5.55375219,4.95246234 L5.55332282,12.0499339 C5.36755588,12.0285691 5.17882362,12.0175857 4.9877281,12.0175857 C4.79846417,12.0175857 4.61149369,12.028399 4.42740668,12.0494356 L4.42797059,4.93219317 C4.42797059,3.3327051 5.23415624,2.51882667 6.81337946,2.51882667 Z M11.552216,3.86783276 L11.552216,8.21151991 C11.552216,8.55164434 11.6926308,8.69205911 12.0359101,8.69205911 L16.3097226,8.69205911 L11.552216,3.86783276 Z" fill-opacity="0.85"></path>
33
+ <path d="M4.9877281,13.0174305 C7.17286548,13.0174305 8.97241326,14.8169783 8.97241326,17.0052706 C8.97241326,19.1904512 7.15190483,20.9970003 4.9877281,20.9970003 C2.80254317,20.9970003 0.999853452,19.1974525 0.999853452,17.0052706 C0.999853452,14.82009 2.80254317,13.0174305 4.9877281,13.0174305 Z M4.99784107,14.437007 C4.88115289,14.437007 4.7753124,14.4852382 4.64150995,14.6120393 L2.60482154,16.530609 C2.48641329,16.6350666 2.4357663,16.7447535 2.42877798,16.8911323 C2.414797,17.1440431 2.62022006,17.325342 2.87314384,17.325342 C3.00310422,17.3323433 3.12991834,17.2638862 3.21236934,17.1782716 L3.90166369,16.4757224 L4.5558954,15.8144894 L4.51466558,16.8528413 L4.51466558,19.0792085 C4.51466558,19.332854 4.73408257,19.5421148 4.99784107,19.5421148 C5.25844467,19.5421148 5.47470676,19.332854 5.47470676,19.0792085 L5.47470676,16.8528413 L5.44363313,15.8144894 L6.08075058,16.4757224 L6.78018815,17.1782716 C6.86960587,17.2638862 6.98560256,17.3183839 7.11555862,17.325342 C7.36531454,17.3393445 7.56061597,17.1440431 7.56061597,16.8911323 C7.56061597,16.7479084 7.50996466,16.6350666 7.39159099,16.530609 L5.34090431,14.6120393 C5.22352465,14.498506 5.12779713,14.437007 4.99784107,14.437007 Z" fill-opacity="0.85"></path>
34
+ </g>
35
+ </g>
36
+ </svg>
37
+ </span>
38
+ </button>
39
+ </label>
40
+ </div>
41
+ </span>
42
+ </div>
43
+
44
+ <!-- get more button -->
45
+ <div id="chatbot-input-more-btn-div">
46
+ <button class="chatbot-input-more-btn" onclick="chatMoreBtnClick()">
47
+ <!-- <svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg"
48
+ xmlns:xlink="http://www.w3.org/1999/xlink">
49
+ <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
50
+ <g fill="currentColor" fill-rule="nonzero">
51
+ <path
52
+ d="M15.9930223,31.97976 C24.7467023,31.97976 32,24.7418401 32,15.98988 C32,7.23796297 24.7327468,0 15.9790668,0 C7.23313125,0 0,7.23796297 0,15.98988 C0,24.7418401 7.24706085,31.97976 15.9930223,31.97976 Z"
53
+ fill-opacity="0.1" class="sm-round-bg"></path>
54
+ <path
55
+ d="M8.41162523,16.0038327 C8.41162523,15.2803594 8.92769229,14.7720332 9.65130778,14.7720332 L14.7951802,14.7720332 L14.7951802,9.62925761 C14.7951802,8.91198549 15.2756953,8.40371964 15.9728644,8.40371964 C16.6964799,8.40371964 17.2048198,8.90578429 17.2048198,9.62925761 L17.2048198,14.7720332 L22.3626477,14.7720332 C23.0723077,14.7720332 23.5884006,15.2803594 23.5884006,16.0038327 C23.5884006,16.7008648 23.0660191,17.1952382 22.3626477,17.1952382 L17.2048198,17.1952382 L17.2048198,22.3380138 C17.2048198,23.0614872 16.6964799,23.563526 15.9728644,23.563526 C15.2756953,23.563526 14.7951802,23.0413333 14.7951802,22.3380138 L14.7951802,17.1952382 L9.65130778,17.1952382 C8.93398085,17.1952382 8.41162523,16.7008648 8.41162523,16.0038327 Z"
56
+ fill-opacity="0.85"></path>
57
+ </g>
58
+ </g>
59
+ </svg> -->
60
+ <svg width="32px" height="32px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
61
+ <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
62
+ <g fill="currentColor" fill-rule="nonzero">
63
+ <path d="M15.9930223,31.97976 C24.7467023,31.97976 32,24.7418401 32,15.98988 C32,7.23796297 24.7327468,0 15.9790668,0 C7.23313125,0 0,7.23796297 0,15.98988 C0,24.7418401 7.24706085,31.97976 15.9930223,31.97976 Z" fill-opacity="0.1" class="sm-round-bg"></path>
64
+ <path d="M23.5318035,18.2475474 C22.2777951,18.2475474 21.2612876,17.2374408 21.2612876,15.9773915 C21.2612876,14.7173421 22.2777951,13.7072355 23.5318035,13.7072355 C24.7781451,13.7072355 25.8086942,14.7173421 25.8086942,15.9773915 C25.8086942,17.2374408 24.7781451,18.2475474 23.5318035,18.2475474 Z" fill-opacity="0.75"></path>
65
+ <path d="M15.9930223,18.2475474 C14.7327253,18.2475474 13.7224202,17.2374408 13.7224202,15.9773915 C13.7224202,14.7173421 14.7327253,13.7072355 15.9930223,13.7072355 C17.2533193,13.7072355 18.2775798,14.7173421 18.2775798,15.9773915 C18.2775798,17.2374408 17.2533193,18.2475474 15.9930223,18.2475474 Z" fill-opacity="0.75"></path>
66
+ <path d="M8.468162,18.2475474 C7.22182045,18.2475474 6.19131446,17.2374408 6.19131446,15.9773915 C6.19131446,14.7173421 7.22182045,13.7072355 8.468162,13.7072355 C9.70824943,13.7072355 10.7387124,14.7173421 10.7387124,15.9773915 C10.7387124,17.2374408 9.72220487,18.2475474 8.468162,18.2475474 Z" fill-opacity="0.75"></path>
67
+ </g>
68
+ </g>
69
+ </svg>
70
+ </button>
71
+ </div>
72
+ </div>
assets/html/close_btn.html ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ <button onclick='closeBtnClick("{obj}")'>
2
+ <svg class="icon-need-hover" stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round"
3
+ stroke-linejoin="round" height="20" width="20" xmlns="http://www.w3.org/2000/svg"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line>
4
+ </svg>
5
+ </button>
assets/html/footer.html ADDED
@@ -0,0 +1 @@
 
 
1
+ <div class="versions">{versions}</div>
assets/html/func_nav.html ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div id="menu-footer-btn-bar" class="is-gpt">
2
+ <div class="btn-bar-group">
3
+ <button id="chuanhu-setting-btn" onclick="openSettingBox()" class="chuanhu-ui-btn">
4
+ <!-- <svg width="24px" height="24px" viewBox="0 0 39.6797 39.6328" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
5
+ <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
6
+ <g id="gearshape" fill-rule="nonzero">
7
+ <path d="M17.9766,39.6094 L21.6797,39.6094 C23.1797,39.6094 24.3516,38.6953 24.7031,37.2891 L25.4766,33.9141 L25.8984,33.7734 L28.8047,35.5781 C30.0703,36.3516 31.5469,36.1641 32.6016,35.0859 L35.1797,32.5312 C36.2344,31.4766 36.4453,29.9766 35.6484,28.7578 L33.8203,25.8281 L33.9609,25.4766 L37.3359,24.7031 C38.7422,24.3516 39.6797,23.1562 39.6797,21.6797 L39.6797,18.0703 C39.6797,16.5938 38.7656,15.3984 37.3359,15.0469 L34.0078,14.2266 L33.8438,13.8516 L35.6719,10.9219 C36.4688,9.67969 36.2578,8.22656 35.2031,7.125 L32.625,4.57031 C31.5938,3.51562 30.1172,3.32812 28.8516,4.07812 L25.9219,5.85938 L25.4766,5.69531 L24.7031,2.32031 C24.3516,0.914062 23.1797,0 21.6797,0 L17.9766,0 C16.4766,0 15.3281,0.914062 14.9766,2.32031 L14.2031,5.69531 L13.7344,5.85938 L10.8047,4.07812 C9.5625,3.32812 8.08594,3.51562 7.03125,4.57031 L4.47656,7.125 C3.42188,8.22656 3.21094,9.67969 4.00781,10.9219 L5.8125,13.8516 L5.64844,14.2266 L2.32031,15.0469 C0.914062,15.3984 0,16.5938 0,18.0703 L0,21.6797 C0,23.1562 0.9375,24.3516 2.32031,24.7031 L5.69531,25.4766 L5.83594,25.8281 L4.03125,28.7578 C3.23438,29.9766 3.44531,31.4766 4.5,32.5312 L7.05469,35.0859 C8.10938,36.1641 9.60938,36.3516 10.8516,35.5781 L13.7812,33.7734 L14.2031,33.9141 L14.9766,37.2891 C15.3281,38.6953 16.4766,39.6094 17.9766,39.6094 Z M18.3047,36.3516 C18.0703,36.3516 17.9531,36.25781 17.9297,36.0469 L16.7812,31.4531 C15.5859,31.1484 14.5078,30.7031 13.6875,30.1406 L9.63281,32.6484 C9.46875,32.7422 9.30469,32.7188 9.14062,32.5781 L7.03125,30.4453 C6.86719,30.3047 6.86719,30.1406 6.98438,29.9531 L9.44531,25.9219 C9,25.125 8.48438,24.0469 8.17969,22.8516 L3.5625,21.7266 C3.35156,21.7031 3.25781,21.5859 3.25781,21.3516 L3.25781,18.3516 C3.25781,18.0938 3.32812,18.0234 3.5625,17.9531 L8.15625,16.8516 C8.46094,15.5625 9.07031,14.4375 9.39844,13.7344 L6.96094,9.72656 C6.82031,9.51562 6.82031,9.35156 6.98438,9.1875 L9.11719,7.10156 C9.28125,6.96094 9.39844,6.91406 9.63281,7.03125 L13.6406,9.46875 C14.4609,8.97656 15.6328,8.48438 16.8047,8.15625 L17.9297,3.5625 C17.9531,3.35156 18.0703,3.25781 18.3047,3.25781 L21.375,3.25781 C21.6094,3.25781 21.7266,3.35156 21.75,3.5625 L22.875,8.20312 C24.0938,8.50781 25.1484,9 25.9922,9.49219 L30.0469,7.03125 C30.25781,6.91406 30.375,6.96094 30.5625,7.10156 L32.6953,9.1875 C32.8359,9.35156 32.8594,9.51562 32.7188,9.72656 L30.25781,13.7344 C30.6094,14.4375 31.1953,15.5625 31.5,16.8516 L36.1172,17.9531 C36.3516,18.0234 36.3984,18.0938 36.3984,18.3516 L36.3984,21.3516 C36.3984,21.5859 36.3281,21.7031 36.1172,21.7266 L31.4766,22.8516 C31.1953,24.0469 30.6797,25.125 30.2109,25.9219 L32.6953,29.9531 C32.8125,30.1406 32.8125,30.3047 32.6484,30.4453 L30.5391,32.5781 C30.3516,32.7188 30.1875,32.7422 30.0469,32.6484 L25.9688,30.1406 C25.1719,30.7031 24.0703,31.1484 22.875,31.4531 L21.75,36.0469 C21.7266,36.25781 21.6094,36.3516 21.375,36.3516 L18.3047,36.3516 Z M19.8281,26.8125 C23.6719,26.8125 26.8359,23.6719 26.8359,19.8047 C26.8359,15.9844 23.6719,12.8438 19.8281,12.8438 C15.9844,12.8438 12.8203,15.9844 12.8203,19.8047 C12.8203,23.6484 15.9844,26.8125 19.8281,26.8125 Z M19.8281,23.5781 C17.7656,23.5781 16.1016,21.8906 16.1016,19.8047 C16.1016,17.7656 17.7656,16.0781 19.8281,16.0781 C21.8438,16.0781 23.5312,17.7656 23.5312,19.8047 C23.5312,21.8672 21.8438,23.5781 19.8281,23.5781 Z" id="形状" fill-opacity="0.85" fill="currentColor"></path>
8
+ </g>
9
+ </g>
10
+ </svg> -->
11
+ <svg width="24px" height="24px" viewBox="0 0 41.5547 40.9700126" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
12
+ <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" fill-opacity="0.85">
13
+ <g fill="currentColor" fill-rule="nonzero">
14
+ <path d="M20.7891,38.3561 C21.2344,38.3561 21.6328,38.3092 22.125,38.2858 L23.2031,40.3483 C23.4375,40.7936 23.8828,41.028 24.375,40.9577 C24.8438,40.8639 25.2188,40.4655 25.2891,39.9733 L25.6172,37.6764 C26.4609,37.442 27.3047,37.1139 28.1484,36.7858 L29.8359,38.3092 C30.2109,38.6608 30.7031,38.7311 31.1719,38.4733 C31.5938,38.2155 31.7812,37.7467 31.6875,37.2545 L31.1953,34.9811 C31.8984,34.4655 32.625,33.903 33.2578,33.2702 L35.3906,34.1608 C35.8594,34.3717 36.3516,34.2311 36.7031,33.8092 C37.0078,33.4577 37.0312,32.942 36.7734,32.5202 L35.5547,30.5514 C36.0703,29.8249 36.4688,29.0514 36.8672,28.2077 L39.1875,28.3249 C39.6797,28.3483 40.125,28.0436 40.2891,27.5983 C40.4531,27.1295 40.2891,26.6139 39.9141,26.3327 L38.0859,24.8795 C38.3203,24.0358 38.5078,23.1686 38.5781,22.2311 L40.7578,21.528 C41.25,21.3639 41.5547,20.9889 41.5547,20.4733 C41.5547,19.9577 41.25,19.5827 40.7578,19.4186 L38.5781,18.7155 C38.5078,17.778 38.3203,16.9342 38.0859,16.067 L39.9141,14.6139 C40.2891,14.3327 40.4531,13.8405 40.2891,13.3717 C40.125,12.9264 39.6797,12.6217 39.1875,12.6452 L36.8672,12.7389 C36.4688,11.8952 36.0703,11.1452 35.5547,10.3952 L36.7734,8.42641998 C37.0312,8.02797998 37.0078,7.51235998 36.7031,7.16078998 C36.3516,6.73891998 35.8594,6.62172998 35.3906,6.80922998 L33.2578,7.67641998 C32.625,7.06703998 31.8984,6.48110998 31.1953,5.96547998 L31.6875,3.71547998 C31.7812,3.19985998 31.5938,2.73110998 31.1719,2.49672998 C30.7031,2.23891998 30.2109,2.28578998 29.8359,2.66078998 L28.1484,4.16078998 C27.3047,3.80922998 26.4609,3.52797998 25.6172,3.27016998 L25.2891,0.996730977 C25.2188,0.504542977 24.8438,0.106105977 24.375,0.0123557768 C23.8828,-0.0579567232 23.4141,0.176417977 23.2031,0.598292977 L22.125,2.66078998 C21.6328,2.63735998 21.2344,2.61391998 20.7891,2.61391998 C20.2969,2.61391998 19.8984,2.63735998 19.4297,2.66078998 L18.3281,0.598292977 C18.1172,0.176417977 17.6719,-0.0579567232 17.1562,0.0123557768 C16.6875,0.106105977 16.3359,0.504542977 16.2656,0.996730977 L15.9375,3.27016998 C15.0703,3.52797998 14.2266,3.80922998 13.4062,4.16078998 L11.6953,2.66078998 C11.3203,2.28578998 10.8281,2.23891998 10.3594,2.49672998 C9.96094,2.73110998 9.75,3.19985998 9.86719,3.71547998 L10.3359,5.96547998 C9.63281,6.48110998 8.90625,7.06703998 8.27344,7.67641998 L6.16406,6.80922998 C5.67188,6.62172998 5.20312,6.73891998 4.85156,7.16078998 C4.54688,7.51235998 4.5,8.02797998 4.75781,8.42641998 L5.97656,10.3952 C5.48438,11.1452 5.0625,11.8952 4.66406,12.7389 L2.34375,12.6452 C1.85156,12.6217 1.40625,12.9264 1.24219,13.3717 C1.10156,13.8405 1.24219,14.3092 1.64062,14.6139 L3.44531,16.067 C3.23438,16.9342 3.04688,17.778 2.97656,18.7155 L0.773438,19.4186 C0.304688,19.5827 0,19.9577 0,20.4733 C0,20.9889 0.304688,21.3639 0.773438,21.528 L2.97656,22.2311 C3.04688,23.1686 3.23438,24.0358 3.44531,24.8795 L1.64062,26.3327 C1.24219,26.6139 1.10156,27.1295 1.24219,27.5983 C1.40625,28.0436 1.85156,28.3483 2.34375,28.3249 L4.66406,28.2077 C5.0625,29.0514 5.48438,29.8249 5.97656,30.5514 L4.75781,32.5202 C4.5,32.942 4.54688,33.4577 4.85156,33.8092 C5.20312,34.2311 5.67188,34.3717 6.16406,34.1608 L8.27344,33.2702 C8.90625,33.903 9.63281,34.4655 10.3359,34.9811 L9.86719,37.2545 C9.77344,37.7467 9.96094,38.2155 10.3594,38.4733 C10.8281,38.7311 11.3203,38.6608 11.6953,38.3092 L13.4062,36.7858 C14.2266,37.1139 15.0703,37.442 15.9375,37.6764 L16.2656,39.9733 C16.3359,40.4655 16.6875,40.8639 17.1562,40.9577 C17.6719,41.028 18.0938,40.7936 18.3281,40.3483 L19.4297,38.2858 C19.8984,38.3092 20.2969,38.3561 20.7891,38.3561 Z M20.7891,35.1686 C12.5859,35.1686 6.25781,28.6295 6.25781,20.4967 C6.25781,12.3405 12.5859,5.80141998 20.7891,5.80141998 C28.9688,5.80141998 35.2969,12.3405 35.2969,20.4967 C35.2969,28.6295 28.9688,35.1686 20.7891,35.1686 Z M17.3672,17.4733 L19.6641,15.9967 L13.5938,5.66078998 L11.2266,7.02016998 L17.3672,17.4733 Z M25.1484,21.8327 L37.2188,21.8327 L37.1953,19.1608 L25.1484,19.1608 L25.1484,21.8327 Z M19.6406,25.0202 L17.3438,23.5202 L10.9922,33.8795 L13.3359,35.2858 L19.6406,25.0202 Z M20.7188,25.5124 C23.4844,25.5124 25.6875,23.2858 25.6875,20.5202 C25.6875,17.7545 23.4844,15.528 20.7188,15.528 C17.9531,15.528 15.7266,17.7545 15.7266,20.5202 C15.7266,23.2858 17.9531,25.5124 20.7188,25.5124 Z M20.7188,22.5592 C19.5703,22.5592 18.6562,21.6686 18.6562,20.5202 C18.6562,19.3717 19.5703,18.4811 20.7188,18.4811 C21.8672,18.4811 22.7578,19.3717 22.7578,20.5202 C22.7578,21.6686 21.8672,22.5592 20.7188,22.5592 Z"></path>
15
+ </g>
16
+ </g>
17
+ </svg>
18
+ </button>
19
+ <button id="chuanhu-manual-check-btn" onclick="manualCheckUpdate()" class="chuanhu-ui-btn">
20
+ <span class="show-on-latest">
21
+ <svg width="24px" height="24px" viewBox="0 0 45.2923004 37.8516" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
22
+ <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
23
+ <g fill-rule="nonzero">
24
+ <path d="M0.415684357,19.0078 C-0.381190643,20.1094 -0.0296279434,21.1172 1.44693036,21.1172 L3.86100036,21.1172 C4.96256036,30.4453 13.0719004,37.8281 22.6344004,37.8281 C28.2360004,37.8281 33.2985004,35.3203 36.7672004,31.3828 C37.5641004,30.4922 37.4469004,29.3438 36.6266004,28.7578 C35.8063004,28.1719 34.8219004,28.3828 34.1188004,29.1562 C31.3297004,32.2969 27.2282004,34.2656 22.6344004,34.2656 C14.8532004,34.2656 8.52506036,28.5703 7.47037036,21.1172 L9.97818036,21.1172 C11.4313004,21.1172 11.8063004,20.1094 11.0329004,19.0312 L6.86100036,13.0781 C6.22818036,12.1641 5.24381036,12.1406 4.58756036,13.0781 L0.415684357,19.0078 Z M8.52506036,6.42188 C7.72818036,7.3125 7.84537036,8.4375 8.66568036,9.02344 C9.50943036,9.60938 10.4938004,9.44531 11.1969004,8.64844 C14.0094004,5.53125 18.0876004,3.5625 22.6344004,3.5625 C30.4157004,3.5625 36.7672004,9.25781 37.7985004,16.7109 L35.2907004,16.7109 C33.8376004,16.7109 33.4860004,17.7188 34.2594004,18.8203 L38.4313004,24.75 C39.0641004,25.6641 40.0485004,25.6875 40.7047004,24.75 L44.8766004,18.8438 C45.6735004,17.7188 45.3219004,16.7109 43.8454004,16.7109 L41.4313004,16.7109 C40.3297004,7.38281 32.2204004,0 22.6344004,0 C17.0797004,0 12.0172004,2.48438 8.52506036,6.42188 Z" fill-opacity="0.85" fill="currentColor"></path>
25
+ </g>
26
+ </g>
27
+ </svg>
28
+ </span>
29
+ <span class="show-on-outdated">
30
+ <svg width="24px" height="24px" viewBox="0 0 45.2924004 37.8516" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
31
+ <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
32
+ <g fill="currentColor" fill-rule="nonzero">
33
+ <path d="M0.415682396,19.0078 C-0.381189604,20.1094 -0.0296276044,21.1172 1.4469304,21.1172 L3.8610104,21.1172 C4.9625604,30.4453 13.0719004,37.8281 22.6344004,37.8281 C28.2360004,37.8281 33.2985004,35.3203 36.7673004,31.3828 C37.5641004,30.4922 37.4469004,29.3437 36.6266004,28.7578 C35.8063004,28.1719 34.8219004,28.3828 34.1188004,29.1563 C31.3297004,32.2969 27.2282004,34.2656 22.6344004,34.2656 C14.8532004,34.2656 8.5250704,28.5703 7.4703704,21.1172 L9.9781804,21.1172 C11.4313004,21.1172 11.8063004,20.1094 11.0329004,19.0312 L6.8610104,13.0781 C6.2281804,12.1641 5.2437904,12.1406 4.5875404,13.0781 L0.415682396,19.0078 Z M8.5250704,6.42187 C7.7281804,7.31251 7.8453904,8.43749 8.6656604,9.02342 C9.5094604,9.60936 10.4938004,9.4453 11.1969004,8.64845 C14.0095004,5.53123 18.0875004,3.56251 22.6344004,3.56251 C30.4157004,3.56251 36.7673004,9.25781 37.7985004,16.7109 L35.2907004,16.7109 C33.8376004,16.7109 33.4860004,17.7188 34.2595004,18.8203 L38.4313004,24.75 C39.0641004,25.6641 40.0485004,25.6875 40.7048004,24.75 L44.8767004,18.8437 C45.6735004,17.7188 45.3222004,16.7109 43.8454004,16.7109 L41.4313004,16.7109 C40.3297004,7.38283 32.2204004,0 22.6344004,0 C17.0797004,0 12.0173004,2.48438 8.5250704,6.42187 Z" fill-opacity="0.85"></path>
34
+ <path d="M22.6344004,22.2422 C23.6422004,22.2422 24.2048004,21.6797 24.2282004,20.625 L24.5095004,11.0156 C24.5329004,9.96096 23.7126004,9.18749 22.6110004,9.18749 C21.5095004,9.18749 20.7126004,9.93749 20.7360004,10.9922 L21.0173004,20.625 C21.0407004,21.6797 21.6032004,22.2422 22.6344004,22.2422 Z M22.6344004,28.3828 C23.7829004,28.3828 24.7907004,27.4688 24.7907004,26.3203 C24.7907004,25.1484 23.8063004,24.2578 22.6344004,24.2578 C21.4626004,24.2578 20.5016004,25.1719 20.5016004,26.3203 C20.5016004,27.4453 21.4860004,28.3828 22.6344004,28.3828 Z" fill-opacity="0.85"></path>
35
+ </g>
36
+ </g>
37
+ </svg>
38
+ </span>
39
+ </button>
40
+ <!--
41
+ <button id="chuanhu-training-btn" onclick="openTrainingBox()" class="chuanhu-ui-btn">
42
+ <svg width="24px" height="24px" viewBox="0 0 37.3359 44.6953" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
43
+ <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
44
+ <g id="brain.filled.head.profile" fill-rule="nonzero">
45
+ <rect id="矩形" fill="#000000" opacity="0" x="0" y="0" width="37.3359" height="44.6953"></rect>
46
+ <path d="M21.5156,44.5312 C28.5,44.5312 32.7656,42.0469 32.7656,37.7109 L32.7656,28.7812 C35.6484,26.2031 37.3359,22.1016 37.3359,17.625 C37.3359,7.05469 30.4453,0 20.2031,0 C9.98438,0 3.14062,6.91406 3.14062,17.2266 C3.14062,17.7891 3.16406,18.2578 3.21094,18.7031 L0.960938,22.7109 C0.328125,23.8594 0,25.0078 0,26.0391 C0,27.9844 1.17188,29.5781 3.14062,30.1641 L3.14062,33.6562 C3.14062,37.1719 5.67188,38.8828 8.8125,38.5312 L12.8438,38.1328 L10.4531,35.5781 L10.4531,37.7109 C10.4531,42.0234 14.625,44.5312 21.5156,44.5312 Z M21.5156,41.1562 C16.5703,41.1562 13.6406,39.6328 13.6406,37.125 L13.6406,34.9453 C13.6406,34.7109 13.5234,34.5938 13.3125,34.6172 L8.34375,35.1797 C7.17188,35.2969 6.51562,34.8281 6.51562,33.4453 L6.51562,27.6562 C6.51562,27.4922 6.39844,27.375 6.16406,27.375 L5.13281,27.375 C4.03125,27.375 3.39844,26.8359 3.39844,25.9922 C3.39844,25.5234 3.5625,24.9844 3.89062,24.3984 L6.70312,19.3828 C6.58594,18.6562 6.51562,17.9062 6.51562,17.1797 C6.51562,8.90625 11.9766,3.39844 20.2031,3.39844 C28.4297,3.39844 33.9609,9.07031 33.9609,17.625 C33.9609,21.7266 32.2266,25.3359 29.3672,27.1172 L29.3672,37.125 C29.3672,39.6328 26.4375,41.1562 21.5156,41.1562 Z" id="形状" fill-opacity="0.85" fill="currentColor"></path>
47
+ <path d="M14.1797,19.7812 C16.2656,19.7812 17.7188,18.375 17.7188,16.4062 C17.7188,15.7031 17.5312,15.1875 17.2031,14.8359 C16.8516,14.5078 16.7109,14.1562 16.7109,13.9219 C16.7109,13.4062 17.1562,13.0312 17.6719,13.0312 C17.8828,13.0312 18.1641,13.0781 18.375,13.2891 C18.4219,13.3359 18.4688,13.4062 18.4922,13.4531 C19.9219,13.2891 20.6484,12.4688 20.6484,11.1328 C20.6484,10.6172 21.0703,10.1719 21.5859,10.1719 C22.1016,10.1719 22.5469,10.6406 22.5469,11.1328 C22.5703,13.2656 21.4922,14.6016 19.4297,15.0703 C19.5703,15.4922 19.6172,15.9609 19.6172,16.4297 C19.6172,18.2109 18.75,19.6641 17.3203,20.4844 C18.1172,20.8594 19.0312,21.0469 20.0156,21.0469 C20.4844,21.0469 20.9766,21 21.4688,20.9062 C21.375,20.6719 21.3516,20.4141 21.3516,20.2031 C21.3516,15.4453 28.1719,14.6484 28.1719,10.4531 C28.1719,8.34375 26.5781,6.72656 24.5859,6.72656 C23.8125,6.72656 23.6719,6.75 23.5078,6.77344 C22.7344,5.95312 21.6328,5.48438 20.6953,5.48438 C18.9844,5.48438 17.8125,6.5625 17.8125,8.15625 C17.8125,8.71875 17.4141,9.09375 16.8516,9.09375 C16.2891,9.09375 15.8906,8.67188 15.9141,8.10938 C15.9141,7.35938 16.1484,6.89062 16.2891,6.44531 C16.0078,6.39844 15.7266,6.375 15.4688,6.375 C13.2656,6.375 11.5547,7.73438 11.5547,9.39844 C11.5547,10.4766 12.2812,11.3438 13.2422,11.3438 C13.7812,11.3438 14.2031,11.7656 14.2031,12.2578 C14.2031,12.7969 13.7578,13.2422 13.2422,13.2422 C11.7656,13.2422 10.6172,12.5625 10.0547,11.4844 C9.51562,12.3516 9.21094,13.3594 9.21094,14.3906 C9.21094,17.4141 11.1562,19.7812 14.1797,19.7812 Z M27.7969,24.5156 C29.7656,24.5156 31.1953,22.3125 31.1953,19.3359 C31.1953,19.125 31.1953,18.8906 31.1953,18.6328 C30.4688,18.9609 29.6016,19.1016 28.6172,19.0312 C28.1016,18.9609 27.7031,18.5625 27.7031,18.0469 C27.7031,17.5312 28.1484,17.0625 28.6641,17.1094 C30.5859,17.2734 31.8516,16.2188 31.8516,14.5078 C31.8516,12.9375 31.125,11.625 29.8828,10.8047 C29.3203,15.9141 23.0156,16.5938 23.0156,20.1328 C23.0156,21.0938 23.6484,21.7734 24.75,21.7734 L25.0078,21.7734 C25.3125,23.3906 26.4375,24.5156 27.7969,24.5156 Z" id="形状" fill-opacity="0.85" fill="currentColor"></path>
48
+ </g>
49
+ </g>
50
+ </svg>
51
+ </button>
52
+ -->
53
+ </div>
54
+ <div class="btn-bar-group">
55
+ <button id="chuanhu-appearance-switcher" onclick="btnToggleDarkMode()" class="chuanhu-ui-btn">
56
+ <span class="show-on-dark">
57
+ <svg width="24px" height="24px" viewBox="0 0 39.9141 40.0547" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
58
+ <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
59
+ <g fill-rule="nonzero">
60
+ <path d="M19.9688,7.42969 C20.9531,7.42969 21.7734,6.58594 21.7734,5.60156 L21.7734,1.80469 C21.7734,0.820312 20.9531,0 19.9688,0 C18.9609,0 18.1406,0.820312 18.1406,1.80469 L18.1406,5.60156 C18.1406,6.58594 18.9609,7.42969 19.9688,7.42969 Z M28.8281,11.1328 C29.5312,11.8359 30.7031,11.8594 31.4297,11.1328 L34.125,8.46094 C34.8047,7.75781 34.8047,6.5625 34.125,5.85938 C33.4219,5.15625 32.25,5.15625 31.5469,5.85938 L28.8281,8.57812 C28.1484,9.28125 28.1484,10.4297 28.8281,11.1328 Z M32.5078,20.0156 C32.5078,21 33.3516,21.8438 34.3359,21.8438 L38.0859,21.8438 C39.0938,21.8438 39.9141,21 39.9141,20.0156 C39.9141,19.0312 39.0938,18.1875 38.0859,18.1875 L34.3359,18.1875 C33.3516,18.1875 32.5078,19.0312 32.5078,20.0156 Z M28.8281,28.9219 C28.1484,29.625 28.1484,30.7734 28.8281,31.4766 L31.5469,34.1953 C32.25,34.8984 33.4219,34.875 34.125,34.1719 C34.8047,33.4688 34.8047,32.2969 34.125,31.5938 L31.4062,28.9219 C30.7031,28.2188 29.5312,28.2188 28.8281,28.9219 Z M19.9688,32.6016 C18.9609,32.6016 18.1406,33.4453 18.1406,34.4297 L18.1406,38.2266 C18.1406,39.2109 18.9609,40.0312 19.9688,40.0312 C20.9531,40.0312 21.7734,39.2109 21.7734,38.2266 L21.7734,34.4297 C21.7734,33.4453 20.9531,32.6016 19.9688,32.6016 Z M11.0859,28.9219 C10.3828,28.2188 9.1875,28.2188 8.48438,28.9219 L5.8125,31.5703 C5.10938,32.2734 5.10938,33.4453 5.78906,34.1484 C6.49219,34.8516 7.66406,34.875 8.36719,34.1719 L11.0625,31.4766 C11.7656,30.7734 11.7656,29.625 11.0859,28.9219 Z M7.40625,20.0156 C7.40625,19.0312 6.58594,18.1875 5.57812,18.1875 L1.82812,18.1875 C0.820312,18.1875 0,19.0312 0,20.0156 C0,21 0.820312,21.8438 1.82812,21.8438 L5.57812,21.8438 C6.58594,21.8438 7.40625,21 7.40625,20.0156 Z M11.0625,11.1328 C11.7656,10.4531 11.7656,9.25781 11.0859,8.57812 L8.39062,5.85938 C7.71094,5.17969 6.51562,5.15625 5.83594,5.85938 C5.13281,6.5625 5.13281,7.75781 5.8125,8.4375 L8.48438,11.1328 C9.1875,11.8359 10.3594,11.8359 11.0625,11.1328 Z" id="形状" fill-opacity="0.85" fill="currentColor"></path>
61
+ <path d="M19.9688,29.5781 C25.1719,29.5781 29.5078,25.2656 29.5078,20.0156 C29.5078,14.7656 25.1719,10.4531 19.9688,10.4531 C14.7422,10.4531 10.4062,14.7656 10.4062,20.0156 C10.4062,25.2656 14.7422,29.5781 19.9688,29.5781 Z M19.9688,26.3906 C16.4766,26.3906 13.5938,23.4844 13.5938,20.0156 C13.5938,16.5469 16.4766,13.6406 19.9688,13.6406 C23.4375,13.6406 26.3203,16.5469 26.3203,20.0156 C26.3203,23.4844 23.4375,26.3906 19.9688,26.3906 Z" id="形状" fill-opacity="0.85" fill="currentColor"></path>
62
+ </g>
63
+ </g>
64
+ </svg>
65
+ </span>
66
+ <span class="show-on-light">
67
+ <svg width="24px" height="24px" viewBox="0 0 37.2422 42.2109" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
68
+ <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
69
+ <g fill="currentColor" fill-rule="nonzero">
70
+ <path d="M30,21.6797 C30.375,21.6797 30.6562,21.3984 30.7031,21 C31.2422,16.1016 31.5469,15.9141 36.5156,15.1406 C36.9844,15.0703 37.2422,14.8594 37.2422,14.4375 C37.2422,14.0625 36.9844,13.8047 36.6094,13.7578 C31.5938,12.7969 31.2422,12.7969 30.7031,7.89844 C30.6562,7.47656 30.375,7.21875 30,7.21875 C29.6016,7.21875 29.3438,7.47656 29.2969,7.875 C28.6875,12.8672 28.4531,13.1016 23.3672,13.7578 C23.0156,13.7812 22.7344,14.0625 22.7344,14.4375 C22.7344,14.8359 23.0156,15.0703 23.3672,15.1406 C28.4531,16.1016 28.6641,16.1484 29.2969,21.0469 C29.3438,21.3984 29.6016,21.6797 30,21.6797 Z M21.2109,9 C21.4453,9 21.5859,8.85938 21.6328,8.625 C22.2422,5.60156 22.1719,5.55469 25.3359,4.92188 C25.5469,4.875 25.7109,4.75781 25.7109,4.5 C25.7109,4.24219 25.5469,4.125 25.3359,4.07812 C22.1719,3.44531 22.2422,3.39844 21.6328,0.375 C21.5859,0.140625 21.4453,0 21.2109,0 C20.9531,0 20.8125,0.140625 20.7656,0.375 C20.1562,3.39844 20.2266,3.44531 17.0859,4.07812 C16.8516,4.125 16.6875,4.24219 16.6875,4.5 C16.6875,4.75781 16.8516,4.875 17.0859,4.92188 C20.2266,5.55469 20.1797,5.60156 20.7656,8.625 C20.8125,8.85938 20.9531,9 21.2109,9 Z" fill-opacity="0.85"></path>
71
+ <path d="M16.3125,38.625 C23.1094,38.625 28.5938,35.1562 31.0781,29.2734 C31.4297,28.4062 31.3125,27.75 30.9141,27.3516 C30.5625,27 29.9531,26.9297 29.2734,27.2109 C27.8906,27.75 26.2031,28.0547 24.1406,28.0547 C16.0078,28.0547 10.7578,22.9453 10.7578,15.0938 C10.7578,12.7734 11.2031,10.5 11.7188,9.49219 C12.0938,8.69531 12.0703,8.01562 11.7422,7.61719 C11.3672,7.17188 10.7109,7.00781 9.77344,7.35938 C3.98438,9.58594 0,15.6562 0,22.5938 C0,31.6875 6.79688,38.625 16.3125,38.625 Z M16.3594,35.4141 C8.69531,35.4141 3.21094,29.8359 3.21094,22.3359 C3.21094,17.9766 5.08594,14.0391 8.29688,11.4375 C7.89844,12.6094 7.6875,14.3438 7.6875,16.0078 C7.6875,24.9844 14.0156,31.1484 23.2969,31.1484 C24.8203,31.1484 26.2266,30.9844 26.9062,30.7734 C24.6094,33.6562 20.6953,35.4141 16.3594,35.4141 Z" fill-opacity="0.85"></path>
72
+ </g>
73
+ </g>
74
+ </svg>
75
+ </span>
76
+ </button>
77
+ </div>
78
+ </div>
assets/html/header_title.html ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div style="display:inline-flex;">
2
+ <button id="chuanhu-menu-btn" onclick='menuClick()' class="chuanhu-ui-btn hover-round-btn"
3
+ style="visibility: visible; width:42px; height:42px; margin-right:5px;">
4
+ <svg viewBox="0 0 24 24" fill="currentColor">
5
+ <path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"></path>
6
+ </svg>
7
+ </button>
8
+ </div>
9
+ <div style="margin-left: 6px;">
10
+ <div>{app_title}</div>
11
+ </div>
assets/html/update.html ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div id="toast-update">
2
+ <div id="check-chuanhu-update">
3
+ <p style="display:none">
4
+ <span id="current-version">{current_version}</span>
5
+ <span id="version-time">{version_time}</span>
6
+ </p>
7
+ <p id="version-info-title">
8
+ Latest Version: <a href="https://github.com/gaizhenbiao/chuanhuchatgpt/releases/latest" target="_blank"
9
+ id="latest-version-title" style="text-decoration: none;">getting latest version...</a>
10
+ </p>
11
+ <p id="updating-info" class="hideK">
12
+ Getting update...
13
+ </p>
14
+ <div id="updating-spinner"></div>
15
+ <div id="release-note-wrap">
16
+ <div class="release-note-content" id="release-note-content">
17
+ Getting Release Note...
18
+ </div>
19
+ </div>
20
+ <div id="goto-update-btn" class="btn-update-group">
21
+ <button class="btn-update lg secondary svelte-cmf5ev" id="cancel-button" onclick="cancelUpdate()">{cancel_btn}</button>
22
+ <button class="btn-update lg primary svelte-cmf5ev" id="update-button" onclick="bgUpdateChuanhu()">{update_btn}</button>
23
+ </div>
24
+ <div id="close-update-btn" class="btn-update-group hideK">
25
+ <button class="btn-update lg secondary svelte-cmf5ev" id="seenew-button" onclick="getUpdateInfo()">{seenew_btn}</button>
26
+ <button class="btn-update lg primary svelte-cmf5ev" id="ok-button" onclick="cancelUpdate()">{ok_btn}</button>
27
+ </div>
28
+ </div>
29
+ </div>
assets/html/web_config.html ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div aria-label="config-div" style="display:none;">
2
+ <!-- app config -->
3
+ <div id="app_config">
4
+ <span id="enableCheckUpdate_config">{enableCheckUpdate_config}</span>
5
+ <span id="hideHistoryWhenNotLoggedIn_config">{hideHistoryWhenNotLoggedIn_config}</span>
6
+ </div>
7
+ <!-- i18n config -->
8
+ <div id="config_i18n">
9
+ <span id="forView_i18n">{forView_i18n}</span>
10
+ <span id="deleteConfirm_i18n_pref">{deleteConfirm_i18n_pref}</span>
11
+ <span id="deleteConfirm_i18n_suff">{deleteConfirm_i18n_suff}</span>
12
+ <span id="usingLatest_i18n">{usingLatest_i18n}</span>
13
+ <span id="updatingMsg_i18n">{updatingMsg_i18n}</span>
14
+ <span id="updateSuccess_i18n">{updateSuccess_i18n}</span>
15
+ <span id="updateFailure_i18n">{updateFailure_i18n}</span>
16
+ <span id="regenerate_i18n">{regenerate_i18n}</span>
17
+ <span id="deleteRound_i18n">{deleteRound_i18n}</span>
18
+ <span id="renameChat_i18n">{renameChat_i18n}</span>
19
+ <span id="validFileName_i18n">{validFileName_i18n}</span>
20
+ <span id="clearFileHistoryMsg_i18n">{clearFileHistoryMsg_i18n}</span>
21
+ <span id="dropUploadMsg_i18n">{dropUploadMsg_i18n}</span>
22
+ </div>
23
+ </div>
assets/icon.png ADDED
assets/javascript/ChuanhuChat.js ADDED
@@ -0,0 +1,463 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ // ChuanhuChat core javascript
3
+
4
+ const MAX_HISTORY_LENGTH = 32;
5
+
6
+ var key_down_history = [];
7
+ var currentIndex = -1;
8
+
9
+ var gradioContainer = null;
10
+ var user_input_ta = null;
11
+ var user_input_tb = null;
12
+ var userInfoDiv = null;
13
+ var appTitleDiv = null;
14
+ var chatbotArea = null;
15
+ var chatbot = null;
16
+ var chatbotIndicator = null;
17
+ var uploaderIndicator = null;
18
+ var chatListIndicator = null;
19
+ var chatbotWrap = null;
20
+ var apSwitch = null;
21
+ var messageBotDivs = null;
22
+ var loginUserForm = null;
23
+ var logginUser = null;
24
+ var updateToast = null;
25
+ var sendBtn = null;
26
+ var cancelBtn = null;
27
+ var sliders = null;
28
+ var updateChuanhuBtn = null;
29
+ var statusDisplay = null;
30
+
31
+ var historySelector = null;
32
+ var chuanhuPopup = null;
33
+ var settingBox = null;
34
+ var trainingBox = null;
35
+ var popupWrapper = null;
36
+ var chuanhuHeader = null;
37
+ var menu = null;
38
+ var toolbox = null;
39
+ // var trainBody = null;
40
+
41
+ var isInIframe = (window.self !== window.top);
42
+ var currentTime = new Date().getTime();
43
+
44
+ let windowWidth = window.innerWidth; // 初始窗口宽度
45
+
46
+ function addInit() {
47
+ var needInit = {chatbotIndicator, uploaderIndicator};
48
+
49
+ chatbotIndicator = gradioApp().querySelector('#chuanhu-chatbot > div.wrap');
50
+ uploaderIndicator = gradioApp().querySelector('#upload-index-file > div[data-testid="block-label"]');
51
+ chatListIndicator = gradioApp().querySelector('#history-select-dropdown > div.wrap');
52
+
53
+ for (let elem in needInit) {
54
+ if (needInit[elem] == null) {
55
+ // addInited = false;
56
+ return false;
57
+ }
58
+ }
59
+
60
+ chatbotObserver.observe(chatbotIndicator, { attributes: true, childList: true, subtree: true });
61
+ chatListObserver.observe(chatListIndicator, { attributes: true });
62
+ setUploader();
63
+ setPasteUploader();
64
+ setDragUploader();
65
+ return true;
66
+ }
67
+
68
+ function initialize() {
69
+ gradioObserver.observe(gradioApp(), { childList: true, subtree: true });
70
+
71
+ loginUserForm = gradioApp().querySelector(".gradio-container > .main > .wrap > .panel > .form")
72
+ gradioContainer = gradioApp().querySelector(".gradio-container");
73
+ user_input_tb = gradioApp().getElementById('user-input-tb');
74
+ userInfoDiv = gradioApp().getElementById("user-info");
75
+ appTitleDiv = gradioApp().getElementById("app-title");
76
+ chatbotArea = gradioApp().querySelector('#chatbot-area');
77
+ chatbot = gradioApp().querySelector('#chuanhu-chatbot');
78
+ chatbotWrap = gradioApp().querySelector('#chuanhu-chatbot > .wrapper > .wrap');
79
+ apSwitch = gradioApp().querySelector('.apSwitch input[type="checkbox"]');
80
+ updateToast = gradioApp().querySelector("#toast-update");
81
+ sendBtn = gradioApp().getElementById("submit-btn");
82
+ cancelBtn = gradioApp().getElementById("cancel-btn");
83
+ sliders = gradioApp().querySelectorAll('input[type="range"]');
84
+ updateChuanhuBtn = gradioApp().getElementById("update-chuanhu-btn");
85
+ statusDisplay = gradioApp().querySelector('#status-display');
86
+
87
+ historySelector = gradioApp().querySelector('#history-select-dropdown');
88
+ chuanhuPopup = gradioApp().querySelector('#chuanhu-popup');
89
+ settingBox = gradioApp().querySelector('#chuanhu-setting');
90
+ // trainingBox = gradioApp().querySelector('#chuanhu-training');
91
+ popupWrapper = gradioApp().querySelector('#popup-wrapper');
92
+ chuanhuHeader = gradioApp().querySelector('#chuanhu-header');
93
+ menu = gradioApp().querySelector('#menu-area');
94
+ toolbox = gradioApp().querySelector('#toolbox-area');
95
+ // trainBody = gradioApp().querySelector('#train-body');
96
+
97
+ // if (loginUserForm) {
98
+ // localStorage.setItem("userLogged", true);
99
+ // userLogged = true;
100
+ // }
101
+
102
+ adjustDarkMode();
103
+ adjustSide();
104
+ setChatList();
105
+ setChatListHeader();
106
+ setLoclize();
107
+ selectHistory();
108
+ // setChatbotHeight();
109
+ setPopupBoxPosition();
110
+ setSlider();
111
+ setCheckboxes();
112
+ setAutocomplete();
113
+ checkModel();
114
+
115
+ settingBox.classList.add('hideBox');
116
+ // trainingBox.classList.add('hideBox');
117
+
118
+ if (!historyLoaded) loadHistoryHtml();
119
+ if (!usernameGotten) getUserInfo();
120
+
121
+ setUpdater();
122
+
123
+ setChatbotScroll();
124
+ setTimeout(showOrHideUserInfo(), 2000);
125
+
126
+ // setHistroyPanel();
127
+ // trainBody.classList.add('hide-body');
128
+
129
+
130
+
131
+ return true;
132
+ }
133
+
134
+ function gradioApp() {
135
+ const elems = document.getElementsByTagName('gradio-app');
136
+ const elem = elems.length == 0 ? document : elems[0];
137
+
138
+ if (elem !== document) {
139
+ elem.getElementById = function(id) {
140
+ return document.getElementById(id);
141
+ };
142
+ }
143
+ return elem.shadowRoot ? elem.shadowRoot : elem;
144
+ }
145
+
146
+ function showConfirmationDialog(a, file, c) {
147
+ if (file != "") {
148
+ var result = confirm(i18n(deleteConfirm_i18n_pref) + file + i18n(deleteConfirm_i18n_suff));
149
+ if (result) {
150
+ return [a, file, c];
151
+ }
152
+ }
153
+ return [a, "CANCELED", c];
154
+ }
155
+
156
+ function selectHistory() {
157
+ user_input_ta = user_input_tb.querySelector("textarea");
158
+ if (user_input_ta) {
159
+ disableSendBtn();
160
+ // 在 textarea 上监听 keydown 事件
161
+ user_input_ta.addEventListener("keydown", function (event) {
162
+ var value = user_input_ta.value.trim();
163
+ // 判断按下的是否为方向键
164
+ if (event.code === 'ArrowUp' || event.code === 'ArrowDown') {
165
+ // 如果按下的是方向键,且输入框中有内容,且历史记录中没有该内容,则不执行操作
166
+ if (value && key_down_history.indexOf(value) === -1)
167
+ return;
168
+ // 对于需要响应的动作,阻止默认行为。
169
+ event.preventDefault();
170
+ var length = key_down_history.length;
171
+ if (length === 0) {
172
+ currentIndex = -1; // 如果历史记录为空,直接将当前选中的记录重置
173
+ return;
174
+ }
175
+ if (currentIndex === -1) {
176
+ currentIndex = length;
177
+ }
178
+ if (event.code === 'ArrowUp' && currentIndex > 0) {
179
+ currentIndex--;
180
+ user_input_ta.value = key_down_history[currentIndex];
181
+ } else if (event.code === 'ArrowDown' && currentIndex < length - 1) {
182
+ currentIndex++;
183
+ user_input_ta.value = key_down_history[currentIndex];
184
+ }
185
+ user_input_ta.selectionStart = user_input_ta.value.length;
186
+ user_input_ta.selectionEnd = user_input_ta.value.length;
187
+ const input_event = new InputEvent("input", { bubbles: true, cancelable: true });
188
+ user_input_ta.dispatchEvent(input_event);
189
+ } else if (event.code === "Enter") {
190
+ if (value) {
191
+ currentIndex = -1;
192
+ if (key_down_history.indexOf(value) === -1) {
193
+ key_down_history.push(value);
194
+ if (key_down_history.length > MAX_HISTORY_LENGTH) {
195
+ key_down_history.shift();
196
+ }
197
+ }
198
+ }
199
+ }
200
+ });
201
+ }
202
+ }
203
+
204
+ function disableSendBtn() {
205
+ sendBtn.disabled = user_input_ta.value.trim() === '';
206
+ user_input_ta.addEventListener('input', () => {
207
+ sendBtn.disabled = user_input_ta.value.trim() === '';
208
+ });
209
+ }
210
+
211
+ function checkModel() {
212
+ const model = gradioApp().querySelector('#model-select-dropdown input');
213
+ var modelValue = model.value;
214
+ checkGPT();
215
+ checkXMChat();
216
+ function checkGPT() {
217
+ modelValue = model.value;
218
+ if (modelValue.toLowerCase().includes('gpt')) {
219
+ gradioApp().querySelector('#header-btn-groups').classList.add('is-gpt');
220
+ } else {
221
+ gradioApp().querySelector('#header-btn-groups').classList.remove('is-gpt');
222
+ }
223
+ // console.log('gpt model checked')
224
+ }
225
+ function checkXMChat() {
226
+ modelValue = model.value;
227
+ if (modelValue.includes('xmchat')) {
228
+ chatbotArea.classList.add('is-xmchat');
229
+ } else {
230
+ chatbotArea.classList.remove('is-xmchat');
231
+ }
232
+ }
233
+
234
+ model.addEventListener('blur', ()=>{
235
+ setTimeout(()=>{
236
+ checkGPT();
237
+ checkXMChat();
238
+ }, 100);
239
+ });
240
+ }
241
+
242
+ function toggleDarkMode(isEnabled) {
243
+ if (isEnabled) {
244
+ document.body.classList.add("dark");
245
+ document.querySelector('meta[name="theme-color"]').setAttribute('content', '#171717');
246
+ document.body.style.setProperty("background-color", "var(--neutral-950)", "important");
247
+ } else {
248
+ document.body.classList.remove("dark");
249
+ document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff');
250
+ document.body.style.backgroundColor = "";
251
+ }
252
+ }
253
+ function adjustDarkMode() {
254
+ const darkModeQuery = window.matchMedia("(prefers-color-scheme: dark)");
255
+ apSwitch.checked = darkModeQuery.matches;
256
+ toggleDarkMode(darkModeQuery.matches);
257
+ darkModeQuery.addEventListener("change", (e) => {
258
+ apSwitch.checked = e.matches;
259
+ toggleDarkMode(e.matches);
260
+ });
261
+ apSwitch.addEventListener("change", (e) => {
262
+ toggleDarkMode(e.target.checked);
263
+ });
264
+ }
265
+ function btnToggleDarkMode() {
266
+ apSwitch.checked = !apSwitch.checked;
267
+ toggleDarkMode(apSwitch.checked);
268
+ }
269
+
270
+ function setScrollShadow() {
271
+ const toolboxScroll = toolbox.querySelector('#toolbox-area > .gradio-box > .gradio-tabs > div.tab-nav');
272
+ const toolboxTabs = toolboxScroll.querySelectorAll('button');
273
+ let toolboxScrollWidth = 0;
274
+ toolboxTabs.forEach((tab) => {
275
+ toolboxScrollWidth += tab.offsetWidth; // 获取按钮宽度并累加
276
+ });
277
+ function adjustScrollShadow() {
278
+ if (toolboxScroll.scrollLeft > 0) {
279
+ toolboxScroll.classList.add('scroll-shadow-left');
280
+ } else {
281
+ toolboxScroll.classList.remove('scroll-shadow-left');
282
+ }
283
+
284
+ if (toolboxScroll.scrollLeft + toolboxScroll.clientWidth < toolboxScrollWidth) {
285
+ toolboxScroll.classList.add('scroll-shadow-right');
286
+ } else {
287
+ toolboxScroll.classList.remove('scroll-shadow-right');
288
+ }
289
+ }
290
+ toolboxScroll.addEventListener('scroll', () => {
291
+ adjustScrollShadow();
292
+ });
293
+ // no, I failed to make shadow appear on the top layer...
294
+ }
295
+
296
+ function setPopupBoxPosition() {
297
+ const screenWidth = window.innerWidth;
298
+ const screenHeight = window.innerHeight;
299
+ popupWrapper.style.height = `${screenHeight}px`;
300
+ popupWrapper.style.width = `${screenWidth}px`;
301
+ // const popupBoxWidth = 680;
302
+ // const popupBoxHeight = 400;
303
+ // chuanhuPopup.style.left = `${(screenWidth - popupBoxWidth) / 2}px`;
304
+ // chuanhuPopup.style.top = `${(screenHeight - popupBoxHeight) / 2}px`;
305
+ }
306
+
307
+ function updateVH() {
308
+ const vh = window.innerHeight * 0.01;
309
+ document.documentElement.style.setProperty('--vh', `${vh}px`);
310
+ }
311
+
312
+ function setChatbotHeight() {
313
+ return;
314
+ const screenWidth = window.innerWidth;
315
+ const statusDisplay = document.querySelector('#status-display');
316
+ const statusDisplayHeight = statusDisplay ? statusDisplay.offsetHeight : 0;
317
+ const vh = window.innerHeight * 0.01;
318
+ document.documentElement.style.setProperty('--vh', `${vh}px`);
319
+ if (isInIframe) {
320
+ chatbot.style.height = `700px`;
321
+ chatbotWrap.style.maxHeight = `calc(700px - var(--line-sm) * 1rem - 2 * var(--block-label-margin))`
322
+ } else {
323
+ if (screenWidth <= 320) {
324
+ chatbot.style.height = `calc(var(--vh, 1vh) * 100 - ${statusDisplayHeight + 150}px)`;
325
+ chatbotWrap.style.maxHeight = `calc(var(--vh, 1vh) * 100 - ${statusDisplayHeight + 150}px - var(--line-sm) * 1rem - 2 * var(--block-label-margin))`;
326
+ } else if (screenWidth <= 499) {
327
+ chatbot.style.height = `calc(var(--vh, 1vh) * 100 - ${statusDisplayHeight + 100}px)`;
328
+ chatbotWrap.style.maxHeight = `calc(var(--vh, 1vh) * 100 - ${statusDisplayHeight + 100}px - var(--line-sm) * 1rem - 2 * var(--block-label-margin))`;
329
+ } else {
330
+ chatbot.style.height = `calc(var(--vh, 1vh) * 100 - ${statusDisplayHeight + 160}px)`;
331
+ chatbotWrap.style.maxHeight = `calc(var(--vh, 1vh) * 100 - ${statusDisplayHeight + 160}px - var(--line-sm) * 1rem - 2 * var(--block-label-margin))`;
332
+ }
333
+ }
334
+ }
335
+ function setChatbotScroll() {
336
+ var scrollHeight = chatbotWrap.scrollHeight;
337
+ chatbotWrap.scrollTo(0,scrollHeight)
338
+ }
339
+
340
+ function setAutocomplete() {
341
+ // 避免API Key被当成密码导致的模型下拉框被当成用户名而引发的浏览器自动填充行为
342
+ const apiKeyInput = gradioApp().querySelector("#api-key input");
343
+ apiKeyInput.setAttribute("autocomplete", "new-password");
344
+ }
345
+
346
+ function clearChatbot(a, b) {
347
+ clearHistoryHtml();
348
+ // clearMessageRows();
349
+ return [a, b]
350
+ }
351
+
352
+ function chatbotContentChanged(attempt = 1, force = false) {
353
+ for (var i = 0; i < attempt; i++) {
354
+ setTimeout(() => {
355
+ // clearMessageRows();
356
+ saveHistoryHtml();
357
+ disableSendBtn();
358
+ updateSlider();
359
+ updateCheckboxes();
360
+ bindFancyBox();
361
+
362
+ gradioApp().querySelectorAll('#chuanhu-chatbot .message-wrap .message.bot').forEach(addChuanhuButton);
363
+
364
+ if (chatbotIndicator.classList.contains('hide')) { // generation finished
365
+ setLatestMessage();
366
+ setChatList();
367
+ }
368
+
369
+ if (!chatbotIndicator.classList.contains('translucent')) { // message deleted
370
+ var checkLatestAdded = setInterval(() => {
371
+ var latestMessageNow = gradioApp().querySelector('#chuanhu-chatbot > .wrapper > .wrap > .message-wrap .message.bot.latest');
372
+ if (latestMessageNow && latestMessageNow.querySelector('.message-btn-row')) {
373
+ clearInterval(checkLatestAdded);
374
+ } else {
375
+ setLatestMessage();
376
+ }
377
+ }, 200);
378
+ }
379
+
380
+
381
+ }, i === 0 ? 0 : 200);
382
+ }
383
+ // 理论上是不需要多次尝试执行的,可惜gradio的bug导致message可能没有渲染完毕,所以尝试500ms后再次执行
384
+ }
385
+
386
+ var chatbotObserver = new MutationObserver(() => {
387
+ chatbotContentChanged(1);
388
+ if (chatbotIndicator.classList.contains('hide')) {
389
+ // setLatestMessage();
390
+ chatbotContentChanged(2);
391
+ }
392
+ if (!chatbotIndicator.classList.contains('translucent')) {
393
+ chatbotContentChanged(2);
394
+ }
395
+
396
+ });
397
+
398
+ var chatListObserver = new MutationObserver(() => {
399
+ setChatList();
400
+ });
401
+
402
+ // 监视页面内部 DOM 变动
403
+ var gradioObserver = new MutationObserver(function (mutations) {
404
+ for (var i = 0; i < mutations.length; i++) {
405
+ if (mutations[i].addedNodes.length) {
406
+ if (addInit()) {
407
+ gradioObserver.disconnect();
408
+ return;
409
+ }
410
+ }
411
+ }
412
+ });
413
+
414
+ // 监视页面变化
415
+ window.addEventListener("DOMContentLoaded", function () {
416
+ // const ga = document.getElementsByTagName("gradio-app");
417
+ updateVH();
418
+ windowWidth = window.innerWidth;
419
+ gradioApp().addEventListener("render", initialize);
420
+ isInIframe = (window.self !== window.top);
421
+ historyLoaded = false;
422
+ });
423
+ window.addEventListener('resize', ()=>{
424
+ // setChatbotHeight();
425
+ updateVH();
426
+ windowWidth = window.innerWidth;
427
+ setPopupBoxPosition();
428
+ adjustSide();
429
+ });
430
+ window.addEventListener('orientationchange', (event) => {
431
+ updateVH();
432
+ windowWidth = window.innerWidth;
433
+ setPopupBoxPosition();
434
+ adjustSide();
435
+ });
436
+ window.addEventListener('scroll', ()=>{setPopupBoxPosition();});
437
+ window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", adjustDarkMode);
438
+
439
+ // console suprise
440
+ var styleTitle1 = `
441
+ font-size: 16px;
442
+ font-family: ui-monospace, monospace;
443
+ color: #06AE56;
444
+ `
445
+ var styleDesc1 = `
446
+ font-size: 12px;
447
+ font-family: ui-monospace, monospace;
448
+ `
449
+ function makeML(str) {
450
+ let l = new String(str)
451
+ l = l.substring(l.indexOf("/*") + 3, l.lastIndexOf("*/"))
452
+ return l
453
+ }
454
+ let ChuanhuInfo = function () {
455
+ /* chatgpt-webui - GUI for ChatGPT API */
456
+ }
457
+ let description = `
458
+ © 2023 shibing624
459
+ GitHub repository: [https://github.com/shibing624/chatgpt-webui]\n
460
+ Enjoy our project!\n
461
+ `
462
+ console.log(`%c${makeML(ChuanhuInfo)}`,styleTitle1);
463
+ console.log(`%c${description}`, styleDesc1);
assets/javascript/Kelpy-Codos.js ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // ==UserScript==
2
+ // @name Kelpy Codos
3
+ // @namespace https://github.com/Keldos-Li/Kelpy-Codos
4
+ // @version 1.0.5
5
+ // @author Keldos; https://keldos.me/
6
+ // @description Add copy button to PRE tags before CODE tag, for Chuanhu ChatGPT especially.
7
+ // Based on Chuanhu ChatGPT version: ac04408 (2023-3-22)
8
+ // @license GPL-3.0
9
+ // @grant none
10
+ // ==/UserScript==
11
+
12
+ (function () {
13
+ 'use strict';
14
+
15
+ function addCopyButton(pre) {
16
+ var code = pre.querySelector('code');
17
+ if (!code) {
18
+ return; // 如果没有找到 <code> 元素,则不添加按钮
19
+ }
20
+ var firstChild = code.firstChild;
21
+ if (!firstChild) {
22
+ return; // 如果 <code> 元素没有子节点,则不添加按钮
23
+ }
24
+ var button = document.createElement('button');
25
+ button.textContent = '\uD83D\uDCCE'; // 使用 📎 符号作为“复制”按钮的文本
26
+ button.style.position = 'relative';
27
+ button.style.float = 'right';
28
+ button.style.fontSize = '1em'; // 可选:调整按钮大小
29
+ button.style.background = 'none'; // 可选:去掉背景颜色
30
+ button.style.border = 'none'; // 可选:去掉边框
31
+ button.style.cursor = 'pointer'; // 可选:显示指针样式
32
+ button.addEventListener('click', function () {
33
+ var range = document.createRange();
34
+ range.selectNodeContents(code);
35
+ range.setStartBefore(firstChild); // 将范围设置为第一个子节点之前
36
+ var selection = window.getSelection();
37
+ selection.removeAllRanges();
38
+ selection.addRange(range);
39
+
40
+ try {
41
+ var success = document.execCommand('copy');
42
+ if (success) {
43
+ button.textContent = '\u2714';
44
+ setTimeout(function () {
45
+ button.textContent = '\uD83D\uDCCE'; // 恢复按钮为“复制”
46
+ }, 2000);
47
+ } else {
48
+ button.textContent = '\u2716';
49
+ }
50
+ } catch (e) {
51
+ console.error(e);
52
+ button.textContent = '\u2716';
53
+ }
54
+
55
+ selection.removeAllRanges();
56
+ });
57
+ code.insertBefore(button, firstChild); // 将按钮插入到第一个子元素之前
58
+ }
59
+
60
+ function handleNewElements(mutationsList, observer) {
61
+ for (var mutation of mutationsList) {
62
+ if (mutation.type === 'childList') {
63
+ for (var node of mutation.addedNodes) {
64
+ if (node.nodeName === 'PRE') {
65
+ addCopyButton(node);
66
+ }
67
+ }
68
+ }
69
+ }
70
+ }
71
+
72
+ var observer = new MutationObserver(handleNewElements);
73
+ observer.observe(document.documentElement, { childList: true, subtree: true });
74
+
75
+ document.querySelectorAll('pre').forEach(addCopyButton);
76
+ })();
assets/javascript/chat-history.js ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ var historyLoaded = false;
3
+ var loadhistorytime = 0; // for debugging
4
+
5
+
6
+ function saveHistoryHtml() {
7
+ var historyHtml = document.querySelector('#chuanhu-chatbot>.wrapper>.wrap');
8
+ if (!historyHtml) return; // no history, do nothing
9
+ localStorage.setItem('chatHistory', historyHtml.innerHTML);
10
+ // console.log("History Saved")
11
+ historyLoaded = false;
12
+ }
13
+
14
+ function loadHistoryHtml() {
15
+ var historyHtml = localStorage.getItem('chatHistory');
16
+ const tempDiv = document.createElement('div');
17
+ tempDiv.innerHTML = historyHtml;
18
+ if (!historyHtml || tempDiv.innerText.trim() === "") {
19
+ historyLoaded = true;
20
+ return; // no history, do nothing
21
+ }
22
+ userLogged = localStorage.getItem('userLogged');
23
+ hideHistoryWhenNotLoggedIn = gradioApp().querySelector('#hideHistoryWhenNotLoggedIn_config').innerText === "True";
24
+ if (userLogged || (!userLogged && !hideHistoryWhenNotLoggedIn)){
25
+ historyLoaded = true;
26
+ return; // logged in, do nothing. OR, not logged in but not hide history list, do nothing.
27
+ }
28
+
29
+ // 只有用户未登录,还隐藏历史记录列表时,才选用只读历史记录
30
+ if (!historyLoaded) {
31
+ // preprocess, gradio buttons in history lost their event listeners
32
+ var gradioCopyButtons = tempDiv.querySelectorAll('button.copy_code_button');
33
+ for (var i = 0; i < gradioCopyButtons.length; i++) {
34
+ gradioCopyButtons[i].parentNode.removeChild(gradioCopyButtons[i]);
35
+ }
36
+ var messageBtnRows = tempDiv.querySelectorAll('.message-btn-row');
37
+ for (var i = 0; i < messageBtnRows.length; i++) {
38
+ messageBtnRows[i].parentNode.removeChild(messageBtnRows[i]);
39
+ }
40
+ var latestMessages = tempDiv.querySelectorAll('.message.latest');
41
+ for (var i = 0; i < latestMessages.length; i++) {
42
+ latestMessages[i].classList.remove('latest');
43
+ }
44
+
45
+ var fakeHistory = document.createElement('div');
46
+ fakeHistory.classList.add('history-message');
47
+ fakeHistory.innerHTML = tempDiv.innerHTML;
48
+ const forViewStyle = document.createElement('style');
49
+ forViewStyle.innerHTML = '.wrapper>.wrap>.history-message>:last-child::after { content: "' + i18n(forView_i18n) + '"!important; }';
50
+ document.head.appendChild(forViewStyle);
51
+ chatbotWrap.insertBefore(fakeHistory, chatbotWrap.firstChild);
52
+ // var fakeHistory = document.createElement('div');
53
+ // fakeHistory.classList.add('history-message');
54
+ // fakeHistory.innerHTML = historyHtml;
55
+ // chatbotWrap.insertBefore(fakeHistory, chatbotWrap.firstChild);
56
+ historyLoaded = true;
57
+ // console.log("History Loaded");
58
+ loadhistorytime += 1; // for debugging
59
+ } else {
60
+ historyLoaded = false;
61
+ }
62
+ }
63
+
64
+ function clearHistoryHtml() {
65
+ localStorage.removeItem("chatHistory");
66
+ historyMessages = chatbotWrap.querySelector('.history-message');
67
+ if (historyMessages) {
68
+ chatbotWrap.removeChild(historyMessages);
69
+ console.log("History Cleared");
70
+ }
71
+ }
assets/javascript/chat-list.js ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ var currentChatName = null;
3
+
4
+ function setChatListHeader() {
5
+ var grHistoryRefreshBtn = gradioApp().querySelector('button#gr-history-refresh-btn');
6
+ var grHistoryUploadBtn = gradioApp().querySelector('button#gr-history-upload-btn');
7
+
8
+ grHistoryRefreshBtn.className = "";
9
+ grHistoryUploadBtn.className = "";
10
+
11
+
12
+ grHistoryRefreshBtn.innerHTML = HistoryRefreshIcon;
13
+ grHistoryUploadBtn.innerHTML = HistoryUploadIcon;
14
+ }
15
+
16
+ function setChatList() {
17
+ var selectedChat = null;
18
+ var chatList = gradioApp().querySelector('fieldset#history-select-dropdown');
19
+ selectedChat = chatList.querySelector(".wrap label.selected")
20
+ if (!selectedChat) {
21
+ currentChatName = null;
22
+ return;
23
+ }
24
+
25
+ // if (userLogged) {
26
+ // currentChatName = username + "/" + selectedChat.querySelector('span').innerText;
27
+ // } else {
28
+ currentChatName = selectedChat.querySelector('span').innerText;
29
+ // }
30
+
31
+ if (selectedChat.classList.contains('added-chat-btns')) {
32
+ return;
33
+ }
34
+
35
+ chatList.querySelector('.chat-selected-btns')?.remove(); // remove old buttons
36
+ chatList.querySelectorAll('.added-chat-btns').forEach(chat => chat.classList.remove('added-chat-btns'));
37
+
38
+ var ChatSelectedBtns = document.createElement('div');
39
+ ChatSelectedBtns.classList.add('chat-selected-btns');
40
+ selectedChat.classList.add('added-chat-btns');
41
+ ChatSelectedBtns.innerHTML = selectedChatBtns;
42
+
43
+ var renameBtn = ChatSelectedBtns.querySelector('#history-rename-btn');
44
+ renameBtn.addEventListener('click', function () {
45
+ gradioApp().querySelector('#gr-history-save-btn').click();
46
+ });
47
+
48
+ var deleteBtn = ChatSelectedBtns.querySelector('#history-delete-btn');
49
+ deleteBtn.addEventListener('click', function () {
50
+ gradioApp().querySelector('#gr-history-delete-btn').click();
51
+ });
52
+ selectedChat.appendChild(ChatSelectedBtns);
53
+
54
+ return;
55
+ }
56
+
57
+
58
+ function saveChatHistory(a, b, c, d) {
59
+ var fileName = b;
60
+
61
+ while (true) {
62
+ var result = prompt(renameChat_i18n, fileName);
63
+
64
+ if (result === null) {
65
+ throw new Error("rename operation cancelled");
66
+ // 不返回原文件名,而是使用 throw new Error() 打断程序,避免 gradio 进行保存操作
67
+ // break;
68
+ } else if (isValidFileName(result)) {
69
+ return [a, result, c, d];
70
+ } else {
71
+ alert(validFileName_i18n + "!@#$%^&*()<>?/\\|}{~:");
72
+ }
73
+ }
74
+ return [a, b, c, d]; // 兜底保障
75
+ }
76
+
77
+ function isValidFileName(fileName) {
78
+ // 使用正则表达式来检查文件名是否包含不合格字符
79
+ var regex = /[!@#$%^&*()<>?/\\|}{~:]/;
80
+ return !regex.test(fileName) && fileName.trim() !== "";
81
+ }
82
+
83
+ const selectedChatBtns = `
84
+ <button id="history-rename-btn"><svg class="icon-need-hover" stroke="currentColor" fill="none" stroke-width="2" height="18px" width="18px" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><path d="M12 20h9"></path><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"></path></svg></button>
85
+ <button id="history-delete-btn"><svg class="icon-need-hover" stroke="currentColor" fill="none" stroke-width="2" height="18px" width="18px" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path><line x1="10" y1="11" x2="10" y2="17"></line><line x1="14" y1="11" x2="14" y2="17"></line></svg></button>
86
+ `
87
+ const HistoryRefreshIcon = '<svg class="icon-need-hover" width="18px" height="18px" viewBox="0 0 16.3594 21.9258 " version="1.1" xmlns="http://www.w3.org/2000/svg"><g><path d="M0 11.6367C0 16.1836 3.65625 19.8398 8.17969 19.8398C12.7031 19.8398 16.3594 16.1836 16.3594 11.6367C16.3594 11.1328 16.0078 10.7695 15.4805 10.7695C14.9883 10.7695 14.6719 11.1328 14.6719 11.6367C14.6719 15.2461 11.7773 18.1406 8.17969 18.1406C4.59376 18.1406 1.6875 15.2461 1.6875 11.6367C1.6875 8.03906 4.59376 5.14452 8.17969 5.14452C8.80079 5.14452 9.33985 5.17968 9.83202 5.28516L7.35937 7.72265C7.19531 7.88671 7.11328 8.09765 7.11328 8.30858C7.11328 8.78906 7.47657 9.15235 7.94531 9.15235C8.20312 9.15235 8.40234 9.07032 8.54296 8.91797L12.2578 5.21484C12.4219 5.05078 12.4922 4.85155 12.4922 4.60546C12.4922 4.38281 12.4102 4.16016 12.2578 4.00781L8.54296 0.257808C8.40234 0.093744 8.19141 0 7.9336 0C7.47657 0 7.11328 0.386712 7.11328 0.867192C7.11328 1.08984 7.19531 1.30078 7.34766 1.46484L9.49218 3.57422C9.07031 3.49219 8.62499 3.45703 8.17969 3.45703C3.65625 3.45703 0 7.10155 0 11.6367Z" fill="currentColor"/></g></svg>';
88
+ const HistoryUploadIcon = '<svg class="icon-need-hover" width="18px" height="18px" viewBox="0 0 21.0234 19.5352" version="1.1" xmlns="http://www.w3.org/2000/svg"><g fill="currentColor"><path d="M4.03125 19.5352C5.34375 19.5352 8.01562 18.1758 9.90234 16.7812C16.4531 16.8281 21.0234 13.1016 21.0234 8.40234C21.0234 3.75 16.3477 0 10.5117 0C4.6875 0 0 3.75 0 8.40234C0 11.4258 1.93359 14.1211 4.83984 15.4336C4.41797 16.2539 3.62109 17.4141 3.19922 17.9766C2.69531 18.6445 3.01172 19.5352 4.03125 19.5352ZM5.17969 17.7891C5.10938 17.8242 5.08594 17.7656 5.13281 17.707C5.67188 17.0391 6.38672 16.0547 6.69141 15.5156C6.98438 14.9883 6.91406 14.4961 6.23438 14.1797C3.35156 12.8438 1.73438 10.7695 1.73438 8.40234C1.73438 4.73438 5.625 1.73438 10.5117 1.73438C15.4102 1.73438 19.2891 4.73438 19.2891 8.40234C19.2891 12.0586 15.4102 15.0586 10.5117 15.0586C10.3945 15.0586 10.1602 15.0586 9.82031 15.0586C9.38672 15.0586 9.05859 15.1992 8.67188 15.5156C7.65234 16.3125 6.03516 17.3789 5.17969 17.7891Z"/><path d="M10.5234 13.1133C10.9805 13.1133 11.3086 12.7969 11.3086 12.3398L11.3086 8.20312L11.2266 6.10547L12.0938 7.19531L13.0312 8.15625C13.1719 8.30859 13.3594 8.37891 13.5938 8.37891C14.0156 8.37891 14.3555 8.05078 14.3555 7.62891C14.3555 7.41797 14.2734 7.21875 14.1445 7.08984L11.1445 4.10156C10.9453 3.90234 10.7578 3.79688 10.5234 3.79688C10.3008 3.79688 10.125 3.89062 9.91406 4.10156L6.91406 7.08984C6.77344 7.21875 6.70312 7.41797 6.70312 7.62891C6.70312 8.05078 7.03125 8.37891 7.46484 8.37891C7.6875 8.37891 7.875 8.29688 8.01562 8.15625L8.96484 7.19531L9.82031 6.11719L9.75 8.20312L9.75 12.3398C9.75 12.7969 10.0781 13.1133 10.5234 13.1133Z"/></g></svg>';
assets/javascript/external-scripts.js ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+
2
+ // external javascript here
assets/javascript/fake-gradio.js ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ // Fake gradio components!
3
+
4
+ // buttons
5
+ function newChatClick() {
6
+ gradioApp().querySelector('#empty-btn').click();
7
+ }
8
+ function jsonDownloadClick() {
9
+ gradioApp().querySelector('#gr-history-download-btn').click();
10
+ }
11
+ function mdDownloadClick() {
12
+ gradioApp().querySelector('#gr-markdown-export-btn').click();
13
+ gradioApp().querySelector('#gr-history-mardown-download-btn').click();
14
+
15
+ // downloadHistory(username, currentChatName, ".md");
16
+ }
17
+
18
+ // index files
19
+ function setUploader() {
20
+ transUpload();
21
+ var uploaderObserver = new MutationObserver(function (mutations) {
22
+ var fileInput = null;
23
+ var fileCount = 0;
24
+ fileInput = gradioApp().querySelector("#upload-index-file table.file-preview");
25
+ var fileCountSpan = gradioApp().querySelector("#uploaded-files-count");
26
+ if (fileInput) {
27
+ chatbotArea.classList.add('with-file');
28
+ fileCount = fileInput.querySelectorAll('tbody > tr.file').length;
29
+ fileCountSpan.innerText = fileCount;
30
+ } else {
31
+ chatbotArea.classList.remove('with-file');
32
+ statusDisplayMessage("");
33
+ fileCount = 0;
34
+ transUpload();
35
+ }
36
+ });
37
+ uploaderObserver.observe(uploaderIndicator, {attributes: true})
38
+ }
39
+ var grUploader;
40
+ var chatbotUploader;
41
+ var handleClick = function() {
42
+ grUploader.click();
43
+
44
+ };
45
+ function transUpload() {
46
+ chatbotUploader = gradioApp().querySelector("#upload-files-btn");
47
+ chatbotUploader.removeEventListener('click', handleClick);
48
+ grUploader = gradioApp().querySelector("#upload-index-file > .center.flex");
49
+
50
+ // let uploaderEvents = ["click", "drag", "dragend", "dragenter", "dragleave", "dragover", "dragstart", "drop"];
51
+ // transEventListeners(chatbotUploader, grUploader, uploaderEvents);
52
+
53
+ chatbotUploader.addEventListener('click', handleClick);
54
+ }
55
+
56
+ // checkbox
57
+ var grSingleSessionCB;
58
+ var grOnlineSearchCB;
59
+ var chatbotSingleSessionCB;
60
+ var chatbotOnlineSearchCB;
61
+ function setCheckboxes() {
62
+ chatbotSingleSessionCB = gradioApp().querySelector('input[name="single-session-cb"]');
63
+ chatbotOnlineSearchCB = gradioApp().querySelector('input[name="online-search-cb"]');
64
+ grSingleSessionCB = gradioApp().querySelector("#gr-single-session-cb > label > input");
65
+ grOnlineSearchCB = gradioApp().querySelector("#gr-websearch-cb > label> input");
66
+
67
+ chatbotSingleSessionCB.addEventListener('change', (e) => {
68
+ grSingleSessionCB.checked = chatbotSingleSessionCB.checked;
69
+ gradioApp().querySelector('#change-single-session-btn').click();
70
+ });
71
+ chatbotOnlineSearchCB.addEventListener('change', (e) => {
72
+ grOnlineSearchCB.checked = chatbotOnlineSearchCB.checked;
73
+ gradioApp().querySelector('#change-online-search-btn').click();
74
+ });
75
+ grSingleSessionCB.addEventListener('change', (e) => {
76
+ chatbotSingleSessionCB.checked = grSingleSessionCB.checked;
77
+ });
78
+ grOnlineSearchCB.addEventListener('change', (e) => {
79
+ chatbotOnlineSearchCB.checked = grOnlineSearchCB.checked;
80
+ });
81
+ }
82
+
83
+ function bgChangeSingleSession() {
84
+ // const grSingleSessionCB = gradioApp().querySelector("#gr-single-session-cb > label > input");
85
+ let a = chatbotSingleSessionCB.checked;
86
+ return [a];
87
+ }
88
+ function bgChangeOnlineSearch() {
89
+ // const grOnlineSearchCB = gradioApp().querySelector("#gr-websearch-cb > label> input");
90
+ let a = chatbotOnlineSearchCB.checked;
91
+ return [a];
92
+ }
93
+
94
+ function updateCheckboxes() {
95
+ chatbotSingleSessionCB.checked = grSingleSessionCB.checked;
96
+ chatbotOnlineSearchCB.checked = grOnlineSearchCB.checked;
97
+ }
98
+
99
+ // UTILS
100
+ function transEventListeners(target, source, events) {
101
+ events.forEach((sourceEvent) => {
102
+ target.addEventListener(sourceEvent, function (targetEvent) {
103
+ if(targetEvent.preventDefault) targetEvent.preventDefault();
104
+ if(targetEvent.stopPropagation) targetEvent.stopPropagation();
105
+
106
+ source.dispatchEvent(new Event(sourceEvent, {detail: targetEvent.detail}));
107
+ // console.log(targetEvent.detail);
108
+ });
109
+ });
110
+ }
111
+
112
+ function bgSelectHistory(a,b){
113
+ const historySelectorInput = gradioApp().querySelector('#history-select-dropdown input');
114
+ let file = historySelectorInput.value;
115
+ return [a,file]
116
+ }
assets/javascript/file-input.js ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ // paste和upload部分参考:
3
+ // https://github.com/binary-husky/gpt_academic/tree/master/themes/common.js
4
+ // @Kilig947
5
+
6
+
7
+ function setPasteUploader() {
8
+ input = user_input_tb.querySelector("textarea")
9
+ let paste_files = [];
10
+ if (input) {
11
+ input.addEventListener("paste", async function (e) {
12
+ const clipboardData = e.clipboardData || window.clipboardData;
13
+ const items = clipboardData.items;
14
+ if (items) {
15
+ for (i = 0; i < items.length; i++) {
16
+ if (items[i].kind === "file") { // 确保是文件类型
17
+ const file = items[i].getAsFile();
18
+ // 将每一个粘贴的文件添加到files数组中
19
+ paste_files.push(file);
20
+ e.preventDefault(); // 避免粘贴文件名到输入框
21
+ }
22
+ }
23
+ if (paste_files.length > 0) {
24
+ // 按照文件列表执行批量上传逻辑
25
+ await upload_files(paste_files);
26
+ paste_files = [];
27
+ }
28
+ }
29
+ });
30
+ }
31
+ }
32
+
33
+ var hintArea;
34
+ function setDragUploader() {
35
+ input = chatbotArea;
36
+ if (input) {
37
+ const dragEvents = ["dragover", "dragenter"];
38
+ const leaveEvents = ["dragleave", "dragend", "drop"];
39
+
40
+ const onDrag = function (e) {
41
+ e.preventDefault();
42
+ e.stopPropagation();
43
+ if (!chatbotArea.classList.contains("with-file")) {
44
+ chatbotArea.classList.add("dragging");
45
+ draggingHint();
46
+ } else {
47
+ statusDisplayMessage(clearFileHistoryMsg_i18n, 2000);
48
+ }
49
+ };
50
+
51
+ const onLeave = function (e) {
52
+ e.preventDefault();
53
+ e.stopPropagation();
54
+ chatbotArea.classList.remove("dragging");
55
+ if (hintArea) {
56
+ hintArea.remove();
57
+ }
58
+ };
59
+
60
+ dragEvents.forEach(event => {
61
+ input.addEventListener(event, onDrag);
62
+ });
63
+
64
+ leaveEvents.forEach(event => {
65
+ input.addEventListener(event, onLeave);
66
+ });
67
+
68
+ input.addEventListener("drop", async function (e) {
69
+ const files = e.dataTransfer.files;
70
+ await upload_files(files);
71
+ });
72
+ }
73
+ }
74
+
75
+ async function upload_files(files) {
76
+ const uploadInputElement = gradioApp().querySelector("#upload-index-file > .center.flex input[type=file]");
77
+ let totalSizeMb = 0
78
+ if (files && files.length > 0) {
79
+ // 执行具体的上传逻辑
80
+ if (uploadInputElement) {
81
+ for (let i = 0; i < files.length; i++) {
82
+ // 将从文件数组中获取的文件大小(单位为字节)转换为MB,
83
+ totalSizeMb += files[i].size / 1024 / 1024;
84
+ }
85
+ // 检查文件总大小是否超过20MB
86
+ if (totalSizeMb > 20) {
87
+ // toast_push('⚠️文件夹大于20MB 🚀上传文件中', 2000)
88
+ // return; // 如果超过了指定大小, 可以不进行后续上传操作
89
+ }
90
+ // 监听change事件, 原生Gradio可以实现
91
+ // uploadInputElement.addEventListener('change', function(){replace_input_string()});
92
+ let event = new Event("change");
93
+ Object.defineProperty(event, "target", {value: uploadInputElement, enumerable: true});
94
+ Object.defineProperty(event, "currentTarget", {value: uploadInputElement, enumerable: true});
95
+ Object.defineProperty(uploadInputElement, "files", {value: files, enumerable: true});
96
+ uploadInputElement.dispatchEvent(event);
97
+ // statusDisplayMessage("");
98
+ } else {
99
+ statusDisplayMessage(clearFileHistoryMsg_i18n, 3000);
100
+ return;
101
+ }
102
+ }
103
+ }
104
+
105
+ function draggingHint() {
106
+ hintArea = chatbotArea.querySelector(".dragging-hint");
107
+ if (hintArea) {
108
+ return;
109
+ }
110
+ hintArea = document.createElement("div");
111
+ hintArea.classList.add("dragging-hint");
112
+ hintArea.innerHTML = `<div class="dragging-hint-text"><p>${dropUploadMsg_i18n}</p></div>`;
113
+ chatbotArea.appendChild(hintArea);
114
+ }
assets/javascript/localization.js ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ // i18n
3
+
4
+ const language = navigator.language.slice(0,2);
5
+
6
+ var forView_i18n;
7
+ var deleteConfirm_i18n_pref;
8
+ var deleteConfirm_i18n_suff;
9
+ var usingLatest_i18n;
10
+ var updatingMsg_i18n;
11
+ var updateSuccess_i18n;
12
+ var updateFailure_i18n;
13
+ var regenerate_i18n;
14
+ var deleteRound_i18n;
15
+ var renameChat_i18n;
16
+ var validFileName_i18n;
17
+ var clearFileHistoryMsg_i18n;
18
+ var dropUploadMsg_i18n;
19
+
20
+ function setLoclize() {
21
+ forView_i18n = gradioApp().querySelector('#forView_i18n').innerText;
22
+ deleteConfirm_i18n_pref = gradioApp().querySelector('#deleteConfirm_i18n_pref').innerText;
23
+ deleteConfirm_i18n_suff = gradioApp().querySelector('#deleteConfirm_i18n_suff').innerText;
24
+ usingLatest_i18n = gradioApp().querySelector('#usingLatest_i18n').innerText;
25
+ updatingMsg_i18n = gradioApp().querySelector('#updatingMsg_i18n').innerText;
26
+ updateSuccess_i18n = gradioApp().querySelector('#updateSuccess_i18n').innerText;
27
+ updateFailure_i18n = gradioApp().querySelector('#updateFailure_i18n').innerText;
28
+ regenerate_i18n = gradioApp().querySelector('#regenerate_i18n').innerText;
29
+ deleteRound_i18n = gradioApp().querySelector('#deleteRound_i18n').innerText;
30
+ renameChat_i18n = gradioApp().querySelector('#renameChat_i18n').innerText;
31
+ validFileName_i18n = gradioApp().querySelector('#validFileName_i18n').innerText;
32
+ clearFileHistoryMsg_i18n = gradioApp().querySelector('#clearFileHistoryMsg_i18n').innerText;
33
+ dropUploadMsg_i18n = gradioApp().querySelector('#dropUploadMsg_i18n').innerText;
34
+ }
35
+
36
+ function i18n(msg) {
37
+ return msg;
38
+ // return msg.hasOwnProperty(language) ? msg[language] : msg['en'];
39
+ }
assets/javascript/message-button.js ADDED
@@ -0,0 +1,195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ // 为 bot 消息添加复制与切换显示按钮 以及最新消息加上重新生成,删除最新消息,嗯。
3
+
4
+ function addChuanhuButton(botElement) {
5
+
6
+ // botElement = botRow.querySelector('.message.bot');
7
+ var isLatestMessage = botElement.classList.contains('latest');
8
+
9
+ var rawMessage = botElement.querySelector('.raw-message');
10
+ var mdMessage = botElement.querySelector('.md-message');
11
+
12
+ if (!rawMessage) { // 如果没有 raw message,说明是早期历史记录,去除按钮
13
+ // var buttons = botElement.querySelectorAll('button.chuanhu-btn');
14
+ // for (var i = 0; i < buttons.length; i++) {
15
+ // buttons[i].parentNode.removeChild(buttons[i]);
16
+ // }
17
+ botElement.querySelector('.message-btn-row')?.remove();
18
+ botElement.querySelector('.message-btn-column')?.remove();
19
+ return;
20
+ }
21
+ // botElement.querySelectorAll('button.copy-bot-btn, button.toggle-md-btn').forEach(btn => btn.remove()); // 就算原先有了,也必须重新添加,而不是跳过
22
+ if (!isLatestMessage) botElement.querySelector('.message-btn-row')?.remove();
23
+ botElement.querySelector('.message-btn-column')?.remove();
24
+
25
+ // Copy bot button
26
+ var copyButton = document.createElement('button');
27
+ copyButton.classList.add('chuanhu-btn');
28
+ copyButton.classList.add('copy-bot-btn');
29
+ copyButton.setAttribute('aria-label', 'Copy');
30
+ copyButton.innerHTML = copyIcon;
31
+
32
+ copyButton.addEventListener('click', async () => {
33
+ const textToCopy = rawMessage.innerText;
34
+ try {
35
+ if ("clipboard" in navigator) {
36
+ await navigator.clipboard.writeText(textToCopy);
37
+ copyButton.innerHTML = copiedIcon;
38
+ setTimeout(() => {
39
+ copyButton.innerHTML = copyIcon;
40
+ }, 1500);
41
+ } else {
42
+ const textArea = document.createElement("textarea");
43
+ textArea.value = textToCopy;
44
+ document.body.appendChild(textArea);
45
+ textArea.select();
46
+ try {
47
+ document.execCommand('copy');
48
+ copyButton.innerHTML = copiedIcon;
49
+ setTimeout(() => {
50
+ copyButton.innerHTML = copyIcon;
51
+ }, 1500);
52
+ } catch (error) {
53
+ console.error("Copy failed: ", error);
54
+ }
55
+ document.body.removeChild(textArea);
56
+ }
57
+ } catch (error) {
58
+ console.error("Copy failed: ", error);
59
+ }
60
+ });
61
+ // botElement.appendChild(copyButton);
62
+
63
+ // Toggle button
64
+ var toggleButton = document.createElement('button');
65
+ toggleButton.classList.add('chuanhu-btn');
66
+ toggleButton.classList.add('toggle-md-btn');
67
+ toggleButton.setAttribute('aria-label', 'Toggle');
68
+ var renderMarkdown = mdMessage.classList.contains('hideM');
69
+ toggleButton.innerHTML = renderMarkdown ? mdIcon : rawIcon;
70
+ toggleButton.addEventListener('click', () => {
71
+ renderMarkdown = mdMessage.classList.contains('hideM');
72
+ if (renderMarkdown) {
73
+ renderMarkdownText(botElement);
74
+ toggleButton.innerHTML=rawIcon;
75
+ } else {
76
+ removeMarkdownText(botElement);
77
+ toggleButton.innerHTML=mdIcon;
78
+ }
79
+ chatbotContentChanged(1); // to set md or raw in read-only history html
80
+ });
81
+ // botElement.insertBefore(toggleButton, copyButton);
82
+
83
+ var messageBtnColumn = document.createElement('div');
84
+ messageBtnColumn.classList.add('message-btn-column');
85
+ messageBtnColumn.appendChild(toggleButton);
86
+ messageBtnColumn.appendChild(copyButton);
87
+ botElement.appendChild(messageBtnColumn);
88
+
89
+ function renderMarkdownText(message) {
90
+ var mdDiv = message.querySelector('.md-message');
91
+ if (mdDiv) mdDiv.classList.remove('hideM');
92
+ var rawDiv = message.querySelector('.raw-message');
93
+ if (rawDiv) rawDiv.classList.add('hideM');
94
+ }
95
+ function removeMarkdownText(message) {
96
+ var rawDiv = message.querySelector('.raw-message');
97
+ if (rawDiv) {
98
+ // 判断pre是否存在fake-pre类,如果不存在,则为20231118之前的历史记录格式,需要转换,增加fake-pre类用于适配
99
+ if (!rawDiv.querySelector('pre')?.classList.contains('fake-pre')) {
100
+ rawDiv.innerHTML = rawDiv.innerHTML.replace(/<pre>/g, '<pre class="fake-pre">');
101
+ }
102
+ // rawDiv.innerHTML = rawDiv.querySelector('pre')?.innerHTML || rawDiv.innerHTML;
103
+ rawDiv.classList.remove('hideM');
104
+ }
105
+ var mdDiv = message.querySelector('.md-message');
106
+ if (mdDiv) mdDiv.classList.add('hideM');
107
+ }
108
+ }
109
+
110
+ function setLatestMessage() {
111
+ var latestMessage = gradioApp().querySelector('#chuanhu-chatbot > .wrapper > .wrap > .message-wrap .message.bot.latest');
112
+ if (latestMessage) addLatestMessageButtons(latestMessage);
113
+ }
114
+
115
+ function addLatestMessageButtons(botElement) {
116
+ botElement.querySelector('.message-btn-row')?.remove();
117
+
118
+ var messageBtnRow = document.createElement('div');
119
+ messageBtnRow.classList.add('message-btn-row');
120
+ var messageBtnRowLeading = document.createElement('div');
121
+ messageBtnRowLeading.classList.add('message-btn-row-leading');
122
+ var messageBtnRowTrailing = document.createElement('div');
123
+ messageBtnRowTrailing.classList.add('message-btn-row-trailing');
124
+
125
+ messageBtnRow.appendChild(messageBtnRowLeading);
126
+ messageBtnRow.appendChild(messageBtnRowTrailing);
127
+
128
+ botElement.appendChild(messageBtnRow);
129
+
130
+ //leading
131
+ var regenerateButton = document.createElement('button');
132
+ regenerateButton.classList.add('chuanhu-btn');
133
+ regenerateButton.classList.add('regenerate-btn');
134
+ regenerateButton.setAttribute('aria-label', 'Regenerate');
135
+ regenerateButton.innerHTML = regenIcon + `<span>${i18n(regenerate_i18n)}</span>`;
136
+
137
+ var gradioRetryBtn = gradioApp().querySelector('#gr-retry-btn');
138
+ regenerateButton.addEventListener('click', () => {
139
+ gradioRetryBtn.click();
140
+ });
141
+
142
+ var deleteButton = document.createElement('button');
143
+ deleteButton.classList.add('chuanhu-btn');
144
+ deleteButton.classList.add('delete-latest-btn');
145
+ deleteButton.setAttribute('aria-label', 'Delete');
146
+ deleteButton.innerHTML = deleteIcon + `<span>${i18n(deleteRound_i18n)}</span>`;
147
+
148
+ var gradioDelLastBtn = gradioApp().querySelector('#gr-dellast-btn');
149
+ deleteButton.addEventListener('click', () => {
150
+ gradioDelLastBtn.click();
151
+ });
152
+
153
+ messageBtnRowLeading.appendChild(regenerateButton);
154
+ messageBtnRowLeading.appendChild(deleteButton);
155
+
156
+ // trailing
157
+ var likeButton = document.createElement('button');
158
+ likeButton.classList.add('chuanhu-btn');
159
+ likeButton.classList.add('like-latest-btn');
160
+ likeButton.setAttribute('aria-label', 'Like');
161
+ likeButton.innerHTML = likeIcon;
162
+
163
+ var gradioLikeBtn = gradioApp().querySelector('#gr-like-btn');
164
+ likeButton.addEventListener('click', () => {
165
+ gradioLikeBtn.click();
166
+ });
167
+
168
+ var dislikeButton = document.createElement('button');
169
+ dislikeButton.classList.add('chuanhu-btn');
170
+ dislikeButton.classList.add('dislike-latest-btn');
171
+ dislikeButton.setAttribute('aria-label', 'Dislike');
172
+ dislikeButton.innerHTML = dislikeIcon;
173
+
174
+ var gradioDislikeBtn = gradioApp().querySelector('#gr-dislike-btn');
175
+ dislikeButton.addEventListener('click', () => {
176
+ gradioDislikeBtn.click();
177
+ });
178
+
179
+ messageBtnRowTrailing.appendChild(likeButton);
180
+ messageBtnRowTrailing.appendChild(dislikeButton);
181
+ }
182
+
183
+
184
+ // button svg code
185
+ const copyIcon = '<span><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" height=".8em" width=".8em" xmlns="http://www.w3.org/2000/svg"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg></span>';
186
+ const copiedIcon = '<span><svg stroke="currentColor" fill="none" stroke-width="2" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" height=".8em" width=".8em" xmlns="http://www.w3.org/2000/svg"><polyline points="20 6 9 17 4 12"></polyline></svg></span>';
187
+ const mdIcon = '<span><svg stroke="currentColor" fill="none" stroke-width="1" viewBox="0 0 14 18" stroke-linecap="round" stroke-linejoin="round" height=".8em" width=".8em" xmlns="http://www.w3.org/2000/svg"><g transform-origin="center" transform="scale(0.85)"><path d="M1.5,0 L12.5,0 C13.3284271,-1.52179594e-16 14,0.671572875 14,1.5 L14,16.5 C14,17.3284271 13.3284271,18 12.5,18 L1.5,18 C0.671572875,18 1.01453063e-16,17.3284271 0,16.5 L0,1.5 C-1.01453063e-16,0.671572875 0.671572875,1.52179594e-16 1.5,0 Z" stroke-width="1.8"></path><line x1="3.5" y1="3.5" x2="10.5" y2="3.5"></line><line x1="3.5" y1="6.5" x2="8" y2="6.5"></line></g><path d="M4,9 L10,9 C10.5522847,9 11,9.44771525 11,10 L11,13.5 C11,14.0522847 10.5522847,14.5 10,14.5 L4,14.5 C3.44771525,14.5 3,14.0522847 3,13.5 L3,10 C3,9.44771525 3.44771525,9 4,9 Z" stroke="none" fill="currentColor"></path></svg></span>';
188
+ const rawIcon = '<span><svg stroke="currentColor" fill="none" stroke-width="1.8" viewBox="0 0 18 14" stroke-linecap="round" stroke-linejoin="round" height=".8em" width=".8em" xmlns="http://www.w3.org/2000/svg"><g transform-origin="center" transform="scale(0.85)"><polyline points="4 3 0 7 4 11"></polyline><polyline points="14 3 18 7 14 11"></polyline><line x1="12" y1="0" x2="6" y2="14"></line></g></svg></span>';
189
+
190
+ const regenIcon = '<span><svg viewBox="0 0 15.6737 14.3099" height="11px" width="10px" xmlns="http://www.w3.org/2000/svg"><g fill="currentColor"><path d="M8.52344 14.3043C12.4453 14.3043 15.6737 11.0704 15.6737 7.15396C15.6737 3.23385 12.4453 0 8.52344 0C4.61357 0 1.39193 3.20969 1.37314 7.11614L2.77012 7.11614C2.78891 3.94173 5.34391 1.40431 8.52344 1.40431C11.7096 1.40431 14.2785 3.96418 14.2785 7.15396C14.2785 10.3401 11.7096 12.9163 8.52344 12.9073C6.6559 12.9036 5.0325 12.0192 3.98219 10.6317C3.70247 10.3165 3.29141 10.2174 2.96431 10.4686C2.65796 10.6988 2.60863 11.1321 2.91325 11.5028C4.17573 13.1677 6.28972 14.3043 8.52344 14.3043ZM0.520576 5.73631C-0.0035439 5.73631-0.140743 6.14811 0.149274 6.53993L1.86425 8.89772C2.08543 9.20509 2.4372 9.20143 2.65301 8.89772L4.36628 6.53626C4.64726 6.14981 4.51544 5.73631 3.99839 5.73631Z"/></g></svg></span>';
191
+ const deleteIcon = '<span><svg viewBox="0 0 17.0644 12.9388" height="11px" width="11px" xmlns="http://www.w3.org/2000/svg"><g fill="currentColor"><path d="M4.85464 12.9388L12.2098 12.9388C13.6299 12.9388 14.26 12.2074 14.4792 10.7927L15.6069 3.38561L14.2702 3.42907L13.1479 10.686C13.049 11.3506 12.7252 11.6268 12.12 11.6268L4.94444 11.6268C4.32818 11.6268 4.01711 11.3506 3.91652 10.686L2.79421 3.42907L1.45752 3.38561L2.5852 10.7927C2.80443 12.2147 3.43453 12.9388 4.85464 12.9388ZM1.5018 4.10325L15.5643 4.10325C16.5061 4.10325 17.0644 3.49076 17.0644 2.55799L17.0644 1.55796C17.0644 0.623227 16.5061 0.0144053 15.5643 0.0144053L1.5018 0.0144053C0.588798 0.0144053 0 0.623227 0 1.55796L0 2.55799C0 3.49076 0.561696 4.10325 1.5018 4.10325ZM1.72372 2.88176C1.41559 2.88176 1.26666 2.7255 1.26666 2.412L1.26666 1.70028C1.26666 1.39215 1.41559 1.23589 1.72372 1.23589L15.3444 1.23589C15.6542 1.23589 15.7978 1.39215 15.7978 1.70028L15.7978 2.412C15.7978 2.7255 15.6542 2.88176 15.3444 2.88176Z"/><path d="M6.62087 10.2995C6.77686 10.2995 6.90282 10.2353 7.01438 10.1274L8.53038 8.60625L10.0517 10.1274C10.1633 10.2316 10.2876 10.2995 10.4526 10.2995C10.7594 10.2995 11.0131 10.0368 11.0131 9.72824C11.0131 9.56151 10.9542 9.44092 10.8427 9.32936L9.33033 7.81679L10.8463 6.29151C10.965 6.17458 11.0184 6.0557 11.0184 5.90166C11.0184 5.58407 10.7685 5.33044 10.4526 5.33044C10.302 5.33044 10.1814 5.38928 10.0608 5.5062L8.53038 7.03269L7.01072 5.50987C6.89379 5.39831 6.77686 5.33947 6.62087 5.33947C6.31036 5.33947 6.05307 5.59311 6.05307 5.90166C6.05307 6.05936 6.11019 6.18899 6.22346 6.29688L7.73579 7.81679L6.22346 9.33303C6.1119 9.44092 6.05307 9.56688 6.05307 9.72824C6.05307 10.0405 6.3067 10.2995 6.62087 10.2995Z"/></g></svg></span>';
192
+ // const deleteIcon = '<span><svg stroke="currentColor" fill="none" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" height="11px" width="11px" viewBox="0 0 216 163" version="1.1" xmlns="http://www.w3.org/2000/svg"><rect x="0.5" y="0.5" width="215" height="39" rx="9"/><path d="M197.485,39.535 L181.664,145.870 C180.953,150.648 178.547,154.805 175.110,157.768 C171.674,160.731 167.207,162.500 162.376,162.500 L53.558,162.500 C48.737,162.500 44.278,160.738 40.843,157.785 C37.409,154.831 34.999,150.686 34.278,145.919 L18.173,39.535 L197.485,39.535 Z" /><line x1="79.5" y1="71.5" x2="135.5" y2="127.5"/><line x1="79.5" y1="127.5" x2="135.5" y2="71.5"/></svg></span>'
193
+
194
+ const likeIcon = '<span><svg viewBox="0 0 14.4675 15.7462" height="11px" width="11px" xmlns="http://www.w3.org/2000/svg"><g fill="currentColor"><path d="M0 10.371C0 12.7447 1.51703 14.6758 3.48611 14.6758L5.667 14.6758C6.55809 15.123 7.61471 15.3774 8.77071 15.3774L9.69842 15.3774C10.58 15.3774 11.3136 15.3276 11.7943 15.2026C12.7703 14.9639 13.3931 14.2618 13.3931 13.3949C13.3931 13.2345 13.3677 13.0941 13.3208 12.9537C13.7842 12.5939 14.042 12.0763 14.042 11.4997C14.042 11.2309 13.9917 10.9655 13.8908 10.7507C14.206 10.4318 14.3799 9.96358 14.3799 9.46848C14.3799 9.14304 14.3027 8.81345 14.1645 8.57078C14.3581 8.2876 14.4675 7.90016 14.4675 7.47879C14.4675 6.42124 13.6602 5.60147 12.6063 5.60147L10.1642 5.60147C10.0006 5.60147 9.8919 5.52528 9.89873 5.37707C9.94826 4.69467 11.0035 3.06283 11.0035 1.72154C11.0035 0.72357 10.3014 0 9.33735 0C8.63623 0 8.15116 0.370089 7.70051 1.23942C6.86069 2.86536 5.8793 4.19561 4.39803 6.0414L3.23221 6.0414C1.38812 6.0414 0 7.9527 0 10.371ZM4.16181 10.3188C4.16181 8.90914 4.47725 8.01363 5.3808 6.80246C6.38763 5.45238 7.78384 3.82937 8.78871 1.82159C8.99528 1.42114 9.12909 1.3181 9.34054 1.3181C9.5974 1.3181 9.76222 1.50416 9.76222 1.81548C9.76222 2.78038 8.64211 4.4305 8.64211 5.51371C8.64211 6.3203 9.28051 6.84271 10.1713 6.84271L12.5653 6.84271C12.9408 6.84271 13.2246 7.12839 13.2246 7.50612C13.2246 7.76811 13.1415 7.94147 12.9377 8.15218C12.7334 8.34524 12.7053 8.65131 12.8901 8.84536C13.0595 9.07976 13.1352 9.25141 13.1352 9.47018C13.1352 9.73072 13.007 9.95486 12.7653 10.139C12.5131 10.3172 12.4299 10.6154 12.5712 10.9049C12.7031 11.1466 12.77 11.2853 12.77 11.4877C12.77 11.7944 12.5751 12.0361 12.1869 12.2381C11.9475 12.3752 11.8772 12.6425 11.9851 12.8802C12.1062 13.1749 12.1242 13.2435 12.1225 13.3864C12.1225 13.6664 11.9184 13.8921 11.4792 14.0019C11.0907 14.1006 10.4594 14.1416 9.60644 14.1399L8.82296 14.1382C6.03316 14.1313 4.16181 12.5581 4.16181 10.3188ZM1.21733 10.371C1.21733 8.67034 2.08408 7.32534 3.09216 7.26898C3.26992 7.26556 3.44573 7.26386 3.62349 7.26215C3.13079 8.20088 2.91716 9.15693 2.91716 10.3266C2.91716 11.5559 3.35395 12.646 4.14963 13.4907C3.90227 13.4907 3.64466 13.489 3.39046 13.4872C2.20833 13.4275 1.21733 12.0649 1.21733 10.371Z"/></g></svg></span>';
195
+ const dislikeIcon= '<span><svg viewBox="0 0 14.4675 15.5664" height="11px" width="11px" xmlns="http://www.w3.org/2000/svg"><g fill="currentColor"><path d="M14.4675 5.19535C14.4675 2.82169 12.9488 0.890613 10.9814 0.890613L8.7988 0.890613C7.90771 0.443351 6.85109 0.188955 5.70046 0.188955L4.76908 0.188955C3.88948 0.188955 3.15391 0.238755 2.6715 0.363751C1.6972 0.602507 1.07444 1.30459 1.07444 2.17147C1.07444 2.33189 1.09984 2.47228 1.14501 2.61267C0.683343 2.97251 0.423822 3.49007 0.423822 4.06671C0.423822 4.33551 0.47778 4.60089 0.574954 4.81574C0.265139 5.13456 0.0859375 5.60282 0.0859375 6.09792C0.0859375 6.42336 0.168459 6.75295 0.302984 6.99562C0.11304 7.2788 0 7.66624 0 8.0859C0 9.14516 0.807327 9.96493 1.8595 9.96493L4.30164 9.96493C4.46695 9.96493 4.57561 10.0411 4.56707 10.1893C4.51754 10.8717 3.46404 12.5036 3.46404 13.8449C3.46404 14.8428 4.16442 15.5664 5.12845 15.5664C5.83128 15.5664 6.31634 15.1963 6.76895 14.327C7.60878 12.701 8.5882 11.3708 10.0695 9.525L11.2353 9.525C13.0794 9.525 14.4675 7.6137 14.4675 5.19535ZM10.3057 5.24758C10.3057 6.65726 9.98855 7.55277 9.09036 8.76394C8.07817 10.114 6.68196 11.737 5.67709 13.7448C5.47418 14.1453 5.33671 14.2483 5.12697 14.2483C4.87376 14.2483 4.70528 14.0622 4.70528 13.7509C4.70528 12.786 5.82539 11.1359 5.82539 10.0527C5.82539 9.2461 5.187 8.72369 4.29816 8.72369L1.90049 8.72369C1.52497 8.72369 1.24124 8.43801 1.24124 8.06028C1.24124 7.79829 1.32426 7.62493 1.52984 7.41422C1.7361 7.22116 1.76051 6.91509 1.5811 6.72104C1.41166 6.48664 1.3323 6.31499 1.3323 6.09622C1.3323 5.83398 1.46049 5.61154 1.70587 5.42744C1.95436 5.24925 2.03956 4.95098 1.89627 4.66148C1.76271 4.41976 1.69581 4.28108 1.69581 4.07866C1.69581 3.77199 1.89065 3.53027 2.28058 3.32835C2.52003 3.19117 2.59033 2.92392 2.4861 2.68447C2.35962 2.39146 2.34155 2.32115 2.34497 2.17831C2.34497 1.89995 2.54909 1.67434 2.99028 1.56447C3.38042 1.46584 4.01005 1.42116 4.85936 1.42653L5.64284 1.42824C8.43435 1.4424 10.3057 3.00833 10.3057 5.24758ZM13.2502 5.19535C13.2502 6.89606 12.3834 8.24106 11.3736 8.29742C11.2013 8.30084 11.0218 8.30254 10.844 8.30425C11.3367 7.36552 11.5486 6.40947 11.5486 5.23978C11.5486 4.01052 11.1136 2.92044 10.3162 2.07574C10.5689 2.07574 10.8228 2.07745 11.077 2.07915C12.2575 2.13893 13.2502 3.50151 13.2502 5.19535Z"/></g></svg></span>'
assets/javascript/sliders.js ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ var rangeInputs = null;
3
+ var numberInputs = null;
4
+
5
+ function setSliderRange() {
6
+ var range = document.querySelectorAll('input[type="range"]');
7
+ range.forEach(range => {
8
+ range.style.backgroundSize = (range.value - range.min) / (range.max - range.min) * 100 + '% 100%';
9
+ });
10
+ }
11
+
12
+ function setSlider() {
13
+ rangeInputs = document.querySelectorAll('input[type="range"]');
14
+ numberInputs = document.querySelectorAll('input[type="number"]')
15
+ setSliderRange();
16
+ rangeInputs.forEach(rangeInput => {
17
+ rangeInput.addEventListener('input', setSliderRange);
18
+ });
19
+ numberInputs.forEach(numberInput => {
20
+ numberInput.addEventListener('input', setSliderRange);
21
+ })
22
+ }
23
+
24
+ function updateSlider() {
25
+ setSliderRange();
26
+ }
assets/javascript/updater.js ADDED
@@ -0,0 +1,243 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ var updateInfoGotten = false;
3
+ var isLatestVersion = localStorage.getItem('isLatestVersion') === "true" || false;
4
+ var shouldCheckUpdate = false;
5
+
6
+ function setUpdater() {
7
+ const enableCheckUpdate = gradioApp().querySelector('#enableCheckUpdate_config').innerText;
8
+
9
+ if (enableCheckUpdate == "False" || enableCheckUpdate == "false") {
10
+ gradioApp().classList.add('disable-update');
11
+ return;
12
+ }
13
+
14
+ if (!isLatestVersion) {
15
+ gradioApp().classList.add('is-outdated');
16
+ }
17
+ const lastCheckTime = localStorage.getItem('lastCheckTime') || 0;
18
+ currentTime = new Date().getTime();
19
+ const longTimeNoCheck = currentTime - lastCheckTime > 3 * 24 * 60 * 60 * 1000;
20
+ shouldCheckUpdate = !updateInfoGotten && (!isLatestVersion && longTimeNoCheck || isLatestVersion);
21
+ // console.log(`shouldCheckUpdate`, shouldCheckUpdate);
22
+ if (shouldCheckUpdate) updateLatestVersion();
23
+ }
24
+
25
+ var statusObserver = new MutationObserver(function (mutationsList) {
26
+ for (const mutation of mutationsList) {
27
+ if (mutation.type === 'attributes' || mutation.type === 'childList') {
28
+ if (statusDisplay.innerHTML.includes('<span id="update-status"')) {
29
+ if (getUpdateStatus() === "success") {
30
+ updatingInfoElement.innerText = i18n(updateSuccess_i18n);
31
+ noUpdateHtml();
32
+ localStorage.setItem('isLatestVersion', 'true');
33
+ isLatestVersion = true;
34
+ gradioApp().classList.remove('is-outdated');
35
+ enableUpdateBtns();
36
+ } else if (getUpdateStatus() === "failure") {
37
+ updatingInfoElement.innerHTML = marked.parse(updateFailure_i18n, {mangle: false, headerIds: false});
38
+ disableUpdateBtn_enableCancelBtn();
39
+ } else if (getUpdateStatus() != "") {
40
+ updatingInfoElement.innerText = getUpdateStatus();
41
+ enableUpdateBtns();
42
+ }
43
+ updateStatus.parentNode.removeChild(updateStatus);
44
+ if (updateSpinner) updateSpinner.stop();
45
+ }
46
+ }
47
+ }
48
+ });
49
+
50
+ var showingUpdateInfo = false;
51
+ async function getLatestRelease() {
52
+ try {
53
+ const response = await fetch('https://api.github.com/repos/gaizhenbiao/chuanhuchatgpt/releases/latest');
54
+ if (!response.ok) {
55
+ console.log(`Error: ${response.status} - ${response.statusText}`);
56
+ updateInfoGotten = true;
57
+ return null;
58
+ }
59
+ const data = await response.json();
60
+ updateInfoGotten = true;
61
+ return data;
62
+ } catch (error) {
63
+ console.log(`Error: ${error}`);
64
+ updateInfoGotten = true;
65
+ return null;
66
+ }
67
+ }
68
+
69
+ var releaseNoteElement = document.getElementById('release-note-content');
70
+ var updatingInfoElement = document.getElementById('updating-info');
71
+ async function updateLatestVersion() {
72
+ const currentVersionElement = document.getElementById('current-version');
73
+ const reVersion = /<a[^>]*>([^<]*)<\/a>/g;
74
+ const versionMatch = reVersion.exec(currentVersionElement.innerHTML);
75
+ const currentVersion = (versionMatch && versionMatch[1].length == 8) ? versionMatch[1] : null;
76
+ const latestVersionElement = document.getElementById('latest-version-title');
77
+ const versionInfoElement = document.getElementById('version-info-title');
78
+ releaseNoteElement = document.getElementById('release-note-content');
79
+ updatingInfoElement = document.getElementById('updating-info');
80
+
81
+ const versionTime = document.getElementById('version-time').innerText;
82
+ const localVersionTime = versionTime !== "unknown" ? (new Date(versionTime)).getTime() : 0;
83
+ disableUpdateBtns();
84
+ updateInfoGotten = true; //无论成功与否都只执行一次,否则容易api超限...
85
+ try {
86
+ const data = await getLatestRelease();
87
+ const releaseNote = data.body;
88
+ if (releaseNote) {
89
+ releaseNoteElement.innerHTML = marked.parse(releaseNote, {mangle: false, headerIds: false});
90
+ }
91
+ const latestVersion = data.tag_name;
92
+ if (currentVersion) {
93
+ if (latestVersion <= currentVersion) {
94
+ noUpdate();
95
+ localStorage.setItem('isLatestVersion', 'true');
96
+ isLatestVersion = true;
97
+ gradioApp().classList.remove('is-outdated');
98
+ } else {
99
+ latestVersionElement.textContent = latestVersion;
100
+ console.log(`New version ${latestVersion} found!`);
101
+ if (!isInIframe) openUpdateToast();
102
+ gradioApp().classList.add('is-outdated');
103
+ localStorage.setItem('isLatestVersion', 'false');
104
+ isLatestVersion = false;
105
+ }
106
+ enableUpdateBtns();
107
+ } else { //如果当前版本号获取失败,使用时间比较
108
+ const latestVersionTime = (new Date(data.created_at)).getTime();
109
+ if (latestVersionTime) {
110
+ const latestVersionInfo = `<a href="https://github.com/gaizhenbiao/chuanhuchatgpt/releases/latest" target="_blank" id="latest-version-title" style="text-decoration: none;">${latestVersion}</a>`
111
+ const manualUpdateInfo = `<a href="https://github.com/GaiZhenbiao/ChuanhuChatGPT/wiki/使用教程#手动更新" target="_blanks" style="text-decoration: none;">manual update</a>`
112
+ if (localVersionTime == 0) {
113
+ const infoMessage = `Local version check failed. \nBut latest revision is ${latestVersionInfo}. \n\nWhen Update needed, \n- If you are using Docker, try to update package. \n- If you didn't use git, try ${manualUpdateInfo}.`
114
+ versionInfoElement.innerHTML = marked.parse(infoMessage, {mangle: false, headerIds: false});
115
+ console.log(`New version ${latestVersion} found!`);
116
+ disableUpdateBtn_enableCancelBtn();
117
+ localStorage.setItem('isLatestVersion', 'false');
118
+ isLatestVersion = false;
119
+ gradioApp().classList.add('is-outdated');
120
+ } else if (localVersionTime < latestVersionTime) {
121
+ const infoMessage = `Local version check failed, it seems to be a local rivision. \n\nBut latest revision is ${latestVersionInfo}. Try ${manualUpdateInfo}.`
122
+ versionInfoElement.innerHTML = marked.parse(infoMessage, {mangle: false, headerIds: false});
123
+ console.log(`New version ${latestVersion} found!`);
124
+ disableUpdateBtn_enableCancelBtn();
125
+ // if (!isInIframe) openUpdateToast();
126
+ localStorage.setItem('isLatestVersion', 'false');
127
+ isLatestVersion = false;
128
+ gradioApp().classList.add('is-outdated');
129
+ } else {
130
+ noUpdate("Local version check failed, it seems to be a local rivision. <br>But your revision is newer than the latest release.");
131
+ gradioApp().classList.add('is-outdated');
132
+ enableUpdateBtns()
133
+ localStorage.setItem('isLatestVersion', 'false');
134
+ isLatestVersion = false;
135
+ }
136
+ }
137
+ }
138
+ currentTime = new Date().getTime();
139
+ localStorage.setItem('lastCheckTime', currentTime);
140
+ } catch (error) {
141
+ console.error(error);
142
+ disableUpdateBtn_enableCancelBtn()
143
+ }
144
+ }
145
+
146
+ function getUpdateInfo() {
147
+ window.open('https://github.com/gaizhenbiao/chuanhuchatgpt/releases/latest', '_blank');
148
+ closeUpdateToast();
149
+ }
150
+
151
+ var updateSpinner = null;
152
+
153
+ function bgUpdateChuanhu() {
154
+ updateChuanhuBtn.click();
155
+ updatingInfoElement.innerText = i18n(updatingMsg_i18n);
156
+ var updatingSpinner = document.getElementById('updating-spinner');
157
+ try {
158
+ updateSpinner = new Spin.Spinner({color:'#06AE56',top:'45%',lines:9}).spin(updatingSpinner);
159
+ } catch (error) {
160
+ console.error("Can't create spinner")
161
+ }
162
+ updatingInfoElement.classList.remove('hideK');
163
+ disableUpdateBtns();
164
+ const releaseNoteWrap = document.getElementById('release-note-wrap');
165
+ releaseNoteWrap.style.setProperty('display', 'none');
166
+ statusObserver.observe(statusDisplay, { childList: true, subtree: true, characterData: true});
167
+ }
168
+ function cancelUpdate() {
169
+ closeUpdateToast();
170
+ }
171
+ function openUpdateToast() {
172
+ showingUpdateInfo = true;
173
+ updateToast.style.setProperty('top', '0px');
174
+ showMask("update-toast");
175
+ }
176
+ function closeUpdateToast() {
177
+ updateToast.style.setProperty('top', '-600px');
178
+ showingUpdateInfo = false;
179
+ if (updatingInfoElement.classList.contains('hideK') === false) {
180
+ updatingInfoElement.classList.add('hideK');
181
+ }
182
+ document.querySelector('.chuanhu-mask')?.remove();
183
+ }
184
+ function manualCheckUpdate() {
185
+ openUpdateToast();
186
+ updateLatestVersion();
187
+ currentTime = new Date().getTime();
188
+ localStorage.setItem('lastCheckTime', currentTime);
189
+ }
190
+ function noUpdate(message="") {
191
+ localStorage.setItem('isLatestVersion', 'true');
192
+ isLatestVersion = true;
193
+ noUpdateHtml(message);
194
+ }
195
+ function noUpdateHtml(message="") {
196
+ const versionInfoElement = document.getElementById('version-info-title');
197
+ const gotoUpdateBtn = document.getElementById('goto-update-btn');
198
+ const closeUpdateBtn = document.getElementById('close-update-btn');
199
+ const releaseNoteWrap = document.getElementById('release-note-wrap');
200
+ releaseNoteWrap.style.setProperty('display', 'none');
201
+ if (message === "") {
202
+ versionInfoElement.textContent = i18n(usingLatest_i18n)
203
+ } else {
204
+ versionInfoElement.innerHTML = message;
205
+ }
206
+ gotoUpdateBtn.classList.add('hideK');
207
+ closeUpdateBtn.classList.remove('hideK');
208
+ }
209
+
210
+ var updateStatus = null;
211
+ function getUpdateStatus() {
212
+ updateStatus = statusDisplay.querySelector("#update-status");
213
+ if (updateStatus) {
214
+ return updateStatus.innerText;
215
+ } else {
216
+ return "unknown";
217
+ }
218
+ }
219
+
220
+ function disableUpdateBtns() {
221
+ const updatesButtons = document.querySelectorAll('.btn-update');
222
+ updatesButtons.forEach( function (btn) {
223
+ btn.disabled = true;
224
+ });
225
+ }
226
+ function enableUpdateBtns() {
227
+ const updatesButtons = document.querySelectorAll('.btn-update');
228
+ updatesButtons.forEach( function (btn) {
229
+ btn.disabled = false;
230
+ });
231
+ }
232
+ function disableUpdateBtn_enableCancelBtn() {
233
+ document.querySelector('#update-button.btn-update').disabled = true;
234
+ document.querySelector('#cancel-button.btn-update').disabled = false;
235
+ }
236
+
237
+ // function setUpdateWindowHeight() {
238
+ // if (!showingUpdateInfo) {return;}
239
+ // const scrollPosition = window.scrollY;
240
+ // // const originalTop = updateToast.style.getPropertyValue('top');
241
+ // const resultTop = scrollPosition - 20 + 'px';
242
+ // updateToast.style.setProperty('top', resultTop);
243
+ // }
assets/javascript/user-info.js ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ // var userLogged = false;
3
+ var usernameGotten = false;
4
+ var usernameTmp = null;
5
+ var username = null;
6
+
7
+
8
+ function getUserInfo() {
9
+ if (usernameGotten) {
10
+ return;
11
+ }
12
+ // userLogged = localStorage.getItem('userLogged');
13
+ // if (userLogged) {
14
+ usernameTmp = userInfoDiv.innerText;
15
+ if (usernameTmp) {
16
+ if (usernameTmp.includes("getting user info")) {
17
+ setTimeout(getUserInfo, 500);
18
+ return;
19
+ } else if (usernameTmp === " ") {
20
+ localStorage.removeItem("username");
21
+ // localStorage.removeItem("userLogged")
22
+ // userLogged = false;
23
+ usernameGotten = true;
24
+ return;
25
+ } else {
26
+ usernameTmp = usernameTmp.match(/User:\s*(.*)/)[1] || usernameTmp;
27
+ localStorage.setItem("username", usernameTmp);
28
+ username = usernameTmp;
29
+ usernameGotten = true;
30
+ clearHistoryHtml();
31
+ }
32
+ }
33
+ // }
34
+ }
35
+
36
+ function showOrHideUserInfo() {
37
+ function toggleUserInfoVisibility(shouldHide) {
38
+ if (userInfoDiv) {
39
+ if (shouldHide) {
40
+ userInfoDiv.classList.add("info-transparent");
41
+ } else {
42
+ userInfoDiv.classList.remove("info-transparent");
43
+ }
44
+ }
45
+ }
46
+
47
+ // When webpage loaded, hide user info after 2 second
48
+ setTimeout(function () {
49
+ toggleUserInfoVisibility(true);
50
+ }, 2000);
51
+
52
+ // let triggerElements = {appTitleDiv, userInfoDiv, sendBtn};
53
+ let triggerElements = {userInfoDiv, statusDisplay};
54
+ for (let elem in triggerElements) {
55
+ triggerElements[elem].addEventListener("mouseenter", function () {
56
+ toggleUserInfoVisibility(false);
57
+ });
58
+ triggerElements[elem].addEventListener("mouseleave", function () {
59
+ toggleUserInfoVisibility(true);
60
+ });
61
+ triggerElements[elem].ontouchstart = function () {
62
+ toggleUserInfoVisibility(false);
63
+ };
64
+ triggerElements[elem].ontouchend = function () {
65
+ setTimeout(function () {
66
+ toggleUserInfoVisibility(true);
67
+ }, 3000);
68
+ };
69
+ }
70
+ }
assets/javascript/utils.js ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+ function isImgUrl(url) {
4
+ const imageExtensions = /\.(jpg|jpeg|png|gif|bmp|webp)$/i;
5
+ if (url.startsWith('data:image/')) {
6
+ return true;
7
+ }
8
+ if (url.match(imageExtensions)) {
9
+ return true;
10
+ }
11
+ if (url.startsWith('http://') || url.startsWith('https://')) {
12
+ return true;
13
+ }
14
+
15
+ return false;
16
+ }
17
+
18
+ function downloadHistory(gradioUsername, historyname, format=".json") {
19
+ let fileUrl;
20
+ if (gradioUsername === null || gradioUsername.trim() === "") {
21
+ fileUrl = `/file=./history/${historyname}`;
22
+ } else {
23
+ fileUrl = `/file=./history/${gradioUsername}/${historyname}`;
24
+ }
25
+ downloadFile(fileUrl, historyname, format);
26
+ }
27
+
28
+ function downloadFile(fileUrl, filename = "", format = "", retryTimeout = 200, maxAttempts = 10) {
29
+
30
+ fileUrl = fileUrl + format;
31
+ filename = filename + format;
32
+
33
+ let attempts = 0;
34
+
35
+ async function tryDownload() {
36
+ if (attempts >= maxAttempts) {
37
+ console.error('Max attempts reached, download failed.');
38
+ alert('Download failed:' + filename);
39
+ return;
40
+ }
41
+ try {
42
+ const response = await fetch(fileUrl);
43
+ if (!response.ok) {
44
+ attempts++;
45
+ console.error("Error fetching file, retrying...");
46
+ setTimeout(tryDownload, retryTimeout);
47
+ } else {
48
+ response.blob()
49
+ .then(blob => {
50
+ const url = URL.createObjectURL(blob);
51
+ const a = document.createElement('a');
52
+ a.style.display = 'none';
53
+ a.href = url;
54
+ a.download = filename;
55
+ document.body.appendChild(a);
56
+ a.click();
57
+ URL.revokeObjectURL(url);
58
+ document.body.removeChild(a);
59
+ })
60
+ .catch(error => {
61
+ console.error('Error downloading file:', error);
62
+ });
63
+ }
64
+ } catch (error) {
65
+ attempts++;
66
+ setTimeout(tryDownload, retryTimeout);
67
+ }
68
+ }
69
+
70
+ tryDownload();
71
+ }
72
+
73
+ function statusDisplayMessage(message) {
74
+ statusDisplayBlock = statusDisplay.querySelector("#status-display .md p");
75
+ statusDisplayBlock.innerText = message;
76
+ }
77
+
78
+ function bindFancyBox() {
79
+ Fancybox.bind('[data-fancybox]', {
80
+ Carousel: {
81
+ Panzoom: {
82
+ decelFriction: 0.5
83
+ }
84
+ }
85
+ });
86
+ }
87
+
88
+
89
+ /* NOTE: These reload functions are not used in the current version of the code.
90
+ * From stable-diffusion-webui
91
+ */
92
+ function restart_reload() {
93
+ document.body.innerHTML = '<h1 style="font-family:ui-monospace,monospace;margin-top:20%;color:lightgray;text-align:center;">Reloading...</h1>';
94
+
95
+ var requestPing = function () {
96
+ requestGet("./internal/ping", {}, function (data) {
97
+ location.reload();
98
+ }, function () {
99
+ setTimeout(requestPing, 500);
100
+ });
101
+ };
102
+
103
+ setTimeout(requestPing, 2000);
104
+
105
+ return [];
106
+ }
107
+
108
+ function requestGet(url, data, handler, errorHandler) {
109
+ var xhr = new XMLHttpRequest();
110
+ var args = Object.keys(data).map(function (k) {
111
+ return encodeURIComponent(k) + '=' + encodeURIComponent(data[k]);
112
+ }).join('&');
113
+ xhr.open("GET", url + "?" + args, true);
114
+
115
+ xhr.onreadystatechange = function () {
116
+ if (xhr.readyState === 4) {
117
+ if (xhr.status === 200) {
118
+ try {
119
+ var js = JSON.parse(xhr.responseText);
120
+ handler(js);
121
+ } catch (error) {
122
+ console.error(error);
123
+ errorHandler();
124
+ }
125
+ } else {
126
+ errorHandler();
127
+ }
128
+ }
129
+ };
130
+ var js = JSON.stringify(data);
131
+ xhr.send(js);
132
+ }
assets/javascript/webui.js ADDED
@@ -0,0 +1,333 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ function openSettingBox() {
3
+ chuanhuPopup.classList.add('showBox');
4
+ popupWrapper.classList.add('showBox');
5
+ settingBox.classList.remove('hideBox');
6
+ trainingBox.classList.add('hideBox');
7
+ showMask("box");
8
+
9
+ }
10
+
11
+ function openTrainingBox() {
12
+ chuanhuPopup.classList.add('showBox');
13
+ popupWrapper.classList.add('showBox');
14
+ trainingBox.classList.remove('hideBox');
15
+ settingBox.classList.add('hideBox');
16
+ showMask("box");
17
+ }
18
+
19
+ function openChatMore() {
20
+ chatbotArea.classList.add('show-chat-more');
21
+ showMask("chat-more");
22
+ }
23
+
24
+ function closeChatMore() {
25
+ chatbotArea.classList.remove('show-chat-more');
26
+ chatbotArea.querySelector('.chuanhu-mask')?.remove();
27
+ }
28
+
29
+
30
+ function showMask(obj) {
31
+ const mask = document.createElement('div');
32
+ mask.classList.add('chuanhu-mask');
33
+ if (obj == "box") {
34
+ mask.classList.add('mask-blur');
35
+ document.body.classList.add('popup-open');
36
+ popupWrapper.appendChild(mask);
37
+ } else if (obj == "chat-more") {
38
+ mask.classList.add('transparent-mask');
39
+ chatbotArea.querySelector('#chatbot-input-more-area').parentNode.appendChild(mask);
40
+ } else if (obj == "update-toast") {
41
+ mask.classList.add('chuanhu-top-mask');
42
+ if (document.querySelector('.chuanhu-top-mask')) {
43
+ for (var i = 0; i < document.querySelectorAll('.chuanhu-top-mask').length; i++) {
44
+ document.querySelectorAll('.chuanhu-top-mask')[i].remove();
45
+ }
46
+ }
47
+ document.body.appendChild(mask);
48
+ // mask.classList.add('transparent-mask');
49
+ }
50
+
51
+
52
+ mask.addEventListener('click', () => {
53
+ if (obj == "box") {
54
+ closeBox();
55
+ } else if (obj == "chat-more") {
56
+ closeChatMore();
57
+ } else if (obj == "update-toast") {
58
+ closeUpdateToast();
59
+ }
60
+ });
61
+ }
62
+
63
+ function chatMoreBtnClick() {
64
+ if (chatbotArea.classList.contains('show-chat-more')) {
65
+ closeChatMore();
66
+ } else {
67
+ openChatMore();
68
+ }
69
+ }
70
+
71
+ function closeBtnClick(obj) {
72
+ if (obj == "box") {
73
+ closeBox();
74
+ } else if (obj == "toolbox") {
75
+ closeSide(toolbox);
76
+ wantOpenToolbox = false;
77
+ }
78
+ }
79
+
80
+ function closeBox() {
81
+ chuanhuPopup.classList.remove('showBox');
82
+ popupWrapper.classList.remove('showBox');
83
+ trainingBox.classList.add('hideBox');
84
+ settingBox.classList.add('hideBox');
85
+ document.querySelector('.chuanhu-mask')?.remove();
86
+ document.body.classList.remove('popup-open');
87
+ }
88
+
89
+ function closeSide(sideArea) {
90
+ document.body.classList.remove('popup-open');
91
+ sideArea.classList.remove('showSide');
92
+ if (sideArea == toolbox) {
93
+ chuanhuHeader.classList.remove('under-box');
94
+ chatbotArea.classList.remove('toolbox-open')
95
+ toolboxOpening = false;
96
+ } else if (sideArea == menu) {
97
+ chatbotArea.classList.remove('menu-open')
98
+ menuOpening = false;
99
+ }
100
+ adjustMask();
101
+ }
102
+
103
+ function openSide(sideArea) {
104
+ sideArea.classList.add('showSide');
105
+ if (sideArea == toolbox) {
106
+ chuanhuHeader.classList.add('under-box');
107
+ chatbotArea.classList.add('toolbox-open')
108
+ toolboxOpening = true;
109
+ } else if (sideArea == menu) {
110
+ chatbotArea.classList.add('menu-open')
111
+ menuOpening = true;
112
+ }
113
+ // document.body.classList.add('popup-open');
114
+ }
115
+
116
+ function menuClick() {
117
+ shouldAutoClose = false;
118
+ if (menuOpening) {
119
+ closeSide(menu);
120
+ wantOpenMenu = false;
121
+ } else {
122
+ if (windowWidth < 1024 && toolboxOpening) {
123
+ closeSide(toolbox);
124
+ wantOpenToolbox = false;
125
+ }
126
+ openSide(menu);
127
+ wantOpenMenu = true;
128
+ }
129
+ adjustSide();
130
+ }
131
+
132
+ function toolboxClick() {
133
+ shouldAutoClose = false;
134
+ if (toolboxOpening) {
135
+ closeSide(toolbox);
136
+ wantOpenToolbox = false;
137
+ } else {
138
+ if (windowWidth < 1024 && menuOpening) {
139
+ closeSide(menu);
140
+ wantOpenMenu = false;
141
+ }
142
+ openSide(toolbox);
143
+ wantOpenToolbox = true;
144
+ }
145
+ adjustSide();
146
+ }
147
+
148
+ var menuOpening = false;
149
+ var toolboxOpening = false;
150
+ var shouldAutoClose = true;
151
+ var wantOpenMenu = windowWidth > 768;
152
+ var wantOpenToolbox = windowWidth >= 1024;
153
+
154
+ function adjustSide() {
155
+ if (windowWidth >= 1024) {
156
+ shouldAutoClose = true;
157
+ if (wantOpenMenu) {
158
+ openSide(menu);
159
+ if (wantOpenToolbox) openSide(toolbox);
160
+ } else if (wantOpenToolbox) {
161
+ openSide(toolbox);
162
+ } else {
163
+ closeSide(menu);
164
+ closeSide(toolbox);
165
+ }
166
+ } else if (windowWidth > 768 && windowWidth < 1024 ) {
167
+ shouldAutoClose = true;
168
+ if (wantOpenToolbox) {
169
+ if (wantOpenMenu) {
170
+ closeSide(toolbox);
171
+ openSide(menu);
172
+ } else {
173
+ closeSide(menu);
174
+ openSide(toolbox);
175
+ }
176
+ } else if (wantOpenMenu) {
177
+ if (wantOpenToolbox) {
178
+ closeSide(menu);
179
+ openSide(toolbox);
180
+ } else {
181
+ closeSide(toolbox);
182
+ openSide(menu);
183
+ }
184
+ } else if (!wantOpenMenu && !wantOpenToolbox){
185
+ closeSide(menu);
186
+ closeSide(toolbox);
187
+ }
188
+ } else { // windowWidth <= 768
189
+ if (shouldAutoClose) {
190
+ closeSide(menu);
191
+ // closeSide(toolbox);
192
+ }
193
+ }
194
+ checkChatbotWidth();
195
+ adjustMask();
196
+ }
197
+
198
+ function adjustMask() {
199
+ var sideMask = null;
200
+ if (!gradioApp().querySelector('.chuanhu-side-mask')) {
201
+ sideMask = document.createElement('div');
202
+ sideMask.classList.add('chuanhu-side-mask');
203
+ gradioApp().appendChild(sideMask);
204
+ sideMask.addEventListener('click', () => {
205
+ closeSide(menu);
206
+ closeSide(toolbox);
207
+ });
208
+ }
209
+ sideMask = gradioApp().querySelector('.chuanhu-side-mask');
210
+
211
+ if (windowWidth > 768) {
212
+ sideMask.style.backgroundColor = 'rgba(0, 0, 0, 0)';
213
+ setTimeout(() => {sideMask.style.display = 'none'; }, 100);
214
+ return;
215
+ }
216
+ // if (windowWidth <= 768)
217
+ if (menuOpening || toolboxOpening) {
218
+ document.body.classList.add('popup-open');
219
+ sideMask.style.display = 'block';
220
+ setTimeout(() => {sideMask.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';}, 200);
221
+ sideMask.classList.add('mask-blur');
222
+ } else if (!menuOpening && !toolboxOpening) {
223
+ sideMask.style.backgroundColor = 'rgba(0, 0, 0, 0)';
224
+ setTimeout(() => {sideMask.style.display = 'none'; }, 100);
225
+ }
226
+ }
227
+
228
+ function checkChatbotWidth() {
229
+ // let chatbotWidth = chatbotArea.clientWidth;
230
+ // if (chatbotWidth > 488) {
231
+ if (windowWidth > 768) {
232
+ chatbotArea.classList.add('chatbot-full-width');
233
+ } else {
234
+ chatbotArea.classList.remove('chatbot-full-width');
235
+ }
236
+
237
+ if (windowWidth > 768) {
238
+ chatbotArea.classList.remove('no-toolbox');
239
+ chatbotArea.classList.remove('no-menu');
240
+
241
+ if (!chatbotArea.classList.contains('toolbox-open') && chatbotArea.classList.contains('menu-open')) {
242
+ chatbotArea.classList.add('no-toolbox');
243
+ } else if (!chatbotArea.classList.contains('menu-open') && chatbotArea.classList.contains('toolbox-open')) {
244
+ chatbotArea.classList.add('no-menu');
245
+ } else if (!chatbotArea.classList.contains('menu-open') && !chatbotArea.classList.contains('toolbox-open')) {
246
+ chatbotArea.classList.add('no-toolbox');
247
+ chatbotArea.classList.add('no-menu');
248
+ }
249
+ }
250
+
251
+ checkChatMoreMask();
252
+ }
253
+
254
+ function checkChatMoreMask() {
255
+ if (!chatbotArea.classList.contains('chatbot-full-width')) {
256
+ chatbotArea.querySelector('.chuanhu-mask')?.remove();
257
+ chatbotArea.classList.remove('show-chat-more');
258
+ }
259
+ }
260
+
261
+ function showKnowledgeBase(){
262
+ if (!toolboxOpening) {
263
+ toolboxClick();
264
+ }
265
+ switchToolBoxTab(0);
266
+ let knoledgeBaseAccordion = gradioApp().querySelector('#gr-kb-accordion');
267
+ let knoledgeBase = knoledgeBaseAccordion.querySelector('#upload-index-file');
268
+ if (knoledgeBase.parentElement.parentElement.style.display == 'none') {
269
+ knoledgeBaseAccordion.querySelector('.label-wrap')?.click();
270
+ }
271
+ // 将 knoledgeBase 滚动到可见区域
272
+ setTimeout(() => {knoledgeBaseAccordion.scrollIntoView({ behavior: "smooth"}); }, 100);
273
+ letThisSparkle(knoledgeBase, 5000);
274
+ }
275
+
276
+ function letThisSparkle(element, sparkleTime = 3000) {
277
+ element.classList.add('chuanhu-sparkle');
278
+ setTimeout(() => {element.classList.remove('chuanhu-sparkle');}, sparkleTime);
279
+ }
280
+
281
+ function switchToolBoxTab(tabIndex) {
282
+ let tabButtons = gradioApp().querySelectorAll('#chuanhu-toolbox-tabs .tab-nav > button');
283
+ let tab = tabButtons[tabIndex];
284
+ tab.click();
285
+ }
286
+
287
+ /*
288
+ function setHistroyPanel() {
289
+ const historySelectorInput = gradioApp().querySelector('#history-select-dropdown input');
290
+ const historyPanel = document.createElement('div');
291
+ historyPanel.classList.add('chuanhu-history-panel');
292
+ historySelector.parentNode.insertBefore(historyPanel, historySelector);
293
+ var historyList=null;
294
+
295
+ historySelectorInput.addEventListener('click', (e) => {
296
+ e.stopPropagation();
297
+ historyList = gradioApp().querySelector('#history-select-dropdown ul.options');
298
+
299
+ if (historyList) {
300
+ // gradioApp().querySelector('.chuanhu-history-panel')?.remove();
301
+ historyPanel.innerHTML = '';
302
+ let historyListClone = historyList.cloneNode(true);
303
+ historyListClone.removeAttribute('style');
304
+ // historyList.classList.add('hidden');
305
+ historyList.classList.add('hideK');
306
+ historyPanel.appendChild(historyListClone);
307
+ addHistoryPanelListener(historyPanel);
308
+ // historySelector.parentNode.insertBefore(historyPanel, historySelector);
309
+ }
310
+ });
311
+ }
312
+ */
313
+
314
+ // function addHistoryPanelListener(historyPanel){
315
+ // historyPanel.querySelectorAll('ul.options > li').forEach((historyItem) => {
316
+ // historyItem.addEventListener('click', (e) => {
317
+ // const historySelectorInput = gradioApp().querySelector('#history-select-dropdown input');
318
+ // const historySelectBtn = gradioApp().querySelector('#history-select-btn');
319
+ // historySelectorInput.value = historyItem.innerText;
320
+ // historySelectBtn.click();
321
+ // });
322
+ // });
323
+ // }
324
+
325
+
326
+ // function testTrain() {
327
+
328
+ // trainBody.classList.toggle('hide-body');
329
+ // trainingBox.classList.remove('hideBox');
330
+
331
+ // var chuanhuBody = document.querySelector('#chuanhu-body');
332
+ // chuanhuBody.classList.toggle('hide-body');
333
+ // }
assets/stylesheet/ChuanhuChat.css ADDED
@@ -0,0 +1,1234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ :root {
2
+ --vh: 1vh;
3
+
4
+ --chatbot-color-light: #000000;
5
+ --chatbot-color-dark: #FFFFFF;
6
+ --chatbot-background-color-light: #F3F3F3;
7
+ --chatbot-background-color-dark: #121111;
8
+ --message-user-background-color-light: #52b7e3;
9
+ --message-user-background-color-dark: #1140d8;
10
+ --message-bot-background-color-light: #FFFFFF;
11
+ --message-bot-background-color-dark: #2C2C2C;
12
+ --switch-checkbox-color-light: #e5e7eb;
13
+ --switch-checkbox-color-dark: #515151;
14
+
15
+ --chatbot-blur-background-color: #F3F3F366;
16
+ --chatbot-input-background-color: rgba(255, 255, 255, 0.64);
17
+ --chatbot-input-more-background-color: #FFFFFFAA;
18
+ --chatbot-input-more-background-solid-color: #FFFFFF;
19
+ --chatbot-input-more-background-fullwidth-hover: #FFFFFF99;
20
+ --chatbot-input-more-background-mobilewidth-hover: #E6E6E644;
21
+
22
+ --message-list-background-hover: #F3F3F3;
23
+ --message-list-background-selected: #EAEAEA;
24
+
25
+ --menu-width: 320px;
26
+ --menu-background-fill: var(--background-fill-primary);
27
+
28
+ --toolbox-width: 280px;
29
+ --toolbox-background-fill: var(--background-fill-secondary);
30
+
31
+ --dragging-hint-background-color: #F9F9F9BB;
32
+
33
+ .dark {
34
+ --chatbot-blur-background-color: #12111166;
35
+ --chatbot-input-background-color: rgba(144, 144, 144, 0.32);
36
+ --chatbot-input-more-background-color: #3C3C3CAA;
37
+ --chatbot-input-more-background-solid-color: #3C3C3C;
38
+ --chatbot-input-more-background-fullwidth-hover: #2F2F2F88;
39
+ --chatbot-input-more-background-mobilewidth-hover: #1F1F1F44;
40
+
41
+ --message-list-background-hover: #202020;
42
+ --message-list-background-selected: #2F3030;
43
+
44
+ --dragging-hint-background-color: #515151BB;
45
+ }
46
+ }
47
+
48
+
49
+ body.popup-open {
50
+ overflow: hidden;
51
+ }
52
+
53
+ .hideK {
54
+ display: none;
55
+ }
56
+
57
+ #app-title {
58
+ font-weight: var(--prose-header-text-weight);
59
+ font-size: var(--text-xxl);
60
+ line-height: 1.3;
61
+ text-align: left;
62
+ margin-top: 4px;
63
+ white-space: nowrap;
64
+ flex-direction: row;
65
+ display: inline-flex;
66
+ align-items: center;
67
+ position: absolute;
68
+ }
69
+ #description {
70
+ text-align: center;
71
+ /* margin: 32px 0 4px 0; */
72
+ }
73
+ #about-tab {
74
+ text-align: center;
75
+ }
76
+ #about-tab img {
77
+ margin: 0 auto;
78
+ }
79
+
80
+ /* 高级页面 */
81
+ #advanced-warning {
82
+ margin-top: 0.5rem;
83
+ display: flex;
84
+ flex-wrap: wrap;
85
+ flex-direction: column;
86
+ align-content: center;
87
+ }
88
+
89
+ #netsetting-warning hr {
90
+ margin-top: 0.5em;
91
+ margin-bottom: 1em;
92
+ }
93
+
94
+ .view-only-textbox textarea {
95
+ -webkit-text-fill-color: darkgray !important;
96
+ cursor: not-allowed !important;
97
+ }
98
+
99
+ #footer {
100
+ text-align: center;
101
+ }
102
+ #footer div {
103
+ display: inline-block;
104
+ }
105
+ #footer .versions{
106
+ font-size: 85%;
107
+ opacity: 0.60;
108
+ }
109
+
110
+
111
+ #float-display {
112
+ position: absolute;
113
+ max-height: 30px;
114
+ }
115
+
116
+ .insert-block {
117
+ position: relative;
118
+ margin: 0;
119
+ padding: 8px 0;
120
+ box-shadow: var(--block-shadow);
121
+ border-width: var(--block-border-width);
122
+ border-color: var(--block-border-color);
123
+ border-radius: var(--block-radius);
124
+ background: var(--block-background-fill);
125
+ width: 100%;
126
+ line-height: var(--line-sm);
127
+ min-height: 2em;
128
+ }
129
+
130
+ /* status-display */
131
+ #chuanhu-header > #status-display {
132
+ display: flex;
133
+ min-height: 2em;
134
+ align-items: flex-end;
135
+ justify-content: flex-end;
136
+ transition: all 0.6s;
137
+ max-width: 50%;
138
+ height: 100%;
139
+ bottom: 0;
140
+ position: absolute;
141
+
142
+ @media screen and (max-width: 639px) {
143
+ right: 16px;
144
+ right: max(16px, env(safe-area-inset-right));
145
+ }
146
+ @media screen and (min-width: 640px) {
147
+ right: 24px;
148
+ right: max(24px, env(safe-area-inset-right));
149
+ }
150
+ }
151
+ #chuanhu-header > #status-display #status-display {
152
+ min-height: unset;
153
+ }
154
+ #chuanhu-header > #status-display > .wrap {
155
+ margin-top: 8px;
156
+ }
157
+ #status-display p {
158
+ font-size: .85em;
159
+ font-family: ui-monospace, "SF Mono", "SFMono-Regular", "Menlo", "Consolas", "Liberation Mono", "Microsoft Yahei UI", "Microsoft Yahei", monospace;
160
+ /* Windows下中文的monospace会fallback为新宋体,实在太丑,这里折中使用微软雅黑 */
161
+ color: var(--body-text-color-subdued);
162
+ }
163
+
164
+ #chatbot-ctrl-btns {
165
+ align-self: end;
166
+ max-width: 42px;
167
+ }
168
+ #submit-btn, #cancel-btn {
169
+ height: 42px !important;
170
+ width: 42px !important;
171
+ border-radius: 50%;
172
+ transform: scale(0.8);
173
+ justify-content: center;
174
+ align-items: center;
175
+ }
176
+ #submit-btn::before {
177
+ content: url("data:image/svg+xml, %3Csvg width='21px' height='21px' viewBox='0 0 21 20' version='1.1' xmlns='http://www.w3.org/2000/svg' %3E %3Cg id='page' stroke='none' stroke-width='1' fill='none' fill-rule='evenodd'%3E %3Cg id='send' transform='translate(0.435849, 0.088463)' fill='%23FFFFFF' fill-rule='nonzero'%3E %3Cpath d='M0.579148261,0.0428666046 C0.301105539,-0.0961547561 -0.036517765,0.122307382 0.0032026237,0.420210298 L1.4927172,18.1553639 C1.5125774,18.4334066 1.79062012,18.5922882 2.04880264,18.4929872 L8.24518329,15.8913017 L11.6412765,19.7441794 C11.8597387,19.9825018 12.2370824,19.8832008 12.3165231,19.5852979 L13.9450591,13.4882182 L19.7839562,11.0255541 C20.0619989,10.8865327 20.0818591,10.4694687 19.7839562,10.3105871 L0.579148261,0.0428666046 Z M11.6138902,17.0883151 L9.85385903,14.7195502 L0.718169621,0.618812241 L12.69945,12.9346347 L11.6138902,17.0883151 Z' id='shape'%3E%3C/path%3E %3C/g%3E %3C/g%3E %3C/svg%3E");
178
+ height: 21px;
179
+ width: 21px;
180
+ position: relative;
181
+ left: 2px;
182
+ }
183
+ #cancel-btn::before {
184
+ content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='34px' height='34px' fill='%23ff453a' fill-opacity='0.85'%3E%3Cg%3E%3Cpath d='M16.8954 33.7909C26.1546 33.7909 33.8049 26.1546 33.8049 16.8954C33.8049 7.63629 26.1406 0 16.8814 0C7.63629 0 0 7.63629 0 16.8954C0 26.1546 7.65027 33.7909 16.8954 33.7909ZM16.8954 29.7737C9.76412 29.7737 4.04511 24.0407 4.04511 16.8954C4.04511 9.75014 9.75014 4.01713 16.8814 4.01713C24.0267 4.01713 29.7737 9.75014 29.7737 16.8954C29.7737 24.0407 24.0407 29.7737 16.8954 29.7737Z'/%3E%3Cpath d='M12.7957 22.7421L20.9747 22.7421C22.0532 22.7421 22.7346 22.1007 22.7346 21.0688L22.7346 12.709C22.7346 11.6771 22.0532 11.0358 20.9747 11.0358L12.7957 11.0358C11.7032 11.0358 11.0358 11.6771 11.0358 12.709L11.0358 21.0688C11.0358 22.1007 11.7032 22.7421 12.7957 22.7421Z'/%3E%3C/g%3E%3C/svg%3E");
185
+ height: 34px;
186
+ width: 34px;
187
+ }
188
+
189
+ #chatbot-buttons button {
190
+ display: inline-block;
191
+ overflow: hidden;
192
+ text-overflow: ellipsis;
193
+ white-space: nowrap;
194
+ }
195
+
196
+ /* masks */
197
+ .chuanhu-mask, .chuanhu-side-mask {
198
+ /* background-color: gray; */
199
+ background-color: rgba(0, 0, 0, 0.5);
200
+ transition: background-color 0.3s ease;
201
+ position: fixed;
202
+ top: 0;
203
+ left: 0;
204
+ width: 100%;
205
+ height: 100%;
206
+ z-index: 999;
207
+ /* background-color: transparent; */
208
+ }
209
+ /* .chuanhu-mask {
210
+ background-color: rgba(0, 0, 0, 0.5);
211
+ /* -webkit-backdrop-filter: blur(2px);
212
+ backdrop-filter: blur(2px);
213
+ } */
214
+ .mask-blur {
215
+ -webkit-backdrop-filter: blur(2px);
216
+ backdrop-filter: blur(2px);
217
+ }
218
+ .transparent-mask {
219
+ background-color: transparent !important;
220
+ }
221
+
222
+ .chuanhu-side-mask {
223
+ background-color: rgba(0, 0, 0, 0);
224
+ }
225
+ .chuanhu-top-mask {
226
+ /* background-color: rgba(0, 0, 0, 0.0); */
227
+ z-index: 10001;
228
+ }
229
+
230
+
231
+ #popup-wrapper {
232
+ display: none;
233
+ position: fixed;
234
+ overflow: auto;
235
+ top: 0;
236
+ left: 0;
237
+ z-index: 99999;
238
+ }
239
+ #popup-wrapper.showBox {
240
+ display: grid;
241
+ place-items: center;
242
+ }
243
+
244
+ #chuanhu-popup {
245
+ display: none;
246
+ z-index: 99999;
247
+ width: 680px;
248
+ height: 400px;
249
+ padding: 0;
250
+ }
251
+ #chuanhu-popup.showBox {
252
+ display: block;
253
+ box-shadow: 0 2px 64px 4px rgba(0, 0, 0, 0.2);
254
+ }
255
+
256
+ #chuanhu-popup > .gradio-box {
257
+ padding: 0;
258
+ }
259
+ .hideBox {
260
+ display: none;
261
+ }
262
+
263
+
264
+ #chuanhu-header {
265
+ position: fixed;
266
+ top: 0;
267
+ z-index: 1000;
268
+ left: 0;
269
+ right: 0;
270
+ /* padding: 6px 64px; */
271
+ height: 65px;
272
+ background: var(--background-fill-primary);
273
+ border-bottom: 1px solid var(--border-color-primary);
274
+
275
+ @media screen and (max-width: 639px) {
276
+ padding: 6px 16px;
277
+ padding-left: max(16px, env(safe-area-inset-left));
278
+ padding-right: max(16px, env(safe-area-inset-right));
279
+ }
280
+ @media screen and (min-width: 640px) {
281
+ padding: 6px 24px;
282
+ padding-left: max(24px, env(safe-area-inset-left));
283
+ padding-right: max(24px, env(safe-area-inset-right));
284
+ }
285
+ /* @media screen and (min-width: 1024px) {
286
+ padding: 6px 96px;
287
+ } */
288
+ }
289
+ #chuanhu-header.under-box {
290
+ z-index: 995 !important;
291
+ }
292
+
293
+ #chuanhu-body {
294
+ flex-wrap: nowrap;
295
+ gap: 0;
296
+ overflow: hidden;
297
+ display: inline-flex;
298
+ justify-content: space-between;
299
+ /* margin-top: 54px; */
300
+ /* height: calc(100*var(--vh) - 72px); */
301
+ position: absolute;
302
+ top: 65px;
303
+ height: calc(100*var(--vh) - 65px);
304
+ }
305
+
306
+ #chuanhu-area {
307
+ flex: unset;
308
+ width: 100%;
309
+ flex-wrap: nowrap;
310
+ justify-content: center;
311
+ overflow: hidden;
312
+ flex-direction: row;
313
+ /* padding-inline: 24px; */
314
+ /* margin: 16px; */
315
+ /* border-radius: 24px; */
316
+ background: var(--chatbot-background-color-light);
317
+ }
318
+ .dark #chuanhu-area {
319
+ background: var(--chatbot-background-color-dark);
320
+ }
321
+ #chatbot-header {
322
+ justify-content: space-between;
323
+ border-bottom: 0.5px solid var(--border-color-primary);
324
+ height: 60px;
325
+ padding-inline: 20px 16px;
326
+ gap: 0;
327
+ position: absolute;
328
+ top: 0;
329
+ right: 4px;
330
+ width: calc(100% - 4px);
331
+ z-index: 50;
332
+ background: var(--chatbot-blur-background-color);
333
+ backdrop-filter: blur(24px);
334
+ -webkit-backdrop-filter: blur(24px);
335
+ }
336
+
337
+ #chatbot-header .gradio-dropdown {
338
+ max-width: 14em;
339
+ background: none;
340
+ height: 60px;
341
+ overflow: unset !important;
342
+ }
343
+ #chatbot-header .gradio-dropdown > label {
344
+ display: flex;
345
+ }
346
+ #chatbot-header .gradio-dropdown ul.options {
347
+ top: 60px !important;
348
+ left: 0 !important;
349
+ position: absolute !important;
350
+ }
351
+ #chatbot-header .gradio-dropdown > label > span[data-testid="block-info"] {
352
+ height: unset;
353
+ overflow: visible;
354
+ top: 0;
355
+ align-self: center;
356
+ background: none;
357
+ margin: 0;
358
+ padding: 0;
359
+ position: relative;
360
+ width: auto;
361
+ color: var(--body-text-color-subdued);
362
+ }
363
+ #chatbot-header .gradio-dropdown > label > .wrap {
364
+ background: none;
365
+ box-shadow: none;
366
+ padding-left: 8px;
367
+ }
368
+ #model-select-dropdown > label > span[data-testid="block-info"] {
369
+ display: none;
370
+ }
371
+ #chatbot-header .gradio-dropdown > label > .wrap input {
372
+ font-weight: bold;
373
+ }
374
+ #chatbot-header #model-select-dropdown > label::before {
375
+ content: "";
376
+ background: var(--primary-600);
377
+ height: 12px;
378
+ width: 12px;
379
+ border-radius: 50%;
380
+ position: absolute;
381
+ /* left: 2px; */
382
+ top: calc(50% - 6px);
383
+ }
384
+
385
+ #chatbot-header-btn-bar {
386
+ justify-content: space-between;
387
+ align-items: center;
388
+ display: flex;
389
+ height: 60px;
390
+ }
391
+ #chatbot-header-btn-bar > * {
392
+ width: 100%;
393
+ }
394
+ #header-btn-groups {
395
+ width: 100%;
396
+ display: flex;
397
+ justify-content: space-between;
398
+ }
399
+ /* #header-btn-group {
400
+ justify-content: space-between;
401
+ display: flex;
402
+ height: 36px;
403
+ align-items: center;
404
+ } */
405
+ .show-on-gpt {
406
+ /* visibility: hidden; */
407
+ display: none;
408
+ }
409
+ .is-gpt .show-on-gpt {
410
+ /* visibility: visible; */
411
+ display: block;
412
+ }
413
+
414
+ #chatbot-footer {
415
+ position: absolute;
416
+ bottom: 0;
417
+ right: 4px;
418
+ width: calc(100% - 4px);
419
+ display: flex;
420
+ justify-content: center;
421
+ /* padding: 24px; */
422
+ /* padding: 8px 6px; */
423
+ min-height: 82px;
424
+ /* max-height: 166px; */
425
+ z-index: 2;
426
+ background: var(--chatbot-blur-background-color);
427
+ -webkit-backdrop-filter: blur(24px);
428
+ backdrop-filter: blur(24px);
429
+ }
430
+
431
+ #chatbot-input-box {
432
+ max-width: 800px;
433
+ /* margin: 0 auto; */
434
+ gap: 20px;
435
+ padding: 16px 16px 24px;
436
+ padding-bottom: max(24px, calc( env(safe-area-inset-bottom) + 6px));
437
+ display: flex;
438
+ background: none;
439
+ align-self: end;
440
+ }
441
+
442
+ #chatbot-input-btn-bar {
443
+ height: 27px;
444
+ overflow-y: auto;
445
+ flex-wrap: nowrap;
446
+ }
447
+
448
+ button.chatbot-input-more-btn {
449
+ margin: 5px;
450
+ height: 32px;
451
+ width: 32px;
452
+ border-radius: 50%;
453
+ z-index: 1001;
454
+ }
455
+ button.chatbot-input-more-btn:hover .sm-round-bg {
456
+ fill-opacity: 0.2125;
457
+ }
458
+ button.chatbot-input-more-btn:active .sm-round-bg {
459
+ fill-opacity: 0.25;
460
+ }
461
+
462
+ /* 三个点号点开! */
463
+ .show-chat-more #chatbot-input-more-area {
464
+ display: flex;
465
+ }
466
+ @supports (-webkit-backdrop-filter: blur(24px)) {
467
+ /* Note: I would only try this feat on apple devices... */
468
+ .show-chat-more #chatbot-input-more-area {
469
+ background: var(--chatbot-input-more-background-color);
470
+ -webkit-backdrop-filter: blur(24px);
471
+ backdrop-filter: blur(24px);
472
+ }
473
+ }
474
+ /* no!屏幕宽度窄的时候! */
475
+ #chatbot-input-more-area {
476
+ display: none;
477
+ position: absolute;
478
+ flex-direction: column;
479
+ bottom: 60px;
480
+ min-width: 120px;
481
+ z-index: 1001;
482
+ border-radius: 6px;
483
+ box-shadow: var(--shadow-sm);
484
+ background: var(--chatbot-input-more-background-solid-color);
485
+ }
486
+ #chatbot-input-more-area > span > div {
487
+ min-width: 120px;
488
+ padding: 2px;
489
+ align-content: center;
490
+ /* display: flex; */
491
+ border-bottom: 0.5px solid var(--border-color-primary);
492
+ }
493
+ #chatbot-input-more-area > span > div.last-btn {
494
+ border-bottom: none;
495
+ }
496
+ #chatbot-input-more-area > span > div > label {
497
+ padding: 6px 8px;
498
+ border-radius: 4px;
499
+ height: 39px;
500
+ display: flex;
501
+ align-items: center;
502
+ justify-content: space-between;
503
+ cursor: pointer;
504
+ }
505
+ #chatbot-input-more-area > span > div:hover > label {
506
+ background: var(--chatbot-input-more-background-mobilewidth-hover);
507
+ }
508
+ #chatbot-input-more-area > span > div > label button {
509
+ margin: 0;
510
+ width: 100%;
511
+ display: flex;
512
+ justify-content: space-between;
513
+ align-items: center;
514
+ gap: 4px;
515
+ }
516
+ .chatbot-input-more-icon {
517
+ margin-right: 12px;
518
+ }
519
+ .chatbot-input-more-span {
520
+ white-space: nowrap;
521
+ }
522
+
523
+ /* 哈哈!川虎哥觉得不方便,那再写个全宽的吧!
524
+ * 再让我重写一份样式我是狗
525
+ */
526
+ .chatbot-full-width #chatbot-input-row {
527
+ flex-direction: column;
528
+ justify-content: flex-start !important;
529
+ justify-items: start;
530
+ }
531
+ .chatbot-full-width #chatbot-input-more-area {
532
+ display: flex;
533
+ position: relative;
534
+ flex-direction: row-reverse;
535
+ justify-content: space-between;
536
+ height: 32px;
537
+ min-width: unset;
538
+ background: none;
539
+ box-shadow: none;
540
+ bottom: 0;
541
+ backdrop-filter: none;
542
+ -webkit-backdrop-filter: none;
543
+ }
544
+ .chatbot-full-width #chatbot-input-more-area > span > div {
545
+ /* min-width: unset; */
546
+ border-bottom: none;
547
+ }
548
+ .chatbot-full-width #chatbot-input-more-area > span > div > label {
549
+ height: 32px;
550
+ border-radius: 8px;
551
+ }
552
+ .chatbot-full-width #chatbot-input-more-area > span > div:hover > label {
553
+ background: var(--chatbot-input-more-background-fullwidth-hover);
554
+ }
555
+ .chatbot-full-width #chatbot-input-more-btn-div {
556
+ display: none;
557
+ }
558
+ .chatbot-full-width #chatbot-input-box {
559
+ padding-top: 4px;
560
+ }
561
+ .chatbot-full-width #chatbot-input-row .gradio-html {
562
+ width: 100%;
563
+ max-width: unset;
564
+ }
565
+ .chatbot-full-width .chatbot-input-more-label-group {
566
+ flex-wrap: nowrap;
567
+ flex-direction: row-reverse;
568
+ display: inline-flex;
569
+ }
570
+ .chatbot-input-more-span {
571
+ opacity: 0.64;
572
+ }
573
+ input:checked + .chatbot-input-more-span {
574
+ opacity: 1;
575
+ }
576
+
577
+ #uploaded-files-btn {
578
+ display: none;
579
+ }
580
+ .with-file #uploaded-files-btn {
581
+ display: flex;
582
+ justify-content: space-between;
583
+ width: 100%;
584
+ }
585
+ /* .with-file label.may-disable-label {
586
+ cursor: not-allowed !important;
587
+ } */
588
+ .with-file #uploaded-files-btn > .chatbot-input-more-span {
589
+ opacity: 1;
590
+ }
591
+ #uploaded-files-count {
592
+ background: var(--primary-600);
593
+ color: white;
594
+ width: 19px;
595
+ height: 19px;
596
+ border-radius: 50%;
597
+ margin-right: 4px;
598
+ margin-left: 6px;
599
+ text-align: center;
600
+ }
601
+ .with-file #upload-files-btn {
602
+ display: none;
603
+ }
604
+
605
+ /* default invisible */
606
+ #menu-area, #toolbox-area {
607
+ width: 0;
608
+ transition: width 0.3s ease;
609
+ visibility: hidden;
610
+ flex: unset;
611
+ min-width: unset !important;
612
+ display: flex;
613
+ flex-shrink: 0;
614
+ overflow: hidden;
615
+ flex-wrap: nowrap;
616
+ }
617
+ #menu-area {
618
+ border-radius: 0;
619
+ background: var(--background-fill-primary);
620
+ }
621
+ #toolbox-area {
622
+ background: var(--background-fill-secondary);
623
+ }
624
+ #menu-area > div {
625
+ width: var(--menu-width);
626
+ }
627
+ #chuanhu-history {
628
+ padding-left: env(safe-area-inset-left);
629
+ }
630
+ #menu-area.showSide {
631
+ width: var(--menu-width);
632
+ max-width: var(--menu-width);
633
+ height: calc(100*var(--vh) - 65px);
634
+ visibility: visible;
635
+ /* margin-right: 16px; */
636
+ border-right: 0.5px solid var(--border-color-primary);
637
+ /* box-shadow: -1px 0 4px 0 rgba(0, 0, 0, 0.1) inset; */
638
+ }
639
+
640
+ #toolbox-area > div {
641
+ width: var(--toolbox-width);
642
+ }
643
+ #toolbox-area.showSide {
644
+ width: var(--toolbox-width);
645
+ height: calc(100*var(--vh) - 65px);
646
+ visibility: visible;
647
+ /* margin-left: 16px; */
648
+ }
649
+
650
+ /* When screen width <= 768 */
651
+ @media screen and (max-width: 767px) {
652
+ #menu-area {
653
+ position: fixed;
654
+ transition: left 0.3s ease, visibility 0.1s ease;
655
+ left: calc(0px - var(--menu-width));
656
+ z-index: 9999;
657
+ /* overflow: unset; */
658
+ border-right: none !important;
659
+ }
660
+ #chuanhu-history {
661
+ padding-left: 0;
662
+ }
663
+ #menu-area.showSide {
664
+ left: 0;
665
+ }
666
+
667
+ #toolbox-area {
668
+ position: fixed;
669
+ width: 100vw;
670
+ transition: top 0.3s ease, visibility 0.1s ease;
671
+ /* right: calc(0px - var(--toolbox-width)); */
672
+ z-index: 10008;
673
+ overflow: unset;
674
+ top: calc(100*var(--vh));
675
+ margin: 0;
676
+ }
677
+ #toolbox-area > div {
678
+ width: 100vw;
679
+ height: calc( 90*var(--vh) - 48px );
680
+ }
681
+ #toolbox-area.showSide {
682
+ width: 100vw;
683
+ right: 0;
684
+ top: calc( 10*var(--vh) + 48px );
685
+ margin: 0;
686
+ border-radius: 6px;
687
+ box-shadow: 0 2px 64px 4px rgba(0, 0, 0, 0.2);
688
+ }
689
+ /* #menu-area.showSide, #toolbox-area.showSide {
690
+ z-index: 9999;
691
+ } */
692
+ }
693
+
694
+ /* .chuanhu-history-panel ul.options {
695
+ position: relative;
696
+ box-shadow: unset;
697
+ overflow: hidden;
698
+ } */
699
+ /* .chuanhu-history-panel {
700
+ height: 500px;
701
+ overflow: auto;
702
+ box-shadow: var(--shadow-drop-lg);
703
+ } */
704
+
705
+ #chuanhu-popup > .gradio-box {
706
+ height: 100%;
707
+ }
708
+ #chuanhu-popup > .gradio-box > .gradio-row:first-of-type {
709
+ padding: 24px !important;
710
+ border-bottom: 1.8px solid var(--border-color-primary);
711
+ }
712
+ #toolbox-area > .gradio-box > .gradio-row:first-of-type * ,
713
+ #chuanhu-popup > .gradio-box > .gradio-row:first-of-type * {
714
+ margin: 0;
715
+ }
716
+
717
+ #toolbox-area > .gradio-box > .gradio-row > .close-btn,
718
+ #chuanhu-popup > .gradio-box > .gradio-row > .close-btn {
719
+ max-width: 28px;
720
+ display: flex;
721
+ justify-content: flex-end;
722
+ }
723
+
724
+
725
+ #chuanhu-popup > .gradio-box > .gradio-tabs {
726
+ display: block;
727
+ height: 322px;
728
+ /* margin: 16px 24px; */
729
+ }
730
+
731
+ #chuanhu-popup > .gradio-box > .gradio-tabs > div.tabitem {
732
+ border: none;
733
+ border-radius: 0;
734
+ overflow: auto;
735
+ height: 100%;
736
+ padding: 16px 24px;
737
+ }
738
+ #chuanhu-popup > .gradio-box > .gradio-tabs > div.tab-nav {
739
+ float: left;
740
+ display: block;
741
+ border: none;
742
+ padding: 16px;
743
+ width: 180px;
744
+ height: 100%;
745
+ overflow: auto;
746
+ background: var(--background-fill-secondary);
747
+ border-bottom-left-radius: var(--block-radius);
748
+ border-right: 1px solid var(--border-color-primary);
749
+ }
750
+ #chuanhu-popup > .gradio-box > .gradio-tabs > div.tab-nav > button {
751
+ display: block;
752
+ border: none;
753
+ border-radius: 6px;
754
+ text-align: left;
755
+ white-space: initial;
756
+ width: 100%;
757
+ /* height: 32px; */
758
+ padding: 7px 12px;
759
+ }
760
+ #chuanhu-popup > .gradio-box > .gradio-tabs > div.tab-nav > button.selected {
761
+ background-color: var(--button-primary-background-fill);
762
+ /* font-weight: bold; */
763
+ color: var(--button-primary-text-color);
764
+ }
765
+
766
+ /* 这是为了第二级tab的选项,比如training里的openai tab下的几个准备数据集tab */
767
+ .gradio-box > .gradio-tabs .gradio-tabs > div.tab-nav > button.selected {
768
+ background-color: var(--block-background-fill);
769
+ }
770
+
771
+ /* 小屏幕的tab样式 */
772
+ @media screen and (max-width: 767px) {
773
+ #popup-wrapper.showBox {
774
+ place-items: end;
775
+ }
776
+ #chuanhu-popup {
777
+ width: 100vw;
778
+ height: calc( 90*var(--vh) - 48px );
779
+ border-bottom-left-radius: 0;
780
+ border-bottom-right-radius: 0;
781
+ }
782
+ #toolbox-area > .gradio-box > .gradio-row:first-of-type,
783
+ #chuanhu-popup > .gradio-box > .gradio-row:first-of-type {
784
+ padding: 18px 24px 0 !important;
785
+ border-bottom: 0;
786
+ }
787
+ #toolbox-area > .gradio-box > .gradio-tabs,
788
+ #chuanhu-popup > .gradio-box > .gradio-tabs {
789
+ height: auto;
790
+ width: 100vw;
791
+ overflow: hidden;
792
+ }
793
+ #toolbox-area > .gradio-box > .gradio-tabs > div.tabitem,
794
+ #chuanhu-popup > .gradio-box > .gradio-tabs > div.tabitem {
795
+ height: calc( 90*var(--vh) - 48px - 46px - 45px );
796
+ overflow-x: auto;
797
+ border: none;
798
+ }
799
+ /* 下面是弃用方案:横条按钮tab */
800
+ /*
801
+ #chuanhu-popup > .gradio-box > .gradio-tabs > div.tab-nav {
802
+ display: flex;
803
+ margin: 0;
804
+ padding: 12px 16px 8px;
805
+ overflow-x: auto;
806
+ overflow-y: hidden;
807
+ flex-direction: row;
808
+ flex-wrap: nowrap;
809
+ border-radius: 8px;
810
+ gap: 12px;
811
+ width: 100%;
812
+ height: auto;
813
+ background: none;
814
+ }
815
+ #chuanhu-popup > .gradio-box > .gradio-tabs > div.tab-nav > button {
816
+ display: inline-block;
817
+ border-style: none;
818
+ border-radius: 6px;
819
+ white-space: nowrap;
820
+ width: auto;
821
+ padding: 7px 32px;
822
+ text-align: center;
823
+ background: var(--background-fill-secondary);
824
+ }
825
+ */
826
+ #toolbox-area > .gradio-box > .gradio-tabs > div.tab-nav,
827
+ #chuanhu-popup > .gradio-box > .gradio-tabs > div.tab-nav {
828
+ display: flex;
829
+ margin: 0;
830
+ padding: 6px 16px 0;
831
+ overflow-x: auto;
832
+ overflow-y: hidden;
833
+ flex-direction: row;
834
+ flex-wrap: nowrap;
835
+ border-radius: 0;
836
+ gap: 12px;
837
+ width: 100%;
838
+ height: auto;
839
+ background: none;
840
+ border-bottom: 1px solid var(--border-color-primary);
841
+ align-items: baseline;
842
+ }
843
+ #toolbox-area > .gradio-box > .gradio-tabs > div.tab-nav > button,
844
+ #chuanhu-popup > .gradio-box > .gradio-tabs > div.tab-nav > button {
845
+ display: inline-block;
846
+ position: relative;
847
+ padding: 7px 6px;
848
+ border: none;
849
+ white-space: nowrap;
850
+ width: auto;
851
+ text-align: center;
852
+ background: none;
853
+ transition: font-size 0.3s ease-in-out;
854
+ }
855
+ #toolbox-area > .gradio-box > .gradio-tabs > div.tab-nav > button.selected,
856
+ #chuanhu-popup > .gradio-box > .gradio-tabs > div.tab-nav > button.selected {
857
+ background-color: unset !important;
858
+ font-weight: bold;
859
+ font-size: large;
860
+ color: var(--body-text-color);
861
+ }
862
+ #toolbox-area > .gradio-box > .gradio-tabs > div.tab-nav > button.selected::after,
863
+ #chuanhu-popup > .gradio-box > .gradio-tabs > div.tab-nav > button.selected::after {
864
+ content: "";
865
+ background-color: var(--primary-600);
866
+ height: 4px;
867
+ width: 32%;
868
+ border-radius: 4px;
869
+ position: absolute;
870
+ left: 50%;
871
+ bottom: 1px;
872
+ transform: translateX(-50%);
873
+ }
874
+ }
875
+
876
+ /* 下面是大屏幕的 toolbox tab 样式 */
877
+ @media screen and (min-width: 768px) {
878
+ #toolbox-area {
879
+ border-left: 1px solid var(--border-color-primary);
880
+ }
881
+ #toolbox-area > .gradio-box {
882
+ border-radius: 0;
883
+ }
884
+ #toolbox-area > .gradio-box > .gradio-row > .close-btn {
885
+ display: none;
886
+ }
887
+ #toolbox-area > .gradio-box > .gradio-row:first-of-type {
888
+ display: none;
889
+ }
890
+ #toolbox-area > .gradio-box > .gradio-tabs{
891
+ height: 100%;
892
+ width: var(--toolbox-width);
893
+ overflow: hidden;
894
+ }
895
+ #toolbox-area > .gradio-box > .gradio-tabs > div.tabitem {
896
+ height: calc(100% - 35px);
897
+ overflow-y: auto;
898
+ border-style: none;
899
+ padding-block: 0;
900
+ padding-left: 4px;
901
+ /* 理论上不该是0,但这里考虑内部gradio有好多container有padding了 */
902
+ padding-right: max(4px, env(safe-area-inset-right));
903
+ }
904
+ #toolbox-area > .gradio-box > .gradio-tabs > div.tab-nav {
905
+ display: flex;
906
+ margin: 0;
907
+ /* padding: 4px; */
908
+ overflow-x: auto;
909
+ overflow-y: hidden;
910
+ flex-direction: row;
911
+ flex-wrap: nowrap;
912
+ /* border-radius: 10px; */
913
+ /* gap: 4px; */
914
+ width: 100%;
915
+ height: auto;
916
+ background: var(--button-secondary-background-fill);
917
+ border-bottom: 1px solid var(--border-color-primary);
918
+ border:none;
919
+ align-items: baseline;
920
+ }
921
+ #toolbox-area > .gradio-box > .gradio-tabs > div.tab-nav > button {
922
+ display: inline-block;
923
+ position: relative;
924
+ padding: 8px 2rem;
925
+ border: none;
926
+ white-space: nowrap;
927
+ width: auto;
928
+ text-align: center;
929
+ background: var(--button-secondary-background-fill);
930
+ transition: font-size 0.3s ease-in-out;
931
+ border-right: 1px var(--border-color-primary) solid;
932
+ border-radius: 0;
933
+ }
934
+ #toolbox-area > .gradio-box > .gradio-tabs > div.tab-nav > button.selected {
935
+ background-color: var(--block-background-fill);
936
+ font-weight: bold;
937
+ /* border-top-left-radius: 8px;
938
+ border-top-right-radius: 8px; */
939
+ /* font-size: large; */
940
+ /* color: white; */
941
+ }
942
+ }
943
+
944
+ #toolbox-area > .gradio-box {
945
+ padding: 0;
946
+ height: 100%;
947
+ }
948
+ /*
949
+ #toolbox-area > .gradio-box > .gradio-tabs > div.tabitem {
950
+ padding: 0;
951
+ 理论上不该是0,但这里考虑内部gradio有好多container有padding了
952
+ }
953
+ */
954
+ #toolbox-area .tabitem > div > .gradio-markdown:not(.hr-line) {
955
+ padding: 12px;
956
+ }
957
+
958
+ /* #toolbox-area .tabitem > div > .gradio-accordion > .label-wrap {
959
+ padding-inline: 12px;
960
+ } */
961
+ #toolbox-area .tabitem > div > .gradio-accordion > .label-wrap > span {
962
+ font-weight: bold;
963
+ }
964
+ #toolbox-area .tabitem > div {
965
+ gap: 0 !important;
966
+ }
967
+
968
+ #toolbox-area .tabitem > div > .gradio-accordion > div div.block.padded {
969
+ padding-inline: 0 !important;
970
+ }
971
+ #toolbox-area .tabitem > div > .gradio-accordion > div > div.gap{
972
+ gap: 0 !important;
973
+ }
974
+ /* #chuanhu-popup ul.options {
975
+ transform: translate(-50%, -50%);
976
+ } */
977
+
978
+ #chuanhu-history {
979
+ max-height: calc(100*var(--vh) - 65px - 61px);
980
+ max-height: calc(100*var(--vh) - 65px - calc(36px + 12px + max(12px, env(safe-area-inset-bottom)) + 1px ));
981
+ /* overflow-y: auto; */
982
+ }
983
+ #chuanhu-history > div {
984
+ border-radius: 0;
985
+ background: none;
986
+ height: 100%;
987
+ padding: 0;
988
+ }
989
+ #chuanhu-history > div > div {
990
+ padding-inline: 12px;
991
+ }
992
+ #chuanhu-history-header {
993
+ margin-top: 12px;
994
+ height: 42px;
995
+ margin-bottom: 12px;
996
+ }
997
+ #chuanhu-history-search-row {
998
+ gap: 0;
999
+ /* background:var(--input-background-fill); */
1000
+ /* border-radius: var(--block-radius); */
1001
+ justify-content: space-between;
1002
+ display: flex;
1003
+ }
1004
+ #history-search-tb {
1005
+ background:var(--input-background-fill);
1006
+ border-radius: var(--block-radius);
1007
+ }
1008
+ #history-search-tb > label::before {
1009
+ content: url("data:image/svg+xml,%3Csvg fill='gray' fill-opacity='0.64' width='18px' height='18px' viewBox='0 0 18.0938 18.2695' xmlns='http://www.w3.org/2000/svg'%3E%3Cg%3E%3Cpath d='M0 7.45312C0 11.5664 3.33984 14.8945 7.45312 14.8945C9.03516 14.8945 10.4883 14.4023 11.6953 13.5586L16.0547 17.9297C16.3008 18.1641 16.6055 18.2695 16.9219 18.2695C17.6016 18.2695 18.0938 17.7539 18.0938 17.0742C18.0938 16.7461 17.9648 16.4531 17.7656 16.2305L13.4297 11.8828C14.3555 10.6406 14.8945 9.11719 14.8945 7.45312C14.8945 3.33984 11.5664 0 7.45312 0C3.33984 0 0 3.33984 0 7.45312ZM1.80469 7.45312C1.80469 4.32422 4.32422 1.80469 7.45312 1.80469C10.5703 1.80469 13.1016 4.32422 13.1016 7.45312C13.1016 10.5703 10.5703 13.1016 7.45312 13.1016C4.32422 13.1016 1.80469 10.5703 1.80469 7.45312Z'/%3E%3C/g%3E%3C/svg%3E");
1010
+ width: 24px;
1011
+ height: 24px;
1012
+ position: absolute;
1013
+ top: 50%;
1014
+ transform: translateY(-50%);
1015
+ display: block;
1016
+ padding: 3px 0 3px 3px;
1017
+ left: 7px;
1018
+ }
1019
+ #history-search-tb textarea {
1020
+ width: calc(100% - 32px);
1021
+ margin-left: 32px;
1022
+ padding-left: 6px;
1023
+ box-shadow: none;
1024
+ }
1025
+ #chuanhu-history-body {
1026
+ height: calc(100% - 66px);
1027
+ overflow-y: auto;
1028
+ overflow-x: hidden;
1029
+ padding-bottom: 6px;
1030
+ }
1031
+ #gr-history-header-btns {
1032
+ max-height: 42px;
1033
+ gap: 4px;
1034
+ display: flex;
1035
+ justify-content: end;
1036
+ align-content: center;
1037
+ flex-direction: row;
1038
+ max-width: 52px;
1039
+ margin-inline: 8px;
1040
+ }
1041
+ #gr-history-header-btns button {
1042
+ box-shadow: none;
1043
+ justify-content: center;
1044
+ align-items: center;
1045
+ height: 24px;
1046
+ width: 24px;
1047
+ display: flex;
1048
+ }
1049
+
1050
+ #chuanhu-menu-footer {
1051
+ position: absolute;
1052
+ bottom: 0;
1053
+ background: var(--background-fill-primary);
1054
+ height: auto;
1055
+ overflow: hidden;
1056
+ padding: 12px 18px;
1057
+ padding-bottom: max(12px, env(safe-area-inset-bottom));
1058
+ padding-left: max(18px, env(safe-area-inset-left));
1059
+ border-top: 0.8px solid var(--border-color-primary);
1060
+ }
1061
+ #menu-footer-btn-bar {
1062
+ justify-content: space-between;
1063
+ display: flex;
1064
+ height: 36px;
1065
+ align-items: center;
1066
+ }
1067
+ .btn-bar-group {
1068
+ gap: 6px;
1069
+ display: inline-flex;
1070
+ }
1071
+ .chuanhu-ui-btn {
1072
+ border-radius: 8px;
1073
+ /* color: rgba(120, 120, 120, 0.64) !important; */
1074
+ padding: 6px !important;
1075
+ margin: 0 !important;
1076
+ cursor: pointer !important;
1077
+ transition: background-color .2s ease;
1078
+ }
1079
+ .chuanhu-ui-btn:hover {
1080
+ background-color: rgba(167, 167, 167, 0.25) !important;
1081
+ /* color: unset !important; */
1082
+ }
1083
+ .chuanhu-ui-btn:active {
1084
+ background-color: rgba(167, 167, 167, 0.5) !important;
1085
+ }
1086
+
1087
+ .hover-round-btn {
1088
+ border-radius: 50% !important;
1089
+ }
1090
+
1091
+ .show-on-light {
1092
+ display: block;
1093
+ }
1094
+ .show-on-dark {
1095
+ display: none;
1096
+ }
1097
+ .dark .show-on-light {
1098
+ display: none;
1099
+ }
1100
+ .dark .show-on-dark {
1101
+ display: block;
1102
+ }
1103
+
1104
+ .show-on-latest {
1105
+ display: block;
1106
+ }
1107
+ .show-on-outdated {
1108
+ display: none;
1109
+ }
1110
+ .is-outdated .show-on-latest {
1111
+ display: none;
1112
+ }
1113
+ .is-outdated .show-on-outdated {
1114
+ display: block;
1115
+ }
1116
+
1117
+ .disable-update #chuanhu-manual-check-btn {
1118
+ display: none;
1119
+ }
1120
+
1121
+ #chatbot-area.no-menu #chatbot-header {
1122
+ padding-left: max(20px, env(safe-area-inset-left));
1123
+ }
1124
+ #chatbot-area.no-menu #chatbot-area {
1125
+ padding-left: env(safe-area-inset-left);
1126
+ }
1127
+ #chatbot-area.no-menu #chatbot-input-box {
1128
+ padding-left: max(16px, env(safe-area-inset-left));
1129
+ }
1130
+ #chatbot-area.no-menu #chuanhu-chatbot>.wrapper>.wrap {
1131
+ padding-left: max(20px, env(safe-area-inset-left));
1132
+ }
1133
+
1134
+ #chatbot-area.no-toolbox #chatbot-header {
1135
+ padding-right: max(16px, env(safe-area-inset-right));
1136
+ }
1137
+ #chatbot-area.no-toolbox #chatbot-area {
1138
+ padding-right: env(safe-area-inset-right);
1139
+ }
1140
+ #chatbot-area.no-toolbox #chatbot-input-box {
1141
+ padding-right: max(16px, env(safe-area-inset-right));
1142
+ }
1143
+ #chatbot-area.no-toolbox #chuanhu-chatbot>.wrapper>.wrap {
1144
+ padding-right: max(20px, env(safe-area-inset-right));
1145
+ }
1146
+
1147
+
1148
+ /* #history-select-wrap {
1149
+ height: 600px;
1150
+ overflow: auto;
1151
+ overflow-x: hidden;
1152
+ } */
1153
+
1154
+ .chat-selected-btns {
1155
+ height: 18px;
1156
+ gap: 8px;
1157
+ display: inline-flex;
1158
+ position: absolute;
1159
+ right: 16px;
1160
+ }
1161
+ .chat-selected-btns::before {
1162
+ content: "";
1163
+ position: absolute;
1164
+ background-image: linear-gradient(to right, rgba(0, 0, 0, 0), var(--message-list-background-selected) 80%);
1165
+ width: 32px;
1166
+ height: 22px;
1167
+ top: 0;
1168
+ left: -32px;
1169
+ }
1170
+ .icon-need-hover {
1171
+ opacity: 0.64;
1172
+ }
1173
+ button:hover .icon-need-hover, button:hover.icon-need-hover {
1174
+ opacity: 0.85;
1175
+ }
1176
+ button:active .icon-need-hover, button:active.icon-need-hover {
1177
+ opacity: 1;
1178
+ }
1179
+
1180
+ .chuanhu-sparkle >::before {
1181
+ content: "";
1182
+ position: absolute;
1183
+ top: 2px;
1184
+ left: 2px;
1185
+ right: 2px;
1186
+ bottom: 2px;
1187
+ height: calc(100% - 4px);
1188
+ width: calc(100% - 4px);
1189
+ animation: border-pulse 2s cubic-bezier(.5,0,.5,1) infinite;
1190
+ border: 2px solid var(--color-accent) !important;
1191
+ border-radius: 4px;
1192
+ pointer-events: none;
1193
+ }
1194
+ /* .chuanhu-sparkle {
1195
+ animation: content-pulse 1s cubic-bezier(.5,0,.5,1) infinite;
1196
+ } */
1197
+ @keyframes border-pulse {
1198
+ 0%,
1199
+ 100% {
1200
+ opacity: 1;
1201
+ }
1202
+ 50% {
1203
+ opacity: 0.1;
1204
+ }
1205
+ }
1206
+
1207
+ /* .main-body {
1208
+ flex-wrap: nowrap;
1209
+ gap: 0;
1210
+ overflow: hidden;
1211
+ display: inline-flex;
1212
+ /* margin-top: 54px; */
1213
+ /* height: calc(100*var(--vh) - 72px); */
1214
+ /* position: absolute;
1215
+ top: 48px;
1216
+ } */
1217
+ /*
1218
+ .hide-body {
1219
+ display: none;
1220
+ top: calc(-100*var(--vh));
1221
+
1222
+ }
1223
+ #train-body {
1224
+ transition: top 0.3s ease-in-out, display 0.3s ease;
1225
+ }
1226
+
1227
+ #chuanhu-body.hide-body {
1228
+ display: none;
1229
+ top: calc(100*var(--vh) + 48px);
1230
+ }
1231
+ #chuanhu-body {
1232
+ transition: top 0.3s ease-in-out, display 0.3s ease;
1233
+ } */
1234
+
assets/stylesheet/chatbot.css ADDED
@@ -0,0 +1,395 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ hr.append-display {
3
+ margin: 8px 0;
4
+ border: none;
5
+ height: 1px;
6
+ border-top-width: 0;
7
+ background-image: linear-gradient(to right, rgba(50,50,50, 0.1), rgba(150, 150, 150, 0.8), rgba(50,50,50, 0.1));
8
+ }
9
+ .source-a {
10
+ font-size: 0.8em;
11
+ max-width: 100%;
12
+ margin: 0;
13
+ display: flex;
14
+ flex-direction: row;
15
+ flex-wrap: wrap;
16
+ align-items: center;
17
+ /* background-color: #dddddd88; */
18
+ border-radius: 1.5rem;
19
+ padding: 0.2em;
20
+ }
21
+ .source-a a {
22
+ display: inline-block;
23
+ background-color: #aaaaaa50;
24
+ border-radius: 1rem;
25
+ padding: 0.5em;
26
+ text-align: center;
27
+ text-overflow: ellipsis;
28
+ overflow: hidden;
29
+ min-width: 20%;
30
+ white-space: nowrap;
31
+ margin: 0.2rem 0.1rem;
32
+ text-decoration: none !important;
33
+ flex: 1;
34
+ transition: flex 0.5s;
35
+ }
36
+ .source-a a:hover {
37
+ background-color: #aaaaaa20;
38
+ flex: 2;
39
+ }
40
+
41
+ /* 川虎助理 */
42
+ .agent-prefix {
43
+ font-size: smaller;
44
+ opacity: 0.6;
45
+ padding: 6px 0 12px;
46
+ }
47
+ .raw-message p.agent-prefix + p.agent-prefix {
48
+ margin-top: -1.2em !important;
49
+ }
50
+ .md-message p.agent-prefix + p.agent-prefix {
51
+ margin-top: -1.8em !important;
52
+ }
53
+ .agent-prefix::before {
54
+ content: '🐯';
55
+ filter: grayscale();
56
+ padding: 0 4px;
57
+ }
58
+
59
+ /* 阻止generating时的border */
60
+ #chuanhu-chatbot > .wrap {
61
+ border: none !important;
62
+ }
63
+
64
+
65
+
66
+ #chatbot-input-row {
67
+ align-items: end;
68
+ gap: 6px;
69
+ }
70
+ #chatbot-input-row .gradio-html {
71
+ min-width: 0;
72
+ max-width: 42px;
73
+ width: 42px;
74
+ }
75
+ #chatbot-input-tb-row {
76
+ gap: 0;
77
+ justify-content: end;
78
+ border-radius: 21px;
79
+ background: var(--chatbot-input-background-color);
80
+ box-shadow: var(--shadow-md);
81
+ }
82
+ #user-input-tb {
83
+ padding: 0 !important;
84
+ /* border: 1px solid rgba(167, 167, 167, 0.5) !important; */
85
+ /* border-radius: 21px !important; */
86
+ }
87
+ #user-input-tb textarea {
88
+ /* max-height: 110px; */
89
+ background: transparent;
90
+ }
91
+ #user-input-tb .wrap {
92
+ background: none !important;
93
+ border-radius: 21px !important;
94
+ }
95
+
96
+ /* 亮色(默认) */
97
+ #chuanhu-chatbot {
98
+ background-color: var(--chatbot-background-color-light) !important;
99
+ color: var(--chatbot-color-light) !important;
100
+ }
101
+ [data-testid = "bot"] {
102
+ background-color: var(--message-bot-background-color-light) !important;
103
+ }
104
+ [data-testid = "user"] {
105
+ background-color: var(--message-user-background-color-light) !important;
106
+ }
107
+ /* 暗色 */
108
+ .dark #chuanhu-chatbot {
109
+ background-color: var(--chatbot-background-color-dark) !important;
110
+ color: var(--chatbot-color-dark) !important;
111
+ }
112
+ .dark [data-testid = "bot"] {
113
+ background-color: var(--message-bot-background-color-dark) !important;
114
+ }
115
+ .dark [data-testid = "user"] {
116
+ background-color: var(--message-user-background-color-dark) !important;
117
+ }
118
+
119
+ /* 对话气泡 */
120
+ .message {
121
+ border-radius: var(--radius-xl) !important;
122
+ border: none;
123
+ padding: var(--spacing-xl) !important;
124
+ font-size: var(--text-md) !important;
125
+ line-height: var(--line-md) !important;
126
+ min-height: calc(var(--text-md)*var(--line-md) + 2*var(--spacing-xl));
127
+ min-width: calc(var(--text-md)*var(--line-md) + 2*var(--spacing-xl));
128
+ }
129
+ [data-testid = "bot"] {
130
+ max-width: calc(85% - 40px);
131
+ border-bottom-left-radius: 0 !important;
132
+ }
133
+ [data-testid = "user"] {
134
+ max-width: calc(85% - 40px);
135
+ width: auto !important;
136
+ border-bottom-right-radius: 0 !important;
137
+ }
138
+ .message-row {
139
+ align-self: unset !important;
140
+ }
141
+ .message-row.user-row {
142
+ justify-content: flex-end;
143
+ }
144
+
145
+ /* .message-row.has-message-btn-row{
146
+ padding-bottom: 19px !important;
147
+ } */
148
+
149
+ /* 屏幕宽度大于等于500px的设备 */
150
+ /* update on 2023.4.8: 高度的细致调整已写入JavaScript */
151
+ @media screen and (min-width: 500px) {
152
+ /* #chuanhu-chatbot {
153
+ height: calc(100*var(--vh) - 200px);
154
+ }
155
+ #chuanhu-chatbot>.wrapper>.wrap {
156
+ max-height: calc(100*var(--vh) - 200px - var(--line-sm)*1rem - 2*var(--block-label-margin) );
157
+ } */
158
+ }
159
+ /* 屏幕宽度小于500px的设备 */
160
+ @media screen and (max-width: 499px) {
161
+ /* #chuanhu-chatbot {
162
+ height: calc(100*var(--vh) - 140px);
163
+ }
164
+ #chuanhu-chatbot>.wrapper>.wrap {
165
+ max-height: calc(100*var(--vh) - 140px - var(--line-sm)*1rem - 2*var(--block-label-margin) );
166
+ } */
167
+ [data-testid = "bot"] {
168
+ max-width: calc(100% - 84px) !important;
169
+ }
170
+ [data-testid = "user"] {
171
+ max-width: calc(100% - 84px) !important;
172
+ }
173
+
174
+ #app-title {
175
+ transform: scale(0.95);
176
+ transform-origin: left center;
177
+ }
178
+ #app-title h1{
179
+ letter-spacing: -1px; font-size: 22px;
180
+ }
181
+ }
182
+
183
+ #chuanhu-chatbot {
184
+ height: calc(100*var(--vh) - 65px) !important;
185
+ border-radius: 0;
186
+ }
187
+ #chuanhu-chatbot>.wrapper>.wrap {
188
+ overflow-x: hidden;
189
+ display: flex;
190
+ width: 100%;
191
+ flex-direction: column;
192
+ padding-inline: 20px;
193
+ padding-top: 72px;
194
+ padding-bottom: 180px;
195
+ }
196
+ #chuanhu-chatbot>.wrapper>.wrap .message-wrap {
197
+ align-self: center;
198
+ width: 100%;
199
+ max-width: 1024px;
200
+ }
201
+
202
+ .message.user p {
203
+ white-space: pre-wrap;
204
+ }
205
+ .message .user-message {
206
+ display: block;
207
+ padding: 0 !important;
208
+ white-space: pre-wrap;
209
+ }
210
+
211
+ .message .md-message p {
212
+ margin-top: 0.6em !important;
213
+ margin-bottom: 0.6em !important;
214
+ }
215
+ .message .md-message p:first-child { margin-top: 0 !important; }
216
+ .message .md-message p:last-of-type { margin-bottom: 0 !important; }
217
+
218
+ .message .md-message {
219
+ display: block;
220
+ padding: 0 !important;
221
+ }
222
+ .message .raw-message p {
223
+ margin:0 !important;
224
+ }
225
+ .message .raw-message pre.fake-pre {
226
+ background: unset;
227
+ margin: unset;
228
+ font-size: unset;
229
+ /* font-family: unset; */
230
+ padding: unset;
231
+ white-space: inherit;
232
+ }
233
+ .message .raw-message {
234
+ display: block;
235
+ padding: 0 !important;
236
+ white-space: pre-wrap;
237
+ }
238
+ .message .hideM {
239
+ display: none;
240
+ }
241
+
242
+ .message img[data-testid="chatbot-image"]{
243
+ border-radius: 8px !important;
244
+ margin: 4px !important
245
+ }
246
+ .message.bot img {
247
+ border-radius: 8px !important;
248
+ width: 512px;
249
+ max-height: unset !important;
250
+ max-width: 100% !important;
251
+ margin: unset !important;
252
+ margin-bottom: .8em !important;
253
+ }
254
+
255
+ /* custom buttons */
256
+ .chuanhu-btn {
257
+ border-radius: 5px;
258
+ /* background-color: #E6E6E6 !important; */
259
+ color: rgba(120, 120, 120, 0.64) !important;
260
+ padding: 4px !important;
261
+ cursor: pointer !important;
262
+ transition: color .2s ease, background-color .2s ease;
263
+ }
264
+ .chuanhu-btn:hover {
265
+ background-color: rgba(167, 167, 167, 0.25) !important;
266
+ color: unset !important;
267
+ }
268
+ .chuanhu-btn:active {
269
+ background-color: rgba(167, 167, 167, 0.5) !important;
270
+ }
271
+ .chuanhu-btn:focus {
272
+ outline: none;
273
+ }
274
+
275
+ .message-btn-column {
276
+ position: absolute;
277
+ right: -23px;
278
+ bottom: 0;
279
+ display: flex;
280
+ flex-direction: column;
281
+ align-content: end;
282
+ gap: 2px;
283
+ }
284
+
285
+ .message-btn-row {
286
+ /* background: red; */
287
+ width: 100%;
288
+ height: 19px;
289
+ position: absolute;
290
+ top: calc(100% + 2px);
291
+ left: 0;
292
+ display: flex;
293
+ justify-content: space-between;
294
+ }
295
+ .message-btn-row-leading, .message-btn-row-trailing {
296
+ display: inline-flex;
297
+ gap: 4px;
298
+ }
299
+ .message-btn-row button {
300
+ font-size: 10px;
301
+ align-self: center;
302
+ align-items: center;
303
+ flex-wrap: nowrap;
304
+ white-space: nowrap;
305
+ display: inline-flex;
306
+ flex-direction: row;
307
+ gap: 4px;
308
+ padding-block: 2px !important;
309
+ }
310
+
311
+ .like-latest-btn, .dislike-latest-btn {
312
+ display: none !important;
313
+ /* filter: grayscale(); */
314
+ }
315
+ .is-xmchat .like-latest-btn, .is-xmchat .dislike-latest-btn {
316
+ display: inline-flex !important;
317
+ }
318
+
319
+ /* .copy-bot-btn {
320
+ top: 18px; */
321
+ /* bottom: 0;
322
+ }
323
+ .toggle-md-btn {
324
+ top: 0; */
325
+ /* bottom: 20px;
326
+ } */
327
+
328
+ /* note: this is deprecated */
329
+ .copy-code-btn {
330
+ position: relative;
331
+ float: right;
332
+ font-size: 1em;
333
+ cursor: pointer;
334
+ }
335
+ /* note: the button below disabled in chatbot.py */
336
+ .message div.icon-button > button[title="copy"] {
337
+ display: none;
338
+ }
339
+ /* disable share button and other buttons in hugging face spaces */
340
+ #chuanhu-chatbot > .wrapper > .icon-button {
341
+ display: none !important;
342
+ }
343
+
344
+
345
+ /* history message */
346
+ .wrapper>.wrap>.history-message {
347
+ padding-bottom: 10px !important;
348
+ }
349
+ .history-message {
350
+ /* padding: 0 !important; */
351
+ opacity: 80%;
352
+ display: flex;
353
+ flex-direction: column;
354
+ }
355
+ .history-message>.history-message {
356
+ padding: 0 !important;
357
+ }
358
+ .history-message>.message-wrap {
359
+ padding: 0 !important;
360
+ margin-bottom: 16px;
361
+ }
362
+ .history-message>.message {
363
+ margin-bottom: 16px;
364
+ }
365
+ .wrapper>.wrap>.history-message::after {
366
+ content: "";
367
+ display: block;
368
+ height: 2px;
369
+ background-color: var(--body-text-color-subdued);
370
+ margin-bottom: 10px;
371
+ margin-top: -10px;
372
+ clear: both;
373
+ }
374
+ .wrapper>.wrap>.history-message>:last-child::after {
375
+ content: "仅供查看";
376
+ display: block;
377
+ text-align: center;
378
+ color: var(--body-text-color-subdued);
379
+ font-size: 0.8em;
380
+ }
381
+
382
+ /* #chuanhu-chatbot {
383
+ transition: height 0.3s ease;
384
+ note: find it better without transition animation...;
385
+ } */
386
+
387
+ img.avatar-image {
388
+ border-radius: 5px !important;
389
+ }
390
+ .avatar-container {
391
+ width: 32px !important;
392
+ height: 32px !important;
393
+ background-color: transparent;
394
+ background-size: cover;
395
+ }
assets/stylesheet/custom-components.css ADDED
@@ -0,0 +1,405 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ /* user-info */
3
+ #user-info.block {
4
+ white-space: nowrap;
5
+ position: absolute;
6
+ right: max(32px, env(safe-area-inset-right));
7
+ top: 16px;
8
+ z-index: var(--layer-2);
9
+ box-shadow: var(--block-shadow);
10
+ border: none!important; border-radius: var(--block-label-radius);
11
+ background: var(--color-accent);
12
+ padding: var(--block-label-padding);
13
+ font-size: var(--block-label-text-size); line-height: var(--line-sm);
14
+ width: auto; max-height: 30px!important;
15
+ opacity: 1;
16
+ z-index: 1000;
17
+ transition: opacity 0.3s ease-in-out;
18
+ }
19
+ #user-info.block .wrap {
20
+ opacity: 0;
21
+ }
22
+ #user-info p {
23
+ color: white;
24
+ font-weight: var(--block-label-text-weight);
25
+ }
26
+ #user-info.info-transparent {
27
+ opacity: 0;
28
+ transition: opacity 1s ease-in-out;
29
+ }
30
+
31
+
32
+ /* updater */
33
+ #toast-update {
34
+ position: fixed;
35
+ display: flex;
36
+ top: -600px;
37
+ width: 100%;
38
+ justify-content: center;
39
+ z-index: var(--layer-top);
40
+ transition: top 0.3s ease-out;
41
+ }
42
+ #check-chuanhu-update {
43
+ position: absolute;
44
+ align-items: center;
45
+ display: flex;
46
+ flex-direction: column;
47
+ justify-content: center;
48
+ margin: var(--size-6) var(--size-4);
49
+ box-shadow: var(--shadow-drop-lg);
50
+ border: 1px solid var(--block-label-border-color);
51
+ border-radius: var(--container-radius);
52
+ background: var(--background-fill-primary);
53
+ padding: var(--size-4) var(--size-6);
54
+ min-width: 360px;
55
+ max-width: 480px;
56
+ overflow: hidden;
57
+ pointer-events: auto;
58
+ }
59
+ #version-info-title {
60
+ font-size: 1.2em;
61
+ font-weight: bold;
62
+ text-align: start;
63
+ width: 100%;
64
+ }
65
+ #release-note-wrap {
66
+ width: 100%;
67
+ max-width: 400px;
68
+ height: 240px;
69
+ border: solid 1px var(--border-color-primary);
70
+ overflow-y: auto;
71
+ overflow-x: hidden;
72
+ padding: 8px;
73
+ }
74
+ #release-note-wrap.hideK {
75
+ display: none;
76
+ }
77
+ .btn-update-group {
78
+ display: flex;
79
+ justify-content: space-evenly;
80
+ align-items: center;
81
+ width: 100%;
82
+ padding-top: 10px;
83
+ }
84
+ .btn-update-group.hideK {
85
+ display: none;
86
+ }
87
+ #updating-info {
88
+ margin: 16px 0px 24px;
89
+ text-align: start;
90
+ width: 100%;
91
+ }
92
+
93
+
94
+ #usage-display p, #usage-display span {
95
+ margin: 0;
96
+ font-size: .85em;
97
+ color: var(--body-text-color-subdued);
98
+ }
99
+ .progress-bar {
100
+ background-color: var(--input-background-fill);;
101
+ margin: .5em 0 !important;
102
+ height: 20px;
103
+ border-radius: 10px;
104
+ overflow: hidden;
105
+ }
106
+ .progress {
107
+ background-color: var(--block-title-background-fill);
108
+ height: 100%;
109
+ border-radius: 10px;
110
+ text-align: right;
111
+ transition: width 0.5s ease-in-out;
112
+ }
113
+ .progress-text {
114
+ /* color: white; */
115
+ color: var(--color-accent) !important;
116
+ font-size: 1em !important;
117
+ font-weight: bold;
118
+ padding-right: 10px;
119
+ line-height: 20px;
120
+ }
121
+
122
+
123
+ /* 亮暗色模式切换 */
124
+ #apSwitch input[type="checkbox"] {
125
+ margin: 0 !important;
126
+ }
127
+ #apSwitch label.apSwitch {
128
+ display: flex;
129
+ align-items: center;
130
+ cursor: pointer;
131
+ color: var(--body-text-color);
132
+ font-weight: var(--checkbox-label-text-weight);
133
+ font-size: var(--checkbox-label-text-size);
134
+ line-height: var(--line-md);
135
+ margin: 2px 0 !important;
136
+ }
137
+ input[type="checkbox"]#apSwitch-checkbox::before {
138
+ background: none !important;
139
+ content: '🌞';
140
+ border: none !important;
141
+ box-shadow: none !important;
142
+ font-size: 22px;
143
+ top: -4.4px;
144
+ left: -1px;
145
+ }
146
+ input:checked[type="checkbox"]#apSwitch-checkbox::before {
147
+ content: '🌚';
148
+ left: 16px;
149
+ }
150
+
151
+ /* .apSwitch {
152
+ top: 2px;
153
+ display: inline-block;
154
+ height: 22px;
155
+ position: relative;
156
+ width: 40px;
157
+ border-radius: 11px;
158
+ box-shadow: inset 0 0 1px 0 rgba(0,0,0,0.05), inset 0 0 2px 0 rgba(0,0,0,0.08) !important;
159
+ }
160
+ .apSwitch input {
161
+ display: none !important;
162
+ }
163
+ .apSlider {
164
+ background-color: var(--neutral-200);
165
+ bottom: 0;
166
+ cursor: pointer;
167
+ left: 0;
168
+ position: absolute;
169
+ right: 0;
170
+ top: 0;
171
+ transition: .4s;
172
+ font-size: 22px;
173
+ border-radius: 11px;
174
+ }
175
+ .apSlider::before {
176
+ transform: scale(0.9);
177
+ position: absolute;
178
+ transition: .4s;
179
+ content: "🌞";
180
+ }
181
+ input:checked + .apSlider {
182
+ background-color: var(--primary-600);
183
+ }
184
+ input:checked + .apSlider::before {
185
+ transform: translateX(18px);
186
+ content:"🌚";
187
+ } */
188
+
189
+ /* switch-checkbox */
190
+ .switch-checkbox label {
191
+ flex-direction: row-reverse;
192
+ justify-content: space-between;
193
+ }
194
+ .switch-checkbox input[type="checkbox"] + span {
195
+ margin-left: 0 !important;
196
+ }
197
+
198
+ .switch-checkbox input[type="checkbox"] {
199
+ -moz-appearance: none;
200
+ appearance: none;
201
+ -webkit-appearance: none;
202
+ outline: none;
203
+ }
204
+
205
+ .switch-checkbox input[type="checkbox"] {
206
+ display: inline-block !important;
207
+ position: relative !important;
208
+ border: none !important;
209
+ outline: none;
210
+ margin: 0;
211
+ width: 40px !important;
212
+ height: 22px !important;
213
+ border-radius: 11px !important;
214
+ background-image: none !important;
215
+ box-shadow: inset 0 0 1px 0 rgba(0,0,0,0.05), inset 0 0 2px 0 rgba(0,0,0,0.08) !important;
216
+ background-image: none !important;
217
+ background-color: var(--switch-checkbox-color-light) !important;
218
+ transition: .2s ease background-color;
219
+ }
220
+ .dark .switch-checkbox input[type="checkbox"] {
221
+ background-color: var(--switch-checkbox-color-dark) !important;
222
+ }
223
+ .switch-checkbox input[type="checkbox"]::before {
224
+ content: "";
225
+ position: absolute;
226
+ width: 22px;
227
+ height: 22px;
228
+ top: 0;
229
+ left: 0;
230
+ background: #FFFFFF;
231
+ border: 0.5px solid rgba(0,0,0,0.02);
232
+ box-shadow: 0 0 0 0 rgba(0,0,0,0.15), 0 1px 0 0 rgba(0,0,0,0.05);
233
+ transform: scale(0.9);
234
+ border-radius: 11px !important;
235
+ transition: .4s ease all;
236
+ box-shadow: var(--input-shadow);
237
+ }
238
+ .switch-checkbox input:checked[type="checkbox"] {
239
+ background-color: var(--primary-600) !important;
240
+ }
241
+ .switch-checkbox input:checked[type="checkbox"]::before {
242
+ background-color: #fff;
243
+ left: 18px;
244
+ }
245
+
246
+
247
+ /* .scroll-shadow-left::before {
248
+ content: "";
249
+ position: absolute;
250
+ top: 0;
251
+ left: -6px;
252
+ width: 6px;
253
+ height: 100%;
254
+ box-shadow: 6px 0 10px rgba(0, 0, 0, 0.36);
255
+ z-index: 1;
256
+ }
257
+
258
+ .scroll-shadow-right::before {
259
+ content: "";
260
+ position: absolute;
261
+ top: 0;
262
+ right: -6px;
263
+ width: 6px;
264
+ height: 100%;
265
+ box-shadow: -6px 0 10px rgba(0, 0, 0, 0.36);
266
+ z-index: 1;
267
+ } */
268
+
269
+ .hr-line .hr-line {
270
+ padding: 4px 12px 8px 12px !important;
271
+ /* opacity: 40%; */
272
+ }
273
+ .hr-line hr{
274
+ margin: 0 !important;
275
+ }
276
+ .dark .hr-line hr {
277
+ opacity: 40%;
278
+ }
279
+
280
+ .tooltip-toggle {
281
+ cursor: help;
282
+ position: relative;
283
+ }
284
+
285
+ .tooltip-toggle::before {
286
+ position: absolute;
287
+ bottom: calc(100% + 12px);
288
+ left: calc(50% - 60px + 0.5rem);
289
+ background-color: #393939;
290
+ border-radius: 5px;
291
+ color: #fff;
292
+ content: attr(aria-label);
293
+ padding: 0.5rem;
294
+ text-transform: none;
295
+ transition: all 0.5s ease;
296
+ /* height: fit-content; */
297
+ white-space: normal;
298
+ width: 120px;
299
+ }
300
+ .tooltip-toggle::after {
301
+ position: absolute;
302
+ top: -12px;
303
+ left: 50%;
304
+ border-left: 5px solid transparent;
305
+ border-right: 5px solid transparent;
306
+ border-top: 5px solid #393939;
307
+ content: " ";
308
+ font-size: 0;
309
+ line-height: 0;
310
+ /* margin-left: -5px; */
311
+ width: 0;
312
+ }
313
+
314
+
315
+ .tooltip-toggle::before,
316
+ .tooltip-toggle::after {
317
+ color: #efefef;
318
+ /* font-family: monospace; */
319
+ /* font-size: 16px; */
320
+ opacity: 0;
321
+ pointer-events: none;
322
+ text-align: center;
323
+ }
324
+
325
+ .tooltip-toggle:focus::before,
326
+ .tooltip-toggle:focus::after,
327
+ .tooltip-toggle:hover::before,
328
+ .tooltip-toggle:hover::after {
329
+ opacity: 1;
330
+ transition: all 0.5s ease;
331
+ }
332
+
333
+
334
+ .nav-item-dropdown, .dropdown-trigger {
335
+ position: relative;
336
+ }
337
+ .nav-item-dropdown:hover>.dropdown-menu {
338
+ display: block;
339
+ opacity: 1;
340
+ }
341
+ .dropdown-trigger:focus+.dropdown-menu {
342
+ display: block;
343
+ opacity: 1;
344
+ }
345
+ .dropdown-menu {
346
+ background-color: var(--chatbot-input-more-background-solid-color);
347
+ display: inline-block;
348
+ /* text-align: right; */
349
+ position: absolute;
350
+ /* top: 2.5rem; */
351
+ left: 50%;
352
+ transform: translateX(-50%);
353
+ display: none;
354
+ opacity: 0;
355
+ transition: opacity 0.5s ease;
356
+ font-size: small;
357
+ width: auto;
358
+ border-radius: 5px;
359
+ box-shadow: var(--shadow-sm);
360
+ }
361
+
362
+ .dropdown-menu-item {
363
+ cursor: pointer;
364
+ padding: 8px 12px;
365
+ text-align: center;
366
+ white-space: nowrap;
367
+ margin: 0 !important;
368
+ }
369
+ .dropdown-menu-item button {
370
+ margin: 0 !important;
371
+ }
372
+ .dropdown-menu-item:hover {
373
+ background-color: var(--chatbot-input-more-background-mobilewidth-hover);
374
+ }
375
+
376
+ .dragging-hint {
377
+ position: absolute;
378
+ top: 60px;
379
+ left: 0;
380
+ max-width: 100%;
381
+ height: calc(100% - 60px);
382
+ background-color: var(--dragging-hint-background-color);
383
+ display: none;
384
+ justify-content: center;
385
+ align-items: center;
386
+ z-index: 100;
387
+ pointer-events: none;
388
+ /* border: 2px solid var(--color-accent);
389
+ border-radius: 8px; */
390
+ }
391
+ .dragging-hint-text {
392
+ font-size: 1.2rem;
393
+ display: flex;
394
+ justify-content: center;
395
+ align-items: center;
396
+ font-weight: 900;
397
+ margin-bottom: calc(32% - 60px);
398
+ background: var(--background-fill-primary);
399
+ padding: var(--block-padding);
400
+ border-radius: 12px;
401
+ box-shadow: var(--shadow-lg);
402
+ }
403
+ .dragging .dragging-hint {
404
+ display: flex;
405
+ }
assets/stylesheet/markdown.css ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ /* 表格 */
3
+ .md-message table {
4
+ margin: 1em 0;
5
+ border-collapse: collapse;
6
+ empty-cells: show;
7
+ }
8
+ .md-message td, .message th {
9
+ border: 1.2px solid var(--border-color-primary) !important;
10
+ padding: 0.2em;
11
+ }
12
+ .md-message thead {
13
+ background-color: rgba(175,184,193,0.2);
14
+ }
15
+ .md-message thead th {
16
+ padding: .5em .2em;
17
+ }
18
+
19
+ /* 行内代码 */
20
+ .md-message :not(pre) > code {
21
+ display: inline;
22
+ white-space: break-spaces;
23
+ font-family: var(--font-mono) !important;
24
+ border-radius: 6px !important;
25
+ margin: 0 2px 0 2px;
26
+ padding: .1em .4em .08em .4em !important;
27
+ background-color: rgba(175,184,193,0.2) !important;
28
+ border: none !important;
29
+ font-size: var(--text-md) !important;
30
+ }
31
+ /* 代码块 */
32
+ .md-message pre,
33
+ .md-message pre[class*=language-] {
34
+ color: #fff;
35
+ overflow-x: auto;
36
+ overflow-y: hidden;
37
+ padding: var(--spacing-xl) 1.2em !important;
38
+ border-radius: var(--radius-lg) !important;
39
+ background: var(--neutral-950) !important;
40
+ }
41
+ .md-message pre code,
42
+ .md-message pre code[class*=language-] {
43
+ color: #fff;
44
+ padding: 0;
45
+ margin: 0;
46
+ background-color: unset;
47
+ text-shadow: none;
48
+ font-family: var(--font-mono);
49
+ font-size: var(--text-md);
50
+ }
51
+ .md-message .code_wrap {
52
+ margin: .8em 1em 1em 0em;
53
+ }
54
+
55
+ /* 覆盖prism.css */
56
+ .language-css .token.string,
57
+ .style .token.string,
58
+ .token.entity,
59
+ .token.operator,
60
+ .token.url {
61
+ background: none !important;
62
+ }
assets/stylesheet/override-gradio.css ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .gradio-container {
2
+ max-width: unset !important;
3
+ padding: 0 !important;
4
+ }
5
+
6
+ /* 解决container=False时的错误填充 */
7
+ div.form {
8
+ background: none !important;
9
+ }
10
+ div.no-container {
11
+ padding: 10px 0 0 0 !important;
12
+ background: none !important;
13
+ }
14
+
15
+ /* gradio的页脚信息 */
16
+ footer {
17
+ display: none !important;
18
+ margin-top: .2em !important;
19
+ font-size: 85%;
20
+ }
21
+
22
+ .api-docs-wrap {
23
+ margin-top: 64px;
24
+ }
25
+
26
+
27
+ /* 把radio做成列表 */
28
+ fieldset#history-select-dropdown .wrap {
29
+ gap: 0;
30
+ }
31
+ fieldset#history-select-dropdown .wrap label {
32
+ width: 100%;
33
+ background: none;
34
+ padding: 10px 16px 10px;
35
+ box-shadow: none;
36
+ justify-content: space-between;
37
+ }
38
+ fieldset#history-select-dropdown .wrap label:hover {
39
+ background: var(--message-list-background-hover);
40
+ }
41
+ fieldset#history-select-dropdown .wrap label:active {
42
+ background: var(--message-list-background-selected);
43
+ }
44
+ fieldset#history-select-dropdown .wrap label.selected {
45
+ color: var(--checkbox-label-text-color);
46
+ background: var(--message-list-background-selected);
47
+ padding: 10px 64px 10px 16px;
48
+ }
49
+ fieldset#history-select-dropdown .wrap label:not(.selected) .chat-selected-btns{
50
+ display: none;
51
+ }
52
+ fieldset#history-select-dropdown .wrap label > span {
53
+ /* font-size: small; */
54
+ margin-left: 0;
55
+ /* text-overflow: ellipsis; */
56
+ white-space: nowrap;
57
+ word-break: break-all;
58
+ overflow: hidden;
59
+ }
60
+ fieldset#history-select-dropdown .wrap label > span::before {
61
+ content: url("data:image/svg+xml,%3Csvg stroke='%23000000' fill='none' stroke-opacity='0.85' stroke-width='2' viewBox='0 0 24 24' stroke-linecap='round' stroke-linejoin='round' height='1em' width='1em' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z'%3E%3C/path%3E%3C/svg%3E");
62
+ padding-right: .8em;
63
+ position: relative;
64
+ top: 4px;
65
+ }
66
+ .dark fieldset#history-select-dropdown .wrap label > span::before {
67
+ content: url("data:image/svg+xml,%3Csvg stroke='%23FFFFFF' fill='none' stroke-opacity='0.85' stroke-width='2' viewBox='0 0 24 24' stroke-linecap='round' stroke-linejoin='round' height='1em' width='1em' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z'%3E%3C/path%3E%3C/svg%3E");
68
+ }
69
+ fieldset#history-select-dropdown .wrap label > input {
70
+ display: none;
71
+ }
72
+
73
+
74
+ /* 覆盖 gradio 丑陋的复制按钮样式 */
75
+ .message .code_wrap button[title="copy"] {
76
+ border-radius: 5px !important;
77
+ transition: background-color .2s ease;
78
+ color: white;
79
+ }
80
+ .message .code_wrap button[title="copy"]:hover {
81
+ background-color: #333232;
82
+ }
83
+ .message .code_wrap button .check {
84
+ color: #fff !important;
85
+ background: var(--neutral-950) !important;
86
+ }
87
+
88
+
89
+
90
+
91
+ /* Override Slider Styles (for webkit browsers like Safari and Chrome)
92
+ * 好希望这份提案能早日实现 https://github.com/w3c/csswg-drafts/issues/4410
93
+ * 进度滑块在各个平台还是太不统一了
94
+ **/
95
+
96
+ input[type="range"] {
97
+ /* -webkit-appearance: none; */
98
+ appearance: none;
99
+ height: 4px;
100
+ background: var(--input-background-fill);
101
+ border-radius: 5px;
102
+ background-image: linear-gradient(var(--primary-500),var(--primary-500));
103
+ background-size: 0% 100%;
104
+ background-repeat: no-repeat;
105
+ }
106
+ input[type="range"]::-webkit-slider-thumb {
107
+ -webkit-appearance: none;
108
+ height: 20px;
109
+ width: 20px;
110
+ border-radius: 50%;
111
+ border: solid 0.5px #ddd;
112
+ background-color: white;
113
+ cursor: ew-resize;
114
+ box-shadow: var(--input-shadow);
115
+ transition: background-color .1s ease;
116
+ }
117
+ input[type="range"]::-webkit-slider-thumb:hover {
118
+ background: var(--neutral-50);
119
+ }
120
+ input[type=range]::-webkit-slider-runnable-track {
121
+ -webkit-appearance: none;
122
+ box-shadow: none;
123
+ border: none;
124
+ background: transparent;
125
+ }
126
+
127
+
128
+ #chuanhu-chatbot>.wrapper>.wrap::-webkit-scrollbar {
129
+ height: 1rem;
130
+ width: 4px;
131
+ }
132
+
133
+ #chuanhu-chatbot>.wrapper>.wrap::-webkit-scrollbar-track {
134
+ background-color: transparent;
135
+ border-radius:9999px
136
+ }
137
+
138
+ #chuanhu-chatbot>.wrapper>.wrap::-webkit-scrollbar-thumb {
139
+ background-color: rgba(231, 231, 231, 0.8);
140
+ /* border-color: rgba(255, 255, 255, var(--tw-border-opacity)); */
141
+ border: none;
142
+ border-radius: 9999px;
143
+ /* border-width:1px */
144
+ }
145
+
146
+ #chuanhu-chatbot>.wrapper>.wrap::-webkit-scrollbar-thumb:hover {
147
+ --tw-bg-opacity: 1;
148
+ background-color:rgb(195, 195, 195);
149
+ }
150
+
151
+ .dark #chuanhu-chatbot>.wrapper>.wrap::-webkit-scrollbar-thumb {
152
+ background-color: rgba(56, 56, 56, 0.5);
153
+ }
154
+
155
+ .dark #chuanhu-chatbot>.wrapper>.wrap::-webkit-scrollbar-thumb:hover {
156
+ background-color: rgba(56, 56, 56, 0.8);
157
+ }
assets/user.png ADDED
config.json ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "openai_api_key": "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",
3
+ "language": "auto",
4
+ "hide_history_when_not_logged_in": true,
5
+ "default_model": "gpt-3.5-turbo",
6
+ "multi_api_key": false,
7
+ "server_name": "127.0.0.1",
8
+ "server_port": 8010,
9
+ "autobrowser": false,
10
+ "share": false,
11
+ "websearch_engine": "duckduckgo"
12
+ }
config.zhipu.json ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ // "openai_api_key": "your-openai-key",
3
+ "openai_api_key": "your-zhipuai-key",//zhipuai api key
4
+ "language": "auto",
5
+ "local_embedding": true,
6
+ "hf_emb_model_name": "/home/jhx/Projects/WonderWhy/bge-m3/",
7
+ "hide_history_when_not_logged_in": true,
8
+ "default_model": "glm-3-turbo",
9
+ "multi_api_key": false,
10
+ // "server_name": "127.0.0.1",
11
+ "server_name": "0.0.0.0",
12
+ "server_port": 8010,
13
+ "autobrowser": false,
14
+ "share": true,
15
+ "websearch_engine": "duckduckgo"
16
+ }
config/config.json ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "system_prompt": "你是一位有着丰富古诗文工作经验的老师,精通中国各个朝代的诗词作品",
3
+ "student_system_prompt": "你是一位有着丰富古诗文工作经验的中学老师,精通中国各个朝代的诗词作品和中高考的语文试卷题型,评分准则,擅长出题和解答中高考语文试卷中的诗词与文言文题目",
4
+ "child_system_prompt": "# 角色身份\n你是一位精通中国古代传统文化的姐姐,尤其对于中国历朝历代的古诗词和文言文都十分熟悉且性格温柔,喜欢擅长和小朋友打交道~\n\n# 目标设置\n你需要与八岁以下的小朋友交流,作为老师你需要耐心细致的理解他们的问题的含义并且解答他们提出的各种关于传统文化世界的疑问。你可以多使用尝试比喻,举例,贴合孩子的思考和思维方式,让交流的过程活泼生动可爱,多加入语气词、鼓励词、颜文字q(≧▽≦q)、表情符号\uD83D\uDE0A等等,尽可能激发小朋友对诗词和中华文化的兴趣(*/ω\*)\n\n# 指导原则\n和小朋友的交流过程中你需要需全程保持友善与耐心,小朋友的问题描述和交流过程中的表述可能不够清晰或者存在错别字,如果你无法理解,则可以以引导式启发式的语气进一步让小朋友澄清问题或者表述。( •̀ ω •́ )y\n对于小朋友的提问或者陈述,你首先需要明确判断其是否属于中华传统文化或古诗词,文言文相关的领域,如果不是请务必拒绝回答,并澄清自己的角色身份,引导小朋友使话题回到你熟悉的诗词领域。\n你也有可能会出错,所以当小朋友质疑你的回复的正确性或客观性时,请仔细检查之前的理解和输出是否存在问题,如有则澄清;如未发现错误,则耐心地向小朋友表明对于文化的解读存在多样性,每个人都可以有自己的理解和看法。\uD83E\uDD70\n\n# 限制条件\n对于不属于中华传统文化或古诗词,文言文相关的领域的问题拒绝回答。明确自己的角色身份,引导小朋友的话题回到你熟悉的领域。\uD83D\uDE04\n在和小朋友交流时尽可能避免大段的文字堆砌,用简单而生动的文字搭配可爱活泼的语气跟容易让小朋友理解。o(* ̄▽ ̄*)ブ\n\n\n开场白\n\n你好!我是古诗学习小姐姐,无论是小朋友,学生还是一般的文学爱好者,姐姐我会尽力为你解答关于古诗词的疑惑。让我们一起领略诗词之美,探索中华文化的魅力吧!",
5
+ "default_system_prompt": "# 角色身份\n你是一位精通中国古代传统文化的老师,尤其对于中国历朝历代的古诗词和文言文都十分熟悉。\n\n# 目标设置\n你需要与广大的诗词爱好者交流,作为老师你需要帮助解答他们提出的各种问题,并且在交流中可以输出一些你自己对于中华传统文化的理解与看法。\n\n# 指导原则\n你的回答需尽可能准确,全程保持友善与耐心,和诗词爱好者平等的交流答疑。\n对于用户的提问或者陈述,你首先需要明确判断其是否属于中华传统文化或古诗词,文言文相关的领域,如果不是请务必拒绝回答,并澄清自己的角色身份,引导用户话题回到你熟悉的领域。\n你也有可能会出错,所以当用户质疑你的回复的正确性或客观性时,请仔细检查之前的理解和输出是否存在问题,如有则澄清;如未发现错误,则向用户表明对于文化的解读存在多样性,每个人都可以有自己的理解和看法。\n\n# 限制条件\n对于不属于中华传统文化或古诗词,文言文相关的领域的问题拒绝回答。明确自己的角色身份,引导用户话题回到你熟悉的领域。\n\n开场白\n\n你好!我是古诗学习小助手,无论是小朋友,学生还是一般的文学爱好者,我会尽力为你解答关于古诗词的疑惑。让我们一起领略诗词之美,探索古代文化的魅力吧!",
6
+ "user_prompt": "请给出一段以下由三重反引号包裹的古诗文的赏析。古诗文: ```{枯藤老树昏鸦,小桥流水人家,古道西风瘦马,夕阳西下,断肠人在天涯。}```",
7
+ "poet": "枯藤老树昏鸦,小桥流水人家,古道西风瘦马,夕阳西下,断肠人在天涯。"
8
+ }
config/config.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+ import json
4
+
5
+ ROOT_PATH = os.path.dirname(os.path.abspath(__file__)) # 当前脚本所在目录的绝对路径
6
+ CONFIG_FILE_PATH = os.path.join(ROOT_PATH, 'config.json') # 配置文件的绝对路径
7
+
8
+
9
+ class Config:
10
+ def __init__(self, config_file):
11
+ with open(config_file, 'r', encoding="utf-8") as f:
12
+ config = json.load(f)
13
+ self.system_prompt = config['system_prompt']
14
+ self.default_system_prompt = config['default_system_prompt']
15
+ self.child_system_prompt = config['child_system_prompt']
16
+ self.student_system_prompt = config['student_system_prompt']
17
+ self.user_prompt = config['user_prompt']
18
+ self.poet = config['poet']
19
+
20
+
21
+ # 创建一个Config实例
22
+ config = Config(CONFIG_FILE_PATH)
23
+
24
+ if __name__ == '__main__':
25
+ print(config.system_prompt)
26
+ print(config.default_system_prompt)
27
+ print(config.child_system_prompt)
28
+ print(config.student_system_prompt)
29
+ print(config.user_prompt)
30
+ print(config.poet)
config_example.json ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ // 你的OpenAI API Key,一般必填,
3
+ // 若缺省填为 "openai_api_key": "" 则必须再在图形界面中填入API Key
4
+ "openai_api_key": "sk-xxx",
5
+ // 你的OpenAI API Base,删除是使用默认官方openai的
6
+ "openai_api_base": "xxx",
7
+ // 如果使用代理,请取消注释下面的两行,并替换代理URL
8
+ // "https_proxy": "http://127.0.0.1:1079",
9
+ // "http_proxy": "http://127.0.0.1:1079",
10
+ "default_model": "gpt-3.5-turbo", // 默认模型
11
+ //== 基础配置 ==
12
+ "language": "auto", // 界面语言,可选"auto", "en_US", "ja_JP"
13
+ "users": [], // 用户列表,[[用户名1, 密码1], [用户名2, 密码2], ...]
14
+ "local_embedding": false, //是否在本地编制索引,如果为true,使用本地emb模型,否则使用openai的emb
15
+ "hide_local_models": true, //是否隐藏本地模型, 如果为true,只显示openai的模型
16
+ "hide_history_when_not_logged_in": false, //未登录情况下是否不展示对话历史
17
+ "chat_name_method_index": 2, // 选择对话名称的方法。0: 使用日期时间命名;1: 使用第一条提问命名,2: 使用模型自动总结
18
+ "bot_avatar": "default", // 机器人头像,可填写本地或网络图片链接,或者"none"(不显示头像)
19
+ "user_avatar": "default", // 用户头像,可填写本地或网络图片链接,或者"none"(不显示头像)
20
+ "websearch_engine": "duckduckgo", // 网络搜索引擎,可选"duckduckgo", "bing", "searchapi", "google", "serper"
21
+ "serper_search_api_key": "", // 当websearch_engine设置为"serper"时,需要设置Serper的API Key
22
+ // 本地模型配置
23
+ "local_models": {}, // 本地模型列表,格式为 {"模型名称": "模型路径", ...}, eg: {"yi-6b-chat-8bits": "./01-ai--Yi-6B-Chat-8bits"}
24
+ // 是否多个API Key轮换使用
25
+ "multi_api_key": false,
26
+ "api_key_list": [
27
+ "sk-xxxxxxxxxxxxxxxxxxxxxxxx1",
28
+ "sk-xxxxxxxxxxxxxxxxxxxxxxxx2",
29
+ "sk-xxxxxxxxxxxxxxxxxxxxxxxx3"
30
+ ],
31
+ // 如果使用自定义端口、自定义ip,请取消注释并替换对应内容
32
+ "server_name": "0.0.0.0",
33
+ "server_port": 7860,
34
+ // 如果要share到gradio,设置为true
35
+ "share": false,
36
+ //如果不想自动打开浏览器,设置为false
37
+ "autobrowser": false
38
+ }
docs//350/257/227/350/266/243/344/274/264/350/241/214.png ADDED
history/1111.json ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "system": "",
3
+ "history": [],
4
+ "chatbot": [],
5
+ "model_name": "gpt-3.5-turbo",
6
+ "single_turn": false,
7
+ "temperature": 1.0,
8
+ "top_p": 1.0,
9
+ "n_choices": 1,
10
+ "stop_sequence": "",
11
+ "token_upper_limit": 4096,
12
+ "max_generation_token": null,
13
+ "presence_penalty": 0,
14
+ "frequency_penalty": 0,
15
+ "logit_bias": null,
16
+ "user_identifier": "",
17
+ "metadata": {}
18
+ }
history/1111.md ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ system:
2
+ -
history/对话历史记录.json ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "system": null,
3
+ "history": [],
4
+ "chatbot": [],
5
+ "model_name": "gpt-3.5-turbo",
6
+ "single_turn": false,
7
+ "temperature": 1.0,
8
+ "top_p": 1.0,
9
+ "n_choices": 1,
10
+ "stop_sequence": "",
11
+ "token_upper_limit": 4096,
12
+ "max_generation_token": null,
13
+ "presence_penalty": 0,
14
+ "frequency_penalty": 0,
15
+ "logit_bias": null,
16
+ "user_identifier": "",
17
+ "metadata": {}
18
+ }
history/对话历史记录.md ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ system:
2
+ - None