fmode-ng 0.0.113 → 0.0.115
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +8 -0
- package/README.md +37 -37
- package/esm2022/fmode-ng.mjs +10 -5
- package/esm2022/lib/aigc/agent/fm-agent-task/fm-agent-task.component.mjs +8 -92
- package/esm2022/lib/aigc/agent/index.mjs +10 -3
- package/esm2022/lib/aigc/avatar/avatar.module.mjs +10 -45
- package/esm2022/lib/aigc/avatar/comp-avatar-particle/avatar.role.mjs +10 -2
- package/esm2022/lib/aigc/avatar/comp-avatar-particle/comp-avatar-particle.component.mjs +10 -315
- package/esm2022/lib/aigc/avatar/comp-avatar-particle/index.mjs +10 -3
- package/esm2022/lib/aigc/avatar/comp-avatar-particle/role-points.class.mjs +10 -57
- package/esm2022/lib/aigc/avatar/comp-avatar-role-image/comp-avatar-role-image.component.mjs +10 -98
- package/esm2022/lib/aigc/avatar/comp-avatar-role-video/comp-avatar-role-video.component.mjs +10 -107
- package/esm2022/lib/aigc/avatar/comp-avatar-talk/comp-avatar-talk.component.mjs +10 -113
- package/esm2022/lib/aigc/avatar/index.mjs +10 -8
- package/esm2022/lib/aigc/avatar/interface-avatar-role.mjs +10 -2
- package/esm2022/lib/aigc/avatar/modal-chat-voice-input/modal-chat-voice-input.component.mjs +8 -164
- package/esm2022/lib/aigc/chat/chat-header-area/comp-header-area.component.mjs +10 -49
- package/esm2022/lib/aigc/chat/chat-header-area/index.mjs +10 -2
- package/esm2022/lib/aigc/chat/chat-list/chat-list.component.mjs +8 -155
- package/esm2022/lib/aigc/chat/chat-list/index.mjs +10 -2
- package/esm2022/lib/aigc/chat/chat-message-area/comp-message-area.component.mjs +10 -40
- package/esm2022/lib/aigc/chat/chat-message-area/index.mjs +10 -2
- package/esm2022/lib/aigc/chat/chat-message-card/comp-message-card.component.mjs +10 -140
- package/esm2022/lib/aigc/chat/chat-message-card/duration-str.pipe.mjs +10 -29
- package/esm2022/lib/aigc/chat/chat-message-card/index.mjs +10 -3
- package/esm2022/lib/aigc/chat/chat-modal-input/index.mjs +10 -3
- package/esm2022/lib/aigc/chat/chat-modal-input/modal-audio-message/modal-audio-message.component.mjs +8 -193
- package/esm2022/lib/aigc/chat/chat-modal-input/modal-input.component.mjs +10 -331
- package/esm2022/lib/aigc/chat/chat-panel/chat-panel.component.mjs +8 -249
- package/esm2022/lib/aigc/chat/comp-role-prompt/comp-role-prompt.component.mjs +10 -83
- package/esm2022/lib/aigc/chat/comp-role-prompt/index.mjs +10 -2
- package/esm2022/lib/aigc/chat/index.mjs +10 -8
- package/esm2022/lib/aigc/comp-markdown-preview/clipboard.service.mjs +10 -82
- package/esm2022/lib/aigc/comp-markdown-preview/markdown-parse.mjs +8 -367
- package/esm2022/lib/aigc/comp-markdown-preview/markdown-preview.component.mjs +10 -51
- package/esm2022/lib/aigc/comp-markdown-preview/markdown-preview.module.mjs +10 -24
- package/esm2022/lib/aigc/comp-markdown-preview/plugins/md-mathjax/index.mjs +10 -115
- package/esm2022/lib/aigc/index.mjs +10 -14
- package/esm2022/lib/aigc/service-fmai/fmai.service.mjs +10 -21
- package/esm2022/lib/aigc/service-fmai/service-chat/chat-class.mjs +10 -2
- package/esm2022/lib/aigc/service-fmai/service-chat/chat.service.mjs +8 -174
- package/esm2022/lib/aigc/service-fmai/service-chat/index.mjs +10 -7
- package/esm2022/lib/aigc/service-fmai/service-chat/mask-list.mjs +9 -194
- package/esm2022/lib/aigc/service-fmai/service-chat/pipes/chat-content.pipe.mjs +10 -27
- package/esm2022/lib/aigc/service-fmai/service-chat/pipes/hidexml.pipe.mjs +10 -27
- package/esm2022/lib/aigc/service-fmai/service-chat/utilnow.pipe.mjs +10 -68
- package/esm2022/lib/aigc/service-fmai/service-imagine/imagine-func.mjs +9 -162
- package/esm2022/lib/aigc/service-fmai/service-imagine/imagine-work.mjs +10 -68
- package/esm2022/lib/aigc/service-fmai/service-imagine/imagine.service.mjs +8 -313
- package/esm2022/lib/aigc/service-fmai/service-imagine/index.mjs +10 -4
- package/esm2022/lib/aigc/story/fm-office-viewer/fm-office-viewer.component.mjs +10 -62
- package/esm2022/lib/aigc/story/fm-story-card/fm-story-card.component.mjs +10 -87
- package/esm2022/lib/aigc/story/fm-story-list/fm-story-list.component.mjs +10 -345
- package/esm2022/lib/aigc/story/fm-story-list/story-preview.mjs +10 -81
- package/esm2022/lib/aigc/story/fm-story-loader/fm-story-loader.component.mjs +10 -152
- package/esm2022/lib/aigc/story/fm-story-splitter/fm-story-splitter.component.mjs +10 -42
- package/esm2022/lib/aigc/story/index.mjs +10 -6
- package/esm2022/lib/aigc/story/modal-chat-story/comp-chat-story-json/comp-chat-story-json.component.mjs +10 -47
- package/esm2022/lib/aigc/story/modal-chat-story/comp-diary-story/comp-diary-story.component.mjs +10 -95
- package/esm2022/lib/aigc/story/modal-chat-story/modal-chat-story.component.mjs +10 -253
- package/esm2022/lib/aigc/story/story.service.mjs +10 -35
- package/esm2022/lib/aigc/voice/fmode-voice.service.mjs +10 -636
- package/esm2022/lib/aigc/voice/index.mjs +10 -7
- package/esm2022/lib/aigc/voice/lib/audio/audio.player.mjs +10 -55
- package/esm2022/lib/aigc/voice/lib/audio/audio.streamer.mjs +10 -2
- package/esm2022/lib/aigc/voice/lib/audio/streamer.microsoft.mjs +10 -96
- package/esm2022/lib/aigc/voice/lib/audio/streamer.pcm.mjs +8 -177
- package/esm2022/lib/aigc/voice/lib/pcm2wav.mjs +10 -38
- package/esm2022/lib/aigc/voice/lib/recorder/extension-waveview.mjs +10 -215
- package/esm2022/lib/aigc/voice/lib/resample.mjs +10 -34
- package/esm2022/lib/aigc/voice/tts/fmode-tts-class.mjs +10 -189
- package/esm2022/lib/aigc/voice/tts/index.mjs +10 -5
- package/esm2022/lib/aigc/voice/tts/int-tts-provider.mjs +10 -2
- package/esm2022/lib/aigc/voice/tts/provider-doubao.mjs +8 -346
- package/esm2022/lib/code/fm-codemirror/fm-codemirror.component.mjs +8 -342
- package/esm2022/lib/code/index.mjs +10 -2
- package/esm2022/lib/core/agent/chat/completion/fmode-completion.mjs +8 -430
- package/esm2022/lib/core/agent/chat/completion/index.mjs +10 -2
- package/esm2022/lib/core/agent/chat/completion/int-gpt-chat-options.mjs +10 -2
- package/esm2022/lib/core/agent/chat/fmode-chat.mjs +8 -617
- package/esm2022/lib/core/agent/chat/index.mjs +10 -4
- package/esm2022/lib/core/agent/chat/interface.mjs +10 -2
- package/esm2022/lib/core/agent/index.mjs +10 -6
- package/esm2022/lib/core/agent/prompt/agent.prompt.mjs +10 -133
- package/esm2022/lib/core/agent/prompt/index.mjs +10 -2
- package/esm2022/lib/core/agent/prompt/prompt-util.mjs +10 -16
- package/esm2022/lib/core/agent/story/agent.story.mjs +10 -64
- package/esm2022/lib/core/agent/story/index.mjs +10 -2
- package/esm2022/lib/core/agent/task/agent.task.mjs +10 -90
- package/esm2022/lib/core/agent/task/index.mjs +10 -2
- package/esm2022/lib/core/agent/waiting/index.mjs +10 -3
- package/esm2022/lib/core/agent/waiting/loading/loading.ctrl.mjs +10 -279
- package/esm2022/lib/core/agent/waiting/tips/tips.ctrl.mjs +8 -190
- package/esm2022/lib/core/index.mjs +10 -4
- package/esm2022/lib/core/parse/datatype/acl.mjs +10 -57
- package/esm2022/lib/core/parse/datatype/file.mjs +10 -69
- package/esm2022/lib/core/parse/datatype/geopoint.mjs +10 -57
- package/esm2022/lib/core/parse/datatype/relation.mjs +10 -56
- package/esm2022/lib/core/parse/fmode.cloud.mjs +10 -0
- package/esm2022/lib/core/parse/fmode.object.mjs +10 -232
- package/esm2022/lib/core/parse/fmode.parse.mjs +10 -84
- package/esm2022/lib/core/parse/fmode.query.mjs +8 -500
- package/esm2022/lib/core/parse/fmode.user.mjs +10 -275
- package/esm2022/lib/core/parse/index.mjs +10 -5
- package/esm2022/lib/core/parse/types.mjs +10 -2
- package/esm2022/lib/core/voice/index.mjs +10 -3
- package/esm2022/lib/core/voice/tts/index.mjs +10 -2
- package/esm2022/lib/icon/filetype/audio.svg.mjs +10 -3
- package/esm2022/lib/icon/filetype/avatar.svg.mjs +10 -14
- package/esm2022/lib/icon/filetype/chat.svg.mjs +10 -3
- package/esm2022/lib/icon/filetype/docx.svg.mjs +10 -3
- package/esm2022/lib/icon/filetype/file.svg.mjs +10 -3
- package/esm2022/lib/icon/filetype/filetype.pipe.mjs +10 -57
- package/esm2022/lib/icon/filetype/index.mjs +10 -12
- package/esm2022/lib/icon/filetype/md.svg.mjs +10 -3
- package/esm2022/lib/icon/filetype/pdf.svg.mjs +10 -3
- package/esm2022/lib/icon/filetype/pptx.svg.mjs +10 -3
- package/esm2022/lib/icon/filetype/svgtoblob.mjs +10 -8
- package/esm2022/lib/icon/filetype/video.svg.mjs +10 -3
- package/esm2022/lib/icon/filetype/xlsx.svg.mjs +10 -3
- package/esm2022/lib/icon/index.mjs +10 -2
- package/esm2022/lib/map/comp-poi-picker/comp-poi-picker.component.mjs +10 -209
- package/esm2022/lib/map/comp-poi-picker/comp-poi-picker.module.mjs +10 -33
- package/esm2022/lib/map/index.mjs +10 -4
- package/esm2022/lib/map/map.module.mjs +10 -61
- package/esm2022/lib/map/page-loca-scatter/page-loca-scatter.component.mjs +10 -132
- package/esm2022/lib/map/page-map.start/page-map.start.component.mjs +8 -115
- package/esm2022/lib/map/page-plan-route/page-plan-route.component.mjs +8 -118
- package/esm2022/lib/nova-cloud/index.mjs +10 -3
- package/esm2022/lib/nova-cloud/ncloud-api-func.mjs +10 -91
- package/esm2022/lib/nova-cloud/nova-cloud.service.mjs +10 -53
- package/esm2022/lib/payment/index.mjs +10 -2
- package/esm2022/lib/payment/payment/payment.component.mjs +10 -543
- package/esm2022/lib/payment/payment.service.mjs +10 -202
- package/esm2022/lib/person/comp-person-gender-icon/comp-person-gender-icon.component.mjs +10 -48
- package/esm2022/lib/person/comp-person-item/comp-person-item.component.mjs +10 -29
- package/esm2022/lib/person/comp-person-story/comp-person-story.component.mjs +10 -211
- package/esm2022/lib/person/edit-upload/edit-upload.component.mjs +8 -412
- package/esm2022/lib/person/edit-upload/edit-upload.module.mjs +10 -50
- package/esm2022/lib/person/index.mjs +10 -5
- package/esm2022/lib/person/modal-person-select/modal-person-select.component.mjs +10 -144
- package/esm2022/lib/person/modal-user-verify/secret-text.pipe.mjs +10 -41
- package/esm2022/lib/person/modal-user-verify/user-verify.component.mjs +10 -595
- package/esm2022/lib/person/person-detail/person-detail.component.mjs +10 -172
- package/esm2022/lib/person/person.service.mjs +8 -193
- package/esm2022/lib/platform/cross.service.mjs +10 -62
- package/esm2022/lib/platform/index.mjs +10 -2
- package/esm2022/lib/social/index.mjs +10 -2
- package/esm2022/lib/social/wechat/wechat-jssdk.service.mjs +8 -230
- package/esm2022/lib/storage/comp-hwobs-manager/hwobs-manager.component.mjs +10 -59
- package/esm2022/lib/storage/index.mjs +10 -5
- package/esm2022/lib/storage/service-hwobs/hwobs.service.mjs +8 -131
- package/esm2022/lib/storage/service-hwobs/index.mjs +10 -3
- package/esm2022/lib/storage/service-hwobs/typings/esdk-obs-browser.mjs +1 -1
- package/esm2022/lib/storage/service-upload/index.mjs +10 -2
- package/esm2022/lib/storage/service-upload/nova-upload.service.mjs +8 -513
- package/esm2022/lib/storage/service-upload/util-file-md5.mjs +10 -28
- package/esm2022/lib/storage/service-upload/util-file-metadata.mjs +10 -93
- package/esm2022/lib/storage/storage.module.mjs +10 -42
- package/esm2022/lib/text/fm-article-editor/article-editor-topbar/article-editor-topbar.component.mjs +10 -72
- package/esm2022/lib/text/fm-article-editor/article.service.mjs +10 -237
- package/esm2022/lib/text/fm-article-editor/comp-upload-book-banners/comp-upload-book-banners.component.mjs +8 -72
- package/esm2022/lib/text/fm-article-editor/draft.service.mjs +10 -207
- package/esm2022/lib/text/fm-article-editor/fm-article-aitool/fm-article-aitool.component.mjs +8 -227
- package/esm2022/lib/text/fm-article-editor/fm-article-draft/fm-article-draft.component.mjs +10 -303
- package/esm2022/lib/text/fm-article-editor/fm-article-editor.component.mjs +8 -371
- package/esm2022/lib/text/fm-article-editor/fm-article-outline/fm-article-outline.component.mjs +10 -94
- package/esm2022/lib/text/fm-article-editor/fm-article-outline-leftitem/fm-article-outline-leftitem.component.mjs +10 -36
- package/esm2022/lib/text/fm-article-editor/fm-article-preview/fm-article-preview.component.mjs +10 -281
- package/esm2022/lib/text/fm-article-editor/fm-article-write-options/fm-article-write-options.component.mjs +10 -72
- package/esm2022/lib/text/fm-article-editor/outline-count.pipe.mjs +10 -22
- package/esm2022/lib/text/fm-article-editor/prompt/prompt-insertion-article.mjs +10 -169
- package/esm2022/lib/text/fm-article-editor/task-article-generation.mjs +10 -69
- package/esm2022/lib/text/fm-article-editor/tasks/task-article-draft-create.mjs +10 -65
- package/esm2022/lib/text/fm-article-editor/tasks/task-article-outline-edit.mjs +10 -55
- package/esm2022/lib/text/fm-article-editor/tasks/task-article-outline.mjs +10 -142
- package/esm2022/lib/text/fm-article-editor/tasks/task-article-preview.mjs +10 -35
- package/esm2022/lib/text/fm-article-editor/tasks/task-article-writing-options.mjs +10 -81
- package/esm2022/lib/text/fm-article-editor/tasks/task-document-select.mjs +10 -50
- package/esm2022/lib/text/fm-text-quill/fm-text-quill.component.mjs +10 -145
- package/esm2022/lib/text/index.mjs +10 -4
- package/esm2022/lib/user/account/account.service.mjs +10 -222
- package/esm2022/lib/user/captcha/captcha.component.mjs +10 -135
- package/esm2022/lib/user/comp-user-avatar/comp-user-avatar.component.mjs +10 -66
- package/esm2022/lib/user/index.mjs +10 -17
- package/esm2022/lib/user/login/auth.guard.mjs +10 -28
- package/esm2022/lib/user/login/auth.service.mjs +8 -433
- package/esm2022/lib/user/login/login.component.mjs +10 -916
- package/esm2022/lib/user/modal-user-login/modal-user-login.component.mjs +10 -311
- package/esm2022/lib/user/profile/auth-profile.guard.mjs +10 -27
- package/esm2022/lib/user/profile/auth-profile.service.mjs +10 -122
- package/esm2022/lib/user/profile/profile-bind/profile-bind.component.mjs +10 -164
- package/esm2022/lib/user/profile/profile-bind/profile-confirm-modal.component.mjs +10 -79
- package/esm2022/lib/user/profile/profile.module.mjs +10 -54
- package/esm2022/lib/user/staff/index.mjs +10 -4
- package/esm2022/lib/user/staff/staff.guard.mjs +10 -26
- package/esm2022/lib/user/staff/staff.module.mjs +10 -18
- package/esm2022/lib/user/staff/staff.service.mjs +10 -85
- package/esm2022/lib/user/user-name.pipe.mjs +10 -29
- package/esm2022/lib/user/user.module.mjs +10 -102
- package/esm2022/lib/video/fm-video/fm-video.component.mjs +10 -67
- package/esm2022/lib/video/index.mjs +10 -2
- package/esm2022/public-api.mjs +10 -21
- package/fesm2022/fmode-ng.mjs +7 -19788
- package/fesm2022/fmode-ng.mjs.map +1 -1
- package/lib/aigc/avatar/comp-avatar-role-image/comp-avatar-role-image.component.d.ts +2 -2
- package/lib/aigc/avatar/comp-avatar-role-video/comp-avatar-role-video.component.d.ts +2 -2
- package/lib/aigc/avatar/comp-avatar-talk/comp-avatar-talk.component.d.ts +2 -2
- package/lib/aigc/chat/chat-list/chat-list.component.d.ts +3 -2
- package/lib/aigc/chat/chat-message-card/comp-message-card.component.d.ts +3 -3
- package/lib/aigc/chat/chat-modal-input/modal-audio-message/modal-audio-message.component.d.ts +2 -2
- package/lib/aigc/chat/chat-modal-input/modal-input.component.d.ts +3 -3
- package/lib/aigc/service-fmai/service-imagine/imagine-func.d.ts +3 -3
- package/lib/aigc/service-fmai/service-imagine/imagine-work.d.ts +4 -4
- package/lib/aigc/service-fmai/service-imagine/imagine.service.d.ts +6 -6
- package/lib/aigc/story/fm-office-viewer/fm-office-viewer.component.d.ts +2 -2
- package/lib/aigc/story/fm-story-card/fm-story-card.component.d.ts +2 -1
- package/lib/aigc/story/fm-story-list/fm-story-list.component.d.ts +6 -6
- package/lib/aigc/story/fm-story-list/story-preview.d.ts +4 -4
- package/lib/aigc/story/fm-story-loader/fm-story-loader.component.d.ts +3 -3
- package/lib/aigc/story/fm-story-splitter/fm-story-splitter.component.d.ts +2 -2
- package/lib/aigc/story/modal-chat-story/comp-chat-story-json/comp-chat-story-json.component.d.ts +3 -2
- package/lib/aigc/story/modal-chat-story/comp-diary-story/comp-diary-story.component.d.ts +3 -2
- package/lib/aigc/story/modal-chat-story/modal-chat-story.component.d.ts +6 -6
- package/lib/aigc/story/story.service.d.ts +3 -2
- package/lib/aigc/voice/tts/fmode-tts-class.d.ts +2 -2
- package/lib/core/agent/chat/fmode-chat.d.ts +11 -11
- package/lib/core/agent/story/agent.story.d.ts +8 -8
- package/lib/core/parse/datatype/geopoint.d.ts +5 -1
- package/lib/core/parse/fmode.cloud.d.ts +32 -0
- package/lib/core/parse/fmode.object.d.ts +2 -2
- package/lib/core/parse/fmode.parse.d.ts +15 -9
- package/lib/core/parse/fmode.query.d.ts +41 -2
- package/lib/core/parse/fmode.user.d.ts +1 -0
- package/lib/core/parse/index.d.ts +1 -0
- package/lib/core/parse/types.d.ts +2 -0
- package/lib/map/comp-poi-picker/comp-poi-picker.component.d.ts +5 -5
- package/lib/payment/payment/payment.component.d.ts +3 -3
- package/lib/payment/payment.service.d.ts +4 -4
- package/lib/person/comp-person-gender-icon/comp-person-gender-icon.component.d.ts +2 -1
- package/lib/person/comp-person-item/comp-person-item.component.d.ts +2 -1
- package/lib/person/comp-person-story/comp-person-story.component.d.ts +13 -13
- package/lib/person/edit-upload/edit-upload.component.d.ts +1 -1
- package/lib/person/modal-person-select/modal-person-select.component.d.ts +5 -5
- package/lib/person/modal-user-verify/user-verify.component.d.ts +5 -5
- package/lib/person/person-detail/person-detail.component.d.ts +4 -4
- package/lib/person/person.service.d.ts +7 -7
- package/lib/storage/service-hwobs/hwobs.service.d.ts +4 -5
- package/lib/storage/service-upload/nova-upload.service.d.ts +5 -5
- package/lib/text/fm-article-editor/article-editor-topbar/article-editor-topbar.component.d.ts +2 -1
- package/lib/text/fm-article-editor/article.service.d.ts +12 -12
- package/lib/text/fm-article-editor/draft.service.d.ts +5 -5
- package/lib/text/fm-article-editor/fm-article-aitool/fm-article-aitool.component.d.ts +3 -2
- package/lib/text/fm-article-editor/fm-article-draft/fm-article-draft.component.d.ts +16 -17
- package/lib/text/fm-article-editor/fm-article-editor.component.d.ts +3 -3
- package/lib/text/fm-article-editor/fm-article-outline/fm-article-outline.component.d.ts +11 -10
- package/lib/text/fm-article-editor/fm-article-preview/fm-article-preview.component.d.ts +2 -2
- package/lib/text/fm-article-editor/prompt/prompt-insertion-article.d.ts +3 -3
- package/lib/text/fm-article-editor/task-article-generation.d.ts +5 -4
- package/lib/text/fm-article-editor/tasks/task-article-draft-create.d.ts +3 -3
- package/lib/text/fm-article-editor/tasks/task-article-outline-edit.d.ts +3 -3
- package/lib/text/fm-article-editor/tasks/task-article-outline.d.ts +3 -3
- package/lib/text/fm-article-editor/tasks/task-article-preview.d.ts +2 -1
- package/lib/text/fm-article-editor/tasks/task-article-writing-options.d.ts +3 -3
- package/lib/text/fm-article-editor/tasks/task-document-select.d.ts +3 -3
- package/lib/user/account/account.service.d.ts +2 -2
- package/lib/user/comp-user-avatar/comp-user-avatar.component.d.ts +2 -2
- package/lib/user/login/auth.service.d.ts +5 -5
- package/lib/user/login/login.component.d.ts +3 -3
- package/lib/user/profile/auth-profile.service.d.ts +8 -8
- package/lib/user/profile/profile-bind/profile-bind.component.d.ts +7 -7
- package/lib/user/profile/profile-bind/profile-confirm-modal.component.d.ts +2 -2
- package/lib/user/staff/staff.service.d.ts +3 -3
- package/lib/user/user-name.pipe.d.ts +2 -2
- package/package.json +12 -18
|
@@ -1,619 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
// var bufferTime:any, concatMap:any, Observable:any, Observer:any,delay:any, finalize:any,Observer:any
|
|
3
|
-
import Parse from "parse";
|
|
4
|
-
import { FmodeTTS, FmodeTTSProviderDoubao } from "../../voice/tts";
|
|
5
|
-
// import { NavController } from "@ionic/angular";
|
|
6
|
-
import { PromptTemplate } from "@langchain/core/prompts";
|
|
7
|
-
import { getFormatTpl } from "../prompt/prompt-util";
|
|
8
|
-
import { FmodeChatCompletion } from "./completion";
|
|
9
|
-
// import { PromptTemplate } from "./lib/langchain/prompts";
|
|
10
|
-
// import { ElementRef } from "@angular/core";
|
|
11
|
-
// var Parse:any = {}
|
|
12
|
-
const PromptTplTalkSSMLOutputCode = "talk-ssml-output-tpl";
|
|
13
|
-
const PromptTplTalkTextSSMLCode = "talk-text-ssml-tpl";
|
|
14
|
-
export function getMessageContentText(content) {
|
|
15
|
-
let text = "";
|
|
16
|
-
if (typeof content == "string")
|
|
17
|
-
text = content;
|
|
18
|
-
if (typeof content == "object")
|
|
19
|
-
text = content?.find(item => item?.text)?.text || "";
|
|
20
|
-
return text;
|
|
21
|
-
}
|
|
22
|
-
export function getMessageImageUrl(content) {
|
|
23
|
-
if (typeof content == "object")
|
|
24
|
-
return content?.find(item => item?.image_url)?.image_url?.url || "";
|
|
25
|
-
return null;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* FmodeChat 聊天对话类
|
|
29
|
-
* @public
|
|
30
|
-
*/
|
|
31
|
-
export class FmodeChat {
|
|
32
|
-
async loadModelList(model) {
|
|
33
|
-
if (this.modelList?.length)
|
|
34
|
-
return;
|
|
35
|
-
let query = new Parse.Query("ChatModel");
|
|
36
|
-
query.notEqualTo("isDeleted", true);
|
|
37
|
-
query.equalTo("isEnabled", true);
|
|
38
|
-
query.addAscending("index");
|
|
39
|
-
this.modelList = await query.find();
|
|
40
|
-
this.currentModel = model || this.modelList?.find(item => item.get("code") == "fmode-1.6-cn");
|
|
41
|
-
}
|
|
42
|
-
showAvatar() {
|
|
43
|
-
this.avatarConfig = this.role?.get("avatarConfig");
|
|
44
|
-
if (this.avatarConfig) {
|
|
45
|
-
this.isAvatarShow = true;
|
|
46
|
-
if (this.avatarConfig?.image) {
|
|
47
|
-
this.avatarConfig.image.waiting = this.avatarConfig.image.waiting || this.role?.get("thumb") || this.role?.get("avatar");
|
|
48
|
-
this.avatarMode = "image";
|
|
49
|
-
}
|
|
50
|
-
if (this.avatarConfig?.video) {
|
|
51
|
-
this.avatarConfig.video.waiting = this.avatarConfig.video.waiting;
|
|
52
|
-
this.avatarMode = "video";
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
// scrollToBottom:Function;
|
|
57
|
-
scrollToBottom(comp) {
|
|
58
|
-
comp = comp || this.scrollComp;
|
|
59
|
-
// console.log(comp)
|
|
60
|
-
if (comp?.nativeElement?.scrollHeight) {
|
|
61
|
-
comp.nativeElement.scrollTop = comp.nativeElement.scrollHeight;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
constructor(sessionId, role, chatSession, chatServ, navCtrl, //NavController,
|
|
65
|
-
ncloud, uploadServ) {
|
|
66
|
-
this.ChatSession = Parse.Object.extend("ChatSession");
|
|
67
|
-
this.messageList = [{ role: "system", content: "系统提示:AI仅供参考" }];
|
|
68
|
-
this.latestAIResponse = ``;
|
|
69
|
-
this.userInput = ``;
|
|
70
|
-
this.userImage = ``;
|
|
71
|
-
this.isDirect = false;
|
|
72
|
-
this.mode = "page";
|
|
73
|
-
// onUserInput:(chat:FmodeChat,message:FmodeChatMessage)=>boolean|Promise<boolean>
|
|
74
|
-
// 界面功能显示控制
|
|
75
|
-
this.hideShare = false;
|
|
76
|
-
this.hideModalSelect = false;
|
|
77
|
-
this.hideInputPreview = false;
|
|
78
|
-
/**
|
|
79
|
-
* 虚拟形象展示状态
|
|
80
|
-
*/
|
|
81
|
-
this.isAvatarShow = false;
|
|
82
|
-
this.avatarMode = "";
|
|
83
|
-
/**
|
|
84
|
-
* 预置提示词弹窗是否展示
|
|
85
|
-
*/
|
|
86
|
-
this.isPromptModalOpen = false;
|
|
87
|
-
this.isPromptMessageAreaShow = true;
|
|
88
|
-
this.promptList = [];
|
|
89
|
-
/**
|
|
90
|
-
* 输入按钮区域
|
|
91
|
-
*/
|
|
92
|
-
this.focusUserInput = () => { };
|
|
93
|
-
this.leftButtons = [
|
|
94
|
-
// 提示 当角色配置预设提示词时 显示
|
|
95
|
-
{ title: "灵感", icon: "color-wand-outline", onClick: () => {
|
|
96
|
-
this.isPromptModalOpen = true;
|
|
97
|
-
}, show: () => {
|
|
98
|
-
return this?.promptList?.length;
|
|
99
|
-
} },
|
|
100
|
-
{ title: "角色", icon: "people-outline", onClick: () => {
|
|
101
|
-
this.navCtrl?.navigateRoot("/chat/pro/mask");
|
|
102
|
-
}, show: () => { return true; } },
|
|
103
|
-
{ title: "呼叫", icon: "call-outline", onClick: () => {
|
|
104
|
-
this.chatServ?.callRole(this.role);
|
|
105
|
-
}, show: () => {
|
|
106
|
-
return this?.role?.get('voiceConfig');
|
|
107
|
-
} },
|
|
108
|
-
];
|
|
109
|
-
/**
|
|
110
|
-
* 是否开启语音消息模式(单次)
|
|
111
|
-
*/
|
|
112
|
-
this.isVoiceInputMode = false;
|
|
113
|
-
this.isTexting = false;
|
|
114
|
-
this.isTalkMode = false;
|
|
115
|
-
this.SSMLRoleVoice = "zh-CN-XiaoxiaoNeural";
|
|
116
|
-
/**
|
|
117
|
-
* 会话Avatar控制
|
|
118
|
-
*/
|
|
119
|
-
this.playAnimation = (animName) => {
|
|
120
|
-
console.log(animName);
|
|
121
|
-
return;
|
|
122
|
-
};
|
|
123
|
-
this.welcome = async () => {
|
|
124
|
-
let msglist = this.messageList?.filter(item => item?.role == "assistant");
|
|
125
|
-
if (msglist?.length)
|
|
126
|
-
return; // 已有对话不开场问候
|
|
127
|
-
let user = Parse.User.current();
|
|
128
|
-
let person = await this.loadSelf("Person", "userVerify");
|
|
129
|
-
let profile = await this.loadSelf("Profile", "user");
|
|
130
|
-
let personName = person?.get("name") || person?.get("userVefiry")?.get("realname") || person?.get("userVefiry")?.get("nickname");
|
|
131
|
-
let userName = user?.get("nickname") || profile?.get("name") || user?.get("realname") || user?.get("name");
|
|
132
|
-
if (person?.get("userVerify")?.id == user?.id) {
|
|
133
|
-
personName = "您"; // 当本人时,称呼角色为您
|
|
134
|
-
}
|
|
135
|
-
if (!userName) { // 若用户无姓名,则用当前帐号名称做称呼
|
|
136
|
-
userName = personName;
|
|
137
|
-
}
|
|
138
|
-
// 问候语/首个话题
|
|
139
|
-
// 单个问候语直接加载
|
|
140
|
-
let tpl = this.role.get("voiceConfig")?.welcome?.prompt;
|
|
141
|
-
// 多条问候语随即加载
|
|
142
|
-
if (this.role.get("voiceConfig")?.welcome?.promptList?.length) {
|
|
143
|
-
let tplList = this.role.get("voiceConfig")?.welcome?.promptList;
|
|
144
|
-
let randomIndex = Math.floor(Math.random() * tplList.length);
|
|
145
|
-
tpl = tplList[randomIndex];
|
|
146
|
-
}
|
|
147
|
-
if (!tpl)
|
|
148
|
-
return; // 无模板则返回
|
|
149
|
-
let welcomeContent = await PromptTemplate.fromTemplate(tpl, {
|
|
150
|
-
templateFormat: "mustache"
|
|
151
|
-
}).format({
|
|
152
|
-
name: userName, // 用户称呼
|
|
153
|
-
userName: userName, // 用户称呼
|
|
154
|
-
personName: personName, // 角色称呼
|
|
155
|
-
timeOfDay: this.getTimeOfDay()
|
|
156
|
-
});
|
|
157
|
-
// let callName = name?`${name},`:"";
|
|
158
|
-
// let callTime = `${this.getTimeOfDay()}好`;
|
|
159
|
-
// let welcomeContent = `${callName}${callTime},期待聆听您的人生故事,想和我聊些什么呢?`;
|
|
160
|
-
// 生成ChatVoice并播放
|
|
161
|
-
let voice = await this.getVoiceByContentText(welcomeContent);
|
|
162
|
-
let message = {
|
|
163
|
-
role: "assistant",
|
|
164
|
-
voice: voice,
|
|
165
|
-
content: welcomeContent,
|
|
166
|
-
complete: true
|
|
167
|
-
};
|
|
168
|
-
this.voiceMap[voice?.id];
|
|
169
|
-
this.playChatVoice(this.voiceMap[voice?.id]);
|
|
170
|
-
this.messageList.push(message);
|
|
171
|
-
};
|
|
172
|
-
this.self = {};
|
|
173
|
-
this.voiceMap = {};
|
|
174
|
-
this.VoiceTTSMap = {};
|
|
175
|
-
this.chatServ = chatServ;
|
|
176
|
-
this.role = role;
|
|
177
|
-
this.sessionId = sessionId;
|
|
178
|
-
this.navCtrl = navCtrl;
|
|
179
|
-
this.ncloud = ncloud;
|
|
180
|
-
this.uploadServ = uploadServ;
|
|
181
|
-
if (chatSession?.id) {
|
|
182
|
-
this.chatSession = chatSession;
|
|
183
|
-
this.messageList = this.chatSession.get("messageList");
|
|
184
|
-
this.sessionId = chatSession?.id;
|
|
185
|
-
}
|
|
186
|
-
if (this.role?.id) {
|
|
187
|
-
this.voiceConfig = this.role?.get("voiceConfig");
|
|
188
|
-
if (this.voiceConfig?.autoTalk) {
|
|
189
|
-
this.isTalkMode = this.isTalkMode || this.voiceConfig?.autoTalk;
|
|
190
|
-
this.isDirect = true;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
getTimeOfDay() {
|
|
195
|
-
const now = new Date();
|
|
196
|
-
const hours = now.getHours();
|
|
197
|
-
if (hours >= 5 && hours < 12) {
|
|
198
|
-
return "早上";
|
|
199
|
-
}
|
|
200
|
-
else if (hours >= 12 && hours < 14) {
|
|
201
|
-
return "中午";
|
|
202
|
-
}
|
|
203
|
-
else if (hours >= 14 && hours < 18) {
|
|
204
|
-
return "下午";
|
|
205
|
-
}
|
|
206
|
-
else {
|
|
207
|
-
return "晚上";
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
async loadSelf(className, userKey) {
|
|
211
|
-
if (this.self[className])
|
|
212
|
-
return this.self[className];
|
|
213
|
-
let user = Parse.User.current();
|
|
214
|
-
let query = new Parse.Query(className);
|
|
215
|
-
query.include(userKey);
|
|
216
|
-
query.equalTo(userKey, user?.id);
|
|
217
|
-
this.self[className] = await query.first();
|
|
218
|
-
return this.self[className];
|
|
219
|
-
}
|
|
1
|
+
|
|
220
2
|
/**
|
|
221
|
-
*
|
|
3
|
+
* @copyright © 未来飞马 © 未来全栈 www.fmode.cn
|
|
4
|
+
* 版权所有 © 未来飞马 © 江西脑控科技有限公司 Copyright © Fmode Technology Co., Ltd.
|
|
5
|
+
* 保留所有权利 All Rights Reserved.
|
|
6
|
+
* /home/ryan/workspace/nova/nova-admin/dist/fmode-ng/esm2022/lib/core/agent/chat/fmode-chat.mjs
|
|
222
7
|
*/
|
|
223
|
-
async loadTalkSystemPrompt(role) {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
if (!role)
|
|
227
|
-
return;
|
|
228
|
-
let voiceConfig = role?.get("voiceConfig");
|
|
229
|
-
// 加载声音模型:默认为晓晓
|
|
230
|
-
if (role?.get('gender') == '男') {
|
|
231
|
-
this.SSMLRoleVoice = "zh-CN-YunyeNeural";
|
|
232
|
-
if (voiceConfig.provider == "doubao") {
|
|
233
|
-
this.SSMLRoleVoice = "zh_male_yangguangqingnian_emo_v2_mars_bigtts";
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
else {
|
|
237
|
-
this.SSMLRoleVoice = "zh-CN-XiaoxiaoNeural";
|
|
238
|
-
if (voiceConfig.provider == "doubao") {
|
|
239
|
-
this.SSMLRoleVoice = "zh_female_shuangkuaisisi_emo_v2_mars_bigtts";
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
this.SSMLRoleVoice = role?.get("voiceConfig")?.voice || this.SSMLRoleVoice;
|
|
243
|
-
let SSMLPromptTemplate = await getFormatTpl(PromptTplTalkSSMLOutputCode, {
|
|
244
|
-
SSMLRoleVoice: this.SSMLRoleVoice, // SSML
|
|
245
|
-
});
|
|
246
|
-
let prompt = role.get("prompt") || "请你扮演飞码AI的人工智能专家。";
|
|
247
|
-
prompt += SSMLPromptTemplate;
|
|
248
|
-
let promptMsg = { role: "user", content: prompt, hidden: true };
|
|
249
|
-
// 查重
|
|
250
|
-
let content = this.messageList?.map(item => item?.content).join();
|
|
251
|
-
if (content.indexOf(prompt) > -1) {
|
|
252
|
-
// 提示词已经存在
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
255
|
-
// 补全提示词
|
|
256
|
-
let systemIndex = this.messageList?.findIndex(item => item?.role == "system");
|
|
257
|
-
let insertIndex = systemIndex + 1;
|
|
258
|
-
this.messageList.splice(insertIndex, 0, promptMsg);
|
|
259
|
-
return;
|
|
260
|
-
}
|
|
261
|
-
/**
|
|
262
|
-
* 角色提示词
|
|
263
|
-
* @returns
|
|
264
|
-
*/
|
|
265
|
-
loadRolePrompt() {
|
|
266
|
-
// 角色提示
|
|
267
|
-
let prompt = this.role?.get("prompt");
|
|
268
|
-
let promptMsg = { role: "user", content: prompt, hidden: true };
|
|
269
|
-
if (!prompt)
|
|
270
|
-
return; // 无提示词无需添加
|
|
271
|
-
// 内容检查
|
|
272
|
-
let content = this.messageList?.map(item => item?.content).join();
|
|
273
|
-
if (content.indexOf(prompt) > -1) {
|
|
274
|
-
// 提示词已经存在
|
|
275
|
-
return;
|
|
276
|
-
}
|
|
277
|
-
// 补全提示词
|
|
278
|
-
let systemIndex = this.messageList?.findIndex(item => item?.role == "system");
|
|
279
|
-
let insertIndex = systemIndex + 1;
|
|
280
|
-
this.messageList.splice(insertIndex, 0, promptMsg);
|
|
281
|
-
// console.log(this.messageList)
|
|
282
|
-
}
|
|
283
|
-
/**
|
|
284
|
-
* 发送消息
|
|
285
|
-
* @param message
|
|
286
|
-
* @param imageUrl
|
|
287
|
-
*/
|
|
288
|
-
async sendMessage(message = "FmodeAiTest测试问题", imageUrl, onComplete, eventMap, voice) {
|
|
289
|
-
// 发消息自动置底
|
|
290
|
-
this.scrollToBottom && this.scrollToBottom();
|
|
291
|
-
// 为消息列表补全提示词
|
|
292
|
-
// await this.loadTalkSystemPrompt(this.role);
|
|
293
|
-
this.isPromptMessageAreaShow = false; // 发送第一条消息后,关闭提示看板
|
|
294
|
-
this.loadRolePrompt();
|
|
295
|
-
// 用户输入消息,添加到历史消息清单中
|
|
296
|
-
if (!imageUrl) { // 纯文本
|
|
297
|
-
// console.log("纯文本")
|
|
298
|
-
let msg = {
|
|
299
|
-
role: "user",
|
|
300
|
-
content: message,
|
|
301
|
-
complete: true,
|
|
302
|
-
createdAt: new Date()
|
|
303
|
-
};
|
|
304
|
-
if (voice) {
|
|
305
|
-
msg.voice = { id: voice?.id, duration: voice?.duration };
|
|
306
|
-
}
|
|
307
|
-
this.messageList.push(msg);
|
|
308
|
-
}
|
|
309
|
-
else { // 带图片
|
|
310
|
-
let msg = {
|
|
311
|
-
"role": "user",
|
|
312
|
-
"content": [
|
|
313
|
-
{
|
|
314
|
-
"type": "image_url",
|
|
315
|
-
"image_url": { "url": imageUrl },
|
|
316
|
-
},
|
|
317
|
-
{
|
|
318
|
-
"type": "text",
|
|
319
|
-
"text": message
|
|
320
|
-
},
|
|
321
|
-
],
|
|
322
|
-
complete: true,
|
|
323
|
-
createdAt: new Date()
|
|
324
|
-
};
|
|
325
|
-
if (voice) {
|
|
326
|
-
msg.voice = { id: voice?.id };
|
|
327
|
-
}
|
|
328
|
-
this.messageList.push({
|
|
329
|
-
"role": "user",
|
|
330
|
-
"content": [
|
|
331
|
-
{
|
|
332
|
-
"type": "image_url",
|
|
333
|
-
"image_url": { "url": imageUrl },
|
|
334
|
-
},
|
|
335
|
-
{
|
|
336
|
-
"type": "text",
|
|
337
|
-
"text": message
|
|
338
|
-
},
|
|
339
|
-
],
|
|
340
|
-
complete: true,
|
|
341
|
-
createdAt: new Date()
|
|
342
|
-
});
|
|
343
|
-
}
|
|
344
|
-
// 创建并发起一条新的消息补全
|
|
345
|
-
// console.log("send",this.messageList)
|
|
346
|
-
let completion = new FmodeChatCompletion(this.fixMessageList(this.messageList), {
|
|
347
|
-
model: this.currentModel?.get("code") || "fmode-1.6-cn"
|
|
348
|
-
});
|
|
349
|
-
// 生命周期:消息获取完成
|
|
350
|
-
if (this.onUserSend) {
|
|
351
|
-
let sendResult = await this.onUserSend(this, this.messageList[this.messageList?.length - 1]);
|
|
352
|
-
if (!sendResult)
|
|
353
|
-
return;
|
|
354
|
-
}
|
|
355
|
-
this.userInput = "";
|
|
356
|
-
this.userImage = "";
|
|
357
|
-
// console.log(this.currentModel?.toJSON())
|
|
358
|
-
// 持续更新事件推送的消息体内容至消息列表
|
|
359
|
-
let isDirect = this.isDirect || false;
|
|
360
|
-
if (this.isTalkMode) {
|
|
361
|
-
isDirect = true;
|
|
362
|
-
}
|
|
363
|
-
let send$ = completion.sendCompletion({
|
|
364
|
-
isDirect: isDirect,
|
|
365
|
-
onComplete: onComplete || null
|
|
366
|
-
}).pipe(finalize(async () => {
|
|
367
|
-
if (this.isTalkMode) {
|
|
368
|
-
let content = this.messageList[completion.indexOfList]?.content;
|
|
369
|
-
let voice = await this.getVoiceByContentText(content, eventMap);
|
|
370
|
-
eventMap?.onSSMLComplete && eventMap?.onSSMLComplete(voice);
|
|
371
|
-
this.messageList[completion.indexOfList].voice = voice;
|
|
372
|
-
this.playChatVoice(this.voiceMap[voice?.id], {
|
|
373
|
-
onResult: (result) => {
|
|
374
|
-
if (result?.duration) {
|
|
375
|
-
this.messageList[completion.indexOfList].voice.duration = result?.duration;
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
});
|
|
379
|
-
}
|
|
380
|
-
this.messageList[completion.indexOfList].complete = true;
|
|
381
|
-
})).subscribe(message => {
|
|
382
|
-
if (!this.messageList[completion.indexOfList]) {
|
|
383
|
-
eventMap?.onMessageStart?.(message);
|
|
384
|
-
}
|
|
385
|
-
this.messageList[completion.indexOfList] = message;
|
|
386
|
-
this.latestAIResponse = this.getContentText(message?.content);
|
|
387
|
-
let savedList = this.chatSession?.get("messageList")?.length;
|
|
388
|
-
// 生命周期:会话创建后,有新消息时,创建保存会话
|
|
389
|
-
if (this.messageList?.length > savedList) {
|
|
390
|
-
// console.log("cycle新会话")
|
|
391
|
-
this.saveChatSession();
|
|
392
|
-
}
|
|
393
|
-
if (message?.complete) {
|
|
394
|
-
// 生命周期:消息获取完成
|
|
395
|
-
this.onMessage && this.onMessage(this, this.messageList[this.messageList?.length - 1]);
|
|
396
|
-
// 消息发送完成后,保存聊天记录
|
|
397
|
-
this.saveChatSession();
|
|
398
|
-
send$.unsubscribe();
|
|
399
|
-
}
|
|
400
|
-
// console.log(message)
|
|
401
|
-
this.scrollToBottom && this.scrollToBottom();
|
|
402
|
-
});
|
|
403
|
-
}
|
|
404
|
-
getVoiceByContentText(content, eventMap, promptEnabled = false) {
|
|
405
|
-
let contentText = this.getContentText(content);
|
|
406
|
-
let ChatVoice = Parse.Object.extend("ChatVoice");
|
|
407
|
-
let chatVoice = new ChatVoice();
|
|
408
|
-
let contentSSML = ``;
|
|
409
|
-
let voiceConfig = this.voiceConfig || this.role?.get("voiceConfig");
|
|
410
|
-
this.SSMLRoleVoice = voiceConfig?.voice || this.SSMLRoleVoice;
|
|
411
|
-
return new Promise(async (resolve, reject) => {
|
|
412
|
-
let resolveChatVoice = async () => {
|
|
413
|
-
chatVoice.set("content", contentText);
|
|
414
|
-
chatVoice.set("ssml", contentSSML);
|
|
415
|
-
chatVoice.set("role", "assistant");
|
|
416
|
-
let company = localStorage.getItem("company");
|
|
417
|
-
company && chatVoice.set("company", { __type: "Pointer", className: "Company", objectId: company });
|
|
418
|
-
Parse.User.current()?.id && chatVoice.set("user", Parse.User.current().toPointer());
|
|
419
|
-
this.chatSession?.id && chatVoice.set("session", this.chatSession?.toPointer());
|
|
420
|
-
chatVoice = await chatVoice.save();
|
|
421
|
-
this.voiceMap[chatVoice?.id] = chatVoice;
|
|
422
|
-
resolve({
|
|
423
|
-
id: chatVoice?.id,
|
|
424
|
-
});
|
|
425
|
-
};
|
|
426
|
-
/**
|
|
427
|
-
* 方法一:高级语音直接读文本,速度快,但细节情绪标记不足。
|
|
428
|
-
*/
|
|
429
|
-
if (promptEnabled == false) {
|
|
430
|
-
let provider = voiceConfig?.provider || "microsoft";
|
|
431
|
-
let rate = voiceConfig?.rate;
|
|
432
|
-
let rateStart = rate ? `<prosody rate="${rate}">` : "";
|
|
433
|
-
let rateEnd = rate ? `</prosody>` : "";
|
|
434
|
-
contentSSML = `<speak provider="${provider}">${rateStart}<voice name="${this.SSMLRoleVoice}">${contentText}</voice>${rateEnd}</speak>`;
|
|
435
|
-
if (provider == "doubao") {
|
|
436
|
-
contentSSML = contentText;
|
|
437
|
-
}
|
|
438
|
-
resolveChatVoice();
|
|
439
|
-
}
|
|
440
|
-
/**
|
|
441
|
-
* promptEnabled == true
|
|
442
|
-
* 方法二:通过大模型再次拼接SSML脚本,实现更优质的语音标记,但是生成时间太慢
|
|
443
|
-
*/
|
|
444
|
-
if (promptEnabled == true) {
|
|
445
|
-
// 拼接Prompt
|
|
446
|
-
let TextSSMLPrompt = await getFormatTpl(PromptTplTalkTextSSMLCode, {
|
|
447
|
-
content: contentText, // 文本内容
|
|
448
|
-
SSMLRoleVoice: this.SSMLRoleVoice, // SSML 演说者
|
|
449
|
-
});
|
|
450
|
-
// 生成SSML
|
|
451
|
-
let completion = new FmodeChatCompletion(this.fixMessageList([{
|
|
452
|
-
role: "user",
|
|
453
|
-
content: TextSSMLPrompt
|
|
454
|
-
}]), {
|
|
455
|
-
model: this.currentModel?.get("code") || "fmode-1.6-cn"
|
|
456
|
-
});
|
|
457
|
-
let send$ = completion.sendCompletion({
|
|
458
|
-
isDirect: true,
|
|
459
|
-
}).subscribe(async (message) => {
|
|
460
|
-
if (message?.complete) {
|
|
461
|
-
contentSSML = this.getContentText(message?.content);
|
|
462
|
-
resolveChatVoice();
|
|
463
|
-
}
|
|
464
|
-
});
|
|
465
|
-
}
|
|
466
|
-
});
|
|
467
|
-
}
|
|
468
|
-
getContentText(content) {
|
|
469
|
-
if (typeof content == "string") {
|
|
470
|
-
return content;
|
|
471
|
-
}
|
|
472
|
-
else {
|
|
473
|
-
return content?.[0]?.text || ``;
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
/**
|
|
477
|
-
* TTS - 语音合成
|
|
478
|
-
*
|
|
479
|
-
*/
|
|
480
|
-
async initTTS() {
|
|
481
|
-
this.voiceConfig = this.voiceConfig || this.role?.get("voiceConfig");
|
|
482
|
-
// if(this.tts) return // 待明确sts有效期和次数进行优化,避免每次重复获取
|
|
483
|
-
let config = await this.ncloud.apig("voice/tts/token", {
|
|
484
|
-
company: localStorage.getItem("company"),
|
|
485
|
-
provider: this.voiceConfig?.provider || "microsoft"
|
|
486
|
-
});
|
|
487
|
-
config.provider = this.voiceConfig?.provider;
|
|
488
|
-
if ((!config?.provider) || config?.provider == "microsoft") {
|
|
489
|
-
// config.provider = new FmodeTTSProviderMicrosoft();
|
|
490
|
-
}
|
|
491
|
-
if (config?.provider == "doubao") {
|
|
492
|
-
config.provider = new FmodeTTSProviderDoubao();
|
|
493
|
-
}
|
|
494
|
-
config.voiceConfig = this.voiceConfig;
|
|
495
|
-
// 有TTS资源,使用情绪合成
|
|
496
|
-
console.log("initTTS", config);
|
|
497
|
-
if (config?.token || config?.stsToken) {
|
|
498
|
-
let tts = new FmodeTTS(config, this.uploadServ);
|
|
499
|
-
return tts;
|
|
500
|
-
}
|
|
501
|
-
else {
|
|
502
|
-
return null;
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
stopPlayingVoice() {
|
|
506
|
-
Object.values(this.VoiceTTSMap).forEach(tts => {
|
|
507
|
-
if (tts?.isPlaying) {
|
|
508
|
-
tts?.stop();
|
|
509
|
-
}
|
|
510
|
-
});
|
|
511
|
-
}
|
|
512
|
-
async playChatVoice(voice, eventMap) {
|
|
513
|
-
let tts = await this.initTTS();
|
|
514
|
-
// tts.autoSaveChatSession = autoSaveChatSession;
|
|
515
|
-
console.log("playChatVoice", tts);
|
|
516
|
-
if (tts) {
|
|
517
|
-
try {
|
|
518
|
-
// console.log(textOrSSML)
|
|
519
|
-
tts.voiceConfig = this.voiceConfig;
|
|
520
|
-
// 完整的消息,通过TTS合成进行讲话
|
|
521
|
-
this.playAnimation("talking"); // Talking动画,暂时用wating代替
|
|
522
|
-
tts.speakAsync(voice?.get("ssml"), voice, {
|
|
523
|
-
onStart: (chatVoice) => {
|
|
524
|
-
eventMap?.onStart && eventMap?.onStart(chatVoice); // 事件传递
|
|
525
|
-
},
|
|
526
|
-
onLoaded: (audio) => {
|
|
527
|
-
eventMap?.onLoaded && eventMap?.onLoaded(audio); // 事件传递
|
|
528
|
-
},
|
|
529
|
-
onResult: (result) => {
|
|
530
|
-
eventMap?.onResult && eventMap?.onResult(result); // 事件传递
|
|
531
|
-
},
|
|
532
|
-
onStop: () => {
|
|
533
|
-
eventMap?.onStop && eventMap?.onStop(); // 事件传递
|
|
534
|
-
this.playAnimation("waiting"); // Talking动画,暂时用wating代替
|
|
535
|
-
}
|
|
536
|
-
});
|
|
537
|
-
}
|
|
538
|
-
catch (ttserr) {
|
|
539
|
-
// console.error(ttserr)
|
|
540
|
-
}
|
|
541
|
-
this.VoiceTTSMap[voice.id] = tts;
|
|
542
|
-
return tts;
|
|
543
|
-
}
|
|
544
|
-
return null;
|
|
545
|
-
// 无TSS资源,调用Edge Speech
|
|
546
|
-
}
|
|
547
|
-
/**
|
|
548
|
-
* 保存单次会话
|
|
549
|
-
*/
|
|
550
|
-
async saveChatSession() {
|
|
551
|
-
if (this.sessionId == "new") {
|
|
552
|
-
this.chatSession = new this.ChatSession();
|
|
553
|
-
}
|
|
554
|
-
this.chatSession.set("title", this.genTitle());
|
|
555
|
-
this.chatSession.set("role", this.role?.toPointer());
|
|
556
|
-
this.chatSession.set("messageList", this.messageList);
|
|
557
|
-
this.chatSession.set("user", Parse.User.current()?.toPointer());
|
|
558
|
-
this.chatSession = await this.chatSession.save();
|
|
559
|
-
this.onChatSaved && this.onChatSaved(this);
|
|
560
|
-
this.sessionId = this.chatSession?.id;
|
|
561
|
-
if (this.sessionId) {
|
|
562
|
-
// 修改URL地址为sessionId,方便分享或切换 角色页面 => 会话页面
|
|
563
|
-
let newHref = `${window.location.origin}/chat/pro/chat/${this.sessionId}`;
|
|
564
|
-
if (window.location?.pathname?.indexOf("chat/session") > -1) {
|
|
565
|
-
newHref = `${window.location.origin}/chat/session/chat/${this.sessionId}`;
|
|
566
|
-
}
|
|
567
|
-
if (this.mode == "modal") {
|
|
568
|
-
newHref = window.location.href;
|
|
569
|
-
}
|
|
570
|
-
newHref = this.getInviteUrl(newHref);
|
|
571
|
-
window.history.replaceState(null, null, newHref + window.location.search);
|
|
572
|
-
// 修改最新条chatList数据
|
|
573
|
-
let newChat = {
|
|
574
|
-
sid: this.chatSession?.id,
|
|
575
|
-
rid: this.role?.id,
|
|
576
|
-
name: this.role?.get('name'),
|
|
577
|
-
message: this.chatSession?.get('messageList')?.[this.chatSession?.get('messageList')?.length - 1]?.content?.slice(0, 20),
|
|
578
|
-
latest: this.chatSession?.createdAt
|
|
579
|
-
};
|
|
580
|
-
if (this.chatServ && !this.chatServ?.chatList?.length)
|
|
581
|
-
this.chatServ.chatList = [];
|
|
582
|
-
let index = this.chatServ?.chatList?.find(item => item?.sid == newChat?.sid);
|
|
583
|
-
if (index > -1) {
|
|
584
|
-
this.chatServ.chatList[index] = newChat;
|
|
585
|
-
}
|
|
586
|
-
else {
|
|
587
|
-
this.chatServ?.chatList.unshift(newChat);
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
getInviteUrl(url) {
|
|
592
|
-
let u = new URL(url);
|
|
593
|
-
let id = Parse.User?.current()?.id;
|
|
594
|
-
// 附加invite参数
|
|
595
|
-
u.searchParams.set("invite", id);
|
|
596
|
-
return u.href;
|
|
597
|
-
}
|
|
598
|
-
// 根据聊天内容及问题,生成标题
|
|
599
|
-
genTitle() {
|
|
600
|
-
if (this.title)
|
|
601
|
-
return this.title;
|
|
602
|
-
let content = this.messageList.find(item => item.role == "user")?.content;
|
|
603
|
-
if (typeof content == "string") { // 截图文本内容文字部分
|
|
604
|
-
this.title = content?.slice(0, 15) || "";
|
|
605
|
-
}
|
|
606
|
-
if (typeof content == "object") { // 截图复合内容文字部分
|
|
607
|
-
this.title = content?.find(item => item?.text)?.text || "";
|
|
608
|
-
}
|
|
609
|
-
return this.title;
|
|
610
|
-
}
|
|
611
|
-
fixMessageList(messages) {
|
|
612
|
-
return messages.map(msg => { return { role: msg.role, content: msg.content }; });
|
|
613
|
-
}
|
|
614
|
-
nowStr() {
|
|
615
|
-
let now = new Date();
|
|
616
|
-
return `${now.getFullYear()}/${now.getMonth() + 1}/${now.getDate()} ${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}`;
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm1vZGUtY2hhdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Ztb2RlLW5nL3NyYy9saWIvY29yZS9hZ2VudC9jaGF0L2Ztb2RlLWNoYXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFxRCxRQUFRLEVBQUUsTUFBTSxNQUFNLENBQUE7QUFDbEYsdUdBQXVHO0FBQ3ZHLE9BQU8sS0FBSyxNQUFNLE9BQU8sQ0FBQztBQUMxQixPQUFPLEVBQUUsUUFBUSxFQUFFLHNCQUFzQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFHbkUsa0RBQWtEO0FBQ2xELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFFckQsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ25ELDREQUE0RDtBQUM1RCw4Q0FBOEM7QUFDOUMscUJBQXFCO0FBR3JCLE1BQU0sMkJBQTJCLEdBQUcsc0JBQXNCLENBQUM7QUFDM0QsTUFBTSx5QkFBeUIsR0FBRyxvQkFBb0IsQ0FBQztBQUl2RCxNQUFNLFVBQVUscUJBQXFCLENBQUMsT0FBOEM7SUFDaEYsSUFBSSxJQUFJLEdBQUcsRUFBRSxDQUFBO0lBQ2IsSUFBRyxPQUFPLE9BQU8sSUFBSSxRQUFRO1FBQUUsSUFBSSxHQUFHLE9BQU8sQ0FBQTtJQUM3QyxJQUFHLE9BQU8sT0FBTyxJQUFJLFFBQVE7UUFBRSxJQUFJLEdBQUcsT0FBTyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUEsRUFBRSxDQUFBLElBQUksRUFBRSxJQUFJLENBQUMsRUFBRSxJQUFJLElBQUksRUFBRSxDQUFBO0lBQ2pGLE9BQU8sSUFBSSxDQUFBO0FBQ2YsQ0FBQztBQUNELE1BQU0sVUFBVSxrQkFBa0IsQ0FBQyxPQUE4QztJQUM3RSxJQUFHLE9BQU8sT0FBTyxJQUFJLFFB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QUFHLENBQUMsUUFBUSxFQUFFLElBQUksR0FBRyxDQUFDLFVBQVUsRUFBRSxJQUFJLEdBQUcsQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFBO0lBQ2hJLENBQUM7Q0FFSiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGJ1ZmZlclRpbWUsIGNvbmNhdE1hcCwgT2JzZXJ2YWJsZSwgT2JzZXJ2ZXIsZGVsYXksIGZpbmFsaXplIH0gZnJvbSBcInJ4anNcIlxyXG4vLyB2YXIgYnVmZmVyVGltZTphbnksIGNvbmNhdE1hcDphbnksIE9ic2VydmFibGU6YW55LCBPYnNlcnZlcjphbnksZGVsYXk6YW55LCBmaW5hbGl6ZTphbnksT2JzZXJ2ZXI6YW55XHJcbmltcG9ydCBQYXJzZSBmcm9tIFwicGFyc2VcIjtcclxuaW1wb3J0IHsgRm1vZGVUVFMsIEZtb2RlVFRTUHJvdmlkZXJEb3ViYW8gfSBmcm9tIFwiLi4vLi4vdm9pY2UvdHRzXCI7XHJcbmltcG9ydCB7IE5vdmFDbG91ZFNlcnZpY2UgfSBmcm9tIFwiLi4vLi4vLi4vbm92YS1jbG91ZFwiO1xyXG5pbXBvcnQgeyBOb3ZhVXBsb2FkU2VydmljZSB9IGZyb20gXCIuLi8uLi8uLi9zdG9yYWdlL3NlcnZpY2UtdXBsb2FkL25vdmEtdXBsb2FkLnNlcnZpY2VcIjtcclxuLy8gaW1wb3J0IHsgTmF2Q29udHJvbGxlciB9IGZyb20gXCJAaW9uaWMvYW5ndWxhclwiO1xyXG5pbXBvcnQgeyBQcm9tcHRUZW1wbGF0ZSB9IGZyb20gXCJAbGFuZ2NoYWluL2NvcmUvcHJvbXB0c1wiO1xyXG5pbXBvcnQgeyBnZXRGb3JtYXRUcGwgfSBmcm9tIFwiLi4vcHJvbXB0L3Byb21wdC11dGlsXCI7XHJcbmltcG9ydCB7IENoYXRJbWFnZUNvbnRlbnRJdGVtLCBGbW9kZUNoYXRFdmVudE1hcCwgRm1vZGVDaGF0TWVzc2FnZSwgRm1vZGVDaGF0TWVzc2FnZVZvaWNlLCBGbW9kZUNoYXRWb2ljZUNvbmZpZyB9IGZyb20gXCIuL2ludGVyZmFjZVwiO1xyXG5pbXBvcnQgeyBGbW9kZUNoYXRDb21wbGV0aW9uIH0gZnJvbSBcIi4vY29tcGxldGlvblwiO1xyXG4vLyBpbXBvcnQgeyBQcm9tcHRUZW1wbGF0ZSB9IGZyb20gXCIuL2xpYi9sYW5nY2hhaW4vcHJvbXB0c1wiO1xyXG4vLyBpbXBvcnQgeyBFbGVtZW50UmVmIH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcclxuLy8gdmFyIFBhcnNlOmFueSA9IHt9XHJcblxyXG5cclxuY29uc3QgUHJvbXB0VHBsVGFsa1NTTUxPdXRwdXRDb2RlID0gXCJ0YWxrLXNzbWwtb3V0cHV0LXRwbFwiO1xyXG5jb25zdCBQcm9tcHRUcGxUYWxrVGV4dFNTTUxDb2RlID0gXCJ0YWxrLXRleHQtc3NtbC10cGxcIjtcclxuXHJcblxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGdldE1lc3NhZ2VDb250ZW50VGV4dChjb250ZW50OmFueXxzdHJpbmd8QXJyYXk8Q2hhdEltYWdlQ29udGVudEl0ZW0+KXtcclxuICAgIGxldCB0ZXh0ID0gXCJcIlxyXG4gICAgaWYodHlwZW9mIGNvbnRlbnQgPT0gXCJzdHJpbmdcIikgdGV4dCA9IGNvbnRlbnRcclxuICAgIGlmKHR5cGVvZiBjb250ZW50ID09IFwib2JqZWN0XCIpIHRleHQgPSBjb250ZW50Py5maW5kKGl0ZW09Pml0ZW0/LnRleHQpPy50ZXh0IHx8IFwiXCJcclxuICAgIHJldHVybiB0ZXh0XHJcbn1cclxuZXhwb3J0IGZ1bmN0aW9uIGdldE1lc3NhZ2VJbWFnZVVybChjb250ZW50OmFueXxzdHJpbmd8QXJyYXk8Q2hhdEltYWdlQ29udGVudEl0ZW0+KXtcclxuICAgIGlmKHR5cGVvZiBjb250ZW50ID09IFwib2JqZWN0XCIpIHJldHVybiBjb250ZW50Py5maW5kKGl0ZW09Pml0ZW0/LmltYWdlX3VybCk/LmltYWdlX3VybD8udXJsIHx8IFwiXCJcclxuICAgIHJldHVybiBudWxsXHJcbiAgfVxyXG5cclxuLyoqXHJcbiAqIEZtb2RlQ2hhdCDogYrlpKnlr7nor53nsbtcclxuICogQHB1YmxpY1xyXG4gKi9cclxuZXhwb3J0IGNsYXNzIEZtb2RlQ2hhdHtcclxuXHJcbiAgICB0aXRsZTpzdHJpbmdcclxuICAgIHNlc3Npb25JZDpzdHJpbmdcclxuICAgIENoYXRTZXNzaW9uID0gUGFyc2UuT2JqZWN0LmV4dGVuZChcIkNoYXRTZXNzaW9uXCIpXHJcbiAgICBjaGF0U2Vzc2lvbjpQYXJzZS5PYmplY3RcclxuICAgIHJvbGU6YW55XHJcbiAgICBtZXNzYWdlTGlzdDpGbW9kZUNoYXRNZXNzYWdlW10gPSBbe3JvbGU6XCJzeXN0ZW1cIixjb250ZW50Olwi57O757uf5o+Q56S677yaQUnku4Xkvpvlj4LogINcIn1dXHJcbiAgICBsYXRlc3RBSVJlc3BvbnNlOnN0cmluZ3x1bmRlZmluZWQgPSBgYFxyXG4gICAgY2hhdFNlcnY6YW55XHJcbiAgICBwdWJsaWMgdXNlcklucHV0OnN0cmluZyA9IGBgO1xyXG4gICAgcHVibGljIHVzZXJJbWFnZTpzdHJpbmcgPSBgYDtcclxuICAgIGlzRGlyZWN0OmJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgICBtb2RlOlwibW9kYWxcInxcInBhZ2VcIiA9IFwicGFnZVwiO1xyXG4gICAgLyoqXHJcbiAgICAgKiDlh73mlbDnlJ/lkb3lkajmnJ9cclxuICAgICAqL1xyXG4gICAgb25DaGF0U2F2ZWQ6KGNoYXQ6Rm1vZGVDaGF0KT0+dm9pZFxyXG4gICAgb25NZXNzYWdlOihjaGF0OkZtb2RlQ2hhdCxtZXNzYWdlOkZtb2RlQ2hhdE1lc3NhZ2UpPT52b2lkXHJcbiAgICBvblVzZXJTZW5kOihjaGF0OkZtb2RlQ2hhdCxtZXNzYWdlOkZtb2RlQ2hhdE1lc3NhZ2UpPT5ib29sZWFufFByb21pc2U8Ym9vbGVhbj5cclxuICAgIG9uQ2xvc2U6KGNoYXQ6Rm1vZGVDaGF0KT0+Ym9vbGVhbnxQcm9taXNlPGJvb2xlYW4+XHJcbiAgICAvLyBvblVzZXJJbnB1dDooY2hhdDpGbW9kZUNoYXQsbWVzc2FnZTpGbW9kZUNoYXRNZXNzYWdlKT0+Ym9vbGVhbnxQcm9taXNlPGJvb2xlYW4+XHJcblxyXG4gICAgLy8g55WM6Z2i5Yqf6IO95pi+56S65o6n5Yi2XHJcbiAgICBoaWRlU2hhcmU6Ym9vbGVhbiA9IGZhbHNlO1xyXG4gICAgaGlkZU1vZGFsU2VsZWN0OmJvb2xlYW4gPSBmYWxzZTtcclxuICAgIGhpZGVJbnB1dFByZXZpZXc6Ym9vbGVhbiA9IGZhbHNlO1xyXG5cclxuXHJcbiAgICAvKipcclxuICAgICAqIOWPr+mAieaooeWei+WIl+ihqOWKoOi9vVxyXG4gICAgICovXHJcbiAgICBtb2RlbExpc3Q6QXJyYXk8UGFyc2UuT2JqZWN0PlxyXG4gICAgY3VycmVudE1vZGVsOlBhcnNlLk9iamVjdFxyXG4gICAgYXN5bmMgbG9hZE1vZGVsTGlzdChtb2RlbD86UGFyc2UuT2JqZWN0KXtcclxuICAgICAgICBpZih0aGlzLm1vZGVsTGlzdD8ubGVuZ3RoKSByZXR1cm5cclxuICAgICAgICBsZXQgcXVlcnkgPSBuZXcgUGFyc2UuUXVlcnkoXCJDaGF0TW9kZWxcIilcclxuICAgICAgICBxdWVyeS5ub3RFcXVhbFRvKFwiaXNEZWxldGVkXCIsdHJ1ZSlcclxuICAgICAgICBxdWVyeS5lcXVhbFRvKFwiaXNFbmFibGVkXCIsdHJ1ZSlcclxuICAgICAgICBxdWVyeS5hZGRBc2NlbmRpbmcoXCJpbmRleFwiKVxyXG4gICAgICAgIHRoaXMubW9kZWxMaXN0ID0gYXdhaXQgcXVlcnkuZmluZCgpO1xyXG4gICAgICAgIHRoaXMuY3VycmVudE1vZGVsID0gbW9kZWwgfHwgdGhpcy5tb2RlbExpc3Q/LmZpbmQoaXRlbT0+aXRlbS5nZXQoXCJjb2RlXCIpPT1cImZtb2RlLTEuNi1jblwiKVxyXG4gICAgfVxyXG5cclxuICAgIC8qKiBcclxuICAgICAqIOiZmuaLn+W9ouixoeWxleekuueKtuaAgVxyXG4gICAgICovXHJcbiAgICBpc0F2YXRhclNob3c6Ym9vbGVhbiA9IGZhbHNlO1xyXG4gICAgYXZhdGFyTW9kZTpzdHJpbmcgPSBcIlwiO1xyXG4gICAgYXZhdGFyQ29uZmlnOmFueXx1bmRlZmluZWQ7XHJcbiAgICBzaG93QXZhdGFyKCl7XHJcbiAgICAgICAgdGhpcy5hdmF0YXJDb25maWcgPSB0aGlzLnJvbGU/LmdldChcImF2YXRhckNvbmZpZ1wiKVxyXG4gICAgICAgIGlmKHRoaXMuYXZhdGFyQ29uZmlnKXtcclxuICAgICAgICAgICAgdGhpcy5pc0F2YXRhclNob3cgPSB0cnVlO1xyXG4gICAgICAgICAgICBpZih0aGlzLmF2YXRhckNvbmZpZz8uaW1hZ2Upe1xyXG4gICAgICAgICAgICAgICAgdGhpcy5hdmF0YXJDb25maWcuaW1hZ2Uud2FpdGluZyA9IHRoaXMuYXZhdGFyQ29uZmlnLmltYWdlLndhaXRpbmcgfHwgdGhpcy5yb2xlPy5nZXQoXCJ0aHVtYlwiKSB8fCB0aGlzLnJvbGU/LmdldChcImF2YXRhclwiKVxyXG4gICAgICAgICAgICAgICAgdGhpcy5hdmF0YXJNb2RlID0gXCJpbWFnZVwiXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYodGhpcy5hdmF0YXJDb25maWc/LnZpZGVvKXtcclxuICAgICAgICAgICAgICAgIHRoaXMuYXZhdGFyQ29uZmlnLnZpZGVvLndhaXRpbmcgPSB0aGlzLmF2YXRhckNvbmZpZy52aWRlby53YWl0aW5nXHJcbiAgICAgICAgICAgICAgICB0aGlzLmF2YXRhck1vZGUgPSBcInZpZGVvXCJcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIOmihOe9ruaPkOekuuivjeW8ueeql+aYr+WQpuWxleekulxyXG4gICAgICovXHJcbiAgICBpc1Byb21wdE1vZGFsT3Blbjpib29sZWFuID0gZmFsc2U7XHJcbiAgICBpc1Byb21wdE1lc3NhZ2VBcmVhU2hvdzpib29sZWFuID0gdHJ1ZTtcclxuICAgIHByb21wdExpc3Q6YW55ID0gW11cclxuXHJcbiAgICAvKipcclxuICAgICAqIOi+k+WFpeaMiemSruWMuuWfn1xyXG4gICAgICovXHJcbiAgICBmb2N1c1VzZXJJbnB1dDpGdW5jdGlvbiA9ICgpPT57fVxyXG4gICAgbmF2Q3RybDphbnkgLy8gTmF2Q29udHJvbGxlclxyXG4gICAgIGxlZnRCdXR0b25zOkFycmF5PGFueXx7dGl0bGU/OnN0cmluZyxzaG93VGl0bGU/OnN0cmluZ30+ID0gW1xyXG4gICAgICAgIC8vIOaPkOekuiDlvZPop5LoibLphY3nva7pooTorr7mj5DnpLror43ml7Yg5pi+56S6XHJcbiAgICAgICAge3RpdGxlOlwi54G15oSfXCIsaWNvbjpcImNvbG9yLXdhbmQtb3V0bGluZVwiLG9uQ2xpY2s6KCk9PntcclxuICAgICAgICAgIHRoaXMuaXNQcm9tcHRNb2RhbE9wZW4gPSB0cnVlXHJcbiAgICAgICAgfSxzaG93OigpPT57XHJcbiAgICAgICAgICByZXR1cm4gdGhpcz8ucHJvbXB0TGlzdD8ubGVuZ3RoXHJcbiAgICAgICAgfX0sXHJcbiAgICAgICAge3RpdGxlOlwi6KeS6ImyXCIsaWNvbjpcInBlb3BsZS1vdXRsaW5lXCIsb25DbGljazooKT0+e1xyXG4gICAgICAgICAgdGhpcy5uYXZDdHJsPy5uYXZpZ2F0ZVJvb3QoXCIvY2hhdC9wcm8vbWFza1wiKTtcclxuICAgICAgICB9LHNob3c6KCk9PntyZXR1cm4gdHJ1ZX19LFxyXG4gICAgICAgIHt0aXRsZTpcIuWRvOWPq1wiLGljb246XCJjYWxsLW91dGxpbmVcIixvbkNsaWNrOigpPT57XHJcbiAgICAgICAgICAgIHRoaXMuY2hhdFNlcnY/LmNhbGxSb2xlKHRoaXMucm9sZSlcclxuICAgICAgICB9LHNob3c6KCk9PntcclxuICAgICAgICAgIHJldHVybiB0aGlzPy5yb2xlPy5nZXQoJ3ZvaWNlQ29uZmlnJyk7XHJcbiAgICAgICAgfX0sXHJcbiAgICAgIF1cclxuXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiDmmK/lkKblvIDlkK/or63pn7Pmtojmga/mqKHlvI/vvIjljZXmrKHvvIlcclxuICAgICAqL1xyXG4gICAgaXNWb2ljZUlucHV0TW9kZTpib29sZWFuID0gZmFsc2U7XHJcbiAgICBpc1RleHRpbmc6Ym9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICog5piv5ZCm5byA5ZCv5a6e5pe25a+56K+d5qih5byP77yI5a6e5pe277yJXHJcbiAgICAgKiBAZGVzY1xyXG4gICAgICog5byA5ZCvc3NtbCBzeXN0ZW3mj5DnpLror41cclxuICAgICAqIOW8gOWQr+WbnuetlOaWh+acrOmZpHhtbOaYvuekuuaooeW8j1xyXG4gICAgICovXHJcbiAgICB2b2ljZUNvbmZpZzpGbW9kZUNoYXRWb2ljZUNvbmZpZ3x1bmRlZmluZWRcclxuICAgIGlzVGFsa01vZGU6Ym9vbGVhbiA9IGZhbHNlO1xyXG4gICAgU1NNTFJvbGVWb2ljZTpzdHJpbmcgPSBcInpoLUNOLVhpYW94aWFvTmV1cmFsXCI7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiDmu5rliqjoh7Pmtojmga/ljLrln5/lupXpg6jmlrnms5VcclxuICAgICAqIEBkZXNjIOmAmui/h2NoYXQtcGFuZWznrYnogYrlpKnpnaLmnb/vvIzotYvlgLzor6Xmlrnms5VcclxuICAgICAqL1xyXG4gICAgc2Nyb2xsQ29tcDphbnkgLy8gRWxlbWVudFJlZjtcclxuICAgIC8vIHNjcm9sbFRvQm90dG9tOkZ1bmN0aW9uO1xyXG4gICAgc2Nyb2xsVG9Cb3R0b20oY29tcD86YW55KXtcclxuICAgICAgICBjb21wID0gY29tcCB8fCB0aGlzLnNjcm9sbENvbXA7XHJcbiAgICAgICAgLy8gY29uc29sZS5sb2coY29tcClcclxuICAgICAgICBpZihjb21wPy5uYXRpdmVFbGVtZW50Py5zY3JvbGxIZWlnaHQpe1xyXG4gICAgICAgICAgY29tcC5uYXRpdmVFbGVtZW50LnNjcm9sbFRvcCA9IGNvbXAubmF0aXZlRWxlbWVudC5zY3JvbGxIZWlnaHRcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIOS+nei1luacjeWKoVxyXG4gICAgICovXHJcbiAgICBuY2xvdWQ6Tm92YUNsb3VkU2VydmljZTtcclxuICAgIHVwbG9hZFNlcnY6Tm92YVVwbG9hZFNlcnZpY2U7XHJcblxyXG4gICAgY29uc3RydWN0b3IoXHJcbiAgICAgICAgc2Vzc2lvbklkOnN0cmluZyxyb2xlPzpQYXJzZS5PYmplY3QsY2hhdFNlc3Npb24/OlBhcnNlLk9iamVjdCxjaGF0U2Vydj86YW55LFxyXG4gICAgICAgIG5hdkN0cmw/OmFueSwvL05hdkNvbnRyb2xsZXIsXHJcbiAgICAgICAgbmNsb3VkPzpOb3ZhQ2xvdWRTZXJ2aWNlLFxyXG4gICAgICAgIHVwbG9hZFNlcnY/Ok5vdmFVcGxvYWRTZXJ2aWNlLFxyXG4gICAgICAgICl7XHJcbiAgICAgICAgdGhpcy5jaGF0U2VydiA9IGNoYXRTZXJ2XHJcbiAgICAgICAgdGhpcy5yb2xlID0gcm9sZVxyXG4gICAgICAgIHRoaXMuc2Vzc2lvbklkID0gc2Vzc2lvbklkXHJcbiAgICAgICAgdGhpcy5uYXZDdHJsID0gbmF2Q3RybFxyXG4gICAgICAgIHRoaXMubmNsb3VkID0gbmNsb3VkXHJcbiAgICAgICAgdGhpcy51cGxvYWRTZXJ2ID0gdXBsb2FkU2VydlxyXG4gICAgICAgIGlmKGNoYXRTZXNzaW9uPy5pZCl7XHJcbiAgICAgICAgICAgIHRoaXMuY2hhdFNlc3Npb24gPSBjaGF0U2Vzc2lvbjtcclxuICAgICAgICAgICAgdGhpcy5tZXNzYWdlTGlzdCA9IHRoaXMuY2hhdFNlc3Npb24uZ2V0KFwibWVzc2FnZUxpc3RcIik7XHJcbiAgICAgICAgICAgIHRoaXMuc2Vzc2lvbklkID0gY2hhdFNlc3Npb24/LmlkO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZih0aGlzLnJvbGU/LmlkKXtcclxuICAgICAgICAgICAgdGhpcy52b2ljZUNvbmZpZyA9IHRoaXMucm9sZT8uZ2V0KFwidm9pY2VDb25maWdcIilcclxuICAgICAgICAgICAgaWYodGhpcy52b2ljZUNvbmZpZz8uYXV0b1RhbGspe1xyXG4gICAgICAgICAgICAgICAgdGhpcy5pc1RhbGtNb2RlID0gdGhpcy5pc1RhbGtNb2RlIHx8IHRoaXMudm9pY2VDb25maWc/LmF1dG9UYWxrO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5pc0RpcmVjdCA9IHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIOS8muivnUF2YXRhcuaOp+WItlxyXG4gICAgICovXHJcbiAgICBwbGF5QW5pbWF0aW9uID0gKGFuaW1OYW1lOnN0cmluZyk9PntcclxuICAgICAgICBjb25zb2xlLmxvZyhhbmltTmFtZSlcclxuICAgICAgICByZXR1cm5cclxuICAgIH1cclxuICAgIHdlbGNvbWUgPSBhc3luYyAoKT0+e1xyXG4gICAgICAgIGxldCBtc2dsaXN0ID0gdGhpcy5tZXNzYWdlTGlzdD8uZmlsdGVyKGl0ZW09Pml0ZW0/LnJvbGU9PVwiYXNzaXN0YW50XCIpO1xyXG4gICAgICAgIGlmKG1zZ2xpc3Q/Lmxlbmd0aCkgcmV0dXJuIC8vIOW3suacieWvueivneS4jeW8gOWcuumXruWAmVxyXG5cclxuICAgICAgICBsZXQgdXNlciA9IFBhcnNlLlVzZXIuY3VycmVudCgpO1xyXG4gICAgICAgIGxldCBwZXJzb24gPSBhd2FpdCB0aGlzLmxvYWRTZWxmKFwiUGVyc29uXCIsXCJ1c2VyVmVyaWZ5XCIpXHJcbiAgICAgICAgbGV0IHByb2ZpbGUgPSBhd2FpdCB0aGlzLmxvYWRTZWxmKFwiUHJvZmlsZVwiLFwidXNlclwiKVxyXG4gICAgICAgIGxldCBwZXJzb25OYW1lID0gcGVyc29uPy5nZXQoXCJuYW1lXCIpIHx8IHBlcnNvbj8uZ2V0KFwidXNlclZlZmlyeVwiKT8uZ2V0KFwicmVhbG5hbWVcIikgfHwgcGVyc29uPy5nZXQoXCJ1c2VyVmVmaXJ5XCIpPy5nZXQoXCJuaWNrbmFtZVwiKVxyXG4gICAgICAgIGxldCB1c2VyTmFtZSA9IHVzZXI/LmdldChcIm5pY2tuYW1lXCIpIHx8IHByb2ZpbGU/LmdldChcIm5hbWVcIikgfHwgdXNlcj8uZ2V0KFwicmVhbG5hbWVcIikgfHwgdXNlcj8uZ2V0KFwibmFtZVwiKVxyXG4gICAgICAgIGlmKHBlcnNvbj8uZ2V0KFwidXNlclZlcmlmeVwiKT8uaWQgPT0gdXNlcj8uaWQpe1xyXG4gICAgICAgICAgICBwZXJzb25OYW1lID0gXCLmgqhcIiAvLyDlvZPmnKzkurrml7bvvIznp7Dlkbzop5LoibLkuLrmgqhcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYoIXVzZXJOYW1lKXsgLy8g6Iul55So5oi35peg5aeT5ZCN77yM5YiZ55So5b2T5YmN5biQ5Y+35ZCN56ew5YGa56ew5ZG8XHJcbiAgICAgICAgICAgIHVzZXJOYW1lID0gcGVyc29uTmFtZVxyXG4gICAgICAgIH1cclxuICAgICAgICAgICAgXHJcbiAgICAgICAgLy8g6Zeu5YCZ6K+tL+mmluS4quivnemimFxyXG4gICAgICAgIC8vIOWNleS4qumXruWAmeivreebtOaOpeWKoOi9vVxyXG4gICAgICAgIGxldCB0cGwgPSB0aGlzLnJvbGUuZ2V0KFwidm9pY2VDb25maWdcIik/LndlbGNvbWU/LnByb21wdFxyXG4gICAgICAgIC8vIOWkmuadoemXruWAmeivremaj+WNs+WKoOi9vVxyXG4gICAgICAgIGlmKHRoaXMucm9sZS5nZXQoXCJ2b2ljZUNvbmZpZ1wiKT8ud2VsY29tZT8ucHJvbXB0TGlzdD8ubGVuZ3RoKXtcclxuICAgICAgICAgICAgbGV0IHRwbExpc3QgPSB0aGlzLnJvbGUuZ2V0KFwidm9pY2VDb25maWdcIik/LndlbGNvbWU/LnByb21wdExpc3Q7XHJcbiAgICAgICAgICAgIGxldCByYW5kb21JbmRleCA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHRwbExpc3QubGVuZ3RoKTtcclxuICAgICAgICAgICAgdHBsID0gdHBsTGlzdFtyYW5kb21JbmRleF07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZighdHBsKSByZXR1cm4gLy8g5peg5qih5p2/5YiZ6L+U5ZueXHJcbiAgICAgICAgbGV0IHdlbGNvbWVDb250ZW50ID0gYXdhaXQgUHJvbXB0VGVtcGxhdGUuZnJvbVRlbXBsYXRlKHRwbCx7XHJcbiAgICAgICAgICAgIHRlbXBsYXRlRm9ybWF0OlwibXVzdGFjaGVcIlxyXG4gICAgICAgIH0pLmZvcm1hdCh7XHJcbiAgICAgICAgICAgIG5hbWU6dXNlck5hbWUsIC8vIOeUqOaIt+ensOWRvFxyXG4gICAgICAgICAgICB1c2VyTmFtZTp1c2VyTmFtZSwgLy8g55So5oi356ew5ZG8XHJcbiAgICAgICAgICAgIHBlcnNvbk5hbWU6cGVyc29uTmFtZSwgLy8g6KeS6Imy56ew5ZG8XHJcbiAgICAgICAgICAgIHRpbWVPZkRheTp0aGlzLmdldFRpbWVPZkRheSgpXHJcbiAgICAgICAgfSlcclxuICAgICAgICAvLyBsZXQgY2FsbE5hbWUgPSBuYW1lP2Ake25hbWV977yMYDpcIlwiO1xyXG4gICAgICAgIC8vIGxldCBjYWxsVGltZSA9IGAke3RoaXMuZ2V0VGltZU9mRGF5KCl95aW9YDtcclxuICAgICAgICAvLyBsZXQgd2VsY29tZUNvbnRlbnQgPSBgJHtjYWxsTmFtZX0ke2NhbGxUaW1lfe+8jOacn+W+heiBhuWQrOaCqOeahOS6uueUn+aVheS6i++8jOaDs+WSjOaIkeiBiuS6m+S7gOS5iOWRou+8n2A7XHJcblxyXG4gICAgICAgIC8vIOeUn+aIkENoYXRWb2ljZeW5tuaSreaUvlxyXG4gICAgICAgIGxldCB2b2ljZSA9IGF3YWl0IHRoaXMuZ2V0Vm9pY2VCeUNvbnRlbnRUZXh0KHdlbGNvbWVDb250ZW50KTtcclxuICAgICAgICBsZXQgbWVzc2FnZSA9IHtcclxuICAgICAgICAgICAgcm9sZTpcImFzc2lzdGFudFwiLFxyXG4gICAgICAgICAgICB2b2ljZTogdm9pY2UsXHJcbiAgICAgICAgICAgIGNvbnRlbnQ6d2VsY29tZUNvbnRlbnQsXHJcbiAgICAgICAgICAgIGNvbXBsZXRlOnRydWVcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy52b2ljZU1hcFt2b2ljZT8uaWRdXHJcbiAgICAgICAgdGhpcy5wbGF5Q2hhdFZvaWNlKHRoaXMudm9pY2VNYXBbdm9pY2U/LmlkXSlcclxuICAgICAgICB0aGlzLm1lc3NhZ2VMaXN0LnB1c2gobWVzc2FnZSlcclxuICAgIH1cclxuICAgIGdldFRpbWVPZkRheSgpIHtcclxuICAgICAgICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpO1xyXG4gICAgICAgIGNvbnN0IGhvdXJzID0gbm93LmdldEhvdXJzKCk7XHJcbiAgICAgICAgaWYgKGhvdXJzID49IDUgJiYgaG91cnMgPCAxMikge1xyXG4gICAgICAgICAgICByZXR1cm4gXCLml6nkuIpcIjtcclxuICAgICAgICB9IGVsc2UgaWYgKGhvdXJzID49IDEyICYmIGhvdXJzIDwgMTQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIFwi5Lit5Y2IXCI7XHJcbiAgICAgICAgfSBlbHNlIGlmIChob3VycyA+PSAxNCAmJiBob3VycyA8IDE4KSB7XHJcbiAgICAgICAgICAgIHJldHVybiBcIuS4i+WNiFwiO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiBcIuaZmuS4ilwiO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHNlbGY6e1xyXG4gICAgICAgIFBlcnNvbj86UGFyc2UuT2JqZWN0fHVuZGVmaW5lZFxyXG4gICAgICAgIFByb2ZpbGU/OlBhcnNlLk9iamVjdHx1bmRlZmluZWRcclxuICAgIH0gPSB7fVxyXG4gICAgYXN5bmMgbG9hZFNlbGYoY2xhc3NOYW1lLHVzZXJLZXkpe1xyXG4gICAgICAgIGlmKHRoaXMuc2VsZltjbGFzc05hbWVdKSByZXR1cm4gdGhpcy5zZWxmW2NsYXNzTmFtZV1cclxuICAgICAgICBsZXQgdXNlciA9IFBhcnNlLlVzZXIuY3VycmVudCgpO1xyXG4gICAgICAgIGxldCBxdWVyeSA9IG5ldyBQYXJzZS5RdWVyeShjbGFzc05hbWUpO1xyXG4gICAgICAgIHF1ZXJ5LmluY2x1ZGUodXNlcktleSlcclxuICAgICAgICBxdWVyeS5lcXVhbFRvKHVzZXJLZXksdXNlcj8uaWQpO1xyXG4gICAgICAgIHRoaXMuc2VsZltjbGFzc05hbWVdID0gYXdhaXQgcXVlcnkuZmlyc3QoKTtcclxuICAgICAgICByZXR1cm4gdGhpcy5zZWxmW2NsYXNzTmFtZV1cclxuICAgIH1cclxuXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiDlr7nor53mqKHlnovmj5DnpLror41cclxuICAgICAqL1xyXG4gICAgIGFzeW5jIGxvYWRUYWxrU3lzdGVtUHJvbXB0KHJvbGU6UGFyc2UuT2JqZWN0KXtcclxuICAgICAgICBpZighdGhpcy5pc1RhbGtNb2RlKSByZXR1cm5cclxuICAgICAgICBpZighcm9sZSkgcmV0dXJuXHJcbiAgICAgICAgbGV0IHZvaWNlQ29uZmlnOmFueSA9IHJvbGU/LmdldChcInZvaWNlQ29uZmlnXCIpXHJcblxyXG4gICAgICAgIC8vIOWKoOi9veWjsOmfs+aooeWei++8mum7mOiupOS4uuaZk+aZk1xyXG4gICAgICAgIGlmKHJvbGU/LmdldCgnZ2VuZGVyJyk9PSfnlLcnKXtcclxuICAgICAgICAgIHRoaXMuU1NNTFJvbGVWb2ljZSA9IFwiemgtQ04tWXVueWVOZXVyYWxcIlxyXG4gICAgICAgICAgaWYodm9pY2VDb25maWcucHJvdmlkZXI9PVwiZG91YmFvXCIpe1xyXG4gICAgICAgICAgICB0aGlzLlNTTUxSb2xlVm9pY2UgPSBcInpoX21hbGVfeWFuZ2d1YW5ncWluZ25pYW5fZW1vX3YyX21hcnNfYmlndHRzXCJcclxuICAgICAgICAgIH1cclxuICAgICAgICB9ZWxzZXtcclxuICAgICAgICAgIHRoaXMuU1NNTFJvbGVWb2ljZSA9IFwiemgtQ04tWGlhb3hpYW9OZXVyYWxcIlxyXG4gICAgICAgICAgaWYodm9pY2VDb25maWcucHJvdmlkZXI9PVwiZG91YmFvXCIpe1xyXG4gICAgICAgICAgICB0aGlzLlNTTUxSb2xlVm9pY2UgPSBcInpoX2ZlbWFsZV9zaHVhbmdrdWFpc2lzaV9lbW9fdjJfbWFyc19iaWd0dHNcIlxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5TU01MUm9sZVZvaWNlID0gcm9sZT8uZ2V0KFwidm9pY2VDb25maWdcIik/LnZvaWNlIHx8IHRoaXMuU1NNTFJvbGVWb2ljZSBcclxuICAgICAgICBsZXQgU1NNTFByb21wdFRlbXBsYXRlID0gYXdhaXQgZ2V0Rm9ybWF0VHBsKFByb21wdFRwbFRhbGtTU01MT3V0cHV0Q29kZSx7XHJcbiAgICAgICAgICAgIFNTTUxSb2xlVm9pY2U6IHRoaXMuU1NNTFJvbGVWb2ljZSwgLy8gU1NNTCBcclxuICAgICAgICB9KVxyXG5cclxuICAgICAgICBsZXQgcHJvbXB0ID0gcm9sZS5nZXQoXCJwcm9tcHRcIikgfHwgXCLor7fkvaDmia7mvJTpo57noIFBSeeahOS6uuW3peaZuuiDveS4k+WutuOAglwiXHJcbiAgICAgICAgcHJvbXB0ICs9IFNTTUxQcm9tcHRUZW1wbGF0ZTtcclxuICAgICAgICBsZXQgcHJvbXB0TXNnOkZtb2RlQ2hhdE1lc3NhZ2UgPSB7cm9sZTpcInVzZXJcIixjb250ZW50OnByb21wdCxoaWRkZW46dHJ1ZX1cclxuXHJcbiAgICAgICAgLy8g5p+l6YeNXHJcbiAgICAgICAgbGV0IGNvbnRlbnQgPSB0aGlzLm1lc3NhZ2VMaXN0Py5tYXAoaXRlbT0+aXRlbT8uY29udGVudCkuam9pbigpXHJcbiAgICAgICAgaWYoY29udGVudC5pbmRleE9mKHByb21wdCk+LTEpe1xyXG4gICAgICAgICAgICAvLyDmj5DnpLror43lt7Lnu4/lrZjlnKhcclxuICAgICAgICAgICAgcmV0dXJuXHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIOihpeWFqOaPkOekuuivjVxyXG4gICAgICAgIGxldCBzeXN0ZW1JbmRleCA9IHRoaXMubWVzc2FnZUxpc3Q/LmZpbmRJbmRleChpdGVtPT5pdGVtPy5yb2xlPT1cInN5c3RlbVwiKTtcclxuICAgICAgICBsZXQgaW5zZXJ0SW5kZXggPSBzeXN0ZW1JbmRleCsxXHJcbiAgICAgICAgdGhpcy5tZXNzYWdlTGlzdC5zcGxpY2UoaW5zZXJ0SW5kZXgsMCxwcm9tcHRNc2cpXHJcbiAgICAgICAgcmV0dXJuIFxyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiDop5LoibLmj5DnpLror41cclxuICAgICAqIEByZXR1cm5zIFxyXG4gICAgICovXHJcbiAgICBsb2FkUm9sZVByb21wdCgpe1xyXG4gICAgICAgIC8vIOinkuiJsuaPkOekulxyXG4gICAgICAgIGxldCBwcm9tcHQgPSB0aGlzLnJvbGU/LmdldChcInByb21wdFwiKVxyXG4gICAgICAgIGxldCBwcm9tcHRNc2c6Rm1vZGVDaGF0TWVzc2FnZSA9IHtyb2xlOlwidXNlclwiLGNvbnRlbnQ6cHJvbXB0LGhpZGRlbjp0cnVlfVxyXG4gICAgICAgIGlmKCFwcm9tcHQpIHJldHVybiAvLyDml6Dmj5DnpLror43ml6DpnIDmt7vliqBcclxuICAgICAgICAvLyDlhoXlrrnmo4Dmn6VcclxuICAgICAgICBsZXQgY29udGVudCA9IHRoaXMubWVzc2FnZUxpc3Q/Lm1hcChpdGVtPT5pdGVtPy5jb250ZW50KS5qb2luKClcclxuICAgICAgICBpZihjb250ZW50LmluZGV4T2YocHJvbXB0KT4tMSl7XHJcbiAgICAgICAgICAgIC8vIOaPkOekuuivjeW3sue7j+WtmOWcqFxyXG4gICAgICAgICAgICByZXR1cm5cclxuICAgICAgICB9XHJcbiAgICAgICAgLy8g6KGl5YWo5o+Q56S66K+NXHJcbiAgICAgICAgbGV0IHN5c3RlbUluZGV4ID0gdGhpcy5tZXNzYWdlTGlzdD8uZmluZEluZGV4KGl0ZW09Pml0ZW0/LnJvbGU9PVwic3lzdGVtXCIpO1xyXG4gICAgICAgIGxldCBpbnNlcnRJbmRleCA9IHN5c3RlbUluZGV4KzFcclxuICAgICAgICB0aGlzLm1lc3NhZ2VMaXN0LnNwbGljZShpbnNlcnRJbmRleCwwLHByb21wdE1zZylcclxuICAgICAgICAvLyBjb25zb2xlLmxvZyh0aGlzLm1lc3NhZ2VMaXN0KVxyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiDlj5HpgIHmtojmga9cclxuICAgICAqIEBwYXJhbSBtZXNzYWdlIFxyXG4gICAgICogQHBhcmFtIGltYWdlVXJsIFxyXG4gICAgICovXHJcbiAgICBhc3luYyBzZW5kTWVzc2FnZShtZXNzYWdlOnN0cmluZz1cIkZtb2RlQWlUZXN05rWL6K+V6Zeu6aKYXCIsaW1hZ2VVcmw/OnN0cmluZyxvbkNvbXBsZXRlPzpGdW5jdGlvbixldmVudE1hcD86Rm1vZGVDaGF0RXZlbnRNYXAsdm9pY2U/OkZtb2RlQ2hhdE1lc3NhZ2VWb2ljZSl7XHJcbiAgICAgICAgLy8g5Y+R5raI5oGv6Ieq5Yqo572u5bqVXHJcbiAgICAgICAgdGhpcy5zY3JvbGxUb0JvdHRvbSYmdGhpcy5zY3JvbGxUb0JvdHRvbSgpO1xyXG5cclxuICAgICAgICAvLyDkuLrmtojmga/liJfooajooaXlhajmj5DnpLror41cclxuICAgICAgICAvLyBhd2FpdCB0aGlzLmxvYWRUYWxrU3lzdGVtUHJvbXB0KHRoaXMucm9sZSk7XHJcbiAgICAgICAgdGhpcy5pc1Byb21wdE1lc3NhZ2VBcmVhU2hvdyA9IGZhbHNlOyAvLyDlj5HpgIHnrKzkuIDmnaHmtojmga/lkI7vvIzlhbPpl63mj5DnpLrnnIvmnb9cclxuICAgICAgICB0aGlzLmxvYWRSb2xlUHJvbXB0KCk7XHJcbiAgICAgICAgLy8g55So5oi36L6T5YWl5raI5oGv77yM5re75Yqg5Yiw5Y6G5Y+y5raI5oGv5riF5Y2V5LitXHJcbiAgICAgICAgaWYoIWltYWdlVXJsKXsgLy8g57qv5paH5pysXHJcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKFwi57qv5paH5pysXCIpXHJcbiAgICAgICAgICAgIGxldCBtc2c6Rm1vZGVDaGF0TWVzc2FnZSA9IHtcclxuICAgICAgICAgICAgICAgIHJvbGU6XCJ1c2VyXCIsXHJcbiAgICAgICAgICAgICAgICBjb250ZW50Om1lc3NhZ2UsXHJcbiAgICAgICAgICAgICAgICBjb21wbGV0ZTp0cnVlLFxyXG4gICAgICAgICAgICAgICAgY3JlYXRlZEF0Om5ldyBEYXRlKClcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZih2b2ljZSl7XHJcbiAgICAgICAgICAgICAgICBtc2cudm9pY2UgPSB7aWQ6dm9pY2U/LmlkLGR1cmF0aW9uOnZvaWNlPy5kdXJhdGlvbn1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2VMaXN0LnB1c2gobXNnKVxyXG4gICAgICAgIH1lbHNleyAvLyDluKblm77niYdcclxuICAgICAgICAgICAgbGV0IG1zZzpGbW9kZUNoYXRNZXNzYWdlID0ge1xyXG4gICAgICAgICAgICAgICAgXCJyb2xlXCI6IFwidXNlclwiLFxyXG4gICAgICAgICAgICAgICAgXCJjb250ZW50XCI6IFtcclxuICAgICAgICAgICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcImltYWdlX3VybFwiLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBcImltYWdlX3VybFwiOiB7XCJ1cmxcIjppbWFnZVVybH0sXHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFwidHlwZVwiOiBcInRleHRcIiwgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFwidGV4dFwiOiBtZXNzYWdlXHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIF0sXHJcbiAgICAgICAgICAgICAgICBjb21wbGV0ZTp0cnVlLFxyXG4gICAgICAgICAgICAgICAgY3JlYXRlZEF0Om5ldyBEYXRlKClcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZih2b2ljZSl7XHJcbiAgICAgICAgICAgICAgICBtc2cudm9pY2UgPSB7aWQ6dm9pY2U/LmlkfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZUxpc3QucHVzaCh7XHJcbiAgICAgICAgICAgICAgICBcInJvbGVcIjogXCJ1c2VyXCIsXHJcbiAgICAgICAgICAgICAgICBcImNvbnRlbnRcIjogW1xyXG4gICAgICAgICAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwiaW1hZ2VfdXJsXCIsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFwiaW1hZ2VfdXJsXCI6IHtcInVybFwiOmltYWdlVXJsfSxcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgXCJ0eXBlXCI6IFwidGV4dFwiLCBcclxuICAgICAgICAgICAgICAgICAgICAgICAgXCJ0ZXh0XCI6IG1lc3NhZ2VcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgXSxcclxuICAgICAgICAgICAgICAgIGNvbXBsZXRlOnRydWUsXHJcbiAgICAgICAgICAgICAgICBjcmVhdGVkQXQ6bmV3IERhdGUoKVxyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgIH1cclxuICAgICAgICAvLyDliJvlu7rlubblj5HotbfkuIDmnaHmlrDnmoTmtojmga/ooaXlhahcclxuICAgICAgICAvLyBjb25zb2xlLmxvZyhcInNlbmRcIix0aGlzLm1lc3NhZ2VMaXN0KVxyXG4gICAgICAgIGxldCBjb21wbGV0aW9uID0gbmV3IEZtb2RlQ2hhdENvbXBsZXRpb24odGhpcy5maXhNZXNzYWdlTGlzdCh0aGlzLm1lc3NhZ2VMaXN0KSx7XHJcbiAgICAgICAgICAgIG1vZGVsOnRoaXMuY3VycmVudE1vZGVsPy5nZXQoXCJjb2RlXCIpIHx8IFwiZm1vZGUtMS42LWNuXCJcclxuICAgICAgICB9KVxyXG5cclxuICAgICAgICAvLyDnlJ/lkb3lkajmnJ/vvJrmtojmga/ojrflj5blrozmiJBcclxuICAgICAgICBpZih0aGlzLm9uVXNlclNlbmQpe1xyXG4gICAgICAgICAgICBsZXQgc2VuZFJlc3VsdCA9IGF3YWl0IHRoaXMub25Vc2VyU2VuZCh0aGlzLHRoaXMubWVzc2FnZUxpc3RbdGhpcy5tZXNzYWdlTGlzdD8ubGVuZ3RoLTFdKVxyXG4gICAgICAgICAgICBpZighc2VuZFJlc3VsdCkgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgIHRoaXMudXNlcklucHV0ID0gXCJcIjtcclxuICAgICAgICB0aGlzLnVzZXJJbWFnZSA9IFwiXCI7XHJcbiAgICAgICAgLy8gY29uc29sZS5sb2codGhpcy5jdXJyZW50TW9kZWw/LnRvSlNPTigpKVxyXG4gICAgICAgIC8vIOaMgee7reabtOaWsOS6i+S7tuaOqOmAgeeahOa2iOaBr+S9k+WGheWuueiHs+a2iOaBr+WIl+ihqFxyXG4gICAgICAgIGxldCBpc0RpcmVjdCA9IHRoaXMuaXNEaXJlY3QgfHwgZmFsc2VcclxuICAgICAgICBpZih0aGlzLmlzVGFsa01vZGUpe1xyXG4gICAgICAgICAgICBpc0RpcmVjdCA9IHRydWVcclxuICAgICAgICB9XHJcbiAgICAgICAgbGV0IHNlbmQkID0gY29tcGxldGlvbi5zZW5kQ29tcGxldGlvbih7XHJcbiAgICAgICAgICAgIGlzRGlyZWN0OmlzRGlyZWN0LFxyXG4gICAgICAgICAgICBvbkNvbXBsZXRlOm9uQ29tcGxldGV8fG51bGxcclxuICAgICAgICB9KS5waXBlKGZpbmFsaXplKGFzeW5jICgpPT57IC8vIOeuoemBk2ZpbmFsaXpl5pu/5Luj5LqG5pen54mI55qEKGNvbXBsZXRlKT0+e31cclxuXHJcbiAgICAgICAgICAgIGlmKHRoaXMuaXNUYWxrTW9kZSl7XHJcbiAgICAgICAgICAgICAgICBsZXQgY29udGVudCA9IHRoaXMubWVzc2FnZUxpc3RbY29tcGxldGlvbi5pbmRleE9mTGlzdF0/LmNvbnRlbnQ7XHJcbiAgICAgICAgICAgICAgICBsZXQgdm9pY2UgPSBhd2FpdCB0aGlzLmdldFZvaWNlQnlDb250ZW50VGV4dChjb250ZW50LGV2ZW50TWFwKTtcclxuICAgICAgICAgICAgICAgIGV2ZW50TWFwPy5vblNTTUxDb21wbGV0ZSYmZXZlbnRNYXA/Lm9uU1NNTENvbXBsZXRlKHZvaWNlKTtcclxuICAgICAgICAgICAgICAgIHRoaXMubWVzc2FnZUxpc3RbY29tcGxldGlvbi5pbmRleE9mTGlzdF0udm9pY2UgPSB2b2ljZTtcclxuICAgICAgICAgICAgICAgIHRoaXMucGxheUNoYXRWb2ljZSh0aGlzLnZvaWNlTWFwW3ZvaWNlPy5pZF0se1xyXG4gICAgICAgICAgICAgICAgICAgIG9uUmVzdWx0OihyZXN1bHQ6YW55KT0+e1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZihyZXN1bHQ/LmR1cmF0aW9uKXtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubWVzc2FnZUxpc3RbY29tcGxldGlvbi5pbmRleE9mTGlzdF0udm9pY2UuZHVyYXRpb24gPSByZXN1bHQ/LmR1cmF0aW9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2VMaXN0W2NvbXBsZXRpb24uaW5kZXhPZkxpc3RdLmNvbXBsZXRlID0gdHJ1ZVxyXG4gICAgICAgIH0pKS5zdWJzY3JpYmUobWVzc2FnZT0+e1xyXG4gICAgICAgICAgICBpZighdGhpcy5tZXNzYWdlTGlzdFtjb21wbGV0aW9uLmluZGV4T2ZMaXN0XSl7XHJcbiAgICAgICAgICAgICAgICBldmVudE1hcD8ub25NZXNzYWdlU3RhcnQ/LihtZXNzYWdlKVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2VMaXN0W2NvbXBsZXRpb24uaW5kZXhPZkxpc3RdID0gbWVzc2FnZTtcclxuICAgICAgICAgICAgdGhpcy5sYXRlc3RBSVJlc3BvbnNlID0gdGhpcy5nZXRDb250ZW50VGV4dChtZXNzYWdlPy5jb250ZW50KVxyXG4gICAgICAgICAgIFxyXG4gICAgICAgICAgICBsZXQgc2F2ZWRMaXN0ID0gdGhpcy5jaGF0U2Vzc2lvbj8uZ2V0KFwibWVzc2FnZUxpc3RcIik/Lmxlbmd0aDtcclxuICAgICAgICAgICAgICAgIC8vIOeUn+WRveWRqOacn++8muS8muivneWIm+W7uuWQju+8jOacieaWsOa2iOaBr+aXtu+8jOWIm+W7uuS/neWtmOS8muivnVxyXG4gICAgICAgICAgICBpZih0aGlzLm1lc3NhZ2VMaXN0Py5sZW5ndGggPiBzYXZlZExpc3Qpe1xyXG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coXCJjeWNsZeaWsOS8muivnVwiKVxyXG4gICAgICAgICAgICAgICAgdGhpcy5zYXZlQ2hhdFNlc3Npb24oKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYobWVzc2FnZT8uY29tcGxldGUpe1xyXG4gICAgICAgICAgICAgICAgLy8g55Sf5ZG95ZGo5pyf77ya5raI5oGv6I635Y+W5a6M5oiQXHJcbiAgICAgICAgICAgICAgICB0aGlzLm9uTWVzc2FnZSYmdGhpcy5vbk1lc3NhZ2UodGhpcyx0aGlzLm1lc3NhZ2VMaXN0W3RoaXMubWVzc2FnZUxpc3Q/Lmxlbmd0aC0xXSlcclxuICAgICAgICAgICAgICAgIC8vIOa2iOaBr+WPkemAgeWujOaIkOWQju+8jOS/neWtmOiBiuWkqeiusOW9lVxyXG4gICAgICAgICAgICAgICAgdGhpcy5zYXZlQ2hhdFNlc3Npb24oKTsgXHJcbiAgICAgICAgICAgICAgICBzZW5kJC51bnN1YnNjcmliZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKG1lc3NhZ2UpXHJcbiAgICAgICAgICAgIHRoaXMuc2Nyb2xsVG9Cb3R0b20mJnRoaXMuc2Nyb2xsVG9Cb3R0b20oKTtcclxuICAgICAgICB9KVxyXG4gICAgfVxyXG5cclxuICAgIGdldFZvaWNlQnlDb250ZW50VGV4dChjb250ZW50OnN0cmluZ3xDaGF0SW1hZ2VDb250ZW50SXRlbVtdLGV2ZW50TWFwPzpGbW9kZUNoYXRFdmVudE1hcCxwcm9tcHRFbmFibGVkOmJvb2xlYW49ZmFsc2UpOlByb21pc2U8Rm1vZGVDaGF0TWVzc2FnZVZvaWNlPntcclxuICAgICAgICBsZXQgY29udGVudFRleHQgPSB0aGlzLmdldENvbnRlbnRUZXh0KGNvbnRlbnQpO1xyXG4gICAgICAgIGxldCBDaGF0Vm9pY2UgPSBQYXJzZS5PYmplY3QuZXh0ZW5kKFwiQ2hhdFZvaWNlXCIpO1xyXG4gICAgICAgIGxldCBjaGF0Vm9pY2UgPSBuZXcgQ2hhdFZvaWNlKCk7XHJcbiAgICAgICAgbGV0IGNvbnRlbnRTU01MID0gYGA7XHJcbiAgICAgICAgbGV0IHZvaWNlQ29uZmlnOmFueSA9IHRoaXMudm9pY2VDb25maWcgfHwgdGhpcy5yb2xlPy5nZXQoXCJ2b2ljZUNvbmZpZ1wiKVxyXG4gICAgICAgIHRoaXMuU1NNTFJvbGVWb2ljZSA9IHZvaWNlQ29uZmlnPy52b2ljZSB8fCB0aGlzLlNTTUxSb2xlVm9pY2UgXHJcblxyXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSxyZWplY3QpPT57XHJcbiAgICAgICAgICAgIGxldCByZXNvbHZlQ2hhdFZvaWNlID0gYXN5bmMgKCk9PntcclxuICAgICAgICAgICAgICAgIGNoYXRWb2ljZS5zZXQoXCJjb250ZW50XCIsY29udGVudFRleHQpO1xyXG4gICAgICAgICAgICAgICAgY2hhdFZvaWNlLnNldChcInNzbWxcIixjb250ZW50U1NNTCk7XHJcbiAgICAgICAgICAgICAgICBjaGF0Vm9pY2Uuc2V0KFwicm9sZVwiLFwiYXNzaXN0YW50XCIpO1xyXG4gICAgICAgICAgICAgICAgbGV0IGNvbXBhbnkgPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbShcImNvbXBhbnlcIilcclxuICAgICAgICAgICAgICAgIGNvbXBhbnkmJmNoYXRWb2ljZS5zZXQoXCJjb21wYW55XCIse19fdHlwZTpcIlBvaW50ZXJcIixjbGFzc05hbWU6XCJDb21wYW55XCIsb2JqZWN0SWQ6Y29tcGFueX0pO1xyXG4gICAgICAgICAgICAgICAgUGFyc2UuVXNlci5jdXJyZW50KCk/LmlkJiZjaGF0Vm9pY2Uuc2V0KFwidXNlclwiLFBhcnNlLlVzZXIuY3VycmVudCgpLnRvUG9pbnRlcigpKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuY2hhdFNlc3Npb24/LmlkJiZjaGF0Vm9pY2Uuc2V0KFwic2Vzc2lvblwiLHRoaXMuY2hhdFNlc3Npb24/LnRvUG9pbnRlcigpKTtcclxuICAgICAgICAgICAgICAgIGNoYXRWb2ljZSA9IGF3YWl0IGNoYXRWb2ljZS5zYXZlKCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnZvaWNlTWFwW2NoYXRWb2ljZT8uaWRdID0gY2hhdFZvaWNlO1xyXG4gICAgICAgICAgICAgICAgcmVzb2x2ZSh7XHJcbiAgICAgICAgICAgICAgICAgICAgaWQ6Y2hhdFZvaWNlPy5pZCxcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIOaWueazleS4gO+8mumrmOe6p+ivremfs+ebtOaOpeivu+aWh+acrO+8jOmAn+W6puW/q++8jOS9hue7huiKguaDhee7quagh+iusOS4jei2s+OAglxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgIGlmKHByb21wdEVuYWJsZWQ9PWZhbHNlKXtcclxuICAgICAgICAgICAgICAgIGxldCBwcm92aWRlciA9IHZvaWNlQ29uZmlnPy5wcm92aWRlciB8fCBcIm1pY3Jvc29mdFwiXHJcbiAgICAgICAgICAgICAgICBsZXQgcmF0ZSA9IHZvaWNlQ29uZmlnPy5yYXRlXHJcbiAgICAgICAgICAgICAgICBsZXQgcmF0ZVN0YXJ0ID0gcmF0ZT9gPHByb3NvZHkgcmF0ZT1cIiR7cmF0ZX1cIj5gOlwiXCJcclxuICAgICAgICAgICAgICAgIGxldCByYXRlRW5kID0gcmF0ZT9gPC9wcm9zb2R5PmA6XCJcIlxyXG4gICAgICAgICAgICAgICAgY29udGVudFNTTUwgPSBgPHNwZWFrIHByb3ZpZGVyPVwiJHtwcm92aWRlcn1cIj4ke3JhdGVTdGFydH08dm9pY2UgbmFtZT1cIiR7dGhpcy5TU01MUm9sZVZvaWNlfVwiPiR7Y29udGVudFRleHR9PC92b2ljZT4ke3JhdGVFbmR9PC9zcGVhaz5gXHJcbiAgICAgICAgICAgICAgICBpZihwcm92aWRlcj09XCJkb3ViYW9cIil7XHJcbiAgICAgICAgICAgICAgICAgICAgY29udGVudFNTTUwgPSBjb250ZW50VGV4dFxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmVzb2x2ZUNoYXRWb2ljZSgpXHJcbiAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBwcm9tcHRFbmFibGVkID09IHRydWVcclxuICAgICAgICAgICAgICog5pa55rOV5LqM77ya6YCa6L+H5aSn5qih5Z6L5YaN5qyh5ou85o6lU1NNTOiEmuacrO+8jOWunueOsOabtOS8mOi0qOeahOivremfs+agh+iusO+8jOS9huaYr+eUn+aIkOaXtumXtOWkquaFolxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgaWYocHJvbXB0RW5hYmxlZD09dHJ1ZSl7XHJcbiAgICAgICAgICAgICAgICAvLyDmi7zmjqVQcm9tcHRcclxuICAgICAgICAgICAgICAgIGxldCBUZXh0U1NNTFByb21wdCA9IGF3YWl0IGdldEZvcm1hdFRwbChQcm9tcHRUcGxUYWxrVGV4dFNTTUxDb2RlLHtcclxuICAgICAgICAgICAgICAgICAgICBjb250ZW50OmNvbnRlbnRUZXh0LCAvLyDmlofmnKzlhoXlrrlcclxuICAgICAgICAgICAgICAgICAgICBTU01MUm9sZVZvaWNlOiB0aGlzLlNTTUxSb2xlVm9pY2UsIC8vIFNTTUwg5ryU6K+06ICFXHJcbiAgICAgICAgICAgICAgICB9KVxyXG5cclxuICAgICAgICAgICAgICAgIC8vIOeUn+aIkFNTTUxcclxuICAgICAgICAgICAgICAgIGxldCBjb21wbGV0aW9uID0gbmV3IEZtb2RlQ2hhdENvbXBsZXRpb24odGhpcy5maXhNZXNzYWdlTGlzdChbe1xyXG4gICAgICAgICAgICAgICAgICAgIHJvbGU6XCJ1c2VyXCIsXHJcbiAgICAgICAgICAgICAgICAgICAgY29udGVudDpUZXh0U1NNTFByb21wdFxyXG4gICAgICAgICAgICAgICAgfV0pLHtcclxuICAgICAgICAgICAgICAgICAgICBtb2RlbDp0aGlzLmN1cnJlbnRNb2RlbD8uZ2V0KFwiY29kZVwiKSB8fCBcImZtb2RlLTEuNi1jblwiXHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgbGV0IHNlbmQkID0gY29tcGxldGlvbi5zZW5kQ29tcGxldGlvbih7XHJcbiAgICAgICAgICAgICAgICAgICAgaXNEaXJlY3Q6dHJ1ZSxcclxuICAgICAgICAgICAgICAgIH0pLnN1YnNjcmliZShhc3luYyBtZXNzYWdlPT57XHJcbiAgICAgICAgICAgICAgICAgICAgaWYobWVzc2FnZT8uY29tcGxldGUpe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50U1NNTCA9IHRoaXMuZ2V0Q29udGVudFRleHQobWVzc2FnZT8uY29udGVudClcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZUNoYXRWb2ljZSgpXHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBcclxuICAgICAgICB9KVxyXG4gICAgfVxyXG4gICAgZ2V0Q29udGVudFRleHQoY29udGVudDpzdHJpbmd8Q2hhdEltYWdlQ29udGVudEl0ZW1bXSl7XHJcbiAgICAgICAgaWYodHlwZW9mIGNvbnRlbnQgPT0gXCJzdHJpbmdcIil7XHJcbiAgICAgICAgICAgIHJldHVybiBjb250ZW50XHJcbiAgICAgICAgfWVsc2V7XHJcbiAgICAgICAgICAgIHJldHVybiBjb250ZW50Py5bMF0/LnRleHQgfHwgYGBcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIFRUUyAtIOivremfs+WQiOaIkFxyXG4gICAgICogXHJcbiAgICAgKi9cclxuICAgIGFzeW5jIGluaXRUVFMoKTpQcm9taXNlPEZtb2RlVFRTfG51bGw+e1xyXG4gICAgICAgIHRoaXMudm9pY2VDb25maWcgPSB0aGlzLnZvaWNlQ29uZmlnIHx8IHRoaXMucm9sZT8uZ2V0KFwidm9pY2VDb25maWdcIilcclxuXHJcbiAgICAgICAgLy8gaWYodGhpcy50dHMpIHJldHVybiAvLyDlvoXmmI7noa5zdHPmnInmlYjmnJ/lkozmrKHmlbDov5vooYzkvJjljJbvvIzpgb/lhY3mr4/mrKHph43lpI3ojrflj5ZcclxuICAgICAgICBsZXQgY29uZmlnOmFueSA9IGF3YWl0IHRoaXMubmNsb3VkLmFwaWcoXCJ2b2ljZS90dHMvdG9rZW5cIix7XHJcbiAgICAgICAgICAgIGNvbXBhbnk6bG9jYWxTdG9yYWdlLmdldEl0ZW0oXCJjb21wYW55XCIpLFxyXG4gICAgICAgICAgICBwcm92aWRlcjp0aGlzLnZvaWNlQ29uZmlnPy5wcm92aWRlciB8fCBcIm1pY3Jvc29mdFwiXHJcbiAgICAgICAgfSlcclxuICAgICAgICBjb25maWcucHJvdmlkZXIgPSB0aGlzLnZvaWNlQ29uZmlnPy5wcm92aWRlclxyXG4gICAgICAgIGlmKCghY29uZmlnPy5wcm92aWRlcil8fGNvbmZpZz8ucHJvdmlkZXIgPT0gXCJtaWNyb3NvZnRcIil7XHJcbiAgICAgICAgICAgIC8vIGNvbmZpZy5wcm92aWRlciA9IG5ldyBGbW9kZVRUU1Byb3ZpZGVyTWljcm9zb2Z0KCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmKGNvbmZpZz8ucHJvdmlkZXIgPT0gXCJkb3ViYW9cIil7XHJcbiAgICAgICAgICAgIGNvbmZpZy5wcm92aWRlciA9IG5ldyBGbW9kZVRUU1Byb3ZpZGVyRG91YmFvKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbmZpZy52b2ljZUNvbmZpZyA9IHRoaXMudm9pY2VDb25maWdcclxuICAgICAgICAvLyDmnIlUVFPotYTmupDvvIzkvb/nlKjmg4Xnu6rlkIjmiJBcclxuICAgICAgICBjb25zb2xlLmxvZyhcImluaXRUVFNcIixjb25maWcpXHJcbiAgICAgICAgaWYoY29uZmlnPy50b2tlbiB8fCBjb25maWc/LnN0c1Rva2VuKXtcclxuICAgICAgICAgICAgbGV0IHR0cyA9IG5ldyBGbW9kZVRUUyhjb25maWcsdGhpcy51cGxvYWRTZXJ2KTtcclxuICAgICAgICAgICAgcmV0dXJuIHR0c1xyXG4gICAgICAgIH1lbHNle1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbFxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHZvaWNlTWFwOmFueSA9IHt9XHJcbiAgICBWb2ljZVRUU01hcDp7XHJcbiAgICAgICAgW2tleTpzdHJpbmddOkZtb2RlVFRTXHJcbiAgICB9ID0ge31cclxuICAgIHN0b3BQbGF5aW5nVm9pY2UoKXtcclxuICAgICAgICBPYmplY3QudmFsdWVzKHRoaXMuVm9pY2VUVFNNYXApLmZvckVhY2godHRzPT57XHJcbiAgICAgICAgICAgIGlmKHR0cz8uaXNQbGF5aW5nKXtcclxuICAgICAgICAgICAgICAgIHR0cz8uc3RvcCgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSlcclxuICAgIH1cclxuICAgIGFzeW5jIHBsYXlDaGF0Vm9pY2Uodm9pY2U6UGFyc2UuT2JqZWN0LGV2ZW50TWFwPzphbnkpOlByb21pc2U8Rm1vZGVUVFN8bnVsbD57XHJcbiAgICAgICAgbGV0IHR0cyA9IGF3YWl0IHRoaXMuaW5pdFRUUygpO1xyXG4gICAgICAgIC8vIHR0cy5hdXRvU2F2ZUNoYXRTZXNzaW9uID0gYXV0b1NhdmVDaGF0U2Vzc2lvbjtcclxuICAgICAgICBjb25zb2xlLmxvZyhcInBsYXlDaGF0Vm9pY2VcIix0dHMpXHJcbiAgICAgICAgaWYodHRzKXtcclxuICAgICAgICAgICAgdHJ5e1xyXG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2codGV4dE9yU1NNTClcclxuICAgICAgICAgICAgICAgIHR0cy52b2ljZUNvbmZpZyA9IHRoaXMudm9pY2VDb25maWdcclxuICAgICAgICAgICAgICAgIC8vIOWujOaVtOeahOa2iOaBr++8jOmAmui/h1RUU+WQiOaIkOi/m+ihjOiusuivnVxyXG4gICAgICAgICAgICAgICAgdGhpcy5wbGF5QW5pbWF0aW9uKFwidGFsa2luZ1wiKSAvLyBUYWxraW5n5Yqo55S777yM5pqC5pe255Sod2F0aW5n5Luj5pu/XHJcbiAgICAgICAgICAgICAgICB0dHMuc3BlYWtBc3luYyh2b2ljZT8uZ2V0KFwic3NtbFwiKSx2b2ljZSx7XHJcbiAgICAgICAgICAgICAgICAgICAgb25TdGFydDooY2hhdFZvaWNlPzphbnkpPT57XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50TWFwPy5vblN0YXJ0JiZldmVudE1hcD8ub25TdGFydChjaGF0Vm9pY2UpOyAvLyDkuovku7bkvKDpgJJcclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgIG9uTG9hZGVkOihhdWRpbzphbnkpPT57XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50TWFwPy5vbkxvYWRlZCYmZXZlbnRNYXA/Lm9uTG9hZGVkKGF1ZGlvKTsgLy8g5LqL5Lu25Lyg6YCSXHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICBvblJlc3VsdDoocmVzdWx0OmFueSk9PnsgLy8ge2R1cmF0aW9uOm51bWJlcn1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRNYXA/Lm9uUmVzdWx0JiZldmVudE1hcD8ub25SZXN1bHQocmVzdWx0KTsgLy8g5LqL5Lu25Lyg6YCSXHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICBvblN0b3A6ICgpPT57XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50TWFwPy5vblN0b3AmJmV2ZW50TWFwPy5vblN0b3AoKTsgLy8g5LqL5Lu25Lyg6YCSXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGxheUFuaW1hdGlvbihcIndhaXRpbmdcIikgLy8gVGFsa2luZ+WKqOeUu++8jOaaguaXtueUqHdhdGluZ+S7o+abv1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIH1jYXRjaCh0dHNlcnIpe1xyXG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS5lcnJvcih0dHNlcnIpXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5Wb2ljZVRUU01hcFt2b2ljZS5pZF0gPSB0dHM7XHJcbiAgICAgICAgICAgIHJldHVybiB0dHNcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG51bGxcclxuXHJcbiAgICAvLyDml6BUU1PotYTmupDvvIzosIPnlKhFZGdlIFNwZWVjaFxyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiDkv53lrZjljZXmrKHkvJror51cclxuICAgICAqL1xyXG4gICAgYXN5bmMgc2F2ZUNoYXRTZXNzaW9uKCl7XHJcbiAgICAgICAgaWYodGhpcy5zZXNzaW9uSWQgPT0gXCJuZXdcIil7XHJcbiAgICAgICAgICAgIHRoaXMuY2hhdFNlc3Npb24gPSBuZXcgdGhpcy5DaGF0U2Vzc2lvbigpXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmNoYXRTZXNzaW9uLnNldChcInRpdGxlXCIsdGhpcy5nZW5UaXRsZSgpKVxyXG4gICAgICAgIHRoaXMuY2hhdFNlc3Npb24uc2V0KFwicm9sZVwiLHRoaXMucm9sZT8udG9Qb2ludGVyKCkpXHJcbiAgICAgICAgdGhpcy5jaGF0U2Vzc2lvbi5zZXQoXCJtZXNzYWdlTGlzdFwiLHRoaXMubWVzc2FnZUxpc3QpXHJcbiAgICAgICAgdGhpcy5jaGF0U2Vzc2lvbi5zZXQoXCJ1c2VyXCIsUGFyc2UuVXNlci5jdXJyZW50KCk/LnRvUG9pbnRlcigpKVxyXG4gICAgICAgIHRoaXMuY2hhdFNlc3Npb24gPSBhd2FpdCB0aGlzLmNoYXRTZXNzaW9uLnNhdmUoKTtcclxuXHJcbiAgICAgICAgdGhpcy5vbkNoYXRTYXZlZCYmdGhpcy5vbkNoYXRTYXZlZCh0aGlzKTtcclxuICAgICAgICBcclxuICAgICAgICB0aGlzLnNlc3Npb25JZCA9IHRoaXMuY2hhdFNlc3Npb24/LmlkXHJcbiAgICAgICAgaWYodGhpcy5zZXNzaW9uSWQpeyBcclxuICAgICAgICAgICAgLy8g5L+u5pS5VVJM5Zyw5Z2A5Li6c2Vzc2lvbklk77yM5pa55L6/5YiG5Lqr5oiW5YiH5o2iIOinkuiJsumhtemdoiA9PiDkvJror53pobXpnaJcclxuICAgICAgICAgICAgbGV0IG5ld0hyZWYgPSBgJHt3aW5kb3cubG9jYXRpb24ub3JpZ2lufS9jaGF0L3Byby9jaGF0LyR7dGhpcy5zZXNzaW9uSWR9YFxyXG4gICAgICAgICAgICBpZih3aW5kb3cubG9jYXRpb24/LnBhdGhuYW1lPy5pbmRleE9mKFwiY2hhdC9zZXNzaW9uXCIpPi0xKXtcclxuICAgICAgICAgICAgICAgIG5ld0hyZWYgPSBgJHt3aW5kb3cubG9jYXRpb24ub3JpZ2lufS9jaGF0L3Nlc3Npb24vY2hhdC8ke3RoaXMuc2Vzc2lvbklkfWBcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZih0aGlzLm1vZGU9PVwibW9kYWxcIil7XHJcbiAgICAgICAgICAgICAgICBuZXdIcmVmID0gd2luZG93LmxvY2F0aW9uLmhyZWY7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgbmV3SHJlZiA9IHRoaXMuZ2V0SW52aXRlVXJsKG5ld0hyZWYpXHJcbiAgICAgICAgICAgIHdpbmRvdy5oaXN0b3J5LnJlcGxhY2VTdGF0ZShudWxsLCBudWxsLCBuZXdIcmVmK3dpbmRvdy5sb2NhdGlvbi5zZWFyY2gpO1xyXG4gICAgICAgICAgICAvLyDkv67mlLnmnIDmlrDmnaFjaGF0TGlzdOaVsOaNrlxyXG4gICAgICAgICAgICBsZXQgbmV3Q2hhdCA9IHtcclxuICAgICAgICAgICAgICAgIHNpZDp0aGlzLmNoYXRTZXNzaW9uPy5pZCxcclxuICAgICAgICAgICAgICAgIHJpZDp0aGlzLnJvbGU/LmlkLFxyXG4gICAgICAgICAgICAgICAgbmFtZTp0aGlzLnJvbGU/LmdldCgnbmFtZScpLFxyXG4gICAgICAgICAgICAgICAgbWVzc2FnZTp0aGlzLmNoYXRTZXNzaW9uPy5nZXQoJ21lc3NhZ2VMaXN0Jyk/Llt0aGlzLmNoYXRTZXNzaW9uPy5nZXQoJ21lc3NhZ2VMaXN0Jyk/Lmxlbmd0aC0xXT8uY29udGVudD8uc2xpY2UoMCwyMCksXHJcbiAgICAgICAgICAgICAgICBsYXRlc3Q6dGhpcy5jaGF0U2Vzc2lvbj8uY3JlYXRlZEF0XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYodGhpcy5jaGF0U2VydiYmIXRoaXMuY2hhdFNlcnY/LmNoYXRMaXN0Py5sZW5ndGgpIHRoaXMuY2hhdFNlcnYuY2hhdExpc3QgPSBbXVxyXG4gICAgICAgICAgICBsZXQgaW5kZXggPSB0aGlzLmNoYXRTZXJ2Py5jaGF0TGlzdD8uZmluZChpdGVtPT5pdGVtPy5zaWQ9PW5ld0NoYXQ/LnNpZClcclxuICAgICAgICAgICAgaWYoaW5kZXg+LTEpe1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jaGF0U2Vydi5jaGF0TGlzdFtpbmRleF0gPSBuZXdDaGF0O1xyXG4gICAgICAgICAgICB9IGVsc2V7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNoYXRTZXJ2Py5jaGF0TGlzdC51bnNoaWZ0KG5ld0NoYXQpXHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZ2V0SW52aXRlVXJsKHVybCl7XHJcbiAgICAgICAgbGV0IHUgPSBuZXcgVVJMKHVybCk7XHJcbiAgICAgICAgbGV0IGlkID0gUGFyc2UuVXNlcj8uY3VycmVudCgpPy5pZFxyXG4gICAgICAgIC8vIOmZhOWKoGludml0ZeWPguaVsFxyXG4gICAgICAgIHUuc2VhcmNoUGFyYW1zLnNldChcImludml0ZVwiLGlkKVxyXG4gICAgICAgIHJldHVybiB1LmhyZWZcclxuICAgICAgfVxyXG4gICAgLy8g5qC55o2u6IGK5aSp5YaF5a655Y+K6Zeu6aKY77yM55Sf5oiQ5qCH6aKYXHJcbiAgICBnZW5UaXRsZSgpe1xyXG4gICAgICAgIGlmKHRoaXMudGl0bGUpIHJldHVybiB0aGlzLnRpdGxlXHJcbiAgICAgICAgbGV0IGNvbnRlbnQ6c3RyaW5nfEFycmF5PENoYXRJbWFnZUNvbnRlbnRJdGVtPiA9ICB0aGlzLm1lc3NhZ2VMaXN0LmZpbmQoaXRlbT0+aXRlbS5yb2xlPT1cInVzZXJcIik/LmNvbnRlbnRcclxuICAgICAgICBpZih0eXBlb2YgY29udGVudD09XCJzdHJpbmdcIil7IC8vIOaIquWbvuaWh+acrOWGheWuueaWh+Wtl+mDqOWIhlxyXG4gICAgICAgICAgICB0aGlzLnRpdGxlID0gY29udGVudD8uc2xpY2UoMCwxNSkgfHwgXCJcIlxyXG4gICAgICAgIH1cclxuICAgICAgICBpZih0eXBlb2YgY29udGVudD09XCJvYmplY3RcIil7IC8vIOaIquWbvuWkjeWQiOWGheWuueaWh+Wtl+mDqOWIhlxyXG4gICAgICAgICAgICB0aGlzLnRpdGxlID0gY29udGVudD8uZmluZChpdGVtPT5pdGVtPy50ZXh0KT8udGV4dCB8fCBcIlwiXHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0aGlzLnRpdGxlXHJcbiAgICB9XHJcbiAgICBmaXhNZXNzYWdlTGlzdChtZXNzYWdlczpGbW9kZUNoYXRNZXNzYWdlW10pe1xyXG4gICAgICAgIHJldHVybiBtZXNzYWdlcy5tYXAobXNnPT57cmV0dXJuIHtyb2xlOm1zZy5yb2xlLGNvbnRlbnQ6bXNnLmNvbnRlbnR9fSlcclxuICAgIH1cclxuXHJcbiAgICBub3dTdHIoKXtcclxuICAgICAgICBsZXQgbm93ID0gbmV3IERhdGUoKTtcclxuICAgICAgICByZXR1cm4gYCR7bm93LmdldEZ1bGxZZWFyKCl9LyR7bm93LmdldE1vbnRoKCkrMX0vJHtub3cuZ2V0RGF0ZSgpfSAke25vdy5nZXRIb3VycygpfToke25vdy5nZXRNaW51dGVzKCl9OiR7bm93LmdldFNlY29uZHMoKX1gXHJcbiAgICB9XHJcbiAgICBcclxufVxyXG5cclxuIl19
|
|
8
|
+
import{finalize}from"rxjs";import{FmodeParse}from"@fmode/parse";const Parse=FmodeParse.with("nova");import{FmodeTTS,FmodeTTSProviderDoubao}from"../../voice/tts";import{PromptTemplate}from"@langchain/core/prompts";import{getFormatTpl}from"../prompt/prompt-util";import{FmodeChatCompletion}from"./completion";const PromptTplTalkSSMLOutputCode="talk-ssml-output-tpl",PromptTplTalkTextSSMLCode="talk-text-ssml-tpl";export function getMessageContentText(t){let e="";return"string"==typeof t&&(e=t),"object"==typeof t&&(e=t?.find((t=>t?.text))?.text||""),e}export function getMessageImageUrl(t){return"object"==typeof t?t?.find((t=>t?.image_url))?.image_url?.url||"":null}export class FmodeChat{async loadModelList(t){if(this.modelList?.length)return;let e=new Parse.Query("ChatModel");e.notEqualTo("isDeleted",!0),e.equalTo("isEnabled",!0),e.addAscending("index"),this.modelList=await e.find(),this.currentModel=t||this.modelList?.find((t=>"fmode-1.6-cn"==t.get("code")))}showAvatar(){this.avatarConfig=this.role?.get("avatarConfig"),this.avatarConfig&&(this.isAvatarShow=!0,this.avatarConfig?.image&&(this.avatarConfig.image.waiting=this.avatarConfig.image.waiting||this.role?.get("thumb")||this.role?.get("avatar"),this.avatarMode="image"),this.avatarConfig?.video&&(this.avatarConfig.video.waiting=this.avatarConfig.video.waiting,this.avatarMode="video"))}scrollToBottom(t){t=t||this.scrollComp,t?.nativeElement?.scrollHeight&&(t.nativeElement.scrollTop=t.nativeElement.scrollHeight)}constructor(t,e,i,s,o,a,n){this.ChatSession=Parse.Object.extend("ChatSession"),this.messageList=[{role:"system",content:"系统提示:AI仅供参考"}],this.latestAIResponse="",this.userInput="",this.userImage="",this.isDirect=!1,this.mode="page",this.hideShare=!1,this.hideModalSelect=!1,this.hideInputPreview=!1,this.isAvatarShow=!1,this.avatarMode="",this.isPromptModalOpen=!1,this.isPromptMessageAreaShow=!0,this.promptList=[],this.focusUserInput=()=>{},this.leftButtons=[{title:"灵感",icon:"color-wand-outline",onClick:()=>{this.isPromptModalOpen=!0},show:()=>this?.promptList?.length},{title:"角色",icon:"people-outline",onClick:()=>{this.navCtrl?.navigateRoot("/chat/pro/mask")},show:()=>!0},{title:"呼叫",icon:"call-outline",onClick:()=>{this.chatServ?.callRole(this.role)},show:()=>this?.role?.get("voiceConfig")}],this.isVoiceInputMode=!1,this.isTexting=!1,this.isTalkMode=!1,this.SSMLRoleVoice="zh-CN-XiaoxiaoNeural",this.playAnimation=t=>{console.log(t)},this.welcome=async()=>{let t=this.messageList?.filter((t=>"assistant"==t?.role));if(t?.length)return;let e=Parse.User.current(),i=await this.loadSelf("Person","userVerify"),s=await this.loadSelf("Profile","user"),o=i?.get("name")||i?.get("userVefiry")?.get("realname")||i?.get("userVefiry")?.get("nickname"),a=e?.get("nickname")||s?.get("name")||e?.get("realname")||e?.get("name");i?.get("userVerify")?.id==e?.id&&(o="您"),a||(a=o);let n=this.role.get("voiceConfig")?.welcome?.prompt;if(this.role.get("voiceConfig")?.welcome?.promptList?.length){let t=this.role.get("voiceConfig")?.welcome?.promptList;n=t[Math.floor(Math.random()*t.length)]}if(!n)return;let r=await PromptTemplate.fromTemplate(n,{templateFormat:"mustache"}).format({name:a,userName:a,personName:o,timeOfDay:this.getTimeOfDay()}),l=await this.getVoiceByContentText(r),h={role:"assistant",voice:l,content:r,complete:!0};this.voiceMap[l?.id],this.playChatVoice(this.voiceMap[l?.id]),this.messageList.push(h)},this.self={},this.voiceMap={},this.VoiceTTSMap={},this.chatServ=s,this.role=e,this.sessionId=t,this.navCtrl=o,this.ncloud=a,this.uploadServ=n,i?.id&&(this.chatSession=i,this.messageList=this.chatSession.get("messageList"),this.sessionId=i?.id),this.role?.id&&(this.voiceConfig=this.role?.get("voiceConfig"),this.voiceConfig?.autoTalk&&(this.isTalkMode=this.isTalkMode||this.voiceConfig?.autoTalk,this.isDirect=!0))}getTimeOfDay(){const t=(new Date).getHours();return t>=5&&t<12?"早上":t>=12&&t<14?"中午":t>=14&&t<18?"下午":"晚上"}async loadSelf(t,e){if(this.self[t])return this.self[t];let i=Parse.User.current(),s=new Parse.Query(t);return s.include(e),s.equalTo(e,i?.id),this.self[t]=await s.first(),this.self[t]}async loadTalkSystemPrompt(t){if(!this.isTalkMode)return;if(!t)return;let e=t?.get("voiceConfig");"男"==t?.get("gender")?(this.SSMLRoleVoice="zh-CN-YunyeNeural","doubao"==e.provider&&(this.SSMLRoleVoice="zh_male_yangguangqingnian_emo_v2_mars_bigtts")):(this.SSMLRoleVoice="zh-CN-XiaoxiaoNeural","doubao"==e.provider&&(this.SSMLRoleVoice="zh_female_shuangkuaisisi_emo_v2_mars_bigtts")),this.SSMLRoleVoice=t?.get("voiceConfig")?.voice||this.SSMLRoleVoice;let i=await getFormatTpl("talk-ssml-output-tpl",{SSMLRoleVoice:this.SSMLRoleVoice}),s=t.get("prompt")||"请你扮演飞码AI的人工智能专家。";s+=i;let o={role:"user",content:s,hidden:!0},a=this.messageList?.map((t=>t?.content)).join();if(a.indexOf(s)>-1)return;let n=this.messageList?.findIndex((t=>"system"==t?.role)),r=n+1;this.messageList.splice(r,0,o)}loadRolePrompt(){let t=this.role?.get("prompt"),e={role:"user",content:t,hidden:!0};if(!t)return;let i=this.messageList?.map((t=>t?.content)).join();if(i.indexOf(t)>-1)return;let s=this.messageList?.findIndex((t=>"system"==t?.role)),o=s+1;this.messageList.splice(o,0,e)}async sendMessage(t="FmodeAiTest测试问题",e,i,s,o){if(this.scrollToBottom&&this.scrollToBottom(),this.isPromptMessageAreaShow=!1,this.loadRolePrompt(),e){let i={role:"user",content:[{type:"image_url",image_url:{url:e}},{type:"text",text:t}],complete:!0,createdAt:new Date};o&&(i.voice={id:o?.id}),this.messageList.push({role:"user",content:[{type:"image_url",image_url:{url:e}},{type:"text",text:t}],complete:!0,createdAt:new Date})}else{let e={role:"user",content:t,complete:!0,createdAt:new Date};o&&(e.voice={id:o?.id,duration:o?.duration}),this.messageList.push(e)}let a=new FmodeChatCompletion(this.fixMessageList(this.messageList),{model:this.currentModel?.get?.("code")||"fmode-1.6-cn"});if(this.onUserSend){if(!await this.onUserSend(this,this.messageList[this.messageList?.length-1]))return}this.userInput="",this.userImage="";let n=this.isDirect||!1;this.isTalkMode&&(n=!0);let r=a.sendCompletion({isDirect:n,onComplete:i||null}).pipe(finalize((async()=>{if(this.isTalkMode){let t=this.messageList[a.indexOfList]?.content,e=await this.getVoiceByContentText(t,s);s?.onSSMLComplete&&s?.onSSMLComplete(e),this.messageList[a.indexOfList].voice=e,this.playChatVoice(this.voiceMap[e?.id],{onResult:t=>{t?.duration&&(this.messageList[a.indexOfList].voice.duration=t?.duration)}})}this.messageList[a.indexOfList].complete=!0}))).subscribe((t=>{this.messageList[a.indexOfList]||s?.onMessageStart?.(t),this.messageList[a.indexOfList]=t,this.latestAIResponse=this.getContentText(t?.content);let e=this.chatSession?.get("messageList")?.length;this.messageList?.length>e&&this.saveChatSession(),t?.complete&&(this.onMessage&&this.onMessage(this,this.messageList[this.messageList?.length-1]),this.saveChatSession(),r.unsubscribe()),this.scrollToBottom&&this.scrollToBottom()}))}getVoiceByContentText(t,e,i=!1){let s=this.getContentText(t),o=new(Parse.Object.extend("ChatVoice")),a="",n=this.voiceConfig||this.role?.get("voiceConfig");return this.SSMLRoleVoice=n?.voice||this.SSMLRoleVoice,new Promise((async(t,e)=>{let resolveChatVoice=async()=>{o.set("content",s),o.set("ssml",a),o.set("role","assistant");let e=localStorage.getItem("company");e&&o.set("company",{__type:"Pointer",className:"Company",objectId:e}),Parse.User.current()?.id&&o.set("user",Parse.User.current().toPointer()),this.chatSession?.id&&o.set("session",this.chatSession?.toPointer()),o=await o.save(),this.voiceMap[o?.id]=o,t({id:o?.id})};if(0==i){let t=n?.provider||"microsoft",e=n?.rate,i=e?"</prosody>":"";a=`<speak provider="${t}">${e?`<prosody rate="${e}">`:""}<voice name="${this.SSMLRoleVoice}">${s}</voice>${i}</speak>`,"doubao"==t&&(a=s),resolveChatVoice()}if(1==i){let t=await getFormatTpl("talk-text-ssml-tpl",{content:s,SSMLRoleVoice:this.SSMLRoleVoice});new FmodeChatCompletion(this.fixMessageList([{role:"user",content:t}]),{model:this.currentModel?.get?.("code")||"fmode-1.6-cn"}).sendCompletion({isDirect:!0}).subscribe((async t=>{t?.complete&&(a=this.getContentText(t?.content),resolveChatVoice())}))}}))}getContentText(t){return"string"==typeof t?t:t?.[0]?.text||""}async initTTS(){this.voiceConfig=this.voiceConfig||this.role?.get("voiceConfig");let t=await this.ncloud.apig("voice/tts/token",{company:localStorage.getItem("company"),provider:this.voiceConfig?.provider||"microsoft"});if(t.provider=this.voiceConfig?.provider,!t?.provider||t?.provider,"doubao"==t?.provider&&(t.provider=new FmodeTTSProviderDoubao),t.voiceConfig=this.voiceConfig,console.log("initTTS",t),t?.token||t?.stsToken){return new FmodeTTS(t,this.uploadServ)}return null}stopPlayingVoice(){Object.values(this.VoiceTTSMap).forEach((t=>{t?.isPlaying&&t?.stop()}))}async playChatVoice(t,e){let i=await this.initTTS();if(console.log("playChatVoice",i),i){try{i.voiceConfig=this.voiceConfig,this.playAnimation("talking"),i.speakAsync(t?.get("ssml"),t,{onStart:t=>{e?.onStart&&e?.onStart(t)},onLoaded:t=>{e?.onLoaded&&e?.onLoaded(t)},onResult:t=>{e?.onResult&&e?.onResult(t)},onStop:()=>{e?.onStop&&e?.onStop(),this.playAnimation("waiting")}})}catch(t){}return this.VoiceTTSMap[t.id]=i,i}return null}async saveChatSession(){if("new"==this.sessionId&&(this.chatSession=new this.ChatSession),this.chatSession.set("title",this.genTitle()),this.chatSession.set("role",this.role?.toPointer()),this.chatSession.set("messageList",this.messageList),this.chatSession.set("user",Parse.User.current()?.toPointer()),this.chatSession=await this.chatSession.save(),this.onChatSaved&&this.onChatSaved(this),this.sessionId=this.chatSession?.id,this.sessionId){let t=`${window.location.origin}/chat/pro/chat/${this.sessionId}`;window.location?.pathname?.indexOf("chat/session")>-1&&(t=`${window.location.origin}/chat/session/chat/${this.sessionId}`),"modal"==this.mode&&(t=window.location.href),t=this.getInviteUrl(t),window.history.replaceState(null,null,t+window.location.search);let e={sid:this.chatSession?.id,rid:this.role?.id,name:this.role?.get("name"),message:this.chatSession?.get("messageList")?.[this.chatSession?.get("messageList")?.length-1]?.content?.slice(0,20),latest:this.chatSession?.createdAt};this.chatServ&&!this.chatServ?.chatList?.length&&(this.chatServ.chatList=[]);let i=this.chatServ?.chatList?.find((t=>t?.sid==e?.sid));i>-1?this.chatServ.chatList[i]=e:this.chatServ?.chatList.unshift(e)}}getInviteUrl(t){let e=new URL(t),i=Parse.User?.current()?.id;return e.searchParams.set("invite",i),e.href}genTitle(){if(this.title)return this.title;let t=this.messageList.find((t=>"user"==t.role))?.content;return"string"==typeof t&&(this.title=t?.slice(0,15)||""),"object"==typeof t&&(this.title=t?.find((t=>t?.text))?.text||""),this.title}fixMessageList(t){return t.map((t=>({role:t.role,content:t.content})))}nowStr(){let t=new Date;return`${t.getFullYear()}/${t.getMonth()+1}/${t.getDate()} ${t.getHours()}:${t.getMinutes()}:${t.getSeconds()}`}}
|
|
9
|
+
var MODULE_PATH_NEED = `6K+l5paH5Lu25piv5pys6aG555uu55qE5LiA6YOo5YiGIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBDb21wb25lbnRzIGluIEZtb2RlIEluYy4KICAgIOeJiOadg+aJgOaciSDCqSDmnKrmnaXpo57pqawgwqkg5rGf6KW/6ISR5o6n56eR5oqA5pyJ6ZmQ5YWs5Y+4IENvcHlyaWdodCDCqSBGbW9kZSBUZWNobm9sb2d5IENvLiwgTHRkLgogICAg5L+d55WZ5omA5pyJ5p2D5YipIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAgICDkuKXnpoHlnKjmnKrnu4/mjojmnYPnmoTmg4XlhrXkuIvvvIzpgJrov4fku7vkvZXlqpLku4vlpI3liLbmraTmlofku7YgVW5hdXRob3JpemVkIGNvcHlpbmcgb2YgdGhpcyBmaWxlLCB2aWEgYW55IG1lZGl1bSBpcyBzdHJpY3RseSBwcm9oaWJpdGVkCiAgICDor6Xmlofku7bmmK/kuJPmnInnmoTmnLrlr4bmlofku7YgUHJvcHJpZXRhcnkgYW5kIGNvbmZpZGVudGlhbAogICAKICAgIENvcHlyaWdodCAyMDIxLW5vdyBGbW9kZSBJbmMuIHN1cHBvcnRAZm1vZGUuY24uIDE4NjA3MDA3MDczLgogICAg5L+d55WZ5omA5pyJ5p2D5YipIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogICAgUEFUSDovaG9tZS9yeWFuL3dvcmtzcGFjZS9ub3ZhL25vdmEtYWRtaW4vZGlzdC9mbW9kZS1uZy9lc20yMDIyL2xpYi9jb3JlL2FnZW50L2NoYXQvZm1vZGUtY2hhdC5tanM=`
|
|
10
|
+
|