vansin commited on
Commit
f3f614f
1 Parent(s): caffddc

feat: update

Browse files
Files changed (50) hide show
  1. app.py +20 -0
  2. dist/assets/background-95159880.png +0 -0
  3. dist/assets/index-26b4a389.js +0 -0
  4. dist/assets/index-ab4095ce.css +1 -0
  5. dist/assets/index-legacy-f957e103.js +0 -0
  6. dist/assets/logo-38417354.svg +24 -0
  7. dist/assets/pack-up-ad0b3cbc.svg +4 -0
  8. dist/assets/polyfills-legacy-0b55db5f.js +1 -0
  9. dist/assets/sendIcon-79e92e84.svg +4 -0
  10. dist/assets/show-right-icon-12c14da5.png +0 -0
  11. dist/index.html +21 -0
  12. frontend/React/.gitignore +20 -0
  13. frontend/React/.prettierignore +7 -0
  14. frontend/React/.prettierrc.json +7 -0
  15. frontend/React/README.md +132 -0
  16. frontend/React/index.html +14 -0
  17. frontend/React/package-lock.json +0 -0
  18. frontend/React/package.json +49 -0
  19. frontend/React/src/App.module.less +54 -0
  20. frontend/React/src/App.tsx +23 -0
  21. frontend/React/src/assets/background.png +0 -0
  22. frontend/React/src/assets/fold-icon.svg +3 -0
  23. frontend/React/src/assets/logo.svg +24 -0
  24. frontend/React/src/assets/pack-up.svg +4 -0
  25. frontend/React/src/assets/sendIcon.svg +4 -0
  26. frontend/React/src/assets/show-right-icon.png +0 -0
  27. frontend/React/src/assets/unflod-icon.svg +3 -0
  28. frontend/React/src/components/iconfont/index.tsx +7 -0
  29. frontend/React/src/config/cgi.ts +2 -0
  30. frontend/React/src/global.d.ts +1 -0
  31. frontend/React/src/index.less +62 -0
  32. frontend/React/src/index.tsx +10 -0
  33. frontend/React/src/pages/render/index.module.less +848 -0
  34. frontend/React/src/pages/render/index.tsx +681 -0
  35. frontend/React/src/pages/render/mindMapItem.tsx +39 -0
  36. frontend/React/src/routes/routes.tsx +38 -0
  37. frontend/React/src/utils/tools.ts +24 -0
  38. frontend/React/src/vite-env.d.ts +9 -0
  39. frontend/React/tsconfig.json +24 -0
  40. frontend/React/vite.config.ts +62 -0
  41. frontend/React/windows-.png +0 -0
  42. frontend/mindsearch_gradio.py +142 -0
  43. frontend/mindsearch_streamlit.py +319 -0
  44. mindsearch/agent/__init__.py +60 -0
  45. mindsearch/agent/mindsearch_agent.py +408 -0
  46. mindsearch/agent/mindsearch_prompt.py +326 -0
  47. mindsearch/agent/models.py +40 -0
  48. mindsearch/app.py +128 -0
  49. mindsearch/terminal.py +50 -0
  50. requirements.txt +12 -0
app.py ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ from flask import Flask, send_from_directory
4
+
5
+
6
+ app = Flask(__name__, static_folder='dist')
7
+
8
+ @app.route('/')
9
+ def serve_index():
10
+ return send_from_directory(app.static_folder, 'index.html')
11
+
12
+ @app.route('/<path:path>')
13
+ def serve_file(path):
14
+ return send_from_directory(app.static_folder, path)
15
+
16
+ if __name__ == '__main__':
17
+ app.run(debug=False, port=7860, host="0.0.0.0")
18
+
19
+
20
+ os.system("python -m mindsearch.app --lang en --model_format internlm_server")
dist/assets/background-95159880.png ADDED
dist/assets/index-26b4a389.js ADDED
The diff for this file is too large to render. See raw diff
 
dist/assets/index-ab4095ce.css ADDED
@@ -0,0 +1 @@
 
 
1
+ body,html,#root{padding:0;margin:0;width:100%;height:100%;font-family:PingFang SC;font-size:14px;line-height:21px}#global__message-container{position:fixed;left:0;right:0;top:72px;z-index:999;display:flex;flex-direction:column;justify-content:center;align-items:center}.f{color:#6674d6;font-family:DIN;font-size:12px;font-style:normal;font-weight:500;line-height:14px;position:relative;top:-4px;padding:0 3px}.f:after{content:"·";position:absolute;top:0;right:-2px;color:#6674d6}p>:nth-last-child(1).f:after,li>:nth-last-child(1).f:after{content:"";opacity:0}.fnn2{color:#6674d6;font-family:DIN;font-size:14px;font-style:normal;font-weight:500;line-height:14px;position:relative;top:-2px}._app_1k3bk_1{height:100%;display:flex;justify-content:space-between;background:url(/assets/background-95159880.png) #f7f8ff;background-size:cover;overflow:hidden}._content_1k3bk_9{padding-top:64px;width:100%;height:100%;box-sizing:border-box}._header_1k3bk_15{position:fixed;padding:16px 32px;width:100%;display:flex;align-items:center;box-sizing:border-box}._header-nav_1k3bk_23{flex:1}._header-nav_1k3bk_23 img{height:40px}._header-nav_1k3bk_23 a{display:inline-block;text-decoration:none;color:#000}._header-nav_1k3bk_23 a:not(:first-of-type){margin-left:40px}._header-nav_1k3bk_23 a._active_1k3bk_37{font-weight:700}._header-opt_1k3bk_40{flex-shrink:0;display:flex;align-items:center}._mainPage_6absh_1{display:flex;justify-content:flex-start;align-items:flex-start;padding:0 60px 60px;height:100%;overflow:hidden;position:relative;min-width:1280px;max-width:1920px;margin:0 auto}._mainPage_6absh_1 ._chatContent_6absh_13{position:relative;display:flex;justify-content:flex-start;flex-direction:column;flex-grow:1;margin-right:40px;height:calc(100% - 60px);overflow-y:hidden;padding:32px 0;box-sizing:border-box}._mainPage_6absh_1 ._chatContent_6absh_13 ._top_6absh_25{height:calc(100% - 110px);overflow-y:auto;margin-bottom:40px}._mainPage_6absh_1 ._chatContent_6absh_13 ._top_6absh_25::-webkit-scrollbar{width:6px}._mainPage_6absh_1 ._chatContent_6absh_13 ._top_6absh_25::-webkit-scrollbar-track{background-color:rgba(255,255,255,0);border-radius:100px}._mainPage_6absh_1 ._chatContent_6absh_13 ._top_6absh_25::-webkit-scrollbar-thumb{background-color:rgba(255,255,255,0);border-radius:100px}._mainPage_6absh_1 ._chatContent_6absh_13 ._question_6absh_41{display:flex;justify-content:flex-end;margin-bottom:40px}._mainPage_6absh_1 ._chatContent_6absh_13 ._question_6absh_41 span{padding:12px 20px;color:#121316;font-size:14px;line-height:24px;border-radius:8px;background:#FFF;max-width:93.75%}._mainPage_6absh_1 ._chatContent_6absh_13 ._end_6absh_55{position:absolute;right:0;background-color:#fff;display:flex;justify-content:center;align-items:center;border-left:1px solid #D7D8DD;padding-left:16px}._mainPage_6absh_1 ._chatContent_6absh_13 ._end_6absh_55 ._node_6absh_65{position:relative}._mainPage_6absh_1 ._chatContent_6absh_13 ._end_6absh_55 ._node_6absh_65:before{content:"";border:1px solid #D7D8DD;border-top:none;border-left:none;width:14px;height:0px;position:absolute;left:-16px;top:50%}._mainPage_6absh_1 ._chatContent_6absh_13 ._end_6absh_55 ._node_6absh_65 article{padding:8px 16px;border-radius:8px;border:1px solid transparent;color:#4082fe;text-align:center;font-size:14px;line-height:24px;box-sizing:border-box;background:rgba(232,233,249);color:#2126c0}._mainPage_6absh_1 ._chatContent_6absh_13 ._answer_6absh_91{border-radius:8px;background:rgba(33,38,192,.1);padding:12px}._mainPage_6absh_1 ._chatContent_6absh_13 ._answer_6absh_91 ._inner_6absh_96{width:100%;background-color:#fff;border-radius:4px;padding:8px;box-sizing:border-box;transition:all .5s ease;margin-bottom:18px}._mainPage_6absh_1 ._chatContent_6absh_13 ._answer_6absh_91 ._inner_6absh_96 ._mapArea_6absh_105{width:100%;overflow-x:auto;overflow-y:hidden}._mainPage_6absh_1 ._chatContent_6absh_13 ._answer_6absh_91 ._inner_6absh_96 ._mapArea_6absh_105::-webkit-scrollbar{height:6px}._mainPage_6absh_1 ._chatContent_6absh_13 ._answer_6absh_91 ._inner_6absh_96 ._mapArea_6absh_105::-webkit-scrollbar-track{background-color:rgba(255,255,255,0);border-radius:10px}._mainPage_6absh_1 ._chatContent_6absh_13 ._answer_6absh_91 ._inner_6absh_96 ._mapArea_6absh_105::-webkit-scrollbar-thumb{background-color:#d7d8dd;border-radius:100px}._mainPage_6absh_1 ._chatContent_6absh_13 ._answer_6absh_91 ._response_6absh_121{color:#121316;font-size:14px;line-height:24px;padding:18px 42px}._mainPage_6absh_1 ._chatContent_6absh_13 ._answer_6absh_91 ._response_6absh_121 h3{font-size:24px;font-weight:600;line-height:36px;margin:0 0 16px}._mainPage_6absh_1 ._chatContent_6absh_13 ._answer_6absh_91 ._response_6absh_121 h4{font-size:20px;font-weight:600;line-height:30px;margin:0 0 8px}._mainPage_6absh_1 ._chatContent_6absh_13 ._answer_6absh_91 ._response_6absh_121 p{color:rgba(18,19,22,.8);font-size:16px;font-weight:400;line-height:28px;margin:0 0 16px}._mainPage_6absh_1 ._chatContent_6absh_13 ._answer_6absh_91 ._response_6absh_121 ul{margin-bottom:8px;padding-left:22px}._mainPage_6absh_1 ._chatContent_6absh_13 ._answer_6absh_91 ._response_6absh_121 li{color:rgba(18,19,22,.8);font-size:16px;font-weight:400;line-height:28px}._mainPage_6absh_1 ._chatContent_6absh_13 ._answer_6absh_91 ._response_6absh_121 li p{margin-bottom:4px}._mainPage_6absh_1 ._chatContent_6absh_13 ._sendArea_6absh_159{display:flex;width:100%;box-sizing:border-box;padding:10px 12px 10px 24px;justify-content:space-between;align-items:center;border-radius:8px;border:2px solid var(--fill-5, #464A53);background:#FFF;position:relative}._mainPage_6absh_1 ._chatContent_6absh_13 ._sendArea_6absh_159 .ant-input:focus{box-shadow:none!important;outline:0!important}._mainPage_6absh_1 ._chatContent_6absh_13 ._sendArea_6absh_159 input{height:36px;line-height:36px;flex-grow:1;border:0;outline:0}._mainPage_6absh_1 ._chatContent_6absh_13 ._sendArea_6absh_159 input:focus{border:0;outline:0}._mainPage_6absh_1 ._chatContent_6absh_13 ._sendArea_6absh_159 button{display:flex;justify-content:flex-start;align-items:center;border:0;background-color:#fff;cursor:pointer;padding:8px;width:65px;flex-shrink:0}._mainPage_6absh_1 ._chatContent_6absh_13 ._sendArea_6absh_159 button img{margin-right:4px}._mainPage_6absh_1 ._chatContent_6absh_13 ._notice_6absh_200{color:rgba(18,19,22,.35);padding-top:8px;text-align:center;font-weight:400}._mainPage_6absh_1 ._chatContent_6absh_13 ._notice_6absh_200 a{text-decoration:none;color:#444;display:inline-flex;align-items:center}._mainPage_6absh_1 ._chatContent_6absh_13 ._notice_6absh_200 a span{font-size:18px}._mainPage_6absh_1 ._progressContent_6absh_215{width:44.44%;flex-shrink:0;box-sizing:border-box;padding:24px;border-radius:8px;border:rgba(33,38,192,.1);background:rgba(255,255,255,.8);height:calc(100% - 60px);overflow-y:auto;position:relative}._mainPage_6absh_1 ._progressContent_6absh_215::-webkit-scrollbar{width:6px}._mainPage_6absh_1 ._progressContent_6absh_215::-webkit-scrollbar-track{background-color:rgba(255,255,255,0);border-radius:100px}._mainPage_6absh_1 ._progressContent_6absh_215::-webkit-scrollbar-thumb{background-color:rgba(255,255,255,0);border-radius:100px}._mainPage_6absh_1 ._progressContent_6absh_215 ._toggleIcon_6absh_238{position:absolute;right:24px;top:28px;cursor:pointer}._mainPage_6absh_1 ._progressContent_6absh_215 ._titleNode_6absh_244{color:#121316;font-size:24px;font-weight:600;line-height:36px;margin-bottom:24px}._mainPage_6absh_1 ._progressContent_6absh_215 ._conclusion_6absh_251{padding-top:8px;color:#121316;font-size:14px;line-height:24px}._mainPage_6absh_1 ._progressContent_6absh_215 ._conclusion_6absh_251 ul{padding-left:24px}._mainPage_6absh_1 ._progressContent_6absh_215 ._steps_6absh_260 ._title_6absh_244{color:var(--100-text-5, #121316);font-size:20px;font-weight:600;line-height:30px;display:flex;justify-content:flex-start;align-items:center;position:relative}._mainPage_6absh_1 ._progressContent_6absh_215 ._steps_6absh_260 ._title_6absh_244 ._open_6absh_270{position:absolute;right:0;font-size:20px;font-weight:400}._mainPage_6absh_1 ._progressContent_6absh_215 ._steps_6absh_260 ._title_6absh_244 ._open_6absh_270 span{color:#121316;opacity:.6}._mainPage_6absh_1 ._progressContent_6absh_215 ._steps_6absh_260 ._title_6absh_244 i{width:12px;height:12px;border-radius:50%;background-color:#2126c0;margin-right:8px}._mainPage_6absh_1 ._progressContent_6absh_215 ._steps_6absh_260._thinking_6absh_287,._mainPage_6absh_1 ._progressContent_6absh_215 ._steps_6absh_260._select_6absh_288{margin-bottom:24px}._mainPage_6absh_1 ._progressContent_6absh_215 ._steps_6absh_260._select_6absh_288 ._searchList_6absh_291{margin-top:0!important;border-radius:8px;background:var(--fill-2, #F4F5F9);padding:8px}._mainPage_6absh_1 ._progressContent_6absh_215 ._steps_6absh_260 ._con_6absh_251{margin-left:5px;padding-top:8px;padding-left:15px;border-left:1px solid rgba(33,38,192,.2);height:auto}._mainPage_6absh_1 ._progressContent_6absh_215 ._steps_6absh_260 ._con_6absh_251._collapsed_6absh_304{overflow:hidden;height:0;padding-top:0;transition:all 1s}._mainPage_6absh_1 ._progressContent_6absh_215 ._steps_6absh_260 ._con_6absh_251 ._subTitle_6absh_310{color:var(--100-text-5, #121316);font-size:14px;font-weight:600;line-height:24px;margin-bottom:4px}._mainPage_6absh_1 ._progressContent_6absh_215 ._steps_6absh_260 ._con_6absh_251 ._subTitle_6absh_310 span{margin-right:4px}._mainPage_6absh_1 ._progressContent_6absh_215 ._steps_6absh_260 ._con_6absh_251 ._query_6absh_320,._mainPage_6absh_1 ._progressContent_6absh_215 ._steps_6absh_260 ._con_6absh_251>._searchList_6absh_291{margin-top:24px}._mainPage_6absh_1 ._progressContent_6absh_215 ._steps_6absh_260 ._con_6absh_251 ._query-Item_6absh_324{display:inline-flex;padding:4px 8px;margin-right:4px;margin-bottom:4px;border-radius:4px;border:1px solid #EBECF0;color:rgba(18,19,22,.8);font-size:14px;line-height:24px;height:32px;box-sizing:border-box;overflow:hidden}._mainPage_6absh_1 ._progressContent_6absh_215 ._steps_6absh_260 ._con_6absh_251 ._searchList_6absh_291 ._thought_6absh_338{color:rgba(18,19,22,.8);font-size:14px;line-height:24px;margin-bottom:16px}._mainPage_6absh_1 ._progressContent_6absh_215 ._steps_6absh_260 ._con_6absh_251 ._searchList_6absh_291 ._scrollCon_6absh_344{padding-right:6px;max-height:300px;overflow-y:auto;position:relative}._mainPage_6absh_1 ._progressContent_6absh_215 ._steps_6absh_260 ._con_6absh_251 ._searchList_6absh_291 ._scrollCon_6absh_344::-webkit-scrollbar{width:6px}._mainPage_6absh_1 ._progressContent_6absh_215 ._steps_6absh_260 ._con_6absh_251 ._searchList_6absh_291 ._scrollCon_6absh_344::-webkit-scrollbar-track{background-color:rgba(255,255,255,0);border-radius:100px}._mainPage_6absh_1 ._progressContent_6absh_215 ._steps_6absh_260 ._con_6absh_251 ._searchList_6absh_291 ._scrollCon_6absh_344::-webkit-scrollbar-thumb{background-color:#d7d8dd;border-radius:100px}._mainPage_6absh_1 ._progressContent_6absh_215 ._steps_6absh_260 ._con_6absh_251 ._searchList_6absh_291 ._inner_6absh_96{width:100%;border-radius:8px;background:var(--fill-2, #F4F5F9);transition:all .5s ease;box-sizing:border-box;padding:8px}._mainPage_6absh_1 ._progressContent_6absh_215 ._steps_6absh_260 ._con_6absh_251 ._searchList_6absh_291 ._searchItem_6absh_369{border-radius:8px;background:var(---fill-0, #FFF);margin-bottom:6px;padding:4px 8px;transition:all .5s ease-in-out}._mainPage_6absh_1 ._progressContent_6absh_215 ._steps_6absh_260 ._con_6absh_251 ._searchList_6absh_291 ._searchItem_6absh_369._highLight_6absh_376{border:1px solid var(---Success-6, #00B365);background:linear-gradient(0deg,rgba(218,242,228,.4) 0%,rgba(218,242,228,.4) 100%),#FFF}._mainPage_6absh_1 ._progressContent_6absh_215 ._steps_6absh_260 ._con_6absh_251 ._searchList_6absh_291 ._searchItem_6absh_369 p{white-space:nowrap;max-width:95%;overflow:hidden;text-overflow:ellipsis;margin:0}._mainPage_6absh_1 ._progressContent_6absh_215 ._steps_6absh_260 ._con_6absh_251 ._searchList_6absh_291 ._searchItem_6absh_369 p._summ_6absh_387{color:rgba(18,19,22,.8);font-size:13px;line-height:20px;margin-bottom:2px}._mainPage_6absh_1 ._progressContent_6absh_215 ._steps_6absh_260 ._con_6absh_251 ._searchList_6absh_291 ._searchItem_6absh_369 p._url_6absh_393{color:var(--60-text-3, rgba(18, 19, 22, .6));font-size:12px;line-height:18px;padding-left:20px}pre{margin:0;padding-top:8px;color:#121316;font-size:14px;line-height:24px;font-family:PingFang SC,Franklin Gothic Medium,Arial Narrow,Arial,sans-serif;white-space:wrap}ul{margin:0;padding:0}._draft_6absh_412{width:100%;white-space:wrap;position:relative}._draft_6absh_412 ._loading_6absh_417,._draft_6absh_412 ._loading_6absh_417>div{position:relative;box-sizing:border-box}._draft_6absh_412 ._loading_6absh_417{display:flex;justify-content:center;align-items:center;font-size:0;color:#fff;background-color:#f90;width:20px;height:20px;border-radius:50%;margin-right:3px;flex-shrink:0;position:absolute;top:0;left:0}._draft_6absh_412 ._loading_6absh_417>div{display:inline-block;float:none;background-color:currentColor;border:0 solid currentColor}._draft_6absh_412 ._loading_6absh_417>div:nth-child(1){animation-delay:-.2s}._draft_6absh_412 ._loading_6absh_417>div:nth-child(2){animation-delay:-.1s}._draft_6absh_412 ._loading_6absh_417>div:nth-child(3){animation-delay:0ms}._draft_6absh_412 ._loading_6absh_417>div{width:3px;height:3px;margin:2px 1px;border-radius:100%;animation:_ball-pulse_6absh_1 1s ease infinite}._mindmap_6absh_460{position:relative}._mindmap_6absh_460 article{padding:6px 16px;border-radius:8px;height:38px;border:1px solid transparent;background:#FFF;color:#121316;text-align:center;font-size:14px;line-height:24px;position:relative;box-sizing:border-box}._mindmap_6absh_460 article._loading_6absh_417{line-height:20px;border-radius:8px;overflow:hidden;border:1px solid transparent;padding:4px}._mindmap_6absh_460 article._loading_6absh_417 span{color:#2126c0;background-color:#fff;border-radius:4px;line-height:24px;padding:2px 12px}._mindmap_6absh_460 article._loading_6absh_417 ._looping_6absh_490{--border-width: 4px;--follow-panel-linear-border: linear-gradient(91deg, #5551FF .58%, #FF87DE 100.36%);position:absolute;top:0;left:0;width:calc(100% + var(--border-width) * 2 - 8px);height:100%;background:var(--follow-panel-linear-border);background-size:300% 300%;background-position:0 50%;animation:_moveGradient_6absh_1 4s alternate infinite}._mindmap_6absh_460 article._disabled_6absh_503{border-radius:8px;border:1px solid #D7D8DD;color:rgba(18,19,22,.35)}._mindmap_6absh_460 article._finished_6absh_508{border:1px solid #2126C0}._mindmap_6absh_460 article._finished_6absh_508 ._finishDot_6absh_511{position:absolute;top:6px;right:6px;width:6px;height:6px;background-color:#c9c0fe;border-radius:50%}._mindmap_6absh_460 article._init_6absh_520{border:1px solid transparent;cursor:auto}._mindmap_6absh_460 article span{display:block;white-space:nowrap;max-width:160px;overflow:hidden;text-overflow:ellipsis;position:relative;z-index:20}._mindmap_6absh_460 article span._status_6absh_533{color:#4082fe}._mindmap_6absh_460>li>article{border-radius:8px;background:rgba(33,38,192,.1);color:#2126c0}._mindmap_6absh_460 li{list-style:none;display:flex;align-items:center;box-sizing:border-box;margin:16px;line-height:1;position:relative}._mindmap_6absh_460 li>ul._onlyone_6absh_550:before{opacity:0}._mindmap_6absh_460 li>ul._onlyone_6absh_550>li{margin-left:0}._mindmap_6absh_460 li>ul._onlyone_6absh_550>li:after{opacity:0}._mindmap_6absh_460 li>ul:before{content:"";border:1px solid #D7D8DD;border-top:none;border-left:none;width:14px;height:0px;position:absolute;left:0;top:50%}._mindmap_6absh_460 li:before{content:"";border:1px solid #D7D8DD;border-top:none;border-left:none;width:16px;height:0px;position:absolute;left:-17px}._mindmap_6absh_460 li:after{content:"";border:1px solid #D7D8DD;border-top:none;border-left:none;width:0px;height:calc(50% + 33px);position:absolute;left:-18px}._mindmap_6absh_460 li:first-of-type:after{top:50%}._mindmap_6absh_460 li:last-of-type:after{bottom:50%}._mindmap_6absh_460 li ul{padding:0 0 0 16px;position:relative}._mindmap_6absh_460>li:after,._mindmap_6absh_460>li:before{display:none}._mindmap_6absh_460 ._endLine_6absh_604{border-bottom:1px solid #D7D8DD;width:3000px;transition:width 1s ease-in-out}._showRight_6absh_609{position:fixed;top:80px;right:-10px;width:42px;cursor:pointer}._showRight_6absh_609 img{width:100%}@keyframes _ball-pulse_6absh_1{0%,60%,to{opacity:1;transform:scale(1)}30%{opacity:.1;transform:scale(.01)}}@keyframes _moveGradient_6absh_1{50%{background-position:100% 50%}}@keyframes _fadeIn_6absh_1{0%{width:0;opacity:0}to{width:auto;opacity:1}}@keyframes _unfold_6absh_1{0%{height:auto}to{height:0}}._loading99_6absh_654{margin:20px;position:relative;width:1px;height:1px}._loading99_6absh_654:before,._loading99_6absh_654:after{position:absolute;display:inline-block;width:15px;height:15px;content:"";border-radius:100%;background-color:#5551ff}._loading99_6absh_654:before{left:-15px;animation:_ball-pulse_6absh_1 infinite .75s -.4s cubic-bezier(.2,.68,.18,1.08)}._loading99_6absh_654:after{right:-15px;animation:_ball-pulse_6absh_1 infinite .75s cubic-bezier(.2,.68,.18,1.08)}@keyframes _ball-pulse_6absh_1{0%{transform:scale(1);opacity:1}50%{transform:scale(.1);opacity:.6}to{transform:scale(1);opacity:1}}
dist/assets/index-legacy-f957e103.js ADDED
The diff for this file is too large to render. See raw diff
 
dist/assets/logo-38417354.svg ADDED
dist/assets/pack-up-ad0b3cbc.svg ADDED
dist/assets/polyfills-legacy-0b55db5f.js ADDED
@@ -0,0 +1 @@
 
 
1
+ !function(){"use strict";var t="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},e=function(t){return t&&t.Math===Math&&t},r=e("object"==typeof globalThis&&globalThis)||e("object"==typeof window&&window)||e("object"==typeof self&&self)||e("object"==typeof t&&t)||e("object"==typeof t&&t)||function(){return this}()||Function("return this")(),n={},o=function(t){try{return!!t()}catch(e){return!0}},i=!o((function(){return 7!==Object.defineProperty({},1,{get:function(){return 7}})[1]})),u=!o((function(){var t=function(){}.bind();return"function"!=typeof t||t.hasOwnProperty("prototype")})),c=u,a=Function.prototype.call,f=c?a.bind(a):function(){return a.apply(a,arguments)},s={},l={}.propertyIsEnumerable,h=Object.getOwnPropertyDescriptor,p=h&&!l.call({1:2},1);s.f=p?function(t){var e=h(this,t);return!!e&&e.enumerable}:l;var v,d,y=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}},g=u,m=Function.prototype,b=m.call,w=g&&m.bind.bind(b,b),S=g?w:function(t){return function(){return b.apply(t,arguments)}},O=S,x=O({}.toString),E=O("".slice),j=function(t){return E(x(t),8,-1)},P=o,T=j,I=Object,L=S("".split),R=P((function(){return!I("z").propertyIsEnumerable(0)}))?function(t){return"String"===T(t)?L(t,""):I(t)}:I,A=function(t){return null==t},k=A,C=TypeError,_=function(t){if(k(t))throw new C("Can't call method on "+t);return t},F=R,N=_,M=function(t){return F(N(t))},D="object"==typeof document&&document.all,z=void 0===D&&void 0!==D?function(t){return"function"==typeof t||t===D}:function(t){return"function"==typeof t},G=z,U=function(t){return"object"==typeof t?null!==t:G(t)},B=r,W=z,V=function(t,e){return arguments.length<2?(r=B[t],W(r)?r:void 0):B[t]&&B[t][e];var r},J=S({}.isPrototypeOf),K="undefined"!=typeof navigator&&String(navigator.userAgent)||"",Y=r,$=K,q=Y.process,H=Y.Deno,X=q&&q.versions||H&&H.version,Q=X&&X.v8;Q&&(d=(v=Q.split("."))[0]>0&&v[0]<4?1:+(v[0]+v[1])),!d&&$&&(!(v=$.match(/Edge\/(\d+)/))||v[1]>=74)&&(v=$.match(/Chrome\/(\d+)/))&&(d=+v[1]);var Z=d,tt=Z,et=o,rt=r.String,nt=!!Object.getOwnPropertySymbols&&!et((function(){var t=Symbol("symbol detection");return!rt(t)||!(Object(t)instanceof Symbol)||!Symbol.sham&&tt&&tt<41})),ot=nt&&!Symbol.sham&&"symbol"==typeof Symbol.iterator,it=V,ut=z,ct=J,at=Object,ft=ot?function(t){return"symbol"==typeof t}:function(t){var e=it("Symbol");return ut(e)&&ct(e.prototype,at(t))},st=String,lt=function(t){try{return st(t)}catch(e){return"Object"}},ht=z,pt=lt,vt=TypeError,dt=function(t){if(ht(t))return t;throw new vt(pt(t)+" is not a function")},yt=dt,gt=A,mt=function(t,e){var r=t[e];return gt(r)?void 0:yt(r)},bt=f,wt=z,St=U,Ot=TypeError,xt={exports:{}},Et=r,jt=Object.defineProperty,Pt=function(t,e){try{jt(Et,t,{value:e,configurable:!0,writable:!0})}catch(r){Et[t]=e}return e},Tt=r,It=Pt,Lt="__core-js_shared__",Rt=xt.exports=Tt[Lt]||It(Lt,{});(Rt.versions||(Rt.versions=[])).push({version:"3.37.1",mode:"global",copyright:"© 2014-2024 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.37.1/LICENSE",source:"https://github.com/zloirock/core-js"});var At=xt.exports,kt=At,Ct=function(t,e){return kt[t]||(kt[t]=e||{})},_t=_,Ft=Object,Nt=function(t){return Ft(_t(t))},Mt=Nt,Dt=S({}.hasOwnProperty),zt=Object.hasOwn||function(t,e){return Dt(Mt(t),e)},Gt=S,Ut=0,Bt=Math.random(),Wt=Gt(1..toString),Vt=function(t){return"Symbol("+(void 0===t?"":t)+")_"+Wt(++Ut+Bt,36)},Jt=Ct,Kt=zt,Yt=Vt,$t=nt,qt=ot,Ht=r.Symbol,Xt=Jt("wks"),Qt=qt?Ht.for||Ht:Ht&&Ht.withoutSetter||Yt,Zt=function(t){return Kt(Xt,t)||(Xt[t]=$t&&Kt(Ht,t)?Ht[t]:Qt("Symbol."+t)),Xt[t]},te=f,ee=U,re=ft,ne=mt,oe=function(t,e){var r,n;if("string"===e&&wt(r=t.toString)&&!St(n=bt(r,t)))return n;if(wt(r=t.valueOf)&&!St(n=bt(r,t)))return n;if("string"!==e&&wt(r=t.toString)&&!St(n=bt(r,t)))return n;throw new Ot("Can't convert object to primitive value")},ie=TypeError,ue=Zt("toPrimitive"),ce=function(t,e){if(!ee(t)||re(t))return t;var r,n=ne(t,ue);if(n){if(void 0===e&&(e="default"),r=te(n,t,e),!ee(r)||re(r))return r;throw new ie("Can't convert object to primitive value")}return void 0===e&&(e="number"),oe(t,e)},ae=ft,fe=function(t){var e=ce(t,"string");return ae(e)?e:e+""},se=U,le=r.document,he=se(le)&&se(le.createElement),pe=function(t){return he?le.createElement(t):{}},ve=pe,de=!i&&!o((function(){return 7!==Object.defineProperty(ve("div"),"a",{get:function(){return 7}}).a})),ye=i,ge=f,me=s,be=y,we=M,Se=fe,Oe=zt,xe=de,Ee=Object.getOwnPropertyDescriptor;n.f=ye?Ee:function(t,e){if(t=we(t),e=Se(e),xe)try{return Ee(t,e)}catch(r){}if(Oe(t,e))return be(!ge(me.f,t,e),t[e])};var je={},Pe=i&&o((function(){return 42!==Object.defineProperty((function(){}),"prototype",{value:42,writable:!1}).prototype})),Te=U,Ie=String,Le=TypeError,Re=function(t){if(Te(t))return t;throw new Le(Ie(t)+" is not an object")},Ae=i,ke=de,Ce=Pe,_e=Re,Fe=fe,Ne=TypeError,Me=Object.defineProperty,De=Object.getOwnPropertyDescriptor,ze="enumerable",Ge="configurable",Ue="writable";je.f=Ae?Ce?function(t,e,r){if(_e(t),e=Fe(e),_e(r),"function"==typeof t&&"prototype"===e&&"value"in r&&Ue in r&&!r[Ue]){var n=De(t,e);n&&n[Ue]&&(t[e]=r.value,r={configurable:Ge in r?r[Ge]:n[Ge],enumerable:ze in r?r[ze]:n[ze],writable:!1})}return Me(t,e,r)}:Me:function(t,e,r){if(_e(t),e=Fe(e),_e(r),ke)try{return Me(t,e,r)}catch(n){}if("get"in r||"set"in r)throw new Ne("Accessors not supported");return"value"in r&&(t[e]=r.value),t};var Be=je,We=y,Ve=i?function(t,e,r){return Be.f(t,e,We(1,r))}:function(t,e,r){return t[e]=r,t},Je={exports:{}},Ke=i,Ye=zt,$e=Function.prototype,qe=Ke&&Object.getOwnPropertyDescriptor,He=Ye($e,"name"),Xe={EXISTS:He,PROPER:He&&"something"===function(){}.name,CONFIGURABLE:He&&(!Ke||Ke&&qe($e,"name").configurable)},Qe=z,Ze=At,tr=S(Function.toString);Qe(Ze.inspectSource)||(Ze.inspectSource=function(t){return tr(t)});var er,rr,nr,or=Ze.inspectSource,ir=z,ur=r.WeakMap,cr=ir(ur)&&/native code/.test(String(ur)),ar=Vt,fr=Ct("keys"),sr=function(t){return fr[t]||(fr[t]=ar(t))},lr={},hr=cr,pr=r,vr=U,dr=Ve,yr=zt,gr=At,mr=sr,br=lr,wr="Object already initialized",Sr=pr.TypeError,Or=pr.WeakMap;if(hr||gr.state){var xr=gr.state||(gr.state=new Or);xr.get=xr.get,xr.has=xr.has,xr.set=xr.set,er=function(t,e){if(xr.has(t))throw new Sr(wr);return e.facade=t,xr.set(t,e),e},rr=function(t){return xr.get(t)||{}},nr=function(t){return xr.has(t)}}else{var Er=mr("state");br[Er]=!0,er=function(t,e){if(yr(t,Er))throw new Sr(wr);return e.facade=t,dr(t,Er,e),e},rr=function(t){return yr(t,Er)?t[Er]:{}},nr=function(t){return yr(t,Er)}}var jr={set:er,get:rr,has:nr,enforce:function(t){return nr(t)?rr(t):er(t,{})},getterFor:function(t){return function(e){var r;if(!vr(e)||(r=rr(e)).type!==t)throw new Sr("Incompatible receiver, "+t+" required");return r}}},Pr=S,Tr=o,Ir=z,Lr=zt,Rr=i,Ar=Xe.CONFIGURABLE,kr=or,Cr=jr.enforce,_r=jr.get,Fr=String,Nr=Object.defineProperty,Mr=Pr("".slice),Dr=Pr("".replace),zr=Pr([].join),Gr=Rr&&!Tr((function(){return 8!==Nr((function(){}),"length",{value:8}).length})),Ur=String(String).split("String"),Br=Je.exports=function(t,e,r){"Symbol("===Mr(Fr(e),0,7)&&(e="["+Dr(Fr(e),/^Symbol\(([^)]*)\).*$/,"$1")+"]"),r&&r.getter&&(e="get "+e),r&&r.setter&&(e="set "+e),(!Lr(t,"name")||Ar&&t.name!==e)&&(Rr?Nr(t,"name",{value:e,configurable:!0}):t.name=e),Gr&&r&&Lr(r,"arity")&&t.length!==r.arity&&Nr(t,"length",{value:r.arity});try{r&&Lr(r,"constructor")&&r.constructor?Rr&&Nr(t,"prototype",{writable:!1}):t.prototype&&(t.prototype=void 0)}catch(o){}var n=Cr(t);return Lr(n,"source")||(n.source=zr(Ur,"string"==typeof e?e:"")),t};Function.prototype.toString=Br((function(){return Ir(this)&&_r(this).source||kr(this)}),"toString");var Wr=Je.exports,Vr=z,Jr=je,Kr=Wr,Yr=Pt,$r=function(t,e,r,n){n||(n={});var o=n.enumerable,i=void 0!==n.name?n.name:e;if(Vr(r)&&Kr(r,i,n),n.global)o?t[e]=r:Yr(e,r);else{try{n.unsafe?t[e]&&(o=!0):delete t[e]}catch(u){}o?t[e]=r:Jr.f(t,e,{value:r,enumerable:!1,configurable:!n.nonConfigurable,writable:!n.nonWritable})}return t},qr={},Hr=Math.ceil,Xr=Math.floor,Qr=Math.trunc||function(t){var e=+t;return(e>0?Xr:Hr)(e)},Zr=function(t){var e=+t;return e!=e||0===e?0:Qr(e)},tn=Zr,en=Math.max,rn=Math.min,nn=Zr,on=Math.min,un=function(t){var e=nn(t);return e>0?on(e,9007199254740991):0},cn=un,an=function(t){return cn(t.length)},fn=M,sn=function(t,e){var r=tn(t);return r<0?en(r+e,0):rn(r,e)},ln=an,hn=function(t){return function(e,r,n){var o=fn(e),i=ln(o);if(0===i)return!t&&-1;var u,c=sn(n,i);if(t&&r!=r){for(;i>c;)if((u=o[c++])!=u)return!0}else for(;i>c;c++)if((t||c in o)&&o[c]===r)return t||c||0;return!t&&-1}},pn={includes:hn(!0),indexOf:hn(!1)},vn=zt,dn=M,yn=pn.indexOf,gn=lr,mn=S([].push),bn=function(t,e){var r,n=dn(t),o=0,i=[];for(r in n)!vn(gn,r)&&vn(n,r)&&mn(i,r);for(;e.length>o;)vn(n,r=e[o++])&&(~yn(i,r)||mn(i,r));return i},wn=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"],Sn=bn,On=wn.concat("length","prototype");qr.f=Object.getOwnPropertyNames||function(t){return Sn(t,On)};var xn={};xn.f=Object.getOwnPropertySymbols;var En=V,jn=qr,Pn=xn,Tn=Re,In=S([].concat),Ln=En("Reflect","ownKeys")||function(t){var e=jn.f(Tn(t)),r=Pn.f;return r?In(e,r(t)):e},Rn=zt,An=Ln,kn=n,Cn=je,_n=o,Fn=z,Nn=/#|\.prototype\./,Mn=function(t,e){var r=zn[Dn(t)];return r===Un||r!==Gn&&(Fn(e)?_n(e):!!e)},Dn=Mn.normalize=function(t){return String(t).replace(Nn,".").toLowerCase()},zn=Mn.data={},Gn=Mn.NATIVE="N",Un=Mn.POLYFILL="P",Bn=Mn,Wn=r,Vn=n.f,Jn=Ve,Kn=$r,Yn=Pt,$n=function(t,e,r){for(var n=An(e),o=Cn.f,i=kn.f,u=0;u<n.length;u++){var c=n[u];Rn(t,c)||r&&Rn(r,c)||o(t,c,i(e,c))}},qn=Bn,Hn=function(t,e){var r,n,o,i,u,c=t.target,a=t.global,f=t.stat;if(r=a?Wn:f?Wn[c]||Yn(c,{}):Wn[c]&&Wn[c].prototype)for(n in e){if(i=e[n],o=t.dontCallGetSet?(u=Vn(r,n))&&u.value:r[n],!qn(a?n:c+(f?".":"#")+n,t.forced)&&void 0!==o){if(typeof i==typeof o)continue;$n(i,o)}(t.sham||o&&o.sham)&&Jn(i,"sham",!0),Kn(r,n,i,t)}},Xn={};Xn[Zt("toStringTag")]="z";var Qn="[object z]"===String(Xn),Zn=Qn,to=z,eo=j,ro=Zt("toStringTag"),no=Object,oo="Arguments"===eo(function(){return arguments}()),io=Zn?eo:function(t){var e,r,n;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(r=function(t,e){try{return t[e]}catch(r){}}(e=no(t),ro))?r:oo?eo(e):"Object"===(n=eo(e))&&to(e.callee)?"Arguments":n},uo=io,co=String,ao=function(t){if("Symbol"===uo(t))throw new TypeError("Cannot convert a Symbol value to a string");return co(t)},fo={},so=bn,lo=wn,ho=Object.keys||function(t){return so(t,lo)},po=i,vo=Pe,yo=je,go=Re,mo=M,bo=ho;fo.f=po&&!vo?Object.defineProperties:function(t,e){go(t);for(var r,n=mo(e),o=bo(e),i=o.length,u=0;i>u;)yo.f(t,r=o[u++],n[r]);return t};var wo,So=V("document","documentElement"),Oo=Re,xo=fo,Eo=wn,jo=lr,Po=So,To=pe,Io="prototype",Lo="script",Ro=sr("IE_PROTO"),Ao=function(){},ko=function(t){return"<"+Lo+">"+t+"</"+Lo+">"},Co=function(t){t.write(ko("")),t.close();var e=t.parentWindow.Object;return t=null,e},_o=function(){try{wo=new ActiveXObject("htmlfile")}catch(o){}var t,e,r;_o="undefined"!=typeof document?document.domain&&wo?Co(wo):(e=To("iframe"),r="java"+Lo+":",e.style.display="none",Po.appendChild(e),e.src=String(r),(t=e.contentWindow.document).open(),t.write(ko("document.F=Object")),t.close(),t.F):Co(wo);for(var n=Eo.length;n--;)delete _o[Io][Eo[n]];return _o()};jo[Ro]=!0;var Fo=Object.create||function(t,e){var r;return null!==t?(Ao[Io]=Oo(t),r=new Ao,Ao[Io]=null,r[Ro]=t):r=_o(),void 0===e?r:xo.f(r,e)},No={},Mo=S([].slice),Do=j,zo=M,Go=qr.f,Uo=Mo,Bo="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[];No.f=function(t){return Bo&&"Window"===Do(t)?function(t){try{return Go(t)}catch(e){return Uo(Bo)}}(t):Go(zo(t))};var Wo=Wr,Vo=je,Jo=function(t,e,r){return r.get&&Wo(r.get,e,{getter:!0}),r.set&&Wo(r.set,e,{setter:!0}),Vo.f(t,e,r)},Ko={},Yo=Zt;Ko.f=Yo;var $o=r,qo=$o,Ho=zt,Xo=Ko,Qo=je.f,Zo=f,ti=V,ei=Zt,ri=$r,ni=je.f,oi=zt,ii=Zt("toStringTag"),ui=function(t,e,r){t&&!r&&(t=t.prototype),t&&!oi(t,ii)&&ni(t,ii,{configurable:!0,value:e})},ci=j,ai=S,fi=function(t){if("Function"===ci(t))return ai(t)},si=dt,li=u,hi=fi(fi.bind),pi=function(t,e){return si(t),void 0===e?t:li?hi(t,e):function(){return t.apply(e,arguments)}},vi=j,di=Array.isArray||function(t){return"Array"===vi(t)},yi=S,gi=o,mi=z,bi=io,wi=or,Si=function(){},Oi=V("Reflect","construct"),xi=/^\s*(?:class|function)\b/,Ei=yi(xi.exec),ji=!xi.test(Si),Pi=function(t){if(!mi(t))return!1;try{return Oi(Si,[],t),!0}catch(e){return!1}},Ti=function(t){if(!mi(t))return!1;switch(bi(t)){case"AsyncFunction":case"GeneratorFunction":case"AsyncGeneratorFunction":return!1}try{return ji||!!Ei(xi,wi(t))}catch(e){return!0}};Ti.sham=!0;var Ii=!Oi||gi((function(){var t;return Pi(Pi.call)||!Pi(Object)||!Pi((function(){t=!0}))||t}))?Ti:Pi,Li=di,Ri=Ii,Ai=U,ki=Zt("species"),Ci=Array,_i=function(t){var e;return Li(t)&&(e=t.constructor,(Ri(e)&&(e===Ci||Li(e.prototype))||Ai(e)&&null===(e=e[ki]))&&(e=void 0)),void 0===e?Ci:e},Fi=pi,Ni=R,Mi=Nt,Di=an,zi=function(t,e){return new(_i(t))(0===e?0:e)},Gi=S([].push),Ui=function(t){var e=1===t,r=2===t,n=3===t,o=4===t,i=6===t,u=7===t,c=5===t||i;return function(a,f,s,l){for(var h,p,v=Mi(a),d=Ni(v),y=Di(d),g=Fi(f,s),m=0,b=l||zi,w=e?b(a,y):r||u?b(a,0):void 0;y>m;m++)if((c||m in d)&&(p=g(h=d[m],m,v),t))if(e)w[m]=p;else if(p)switch(t){case 3:return!0;case 5:return h;case 6:return m;case 2:Gi(w,h)}else switch(t){case 4:return!1;case 7:Gi(w,h)}return i?-1:n||o?o:w}},Bi={forEach:Ui(0),map:Ui(1),filter:Ui(2),some:Ui(3),every:Ui(4),find:Ui(5),findIndex:Ui(6),filterReject:Ui(7)},Wi=Hn,Vi=r,Ji=f,Ki=S,Yi=i,$i=nt,qi=o,Hi=zt,Xi=J,Qi=Re,Zi=M,tu=fe,eu=ao,ru=y,nu=Fo,ou=ho,iu=qr,uu=No,cu=xn,au=n,fu=je,su=fo,lu=s,hu=$r,pu=Jo,vu=Ct,du=lr,yu=Vt,gu=Zt,mu=Ko,bu=function(t){var e=qo.Symbol||(qo.Symbol={});Ho(e,t)||Qo(e,t,{value:Xo.f(t)})},wu=function(){var t=ti("Symbol"),e=t&&t.prototype,r=e&&e.valueOf,n=ei("toPrimitive");e&&!e[n]&&ri(e,n,(function(t){return Zo(r,this)}),{arity:1})},Su=ui,Ou=jr,xu=Bi.forEach,Eu=sr("hidden"),ju="Symbol",Pu="prototype",Tu=Ou.set,Iu=Ou.getterFor(ju),Lu=Object[Pu],Ru=Vi.Symbol,Au=Ru&&Ru[Pu],ku=Vi.RangeError,Cu=Vi.TypeError,_u=Vi.QObject,Fu=au.f,Nu=fu.f,Mu=uu.f,Du=lu.f,zu=Ki([].push),Gu=vu("symbols"),Uu=vu("op-symbols"),Bu=vu("wks"),Wu=!_u||!_u[Pu]||!_u[Pu].findChild,Vu=function(t,e,r){var n=Fu(Lu,e);n&&delete Lu[e],Nu(t,e,r),n&&t!==Lu&&Nu(Lu,e,n)},Ju=Yi&&qi((function(){return 7!==nu(Nu({},"a",{get:function(){return Nu(this,"a",{value:7}).a}})).a}))?Vu:Nu,Ku=function(t,e){var r=Gu[t]=nu(Au);return Tu(r,{type:ju,tag:t,description:e}),Yi||(r.description=e),r},Yu=function(t,e,r){t===Lu&&Yu(Uu,e,r),Qi(t);var n=tu(e);return Qi(r),Hi(Gu,n)?(r.enumerable?(Hi(t,Eu)&&t[Eu][n]&&(t[Eu][n]=!1),r=nu(r,{enumerable:ru(0,!1)})):(Hi(t,Eu)||Nu(t,Eu,ru(1,nu(null))),t[Eu][n]=!0),Ju(t,n,r)):Nu(t,n,r)},$u=function(t,e){Qi(t);var r=Zi(e),n=ou(r).concat(Qu(r));return xu(n,(function(e){Yi&&!Ji(qu,r,e)||Yu(t,e,r[e])})),t},qu=function(t){var e=tu(t),r=Ji(Du,this,e);return!(this===Lu&&Hi(Gu,e)&&!Hi(Uu,e))&&(!(r||!Hi(this,e)||!Hi(Gu,e)||Hi(this,Eu)&&this[Eu][e])||r)},Hu=function(t,e){var r=Zi(t),n=tu(e);if(r!==Lu||!Hi(Gu,n)||Hi(Uu,n)){var o=Fu(r,n);return!o||!Hi(Gu,n)||Hi(r,Eu)&&r[Eu][n]||(o.enumerable=!0),o}},Xu=function(t){var e=Mu(Zi(t)),r=[];return xu(e,(function(t){Hi(Gu,t)||Hi(du,t)||zu(r,t)})),r},Qu=function(t){var e=t===Lu,r=Mu(e?Uu:Zi(t)),n=[];return xu(r,(function(t){!Hi(Gu,t)||e&&!Hi(Lu,t)||zu(n,Gu[t])})),n};$i||(Ru=function(){if(Xi(Au,this))throw new Cu("Symbol is not a constructor");var t=arguments.length&&void 0!==arguments[0]?eu(arguments[0]):void 0,e=yu(t),r=function(t){var n=void 0===this?Vi:this;n===Lu&&Ji(r,Uu,t),Hi(n,Eu)&&Hi(n[Eu],e)&&(n[Eu][e]=!1);var o=ru(1,t);try{Ju(n,e,o)}catch(i){if(!(i instanceof ku))throw i;Vu(n,e,o)}};return Yi&&Wu&&Ju(Lu,e,{configurable:!0,set:r}),Ku(e,t)},hu(Au=Ru[Pu],"toString",(function(){return Iu(this).tag})),hu(Ru,"withoutSetter",(function(t){return Ku(yu(t),t)})),lu.f=qu,fu.f=Yu,su.f=$u,au.f=Hu,iu.f=uu.f=Xu,cu.f=Qu,mu.f=function(t){return Ku(gu(t),t)},Yi&&(pu(Au,"description",{configurable:!0,get:function(){return Iu(this).description}}),hu(Lu,"propertyIsEnumerable",qu,{unsafe:!0}))),Wi({global:!0,constructor:!0,wrap:!0,forced:!$i,sham:!$i},{Symbol:Ru}),xu(ou(Bu),(function(t){bu(t)})),Wi({target:ju,stat:!0,forced:!$i},{useSetter:function(){Wu=!0},useSimple:function(){Wu=!1}}),Wi({target:"Object",stat:!0,forced:!$i,sham:!Yi},{create:function(t,e){return void 0===e?nu(t):$u(nu(t),e)},defineProperty:Yu,defineProperties:$u,getOwnPropertyDescriptor:Hu}),Wi({target:"Object",stat:!0,forced:!$i},{getOwnPropertyNames:Xu}),wu(),Su(Ru,ju),du[Eu]=!0;var Zu=nt&&!!Symbol.for&&!!Symbol.keyFor,tc=Hn,ec=V,rc=zt,nc=ao,oc=Ct,ic=Zu,uc=oc("string-to-symbol-registry"),cc=oc("symbol-to-string-registry");tc({target:"Symbol",stat:!0,forced:!ic},{for:function(t){var e=nc(t);if(rc(uc,e))return uc[e];var r=ec("Symbol")(e);return uc[e]=r,cc[r]=e,r}});var ac=Hn,fc=zt,sc=ft,lc=lt,hc=Zu,pc=Ct("symbol-to-string-registry");ac({target:"Symbol",stat:!0,forced:!hc},{keyFor:function(t){if(!sc(t))throw new TypeError(lc(t)+" is not a symbol");if(fc(pc,t))return pc[t]}});var vc=u,dc=Function.prototype,yc=dc.apply,gc=dc.call,mc="object"==typeof Reflect&&Reflect.apply||(vc?gc.bind(yc):function(){return gc.apply(yc,arguments)}),bc=di,wc=z,Sc=j,Oc=ao,xc=S([].push),Ec=Hn,jc=V,Pc=mc,Tc=f,Ic=S,Lc=o,Rc=z,Ac=ft,kc=Mo,Cc=function(t){if(wc(t))return t;if(bc(t)){for(var e=t.length,r=[],n=0;n<e;n++){var o=t[n];"string"==typeof o?xc(r,o):"number"!=typeof o&&"Number"!==Sc(o)&&"String"!==Sc(o)||xc(r,Oc(o))}var i=r.length,u=!0;return function(t,e){if(u)return u=!1,e;if(bc(this))return e;for(var n=0;n<i;n++)if(r[n]===t)return e}}},_c=nt,Fc=String,Nc=jc("JSON","stringify"),Mc=Ic(/./.exec),Dc=Ic("".charAt),zc=Ic("".charCodeAt),Gc=Ic("".replace),Uc=Ic(1..toString),Bc=/[\uD800-\uDFFF]/g,Wc=/^[\uD800-\uDBFF]$/,Vc=/^[\uDC00-\uDFFF]$/,Jc=!_c||Lc((function(){var t=jc("Symbol")("stringify detection");return"[null]"!==Nc([t])||"{}"!==Nc({a:t})||"{}"!==Nc(Object(t))})),Kc=Lc((function(){return'"\\udf06\\ud834"'!==Nc("\udf06\ud834")||'"\\udead"'!==Nc("\udead")})),Yc=function(t,e){var r=kc(arguments),n=Cc(e);if(Rc(n)||void 0!==t&&!Ac(t))return r[1]=function(t,e){if(Rc(n)&&(e=Tc(n,this,Fc(t),e)),!Ac(e))return e},Pc(Nc,null,r)},$c=function(t,e,r){var n=Dc(r,e-1),o=Dc(r,e+1);return Mc(Wc,t)&&!Mc(Vc,o)||Mc(Vc,t)&&!Mc(Wc,n)?"\\u"+Uc(zc(t,0),16):t};Nc&&Ec({target:"JSON",stat:!0,arity:3,forced:Jc||Kc},{stringify:function(t,e,r){var n=kc(arguments),o=Pc(Jc?Yc:Nc,null,n);return Kc&&"string"==typeof o?Gc(o,Bc,$c):o}});var qc=xn,Hc=Nt;Hn({target:"Object",stat:!0,forced:!nt||o((function(){qc.f(1)}))},{getOwnPropertySymbols:function(t){var e=qc.f;return e?e(Hc(t)):[]}});var Xc=o,Qc=Z,Zc=Zt("species"),ta=Bi.filter;Hn({target:"Array",proto:!0,forced:!function(t){return Qc>=51||!Xc((function(){var e=[];return(e.constructor={})[Zc]=function(){return{foo:1}},1!==e[t](Boolean).foo}))}("filter")},{filter:function(t){return ta(this,t,arguments.length>1?arguments[1]:void 0)}});var ea,ra,na,oa,ia="process"===j(r.process),ua=S,ca=dt,aa=function(t,e,r){try{return ua(ca(Object.getOwnPropertyDescriptor(t,e)[r]))}catch(n){}},fa=U,sa=function(t){return fa(t)||null===t},la=String,ha=TypeError,pa=aa,va=U,da=_,ya=function(t){if(sa(t))return t;throw new ha("Can't set "+la(t)+" as a prototype")},ga=Object.setPrototypeOf||("__proto__"in{}?function(){var t,e=!1,r={};try{(t=pa(Object.prototype,"__proto__","set"))(r,[]),e=r instanceof Array}catch(n){}return function(r,n){return da(r),ya(n),va(r)?(e?t(r,n):r.__proto__=n,r):r}}():void 0),ma=V,ba=Jo,wa=i,Sa=Zt("species"),Oa=function(t){var e=ma(t);wa&&e&&!e[Sa]&&ba(e,Sa,{configurable:!0,get:function(){return this}})},xa=J,Ea=TypeError,ja=function(t,e){if(xa(e,t))return t;throw new Ea("Incorrect invocation")},Pa=Ii,Ta=lt,Ia=TypeError,La=Re,Ra=function(t){if(Pa(t))return t;throw new Ia(Ta(t)+" is not a constructor")},Aa=A,ka=Zt("species"),Ca=function(t,e){var r,n=La(t).constructor;return void 0===n||Aa(r=La(n)[ka])?e:Ra(r)},_a=TypeError,Fa=/(?:ipad|iphone|ipod).*applewebkit/i.test(K),Na=r,Ma=mc,Da=pi,za=z,Ga=zt,Ua=o,Ba=So,Wa=Mo,Va=pe,Ja=function(t,e){if(t<e)throw new _a("Not enough arguments");return t},Ka=Fa,Ya=ia,$a=Na.setImmediate,qa=Na.clearImmediate,Ha=Na.process,Xa=Na.Dispatch,Qa=Na.Function,Za=Na.MessageChannel,tf=Na.String,ef=0,rf={},nf="onreadystatechange";Ua((function(){ea=Na.location}));var of=function(t){if(Ga(rf,t)){var e=rf[t];delete rf[t],e()}},uf=function(t){return function(){of(t)}},cf=function(t){of(t.data)},af=function(t){Na.postMessage(tf(t),ea.protocol+"//"+ea.host)};$a&&qa||($a=function(t){Ja(arguments.length,1);var e=za(t)?t:Qa(t),r=Wa(arguments,1);return rf[++ef]=function(){Ma(e,void 0,r)},ra(ef),ef},qa=function(t){delete rf[t]},Ya?ra=function(t){Ha.nextTick(uf(t))}:Xa&&Xa.now?ra=function(t){Xa.now(uf(t))}:Za&&!Ka?(oa=(na=new Za).port2,na.port1.onmessage=cf,ra=Da(oa.postMessage,oa)):Na.addEventListener&&za(Na.postMessage)&&!Na.importScripts&&ea&&"file:"!==ea.protocol&&!Ua(af)?(ra=af,Na.addEventListener("message",cf,!1)):ra=nf in Va("script")?function(t){Ba.appendChild(Va("script"))[nf]=function(){Ba.removeChild(this),of(t)}}:function(t){setTimeout(uf(t),0)});var ff={set:$a,clear:qa},sf=r,lf=i,hf=Object.getOwnPropertyDescriptor,pf=function(){this.head=null,this.tail=null};pf.prototype={add:function(t){var e={item:t,next:null},r=this.tail;r?r.next=e:this.head=e,this.tail=e},get:function(){var t=this.head;if(t)return null===(this.head=t.next)&&(this.tail=null),t.item}};var vf,df,yf,gf,mf,bf=pf,wf=/ipad|iphone|ipod/i.test(K)&&"undefined"!=typeof Pebble,Sf=/web0s(?!.*chrome)/i.test(K),Of=r,xf=function(t){if(!lf)return sf[t];var e=hf(sf,t);return e&&e.value},Ef=pi,jf=ff.set,Pf=bf,Tf=Fa,If=wf,Lf=Sf,Rf=ia,Af=Of.MutationObserver||Of.WebKitMutationObserver,kf=Of.document,Cf=Of.process,_f=Of.Promise,Ff=xf("queueMicrotask");if(!Ff){var Nf=new Pf,Mf=function(){var t,e;for(Rf&&(t=Cf.domain)&&t.exit();e=Nf.get();)try{e()}catch(r){throw Nf.head&&vf(),r}t&&t.enter()};Tf||Rf||Lf||!Af||!kf?!If&&_f&&_f.resolve?((gf=_f.resolve(void 0)).constructor=_f,mf=Ef(gf.then,gf),vf=function(){mf(Mf)}):Rf?vf=function(){Cf.nextTick(Mf)}:(jf=Ef(jf,Of),vf=function(){jf(Mf)}):(df=!0,yf=kf.createTextNode(""),new Af(Mf).observe(yf,{characterData:!0}),vf=function(){yf.data=df=!df}),Ff=function(t){Nf.head||vf(),Nf.add(t)}}var Df=Ff,zf=function(t){try{return{error:!1,value:t()}}catch(e){return{error:!0,value:e}}},Gf=r.Promise,Uf="object"==typeof Deno&&Deno&&"object"==typeof Deno.version,Bf=!Uf&&!ia&&"object"==typeof window&&"object"==typeof document,Wf=r,Vf=Gf,Jf=z,Kf=Bn,Yf=or,$f=Zt,qf=Bf,Hf=Uf,Xf=Z;Vf&&Vf.prototype;var Qf=$f("species"),Zf=!1,ts=Jf(Wf.PromiseRejectionEvent),es=Kf("Promise",(function(){var t=Yf(Vf),e=t!==String(Vf);if(!e&&66===Xf)return!0;if(!Xf||Xf<51||!/native code/.test(t)){var r=new Vf((function(t){t(1)})),n=function(t){t((function(){}),(function(){}))};if((r.constructor={})[Qf]=n,!(Zf=r.then((function(){}))instanceof n))return!0}return!e&&(qf||Hf)&&!ts})),rs={CONSTRUCTOR:es,REJECTION_EVENT:ts,SUBCLASSING:Zf},ns={},os=dt,is=TypeError,us=function(t){var e,r;this.promise=new t((function(t,n){if(void 0!==e||void 0!==r)throw new is("Bad Promise constructor");e=t,r=n})),this.resolve=os(e),this.reject=os(r)};ns.f=function(t){return new us(t)};var cs,as,fs,ss=Hn,ls=ia,hs=r,ps=f,vs=$r,ds=ga,ys=ui,gs=Oa,ms=dt,bs=z,ws=U,Ss=ja,Os=Ca,xs=ff.set,Es=Df,js=function(t,e){try{1===arguments.length?console.error(t):console.error(t,e)}catch(r){}},Ps=zf,Ts=bf,Is=jr,Ls=Gf,Rs=ns,As="Promise",ks=rs.CONSTRUCTOR,Cs=rs.REJECTION_EVENT,_s=rs.SUBCLASSING,Fs=Is.getterFor(As),Ns=Is.set,Ms=Ls&&Ls.prototype,Ds=Ls,zs=Ms,Gs=hs.TypeError,Us=hs.document,Bs=hs.process,Ws=Rs.f,Vs=Ws,Js=!!(Us&&Us.createEvent&&hs.dispatchEvent),Ks="unhandledrejection",Ys=function(t){var e;return!(!ws(t)||!bs(e=t.then))&&e},$s=function(t,e){var r,n,o,i=e.value,u=1===e.state,c=u?t.ok:t.fail,a=t.resolve,f=t.reject,s=t.domain;try{c?(u||(2===e.rejection&&Zs(e),e.rejection=1),!0===c?r=i:(s&&s.enter(),r=c(i),s&&(s.exit(),o=!0)),r===t.promise?f(new Gs("Promise-chain cycle")):(n=Ys(r))?ps(n,r,a,f):a(r)):f(i)}catch(l){s&&!o&&s.exit(),f(l)}},qs=function(t,e){t.notified||(t.notified=!0,Es((function(){for(var r,n=t.reactions;r=n.get();)$s(r,t);t.notified=!1,e&&!t.rejection&&Xs(t)})))},Hs=function(t,e,r){var n,o;Js?((n=Us.createEvent("Event")).promise=e,n.reason=r,n.initEvent(t,!1,!0),hs.dispatchEvent(n)):n={promise:e,reason:r},!Cs&&(o=hs["on"+t])?o(n):t===Ks&&js("Unhandled promise rejection",r)},Xs=function(t){ps(xs,hs,(function(){var e,r=t.facade,n=t.value;if(Qs(t)&&(e=Ps((function(){ls?Bs.emit("unhandledRejection",n,r):Hs(Ks,r,n)})),t.rejection=ls||Qs(t)?2:1,e.error))throw e.value}))},Qs=function(t){return 1!==t.rejection&&!t.parent},Zs=function(t){ps(xs,hs,(function(){var e=t.facade;ls?Bs.emit("rejectionHandled",e):Hs("rejectionhandled",e,t.value)}))},tl=function(t,e,r){return function(n){t(e,n,r)}},el=function(t,e,r){t.done||(t.done=!0,r&&(t=r),t.value=e,t.state=2,qs(t,!0))},rl=function(t,e,r){if(!t.done){t.done=!0,r&&(t=r);try{if(t.facade===e)throw new Gs("Promise can't be resolved itself");var n=Ys(e);n?Es((function(){var r={done:!1};try{ps(n,e,tl(rl,r,t),tl(el,r,t))}catch(o){el(r,o,t)}})):(t.value=e,t.state=1,qs(t,!1))}catch(o){el({done:!1},o,t)}}};if(ks&&(zs=(Ds=function(t){Ss(this,zs),ms(t),ps(cs,this);var e=Fs(this);try{t(tl(rl,e),tl(el,e))}catch(r){el(e,r)}}).prototype,(cs=function(t){Ns(this,{type:As,done:!1,notified:!1,parent:!1,reactions:new Ts,rejection:!1,state:0,value:void 0})}).prototype=vs(zs,"then",(function(t,e){var r=Fs(this),n=Ws(Os(this,Ds));return r.parent=!0,n.ok=!bs(t)||t,n.fail=bs(e)&&e,n.domain=ls?Bs.domain:void 0,0===r.state?r.reactions.add(n):Es((function(){$s(n,r)})),n.promise})),as=function(){var t=new cs,e=Fs(t);this.promise=t,this.resolve=tl(rl,e),this.reject=tl(el,e)},Rs.f=Ws=function(t){return t===Ds||undefined===t?new as(t):Vs(t)},bs(Ls)&&Ms!==Object.prototype)){fs=Ms.then,_s||vs(Ms,"then",(function(t,e){var r=this;return new Ds((function(t,e){ps(fs,r,t,e)})).then(t,e)}),{unsafe:!0});try{delete Ms.constructor}catch(wb){}ds&&ds(Ms,zs)}ss({global:!0,constructor:!0,wrap:!0,forced:ks},{Promise:Ds}),ys(Ds,As,!1),gs(As);var nl={},ol=nl,il=Zt("iterator"),ul=Array.prototype,cl=io,al=mt,fl=A,sl=nl,ll=Zt("iterator"),hl=function(t){if(!fl(t))return al(t,ll)||al(t,"@@iterator")||sl[cl(t)]},pl=f,vl=dt,dl=Re,yl=lt,gl=hl,ml=TypeError,bl=f,wl=Re,Sl=mt,Ol=function(t,e,r){var n,o;wl(t);try{if(!(n=Sl(t,"return"))){if("throw"===e)throw r;return r}n=bl(n,t)}catch(wb){o=!0,n=wb}if("throw"===e)throw r;if(o)throw n;return wl(n),r},xl=pi,El=f,jl=Re,Pl=lt,Tl=function(t){return void 0!==t&&(ol.Array===t||ul[il]===t)},Il=an,Ll=J,Rl=function(t,e){var r=arguments.length<2?gl(t):e;if(vl(r))return dl(pl(r,t));throw new ml(yl(t)+" is not iterable")},Al=hl,kl=Ol,Cl=TypeError,_l=function(t,e){this.stopped=t,this.result=e},Fl=_l.prototype,Nl=function(t,e,r){var n,o,i,u,c,a,f,s=r&&r.that,l=!(!r||!r.AS_ENTRIES),h=!(!r||!r.IS_RECORD),p=!(!r||!r.IS_ITERATOR),v=!(!r||!r.INTERRUPTED),d=xl(e,s),y=function(t){return n&&kl(n,"normal",t),new _l(!0,t)},g=function(t){return l?(jl(t),v?d(t[0],t[1],y):d(t[0],t[1])):v?d(t,y):d(t)};if(h)n=t.iterator;else if(p)n=t;else{if(!(o=Al(t)))throw new Cl(Pl(t)+" is not iterable");if(Tl(o)){for(i=0,u=Il(t);u>i;i++)if((c=g(t[i]))&&Ll(Fl,c))return c;return new _l(!1)}n=Rl(t,o)}for(a=h?t.next:n.next;!(f=El(a,n)).done;){try{c=g(f.value)}catch(wb){kl(n,"throw",wb)}if("object"==typeof c&&c&&Ll(Fl,c))return c}return new _l(!1)},Ml=Zt("iterator"),Dl=!1;try{var zl=0,Gl={next:function(){return{done:!!zl++}},return:function(){Dl=!0}};Gl[Ml]=function(){return this},Array.from(Gl,(function(){throw 2}))}catch(wb){}var Ul=function(t,e){try{if(!e&&!Dl)return!1}catch(wb){return!1}var r=!1;try{var n={};n[Ml]=function(){return{next:function(){return{done:r=!0}}}},t(n)}catch(wb){}return r},Bl=Gf,Wl=rs.CONSTRUCTOR||!Ul((function(t){Bl.all(t).then(void 0,(function(){}))})),Vl=f,Jl=dt,Kl=ns,Yl=zf,$l=Nl;Hn({target:"Promise",stat:!0,forced:Wl},{all:function(t){var e=this,r=Kl.f(e),n=r.resolve,o=r.reject,i=Yl((function(){var r=Jl(e.resolve),i=[],u=0,c=1;$l(t,(function(t){var a=u++,f=!1;c++,Vl(r,e,t).then((function(t){f||(f=!0,i[a]=t,--c||n(i))}),o)})),--c||n(i)}));return i.error&&o(i.value),r.promise}});var ql=Hn,Hl=rs.CONSTRUCTOR,Xl=Gf,Ql=V,Zl=z,th=$r,eh=Xl&&Xl.prototype;if(ql({target:"Promise",proto:!0,forced:Hl,real:!0},{catch:function(t){return this.then(void 0,t)}}),Zl(Xl)){var rh=Ql("Promise").prototype.catch;eh.catch!==rh&&th(eh,"catch",rh,{unsafe:!0})}var nh=f,oh=dt,ih=ns,uh=zf,ch=Nl;Hn({target:"Promise",stat:!0,forced:Wl},{race:function(t){var e=this,r=ih.f(e),n=r.reject,o=uh((function(){var o=oh(e.resolve);ch(t,(function(t){nh(o,e,t).then(r.resolve,n)}))}));return o.error&&n(o.value),r.promise}});var ah=ns;Hn({target:"Promise",stat:!0,forced:rs.CONSTRUCTOR},{reject:function(t){var e=ah.f(this);return(0,e.reject)(t),e.promise}});var fh=Re,sh=U,lh=ns,hh=function(t,e){if(fh(t),sh(e)&&e.constructor===t)return e;var r=lh.f(t);return(0,r.resolve)(e),r.promise},ph=Hn,vh=rs.CONSTRUCTOR,dh=hh;V("Promise"),ph({target:"Promise",stat:!0,forced:vh},{resolve:function(t){return dh(this,t)}});var yh=Hn,gh=Gf,mh=o,bh=V,wh=z,Sh=Ca,Oh=hh,xh=$r,Eh=gh&&gh.prototype;if(yh({target:"Promise",proto:!0,real:!0,forced:!!gh&&mh((function(){Eh.finally.call({then:function(){}},(function(){}))}))},{finally:function(t){var e=Sh(this,bh("Promise")),r=wh(t);return this.then(r?function(r){return Oh(e,t()).then((function(){return r}))}:t,r?function(r){return Oh(e,t()).then((function(){throw r}))}:t)}}),wh(gh)){var jh=bh("Promise").prototype.finally;Eh.finally!==jh&&xh(Eh,"finally",jh,{unsafe:!0})}var Ph=Zt,Th=Fo,Ih=je.f,Lh=Ph("unscopables"),Rh=Array.prototype;void 0===Rh[Lh]&&Ih(Rh,Lh,{configurable:!0,value:Th(null)});var Ah,kh,Ch,_h=!o((function(){function t(){}return t.prototype.constructor=null,Object.getPrototypeOf(new t)!==t.prototype})),Fh=zt,Nh=z,Mh=Nt,Dh=_h,zh=sr("IE_PROTO"),Gh=Object,Uh=Gh.prototype,Bh=Dh?Gh.getPrototypeOf:function(t){var e=Mh(t);if(Fh(e,zh))return e[zh];var r=e.constructor;return Nh(r)&&e instanceof r?r.prototype:e instanceof Gh?Uh:null},Wh=o,Vh=z,Jh=U,Kh=Bh,Yh=$r,$h=Zt("iterator"),qh=!1;[].keys&&("next"in(Ch=[].keys())?(kh=Kh(Kh(Ch)))!==Object.prototype&&(Ah=kh):qh=!0);var Hh=!Jh(Ah)||Wh((function(){var t={};return Ah[$h].call(t)!==t}));Hh&&(Ah={}),Vh(Ah[$h])||Yh(Ah,$h,(function(){return this}));var Xh={IteratorPrototype:Ah,BUGGY_SAFARI_ITERATORS:qh},Qh=Xh.IteratorPrototype,Zh=Fo,tp=y,ep=ui,rp=nl,np=function(){return this},op=function(t,e,r,n){var o=e+" Iterator";return t.prototype=Zh(Qh,{next:tp(+!n,r)}),ep(t,o,!1),rp[o]=np,t},ip=Hn,up=f,cp=z,ap=op,fp=Bh,sp=ga,lp=ui,hp=Ve,pp=$r,vp=nl,dp=Xe.PROPER,yp=Xe.CONFIGURABLE,gp=Xh.IteratorPrototype,mp=Xh.BUGGY_SAFARI_ITERATORS,bp=Zt("iterator"),wp="keys",Sp="values",Op="entries",xp=function(){return this},Ep=function(t,e,r,n,o,i,u){ap(r,e,n);var c,a,f,s=function(t){if(t===o&&d)return d;if(!mp&&t&&t in p)return p[t];switch(t){case wp:case Sp:case Op:return function(){return new r(this,t)}}return function(){return new r(this)}},l=e+" Iterator",h=!1,p=t.prototype,v=p[bp]||p["@@iterator"]||o&&p[o],d=!mp&&v||s(o),y="Array"===e&&p.entries||v;if(y&&(c=fp(y.call(new t)))!==Object.prototype&&c.next&&(fp(c)!==gp&&(sp?sp(c,gp):cp(c[bp])||pp(c,bp,xp)),lp(c,l,!0)),dp&&o===Sp&&v&&v.name!==Sp&&(yp?hp(p,"name",Sp):(h=!0,d=function(){return up(v,this)})),o)if(a={values:s(Sp),keys:i?d:s(wp),entries:s(Op)},u)for(f in a)(mp||h||!(f in p))&&pp(p,f,a[f]);else ip({target:e,proto:!0,forced:mp||h},a);return p[bp]!==d&&pp(p,bp,d,{name:o}),vp[e]=d,a},jp=function(t,e){return{value:t,done:e}},Pp=M,Tp=function(t){Rh[Lh][t]=!0},Ip=nl,Lp=jr,Rp=je.f,Ap=Ep,kp=jp,Cp=i,_p="Array Iterator",Fp=Lp.set,Np=Lp.getterFor(_p),Mp=Ap(Array,"Array",(function(t,e){Fp(this,{type:_p,target:Pp(t),index:0,kind:e})}),(function(){var t=Np(this),e=t.target,r=t.index++;if(!e||r>=e.length)return t.target=void 0,kp(void 0,!0);switch(t.kind){case"keys":return kp(r,!1);case"values":return kp(e[r],!1)}return kp([r,e[r]],!1)}),"values"),Dp=Ip.Arguments=Ip.Array;if(Tp("keys"),Tp("values"),Tp("entries"),Cp&&"values"!==Dp.name)try{Rp(Dp,"name",{value:"values"})}catch(wb){}var zp={exports:{}},Gp=o((function(){if("function"==typeof ArrayBuffer){var t=new ArrayBuffer(8);Object.isExtensible(t)&&Object.defineProperty(t,"a",{value:8})}})),Up=o,Bp=U,Wp=j,Vp=Gp,Jp=Object.isExtensible,Kp=Up((function(){Jp(1)}))||Vp?function(t){return!!Bp(t)&&((!Vp||"ArrayBuffer"!==Wp(t))&&(!Jp||Jp(t)))}:Jp,Yp=!o((function(){return Object.isExtensible(Object.preventExtensions({}))})),$p=Hn,qp=S,Hp=lr,Xp=U,Qp=zt,Zp=je.f,tv=qr,ev=No,rv=Kp,nv=Yp,ov=!1,iv=Vt("meta"),uv=0,cv=function(t){Zp(t,iv,{value:{objectID:"O"+uv++,weakData:{}}})},av=zp.exports={enable:function(){av.enable=function(){},ov=!0;var t=tv.f,e=qp([].splice),r={};r[iv]=1,t(r).length&&(tv.f=function(r){for(var n=t(r),o=0,i=n.length;o<i;o++)if(n[o]===iv){e(n,o,1);break}return n},$p({target:"Object",stat:!0,forced:!0},{getOwnPropertyNames:ev.f}))},fastKey:function(t,e){if(!Xp(t))return"symbol"==typeof t?t:("string"==typeof t?"S":"P")+t;if(!Qp(t,iv)){if(!rv(t))return"F";if(!e)return"E";cv(t)}return t[iv].objectID},getWeakData:function(t,e){if(!Qp(t,iv)){if(!rv(t))return!0;if(!e)return!1;cv(t)}return t[iv].weakData},onFreeze:function(t){return nv&&ov&&rv(t)&&!Qp(t,iv)&&cv(t),t}};Hp[iv]=!0;var fv=zp.exports,sv=z,lv=U,hv=ga,pv=Hn,vv=r,dv=S,yv=Bn,gv=$r,mv=fv,bv=Nl,wv=ja,Sv=z,Ov=A,xv=U,Ev=o,jv=Ul,Pv=ui,Tv=function(t,e,r){var n,o;return hv&&sv(n=e.constructor)&&n!==r&&lv(o=n.prototype)&&o!==r.prototype&&hv(t,o),t},Iv=function(t,e,r){var n=-1!==t.indexOf("Map"),o=-1!==t.indexOf("Weak"),i=n?"set":"add",u=vv[t],c=u&&u.prototype,a=u,f={},s=function(t){var e=dv(c[t]);gv(c,t,"add"===t?function(t){return e(this,0===t?0:t),this}:"delete"===t?function(t){return!(o&&!xv(t))&&e(this,0===t?0:t)}:"get"===t?function(t){return o&&!xv(t)?void 0:e(this,0===t?0:t)}:"has"===t?function(t){return!(o&&!xv(t))&&e(this,0===t?0:t)}:function(t,r){return e(this,0===t?0:t,r),this})};if(yv(t,!Sv(u)||!(o||c.forEach&&!Ev((function(){(new u).entries().next()})))))a=r.getConstructor(e,t,n,i),mv.enable();else if(yv(t,!0)){var l=new a,h=l[i](o?{}:-0,1)!==l,p=Ev((function(){l.has(1)})),v=jv((function(t){new u(t)})),d=!o&&Ev((function(){for(var t=new u,e=5;e--;)t[i](e,e);return!t.has(-0)}));v||((a=e((function(t,e){wv(t,c);var r=Tv(new u,t,a);return Ov(e)||bv(e,r[i],{that:r,AS_ENTRIES:n}),r}))).prototype=c,c.constructor=a),(p||d)&&(s("delete"),s("has"),n&&s("get")),(d||h)&&s(i),o&&c.clear&&delete c.clear}return f[t]=a,pv({global:!0,constructor:!0,forced:a!==u},f),Pv(a,t),o||r.setStrong(a,t,n),a},Lv=$r,Rv=Fo,Av=Jo,kv=function(t,e,r){for(var n in e)Lv(t,n,e[n],r);return t},Cv=pi,_v=ja,Fv=A,Nv=Nl,Mv=Ep,Dv=jp,zv=Oa,Gv=i,Uv=fv.fastKey,Bv=jr.set,Wv=jr.getterFor,Vv={getConstructor:function(t,e,r,n){var o=t((function(t,o){_v(t,i),Bv(t,{type:e,index:Rv(null),first:void 0,last:void 0,size:0}),Gv||(t.size=0),Fv(o)||Nv(o,t[n],{that:t,AS_ENTRIES:r})})),i=o.prototype,u=Wv(e),c=function(t,e,r){var n,o,i=u(t),c=a(t,e);return c?c.value=r:(i.last=c={index:o=Uv(e,!0),key:e,value:r,previous:n=i.last,next:void 0,removed:!1},i.first||(i.first=c),n&&(n.next=c),Gv?i.size++:t.size++,"F"!==o&&(i.index[o]=c)),t},a=function(t,e){var r,n=u(t),o=Uv(e);if("F"!==o)return n.index[o];for(r=n.first;r;r=r.next)if(r.key===e)return r};return kv(i,{clear:function(){for(var t=u(this),e=t.first;e;)e.removed=!0,e.previous&&(e.previous=e.previous.next=void 0),e=e.next;t.first=t.last=void 0,t.index=Rv(null),Gv?t.size=0:this.size=0},delete:function(t){var e=this,r=u(e),n=a(e,t);if(n){var o=n.next,i=n.previous;delete r.index[n.index],n.removed=!0,i&&(i.next=o),o&&(o.previous=i),r.first===n&&(r.first=o),r.last===n&&(r.last=i),Gv?r.size--:e.size--}return!!n},forEach:function(t){for(var e,r=u(this),n=Cv(t,arguments.length>1?arguments[1]:void 0);e=e?e.next:r.first;)for(n(e.value,e.key,this);e&&e.removed;)e=e.previous},has:function(t){return!!a(this,t)}}),kv(i,r?{get:function(t){var e=a(this,t);return e&&e.value},set:function(t,e){return c(this,0===t?0:t,e)}}:{add:function(t){return c(this,t=0===t?0:t,t)}}),Gv&&Av(i,"size",{configurable:!0,get:function(){return u(this).size}}),o},setStrong:function(t,e,r){var n=e+" Iterator",o=Wv(e),i=Wv(n);Mv(t,e,(function(t,e){Bv(this,{type:n,target:t,state:o(t),kind:e,last:void 0})}),(function(){for(var t=i(this),e=t.kind,r=t.last;r&&r.removed;)r=r.previous;return t.target&&(t.last=r=r?r.next:t.state.first)?Dv("keys"===e?r.key:"values"===e?r.value:[r.key,r.value],!1):(t.target=void 0,Dv(void 0,!0))}),r?"entries":"values",!r,!0),zv(e)}};Iv("Map",(function(t){return function(){return t(this,arguments.length?arguments[0]:void 0)}}),Vv);var Jv=S,Kv=Map.prototype,Yv={Map:Map,set:Jv(Kv.set),get:Jv(Kv.get),has:Jv(Kv.has),remove:Jv(Kv.delete),proto:Kv},$v=Hn,qv=dt,Hv=_,Xv=Nl,Qv=o,Zv=Yv.Map,td=Yv.has,ed=Yv.get,rd=Yv.set,nd=S([].push);$v({target:"Map",stat:!0,forced:Qv((function(){return 1!==Zv.groupBy("ab",(function(t){return t})).get("a").length}))},{groupBy:function(t,e){Hv(t),qv(e);var r=new Zv,n=0;return Xv(t,(function(t){var o=e(t,n++);td(r,o)?nd(ed(r,o),t):rd(r,o,[t])})),r}});var od=io,id=Qn?{}.toString:function(){return"[object "+od(this)+"]"};Qn||$r(Object.prototype,"toString",id,{unsafe:!0});var ud=S,cd=Zr,ad=ao,fd=_,sd=ud("".charAt),ld=ud("".charCodeAt),hd=ud("".slice),pd=function(t){return function(e,r){var n,o,i=ad(fd(e)),u=cd(r),c=i.length;return u<0||u>=c?t?"":void 0:(n=ld(i,u))<55296||n>56319||u+1===c||(o=ld(i,u+1))<56320||o>57343?t?sd(i,u):n:t?hd(i,u,u+2):o-56320+(n-55296<<10)+65536}},vd={codeAt:pd(!1),charAt:pd(!0)},dd=vd.charAt,yd=ao,gd=jr,md=Ep,bd=jp,wd="String Iterator",Sd=gd.set,Od=gd.getterFor(wd);md(String,"String",(function(t){Sd(this,{type:wd,string:yd(t),index:0})}),(function(){var t,e=Od(this),r=e.string,n=e.index;return n>=r.length?bd(void 0,!0):(t=dd(r,n),e.index+=t.length,bd(t,!1))})),$o.Map,Iv("Set",(function(t){return function(){return t(this,arguments.length?arguments[0]:void 0)}}),Vv);var xd=S,Ed=Set.prototype,jd={Set:Set,add:xd(Ed.add),has:xd(Ed.has),remove:xd(Ed.delete),proto:Ed},Pd=jd.has,Td=function(t){return Pd(t),t},Id=f,Ld=function(t,e,r){for(var n,o,i=r?t:t.iterator,u=t.next;!(n=Id(u,i)).done;)if(void 0!==(o=e(n.value)))return o},Rd=S,Ad=Ld,kd=jd.Set,Cd=jd.proto,_d=Rd(Cd.forEach),Fd=Rd(Cd.keys),Nd=Fd(new kd).next,Md=function(t,e,r){return r?Ad({iterator:Fd(t),next:Nd},e):_d(t,e)},Dd=Md,zd=jd.Set,Gd=jd.add,Ud=function(t){var e=new zd;return Dd(t,(function(t){Gd(e,t)})),e},Bd=aa(jd.proto,"size","get")||function(t){return t.size},Wd=dt,Vd=Re,Jd=f,Kd=Zr,Yd=function(t){return{iterator:t,next:t.next,done:!1}},$d="Invalid size",qd=RangeError,Hd=TypeError,Xd=Math.max,Qd=function(t,e){this.set=t,this.size=Xd(e,0),this.has=Wd(t.has),this.keys=Wd(t.keys)};Qd.prototype={getIterator:function(){return Yd(Vd(Jd(this.keys,this.set)))},includes:function(t){return Jd(this.has,this.set,t)}};var Zd=function(t){Vd(t);var e=+t.size;if(e!=e)throw new Hd($d);var r=Kd(e);if(r<0)throw new qd($d);return new Qd(t,r)},ty=Td,ey=Ud,ry=Bd,ny=Zd,oy=Md,iy=Ld,uy=jd.has,cy=jd.remove,ay=V,fy=function(t){return{size:t,has:function(){return!1},keys:function(){return{next:function(){return{done:!0}}}}}},sy=function(t){var e=ay("Set");try{(new e)[t](fy(0));try{return(new e)[t](fy(-1)),!1}catch(r){return!0}}catch(wb){return!1}},ly=function(t){var e=ty(this),r=ny(t),n=ey(e);return ry(e)<=r.size?oy(e,(function(t){r.includes(t)&&cy(n,t)})):iy(r.getIterator(),(function(t){uy(e,t)&&cy(n,t)})),n};Hn({target:"Set",proto:!0,real:!0,forced:!sy("difference")},{difference:ly});var hy=Td,py=Bd,vy=Zd,dy=Md,yy=Ld,gy=jd.Set,my=jd.add,by=jd.has,wy=o,Sy=function(t){var e=hy(this),r=vy(t),n=new gy;return py(e)>r.size?yy(r.getIterator(),(function(t){by(e,t)&&my(n,t)})):dy(e,(function(t){r.includes(t)&&my(n,t)})),n};Hn({target:"Set",proto:!0,real:!0,forced:!sy("intersection")||wy((function(){return"3,2"!==String(Array.from(new Set([1,2,3]).intersection(new Set([3,2]))))}))},{intersection:Sy});var Oy=Td,xy=jd.has,Ey=Bd,jy=Zd,Py=Md,Ty=Ld,Iy=Ol,Ly=function(t){var e=Oy(this),r=jy(t);if(Ey(e)<=r.size)return!1!==Py(e,(function(t){if(r.includes(t))return!1}),!0);var n=r.getIterator();return!1!==Ty(n,(function(t){if(xy(e,t))return Iy(n,"normal",!1)}))};Hn({target:"Set",proto:!0,real:!0,forced:!sy("isDisjointFrom")},{isDisjointFrom:Ly});var Ry=Td,Ay=Bd,ky=Md,Cy=Zd,_y=function(t){var e=Ry(this),r=Cy(t);return!(Ay(e)>r.size)&&!1!==ky(e,(function(t){if(!r.includes(t))return!1}),!0)};Hn({target:"Set",proto:!0,real:!0,forced:!sy("isSubsetOf")},{isSubsetOf:_y});var Fy=Td,Ny=jd.has,My=Bd,Dy=Zd,zy=Ld,Gy=Ol,Uy=function(t){var e=Fy(this),r=Dy(t);if(My(e)<r.size)return!1;var n=r.getIterator();return!1!==zy(n,(function(t){if(!Ny(e,t))return Gy(n,"normal",!1)}))};Hn({target:"Set",proto:!0,real:!0,forced:!sy("isSupersetOf")},{isSupersetOf:Uy});var By=Td,Wy=Ud,Vy=Zd,Jy=Ld,Ky=jd.add,Yy=jd.has,$y=jd.remove,qy=function(t){var e=By(this),r=Vy(t).getIterator(),n=Wy(e);return Jy(r,(function(t){Yy(e,t)?$y(n,t):Ky(n,t)})),n};Hn({target:"Set",proto:!0,real:!0,forced:!sy("symmetricDifference")},{symmetricDifference:qy});var Hy=Td,Xy=jd.add,Qy=Ud,Zy=Zd,tg=Ld,eg=function(t){var e=Hy(this),r=Zy(t).getIterator(),n=Qy(e);return tg(r,(function(t){Xy(n,t)})),n};Hn({target:"Set",proto:!0,real:!0,forced:!sy("union")},{union:eg}),$o.Set;var rg=o,ng=Bi.forEach,og=function(t,e){var r=[][t];return!!r&&rg((function(){r.call(null,e||function(){return 1},1)}))},ig=og("forEach")?[].forEach:function(t){return ng(this,t,arguments.length>1?arguments[1]:void 0)};Hn({target:"Array",proto:!0,forced:[].forEach!==ig},{forEach:ig});var ug=Hn,cg=i,ag=fo.f;ug({target:"Object",stat:!0,forced:Object.defineProperties!==ag,sham:!cg},{defineProperties:ag});var fg=Hn,sg=i,lg=je.f;fg({target:"Object",stat:!0,forced:Object.defineProperty!==lg,sham:!sg},{defineProperty:lg});var hg=Hn,pg=o,vg=M,dg=n.f,yg=i;hg({target:"Object",stat:!0,forced:!yg||pg((function(){dg(1)})),sham:!yg},{getOwnPropertyDescriptor:function(t,e){return dg(vg(t),e)}});var gg=i,mg=je,bg=y,wg=Ln,Sg=M,Og=n,xg=function(t,e,r){gg?mg.f(t,e,bg(0,r)):t[e]=r};Hn({target:"Object",stat:!0,sham:!i},{getOwnPropertyDescriptors:function(t){for(var e,r,n=Sg(t),o=Og.f,i=wg(n),u={},c=0;i.length>c;)void 0!==(r=o(n,e=i[c++]))&&xg(u,e,r);return u}});var Eg=Nt,jg=ho;Hn({target:"Object",stat:!0,forced:o((function(){jg(1)}))},{keys:function(t){return jg(Eg(t))}});var Pg={CSSRuleList:0,CSSStyleDeclaration:0,CSSValueList:0,ClientRectList:0,DOMRectList:0,DOMStringList:0,DOMTokenList:1,DataTransferItemList:0,FileList:0,HTMLAllCollection:0,HTMLCollection:0,HTMLFormElement:0,HTMLSelectElement:0,MediaList:0,MimeTypeArray:0,NamedNodeMap:0,NodeList:1,PaintRequestList:0,Plugin:0,PluginArray:0,SVGLengthList:0,SVGNumberList:0,SVGPathSegList:0,SVGPointList:0,SVGStringList:0,SVGTransformList:0,SourceBufferList:0,StyleSheetList:0,TextTrackCueList:0,TextTrackList:0,TouchList:0},Tg=pe("span").classList,Ig=Tg&&Tg.constructor&&Tg.constructor.prototype,Lg=Ig===Object.prototype?void 0:Ig,Rg=r,Ag=Pg,kg=Lg,Cg=ig,_g=Ve,Fg=function(t){if(t&&t.forEach!==Cg)try{_g(t,"forEach",Cg)}catch(wb){t.forEach=Cg}};for(var Ng in Ag)Ag[Ng]&&Fg(Rg[Ng]&&Rg[Ng].prototype);Fg(kg);var Mg=r;Hn({global:!0,forced:Mg.globalThis!==Mg},{globalThis:Mg});var Dg,zg,Gg=U,Ug=j,Bg=Zt("match"),Wg=Re,Vg=function(){var t=Wg(this),e="";return t.hasIndices&&(e+="d"),t.global&&(e+="g"),t.ignoreCase&&(e+="i"),t.multiline&&(e+="m"),t.dotAll&&(e+="s"),t.unicode&&(e+="u"),t.unicodeSets&&(e+="v"),t.sticky&&(e+="y"),e},Jg=f,Kg=zt,Yg=J,$g=Vg,qg=RegExp.prototype,Hg=vd.charAt,Xg=o,Qg=r.RegExp,Zg=Xg((function(){var t=Qg("a","y");return t.lastIndex=2,null!==t.exec("abcd")})),tm=Zg||Xg((function(){return!Qg("a","y").sticky})),em={BROKEN_CARET:Zg||Xg((function(){var t=Qg("^r","gy");return t.lastIndex=2,null!==t.exec("str")})),MISSED_STICKY:tm,UNSUPPORTED_Y:Zg},rm=o,nm=r.RegExp,om=rm((function(){var t=nm(".","s");return!(t.dotAll&&t.test("\n")&&"s"===t.flags)})),im=o,um=r.RegExp,cm=im((function(){var t=um("(?<a>b)","g");return"b"!==t.exec("b").groups.a||"bc"!=="b".replace(t,"$<a>c")})),am=f,fm=S,sm=ao,lm=Vg,hm=em,pm=Fo,vm=jr.get,dm=om,ym=cm,gm=Ct("native-string-replace",String.prototype.replace),mm=RegExp.prototype.exec,bm=mm,wm=fm("".charAt),Sm=fm("".indexOf),Om=fm("".replace),xm=fm("".slice),Em=(zg=/b*/g,am(mm,Dg=/a/,"a"),am(mm,zg,"a"),0!==Dg.lastIndex||0!==zg.lastIndex),jm=hm.BROKEN_CARET,Pm=void 0!==/()??/.exec("")[1];(Em||Pm||jm||dm||ym)&&(bm=function(t){var e,r,n,o,i,u,c,a=this,f=vm(a),s=sm(t),l=f.raw;if(l)return l.lastIndex=a.lastIndex,e=am(bm,l,s),a.lastIndex=l.lastIndex,e;var h=f.groups,p=jm&&a.sticky,v=am(lm,a),d=a.source,y=0,g=s;if(p&&(v=Om(v,"y",""),-1===Sm(v,"g")&&(v+="g"),g=xm(s,a.lastIndex),a.lastIndex>0&&(!a.multiline||a.multiline&&"\n"!==wm(s,a.lastIndex-1))&&(d="(?: "+d+")",g=" "+g,y++),r=new RegExp("^(?:"+d+")",v)),Pm&&(r=new RegExp("^"+d+"$(?!\\s)",v)),Em&&(n=a.lastIndex),o=am(mm,p?r:a,g),p?o?(o.input=xm(o.input,y),o[0]=xm(o[0],y),o.index=a.lastIndex,a.lastIndex+=o[0].length):a.lastIndex=0:Em&&o&&(a.lastIndex=a.global?o.index+o[0].length:n),Pm&&o&&o.length>1&&am(gm,o[0],r,(function(){for(i=1;i<arguments.length-2;i++)void 0===arguments[i]&&(o[i]=void 0)})),o&&h)for(o.groups=u=pm(null),i=0;i<h.length;i++)u[(c=h[i])[0]]=o[c[1]];return o});var Tm=f,Im=Re,Lm=z,Rm=j,Am=bm,km=TypeError,Cm=Hn,_m=f,Fm=fi,Nm=op,Mm=jp,Dm=_,zm=un,Gm=ao,Um=Re,Bm=A,Wm=function(t){var e;return Gg(t)&&(void 0!==(e=t[Bg])?!!e:"RegExp"===Ug(t))},Vm=function(t){var e=t.flags;return void 0!==e||"flags"in qg||Kg(t,"flags")||!Yg(qg,t)?e:Jg($g,t)},Jm=mt,Km=$r,Ym=o,$m=Ca,qm=function(t,e,r){return e+(r?Hg(t,e).length:1)},Hm=function(t,e){var r=t.exec;if(Lm(r)){var n=Tm(r,t,e);return null!==n&&Im(n),n}if("RegExp"===Rm(t))return Tm(Am,t,e);throw new km("RegExp#exec called on incompatible receiver")},Xm=jr,Qm=Zt("matchAll"),Zm="RegExp String",tb=Zm+" Iterator",eb=Xm.set,rb=Xm.getterFor(tb),nb=RegExp.prototype,ob=TypeError,ib=Fm("".indexOf),ub=Fm("".matchAll),cb=!!ub&&!Ym((function(){ub("a",/./)})),ab=Nm((function(t,e,r,n){eb(this,{type:tb,regexp:t,string:e,global:r,unicode:n,done:!1})}),Zm,(function(){var t=rb(this);if(t.done)return Mm(void 0,!0);var e=t.regexp,r=t.string,n=Hm(e,r);return null===n?(t.done=!0,Mm(void 0,!0)):t.global?(""===Gm(n[0])&&(e.lastIndex=qm(r,zm(e.lastIndex),t.unicode)),Mm(n,!1)):(t.done=!0,Mm(n,!1))})),fb=function(t){var e,r,n,o=Um(this),i=Gm(t),u=$m(o,RegExp),c=Gm(Vm(o));return e=new u(u===RegExp?o.source:o,c),r=!!~ib(c,"g"),n=!!~ib(c,"u"),e.lastIndex=zm(o.lastIndex),new ab(e,i,r,n)};Cm({target:"String",proto:!0,forced:cb},{matchAll:function(t){var e,r,n,o=Dm(this);if(Bm(t)){if(cb)return ub(o,t)}else{if(Wm(t)&&(e=Gm(Dm(Vm(t))),!~ib(e,"g")))throw new ob("`.matchAll` does not allow non-global regexes");if(cb)return ub(o,t);if(n=Jm(t,Qm))return _m(n,t,o)}return r=Gm(o),new RegExp(t,"g")[Qm](r)}}),Qm in nb||Km(nb,Qm,fb);!function(t){var e=function(t){var e,r=Object.prototype,n=r.hasOwnProperty,o=Object.defineProperty||function(t,e,r){t[e]=r.value},i="function"==typeof Symbol?Symbol:{},u=i.iterator||"@@iterator",c=i.asyncIterator||"@@asyncIterator",a=i.toStringTag||"@@toStringTag";function f(t,e,r){return Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}),t[e]}try{f({},"")}catch(C){f=function(t,e,r){return t[e]=r}}function s(t,e,r,n){var i=e&&e.prototype instanceof g?e:g,u=Object.create(i.prototype),c=new R(n||[]);return o(u,"_invoke",{value:P(t,r,c)}),u}function l(t,e,r){try{return{type:"normal",arg:t.call(e,r)}}catch(C){return{type:"throw",arg:C}}}t.wrap=s;var h="suspendedStart",p="suspendedYield",v="executing",d="completed",y={};function g(){}function m(){}function b(){}var w={};f(w,u,(function(){return this}));var S=Object.getPrototypeOf,O=S&&S(S(A([])));O&&O!==r&&n.call(O,u)&&(w=O);var x=b.prototype=g.prototype=Object.create(w);function E(t){["next","throw","return"].forEach((function(e){f(t,e,(function(t){return this._invoke(e,t)}))}))}function j(t,e){function r(o,i,u,c){var a=l(t[o],t,i);if("throw"!==a.type){var f=a.arg,s=f.value;return s&&"object"==typeof s&&n.call(s,"__await")?e.resolve(s.__await).then((function(t){r("next",t,u,c)}),(function(t){r("throw",t,u,c)})):e.resolve(s).then((function(t){f.value=t,u(f)}),(function(t){return r("throw",t,u,c)}))}c(a.arg)}var i;o(this,"_invoke",{value:function(t,n){function o(){return new e((function(e,o){r(t,n,e,o)}))}return i=i?i.then(o,o):o()}})}function P(t,e,r){var n=h;return function(o,i){if(n===v)throw new Error("Generator is already running");if(n===d){if("throw"===o)throw i;return k()}for(r.method=o,r.arg=i;;){var u=r.delegate;if(u){var c=T(u,r);if(c){if(c===y)continue;return c}}if("next"===r.method)r.sent=r._sent=r.arg;else if("throw"===r.method){if(n===h)throw n=d,r.arg;r.dispatchException(r.arg)}else"return"===r.method&&r.abrupt("return",r.arg);n=v;var a=l(t,e,r);if("normal"===a.type){if(n=r.done?d:p,a.arg===y)continue;return{value:a.arg,done:r.done}}"throw"===a.type&&(n=d,r.method="throw",r.arg=a.arg)}}}function T(t,r){var n=r.method,o=t.iterator[n];if(o===e)return r.delegate=null,"throw"===n&&t.iterator.return&&(r.method="return",r.arg=e,T(t,r),"throw"===r.method)||"return"!==n&&(r.method="throw",r.arg=new TypeError("The iterator does not provide a '"+n+"' method")),y;var i=l(o,t.iterator,r.arg);if("throw"===i.type)return r.method="throw",r.arg=i.arg,r.delegate=null,y;var u=i.arg;return u?u.done?(r[t.resultName]=u.value,r.next=t.nextLoc,"return"!==r.method&&(r.method="next",r.arg=e),r.delegate=null,y):u:(r.method="throw",r.arg=new TypeError("iterator result is not an object"),r.delegate=null,y)}function I(t){var e={tryLoc:t[0]};1 in t&&(e.catchLoc=t[1]),2 in t&&(e.finallyLoc=t[2],e.afterLoc=t[3]),this.tryEntries.push(e)}function L(t){var e=t.completion||{};e.type="normal",delete e.arg,t.completion=e}function R(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(I,this),this.reset(!0)}function A(t){if(t){var r=t[u];if(r)return r.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var o=-1,i=function r(){for(;++o<t.length;)if(n.call(t,o))return r.value=t[o],r.done=!1,r;return r.value=e,r.done=!0,r};return i.next=i}}return{next:k}}function k(){return{value:e,done:!0}}return m.prototype=b,o(x,"constructor",{value:b,configurable:!0}),o(b,"constructor",{value:m,configurable:!0}),m.displayName=f(b,a,"GeneratorFunction"),t.isGeneratorFunction=function(t){var e="function"==typeof t&&t.constructor;return!!e&&(e===m||"GeneratorFunction"===(e.displayName||e.name))},t.mark=function(t){return Object.setPrototypeOf?Object.setPrototypeOf(t,b):(t.__proto__=b,f(t,a,"GeneratorFunction")),t.prototype=Object.create(x),t},t.awrap=function(t){return{__await:t}},E(j.prototype),f(j.prototype,c,(function(){return this})),t.AsyncIterator=j,t.async=function(e,r,n,o,i){void 0===i&&(i=Promise);var u=new j(s(e,r,n,o),i);return t.isGeneratorFunction(r)?u:u.next().then((function(t){return t.done?t.value:u.next()}))},E(x),f(x,a,"Generator"),f(x,u,(function(){return this})),f(x,"toString",(function(){return"[object Generator]"})),t.keys=function(t){var e=Object(t),r=[];for(var n in e)r.push(n);return r.reverse(),function t(){for(;r.length;){var n=r.pop();if(n in e)return t.value=n,t.done=!1,t}return t.done=!0,t}},t.values=A,R.prototype={constructor:R,reset:function(t){if(this.prev=0,this.next=0,this.sent=this._sent=e,this.done=!1,this.delegate=null,this.method="next",this.arg=e,this.tryEntries.forEach(L),!t)for(var r in this)"t"===r.charAt(0)&&n.call(this,r)&&!isNaN(+r.slice(1))&&(this[r]=e)},stop:function(){this.done=!0;var t=this.tryEntries[0].completion;if("throw"===t.type)throw t.arg;return this.rval},dispatchException:function(t){if(this.done)throw t;var r=this;function o(n,o){return c.type="throw",c.arg=t,r.next=n,o&&(r.method="next",r.arg=e),!!o}for(var i=this.tryEntries.length-1;i>=0;--i){var u=this.tryEntries[i],c=u.completion;if("root"===u.tryLoc)return o("end");if(u.tryLoc<=this.prev){var a=n.call(u,"catchLoc"),f=n.call(u,"finallyLoc");if(a&&f){if(this.prev<u.catchLoc)return o(u.catchLoc,!0);if(this.prev<u.finallyLoc)return o(u.finallyLoc)}else if(a){if(this.prev<u.catchLoc)return o(u.catchLoc,!0)}else{if(!f)throw new Error("try statement without catch or finally");if(this.prev<u.finallyLoc)return o(u.finallyLoc)}}}},abrupt:function(t,e){for(var r=this.tryEntries.length-1;r>=0;--r){var o=this.tryEntries[r];if(o.tryLoc<=this.prev&&n.call(o,"finallyLoc")&&this.prev<o.finallyLoc){var i=o;break}}i&&("break"===t||"continue"===t)&&i.tryLoc<=e&&e<=i.finallyLoc&&(i=null);var u=i?i.completion:{};return u.type=t,u.arg=e,i?(this.method="next",this.next=i.finallyLoc,y):this.complete(u)},complete:function(t,e){if("throw"===t.type)throw t.arg;return"break"===t.type||"continue"===t.type?this.next=t.arg:"return"===t.type?(this.rval=this.arg=t.arg,this.method="return",this.next="end"):"normal"===t.type&&e&&(this.next=e),y},finish:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var r=this.tryEntries[e];if(r.finallyLoc===t)return this.complete(r.completion,r.afterLoc),L(r),y}},catch:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var r=this.tryEntries[e];if(r.tryLoc===t){var n=r.completion;if("throw"===n.type){var o=n.arg;L(r)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(t,r,n){return this.delegate={iterator:A(t),resultName:r,nextLoc:n},"next"===this.method&&(this.arg=e),y}},t}(t.exports);try{regeneratorRuntime=e}catch(r){"object"==typeof globalThis?globalThis.regeneratorRuntime=e:Function("r","regeneratorRuntime = r")(e)}}({exports:{}});var sb=r,lb=Pg,hb=Lg,pb=Mp,vb=Ve,db=ui,yb=Zt("iterator"),gb=pb.values,mb=function(t,e){if(t){if(t[yb]!==gb)try{vb(t,yb,gb)}catch(wb){t[yb]=gb}if(db(t,e,!0),lb[e])for(var r in pb)if(t[r]!==pb[r])try{vb(t,r,pb[r])}catch(wb){t[r]=pb[r]}}};for(var bb in lb)mb(sb[bb]&&sb[bb].prototype,bb);mb(hb,"DOMTokenList"),function(){function e(t,e){return(e||"")+" (SystemJS https://github.com/systemjs/systemjs/blob/main/docs/errors.md#"+t+")"}function r(t,e){if(-1!==t.indexOf("\\")&&(t=t.replace(E,"/")),"/"===t[0]&&"/"===t[1])return e.slice(0,e.indexOf(":")+1)+t;if("."===t[0]&&("/"===t[1]||"."===t[1]&&("/"===t[2]||2===t.length&&(t+="/"))||1===t.length&&(t+="/"))||"/"===t[0]){var r,n=e.slice(0,e.indexOf(":")+1);if(r="/"===e[n.length+1]?"file:"!==n?(r=e.slice(n.length+2)).slice(r.indexOf("/")+1):e.slice(8):e.slice(n.length+("/"===e[n.length])),"/"===t[0])return e.slice(0,e.length-r.length-1)+t;for(var o=r.slice(0,r.lastIndexOf("/")+1)+t,i=[],u=-1,c=0;c<o.length;c++)-1!==u?"/"===o[c]&&(i.push(o.slice(u,c+1)),u=-1):"."===o[c]?"."!==o[c+1]||"/"!==o[c+2]&&c+2!==o.length?"/"===o[c+1]||c+1===o.length?c+=1:u=c:(i.pop(),c+=2):u=c;return-1!==u&&i.push(o.slice(u)),e.slice(0,e.length-r.length)+i.join("")}}function n(t,e){return r(t,e)||(-1!==t.indexOf(":")?t:r("./"+t,e))}function o(t,e,n,o,i){for(var u in t){var c=r(u,n)||u,s=t[u];if("string"==typeof s){var l=f(o,r(s,n)||s,i);l?e[c]=l:a("W1",u,s)}}}function i(t,e,r){var i;for(i in t.imports&&o(t.imports,r.imports,e,r,null),t.scopes||{}){var u=n(i,e);o(t.scopes[i],r.scopes[u]||(r.scopes[u]={}),e,r,u)}for(i in t.depcache||{})r.depcache[n(i,e)]=t.depcache[i];for(i in t.integrity||{})r.integrity[n(i,e)]=t.integrity[i]}function u(t,e){if(e[t])return t;var r=t.length;do{var n=t.slice(0,r+1);if(n in e)return n}while(-1!==(r=t.lastIndexOf("/",r-1)))}function c(t,e){var r=u(t,e);if(r){var n=e[r];if(null===n)return;if(!(t.length>r.length&&"/"!==n[n.length-1]))return n+t.slice(r.length);a("W2",r,n)}}function a(t,r,n){console.warn(e(t,[n,r].join(", ")))}function f(t,e,r){for(var n=t.scopes,o=r&&u(r,n);o;){var i=c(e,n[o]);if(i)return i;o=u(o.slice(0,o.lastIndexOf("/")),n)}return c(e,t.imports)||-1!==e.indexOf(":")&&e}function s(){this[P]={}}function l(t,r,n,o){var i=t[P][r];if(i)return i;var u=[],c=Object.create(null);j&&Object.defineProperty(c,j,{value:"Module"});var a=Promise.resolve().then((function(){return t.instantiate(r,n,o)})).then((function(n){if(!n)throw Error(e(2,r));var o=n[1]((function(t,e){i.h=!0;var r=!1;if("string"==typeof t)t in c&&c[t]===e||(c[t]=e,r=!0);else{for(var n in t)e=t[n],n in c&&c[n]===e||(c[n]=e,r=!0);t&&t.__esModule&&(c.__esModule=t.__esModule)}if(r)for(var o=0;o<u.length;o++){var a=u[o];a&&a(c)}return e}),2===n[1].length?{import:function(e,n){return t.import(e,r,n)},meta:t.createContext(r)}:void 0);return i.e=o.execute||function(){},[n[0],o.setters||[],n[2]||[]]}),(function(t){throw i.e=null,i.er=t,t})),f=a.then((function(e){return Promise.all(e[0].map((function(n,o){var i=e[1][o],u=e[2][o];return Promise.resolve(t.resolve(n,r)).then((function(e){var n=l(t,e,r,u);return Promise.resolve(n.I).then((function(){return i&&(n.i.push(i),!n.h&&n.I||i(n.n)),n}))}))}))).then((function(t){i.d=t}))}));return i=t[P][r]={id:r,i:u,n:c,m:o,I:a,L:f,h:!1,d:void 0,e:void 0,er:void 0,E:void 0,C:void 0,p:void 0}}function h(t,e,r,n){if(!n[e.id])return n[e.id]=!0,Promise.resolve(e.L).then((function(){return e.p&&null!==e.p.e||(e.p=r),Promise.all(e.d.map((function(e){return h(t,e,r,n)})))})).catch((function(t){if(e.er)throw t;throw e.e=null,t}))}function p(t,e){return e.C=h(t,e,e,{}).then((function(){return v(t,e,{})})).then((function(){return e.n}))}function v(t,e,r){function n(){try{var t=i.call(I);if(t)return t=t.then((function(){e.C=e.n,e.E=null}),(function(t){throw e.er=t,e.E=null,t})),e.E=t;e.C=e.n,e.L=e.I=void 0}catch(r){throw e.er=r,r}}if(!r[e.id]){if(r[e.id]=!0,!e.e){if(e.er)throw e.er;return e.E?e.E:void 0}var o,i=e.e;return e.e=null,e.d.forEach((function(n){try{var i=v(t,n,r);i&&(o=o||[]).push(i)}catch(c){throw e.er=c,c}})),o?Promise.all(o).then(n):n()}}function d(){[].forEach.call(document.querySelectorAll("script"),(function(t){if(!t.sp)if("systemjs-module"===t.type){if(t.sp=!0,!t.src)return;System.import("import:"===t.src.slice(0,7)?t.src.slice(7):n(t.src,y)).catch((function(e){if(e.message.indexOf("https://github.com/systemjs/systemjs/blob/main/docs/errors.md#3")>-1){var r=document.createEvent("Event");r.initEvent("error",!1,!1),t.dispatchEvent(r)}return Promise.reject(e)}))}else if("systemjs-importmap"===t.type){t.sp=!0;var r=t.src?(System.fetch||fetch)(t.src,{integrity:t.integrity,priority:t.fetchPriority,passThrough:!0}).then((function(t){if(!t.ok)throw Error(t.status);return t.text()})).catch((function(r){return r.message=e("W4",t.src)+"\n"+r.message,console.warn(r),"function"==typeof t.onerror&&t.onerror(),"{}"})):t.innerHTML;A=A.then((function(){return r})).then((function(r){!function(t,r,n){var o={};try{o=JSON.parse(r)}catch(c){console.warn(Error(e("W5")))}i(o,n,t)}(k,r,t.src||y)}))}}))}var y,g="undefined"!=typeof Symbol,m="undefined"!=typeof self,b="undefined"!=typeof document,w=m?self:t;if(b){var S=document.querySelector("base[href]");S&&(y=S.href)}if(!y&&"undefined"!=typeof location){var O=(y=location.href.split("#")[0].split("?")[0]).lastIndexOf("/");-1!==O&&(y=y.slice(0,O+1))}var x,E=/\\/g,j=g&&Symbol.toStringTag,P=g?Symbol():"@",T=s.prototype;T.import=function(t,e,r){var n=this;return e&&"object"==typeof e&&(r=e,e=void 0),Promise.resolve(n.prepareImport()).then((function(){return n.resolve(t,e,r)})).then((function(t){var e=l(n,t,void 0,r);return e.C||p(n,e)}))},T.createContext=function(t){var e=this;return{url:t,resolve:function(r,n){return Promise.resolve(e.resolve(r,n||t))}}},T.register=function(t,e,r){x=[t,e,r]},T.getRegister=function(){var t=x;return x=void 0,t};var I=Object.freeze(Object.create(null));w.System=new s;var L,R,A=Promise.resolve(),k={imports:{},scopes:{},depcache:{},integrity:{}},C=b;if(T.prepareImport=function(t){return(C||t)&&(d(),C=!1),A},T.getImportMap=function(){return JSON.parse(JSON.stringify(k))},b&&(d(),window.addEventListener("DOMContentLoaded",d)),T.addImportMap=function(t,e){i(t,e||y,k)},b){window.addEventListener("error",(function(t){F=t.filename,N=t.error}));var _=location.origin}T.createScript=function(t){var e=document.createElement("script");e.async=!0,t.indexOf(_+"/")&&(e.crossOrigin="anonymous");var r=k.integrity[t];return r&&(e.integrity=r),e.src=t,e};var F,N,M={},D=T.register;T.register=function(t,e){if(b&&"loading"===document.readyState&&"string"!=typeof t){var r=document.querySelectorAll("script[src]"),n=r[r.length-1];if(n){L=t;var o=this;R=setTimeout((function(){M[n.src]=[t,e],o.import(n.src)}))}}else L=void 0;return D.call(this,t,e)},T.instantiate=function(t,r){var n=M[t];if(n)return delete M[t],n;var o=this;return Promise.resolve(T.createScript(t)).then((function(n){return new Promise((function(i,u){n.addEventListener("error",(function(){u(Error(e(3,[t,r].join(", "))))})),n.addEventListener("load",(function(){if(document.head.removeChild(n),F===t)u(N);else{var e=o.getRegister(t);e&&e[0]===L&&clearTimeout(R),i(e)}})),document.head.appendChild(n)}))}))},T.shouldFetch=function(){return!1},"undefined"!=typeof fetch&&(T.fetch=fetch);var z=T.instantiate,G=/^(text|application)\/(x-)?javascript(;|$)/;T.instantiate=function(t,r,n){var o=this;return this.shouldFetch(t,r,n)?this.fetch(t,{credentials:"same-origin",integrity:k.integrity[t],meta:n}).then((function(n){if(!n.ok)throw Error(e(7,[n.status,n.statusText,t,r].join(", ")));var i=n.headers.get("content-type");if(!i||!G.test(i))throw Error(e(4,i));return n.text().then((function(e){return e.indexOf("//# sourceURL=")<0&&(e+="\n//# sourceURL="+t),(0,eval)(e),o.getRegister(t)}))})):z.apply(this,arguments)},T.resolve=function(t,n){return f(k,r(t,n=n||y)||t,n)||function(t,r){throw Error(e(8,[t,r].join(", ")))}(t,n)};var U=T.instantiate;T.instantiate=function(t,e,r){var n=k.depcache[t];if(n)for(var o=0;o<n.length;o++)l(this,this.resolve(n[o],t),t);return U.call(this,t,e,r)},m&&"function"==typeof importScripts&&(T.instantiate=function(t){var e=this;return Promise.resolve().then((function(){return importScripts(t),e.getRegister(t)}))})}()}();
dist/assets/sendIcon-79e92e84.svg ADDED
dist/assets/show-right-icon-12c14da5.png ADDED
dist/index.html ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title></title>
8
+ <script type="module" crossorigin src="/assets/index-26b4a389.js"></script>
9
+ <link rel="stylesheet" href="/assets/index-ab4095ce.css">
10
+ <script type="module">import.meta.url;import("_").catch(()=>1);async function* g(){};if(location.protocol!="file:"){window.__vite_is_modern_browser=true}</script>
11
+ <script type="module">!function(){if(window.__vite_is_modern_browser)return;console.warn("vite: loading legacy chunks, syntax error above and the same error below should be ignored");var e=document.getElementById("vite-legacy-polyfill"),n=document.createElement("script");n.src=e.src,n.onload=function(){System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))},document.body.appendChild(n)}();</script>
12
+ </head>
13
+
14
+ <body>
15
+ <div id="root"></div>
16
+
17
+ <script nomodule>!function(){var e=document,t=e.createElement("script");if(!("noModule"in t)&&"onbeforeload"in t){var n=!1;e.addEventListener("beforeload",(function(e){if(e.target===t)n=!0;else if(!e.target.hasAttribute("nomodule")||!n)return;e.preventDefault()}),!0),t.type="module",t.src=".",e.head.appendChild(t),t.remove()}}();</script>
18
+ <script nomodule crossorigin id="vite-legacy-polyfill" src="/assets/polyfills-legacy-0b55db5f.js"></script>
19
+ <script nomodule crossorigin id="vite-legacy-entry" data-src="/assets/index-legacy-f957e103.js">System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))</script>
20
+ </body>
21
+ </html>
frontend/React/.gitignore ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
3
+
4
+ # dependencies
5
+ /node_modules
6
+ /.pnp
7
+ .pnp.js
8
+
9
+ # testing
10
+ /coverage
11
+
12
+ # production
13
+ /build
14
+
15
+ # misc
16
+ .DS_Store
17
+
18
+ npm-debug.log*
19
+ yarn-debug.log*
20
+ yarn-error.log*
frontend/React/.prettierignore ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ dist
2
+ deploy
3
+ values
4
+ node_modules
5
+ .gitignore
6
+ .prettierignore
7
+ .husky
frontend/React/.prettierrc.json ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ {
2
+ "printWidth": 120,
3
+ "tabWidth": 4,
4
+ "singleQuote": true,
5
+ "quoteProps": "as-needed",
6
+ "bracketSpacing": true
7
+ }
frontend/React/README.md ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 开始
2
+ ## 准备node.js开发环境
3
+ Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,允许你在服务器端运行 JavaScript。以下是在 Windows、Linux 和 macOS 上安装 Node.js 的详细步骤。
4
+
5
+ ### 在 Windows 上安装 Node.js
6
+ - 步骤 1: 访问 Node.js 官网
7
+
8
+ 打开浏览器,访问 [Node.js](https://nodejs.org/zh-cn/download/prebuilt-installer) 官方网站。
9
+
10
+ - 步骤 2: 下载 Node.js 安装包
11
+
12
+ 选择你需要的nodejs版本,设备的类型,点击下载,示例如下图:
13
+ ![windows install](./windows-.png)
14
+
15
+ - 步骤 3: 安装 Node.js
16
+
17
+ 双击下载的安装包开始安装。
18
+
19
+ 跟随安装向导的指示进行安装。在安装过程中,你可以选择安装位置、是否将 Node.js 添加到系统 PATH 环境变量等选项。推荐选择“添加到 PATH”以便在任何地方都能通过命令行访问 Node.js。
20
+ 安装完成后,点击“Finish”结束安装。
21
+
22
+ - 步骤 4: 验证安装
23
+
24
+ 打开命令提示符(CMD)或 PowerShell。
25
+ 输入 node -v 并回车,如果系统返回了 Node.js 的版本号,说明安装成功。
26
+ 接着,输入 npm -v 并回车,npm 是 Node.js 的包管理器,如果返回了版本号,表示 npm 也已正确安装。
27
+
28
+ ### 在 Linux 上安装 Node.js
29
+ 注意: 由于 Linux 发行版众多,以下以 Ubuntu 为例说明,其他发行版(如 CentOS、Debian 等)的安装方式可能略有不同,可自行查询对应的安装办法。
30
+
31
+ - 步骤 1: 更新你的包管理器
32
+
33
+ 打开终端。
34
+
35
+ 输入 sudo apt update 并回车,以更新 Ubuntu 的包索引。
36
+
37
+ - 步骤 2: 安装 Node.js
38
+
39
+ 对于 Ubuntu 18.04 及更高版本,Node.js 可以直接从 Ubuntu 的仓库中安装。
40
+ 输入 sudo apt install nodejs npm 并回车。
41
+ 对于旧版本的 Ubuntu 或需要安装特定版本的 Node.js,你可能需要使用如 NodeSource 这样的第三方仓库。
42
+
43
+ - 步骤 3: 验证安装
44
+
45
+ 在终端中,输入 node -v 和 npm -v 来验证 Node.js 和 npm 是否已正确安装。
46
+
47
+ ### 在 macOS 上安装 Node.js
48
+
49
+ #### 下载安装
50
+ - 步骤 1: 访问 Node.js 官网
51
+
52
+ 打开浏览器,访问 Node.js 官方网站。
53
+
54
+ - 步骤 2: 下载 Node.js 安装包
55
+
56
+ 在首页找到 macOS 对应的安装包(通常是 .pkg 文件),点击下载。
57
+
58
+ - 步骤 3: 安装 Node.js
59
+
60
+ 找到下载的 .pkg 文件,双击打开。
61
+ 跟随安装向导的指示进行安装。
62
+ 安装完成后,点击“Close”结束安装。
63
+
64
+ - 步骤 4: 验证安装
65
+
66
+ 打开终端。
67
+
68
+ 输入 node -v 和 npm -v 来验证 Node.js 和 npm 是否已正确安装。
69
+
70
+ #### 使用HomeBrew安装
71
+ 前提条件:确保你的macOS上已经安装了Homebrew。如果尚未安装,可以通过以下命令进行安装(以终端操作为例):
72
+ ```
73
+ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
74
+ ```
75
+ 按照提示输入密码以确认安装。安装过程中,可能需要你同意许可协议等。
76
+
77
+ - 打开终端:
78
+ 在macOS上找到并打开“终端”应用程序。
79
+
80
+ - 使用Homebrew安装Node.js:
81
+ 在终端中输入以下命令来安装最新版本的Node.js
82
+ ```
83
+ brew install node
84
+ ```
85
+ Homebrew会自动下载Node.js的安装包,并处理相关的依赖项和安装过程。你需要等待一段时间,直到安装完成。
86
+
87
+ - 验证安装:
88
+ 安装完成后,你可以通过输入以下命令来验证Node.js是否成功安装:
89
+ ```
90
+ node -v
91
+ ```
92
+ 如果终端输出了Node.js的版本号,那么表示安装成功。同时,你也可以通过输入npm -v来验证npm(Node.js的包管理器)是否也成功安装。
93
+
94
+ 完成以上步骤后,你应该能在你的 Windows、Linux 或 macOS 系统上成功安装并运行 Node.js。
95
+
96
+ ### 更多
97
+ 如需了解更多,可参照:https://nodejs.org/en
98
+
99
+ 如环境已经准备好,跳转下一步
100
+
101
+ ## 安装依赖
102
+ 进入前端项目根目录
103
+ ```
104
+ npm install
105
+ ```
106
+
107
+ ## 启动
108
+ ```
109
+ npm start
110
+ ```
111
+
112
+ 启动成功后,界面将出现可访问的本地url
113
+
114
+ ## 配置
115
+ ### 接口请求配置
116
+ - 如您需要配置的服务支持跨域,可至/src/config/cgi.ts中修改请求链接,请求链接为http://ip:port/path;
117
+ - 如您需要配置的服务不支持跨域,可至vite.config.ts中配置proxy,示例如下:
118
+
119
+ ```
120
+ server: {
121
+ port: 8080,
122
+ proxy: {
123
+ "/solve": {
124
+ target: "https://example.com",
125
+ changeOrigin: true,
126
+ }
127
+ }
128
+ }
129
+ ```
130
+
131
+ ## 知悉
132
+ - 前端服务基于react开发,如需了解react相关知识,可参考:https://react.dev/
frontend/React/index.html ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title></title>
8
+ </head>
9
+
10
+ <body>
11
+ <div id="root"></div>
12
+ <script type="module" src="/src/index.tsx"></script>
13
+ </body>
14
+ </html>
frontend/React/package-lock.json ADDED
The diff for this file is too large to render. See raw diff
 
frontend/React/package.json ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "test-react-flow",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "start": "vite --host --mode dev",
8
+ "build": "tsc && vite build",
9
+ "preview": "vite preview",
10
+ "prettier": "prettier --write ."
11
+ },
12
+ "devDependencies": {
13
+ "@babel/plugin-proposal-optional-chaining": "^7.21.0",
14
+ "@types/classnames": "^2.3.1",
15
+ "@types/js-cookie": "^3.0.3",
16
+ "@types/node": "^18.15.11",
17
+ "@types/react": "^18.0.28",
18
+ "@types/react-dom": "^18.0.11",
19
+ "@vitejs/plugin-legacy": "^4.0.2",
20
+ "@vitejs/plugin-react": "^3.1.0",
21
+ "husky": "^9.0.11",
22
+ "less": "^4.1.3",
23
+ "lint-staged": "^15.2.7",
24
+ "prettier": "^3.0.0",
25
+ "react": "^18.2.0",
26
+ "react-dom": "^18.2.0",
27
+ "terser": "^5.16.9",
28
+ "typescript": "^4.9.3",
29
+ "vite": "^4.2.1",
30
+ "vite-babel-plugin": "^0.0.2"
31
+ },
32
+ "dependencies": {
33
+ "@antv/x6": "^2.18.1",
34
+ "@microsoft/fetch-event-source": "^2.0.1",
35
+ "antd": "^5.18.3",
36
+ "axios": "^1.3.5",
37
+ "classnames": "^2.5.1",
38
+ "elkjs": "^0.9.3",
39
+ "js-cookie": "^3.0.1",
40
+ "react-markdown": "^9.0.1",
41
+ "react-router": "^6.11.2",
42
+ "react-router-dom": "^6.11.2",
43
+ "reactflow": "^11.11.3",
44
+ "rehype-raw": "^7.0.0"
45
+ },
46
+ "lint-staged": {
47
+ "**/*.{ts, tsx, less, module.less, json, md, .html}": "prettier --write ."
48
+ }
49
+ }
frontend/React/src/App.module.less ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .app {
2
+ height: 100%;
3
+ display: flex;
4
+ justify-content: space-between;
5
+ background: url(./assets/background.png) rgb(247, 248, 255);
6
+ background-size: cover;
7
+ overflow: hidden;
8
+ }
9
+
10
+ .content {
11
+ padding-top: 64px;
12
+ width: 100%;
13
+ height: 100%;
14
+ box-sizing: border-box;
15
+ // display: flex;
16
+ // justify-content: center;
17
+ }
18
+
19
+ .header {
20
+ position: fixed;
21
+ padding: 16px 32px;
22
+ width: 100%;
23
+ display: flex;
24
+ align-items: center;
25
+ box-sizing: border-box;
26
+
27
+ &-nav {
28
+ flex: 1;
29
+
30
+ img {
31
+ height: 40px;
32
+ }
33
+
34
+ a {
35
+ display: inline-block;
36
+ text-decoration: none;
37
+ color: black;
38
+
39
+ &:not(:first-of-type) {
40
+ margin-left: 40px;
41
+ }
42
+
43
+ &.active {
44
+ font-weight: bold;
45
+ }
46
+ }
47
+ }
48
+
49
+ &-opt {
50
+ flex-shrink: 0;
51
+ display: flex;
52
+ align-items: center;
53
+ }
54
+ }
frontend/React/src/App.tsx ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import style from "./App.module.less";
2
+ import Logo from "@/assets/logo.svg";
3
+ import { BrowserRouter } from "react-router-dom";
4
+ import RouterRoutes from "@/routes/routes";
5
+
6
+ function App() {
7
+ return (
8
+ <BrowserRouter>
9
+ <div className={style.app} id="app">
10
+ <div className={style.header}>
11
+ <div className={style.headerNav}>
12
+ <img src={Logo} />
13
+ </div>
14
+ </div>
15
+ <div className={style.content}>
16
+ <RouterRoutes />
17
+ </div>
18
+ </div>
19
+ </BrowserRouter>
20
+ );
21
+ }
22
+
23
+ export default App;
frontend/React/src/assets/background.png ADDED
frontend/React/src/assets/fold-icon.svg ADDED
frontend/React/src/assets/logo.svg ADDED
frontend/React/src/assets/pack-up.svg ADDED
frontend/React/src/assets/sendIcon.svg ADDED
frontend/React/src/assets/show-right-icon.png ADDED
frontend/React/src/assets/unflod-icon.svg ADDED
frontend/React/src/components/iconfont/index.tsx ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ import { createFromIconfontCN } from "@ant-design/icons";
2
+
3
+ const IconFont = createFromIconfontCN({
4
+ scriptUrl: "//at.alicdn.com/t/c/font_3858115_p8dw9q83s0h.js"
5
+ });
6
+
7
+ export default IconFont;
frontend/React/src/config/cgi.ts ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ export const mode = import.meta.env.MODE;
2
+ export const GET_SSE_DATA = 'http://127.0.0.1:8002/solve';
frontend/React/src/global.d.ts ADDED
@@ -0,0 +1 @@
 
 
1
+ declare module 'event-source-polyfill';
frontend/React/src/index.less ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body,
2
+ html,
3
+ #root {
4
+ padding: 0;
5
+ margin: 0;
6
+ width: 100%;
7
+ height: 100%;
8
+ font-family: "PingFang SC";
9
+ font-size: 14px;
10
+ line-height: 21px;
11
+ }
12
+
13
+ #global__message-container {
14
+ position: fixed;
15
+ left: 0;
16
+ right: 0;
17
+ top: 72px;
18
+ z-index: 999;
19
+ display: flex;
20
+ flex-direction: column;
21
+ justify-content: center;
22
+ align-items: center;
23
+ }
24
+
25
+ .f {
26
+ color: #6674D6;
27
+ font-family: DIN;
28
+ font-size: 12px;
29
+ font-style: normal;
30
+ font-weight: 500;
31
+ line-height: 14px;
32
+ position: relative;
33
+ top: -4px;
34
+ padding: 0 3px;
35
+
36
+ &::after {
37
+ content: '·';
38
+ position: absolute;
39
+ top: 0;
40
+ right: -2px;
41
+ color: #6674D6;
42
+ }
43
+ }
44
+
45
+ p> :nth-last-child(1).f,
46
+ li> :nth-last-child(1).f {
47
+ &::after {
48
+ content: '';
49
+ opacity: 0;
50
+ }
51
+ }
52
+
53
+ .fnn2 {
54
+ color: #6674D6;
55
+ font-family: DIN;
56
+ font-size: 14px;
57
+ font-style: normal;
58
+ font-weight: 500;
59
+ line-height: 14px;
60
+ position: relative;
61
+ top: -2px;
62
+ }
frontend/React/src/index.tsx ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from "react";
2
+ import ReactDOM from "react-dom/client";
3
+ import "./index.less";
4
+ import App from "./App";
5
+
6
+ ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
7
+ <React.StrictMode>
8
+ <App />
9
+ </React.StrictMode>,
10
+ );
frontend/React/src/pages/render/index.module.less ADDED
@@ -0,0 +1,848 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // inspired by https://www.youtube.com/watch?v=Pl1Gw14pS2I
2
+ .mainPage {
3
+ display: flex;
4
+ justify-content: flex-start;
5
+ align-items: flex-start;
6
+ padding: 0 60px 60px;
7
+ height: 100%;
8
+ overflow: hidden;
9
+ position: relative;
10
+ min-width: 1280px;
11
+ max-width: 1920px;
12
+ margin: 0 auto;
13
+
14
+ .chatContent {
15
+ position: relative;
16
+ display: flex;
17
+ justify-content: flex-start;
18
+ flex-direction: column;
19
+ flex-grow: 1;
20
+ margin-right: 40px;
21
+ height: calc(100% - 60px);
22
+ overflow-y: hidden;
23
+ padding: 32px 0;
24
+ box-sizing: border-box;
25
+
26
+ .top {
27
+ height: calc(100% - 110px);
28
+ overflow-y: auto;
29
+ margin-bottom: 40px;
30
+ }
31
+
32
+ .top::-webkit-scrollbar {
33
+ width: 6px;
34
+ }
35
+
36
+ .top::-webkit-scrollbar-track {
37
+ background-color: rgba(255, 255, 255, 0);
38
+ border-radius: 100px;
39
+ }
40
+
41
+ .top::-webkit-scrollbar-thumb {
42
+ background-color: rgba(255, 255, 255, 0);
43
+ border-radius: 100px;
44
+ }
45
+
46
+ .question {
47
+ display: flex;
48
+ justify-content: flex-end;
49
+ margin-bottom: 40px;
50
+
51
+ span {
52
+ padding: 12px 20px;
53
+ color: #121316;
54
+ font-size: 14px;
55
+ line-height: 24px;
56
+ border-radius: 8px;
57
+ background: #FFF;
58
+ max-width: 93.75%;
59
+ }
60
+ }
61
+
62
+ .end {
63
+ position: absolute;
64
+ right: 0;
65
+ background-color: #fff;
66
+ display: flex;
67
+ justify-content: center;
68
+ align-items: center;
69
+ border-left: 1px solid #D7D8DD;
70
+ padding-left: 16px;
71
+
72
+ .node {
73
+ position: relative;
74
+
75
+ &::before {
76
+ content: "";
77
+ border: 1px solid #D7D8DD;
78
+ border-top: none;
79
+ border-left: none;
80
+ width: calc(16px - 2px);
81
+ height: 0px;
82
+ position: absolute;
83
+ left: -16px;
84
+ top: 50%;
85
+ // transform: translateY(-50%);
86
+ }
87
+
88
+ article {
89
+ padding: 8px 16px;
90
+ border-radius: 8px;
91
+ border: 1px solid transparent;
92
+ color: #4082FE;
93
+ text-align: center;
94
+ font-size: 14px;
95
+ line-height: 24px;
96
+ box-sizing: border-box;
97
+ background: rgba(232, 233, 249);
98
+ color: #2126C0;
99
+ }
100
+ }
101
+ }
102
+
103
+ .answer {
104
+ border-radius: 8px;
105
+ background: rgba(33, 38, 192, 0.10);
106
+ padding: 12px;
107
+
108
+ .inner {
109
+ width: 100%;
110
+ background-color: #fff;
111
+ border-radius: 4px;
112
+ padding: 8px;
113
+ box-sizing: border-box;
114
+ transition: all 0.5s ease;
115
+ margin-bottom: 18px;
116
+
117
+ .mapArea {
118
+ width: 100%;
119
+ overflow-x: auto;
120
+ overflow-y: hidden;
121
+
122
+ &::-webkit-scrollbar {
123
+ height: 6px;
124
+ }
125
+
126
+ &::-webkit-scrollbar-track {
127
+ background-color: rgba(255, 255, 255, 0);
128
+ border-radius: 10px;
129
+ }
130
+
131
+ &::-webkit-scrollbar-thumb {
132
+ background-color: #d7d8dd;
133
+ border-radius: 100px;
134
+ }
135
+ }
136
+
137
+ }
138
+
139
+
140
+ .response {
141
+ color: #121316;
142
+ font-size: 14px;
143
+ line-height: 24px;
144
+ padding: 18px 42px;
145
+
146
+ h3 {
147
+ font-size: 24px;
148
+ font-weight: 600;
149
+ line-height: 36px;
150
+ margin: 0 0 16px 0;
151
+ }
152
+
153
+ h4 {
154
+ font-size: 20px;
155
+ font-weight: 600;
156
+ line-height: 30px;
157
+ margin: 0 0 8px 0;
158
+ }
159
+
160
+ p {
161
+ color: rgba(18, 19, 22, 0.80);
162
+ font-size: 16px;
163
+ font-weight: 400;
164
+ line-height: 28px;
165
+ margin: 0 0 16px 0;
166
+ }
167
+
168
+ ul {
169
+ margin-bottom: 8px;
170
+ padding-left: 22px;
171
+ }
172
+
173
+ li {
174
+ color: rgba(18, 19, 22, 0.80);
175
+ font-size: 16px;
176
+ font-weight: 400;
177
+ line-height: 28px;
178
+
179
+ p {
180
+ margin-bottom: 4px;
181
+ }
182
+ }
183
+ }
184
+ }
185
+
186
+ .sendArea {
187
+ display: flex;
188
+ width: 100%;
189
+ box-sizing: border-box;
190
+ padding: 10px 12px 10px 24px;
191
+ justify-content: space-between;
192
+ align-items: center;
193
+ border-radius: 8px;
194
+ border: 2px solid var(--fill-5, #464A53);
195
+ background: #FFF;
196
+ position: relative;
197
+
198
+ :global {
199
+ .ant-input {
200
+ &:focus {
201
+ box-shadow: none !important;
202
+ outline: 0 !important;
203
+ }
204
+ }
205
+ }
206
+
207
+ input {
208
+ height: 36px;
209
+ line-height: 36px;
210
+ flex-grow: 1;
211
+ border: 0;
212
+ outline: 0;
213
+
214
+ &:focus {
215
+ border: 0;
216
+ outline: 0;
217
+ }
218
+ }
219
+
220
+ button {
221
+ display: flex;
222
+ justify-content: flex-start;
223
+ align-items: center;
224
+ border: 0;
225
+ background-color: #fff;
226
+ cursor: pointer;
227
+ padding: 8px;
228
+ width: 65px;
229
+ flex-shrink: 0;
230
+
231
+ img {
232
+ margin-right: 4px;
233
+ }
234
+ }
235
+ }
236
+
237
+ .notice {
238
+ color: #12131659;
239
+ padding-top: 8px;
240
+ text-align: center;
241
+ font-weight: 400;
242
+
243
+ a {
244
+ text-decoration: none;
245
+ color: #444;
246
+ display: inline-flex;
247
+ align-items: center;
248
+
249
+ span {
250
+ font-size: 18px;
251
+ }
252
+ }
253
+ }
254
+ }
255
+
256
+ .progressContent {
257
+ width: 44.44%;
258
+ flex-shrink: 0;
259
+ box-sizing: border-box;
260
+ padding: 24px;
261
+ border-radius: 8px;
262
+ border: rgba(33, 38, 192, 0.10);
263
+ background: rgba(255, 255, 255, 0.80);
264
+ height: calc(100% - 60px);
265
+ overflow-y: auto;
266
+ position: relative;
267
+
268
+ &::-webkit-scrollbar {
269
+ width: 6px;
270
+ }
271
+
272
+ &::-webkit-scrollbar-track {
273
+ background-color: rgba(255, 255, 255, 0);
274
+ border-radius: 100px;
275
+ }
276
+
277
+ &::-webkit-scrollbar-thumb {
278
+ background-color: rgba(255, 255, 255, 0);
279
+ border-radius: 100px;
280
+ }
281
+
282
+ .toggleIcon {
283
+ position: absolute;
284
+ right: 24px;
285
+ top: 28px;
286
+ cursor: pointer;
287
+ }
288
+
289
+ .titleNode {
290
+ color: #121316;
291
+ font-size: 24px;
292
+ font-weight: 600;
293
+ line-height: 36px;
294
+ margin-bottom: 24px;
295
+ }
296
+
297
+ .conclusion {
298
+ padding-top: 8px;
299
+ color: #121316;
300
+ font-size: 14px;
301
+ line-height: 24px;
302
+
303
+ ul {
304
+ padding-left: 24px;
305
+ }
306
+ }
307
+
308
+ .steps {
309
+ .title {
310
+ color: var(--100-text-5, #121316);
311
+ font-size: 20px;
312
+ font-weight: 600;
313
+ line-height: 30px;
314
+ display: flex;
315
+ justify-content: flex-start;
316
+ align-items: center;
317
+ position: relative;
318
+
319
+ .open {
320
+ position: absolute;
321
+ right: 0;
322
+ font-size: 20px;
323
+ font-weight: normal;
324
+
325
+ span {
326
+ color: #121316;
327
+ opacity: 0.6;
328
+ }
329
+ }
330
+
331
+ i {
332
+ width: 12px;
333
+ height: 12px;
334
+ border-radius: 50%;
335
+ background-color: #2126C0;
336
+ margin-right: 8px;
337
+ }
338
+ }
339
+
340
+ &.thinking,
341
+ &.select {
342
+ margin-bottom: 24px;
343
+ }
344
+
345
+ &.select {
346
+ .searchList {
347
+ margin-top: 0 !important;
348
+ border-radius: 8px;
349
+ background: var(--fill-2, #F4F5F9);
350
+ padding: 8px;
351
+ }
352
+ }
353
+
354
+ .con {
355
+ margin-left: 5px;
356
+ padding-top: 8px;
357
+ padding-left: 15px;
358
+ border-left: 1px solid rgba(33, 38, 192, 0.20);
359
+ height: auto;
360
+
361
+ &.collapsed {
362
+ overflow: hidden;
363
+ height: 0;
364
+ padding-top: 0;
365
+ transition: all 1s;
366
+ }
367
+
368
+ .subTitle {
369
+ color: var(--100-text-5, #121316);
370
+ font-size: 14px;
371
+ font-weight: 600;
372
+ line-height: 24px;
373
+ margin-bottom: 4px;
374
+
375
+ span {
376
+ margin-right: 4px;
377
+ }
378
+ }
379
+
380
+ .query,
381
+ >.searchList {
382
+ margin-top: 24px;
383
+ // margin-bottom: 24px;
384
+ }
385
+
386
+ .query {
387
+ &-Item {
388
+ display: inline-flex;
389
+ padding: 4px 8px;
390
+ margin-right: 4px;
391
+ margin-bottom: 4px;
392
+ border-radius: 4px;
393
+ border: 1px solid #EBECF0;
394
+ color: rgba(18, 19, 22, 0.80);
395
+ font-size: 14px;
396
+ line-height: 24px;
397
+ height: 32px;
398
+ box-sizing: border-box;
399
+ overflow: hidden;
400
+ // animation: fadeIn linear 2s;
401
+ }
402
+ }
403
+
404
+ .searchList {
405
+ .thought {
406
+ color: rgba(18, 19, 22, 0.80);
407
+ font-size: 14px;
408
+ line-height: 24px;
409
+ margin-bottom: 16px;
410
+ }
411
+
412
+ .scrollCon {
413
+ padding-right: 6px;
414
+ max-height: 300px;
415
+ overflow-y: auto;
416
+ position: relative;
417
+ }
418
+
419
+ .scrollCon::-webkit-scrollbar {
420
+ width: 6px;
421
+ }
422
+
423
+ .scrollCon::-webkit-scrollbar-track {
424
+ background-color: rgba(255, 255, 255, 0);
425
+ border-radius: 100px;
426
+ }
427
+
428
+ .scrollCon::-webkit-scrollbar-thumb {
429
+ background-color: #d7d8dd;
430
+ border-radius: 100px;
431
+ }
432
+
433
+ .inner {
434
+ width: 100%;
435
+ border-radius: 8px;
436
+ background: var(--fill-2, #F4F5F9);
437
+ transition: all 0.5s ease;
438
+ box-sizing: border-box;
439
+ padding: 8px;
440
+ }
441
+
442
+ .searchItem {
443
+ border-radius: 8px;
444
+ background: var(---fill-0, #FFF);
445
+ margin-bottom: 6px;
446
+ padding: 4px 8px;
447
+ transition: all 0.5s ease-in-out;
448
+
449
+ &.highLight {
450
+ border: 1px solid var(---Success-6, #00B365);
451
+ background: linear-gradient(0deg, rgba(218, 242, 228, 0.40) 0%, rgba(218, 242, 228, 0.40) 100%), #FFF;
452
+ }
453
+
454
+ p {
455
+ white-space: nowrap;
456
+ max-width: 95%;
457
+ overflow: hidden;
458
+ text-overflow: ellipsis;
459
+ margin: 0;
460
+ }
461
+
462
+ p.summ {
463
+ color: rgba(18, 19, 22, 0.80);
464
+ font-size: 13px;
465
+ line-height: 20px;
466
+ margin-bottom: 2px;
467
+ }
468
+
469
+ p.url {
470
+ color: var(--60-text-3, rgba(18, 19, 22, 0.60));
471
+ font-size: 12px;
472
+ line-height: 18px;
473
+ padding-left: 20px;
474
+ }
475
+ }
476
+ }
477
+
478
+
479
+ }
480
+ }
481
+ }
482
+ }
483
+
484
+ pre {
485
+ margin: 0;
486
+ padding-top: 8px;
487
+ color: #121316;
488
+ font-size: 14px;
489
+ line-height: 24px;
490
+ font-family: 'PingFang SC', 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;
491
+ white-space: wrap;
492
+ }
493
+
494
+ ul {
495
+ margin: 0;
496
+ padding: 0;
497
+ }
498
+
499
+ .draft {
500
+ width: 100%;
501
+ white-space: wrap;
502
+ // display: flex;
503
+ // justify-content: flex-start;
504
+ // align-items: flex-start;
505
+ position: relative;
506
+
507
+ .loading,
508
+ .loading>div {
509
+ position: relative;
510
+ box-sizing: border-box;
511
+ }
512
+
513
+ .loading {
514
+ display: flex;
515
+ justify-content: center;
516
+ align-items: center;
517
+ font-size: 0;
518
+ color: #fff;
519
+ background-color: #f90;
520
+ width: 20px;
521
+ height: 20px;
522
+ border-radius: 50%;
523
+ margin-right: 3px;
524
+ flex-shrink: 0;
525
+ position: absolute;
526
+ top: 0;
527
+ left: 0;
528
+ }
529
+
530
+ .loading>div {
531
+ display: inline-block;
532
+ float: none;
533
+ background-color: currentColor;
534
+ border: 0 solid currentColor;
535
+ }
536
+
537
+ .loading>div:nth-child(1) {
538
+ animation-delay: -200ms;
539
+ }
540
+
541
+ .loading>div:nth-child(2) {
542
+ animation-delay: -100ms;
543
+ }
544
+
545
+ .loading>div:nth-child(3) {
546
+ animation-delay: 0ms;
547
+ }
548
+
549
+ .loading>div {
550
+ width: 3px;
551
+ height: 3px;
552
+ margin: 2px 1px;
553
+ border-radius: 100%;
554
+ animation: ball-pulse 1s ease infinite;
555
+ }
556
+ }
557
+
558
+ .mindmap {
559
+ position: relative;
560
+
561
+ article {
562
+ padding: 6px 16px;
563
+ border-radius: 8px;
564
+ height: 38px;
565
+ border: 1px solid transparent;
566
+ background: #FFF;
567
+ color: #121316;
568
+ text-align: center;
569
+ font-size: 14px;
570
+ line-height: 24px;
571
+ position: relative;
572
+ box-sizing: border-box;
573
+
574
+ &.loading {
575
+ line-height: 20px;
576
+ border-radius: 8px;
577
+ overflow: hidden;
578
+ border: 1px solid transparent;
579
+ padding: 4px;
580
+
581
+ span {
582
+ color: #2126C0;
583
+ background-color: #fff;
584
+ border-radius: 4px;
585
+ line-height: 24px;
586
+ padding: 2px 12px;
587
+ }
588
+
589
+ .looping {
590
+ --border-width: 4px;
591
+ --follow-panel-linear-border: linear-gradient(91deg,
592
+ #5551FF 0.58%,
593
+ #FF87DE 100.36%);
594
+
595
+ position: absolute;
596
+ top: 0;
597
+ left: 0;
598
+ width: calc(100% + var(--border-width) * 2 - 8px);
599
+ height: calc(100%);
600
+ background: var(--follow-panel-linear-border);
601
+ background-size: 300% 300%;
602
+ background-position: 0 50%;
603
+ animation: moveGradient 4s alternate infinite;
604
+ }
605
+ }
606
+
607
+ &.disabled {
608
+ border-radius: 8px;
609
+ border: 1px solid #D7D8DD;
610
+ color: rgba(18, 19, 22, 0.35);
611
+ }
612
+
613
+ &.finished {
614
+ // cursor: pointer;
615
+ border: 1px solid #2126C0;
616
+
617
+ .finishDot {
618
+ position: absolute;
619
+ top: 6px;
620
+ right: 6px;
621
+ width: 6px;
622
+ height: 6px;
623
+ background-color: #C9C0FE;
624
+ border-radius: 50%;
625
+ }
626
+ }
627
+
628
+ &.init {
629
+ border: 1px solid transparent;
630
+ cursor: auto;
631
+ }
632
+
633
+ span {
634
+ display: block;
635
+ white-space: nowrap;
636
+ max-width: 160px;
637
+ overflow: hidden;
638
+ text-overflow: ellipsis;
639
+ position: relative;
640
+ z-index: 20;
641
+ }
642
+
643
+ span.status {
644
+ color: #4082FE;
645
+ }
646
+
647
+ }
648
+
649
+ // 第一个article,起始节点
650
+ >li {
651
+ >article {
652
+ border-radius: 8px;
653
+ background: rgba(33, 38, 192, 0.10);
654
+ color: #2126C0;
655
+ }
656
+ }
657
+
658
+ li {
659
+ list-style: none;
660
+ display: flex;
661
+ align-items: center;
662
+ box-sizing: border-box;
663
+ margin: 16px;
664
+ line-height: 1;
665
+ position: relative;
666
+
667
+ &>ul.onlyone {
668
+ &:before {
669
+ opacity: 0;
670
+ }
671
+
672
+ >li {
673
+ margin-left: 0px;
674
+ }
675
+
676
+ &>li:after {
677
+ opacity: 0;
678
+ }
679
+
680
+ &>li:before {
681
+ // left: 0;
682
+ }
683
+ }
684
+
685
+ &>ul:before {
686
+ content: "";
687
+ border: 1px solid #D7D8DD;
688
+ border-top: none;
689
+ border-left: none;
690
+ width: calc(16px - 2px);
691
+ height: 0px;
692
+ position: absolute;
693
+ left: 0;
694
+ top: 50%;
695
+ // transform: translateY(-50%);
696
+ }
697
+
698
+ &:before {
699
+ content: "";
700
+ border: 1px solid #D7D8DD;
701
+ border-top: none;
702
+ border-left: none;
703
+ width: 16px;
704
+ height: 0px;
705
+ position: absolute;
706
+ left: calc(-16px - 1px);
707
+ }
708
+
709
+ &:after {
710
+ content: "";
711
+ border: 1px solid #D7D8DD;
712
+ border-top: none;
713
+ border-left: none;
714
+ width: 0px;
715
+ height: calc(100% / 2 + 33px);
716
+ position: absolute;
717
+ left: calc(-16px - 2px);
718
+ }
719
+
720
+ &:first-of-type:after {
721
+ top: 50%;
722
+ }
723
+
724
+ &:last-of-type:after {
725
+ bottom: 50%;
726
+ }
727
+
728
+ ul {
729
+ padding: 0 0 0 16px;
730
+ position: relative;
731
+ }
732
+ }
733
+
734
+ &>li {
735
+
736
+ &:after,
737
+ &:before {
738
+ display: none;
739
+ }
740
+ }
741
+
742
+ .endLine {
743
+ border-bottom: 1px solid #D7D8DD;
744
+ width: 3000px;
745
+ transition: width 1s ease-in-out;
746
+ }
747
+ }
748
+
749
+ .showRight {
750
+ position: fixed;
751
+ top: 80px;
752
+ right: -10px;
753
+ width: 42px;
754
+ cursor: pointer;
755
+
756
+ img {
757
+ width: 100%;
758
+ }
759
+ }
760
+
761
+ @keyframes ball-pulse {
762
+
763
+ 0%,
764
+ 60%,
765
+ 100% {
766
+ opacity: 1;
767
+ transform: scale(1);
768
+ }
769
+
770
+ 30% {
771
+ opacity: 0.1;
772
+ transform: scale(0.01);
773
+ }
774
+ }
775
+
776
+ @keyframes moveGradient {
777
+ 50% {
778
+ background-position: 100% 50%;
779
+ }
780
+ }
781
+
782
+ @keyframes fadeIn {
783
+ 0% {
784
+ width: 0;
785
+ opacity: 0;
786
+ }
787
+
788
+ 100% {
789
+ width: auto;
790
+ opacity: 1;
791
+ }
792
+ }
793
+
794
+ @keyframes unfold {
795
+ 0% {
796
+ height: auto;
797
+ }
798
+
799
+ 100% {
800
+ height: 0;
801
+ }
802
+ }
803
+
804
+
805
+ .loading99 {
806
+ margin: 20px;
807
+ position: relative;
808
+ width: 1px;
809
+ height: 1px;
810
+ }
811
+
812
+ .loading99:before,
813
+ .loading99:after {
814
+ position: absolute;
815
+ display: inline-block;
816
+ width: 15px;
817
+ height: 15px;
818
+ content: "";
819
+ border-radius: 100%;
820
+ background-color: #5551FF;
821
+ }
822
+
823
+ .loading99:before {
824
+ left: -15px;
825
+ animation: ball-pulse infinite 0.75s -0.4s cubic-bezier(0.2, 0.68, 0.18, 1.08);
826
+ }
827
+
828
+ .loading99:after {
829
+ right: -15px;
830
+ animation: ball-pulse infinite 0.75s cubic-bezier(0.2, 0.68, 0.18, 1.08);
831
+ }
832
+
833
+ @keyframes ball-pulse {
834
+ 0% {
835
+ transform: scale(1);
836
+ opacity: 1;
837
+ }
838
+
839
+ 50% {
840
+ transform: scale(0.1);
841
+ opacity: 0.6;
842
+ }
843
+
844
+ 100% {
845
+ transform: scale(1);
846
+ opacity: 1;
847
+ }
848
+ }
frontend/React/src/pages/render/index.tsx ADDED
@@ -0,0 +1,681 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import styles from './index.module.less';
2
+ import { useEffect, useState, useRef, Children } from 'react';
3
+ import MindMapItem from './mindMapItem';
4
+ import PackIcon from '@/assets/pack-up.svg';
5
+ import SendIcon from '@/assets/sendIcon.svg';
6
+ import { Tooltip, Input, message } from 'antd';
7
+ import IconFont from '@/components/iconfont';
8
+ import ReactMarkdown from "react-markdown";
9
+ import ShowRightIcon from "@/assets/show-right-icon.png";
10
+ import rehypeRaw from 'rehype-raw';
11
+ import classNames from 'classnames';
12
+ import { fetchEventSource } from '@microsoft/fetch-event-source';
13
+ import { GET_SSE_DATA } from '@/config/cgi';
14
+ import { replaceStr } from '@/utils/tools';
15
+
16
+ const RenderTest = () => {
17
+ let eventSource: any = null;
18
+ let sseTimer: any = useRef(null);
19
+ const [isWaiting, setIsWaiting] = useState(false);
20
+ const [question, setQuestion] = useState("");
21
+ const [stashQuestion, setStashQuestion] = useState("");
22
+ const [isEnd, setIsEnd] = useState(false);
23
+ const [showEndNode, setShowEndNode] = useState(false);
24
+ // 一组节点的渲染草稿
25
+ const [draft, setDraft] = useState('');
26
+ // 一轮完整对话结束
27
+ const [chatIsOver, setChatIsOver] = useState(true);
28
+ // 一组节点的思考草稿是不是打印结束
29
+ const [draftEnd, setDraftEnd] = useState(false);
30
+
31
+ const [progress1, setProgress1] = useState('');
32
+ const [progress2, setProgress2] = useState('');
33
+ const [progressEnd, setProgressEnd] = useState(false);
34
+
35
+ const [conclusion, setConclusion] = useState('');
36
+ const [stashConclusion, setstashConclusion] = useState('');
37
+
38
+ const [query, setQuery] = useState([]);
39
+ const [searchList, setSearchList] = useState([]);
40
+ // 整体的渲染树
41
+ const [renderData, setRenderData] = useState<any[]>([]);
42
+ const [currentNode, setCurrentNode] = useState<any>(null);
43
+ // 渲染minddata里的第几个item
44
+ const [renderIndex, setRenderIndex] = useState<number>(0);
45
+ const [response, setResponse] = useState("");
46
+ const [currentStep, setCurrentStep] = useState(0);
47
+ // steps展开收起的信息
48
+ const [collapseInfo, setCollapseInfo] = useState([true, true]);
49
+ const [mapWidth, setMapWidth] = useState(0);
50
+ // 是否展示右侧内容
51
+ const [showRight, setShowRight] = useState(true);
52
+
53
+ const [currentNodeRendering, setCurrentNodeRendering] = useState(false);
54
+ const [selectedIds, setSelectedIds] = useState([]);
55
+ const [nodeName, setNodeName] = useState('');
56
+ const hasHighlight = useRef(false);
57
+ const conclusionRender = useRef(false);
58
+ const nodeDraftRender = useRef(false);
59
+ const [obj, setObj] = useState<any>(null);
60
+ const [nodeOutputEnd, setNodeEnd] = useState(false);
61
+ const [adjList, setAdjList] = useState([]);
62
+
63
+ const TEXT_INTERVAL = 20;
64
+ const SEARCHLIST_INTERVAL = 80;
65
+
66
+
67
+ const toggleRight = () => {
68
+ setShowRight(!showRight);
69
+ };
70
+
71
+ const findAndUpdateStatus = (nodes: any[], targetNode: any) => {
72
+ return nodes.map((node) => {
73
+ if (node.state === 1 && node.id !== 0) {
74
+ return { ...node, state: 3 };
75
+ }
76
+
77
+ if (node.name === targetNode) {
78
+ return { ...node, state: 1 };
79
+ }
80
+
81
+ if (node.children) {
82
+ // 递归地在子节点中查找
83
+ node.children = findAndUpdateStatus(node.children, targetNode);
84
+ }
85
+
86
+ return node;
87
+ });
88
+ }
89
+
90
+ const generateEndStyle = () => {
91
+ // 获取所有class为endline的div元素
92
+ const endlineDivs = document.getElementsByClassName('endline');
93
+ const mindMap = document.getElementById("mindMap");
94
+ // 确保至少有两个元素
95
+ if (endlineDivs.length >= 2 && mindMap) {
96
+ // 获取第一个和最后一个元素的边界框(bounding rectangle)
97
+ const firstRect = endlineDivs[0].getBoundingClientRect();
98
+ const lastRect = endlineDivs[endlineDivs.length - 1].getBoundingClientRect();
99
+ const mindMapRect = mindMap?.getBoundingClientRect();
100
+ // 计算y值的差值
101
+ const yDiff = lastRect.top - firstRect.top;
102
+ // const top = firstRect.top - mindMapRect.top;
103
+ // 如果需要包含元素的完整高度(不仅仅是顶部位置),可以加上元素的高度
104
+ // const yDiffWithHeight = yDiff + (lastRect.height - firstRect.height);
105
+ return {
106
+ top: firstRect.top - mindMapRect.top,
107
+ height: yDiff + 1
108
+ };
109
+ } else {
110
+ return {
111
+ top: '50%',
112
+ height: 0
113
+ };
114
+ }
115
+ };
116
+
117
+ const generateWidth = () => {
118
+ const articles = document.querySelectorAll('article');
119
+ // 确保至少有两个元素
120
+ if (articles?.length) {
121
+ let maxRight = 0;
122
+ articles.forEach((item, index) => {
123
+ if (item.getBoundingClientRect().right > maxRight) {
124
+ maxRight = item.getBoundingClientRect().right;
125
+ }
126
+ })
127
+ const firstArticle = articles[0].getBoundingClientRect();
128
+ if (maxRight - firstArticle.left + 200 > mapWidth) {
129
+ return maxRight - firstArticle.left + 200
130
+ } else {
131
+ return mapWidth;
132
+ }
133
+ } else {
134
+ return 100;
135
+ }
136
+ };
137
+
138
+ // 逐字渲染
139
+ const renderDraft = (str: string, type: string, endCallback: () => void) => {
140
+ // 已经输出的字符数量
141
+ let outputIndex = 0;
142
+
143
+ // 输出字符的函数
144
+ const outputText = () => {
145
+ // 给出高亮后draft输出的结束标志
146
+ if (type === 'stepDraft-1' && outputIndex + 3 > str?.length) {
147
+ nodeDraftRender.current = true;
148
+ }
149
+ // 如果还有字符未输出
150
+ if (outputIndex < str?.length) {
151
+ // 获取接下来要输出的1个字符(或剩余字符,如果不足3个)
152
+ let chunk = str.slice(outputIndex, Math.min(outputIndex + 10, str.length));
153
+ // 更新已输出字符的索引
154
+ outputIndex += chunk.length;
155
+ if (type === 'thought') {
156
+ setDraft(str.slice(0, outputIndex));
157
+ } else if (type === "stepDraft-0") {
158
+ setProgress1(str.slice(0, outputIndex));
159
+ } else if (type === "stepDraft-1") {
160
+ setProgress2(str.slice(0, outputIndex));
161
+ } else if (type === "conclusion") {
162
+ setConclusion(str.slice(0, outputIndex));
163
+ } else if (type === "response") {
164
+ setResponse(str.slice(0, outputIndex));
165
+ }
166
+ } else {
167
+ // 如果没有更多字符需要输出,则清除定时器
168
+ clearInterval(intervalId);
169
+ endCallback && endCallback()
170
+ }
171
+ }
172
+
173
+ // 设定定时器ID
174
+ let intervalId = setInterval(outputText, TEXT_INTERVAL);
175
+ }
176
+
177
+ // 渲染搜索结果renderSearchList
178
+ const renderSearchList = () => {
179
+ let outputIndex = 0;
180
+ const content = JSON.parse(currentNode.actions[currentStep].result[0].content);
181
+
182
+ const arr: any = Object.keys(content).map(item => {
183
+ return { id: item, ...content[item] };
184
+ });
185
+ const len = Object.keys(content).length;
186
+ const outputText = () => {
187
+ outputIndex++;
188
+ if (outputIndex < len + 1) {
189
+ setSearchList(arr.slice(0, outputIndex));
190
+ } else {
191
+ clearInterval(intervalId);
192
+ }
193
+ };
194
+ // 设定定时器ID
195
+ let intervalId = setInterval(outputText, SEARCHLIST_INTERVAL);
196
+ };
197
+
198
+ // 高亮searchList
199
+ const highLightSearchList = (ids: any) => {
200
+ setSelectedIds([]);
201
+ const newStep = currentStep + 1;
202
+ setCurrentStep(newStep);
203
+ const highlightArr: any = [...searchList];
204
+ highlightArr.forEach((item: any) => {
205
+ if (ids.includes(Number(item.id))) {
206
+ item.highLight = true;
207
+ }
208
+ })
209
+ highlightArr.sort((item1: any, item2: any) => {
210
+ if (item1.highLight === item2.highLight) {
211
+ return 0;
212
+ }
213
+ // 如果item1是highlight,放在前面
214
+ if (item1.highLight) {
215
+ return -1;
216
+ }
217
+ // 如果item2是highlight,放在后面
218
+ return 1;
219
+ })
220
+ setSearchList(highlightArr);
221
+ renderDraft(currentNode.actions[1].thought, `stepDraft-1`, () => { });
222
+ hasHighlight.current = true; // 标记为高亮已执行
223
+ };
224
+
225
+ // 渲染结论
226
+ const renderConclusion = () => {
227
+ const res = window.localStorage.getItem('nodeRes') || '';
228
+ const replaced = replaceStr(res);
229
+ // setTimeout(() => { setCollapseInfo([false, false]); }, 2000);
230
+ setCollapseInfo([false, false]);
231
+ setConclusion(replaced);
232
+ setstashConclusion(res);
233
+ // 给出conclusion结束的条件
234
+ if (stashConclusion.length + 5 > res.length) {
235
+ conclusionRender.current = true;
236
+ setProgressEnd(true);
237
+ }
238
+ };
239
+
240
+ // 渲染query
241
+ const renderQuery = (endCallback: () => void) => {
242
+ const queries = currentNode.actions[currentStep]?.args?.query;
243
+ setQuery(queries);
244
+ endCallback && endCallback();
245
+ };
246
+
247
+ const renderSteps = () => {
248
+ setCurrentNodeRendering(true);
249
+ const queryEndCallback = () => {
250
+ if (currentNode.actions[currentStep].result[0].content) {
251
+ if (currentNode.actions[currentStep].type === "BingBrowser.search" || currentNode.actions[currentStep].type === "BingBrowser") {
252
+ renderSearchList();
253
+ }
254
+ }
255
+ };
256
+ const thoughtEndCallback = () => {
257
+ if (currentNode.actions[currentStep]?.args?.query?.length) {
258
+ renderQuery(queryEndCallback);
259
+ } else {
260
+ queryEndCallback();
261
+ }
262
+ };
263
+ if (currentNode.actions[currentStep].thought) {
264
+ renderDraft(currentNode.actions[currentStep].thought, `stepDraft-${currentStep}`, thoughtEndCallback);
265
+ }
266
+ }
267
+
268
+ // 展开收起
269
+ const toggleCard = (index: number) => {
270
+ const arr = [...collapseInfo];
271
+ arr[index] = !arr[index];
272
+ setCollapseInfo(arr);
273
+ };
274
+
275
+ // 渲染过程中保持渲染文字可见
276
+ const keepScrollTop = (divA: any, divB: any) => {
277
+ // 获取 divB 的当前高度
278
+ const bHeight = divB.offsetHeight;
279
+
280
+ // 检查 divA 是否需要滚动(即 divB 的高度是否大于 divA 的可视高度)
281
+ if (bHeight > divA.offsetHeight) {
282
+ // 滚动到 divB 的底部在 divA 的可视区域内
283
+ divA.scrollTop = bHeight - divA.offsetHeight;
284
+ }
285
+ };
286
+
287
+ useEffect(() => {
288
+ setRenderData([
289
+ {
290
+ id: 0,
291
+ state: 3,
292
+ name: '原始问题',
293
+ children: adjList
294
+ }
295
+ ])
296
+ }, [JSON.stringify(adjList)]);
297
+
298
+ useEffect(() => {
299
+ console.log('render data changed-----', renderData);
300
+ }, [renderData]);
301
+
302
+ useEffect(() => {
303
+ if (currentStep === 1) {
304
+ setCollapseInfo([false, true]);
305
+ }
306
+ }, [currentStep]);
307
+
308
+ useEffect(() => {
309
+ if (nodeOutputEnd && !localStorage.getItem('nodeRes')) {
310
+ // 如果节点输出结束了,但是response还没有结束,认为节点渲染已结束
311
+ conclusionRender.current = true;
312
+ setProgressEnd(true);
313
+ return;
314
+ }
315
+ if (nodeDraftRender.current && localStorage.getItem('nodeRes')) {
316
+ renderConclusion();
317
+ }
318
+ }, [localStorage.getItem('nodeRes'), nodeDraftRender.current, nodeOutputEnd]);
319
+
320
+ useEffect(() => {
321
+ if (obj?.response?.nodes[obj.current_node]?.detail?.state !== 1) {
322
+ setIsWaiting(true);
323
+ }
324
+ if (obj?.response?.nodes?.[obj.current_node].detail?.state === 0 && currentNode?.current_node === obj.current_node) {
325
+ console.log('node render end-----', obj);
326
+ setNodeEnd(true);
327
+ }
328
+
329
+ if (obj?.current_node && obj?.response?.state === 3) {
330
+ // 当node节点的数据可以开始渲染时,给currentnode赋值
331
+ // update conclusion
332
+ if (obj.response.nodes[obj.current_node]?.detail?.actions?.length === 2 &&
333
+ obj.response.nodes[obj.current_node]?.detail?.state === 1 &&
334
+ obj.response.nodes[obj.current_node]?.detail.response) {
335
+ window.localStorage.setItem('nodeRes', obj.response.nodes[obj.current_node]?.detail.response);
336
+ }
337
+ if (obj.current_node &&
338
+ (obj.response.nodes[obj.current_node]?.detail?.state === 1) &&
339
+ obj.response.nodes[obj.current_node]?.detail?.actions?.length &&
340
+ currentStep === 0 &&
341
+ currentNode?.current_node !== obj?.current_node
342
+ ) {
343
+ // 更新当前渲染节点
344
+ console.log('update current node----');
345
+ setIsWaiting(false);
346
+ setCurrentNode({ ...obj.response.nodes[obj.current_node]?.detail, current_node: obj.current_node });
347
+ }
348
+
349
+ // 设置highlight
350
+ if (!selectedIds.length &&
351
+ obj.response.nodes[obj.current_node]?.detail?.actions?.[1]?.type === 'BingBrowser.select' &&
352
+ (obj.response.nodes[obj.current_node]?.detail?.state === 1)) {
353
+ setSelectedIds(obj.response.nodes[obj.current_node]?.detail?.actions?.[1]?.args?.select_ids || []);
354
+ setCurrentNode({ ...obj.response.nodes[obj.current_node]?.detail, current_node: obj.current_node });
355
+ }
356
+ }
357
+ }, [obj]);
358
+
359
+ useEffect(() => {
360
+ // 输出思考过程
361
+ if (!currentNode || currentNodeRendering) { return; }
362
+ renderSteps();
363
+ }, [currentNode, currentNodeRendering, selectedIds]);
364
+
365
+ useEffect(() => {
366
+ if (!hasHighlight.current && selectedIds.length && currentNode?.actions.length === 2) {
367
+ // 渲染高亮的search信息
368
+ highLightSearchList(selectedIds);
369
+ }
370
+ }, [selectedIds, currentNode]);
371
+
372
+ useEffect(() => {
373
+ // 当前节点渲染结束
374
+ if (nodeName && nodeName !== currentNode?.current_node && progressEnd && !isEnd) {
375
+ resetNode(nodeName);
376
+ setMapWidth(generateWidth());
377
+ }
378
+ }, [nodeName, currentNode, progressEnd, isEnd]);
379
+
380
+ let responseTimer: any = useRef(null);
381
+ useEffect(() => {
382
+ if (isEnd) {
383
+ responseTimer.current = setInterval(() => {
384
+ const divA = document.getElementById('chatArea') as HTMLDivElement;
385
+ const divB = document.getElementById('messageWindowId') as HTMLDivElement;
386
+ keepScrollTop(divA, divB);
387
+ if (chatIsOver) {
388
+ clearInterval(responseTimer.current);
389
+ }
390
+ }, 500);
391
+ setTimeout(() => {
392
+ setShowEndNode(true);
393
+ }, 300);
394
+ } else if (responseTimer.current) {
395
+ // 如果 isEnd 变为 false,清除定时器
396
+ clearInterval(responseTimer.current);
397
+ responseTimer.current = null;
398
+ }
399
+
400
+ // 返回清理函数,确保组件卸载时清除定时器
401
+ return () => {
402
+ if (responseTimer.current) {
403
+ clearInterval(responseTimer.current);
404
+ responseTimer.current = null;
405
+ }
406
+ };
407
+ }, [isEnd, chatIsOver]);
408
+
409
+ useEffect(() => {
410
+ setRenderData([]);
411
+ setResponse('');
412
+ setDraft('');
413
+ setIsEnd(false);
414
+ setShowRight(true);
415
+ window.localStorage.setItem('nodeRes', '');
416
+ window.localStorage.setItem('finishedNodes', '');
417
+ }, [question]);
418
+
419
+ const resetNode = (targetNode: string) => {
420
+ if (targetNode === 'response') return; // 如果开始response了,所有节点都渲染完了,不需要reset
421
+ // 渲染下一个节点前,初始化状态
422
+ const newData = findAndUpdateStatus(renderData, targetNode);
423
+ console.log('reset node------', targetNode, renderData);
424
+ setCurrentStep(0);
425
+ setQuery([]);
426
+ setSearchList([]);
427
+ setConclusion('');
428
+ setCollapseInfo([true, true]);
429
+ setProgress1('');
430
+ setProgress2('');
431
+ setProgressEnd(false);
432
+ setCurrentNode(null);
433
+ setCurrentNodeRendering(false);
434
+ setSelectedIds([]);
435
+ setNodeEnd(false);
436
+ hasHighlight.current = false;
437
+ nodeDraftRender.current = false;
438
+ conclusionRender.current = false;
439
+ window.localStorage.setItem('nodeRes', '');
440
+ };
441
+
442
+ const formatData = (data: any) => {
443
+ try {
444
+ setIsWaiting(false);
445
+ const obj = JSON.parse(data);
446
+ if (!obj.current_node && obj.response.state === 0) {
447
+ console.log('chat is over end-------');
448
+ setChatIsOver(true);
449
+ return;
450
+ }
451
+ if (!obj.current_node && obj.response.state === 9) {
452
+ setShowRight(false);
453
+ setIsEnd(true);
454
+ const replaced = replaceStr(obj.response.response);
455
+ setResponse(replaced);
456
+ return;
457
+ }
458
+ if (!obj.current_node && obj.response.state === 1 && !currentNode) {
459
+ // 有thought,没有node
460
+ setDraftEnd(false);
461
+ setDraft(obj.response.response);
462
+ }
463
+ if (!obj.current_node && (obj.response.state !== 1 || obj.response.state !== 0 || obj.response.state !== 9)) {
464
+ // 有thought,没有node, 不用处理渲染
465
+ //console.log('loading-------------', obj);
466
+ setDraftEnd(true);
467
+ setIsWaiting(true);
468
+ }
469
+ if (obj.current_node && obj.response.state === 3) {
470
+ setNodeName(obj.current_node);
471
+ // 有node
472
+ setObj(obj);
473
+ const newAdjList = obj.response?.adjacency_list;
474
+ if (newAdjList?.length > 0) {
475
+ setAdjList(newAdjList);
476
+ }
477
+ }
478
+ } catch (err) {
479
+ console.log('format error-----', err);
480
+ }
481
+ };
482
+
483
+ const startEventSource = () => {
484
+ if (!chatIsOver) {
485
+ message.warning('有对话进行中!');
486
+ return;
487
+ }
488
+ setQuestion(stashQuestion);
489
+ setChatIsOver(false);
490
+ const postData = {
491
+ inputs: [
492
+ {
493
+ role: 'user',
494
+ content: stashQuestion
495
+ }
496
+ ]
497
+ }
498
+ const ctrl = new AbortController();
499
+ eventSource = fetchEventSource(GET_SSE_DATA, {
500
+ method: 'POST',
501
+ headers: {
502
+ 'Content-Type': 'application/json',
503
+ },
504
+ body: JSON.stringify(postData),
505
+ onmessage(ev) {
506
+ formatData(ev.data);
507
+ },
508
+ onerror(err) {
509
+ console.log('sse error------', err);
510
+ },
511
+ // signal: ctrl.signal,
512
+ });
513
+ };
514
+
515
+ const abortEventSource = () => {
516
+ if (eventSource) {
517
+ eventSource.close(); // 或使用其他方法关闭连接,具体取决于库的API
518
+ eventSource = null;
519
+ console.log('EventSource connection aborted due to timeout.');
520
+ message.error('连接中断,2s后即将刷新页面---');
521
+ setTimeout(() => {
522
+ location.reload();
523
+ }, 2000);
524
+ }
525
+ };
526
+
527
+ return <div className={styles.mainPage} style={!showRight ? { maxWidth: '1000px' } : {}}>
528
+ <div className={styles.chatContent}>
529
+ <div className={styles.top} id="chatArea">
530
+ <div id="messageWindowId">
531
+ {
532
+ question && <div className={styles.question}>
533
+ <span>{question}</span>
534
+ </div>
535
+ }
536
+ {
537
+ (draft || response || renderData?.length > 0) &&
538
+ <div className={styles.answer}>
539
+ {
540
+ renderData?.length > 0 ? <div className={styles.inner}>
541
+ <div className={styles.mapArea}>
542
+ <ul className={styles.mindmap} id="mindMap" style={isEnd ? { width: mapWidth, overflow: "hidden" } : {}}>
543
+ {renderData.map((item: any) => (
544
+ <MindMapItem key={item.name} item={item} isEnd={isEnd} />
545
+ ))}
546
+ {showEndNode &&
547
+ <div className={styles.end} style={generateEndStyle()}>
548
+ <div className={styles.node}>
549
+ <article>最终回复</article>
550
+ </div>
551
+ </div>
552
+ }
553
+ </ul>
554
+ </div>
555
+ </div> : <></>
556
+ }
557
+ {
558
+ !response && <div className={styles.draft}>
559
+ {/* {!draftEnd && draft && <div className={styles.loading}>
560
+ <div></div>
561
+ <div></div>
562
+ <div></div>
563
+ </div>} */}
564
+ <ReactMarkdown rehypePlugins={[rehypeRaw]}>{replaceStr(draft)}</ReactMarkdown>
565
+ </div>
566
+ }
567
+ {response && <div className={styles.response}>
568
+ <ReactMarkdown rehypePlugins={[rehypeRaw]}>{response}</ReactMarkdown>
569
+ </div>}
570
+ </div>
571
+ }
572
+ </div>
573
+ </div>
574
+ <div className={styles.sendArea}>
575
+ <Input type="text" placeholder='说点什么吧~ Shift+Enter 换行 ; Enter 发送' onChange={(e) => { setStashQuestion(e.target.value) }}
576
+ onPressEnter={startEventSource} />
577
+ <button onClick={startEventSource}>
578
+ <img src={SendIcon} />
579
+ 发送
580
+ </button>
581
+ </div>
582
+ <div className={styles.notice}>如果想要更丝滑的体验,请在本地搭建-<a href='https://github.com/InternLM/MindSearch' target='_blank'>MindSearch <IconFont type='icon-GithubFilled' /></a></div>
583
+ </div>
584
+ {showRight && <div className={styles.progressContent}>
585
+ {
586
+ currentNode && <>
587
+ <div className={styles.toggleIcon} onClick={toggleRight}>
588
+ <Tooltip placement="top" title="收起">
589
+ <img src={PackIcon} />
590
+ </Tooltip></div>
591
+ <div className={styles.titleNode}>{currentNode?.content || currentNode?.node}</div>
592
+ {
593
+ currentNode?.actions?.length ? <>
594
+ {
595
+ currentNode.actions.map((item: any, idx: number) => (
596
+ currentStep >= idx && <div className={classNames(
597
+ styles.steps,
598
+ item.type === "BingBrowser.search" ? styles.thinking : styles.select
599
+ )} key={`step-${idx}`}>
600
+ <div className={styles.title}>
601
+ <i></i>{item.type === "BingBrowser.search" ? "思考" : item.type === "BingBrowser.select" ? "信息来源" : "信息整合"}
602
+ <div className={styles.open} onClick={() => { toggleCard(idx) }}>
603
+ <IconFont type={collapseInfo[idx] ? "icon-shouqi" : "icon-xiangxiazhankai"} />
604
+ </div>
605
+ </div>
606
+ <div className={classNames(
607
+ styles.con,
608
+ !collapseInfo[idx] ? styles.collapsed : ""
609
+ )}>
610
+ {
611
+ item.type === "BingBrowser.search" && <div className={styles.thought}>
612
+ <ReactMarkdown rehypePlugins={[rehypeRaw]}>{progress1}</ReactMarkdown>
613
+ </div>
614
+ }
615
+ {
616
+ item.type === "BingBrowser.search" && query.length > 0 && <div className={styles.query}>
617
+ <div className={styles.subTitle}><IconFont type="icon-SearchOutlined" />搜索关键词</div>
618
+ {
619
+ query.map((item, index) => (<div key={`query-item-${item}`} className={classNames(styles.queryItem, styles.fadeIn)}>
620
+ {item}
621
+ </div>))
622
+ }
623
+ </div>
624
+ }
625
+ {
626
+ currentStep === idx && searchList.length > 0 && <div className={styles.searchList}>
627
+ {item.type === "BingBrowser.search" && <div className={styles.subTitle}><IconFont type="icon-DocOutlined" />信息来源</div>}
628
+ {
629
+ item.type === "BingBrowser.select" && <div className={styles.thought}>
630
+ <ReactMarkdown rehypePlugins={[rehypeRaw]}>{progress2}</ReactMarkdown>
631
+ </div>
632
+ }
633
+ <div className={styles.scrollCon} style={(searchList.length > 5 && currentStep === 0) ? { height: '300px' } : {}}>
634
+
635
+ <div className={styles.inner} style={(searchList.length > 5 && currentStep === 0) ? { position: 'absolute', bottom: 0, left: 0 } : {}}>
636
+
637
+ {
638
+ searchList.map((item: any, num: number) => (
639
+ <div className={classNames(
640
+ styles.searchItem,
641
+ item.highLight ? styles.highLight : ""
642
+ )} key={`search-item-${item.url}-${idx}`}>
643
+ <p className={styles.summ}>{item.id}. {item?.title}</p>
644
+ <p className={styles.url}>{item?.url}</p>
645
+ </div>
646
+ ))
647
+ }
648
+ </div>
649
+ </div>
650
+ </div>
651
+ }
652
+ </div>
653
+ </div>
654
+ ))
655
+ }
656
+ </> : <></>
657
+ }
658
+ </>
659
+ }
660
+ {
661
+ conclusion && <div className={styles.steps}>
662
+ <div className={styles.title}>
663
+ <i></i>信息整合
664
+ </div>
665
+ <div className={styles.conclusion}>
666
+ <ReactMarkdown rehypePlugins={[rehypeRaw]}>{conclusion}</ReactMarkdown>
667
+ </div>
668
+ </div>
669
+ }
670
+ {isWaiting && question && <div className={styles.loading99}></div>}
671
+ </div>}
672
+ {
673
+ !showRight && <div className={styles.showRight} onClick={toggleRight}>
674
+ <img src={ShowRightIcon} />
675
+ </div>
676
+ }
677
+
678
+ </div>
679
+ };
680
+
681
+ export default RenderTest;
frontend/React/src/pages/render/mindMapItem.tsx ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import styles from './index.module.less';
2
+ import classNames from 'classnames';
3
+
4
+ // 递归组件用于渲染mindMap中的节点
5
+ const MindMapItem = ({ item, isEnd }: any) => {
6
+ // 递归渲染子节点
7
+ const renderChildren = () => {
8
+ if (item.children && item.children.length > 0) {
9
+ return (
10
+ <ul className={item.children.length === 1 ? styles.onlyone : ''}>
11
+ {item.children.map((child: any) => (
12
+ <MindMapItem key={child.name} item={child} isEnd={isEnd} />
13
+ ))}
14
+ </ul>
15
+ );
16
+ }
17
+ return null;
18
+ };
19
+
20
+ return (
21
+ <li>
22
+ <article className={
23
+ classNames(
24
+ item.state === 1 ? styles.loading : item.state === 2 ? styles.disabled : item.state === 3 ? styles.finished : "",
25
+ item.id === 0 ? styles.init : ''
26
+ )}>
27
+ <span>{item.name}</span>
28
+ {item.state === 1 && <div className={styles.looping}></div>}
29
+ {item.id !== 0 && <div className={styles.finishDot}></div>}
30
+ </article>
31
+ {item.children.length > 0 && renderChildren()}
32
+ {
33
+ isEnd && item.children?.length === 0 && <div className={classNames(styles.endLine, "endline")}></div>
34
+ }
35
+ </li>
36
+ );
37
+ };
38
+
39
+ export default MindMapItem;
frontend/React/src/routes/routes.tsx ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import RenderTest from "@/pages/render";
2
+
3
+ import { ReactElement } from "react";
4
+ import { Navigate, useRoutes } from "react-router-dom";
5
+
6
+ interface RouteItem {
7
+ path: string;
8
+ needLogin?: boolean;
9
+ element: ReactElement;
10
+ }
11
+
12
+ const routes: RouteItem[] = [
13
+ {
14
+ path: "/",
15
+ needLogin: false,
16
+ element: <RenderTest />,
17
+ },
18
+ {
19
+ path: "*",
20
+ element: <Navigate to="/" />,
21
+ },
22
+ ];
23
+
24
+ const WrapperRoutes = () => {
25
+ return useRoutes(
26
+ routes.map((item: RouteItem) => {
27
+ if (item.needLogin) {
28
+ return {
29
+ ...item,
30
+ element: <></>,
31
+ };
32
+ }
33
+ return item;
34
+ }),
35
+ );
36
+ };
37
+
38
+ export default WrapperRoutes;
frontend/React/src/utils/tools.ts ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export const getQueryString = (search: string, name: string) => {
2
+ if (!search) return "";
3
+ const reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
4
+ const result = search.substring(1).match(reg);
5
+ if (result != null) return result[2];
6
+ return "";
7
+ };
8
+
9
+ export const isInWhiteList = (url: string = "", list: string[] = []) => {
10
+ const baseUrl = url.split("?")[0];
11
+ for (let whiteApi of list) {
12
+ if (baseUrl.endsWith(whiteApi)) {
13
+ return true;
14
+ }
15
+ }
16
+ return false;
17
+ };
18
+
19
+ export const replaceStr = (str: string) => {
20
+ return str.replace(/\[\[(\d+)\]\]/g, (match: any, number: any) => {
21
+ // 创建一个带有class为'fnn2'的span元素,并将数字作为文本内容
22
+ return `<i class='f'>${number}</i>`;
23
+ });
24
+ };
frontend/React/src/vite-env.d.ts ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ /// <reference types="vite/client" />
2
+
3
+ interface ImportMetaEnv {
4
+ readonly VITE_SSO_URL: string;
5
+ }
6
+
7
+ interface ImportMeta {
8
+ readonly env: ImportMetaEnv;
9
+ }
frontend/React/tsconfig.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES5",
4
+ "useDefineForClassFields": true,
5
+ "lib": ["DOM", "DOM.Iterable", "ESNext"],
6
+ "allowJs": false,
7
+ "skipLibCheck": true,
8
+ "esModuleInterop": false,
9
+ "allowSyntheticDefaultImports": true,
10
+ "strict": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "module": "ESNext",
13
+ "moduleResolution": "Node",
14
+ "resolveJsonModule": true,
15
+ "isolatedModules": true,
16
+ "noEmit": true,
17
+ "jsx": "react-jsx",
18
+ "baseUrl": "./",
19
+ "paths": {
20
+ "@/*": ["src/*"]
21
+ }
22
+ },
23
+ "include": ["src"]
24
+ }
frontend/React/vite.config.ts ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { defineConfig } from "vite";
2
+ import react from "@vitejs/plugin-react";
3
+ import path from "path";
4
+ import legacy from "@vitejs/plugin-legacy";
5
+
6
+ // https://vitejs.dev/config/
7
+ export default defineConfig({
8
+ plugins: [
9
+ react({
10
+ babel: {
11
+ plugins: [
12
+ "@babel/plugin-proposal-optional-chaining", // 兼容老版本浏览器的语法解译
13
+ ],
14
+ },
15
+ }),
16
+ legacy({
17
+ targets: ["defaults", "ie >= 11", "chrome >= 52"], //需要兼容的目标列表,可以设置多个
18
+ additionalLegacyPolyfills: ["regenerator-runtime/runtime"],
19
+ renderLegacyChunks: true,
20
+ polyfills: [
21
+ "es.symbol",
22
+ "es.array.filter",
23
+ "es.promise",
24
+ "es.promise.finally",
25
+ "es/map",
26
+ "es/set",
27
+ "es.array.for-each",
28
+ "es.object.define-properties",
29
+ "es.object.define-property",
30
+ "es.object.get-own-property-descriptor",
31
+ "es.object.get-own-property-descriptors",
32
+ "es.object.keys",
33
+ "es.object.to-string",
34
+ "web.dom-collections.for-each",
35
+ "esnext.global-this",
36
+ "esnext.string.match-all",
37
+ ],
38
+ }),
39
+ ],
40
+ build: {
41
+ target: "es5",
42
+ },
43
+ resolve: {
44
+ alias: {
45
+ "@": path.resolve(__dirname, "src"),
46
+ },
47
+ },
48
+ css: {
49
+ modules: {
50
+ localsConvention: "camelCase",
51
+ },
52
+ },
53
+ server: {
54
+ port: 8080,
55
+ proxy: {
56
+ // "/solve": {
57
+ // target: "...",
58
+ // changeOrigin: true,
59
+ // },
60
+ },
61
+ },
62
+ });
frontend/React/windows-.png ADDED
frontend/mindsearch_gradio.py ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+
3
+ import gradio as gr
4
+ import requests
5
+ from lagent.schema import AgentStatusCode
6
+
7
+ PLANNER_HISTORY = []
8
+ SEARCHER_HISTORY = []
9
+
10
+
11
+ def rst_mem(history_planner: list, history_searcher: list):
12
+ '''
13
+ Reset the chatbot memory.
14
+ '''
15
+ history_planner = []
16
+ history_searcher = []
17
+ if PLANNER_HISTORY:
18
+ PLANNER_HISTORY.clear()
19
+ return history_planner, history_searcher
20
+
21
+
22
+ def format_response(gr_history, agent_return):
23
+ if agent_return['state'] in [
24
+ AgentStatusCode.STREAM_ING, AgentStatusCode.ANSWER_ING
25
+ ]:
26
+ gr_history[-1][1] = agent_return['response']
27
+ elif agent_return['state'] == AgentStatusCode.PLUGIN_START:
28
+ thought = gr_history[-1][1].split('```')[0]
29
+ if agent_return['response'].startswith('```'):
30
+ gr_history[-1][1] = thought + '\n' + agent_return['response']
31
+ elif agent_return['state'] == AgentStatusCode.PLUGIN_END:
32
+ thought = gr_history[-1][1].split('```')[0]
33
+ if isinstance(agent_return['response'], dict):
34
+ gr_history[-1][
35
+ 1] = thought + '\n' + f'```json\n{json.dumps(agent_return["response"], ensure_ascii=False, indent=4)}\n```' # noqa: E501
36
+ elif agent_return['state'] == AgentStatusCode.PLUGIN_RETURN:
37
+ assert agent_return['inner_steps'][-1]['role'] == 'environment'
38
+ item = agent_return['inner_steps'][-1]
39
+ gr_history.append([
40
+ None,
41
+ f"```json\n{json.dumps(item['content'], ensure_ascii=False, indent=4)}\n```"
42
+ ])
43
+ gr_history.append([None, ''])
44
+ return
45
+
46
+
47
+ def predict(history_planner, history_searcher):
48
+
49
+ def streaming(raw_response):
50
+ for chunk in raw_response.iter_lines(chunk_size=8192,
51
+ decode_unicode=False,
52
+ delimiter=b'\n'):
53
+ if chunk:
54
+ decoded = chunk.decode('utf-8')
55
+ if decoded == '\r':
56
+ continue
57
+ if decoded[:6] == 'data: ':
58
+ decoded = decoded[6:]
59
+ elif decoded.startswith(': ping - '):
60
+ continue
61
+ response = json.loads(decoded)
62
+ yield (response['response'], response['current_node'])
63
+
64
+ global PLANNER_HISTORY
65
+ PLANNER_HISTORY.append(dict(role='user', content=history_planner[-1][0]))
66
+ new_search_turn = True
67
+
68
+ url = 'http://localhost:8002/solve'
69
+ headers = {'Content-Type': 'application/json'}
70
+ data = {'inputs': PLANNER_HISTORY}
71
+ raw_response = requests.post(url,
72
+ headers=headers,
73
+ data=json.dumps(data),
74
+ timeout=20,
75
+ stream=True)
76
+
77
+ for resp in streaming(raw_response):
78
+ agent_return, node_name = resp
79
+ if node_name:
80
+ if node_name in ['root', 'response']:
81
+ continue
82
+ agent_return = agent_return['nodes'][node_name]['detail']
83
+ if new_search_turn:
84
+ history_searcher.append([agent_return['content'], ''])
85
+ new_search_turn = False
86
+ format_response(history_searcher, agent_return)
87
+ if agent_return['state'] == AgentStatusCode.END:
88
+ new_search_turn = True
89
+ yield history_planner, history_searcher
90
+ else:
91
+ new_search_turn = True
92
+ format_response(history_planner, agent_return)
93
+ if agent_return['state'] == AgentStatusCode.END:
94
+ PLANNER_HISTORY = agent_return['inner_steps']
95
+ yield history_planner, history_searcher
96
+ return history_planner, history_searcher
97
+
98
+
99
+ with gr.Blocks() as demo:
100
+ gr.HTML("""<h1 align="center">WebAgent Gradio Simple Demo</h1>""")
101
+ with gr.Row():
102
+ with gr.Column(scale=10):
103
+ with gr.Row():
104
+ with gr.Column():
105
+ planner = gr.Chatbot(label='planner',
106
+ height=700,
107
+ show_label=True,
108
+ show_copy_button=True,
109
+ bubble_full_width=False,
110
+ render_markdown=True)
111
+ with gr.Column():
112
+ searcher = gr.Chatbot(label='searcher',
113
+ height=700,
114
+ show_label=True,
115
+ show_copy_button=True,
116
+ bubble_full_width=False,
117
+ render_markdown=True)
118
+ with gr.Row():
119
+ user_input = gr.Textbox(show_label=False,
120
+ placeholder='inputs...',
121
+ lines=5,
122
+ container=False)
123
+ with gr.Row():
124
+ with gr.Column(scale=2):
125
+ submitBtn = gr.Button('Submit')
126
+ with gr.Column(scale=1, min_width=20):
127
+ emptyBtn = gr.Button('Clear History')
128
+
129
+ def user(query, history):
130
+ return '', history + [[query, '']]
131
+
132
+ submitBtn.click(user, [user_input, planner], [user_input, planner],
133
+ queue=False).then(predict, [planner, searcher],
134
+ [planner, searcher])
135
+ emptyBtn.click(rst_mem, [planner, searcher], [planner, searcher],
136
+ queue=False)
137
+
138
+ demo.queue()
139
+ demo.launch(server_name='127.0.0.1',
140
+ server_port=7882,
141
+ inbrowser=True,
142
+ share=True)
frontend/mindsearch_streamlit.py ADDED
@@ -0,0 +1,319 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import tempfile
3
+
4
+ import requests
5
+ import streamlit as st
6
+ from lagent.schema import AgentStatusCode
7
+ from pyvis.network import Network
8
+
9
+
10
+ # Function to create the network graph
11
+ def create_network_graph(nodes, adjacency_list):
12
+ net = Network(height='500px',
13
+ width='60%',
14
+ bgcolor='white',
15
+ font_color='black')
16
+ for node_id, node_data in nodes.items():
17
+ if node_id in ['root', 'response']:
18
+ title = node_data.get('content', node_id)
19
+ else:
20
+ title = node_data['detail']['content']
21
+ net.add_node(node_id,
22
+ label=node_id,
23
+ title=title,
24
+ color='#FF5733',
25
+ size=25)
26
+ for node_id, neighbors in adjacency_list.items():
27
+ for neighbor in neighbors:
28
+ if neighbor['name'] in nodes:
29
+ net.add_edge(node_id, neighbor['name'])
30
+ net.show_buttons(filter_=['physics'])
31
+ return net
32
+
33
+
34
+ # Function to draw the graph and return the HTML file path
35
+ def draw_graph(net):
36
+ path = tempfile.mktemp(suffix='.html')
37
+ net.save_graph(path)
38
+ return path
39
+
40
+
41
+ def streaming(raw_response):
42
+ for chunk in raw_response.iter_lines(chunk_size=8192,
43
+ decode_unicode=False,
44
+ delimiter=b'\n'):
45
+ if chunk:
46
+ decoded = chunk.decode('utf-8')
47
+ if decoded == '\r':
48
+ continue
49
+ if decoded[:6] == 'data: ':
50
+ decoded = decoded[6:]
51
+ elif decoded.startswith(': ping - '):
52
+ continue
53
+ response = json.loads(decoded)
54
+ yield (response['response'], response['current_node'])
55
+
56
+
57
+ # Initialize Streamlit session state
58
+ if 'queries' not in st.session_state:
59
+ st.session_state['queries'] = []
60
+ st.session_state['responses'] = []
61
+ st.session_state['graphs_html'] = []
62
+ st.session_state['nodes_list'] = []
63
+ st.session_state['adjacency_list_list'] = []
64
+ st.session_state['history'] = []
65
+ st.session_state['already_used_keys'] = list()
66
+
67
+ # Set up page layout
68
+ st.set_page_config(layout='wide')
69
+ st.title('MindSearch-思索')
70
+
71
+
72
+ # Function to update chat
73
+ def update_chat(query):
74
+ with st.chat_message('user'):
75
+ st.write(query)
76
+ if query not in st.session_state['queries']:
77
+ # Mock data to simulate backend response
78
+ # response, history, nodes, adjacency_list
79
+ st.session_state['queries'].append(query)
80
+ st.session_state['responses'].append([])
81
+ history = None
82
+ # 暂不支持多轮
83
+ message = [dict(role='user', content=query)]
84
+
85
+ url = 'http://localhost:8002/solve'
86
+ headers = {'Content-Type': 'application/json'}
87
+ data = {'inputs': message}
88
+ raw_response = requests.post(url,
89
+ headers=headers,
90
+ data=json.dumps(data),
91
+ timeout=20,
92
+ stream=True)
93
+
94
+ for resp in streaming(raw_response):
95
+ agent_return, node_name = resp
96
+ if node_name and node_name in ['root', 'response']:
97
+ continue
98
+ nodes = agent_return['nodes']
99
+ adjacency_list = agent_return['adj']
100
+ response = agent_return['response']
101
+ history = agent_return['inner_steps']
102
+ if nodes:
103
+ net = create_network_graph(nodes, adjacency_list)
104
+ graph_html_path = draw_graph(net)
105
+ with open(graph_html_path, encoding='utf-8') as f:
106
+ graph_html = f.read()
107
+ else:
108
+ graph_html = None
109
+ if 'graph_placeholder' not in st.session_state:
110
+ st.session_state['graph_placeholder'] = st.empty()
111
+ if 'expander_placeholder' not in st.session_state:
112
+ st.session_state['expander_placeholder'] = st.empty()
113
+ if graph_html:
114
+ with st.session_state['expander_placeholder'].expander(
115
+ 'Show Graph', expanded=False):
116
+ st.session_state['graph_placeholder']._html(graph_html,
117
+ height=500)
118
+ if 'container_placeholder' not in st.session_state:
119
+ st.session_state['container_placeholder'] = st.empty()
120
+ with st.session_state['container_placeholder'].container():
121
+ if 'columns_placeholder' not in st.session_state:
122
+ st.session_state['columns_placeholder'] = st.empty()
123
+ col1, col2 = st.session_state['columns_placeholder'].columns(
124
+ [2, 1])
125
+ with col1:
126
+ if 'planner_placeholder' not in st.session_state:
127
+ st.session_state['planner_placeholder'] = st.empty()
128
+ if 'session_info_temp' not in st.session_state:
129
+ st.session_state['session_info_temp'] = ''
130
+ if not node_name:
131
+ if agent_return['state'] in [
132
+ AgentStatusCode.STREAM_ING,
133
+ AgentStatusCode.ANSWER_ING
134
+ ]:
135
+ st.session_state['session_info_temp'] = response
136
+ elif agent_return[
137
+ 'state'] == AgentStatusCode.PLUGIN_START:
138
+ thought = st.session_state[
139
+ 'session_info_temp'].split('```')[0]
140
+ if agent_return['response'].startswith('```'):
141
+ st.session_state[
142
+ 'session_info_temp'] = thought + '\n' + response
143
+ elif agent_return[
144
+ 'state'] == AgentStatusCode.PLUGIN_RETURN:
145
+ assert agent_return['inner_steps'][-1][
146
+ 'role'] == 'environment'
147
+ st.session_state[
148
+ 'session_info_temp'] += '\n' + agent_return[
149
+ 'inner_steps'][-1]['content']
150
+ st.session_state['planner_placeholder'].markdown(
151
+ st.session_state['session_info_temp'])
152
+ if agent_return[
153
+ 'state'] == AgentStatusCode.PLUGIN_RETURN:
154
+ st.session_state['responses'][-1].append(
155
+ st.session_state['session_info_temp'])
156
+ st.session_state['session_info_temp'] = ''
157
+ else:
158
+ st.session_state['planner_placeholder'].markdown(
159
+ st.session_state['responses'][-1][-1] if
160
+ not st.session_state['session_info_temp'] else st.
161
+ session_state['session_info_temp'])
162
+ with col2:
163
+ if 'selectbox_placeholder' not in st.session_state:
164
+ st.session_state['selectbox_placeholder'] = st.empty()
165
+ if 'searcher_placeholder' not in st.session_state:
166
+ st.session_state['searcher_placeholder'] = st.empty()
167
+ # st.session_state['searcher_placeholder'].markdown('')
168
+ if node_name:
169
+ selected_node_key = f"selected_node_{len(st.session_state['queries'])}_{node_name}"
170
+ if selected_node_key not in st.session_state:
171
+ st.session_state[selected_node_key] = node_name
172
+ if selected_node_key not in st.session_state[
173
+ 'already_used_keys']:
174
+ selected_node = st.session_state[
175
+ 'selectbox_placeholder'].selectbox(
176
+ 'Select a node:',
177
+ list(nodes.keys()),
178
+ key=f'key_{selected_node_key}',
179
+ index=list(nodes.keys()).index(node_name))
180
+ st.session_state['already_used_keys'].append(
181
+ selected_node_key)
182
+ else:
183
+ selected_node = node_name
184
+ st.session_state[selected_node_key] = selected_node
185
+ if selected_node in nodes:
186
+ node = nodes[selected_node]
187
+ agent_return = node['detail']
188
+ node_info_key = f'{selected_node}_info'
189
+ if 'node_info_temp' not in st.session_state:
190
+ st.session_state[
191
+ 'node_info_temp'] = f'### {agent_return["content"]}'
192
+ if node_info_key not in st.session_state:
193
+ st.session_state[node_info_key] = []
194
+ if agent_return['state'] in [
195
+ AgentStatusCode.STREAM_ING,
196
+ AgentStatusCode.ANSWER_ING
197
+ ]:
198
+ st.session_state[
199
+ 'node_info_temp'] = agent_return[
200
+ 'response']
201
+ elif agent_return[
202
+ 'state'] == AgentStatusCode.PLUGIN_START:
203
+ thought = st.session_state[
204
+ 'node_info_temp'].split('```')[0]
205
+ if agent_return['response'].startswith('```'):
206
+ st.session_state[
207
+ 'node_info_temp'] = thought + '\n' + agent_return[
208
+ 'response']
209
+ elif agent_return[
210
+ 'state'] == AgentStatusCode.PLUGIN_END:
211
+ thought = st.session_state[
212
+ 'node_info_temp'].split('```')[0]
213
+ if isinstance(agent_return['response'], dict):
214
+ st.session_state[
215
+ 'node_info_temp'] = thought + '\n' + f'```json\n{json.dumps(agent_return["response"], ensure_ascii=False, indent=4)}\n```' # noqa: E501
216
+ elif agent_return[
217
+ 'state'] == AgentStatusCode.PLUGIN_RETURN:
218
+ assert agent_return['inner_steps'][-1][
219
+ 'role'] == 'environment'
220
+ st.session_state[node_info_key].append(
221
+ ('thought',
222
+ st.session_state['node_info_temp']))
223
+ st.session_state[node_info_key].append(
224
+ ('observation',
225
+ agent_return['inner_steps'][-1]['content']
226
+ ))
227
+ st.session_state['searcher_placeholder'].markdown(
228
+ st.session_state['node_info_temp'])
229
+ if agent_return['state'] == AgentStatusCode.END:
230
+ st.session_state[node_info_key].append(
231
+ ('answer',
232
+ st.session_state['node_info_temp']))
233
+ st.session_state['node_info_temp'] = ''
234
+ if st.session_state['session_info_temp']:
235
+ st.session_state['responses'][-1].append(
236
+ st.session_state['session_info_temp'])
237
+ st.session_state['session_info_temp'] = ''
238
+ # st.session_state['responses'][-1] = '\n'.join(st.session_state['responses'][-1])
239
+ st.session_state['graphs_html'].append(graph_html)
240
+ st.session_state['nodes_list'].append(nodes)
241
+ st.session_state['adjacency_list_list'].append(adjacency_list)
242
+ st.session_state['history'] = history
243
+
244
+
245
+ def display_chat_history():
246
+ for i, query in enumerate(st.session_state['queries'][-1:]):
247
+ # with st.chat_message('assistant'):
248
+ if st.session_state['graphs_html'][i]:
249
+ with st.session_state['expander_placeholder'].expander(
250
+ 'Show Graph', expanded=False):
251
+ st.session_state['graph_placeholder']._html(
252
+ st.session_state['graphs_html'][i], height=500)
253
+ with st.session_state['container_placeholder'].container():
254
+ col1, col2 = st.session_state['columns_placeholder'].columns(
255
+ [2, 1])
256
+ with col1:
257
+ st.session_state['planner_placeholder'].markdown(
258
+ st.session_state['responses'][-1][-1])
259
+ with col2:
260
+ selected_node_key = st.session_state['already_used_keys'][
261
+ -1]
262
+ st.session_state['selectbox_placeholder'] = st.empty()
263
+ selected_node = st.session_state[
264
+ 'selectbox_placeholder'].selectbox(
265
+ 'Select a node:',
266
+ list(st.session_state['nodes_list'][i].keys()),
267
+ key=f'replay_key_{i}',
268
+ index=list(st.session_state['nodes_list'][i].keys(
269
+ )).index(st.session_state[selected_node_key]))
270
+ st.session_state[selected_node_key] = selected_node
271
+ if selected_node not in [
272
+ 'root', 'response'
273
+ ] and selected_node in st.session_state['nodes_list'][i]:
274
+ node_info_key = f'{selected_node}_info'
275
+ for item in st.session_state[node_info_key]:
276
+ if item[0] in ['thought', 'answer']:
277
+ st.session_state[
278
+ 'searcher_placeholder'] = st.empty()
279
+ st.session_state[
280
+ 'searcher_placeholder'].markdown(item[1])
281
+ elif item[0] == 'observation':
282
+ st.session_state[
283
+ 'observation_expander'] = st.empty()
284
+ with st.session_state[
285
+ 'observation_expander'].expander(
286
+ 'Results'):
287
+ st.write(item[1])
288
+ # st.session_state['searcher_placeholder'].markdown(st.session_state[node_info_key])
289
+
290
+
291
+ def clean_history():
292
+ st.session_state['queries'] = []
293
+ st.session_state['responses'] = []
294
+ st.session_state['graphs_html'] = []
295
+ st.session_state['nodes_list'] = []
296
+ st.session_state['adjacency_list_list'] = []
297
+ st.session_state['history'] = []
298
+ st.session_state['already_used_keys'] = list()
299
+ for k in st.session_state:
300
+ if k.endswith('placeholder') or k.endswith('_info'):
301
+ del st.session_state[k]
302
+
303
+
304
+ # Main function to run the Streamlit app
305
+ def main():
306
+ st.sidebar.title('Model Control')
307
+ col1, col2 = st.columns([4, 1])
308
+ with col1:
309
+ user_input = st.chat_input('Enter your query:')
310
+ with col2:
311
+ if st.button('Clear History'):
312
+ clean_history()
313
+ if user_input:
314
+ update_chat(user_input)
315
+ display_chat_history()
316
+
317
+
318
+ if __name__ == '__main__':
319
+ main()
mindsearch/agent/__init__.py ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from datetime import datetime
3
+
4
+ from lagent.actions import ActionExecutor, BingBrowser
5
+
6
+ import mindsearch.agent.models as llm_factory
7
+ from mindsearch.agent.mindsearch_agent import (MindSearchAgent,
8
+ MindSearchProtocol)
9
+ from mindsearch.agent.mindsearch_prompt import (
10
+ FINAL_RESPONSE_CN, FINAL_RESPONSE_EN, GRAPH_PROMPT_CN, GRAPH_PROMPT_EN,
11
+ fewshot_example_cn, fewshot_example_en, graph_fewshot_example_cn,
12
+ graph_fewshot_example_en, searcher_context_template_cn,
13
+ searcher_context_template_en, searcher_input_template_cn,
14
+ searcher_input_template_en, searcher_system_prompt_cn,
15
+ searcher_system_prompt_en)
16
+
17
+ LLM = {}
18
+
19
+
20
+ def init_agent(lang='cn', model_format='internlm_server'):
21
+ llm = LLM.get(model_format, None)
22
+ if llm is None:
23
+ llm_cfg = getattr(llm_factory, model_format)
24
+ if llm_cfg is None:
25
+ raise NotImplementedError
26
+ llm_cfg = llm_cfg.copy()
27
+ llm = llm_cfg.pop('type')(**llm_cfg)
28
+ LLM[model_format] = llm
29
+
30
+ interpreter_prompt = GRAPH_PROMPT_CN if lang == 'cn' else GRAPH_PROMPT_EN
31
+ plugin_prompt = searcher_system_prompt_cn if lang == 'cn' else searcher_system_prompt_en
32
+ if model_format == 'gpt4':
33
+ interpreter_prompt += graph_fewshot_example_cn if lang == 'cn' else graph_fewshot_example_en
34
+ plugin_prompt += fewshot_example_cn if lang == 'cn' else fewshot_example_en
35
+
36
+ agent = MindSearchAgent(
37
+ llm=llm,
38
+ protocol=MindSearchProtocol(meta_prompt=datetime.now().strftime(
39
+ 'The current date is %Y-%m-%d.'),
40
+ interpreter_prompt=interpreter_prompt,
41
+ response_prompt=FINAL_RESPONSE_CN
42
+ if lang == 'cn' else FINAL_RESPONSE_EN),
43
+ searcher_cfg=dict(
44
+ llm=llm,
45
+ plugin_executor=ActionExecutor(
46
+ BingBrowser(searcher_type='DuckDuckGoSearch',
47
+ topk=6,
48
+ api_key=os.environ.get('BING_API_KEY',
49
+ 'YOUR BING API'))),
50
+ protocol=MindSearchProtocol(
51
+ meta_prompt=datetime.now().strftime(
52
+ 'The current date is %Y-%m-%d.'),
53
+ plugin_prompt=plugin_prompt,
54
+ ),
55
+ template=dict(input=searcher_input_template_cn
56
+ if lang == 'cn' else searcher_input_template_en,
57
+ context=searcher_context_template_cn
58
+ if lang == 'cn' else searcher_context_template_en)),
59
+ max_turn=10)
60
+ return agent
mindsearch/agent/mindsearch_agent.py ADDED
@@ -0,0 +1,408 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import logging
3
+ import queue
4
+ import random
5
+ import re
6
+ import threading
7
+ import uuid
8
+ from collections import defaultdict
9
+ from concurrent.futures import ThreadPoolExecutor, as_completed
10
+ from copy import deepcopy
11
+ from dataclasses import asdict
12
+ from typing import Dict, List, Optional
13
+
14
+ from lagent.actions import ActionExecutor
15
+ from lagent.agents import BaseAgent, Internlm2Agent
16
+ from lagent.agents.internlm2_agent import Internlm2Protocol
17
+ from lagent.schema import AgentReturn, AgentStatusCode, ModelStatusCode
18
+ from termcolor import colored
19
+
20
+ # 初始化日志记录
21
+ logging.basicConfig(level=logging.INFO)
22
+ logger = logging.getLogger(__name__)
23
+
24
+
25
+ class SearcherAgent(Internlm2Agent):
26
+
27
+ def __init__(self, template='{query}', **kwargs) -> None:
28
+ super().__init__(**kwargs)
29
+ self.template = template
30
+
31
+ def stream_chat(self,
32
+ question: str,
33
+ root_question: str = None,
34
+ parent_response: List[dict] = None,
35
+ **kwargs) -> AgentReturn:
36
+ message = self.template['input'].format(question=question,
37
+ topic=root_question)
38
+ if parent_response:
39
+ if 'context' in self.template:
40
+ parent_response = [
41
+ self.template['context'].format(**item)
42
+ for item in parent_response
43
+ ]
44
+ message = '\n'.join(parent_response + [message])
45
+ print(colored(f'current query: {message}', 'green'))
46
+ for agent_return in super().stream_chat(message,
47
+ session_id=random.randint(
48
+ 0, 999999),
49
+ **kwargs):
50
+ agent_return.type = 'searcher'
51
+ agent_return.content = question
52
+ yield deepcopy(agent_return)
53
+
54
+
55
+ class MindSearchProtocol(Internlm2Protocol):
56
+
57
+ def __init__(
58
+ self,
59
+ meta_prompt: str = None,
60
+ interpreter_prompt: str = None,
61
+ plugin_prompt: str = None,
62
+ few_shot: Optional[List] = None,
63
+ response_prompt: str = None,
64
+ language: Dict = dict(
65
+ begin='',
66
+ end='',
67
+ belong='assistant',
68
+ ),
69
+ tool: Dict = dict(
70
+ begin='{start_token}{name}\n',
71
+ start_token='<|action_start|>',
72
+ name_map=dict(plugin='<|plugin|>', interpreter='<|interpreter|>'),
73
+ belong='assistant',
74
+ end='<|action_end|>\n',
75
+ ),
76
+ execute: Dict = dict(role='execute',
77
+ begin='',
78
+ end='',
79
+ fallback_role='environment'),
80
+ ) -> None:
81
+ self.response_prompt = response_prompt
82
+ super().__init__(meta_prompt=meta_prompt,
83
+ interpreter_prompt=interpreter_prompt,
84
+ plugin_prompt=plugin_prompt,
85
+ few_shot=few_shot,
86
+ language=language,
87
+ tool=tool,
88
+ execute=execute)
89
+
90
+ def format(self,
91
+ inner_step: List[Dict],
92
+ plugin_executor: ActionExecutor = None,
93
+ **kwargs) -> list:
94
+ formatted = []
95
+ if self.meta_prompt:
96
+ formatted.append(dict(role='system', content=self.meta_prompt))
97
+ if self.plugin_prompt:
98
+ plugin_prompt = self.plugin_prompt.format(tool_info=json.dumps(
99
+ plugin_executor.get_actions_info(), ensure_ascii=False))
100
+ formatted.append(
101
+ dict(role='system', content=plugin_prompt, name='plugin'))
102
+ if self.interpreter_prompt:
103
+ formatted.append(
104
+ dict(role='system',
105
+ content=self.interpreter_prompt,
106
+ name='interpreter'))
107
+ if self.few_shot:
108
+ for few_shot in self.few_shot:
109
+ formatted += self.format_sub_role(few_shot)
110
+ formatted += self.format_sub_role(inner_step)
111
+ return formatted
112
+
113
+
114
+ class WebSearchGraph:
115
+ end_signal = 'end'
116
+ searcher_cfg = dict()
117
+
118
+ def __init__(self):
119
+ self.nodes = {}
120
+ self.adjacency_list = defaultdict(list)
121
+ self.executor = ThreadPoolExecutor(max_workers=10)
122
+ self.future_to_query = dict()
123
+ self.searcher_resp_queue = queue.Queue()
124
+
125
+ def add_root_node(self, node_content, node_name='root'):
126
+ self.nodes[node_name] = dict(content=node_content, type='root')
127
+ self.adjacency_list[node_name] = []
128
+ self.searcher_resp_queue.put((node_name, self.nodes[node_name], []))
129
+
130
+ def add_node(self, node_name, node_content):
131
+ self.nodes[node_name] = dict(content=node_content, type='searcher')
132
+ self.adjacency_list[node_name] = []
133
+
134
+ def model_stream_thread():
135
+ agent = SearcherAgent(**self.searcher_cfg)
136
+ try:
137
+ parent_nodes = []
138
+ for start_node, adj in self.adjacency_list.items():
139
+ for neighbor in adj:
140
+ if node_name == neighbor[
141
+ 'name'] and start_node in self.nodes and 'response' in self.nodes[
142
+ start_node]:
143
+ parent_nodes.append(self.nodes[start_node])
144
+ parent_response = [
145
+ dict(question=node['content'], answer=node['response'])
146
+ for node in parent_nodes
147
+ ]
148
+ for answer in agent.stream_chat(
149
+ node_content,
150
+ self.nodes['root']['content'],
151
+ parent_response=parent_response):
152
+ self.searcher_resp_queue.put(
153
+ deepcopy((node_name,
154
+ dict(response=answer.response,
155
+ detail=answer), [])))
156
+ self.nodes[node_name]['response'] = answer.response
157
+ self.nodes[node_name]['detail'] = answer
158
+ except Exception as e:
159
+ logger.exception(f'Error in model_stream_thread: {e}')
160
+
161
+ self.future_to_query[self.executor.submit(
162
+ model_stream_thread)] = f'{node_name}-{node_content}'
163
+
164
+ def add_response_node(self, node_name='response'):
165
+ self.nodes[node_name] = dict(type='end')
166
+ self.searcher_resp_queue.put((node_name, self.nodes[node_name], []))
167
+
168
+ def add_edge(self, start_node, end_node):
169
+ self.adjacency_list[start_node].append(
170
+ dict(id=str(uuid.uuid4()), name=end_node, state=2))
171
+ self.searcher_resp_queue.put((start_node, self.nodes[start_node],
172
+ self.adjacency_list[start_node]))
173
+
174
+ def reset(self):
175
+ self.nodes = {}
176
+ self.adjacency_list = defaultdict(list)
177
+
178
+ def node(self, node_name):
179
+ return self.nodes[node_name].copy()
180
+
181
+
182
+ class MindSearchAgent(BaseAgent):
183
+
184
+ def __init__(self,
185
+ llm,
186
+ searcher_cfg,
187
+ protocol=MindSearchProtocol(),
188
+ max_turn=10):
189
+ self.local_dict = {}
190
+ self.ptr = 0
191
+ self.llm = llm
192
+ self.max_turn = max_turn
193
+ WebSearchGraph.searcher_cfg = searcher_cfg
194
+ super().__init__(llm=llm, action_executor=None, protocol=protocol)
195
+
196
+ def stream_chat(self, message, **kwargs):
197
+ if isinstance(message, str):
198
+ message = [{'role': 'user', 'content': message}]
199
+ elif isinstance(message, dict):
200
+ message = [message]
201
+ as_dict = kwargs.pop('as_dict', False)
202
+ return_early = kwargs.pop('return_early', False)
203
+ self.local_dict.clear()
204
+ self.ptr = 0
205
+ inner_history = message[:]
206
+ agent_return = AgentReturn()
207
+ agent_return.type = 'planner'
208
+ agent_return.nodes = {}
209
+ agent_return.adjacency_list = {}
210
+ agent_return.inner_steps = deepcopy(inner_history)
211
+ for _ in range(self.max_turn):
212
+ prompt = self._protocol.format(inner_step=inner_history)
213
+ for model_state, response, _ in self.llm.stream_chat(
214
+ prompt, session_id=random.randint(0, 999999), **kwargs):
215
+ if model_state.value < 0:
216
+ agent_return.state = getattr(AgentStatusCode,
217
+ model_state.name)
218
+ yield deepcopy(agent_return)
219
+ return
220
+ response = response.replace('<|plugin|>', '<|interpreter|>')
221
+ _, language, action = self._protocol.parse(response)
222
+ if not language and not action:
223
+ continue
224
+ code = action['parameters']['command'] if action else ''
225
+ agent_return.state = self._determine_agent_state(
226
+ model_state, code, agent_return)
227
+ agent_return.response = language if not code else code
228
+
229
+ # if agent_return.state == AgentStatusCode.STREAM_ING:
230
+ yield deepcopy(agent_return)
231
+
232
+ inner_history.append({'role': 'language', 'content': language})
233
+ print(colored(response, 'blue'))
234
+
235
+ if code:
236
+ yield from self._process_code(agent_return, inner_history,
237
+ code, as_dict, return_early)
238
+ else:
239
+ agent_return.state = AgentStatusCode.END
240
+ yield deepcopy(agent_return)
241
+ return
242
+
243
+ agent_return.state = AgentStatusCode.END
244
+ yield deepcopy(agent_return)
245
+
246
+ def _determine_agent_state(self, model_state, code, agent_return):
247
+ if code:
248
+ return (AgentStatusCode.PLUGIN_START if model_state
249
+ == ModelStatusCode.END else AgentStatusCode.PLUGIN_START)
250
+ return (AgentStatusCode.ANSWER_ING
251
+ if agent_return.nodes and 'response' in agent_return.nodes else
252
+ AgentStatusCode.STREAM_ING)
253
+
254
+ def _process_code(self,
255
+ agent_return,
256
+ inner_history,
257
+ code,
258
+ as_dict=False,
259
+ return_early=False):
260
+ for node_name, node, adj in self.execute_code(
261
+ code, return_early=return_early):
262
+ if as_dict and 'detail' in node:
263
+ node['detail'] = asdict(node['detail'])
264
+ if not adj:
265
+ agent_return.nodes[node_name] = node
266
+ else:
267
+ agent_return.adjacency_list[node_name] = adj
268
+ # state 1进行中,2未开始,3已结束
269
+ for start_node, neighbors in agent_return.adjacency_list.items():
270
+ for neighbor in neighbors:
271
+ if neighbor['name'] not in agent_return.nodes:
272
+ state = 2
273
+ elif 'detail' not in agent_return.nodes[neighbor['name']]:
274
+ state = 2
275
+ elif agent_return.nodes[neighbor['name']][
276
+ 'detail'].state == AgentStatusCode.END:
277
+ state = 3
278
+ else:
279
+ state = 1
280
+ neighbor['state'] = state
281
+ if not adj:
282
+ yield deepcopy((agent_return, node_name))
283
+ reference, references_url = self._generate_reference(
284
+ agent_return, code, as_dict)
285
+ inner_history.append({
286
+ 'role': 'tool',
287
+ 'content': code,
288
+ 'name': 'plugin'
289
+ })
290
+ inner_history.append({
291
+ 'role': 'environment',
292
+ 'content': reference,
293
+ 'name': 'plugin'
294
+ })
295
+ agent_return.inner_steps = deepcopy(inner_history)
296
+ agent_return.state = AgentStatusCode.PLUGIN_RETURN
297
+ agent_return.references.update(references_url)
298
+ yield deepcopy(agent_return)
299
+
300
+ def _generate_reference(self, agent_return, code, as_dict):
301
+ node_list = [
302
+ node.strip().strip('\"') for node in re.findall(
303
+ r'graph\.node\("((?:[^"\\]|\\.)*?)"\)', code)
304
+ ]
305
+ if 'add_response_node' in code:
306
+ return self._protocol.response_prompt, dict()
307
+ references = []
308
+ references_url = dict()
309
+ for node_name in node_list:
310
+ if as_dict:
311
+ ref_results = agent_return.nodes[node_name]['detail'][
312
+ 'actions'][0]['result'][0]['content']
313
+ else:
314
+ ref_results = agent_return.nodes[node_name]['detail'].actions[
315
+ 0].result[0]['content']
316
+ ref_results = json.loads(ref_results)
317
+ ref2url = {idx: item['url'] for idx, item in ref_results.items()}
318
+ ref = f"## {node_name}\n\n{agent_return.nodes[node_name]['response']}\n"
319
+ updated_ref = re.sub(
320
+ r'\[\[(\d+)\]\]',
321
+ lambda match: f'[[{int(match.group(1)) + self.ptr}]]', ref)
322
+ numbers = [int(n) for n in re.findall(r'\[\[(\d+)\]\]', ref)]
323
+ if numbers:
324
+ assert all(str(elem) in ref2url for elem in numbers)
325
+ references_url.update({
326
+ str(idx + self.ptr): ref2url[str(idx)]
327
+ for idx in set(numbers)
328
+ })
329
+ self.ptr += max(numbers) + 1
330
+ references.append(updated_ref)
331
+ return '\n'.join(references), references_url
332
+
333
+ def execute_code(self, command: str, return_early=False):
334
+
335
+ def extract_code(text: str) -> str:
336
+ text = re.sub(r'from ([\w.]+) import WebSearchGraph', '', text)
337
+ triple_match = re.search(r'```[^\n]*\n(.+?)```', text, re.DOTALL)
338
+ single_match = re.search(r'`([^`]*)`', text, re.DOTALL)
339
+ if triple_match:
340
+ return triple_match.group(1)
341
+ elif single_match:
342
+ return single_match.group(1)
343
+ return text
344
+
345
+ def run_command(cmd):
346
+ try:
347
+ exec(cmd, globals(), self.local_dict)
348
+ plan_graph = self.local_dict.get('graph')
349
+ assert plan_graph is not None
350
+ for future in as_completed(plan_graph.future_to_query):
351
+ future.result()
352
+ plan_graph.future_to_query.clear()
353
+ plan_graph.searcher_resp_queue.put(plan_graph.end_signal)
354
+ except Exception as e:
355
+ logger.exception(f'Error executing code: {e}')
356
+
357
+ command = extract_code(command)
358
+ producer_thread = threading.Thread(target=run_command,
359
+ args=(command, ))
360
+ producer_thread.start()
361
+
362
+ responses = defaultdict(list)
363
+ ordered_nodes = []
364
+ active_node = None
365
+
366
+ while True:
367
+ try:
368
+ item = self.local_dict.get('graph').searcher_resp_queue.get(
369
+ timeout=60)
370
+ if item is WebSearchGraph.end_signal:
371
+ for node_name in ordered_nodes:
372
+ # resp = None
373
+ for resp in responses[node_name]:
374
+ yield deepcopy(resp)
375
+ # if resp:
376
+ # assert resp[1][
377
+ # 'detail'].state == AgentStatusCode.END
378
+ break
379
+ node_name, node, adj = item
380
+ if node_name in ['root', 'response']:
381
+ yield deepcopy((node_name, node, adj))
382
+ else:
383
+ if node_name not in ordered_nodes:
384
+ ordered_nodes.append(node_name)
385
+ responses[node_name].append((node_name, node, adj))
386
+ if not active_node and ordered_nodes:
387
+ active_node = ordered_nodes[0]
388
+ while active_node and responses[active_node]:
389
+ if return_early:
390
+ if 'detail' in responses[active_node][-1][
391
+ 1] and responses[active_node][-1][1][
392
+ 'detail'].state == AgentStatusCode.END:
393
+ item = responses[active_node][-1]
394
+ else:
395
+ item = responses[active_node].pop(0)
396
+ else:
397
+ item = responses[active_node].pop(0)
398
+ if 'detail' in item[1] and item[1][
399
+ 'detail'].state == AgentStatusCode.END:
400
+ ordered_nodes.pop(0)
401
+ responses[active_node].clear()
402
+ active_node = None
403
+ yield deepcopy(item)
404
+ except queue.Empty:
405
+ if not producer_thread.is_alive():
406
+ break
407
+ producer_thread.join()
408
+ return
mindsearch/agent/mindsearch_prompt.py ADDED
@@ -0,0 +1,326 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # flake8: noqa
2
+
3
+ searcher_system_prompt_cn = """## 人物简介
4
+ 你是一个可以调用网络搜索工具的智能助手。请根据"当前问题",调用搜索工具收集信息并回复问题。你能够调用如下工具:
5
+ {tool_info}
6
+ ## 回复格式
7
+
8
+ 调用工具时,请按照以下格式:
9
+ ```
10
+ 你的思考过程...<|action_start|><|plugin|>{{"name": "tool_name", "parameters": {{"param1": "value1"}}}}<|action_end|>
11
+ ```
12
+
13
+ ## 要求
14
+
15
+ - 回答中每个关键点需标注引用的搜索结果来源,以确保信息的可信度。给出索引的形式为`[[int]]`,如果有多个索引,则用多个[[]]表示,如`[[id_1]][[id_2]]`。
16
+ - 基于"当前问题"的搜索结果,撰写详细完备的回复,优先回答"当前问题"。
17
+
18
+ """
19
+
20
+ searcher_system_prompt_en = """## Character Introduction
21
+ You are an intelligent assistant that can call web search tools. Please collect information and reply to the question based on the current problem. You can use the following tools:
22
+ {tool_info}
23
+ ## Reply Format
24
+
25
+ When calling the tool, please follow the format below:
26
+ ```
27
+ Your thought process...<|action_start|><|plugin|>{{"name": "tool_name", "parameters": {{"param1": "value1"}}}}<|action_end|>
28
+ ```
29
+
30
+ ## Requirements
31
+
32
+ - Each key point in the response should be marked with the source of the search results to ensure the credibility of the information. The citation format is `[[int]]`. If there are multiple citations, use multiple [[]] to provide the index, such as `[[id_1]][[id_2]]`.
33
+ - Based on the search results of the "current problem", write a detailed and complete reply to answer the "current problem".
34
+ """
35
+
36
+ fewshot_example_cn = """
37
+ ## 样例
38
+
39
+ ### search
40
+ 当我希望搜索"王者荣耀现在是什么赛季"时,我会按照以下格式进行操作:
41
+ 现在是2024年,因此我应该搜索王者荣耀赛季关键词<|action_start|><|plugin|>{{"name": "FastWebBrowser.search", "parameters": {{"query": ["王者荣耀 赛季", "2024年王者荣耀赛季"]}}}}<|action_end|>
42
+
43
+ ### select
44
+ 为了找到王者荣耀s36赛季最强射手,我需要寻找提及王者荣耀s36射手的网页。初步浏览网页后,发现网页0提到王者荣耀s36赛季的信息,但没有具体提及射手的相关信息。网页3提到“s36最强射手出现?”,有可能包含最强射手信息。网页13提到“四大T0英雄崛起,射手荣耀降临”,可能包含最强射手的信息。因此,我选择了网页3和网页13进行进一步阅读。<|action_start|><|plugin|>{{"name": "FastWebBrowser.select", "parameters": {{"index": [3, 13]}}}}<|action_end|>
45
+ """
46
+
47
+ fewshot_example_en = """
48
+ ## Example
49
+
50
+ ### search
51
+ When I want to search for "What season is Honor of Kings now", I will operate in the following format:
52
+ Now it is 2024, so I should search for the keyword of the Honor of Kings<|action_start|><|plugin|>{{"name": "FastWebBrowser.search", "parameters": {{"query": ["Honor of Kings Season", "season for Honor of Kings in 2024"]}}}}<|action_end|>
53
+
54
+ ### select
55
+ In order to find the strongest shooters in Honor of Kings in season s36, I needed to look for web pages that mentioned shooters in Honor of Kings in season s36. After an initial browse of the web pages, I found that web page 0 mentions information about Honor of Kings in s36 season, but there is no specific mention of information about the shooter. Webpage 3 mentions that “the strongest shooter in s36 has appeared?”, which may contain information about the strongest shooter. Webpage 13 mentions “Four T0 heroes rise, archer's glory”, which may contain information about the strongest archer. Therefore, I chose webpages 3 and 13 for further reading.<|action_start|><|plugin|>{{"name": "FastWebBrowser.select", "parameters": {{"index": [3, 13]}}}}<|action_end|>
56
+ """
57
+
58
+ searcher_input_template_en = """## Final Problem
59
+ {topic}
60
+ ## Current Problem
61
+ {question}
62
+ """
63
+
64
+ searcher_input_template_cn = """## 主问题
65
+ {topic}
66
+ ## 当前问题
67
+ {question}
68
+ """
69
+
70
+ searcher_context_template_en = """## Historical Problem
71
+ {question}
72
+ Answer: {answer}
73
+ """
74
+
75
+ searcher_context_template_cn = """## 历史问题
76
+ {question}
77
+ 回答:{answer}
78
+ """
79
+
80
+ search_template_cn = '## {query}\n\n{result}\n'
81
+ search_template_en = '## {query}\n\n{result}\n'
82
+
83
+ GRAPH_PROMPT_CN = """## 人物简介
84
+ 你是一个可以利用 Jupyter 环境 Python 编程的程序员。你可以利用提供的 API 来构建 Web 搜索图,最终生成代码并执行。
85
+
86
+ ## API 介绍
87
+
88
+ 下面是包含属性详细说明的 `WebSearchGraph` 类的 API 文档:
89
+
90
+ ### 类:`WebSearchGraph`
91
+
92
+ 此类用于管理网络搜索图的节点和边,并通过网络代理进行搜索。
93
+
94
+ #### 初始化方法
95
+
96
+ 初始化 `WebSearchGraph` 实例。
97
+
98
+ **属性:**
99
+
100
+ - `nodes` (Dict[str, Dict[str, str]]): 存储图中所有节点的字典。每个节点由其名称索引,并包含内容、类型以及其他相关信息。
101
+ - `adjacency_list` (Dict[str, List[str]]): 存储图中所有节点之间连接关系的邻接表。每个节点由其名称索引,并包含一个相邻节点名称的列表。
102
+
103
+
104
+ #### 方法:`add_root_node`
105
+
106
+ 添加原始问题作为根节点。
107
+ **参数:**
108
+
109
+ - `node_content` (str): 用户提出的问题。
110
+ - `node_name` (str, 可选): 节点名称,默认为 'root'。
111
+
112
+
113
+ #### 方法:`add_node`
114
+
115
+ 添加搜索子问题节点并返回搜索结果。
116
+ **参数:
117
+
118
+ - `node_name` (str): 节点名称。
119
+ - `node_content` (str): 子问题内容。
120
+
121
+ **返回:**
122
+
123
+ - `str`: 返回搜索结果。
124
+
125
+
126
+ #### 方法:`add_response_node`
127
+
128
+ 当前获取的信息已经满足问题需求,添加回复节点。
129
+
130
+ **参数:**
131
+
132
+ - `node_name` (str, 可选): 节点名称,默认为 'response'。
133
+
134
+
135
+ #### 方法:`add_edge`
136
+
137
+ 添加边。
138
+
139
+ **参数:**
140
+
141
+ - `start_node` (str): 起始节点名称。
142
+ - `end_node` (str): 结束节点名称。
143
+
144
+
145
+ #### 方法:`reset`
146
+
147
+ 重置节点和边。
148
+
149
+
150
+ #### 方法:`node`
151
+
152
+ 获取节点信息。
153
+
154
+ ```python
155
+ def node(self, node_name: str) -> str
156
+ ```
157
+
158
+ **参数:**
159
+
160
+ - `node_name` (str): 节点名称。
161
+
162
+ **返回:**
163
+
164
+ - `str`: 返回包含节点信息的字典,包含节点的内容、类型、思考过程(如果有)和前驱节点列表。
165
+
166
+ ## 任务介绍
167
+ 通过将一个问题拆分成能够通过搜索回答的子问题(没有关联的问题可以同步并列搜索),每个搜索的问题应该是一个单一问题,即单个具体人、事、物、具体时间点、地点或知识点的问题,不是一个复合问题(比如某个时间段), 一步步构建搜索图,最终回答问题。
168
+
169
+ ## 注意事项
170
+
171
+ 1. 注意,每个搜索节点的内容必须单个问题,不要包含多个问题(比如同时问多个知识点的问题或者多个事物的比较加筛选,类似 A, B, C 有什么区别,那个价格在哪个区间 -> 分别查询)
172
+ 2. 不要杜撰搜索结果,要等待代码返回结果
173
+ 3. 同样的问题不要重复提问,可以在已有问题的基础上继续提问
174
+ 4. 添加 response 节点的时候,要单独添加,不要和其他节点一起添加,不能同时添加 response 节点和其他节点
175
+ 5. 一次输出中,不要包含多个代码块,每次只能有一个代码块
176
+ 6. 每个代码块应该放置在一个代码块标记中,同时生成完代码后添加一个<|action_end|>标志,如下所示:
177
+ <|action_start|><|interpreter|>```python
178
+ # 你的代码块
179
+ ```<|action_end|>
180
+ 7. 最后一次回复应该是添加node_name为'response'的 response 节点,必须添加 response 节点,不要添加其他节点
181
+ """
182
+
183
+ GRAPH_PROMPT_EN = """## Character Profile
184
+ You are a programmer capable of Python programming in a Jupyter environment. You can utilize the provided API to construct a Web Search Graph, ultimately generating and executing code.
185
+
186
+ ## API Description
187
+
188
+ Below is the API documentation for the WebSearchGraph class, including detailed attribute descriptions:
189
+
190
+ ### Class: WebSearchGraph
191
+
192
+ This class manages nodes and edges of a web search graph and conducts searches via a web proxy.
193
+
194
+ #### Initialization Method
195
+
196
+ Initializes an instance of WebSearchGraph.
197
+
198
+ **Attributes:**
199
+
200
+ - nodes (Dict[str, Dict[str, str]]): A dictionary storing all nodes in the graph. Each node is indexed by its name and contains content, type, and other related information.
201
+ - adjacency_list (Dict[str, List[str]]): An adjacency list storing the connections between all nodes in the graph. Each node is indexed by its name and contains a list of adjacent node names.
202
+
203
+ #### Method: add_root_node
204
+
205
+ Adds the initial question as the root node.
206
+ **Parameters:**
207
+
208
+ - node_content (str): The user's question.
209
+ - node_name (str, optional): The node name, default is 'root'.
210
+
211
+ #### Method: add_node
212
+
213
+ Adds a sub-question node and returns search results.
214
+ **Parameters:**
215
+
216
+ - node_name (str): The node name.
217
+ - node_content (str): The sub-question content.
218
+
219
+ **Returns:**
220
+
221
+ - str: Returns the search results.
222
+
223
+ #### Method: add_response_node
224
+
225
+ Adds a response node when the current information satisfies the question's requirements.
226
+
227
+ **Parameters:**
228
+
229
+ - node_name (str, optional): The node name, default is 'response'.
230
+
231
+ #### Method: add_edge
232
+
233
+ Adds an edge.
234
+
235
+ **Parameters:**
236
+
237
+ - start_node (str): The starting node name.
238
+ - end_node (str): The ending node name.
239
+
240
+ #### Method: reset
241
+
242
+ Resets nodes and edges.
243
+
244
+ #### Method: node
245
+
246
+ Get node information.
247
+
248
+ python
249
+ def node(self, node_name: str) -> str
250
+
251
+ **Parameters:**
252
+
253
+ - node_name (str): The node name.
254
+
255
+ **Returns:**
256
+
257
+ - str: Returns a dictionary containing the node's information, including content, type, thought process (if any), and list of predecessor nodes.
258
+
259
+ ## Task Description
260
+ By breaking down a question into sub-questions that can be answered through searches (unrelated questions can be searched concurrently), each search query should be a single question focusing on a specific person, event, object, specific time point, location, or knowledge point. It should not be a compound question (e.g., a time period). Step by step, build the search graph to finally answer the question.
261
+
262
+ ## Considerations
263
+
264
+ 1. Each search node's content must be a single question; do not include multiple questions (e.g., do not ask multiple knowledge points or compare and filter multiple things simultaneously, like asking for differences between A, B, and C, or price ranges -> query each separately).
265
+ 2. Do not fabricate search results; wait for the code to return results.
266
+ 3. Do not repeat the same question; continue asking based on existing questions.
267
+ 4. When adding a response node, add it separately; do not add a response node and other nodes simultaneously.
268
+ 5. In a single output, do not include multiple code blocks; only one code block per output.
269
+ 6. Each code block should be placed within a code block marker, and after generating the code, add an <|action_end|> tag as shown below:
270
+ <|action_start|><|interpreter|>
271
+ ```python
272
+ # Your code block (Note that the 'Get new added node information' logic must be added at the end of the code block, such as 'graph.node('...')')
273
+ ```<|action_end|>
274
+ 7. The final response should add a response node with node_name 'response', and no other nodes should be added.
275
+ """
276
+
277
+ graph_fewshot_example_cn = """
278
+ ## 返回格式示例
279
+ <|action_start|><|interpreter|>```python
280
+ graph = WebSearchGraph()
281
+ graph.add_root_node(node_content="哪家大模型API最便宜?", node_name="root") # 添加原始问题作为根节点
282
+ graph.add_node(
283
+ node_name="大模型API提供商", # 节点名称最好有意义
284
+ node_content="目前有哪些主要的大模型API提供商?")
285
+ graph.add_node(
286
+ node_name="sub_name_2", # 节点名称最好有意义
287
+ node_content="content of sub_name_2")
288
+ ...
289
+ graph.add_edge(start_node="root", end_node="sub_name_1")
290
+ ...
291
+ graph.node("大模型API提供商"), graph.node("sub_name_2"), ...
292
+ ```<|action_end|>
293
+ """
294
+
295
+ graph_fewshot_example_en = """
296
+ ## Response Format
297
+ <|action_start|><|interpreter|>```python
298
+ graph = WebSearchGraph()
299
+ graph.add_root_node(node_content="Which large model API is the cheapest?", node_name="root") # Add the original question as the root node
300
+ graph.add_node(
301
+ node_name="Large Model API Providers", # The node name should be meaningful
302
+ node_content="Who are the main large model API providers currently?")
303
+ graph.add_node(
304
+ node_name="sub_name_2", # The node name should be meaningful
305
+ node_content="content of sub_name_2")
306
+ ...
307
+ graph.add_edge(start_node="root", end_node="sub_name_1")
308
+ ...
309
+ # Get node info
310
+ graph.node("Large Model API Providers"), graph.node("sub_name_2"), ...
311
+ ```<|action_end|>
312
+ """
313
+
314
+ FINAL_RESPONSE_CN = """基于提供的问答对,撰写一篇详细完备的最终回答。
315
+ - 回答内容需要逻辑清晰,层次分明,确保读者易于理解。
316
+ - 回答中每个关键点需标注引用的搜索结果来源(保持跟问答对中的索引一致),以确保信息的可信度。给出索引的形式为`[[int]]`,如果有多个索引,则用多个[[]]表示,如`[[id_1]][[id_2]]`。
317
+ - 回答部分需要全面且完备,不要出现"基于上述内容"等模糊表达,最终呈现的回答不包括提供给你的问答对。
318
+ - 语言风格需要专业、严谨,避免口语化表达。
319
+ - 保持统一的语法和词汇使用,确保整体文档的一致性和连贯性。"""
320
+
321
+ FINAL_RESPONSE_EN = """Based on the provided Q&A pairs, write a detailed and comprehensive final response.
322
+ - The response content should be logically clear and well-structured to ensure reader understanding.
323
+ - Each key point in the response should be marked with the source of the search results (consistent with the indices in the Q&A pairs) to ensure information credibility. The index is in the form of `[[int]]`, and if there are multiple indices, use multiple `[[]]`, such as `[[id_1]][[id_2]]`.
324
+ - The response should be comprehensive and complete, without vague expressions like "based on the above content". The final response should not include the Q&A pairs provided to you.
325
+ - The language style should be professional and rigorous, avoiding colloquial expressions.
326
+ - Maintain consistent grammar and vocabulary usage to ensure overall document consistency and coherence."""
mindsearch/agent/models.py ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ from lagent.llms import (GPTAPI, INTERNLM2_META, HFTransformerCasualLM,
4
+ LMDeployClient, LMDeployServer)
5
+
6
+ internlm_server = dict(type=LMDeployServer,
7
+ path='internlm/internlm2_5-7b-chat',
8
+ model_name='internlm2',
9
+ meta_template=INTERNLM2_META,
10
+ top_p=0.8,
11
+ top_k=1,
12
+ temperature=0,
13
+ max_new_tokens=8192,
14
+ repetition_penalty=1.02,
15
+ stop_words=['<|im_end|>'])
16
+
17
+ internlm_client = dict(type=LMDeployClient,
18
+ model_name='internlm2_5-7b-chat',
19
+ url='http://127.0.0.1:23333',
20
+ meta_template=INTERNLM2_META,
21
+ top_p=0.8,
22
+ top_k=1,
23
+ temperature=0,
24
+ max_new_tokens=8192,
25
+ repetition_penalty=1.02,
26
+ stop_words=['<|im_end|>'])
27
+
28
+ internlm_hf = dict(type=HFTransformerCasualLM,
29
+ path='internlm/internlm2_5-7b-chat',
30
+ meta_template=INTERNLM2_META,
31
+ top_p=0.8,
32
+ top_k=None,
33
+ temperature=1e-6,
34
+ max_new_tokens=8192,
35
+ repetition_penalty=1.02,
36
+ stop_words=['<|im_end|>'])
37
+
38
+ gpt4 = dict(type=GPTAPI,
39
+ model_type='gpt-4-turbo',
40
+ key=os.environ.get('OPENAI_API_KEY', 'YOUR OPENAI API KEY'))
mindsearch/app.py ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
+ import json
3
+ import logging
4
+ from copy import deepcopy
5
+ from dataclasses import asdict
6
+ from typing import Dict, List, Union
7
+
8
+ import janus
9
+ from fastapi import FastAPI
10
+ from fastapi.middleware.cors import CORSMiddleware
11
+ from lagent.schema import AgentStatusCode
12
+ from pydantic import BaseModel
13
+ from sse_starlette.sse import EventSourceResponse
14
+
15
+ from mindsearch.agent import init_agent
16
+
17
+
18
+ def parse_arguments():
19
+ import argparse
20
+ parser = argparse.ArgumentParser(description='MindSearch API')
21
+ parser.add_argument('--lang', default='cn', type=str, help='Language')
22
+ parser.add_argument('--model_format',
23
+ default='internlm_server',
24
+ type=str,
25
+ help='Model format')
26
+ return parser.parse_args()
27
+
28
+
29
+ args = parse_arguments()
30
+ app = FastAPI(docs_url='/')
31
+
32
+ app.add_middleware(CORSMiddleware,
33
+ allow_origins=['*'],
34
+ allow_credentials=True,
35
+ allow_methods=['*'],
36
+ allow_headers=['*'])
37
+
38
+
39
+ class GenerationParams(BaseModel):
40
+ inputs: Union[str, List[Dict]]
41
+ agent_cfg: Dict = dict()
42
+
43
+
44
+ @app.post('/solve')
45
+ async def run(request: GenerationParams):
46
+
47
+ def convert_adjacency_to_tree(adjacency_input, root_name):
48
+
49
+ def build_tree(node_name):
50
+ node = {'name': node_name, 'children': []}
51
+ if node_name in adjacency_input:
52
+ for child in adjacency_input[node_name]:
53
+ child_node = build_tree(child['name'])
54
+ child_node['state'] = child['state']
55
+ child_node['id'] = child['id']
56
+ node['children'].append(child_node)
57
+ return node
58
+
59
+ return build_tree(root_name)
60
+
61
+ async def generate():
62
+ try:
63
+ queue = janus.Queue()
64
+
65
+ # 使用 run_in_executor 将同步生成器包装成异步生成器
66
+ def sync_generator_wrapper():
67
+ try:
68
+ for response in agent.stream_chat(inputs):
69
+ queue.sync_q.put(response)
70
+ except Exception as e:
71
+ logging.exception(
72
+ f'Exception in sync_generator_wrapper: {e}')
73
+ finally:
74
+ # 确保在发生异常时队列中的所有元素都被消费
75
+ queue.sync_q.put(None)
76
+
77
+ async def async_generator_wrapper():
78
+ loop = asyncio.get_event_loop()
79
+ loop.run_in_executor(None, sync_generator_wrapper)
80
+ while True:
81
+ response = await queue.async_q.get()
82
+ if response is None: # 确保消费完所有元素
83
+ break
84
+ yield response
85
+ if not isinstance(
86
+ response,
87
+ tuple) and response.state == AgentStatusCode.END:
88
+ break
89
+
90
+ async for response in async_generator_wrapper():
91
+ if isinstance(response, tuple):
92
+ agent_return, node_name = response
93
+ else:
94
+ agent_return = response
95
+ node_name = None
96
+ origin_adj = deepcopy(agent_return.adjacency_list)
97
+ adjacency_list = convert_adjacency_to_tree(
98
+ agent_return.adjacency_list, 'root')
99
+ assert adjacency_list[
100
+ 'name'] == 'root' and 'children' in adjacency_list
101
+ agent_return.adjacency_list = adjacency_list['children']
102
+ agent_return = asdict(agent_return)
103
+ agent_return['adj'] = origin_adj
104
+ response_json = json.dumps(dict(response=agent_return,
105
+ current_node=node_name),
106
+ ensure_ascii=False)
107
+ yield {'data': response_json}
108
+ # yield f'data: {response_json}\n\n'
109
+ except Exception as exc:
110
+ msg = 'An error occurred while generating the response.'
111
+ logging.exception(msg)
112
+ response_json = json.dumps(
113
+ dict(error=dict(msg=msg, details=str(exc))),
114
+ ensure_ascii=False)
115
+ yield {'data': response_json}
116
+ # yield f'data: {response_json}\n\n'
117
+ finally:
118
+ queue.close()
119
+ await queue.wait_closed()
120
+
121
+ inputs = request.inputs
122
+ agent = init_agent(lang=args.lang, model_format=args.model_format)
123
+ return EventSourceResponse(generate())
124
+
125
+
126
+ if __name__ == '__main__':
127
+ import uvicorn
128
+ uvicorn.run(app, host='0.0.0.0', port=8002, log_level='info')
mindsearch/terminal.py ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from datetime import datetime
2
+
3
+ from lagent.actions import ActionExecutor, BingBrowser
4
+ from lagent.llms import INTERNLM2_META, LMDeployServer
5
+
6
+ from mindsearch.agent.mindsearch_agent import (MindSearchAgent,
7
+ MindSearchProtocol)
8
+ from mindsearch.agent.mindsearch_prompt import (
9
+ FINAL_RESPONSE_CN, FINAL_RESPONSE_EN, GRAPH_PROMPT_CN, GRAPH_PROMPT_EN,
10
+ searcher_context_template_cn, searcher_context_template_en,
11
+ searcher_input_template_cn, searcher_input_template_en,
12
+ searcher_system_prompt_cn, searcher_system_prompt_en)
13
+
14
+ lang = 'cn'
15
+ llm = LMDeployServer(path='internlm/internlm2_5-7b-chat',
16
+ model_name='internlm2',
17
+ meta_template=INTERNLM2_META,
18
+ top_p=0.8,
19
+ top_k=1,
20
+ temperature=0,
21
+ max_new_tokens=8192,
22
+ repetition_penalty=1.02,
23
+ stop_words=['<|im_end|>'])
24
+
25
+ agent = MindSearchAgent(
26
+ llm=llm,
27
+ protocol=MindSearchProtocol(
28
+ meta_prompt=datetime.now().strftime('The current date is %Y-%m-%d.'),
29
+ interpreter_prompt=GRAPH_PROMPT_CN
30
+ if lang == 'cn' else GRAPH_PROMPT_EN,
31
+ response_prompt=FINAL_RESPONSE_CN
32
+ if lang == 'cn' else FINAL_RESPONSE_EN),
33
+ searcher_cfg=dict(
34
+ llm=llm,
35
+ plugin_executor=ActionExecutor(
36
+ BingBrowser(searcher_type='DuckDuckGoSearch', topk=6)),
37
+ protocol=MindSearchProtocol(
38
+ meta_prompt=datetime.now().strftime(
39
+ 'The current date is %Y-%m-%d.'),
40
+ plugin_prompt=searcher_system_prompt_cn
41
+ if lang == 'cn' else searcher_system_prompt_en,
42
+ ),
43
+ template=dict(input=searcher_input_template_cn
44
+ if lang == 'cn' else searcher_input_template_en,
45
+ context=searcher_context_template_cn
46
+ if lang == 'cn' else searcher_context_template_en)),
47
+ max_turn=10)
48
+
49
+ for agent_return in agent.stream_chat('上海今天适合穿什么衣服'):
50
+ pass
requirements.txt ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ flask
2
+ duckduckgo_search==5.3.1b1
3
+ einops
4
+ fastapi
5
+ git+https://github.com/InternLM/lagent.git
6
+ gradio
7
+ janus
8
+ lmdeploy==0.2.3
9
+ pyvis
10
+ sse-starlette
11
+ termcolor
12
+ uvicorn