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,432 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
// const API_BASE:string = "http://127.0.0.1:7337/api/apig/aigc/gpt"
|
|
3
|
-
// const API_BASE:string = "https://test.fmode.cn/api/apig/aigc/gpt"
|
|
4
|
-
const API_BASE = "https://server.fmode.cn/api/apig/aigc/gpt";
|
|
5
|
-
import Parse from "parse";
|
|
6
|
-
Parse.initialize("ncloudmaster");
|
|
7
|
-
Parse.serverURL = "https://server.fmode.cn/parse";
|
|
8
|
-
/**
|
|
9
|
-
* FmodeChatCompletion 文本补全类
|
|
10
|
-
* @public
|
|
11
|
-
*/
|
|
12
|
-
export class FmodeChatCompletion {
|
|
13
|
-
constructor(messages, options) {
|
|
14
|
-
this.content = ""; // 本次接收消息结果
|
|
15
|
-
this.contentBuffer = [];
|
|
16
|
-
this.isCompleted = false;
|
|
17
|
-
this.indexOfList = Number(messages.length);
|
|
18
|
-
this.messages = messages;
|
|
19
|
-
this.model = options?.model || "fmode-1.6-cn"; // 默认豆包 1.6 性价比目前最高
|
|
20
|
-
this.max_tokens = options?.max_tokens || 32768; // 豆包1.6 + 32k以上
|
|
21
|
-
}
|
|
1
|
+
|
|
22
2
|
/**
|
|
23
|
-
* @
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
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/completion/fmode-completion.mjs
|
|
27
7
|
*/
|
|
28
|
-
sendCompletion(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (options?.isDirect)
|
|
32
|
-
options.intTime = 1;
|
|
33
|
-
let that = this;
|
|
34
|
-
let opts = {
|
|
35
|
-
"messages": this.messages,
|
|
36
|
-
"stream": true,
|
|
37
|
-
"model": this.model,
|
|
38
|
-
"temperature": options?.temperature || 0.5,
|
|
39
|
-
"presence_penalty": options?.presence_penalty || 0,
|
|
40
|
-
"frequency_penalty": options?.frequency_penalty || 0
|
|
41
|
-
};
|
|
42
|
-
// thinking模式的适配:豆包
|
|
43
|
-
if (this.model.indexOf("1.6") > -1) {
|
|
44
|
-
opts.thinking = opts.thinking || { type: "disabled" };
|
|
45
|
-
}
|
|
46
|
-
if (options?.max_tokens) {
|
|
47
|
-
opts["max_tokens"] = options?.max_tokens || this.max_tokens;
|
|
48
|
-
}
|
|
49
|
-
// console.log(opts)
|
|
50
|
-
let $messageReceiver = new Observable((observer) => {
|
|
51
|
-
let subscription = RequestFmodeChatApi("/v1/chat/completions", opts)
|
|
52
|
-
.subscribe(data => {
|
|
53
|
-
// Handle each chunk of data
|
|
54
|
-
/** Chunk文本数据格式如下:
|
|
55
|
-
正常消息:
|
|
56
|
-
'data: {"id":"chatcmpl-y2PLKqPDnwAFJIj2L5aqdH5TWK9Yv","object":"chat.completion.chunk","created":1696770162,"model":"gpt-3.5-turbo-0613","choices":[{"index":0,"delta":{"content":"本提示词仅用于测试。"},"finish_reason":null}]}',
|
|
57
|
-
终止原因:
|
|
58
|
-
'data: {"id":"chatcmpl-y2PLKqPDnwAFJIj2L5aqdH5TWK9Yv","object":"chat.completion.chunk","created":1696770162,"model":"gpt-3.5-turbo-0613","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}',
|
|
59
|
-
结束消息:
|
|
60
|
-
'data: [DONE]'
|
|
61
|
-
*/
|
|
62
|
-
// console.log("chunk",data)
|
|
63
|
-
let chunk = String(data);
|
|
64
|
-
// Check if the completion message is received
|
|
65
|
-
let chunkjson;
|
|
66
|
-
try {
|
|
67
|
-
chunkjson = chunkToJson(chunk);
|
|
68
|
-
}
|
|
69
|
-
catch (err) { }
|
|
70
|
-
// console.log(chunk,chunkjson,chunkjson?.choices?.[0]?.delta?.content)
|
|
71
|
-
if (chunk == 'data: [DONE]'
|
|
72
|
-
||
|
|
73
|
-
(chunkjson?.created &&
|
|
74
|
-
chunkjson?.choices?.[0]?.finish_reason // finish_reason == 'stop'
|
|
75
|
-
// (!chunkjson.choices?.length || !chunkjson?.choices?.[0]?.delta?.content)
|
|
76
|
-
)) {
|
|
77
|
-
this.isCompleted = true; // 标记完成 => 等待interval推送
|
|
78
|
-
// console.log("data: [DONE]",options?.isDirect,this.isCompleted)
|
|
79
|
-
if (options?.isDirect && this.isCompleted) {
|
|
80
|
-
observer.next({
|
|
81
|
-
role: "assistant",
|
|
82
|
-
// cid:chunkjson?.['id'],
|
|
83
|
-
content: this.content,
|
|
84
|
-
complete: true, // 推送完成
|
|
85
|
-
createdAt: new Date()
|
|
86
|
-
});
|
|
87
|
-
subscription.unsubscribe(); // Unsubscribe when done
|
|
88
|
-
options?.onComplete && options.onComplete({
|
|
89
|
-
role: "assistant",
|
|
90
|
-
// cid:chunkjson?.['id'],
|
|
91
|
-
content: this.content,
|
|
92
|
-
complete: true, // 推送完成
|
|
93
|
-
createdAt: new Date()
|
|
94
|
-
});
|
|
95
|
-
observer.complete();
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
// console.log(chunk)
|
|
99
|
-
if (chunk.indexOf("data:\ {") > -1) {
|
|
100
|
-
// console.log(chunk)
|
|
101
|
-
// console.log(chunkjson?.choices?.[0]?.delta)
|
|
102
|
-
let words = chunkjson?.choices?.[0]?.delta?.content || "";
|
|
103
|
-
this.contentBuffer.push(words);
|
|
104
|
-
// 消息返回模式:定时器推送,模拟逐字输出
|
|
105
|
-
if (options?.isDirect) {
|
|
106
|
-
this.content += (words || "");
|
|
107
|
-
// 默认累加消息结果
|
|
108
|
-
if (!this.isCompleted) {
|
|
109
|
-
observer.next({
|
|
110
|
-
role: "assistant",
|
|
111
|
-
cid: chunkjson?.['id'],
|
|
112
|
-
content: this.content,
|
|
113
|
-
createdAt: new Date()
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
if (!options?.isDirect && !this.contentPusher) {
|
|
118
|
-
this.contentPusher = setInterval(() => {
|
|
119
|
-
if (this.isCompleted && this.contentBuffer?.length == 0) { // 推送完毕,清除计时器
|
|
120
|
-
observer.next({
|
|
121
|
-
role: "assistant",
|
|
122
|
-
cid: chunkjson?.['id'],
|
|
123
|
-
content: this.content,
|
|
124
|
-
complete: true, // 推送完成
|
|
125
|
-
createdAt: new Date()
|
|
126
|
-
});
|
|
127
|
-
subscription.unsubscribe(); // Unsubscribe when done
|
|
128
|
-
clearInterval(this.contentPusher);
|
|
129
|
-
observer.complete();
|
|
130
|
-
}
|
|
131
|
-
if (this.contentBuffer?.length >= 0) {
|
|
132
|
-
if (this.contentBuffer?.length > 0) {
|
|
133
|
-
this.content += this.contentBuffer.shift();
|
|
134
|
-
}
|
|
135
|
-
observer.next({
|
|
136
|
-
role: "assistant",
|
|
137
|
-
cid: chunkjson?.['id'],
|
|
138
|
-
content: this.content,
|
|
139
|
-
createdAt: new Date()
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
}, options?.intTime);
|
|
143
|
-
}
|
|
144
|
-
// console.log(this.content)
|
|
145
|
-
}
|
|
146
|
-
});
|
|
147
|
-
});
|
|
148
|
-
return $messageReceiver.pipe(bufferTime(100), // 每100ms收集消息
|
|
149
|
-
concatMap(messages => messages), // 使用 concatMap 逐个发送消息
|
|
150
|
-
delay(200) // 延迟200ms输出每条消息
|
|
151
|
-
);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
function chunkToJson(chunk) {
|
|
155
|
-
let chunkjson;
|
|
156
|
-
try {
|
|
157
|
-
chunkjson = JSON.parse(chunk.replaceAll("data:\ ", ""));
|
|
158
|
-
}
|
|
159
|
-
catch (errdj) {
|
|
160
|
-
// console.error(errdj)
|
|
161
|
-
}
|
|
162
|
-
return chunkjson || {};
|
|
163
|
-
}
|
|
164
|
-
function RequestFmodeChatApi(apipath, body, method = "POST") {
|
|
165
|
-
return new Observable((observer) => {
|
|
166
|
-
let url = API_BASE + apipath;
|
|
167
|
-
let API_TOKEN = Parse.User.current()?.getSessionToken() || localStorage.getItem("FMODE_AI_TOKEN");
|
|
168
|
-
// 通过body传递token参数,避免no-cors模式下Authoriztion头部无效
|
|
169
|
-
let AUTH_TOKEN = `Bearer ${API_TOKEN}`;
|
|
170
|
-
body.token = AUTH_TOKEN;
|
|
171
|
-
if (body)
|
|
172
|
-
body = JSON.stringify(body);
|
|
173
|
-
// console.log(url,body)
|
|
174
|
-
fetch(url, {
|
|
175
|
-
"headers": {
|
|
176
|
-
// "Authorization": AUTH_TOKEN,
|
|
177
|
-
"Content-Type": "text/plain; charset=utf-8",
|
|
178
|
-
"Cache-Control": "no-cache"
|
|
179
|
-
},
|
|
180
|
-
"body": body || null,
|
|
181
|
-
"method": method,
|
|
182
|
-
"credentials": "omit",
|
|
183
|
-
"mode": "cors"
|
|
184
|
-
}).then(response => {
|
|
185
|
-
let isStream = true || response.headers?.get("Content-Type")?.indexOf("text/event-stream") > -1;
|
|
186
|
-
let remainingData = ``;
|
|
187
|
-
function processData(data) {
|
|
188
|
-
let combinedData = remainingData + data;
|
|
189
|
-
let messages = combinedData.split('\n');
|
|
190
|
-
if (messages?.length > 1) { // 至少分割2条消息时进行处理
|
|
191
|
-
// 处理每个完整的消息
|
|
192
|
-
for (let i = 0; i < messages.length - 1; i++) {
|
|
193
|
-
let message = messages[i];
|
|
194
|
-
observer.next(message);
|
|
195
|
-
}
|
|
196
|
-
// 保存最后一个不完整的消息
|
|
197
|
-
remainingData = messages[messages.length - 1];
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
if (isStream) {
|
|
201
|
-
let greader = response.body?.getReader();
|
|
202
|
-
const decoder = new TextDecoder();
|
|
203
|
-
let rstream = new ReadableStream({
|
|
204
|
-
start(controller) {
|
|
205
|
-
function read() {
|
|
206
|
-
greader.read().then(({ done, value }) => {
|
|
207
|
-
if (done) {
|
|
208
|
-
controller.close();
|
|
209
|
-
observer.complete(); // Complete the observer when stream processing is done
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
controller.enqueue(value);
|
|
213
|
-
read();
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
read();
|
|
217
|
-
}
|
|
218
|
-
});
|
|
219
|
-
let reader = rstream.getReader();
|
|
220
|
-
function processStream(result) {
|
|
221
|
-
let { done, value } = result;
|
|
222
|
-
if (done) {
|
|
223
|
-
return;
|
|
224
|
-
}
|
|
225
|
-
let text = decoder.decode(value);
|
|
226
|
-
processData(text); // Emit each chunk of data
|
|
227
|
-
reader.read().then(processStream);
|
|
228
|
-
}
|
|
229
|
-
reader.read().then(processStream);
|
|
230
|
-
}
|
|
231
|
-
})
|
|
232
|
-
.catch(error => observer.error(error)); // Handle any errors
|
|
233
|
-
// Return the subscription logic
|
|
234
|
-
return () => {
|
|
235
|
-
// Clean up logic, if needed
|
|
236
|
-
};
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
function JsonToFormData(json) {
|
|
240
|
-
const formData = new FormData();
|
|
241
|
-
function appendFormData(data, path = '') {
|
|
242
|
-
if (Array.isArray(data)) {
|
|
243
|
-
data.forEach((value, index) => {
|
|
244
|
-
appendFormData(value, `${path}[${index}]`);
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
else if (typeof data === 'object' && data !== null) {
|
|
248
|
-
Object.keys(data).forEach(key => {
|
|
249
|
-
const newPath = path ? `${path}.${key}` : key;
|
|
250
|
-
appendFormData(data[key], newPath);
|
|
251
|
-
});
|
|
252
|
-
}
|
|
253
|
-
else {
|
|
254
|
-
formData.append(path, data);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
appendFormData(json);
|
|
258
|
-
return formData;
|
|
259
|
-
}
|
|
260
|
-
/**
|
|
261
|
-
* 使用AI生成符合指定结构的JSON数据
|
|
262
|
-
* @param prompt 任务要求的整体提示词
|
|
263
|
-
* @param jsonSchema 期望的JSON结构描述(用于提示词)
|
|
264
|
-
* @param onMessage 实时生成内容回调
|
|
265
|
-
* @param retryCount 重试次数,默认为1次
|
|
266
|
-
* @returns 解析后的JSON对象
|
|
267
|
-
*/
|
|
268
|
-
export async function completionJSON(prompt, jsonSchema, onMessage, retryCount = 1, options) {
|
|
269
|
-
options = options || {};
|
|
270
|
-
let currentRetry = 0;
|
|
271
|
-
const attemptCompletion = async () => {
|
|
272
|
-
// 1. 构建提示词
|
|
273
|
-
const JsonResultParsePrompt = `请严格按照以下要求生成JSON数据:
|
|
274
|
-
- 数据结构要求:${jsonSchema}
|
|
275
|
-
- 返回一个完整的JSON对象,请确保JSON格式完整,不要遗漏任何标点符号
|
|
276
|
-
- 注意返回的JSON格式每个KEY都有""包裹和Value之间都有:
|
|
277
|
-
- 注意""字符串内再出现"符号需要用\\\"转义
|
|
278
|
-
`;
|
|
279
|
-
// 2. 初始化消息列表
|
|
280
|
-
const messageList = [
|
|
281
|
-
{
|
|
282
|
-
role: "user",
|
|
283
|
-
content: prompt + JsonResultParsePrompt
|
|
284
|
-
}
|
|
285
|
-
];
|
|
286
|
-
// 3. 创建FmodeChatCompletion实例
|
|
287
|
-
options.response_format = { "type": "json_object" };
|
|
288
|
-
const completion = new FmodeChatCompletion(messageList, options);
|
|
289
|
-
// 4. 存储累积内容
|
|
290
|
-
let fullContent = "";
|
|
291
|
-
// 5. 返回Promise,处理异步流式响应
|
|
292
|
-
return new Promise((resolve, reject) => {
|
|
293
|
-
const send$ = completion.sendCompletion({ isDirect: true, max_tokens: 32768 }).subscribe({
|
|
294
|
-
next: (message) => {
|
|
295
|
-
// 处理消息内容
|
|
296
|
-
if (typeof message?.content === "string") {
|
|
297
|
-
fullContent = message.content;
|
|
298
|
-
// 调用回调函数,实时推送生成内容
|
|
299
|
-
if (onMessage) {
|
|
300
|
-
onMessage(fullContent);
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
// 检查是否完成
|
|
304
|
-
if (message.complete) {
|
|
305
|
-
// 6. 最终JSON提取
|
|
306
|
-
try {
|
|
307
|
-
const jsonObject = extractJSON(fullContent);
|
|
308
|
-
if (jsonObject) {
|
|
309
|
-
resolve(jsonObject);
|
|
310
|
-
}
|
|
311
|
-
else {
|
|
312
|
-
throw new Error("未能从响应中提取有效的JSON对象");
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
catch (e) {
|
|
316
|
-
console.error(`JSON解析失败 (第${currentRetry + 1}次尝试):`, e);
|
|
317
|
-
// console.log("原始内容:", fullContent);
|
|
318
|
-
reject(new Error(`生成的响应不符合JSON格式: ${e.message}`));
|
|
319
|
-
}
|
|
320
|
-
// 结束订阅
|
|
321
|
-
send$.unsubscribe();
|
|
322
|
-
}
|
|
323
|
-
},
|
|
324
|
-
error: (error) => {
|
|
325
|
-
console.error("Completion请求失败:", error);
|
|
326
|
-
send$.unsubscribe();
|
|
327
|
-
reject(error);
|
|
328
|
-
}
|
|
329
|
-
});
|
|
330
|
-
});
|
|
331
|
-
};
|
|
332
|
-
// 重试逻辑
|
|
333
|
-
while (currentRetry <= retryCount) {
|
|
334
|
-
try {
|
|
335
|
-
const result = await attemptCompletion();
|
|
336
|
-
if (currentRetry > 0) {
|
|
337
|
-
console.log(`JSON生成成功,重试了 ${currentRetry} 次`);
|
|
338
|
-
}
|
|
339
|
-
return result;
|
|
340
|
-
}
|
|
341
|
-
catch (error) {
|
|
342
|
-
currentRetry++;
|
|
343
|
-
if (currentRetry <= retryCount) {
|
|
344
|
-
console.warn(`第 ${currentRetry} 次尝试失败,正在重试... 错误信息:`, error.message);
|
|
345
|
-
// 可以添加延迟避免过快重试
|
|
346
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
347
|
-
}
|
|
348
|
-
else {
|
|
349
|
-
console.error(`JSON生成失败,已重试 ${retryCount} 次,最终错误:`, error);
|
|
350
|
-
throw new Error(`经过 ${retryCount} 次重试后仍无法生成有效JSON: ${error.message}`);
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
/**
|
|
356
|
-
* 从字符串中提取JSON对象(增强版)
|
|
357
|
-
* @param str 包含JSON的字符串
|
|
358
|
-
* @returns 解析后的JSON对象或null
|
|
359
|
-
*/
|
|
360
|
-
export function extractJSON(str) {
|
|
361
|
-
// console.log("fullContent",str)
|
|
362
|
-
// 首先尝试直接解析整个字符串
|
|
363
|
-
try {
|
|
364
|
-
return JSON.parse(str.trim());
|
|
365
|
-
}
|
|
366
|
-
catch (e) {
|
|
367
|
-
// 如果直接解析失败,则尝试提取JSON片段
|
|
368
|
-
}
|
|
369
|
-
let stack = 0;
|
|
370
|
-
let startIndex = -1;
|
|
371
|
-
let result = null;
|
|
372
|
-
for (let i = 0; i < str.length; i++) {
|
|
373
|
-
if (str[i] === '{') {
|
|
374
|
-
if (stack === 0)
|
|
375
|
-
startIndex = i;
|
|
376
|
-
stack++;
|
|
377
|
-
}
|
|
378
|
-
else if (str[i] === '}') {
|
|
379
|
-
stack--;
|
|
380
|
-
if (stack === 0 && startIndex !== -1) {
|
|
381
|
-
try {
|
|
382
|
-
const jsonStr = str.slice(startIndex, i + 1);
|
|
383
|
-
result = JSON.parse(jsonStr);
|
|
384
|
-
break;
|
|
385
|
-
}
|
|
386
|
-
catch (e) {
|
|
387
|
-
// 继续尝试下一个可能的 JSON
|
|
388
|
-
startIndex = -1;
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
// 如果还是没有找到有效JSON,尝试修复常见的JSON格式问题
|
|
394
|
-
if (!result) {
|
|
395
|
-
result = tryFixAndParseJSON(str);
|
|
396
|
-
}
|
|
397
|
-
return result;
|
|
398
|
-
}
|
|
399
|
-
/**
|
|
400
|
-
* 尝试修复常见的JSON格式问题并解析
|
|
401
|
-
* @param str 可能有格式问题的JSON字符串
|
|
402
|
-
* @returns 解析后的JSON对象或null
|
|
403
|
-
*/
|
|
404
|
-
function tryFixAndParseJSON(str) {
|
|
405
|
-
// 提取可能的JSON部分
|
|
406
|
-
const jsonMatch = str.match(/\{[\s\S]*\}/);
|
|
407
|
-
if (!jsonMatch)
|
|
408
|
-
return null;
|
|
409
|
-
let jsonStr = jsonMatch[0];
|
|
410
|
-
// 尝试修复常见问题
|
|
411
|
-
const fixes = [
|
|
412
|
-
// 移除末尾多余的逗号
|
|
413
|
-
(s) => s.replace(/,(\s*[}\]])/g, '$1'),
|
|
414
|
-
// 确保属性名有引号
|
|
415
|
-
(s) => s.replace(/([{,]\s*)([a-zA-Z_$][a-zA-Z0-9_$]*)\s*:/g, '$1"$2":'),
|
|
416
|
-
// 修复单引号为双引号
|
|
417
|
-
(s) => s.replace(/'/g, '"'),
|
|
418
|
-
// 移除注释
|
|
419
|
-
(s) => s.replace(/\/\*[\s\S]*?\*\//g, '').replace(/\/\/.*$/gm, ''),
|
|
420
|
-
];
|
|
421
|
-
for (const fix of fixes) {
|
|
422
|
-
try {
|
|
423
|
-
const fixedStr = fix(jsonStr);
|
|
424
|
-
return JSON.parse(fixedStr);
|
|
425
|
-
}
|
|
426
|
-
catch (e) {
|
|
427
|
-
// 继续尝试下一个修复方法
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
return null;
|
|
431
|
-
}
|
|
432
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm1vZGUtY29tcGxldGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Ztb2RlLW5nL3NyYy9saWIvY29yZS9hZ2VudC9jaGF0L2NvbXBsZXRpb24vZm1vZGUtY29tcGxldGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFZLE1BQU0sTUFBTSxDQUFBO0FBQ3pFLG9FQUFvRTtBQUNwRSxvRUFBb0U7QUFDcEUsTUFBTSxRQUFRLEdBQVUsMkNBQTJDLENBQUE7QUFFbkUsT0FBTyxLQUFLLE1BQU0sT0FBTyxDQUFDO0FBQ3pCLEtBQWEsQ0FBQyxVQUFVLENBQUMsY0FBYyxDQUFDLENBQUM7QUFDekMsS0FBYSxDQUFDLFNBQVMsR0FBRywrQkFBK0IsQ0FBQztBQUczRDs7O0dBR0c7QUFDSCxNQUFNLE9BQU8sbUJBQW1CO0lBUzVCLFlBQ0ksUUFBMkIsRUFBQyxPQUczQjtRQVJMLFlBQU8sR0FBVSxFQUFFLENBQUEsQ0FBQyxXQUFXO1FBQy9CLGtCQUFhLEdBQVksRUFBRSxDQUFBO1FBRTNCLGdCQUFXLEdBQVcsS0FBSyxDQUFDO1FBT3hCLElBQUksQ0FBQyxXQUFXLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUMxQyxJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQTtRQUN4QixJQUFJLENBQUMsS0FBSyxHQUFHLE9BQU8sRUFBRSxLQUFLLElBQUksY0FBYyxDQUFBLENBQUMsbUJBQW1CO1FBQ2pFLElBQUksQ0FBQyxVQUFVLEdBQUcsT0FBTyxFQUFFLFVBQVUsSUFBSSxLQUFLLENBQUEsQ0FBQyxnQkFBZ0I7SUFDbkUsQ0FBQztJQUNEOzs7OztPQUtHO0lBQ0gsY0FBYyxDQUFDLFVBSW9CLEVBQUMsUUFBUSxFQUFDLEVBQUUsRUFBQztRQUM1QyxPQUFPLENB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TUFBTSxLQUFLLEdBQUc7UUFDVixZQUFZO1FBQ1osQ0FBQyxDQUFTLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsY0FBYyxFQUFFLElBQUksQ0FBQztRQUM5QyxXQUFXO1FBQ1gsQ0FBQyxDQUFTLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsMENBQTBDLEVBQUUsU0FBUyxDQUFDO1FBQy9FLFlBQVk7UUFDWixDQUFDLENBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDO1FBQ25DLE9BQU87UUFDUCxDQUFDLENBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxtQkFBbUIsRUFBRSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLEVBQUUsQ0FBQztLQUM3RSxDQUFDO0lBRUYsS0FBSyxNQUFNLEdBQUcsSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUN0QixJQUFJLENBQUM7WUFDRCxNQUFNLFFBQVEsR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDOUIsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ2hDLENBQUM7UUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ1QsY0FBYztRQUNsQixDQUFDO0lBQ0wsQ0FBQztJQUVELE9BQU8sSUFBSSxDQUFDO0FBQ2hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBidWZmZXJUaW1lLCBjb25jYXRNYXAsIGRlbGF5LCBPYnNlcnZhYmxlLCBPYnNlcnZlciB9IGZyb20gXCJyeGpzXCJcclxuLy8gY29uc3QgQVBJX0JBU0U6c3RyaW5nID0gXCJodHRwOi8vMTI3LjAuMC4xOjczMzcvYXBpL2FwaWcvYWlnYy9ncHRcIlxyXG4vLyBjb25zdCBBUElfQkFTRTpzdHJpbmcgPSBcImh0dHBzOi8vdGVzdC5mbW9kZS5jbi9hcGkvYXBpZy9haWdjL2dwdFwiXHJcbmNvbnN0IEFQSV9CQVNFOnN0cmluZyA9IFwiaHR0cHM6Ly9zZXJ2ZXIuZm1vZGUuY24vYXBpL2FwaWcvYWlnYy9ncHRcIlxyXG5pbXBvcnQgeyBGbW9kZUNoYXRNZXNzYWdlIH0gZnJvbSBcIi4uL2ludGVyZmFjZVwiO1xyXG5pbXBvcnQgUGFyc2UgZnJvbSBcInBhcnNlXCI7XHJcbihQYXJzZSBhcyBhbnkpLmluaXRpYWxpemUoXCJuY2xvdWRtYXN0ZXJcIik7XHJcbihQYXJzZSBhcyBhbnkpLnNlcnZlclVSTCA9IFwiaHR0cHM6Ly9zZXJ2ZXIuZm1vZGUuY24vcGFyc2VcIjtcclxuaW1wb3J0IHsgRG91YmFvQ2hhdE9wdGlvbnMsIEdwdENoYXRPcHRpb25zIH0gZnJvbSBcIi4vaW50LWdwdC1jaGF0LW9wdGlvbnNcIlxyXG5cclxuLyoqXHJcbiAqIEZtb2RlQ2hhdENvbXBsZXRpb24g5paH5pys6KGl5YWo57G7XHJcbiAqIEBwdWJsaWNcclxuICovXHJcbmV4cG9ydCBjbGFzcyBGbW9kZUNoYXRDb21wbGV0aW9ue1xyXG4gICAgaW5kZXhPZkxpc3Q6bnVtYmVyXHJcbiAgICBtb2RlbDpzdHJpbmdcclxuICAgIG1heF90b2tlbnM6bnVtYmVyXHJcbiAgICBtZXNzYWdlczpGbW9kZUNoYXRNZXNzYWdlW10gLy8g6KGl5YWo5YmN5o+Q56S66K+N5YiX6KGoXHJcbiAgICBjb250ZW50OnN0cmluZyA9IFwiXCIgLy8g5pys5qyh5o6l5pS25raI5oGv57uT5p6cXHJcbiAgICBjb250ZW50QnVmZmVyOnN0cmluZ1tdID0gW11cclxuICAgIGNvbnRlbnRQdXNoZXI6YW55XHJcbiAgICBpc0NvbXBsZXRlZDpib29sZWFuID0gZmFsc2U7XHJcbiAgICBjb25zdHJ1Y3RvcihcclxuICAgICAgICBtZXNzYWdlczpGbW9kZUNoYXRNZXNzYWdlW10sb3B0aW9ucz86e1xyXG4gICAgICAgICAgICBtb2RlbD86c3RyaW5nXHJcbiAgICAgICAgICAgIG1heF90b2tlbnM/Om51bWJlclxyXG4gICAgICAgIH1cclxuICAgICl7XHJcbiAgICAgICAgdGhpcy5pbmRleE9mTGlzdCA9IE51bWJlcihtZXNzYWdlcy5sZW5ndGgpXHJcbiAgICAgICAgdGhpcy5tZXNzYWdlcyA9IG1lc3NhZ2VzXHJcbiAgICAgICAgdGhpcy5tb2RlbCA9IG9wdGlvbnM/Lm1vZGVsIHx8IFwiZm1vZGUtMS42LWNuXCIgLy8g6buY6K6k6LGG5YyFIDEuNiDmgKfku7fmr5Tnm67liY3mnIDpq5hcclxuICAgICAgICB0aGlzLm1heF90b2tlbnMgPSBvcHRpb25zPy5tYXhfdG9rZW5zIHx8IDMyNzY4IC8vIOixhuWMhTEuNiArIDMya+S7peS4ilxyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBAcGFyYW0gb3B0aW9uc1xyXG4gICAgICogQHBhcmFtIG9wdGlvbnMuaXNEaXJlY3Qg5piv5ZCm5LiN562J5b6F6YCQ5a2X6I635Y+W77yM55u05o6l5a6M5oiQ5YaF5a655o6o6YCBXHJcbiAgICAgKiBAcGFyYW0gb3B0aW9ucy5pbnRUaW1lIOaYr+WQpuS4jeetieW+hemAkOWtl+iOt+WPlu+8jOebtOaOpeWujOaIkOWGheWuueaOqOmAgVxyXG4gICAgICogQHJldHVybnMgXHJcbiAgICAgKi9cclxuICAgIHNlbmRDb21wbGV0aW9uKG9wdGlvbnM6e1xyXG4gICAgICAgIGlzRGlyZWN0Pzpib29sZWFuLFxyXG4gICAgICAgIGludFRpbWU/Om51bWJlcixcclxuICAgICAgICBvbkNvbXBsZXRlPzpGdW5jdGlvblxyXG4gICAgfSZHcHRDaGF0T3B0aW9ucyZEb3ViYW9DaGF0T3B0aW9ucz17bWVzc2FnZXM6W119KTpPYnNlcnZhYmxlPEZtb2RlQ2hhdE1lc3NhZ2U+e1xyXG4gICAgICAgIG9wdGlvbnMuaW50VGltZSA9IG9wdGlvbnM/LmludFRpbWUgfHwgNTAgLy8g5oyJ5q+r56eS6YCQ5a2X5o6o6YCBXHJcbiAgICAgICAgb3B0aW9ucy5pc0RpcmVjdCA9IG9wdGlvbnM/LmlzRGlyZWN0IHx8IGZhbHNlXHJcbiAgICAgICAgaWYob3B0aW9ucz8uaXNEaXJlY3QpIG9wdGlvbnMuaW50VGltZSA9IDFcclxuXHJcbiAgICAgICAgbGV0IHRoYXQgPSB0aGlzO1xyXG4gICAgICAgIGxldCBvcHRzOkdwdENoYXRPcHRpb25zJkRvdWJhb0NoYXRPcHRpb25zID0ge1xyXG4gICAgICAgICAgICBcIm1lc3NhZ2VzXCI6dGhpcy5tZXNzYWdlcyxcclxuICAgICAgICAgICAgXCJzdHJlYW1cIjp0cnVlLFxyXG4gICAgICAgICAgICBcIm1vZGVsXCI6dGhpcy5tb2RlbCxcclxuICAgICAgICAgICAgXCJ0ZW1wZXJhdHVyZVwiOm9wdGlvbnM/LnRlbXBlcmF0dXJlIHx8IDAuNSxcclxuICAgICAgICAgICAgXCJwcmVzZW5jZV9wZW5hbHR5XCI6b3B0aW9ucz8ucHJlc2VuY2VfcGVuYWx0eSB8fCAwLFxyXG4gICAgICAgICAgICBcImZyZXF1ZW5jeV9wZW5hbHR5XCI6b3B0aW9ucz8uZnJlcXVlbmN5X3BlbmFsdHkgfHwgMFxyXG4gICAgICAgIH1cclxuICAgICAgICAvLyB0aGlua2luZ+aooeW8j+eahOmAgumFje+8muixhuWMhVxyXG4gICAgICAgIGlmKHRoaXMubW9kZWwuaW5kZXhPZihcIjEuNlwiKT4tMSl7XHJcbiAgICAgICAgICAgIG9wdHMudGhpbmtpbmcgPSBvcHRzLnRoaW5raW5nIHx8IHt0eXBlOlwiZGlzYWJsZWRcIn07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZihvcHRpb25zPy5tYXhfdG9rZW5zKXtcclxuICAgICAgICAgICAgb3B0c1tcIm1heF90b2tlbnNcIl0gPSBvcHRpb25zPy5tYXhfdG9rZW5zIHx8IHRoaXMubWF4X3Rva2VucztcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gY29uc29sZS5sb2cob3B0cylcclxuICAgICAgICBsZXQgJG1lc3NhZ2VSZWNlaXZlciA9IG5ldyBPYnNlcnZhYmxlKChvYnNlcnZlcjogT2JzZXJ2ZXI8Rm1vZGVDaGF0TWVzc2FnZT4pID0+IHtcclxuICAgICAgICAgICAgbGV0IHN1YnNjcmlwdGlvbiA9IFJlcXVlc3RGbW9kZUNoYXRBcGkoXCIvdjEvY2hhdC9jb21wbGV0aW9uc1wiLCBvcHRzKVxyXG4gICAgICAgICAgICAuc3Vic2NyaWJlKGRhdGEgPT4ge1xyXG4gICAgICAgICAgICAgICAgLy8gSGFuZGxlIGVhY2ggY2h1bmsgb2YgZGF0YVxyXG4gICAgICAgICAgICAgICAgLyoqIENodW5r5paH5pys5pWw5o2u5qC85byP5aaC5LiL77yaXHJcbiAgICAgICAgICAgICAgICDmraPluLjmtojmga/vvJpcclxuICAgICAgICAgICAgICAgICdkYXRhOiB7XCJpZFwiOlwiY2hhdGNtcGwteTJQTEtxUERud0FGSklqMkw1YXFkSDVUV0s5WXZcIixcIm9iamVjdFwiOlwiY2hhdC5jb21wbGV0aW9uLmNodW5rXCIsXCJjcmVhdGVkXCI6MTY5Njc3MDE2MixcIm1vZGVsXCI6XCJncHQtMy41LXR1cmJvLTA2MTNcIixcImNob2ljZXNcIjpbe1wiaW5kZXhcIjowLFwiZGVsdGFcIjp7XCJjb250ZW50XCI6XCLmnKzmj5DnpLror43ku4XnlKjkuo7mtYvor5XjgIJcIn0sXCJmaW5pc2hfcmVhc29uXCI6bnVsbH1dfScsXHJcbiAgICAgICAgICAgICAgICDnu4jmraLljp/lm6DvvJpcclxuICAgICAgICAgICAgICAgICdkYXRhOiB7XCJpZFwiOlwiY2hhdGNtcGwteTJQTEtxUERud0FGSklqMkw1YXFkSDVUV0s5WXZcIixcIm9iamVjdFwiOlwiY2hhdC5jb21wbGV0aW9uLmNodW5rXCIsXCJjcmVhdGVkXCI6MTY5Njc3MDE2MixcIm1vZGVsXCI6XCJncHQtMy41LXR1cmJvLTA2MTNcIixcImNob2ljZXNcIjpbe1wiaW5kZXhcIjowLFwiZGVsdGFcIjp7fSxcImZpbmlzaF9yZWFzb25cIjpcInN0b3BcIn1dfScsXHJcbiAgICAgICAgICAgICAgICDnu5PmnZ/mtojmga/vvJpcclxuICAgICAgICAgICAgICAgICdkYXRhOiBbRE9ORV0nXHJcbiAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coXCJjaHVua1wiLGRhdGEpXHJcbiAgICAgICAgICAgICAgICBsZXQgY2h1bmsgPSBTdHJpbmcoZGF0YSk7XHJcbiAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiB0aGUgY29tcGxldGlvbiBtZXNzYWdlIGlzIHJlY2VpdmVkXHJcbiAgICAgICAgICAgICAgICBsZXQgY2h1bmtqc29uOmFueVxyXG4gICAgICAgICAgICAgICAgdHJ5e1xyXG4gICAgICAgICAgICAgICAgICAgIGNodW5ranNvbiA9IGNodW5rVG9Kc29uKGNodW5rKVxyXG4gICAgICAgICAgICAgICAgfWNhdGNoKGVycil7fVxyXG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coY2h1bmssY2h1bmtqc29uLGNodW5ranNvbj8uY2hvaWNlcz8uWzBdPy5kZWx0YT8uY29udGVudClcclxuICAgICAgICAgICAgICAgIGlmIChcclxuICAgICAgICAgICAgICAgICAgICBjaHVuayA9PSAnZGF0YTogW0RPTkVdJyBcclxuICAgICAgICAgICAgICAgICAgICB8fCBcclxuICAgICAgICAgICAgICAgICAgICAoY2h1bmtqc29uPy5jcmVhdGVkICYmIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjaHVua2pzb24/LmNob2ljZXM/LlswXT8uZmluaXNoX3JlYXNvbiAvLyBmaW5pc2hfcmVhc29uID09ICdzdG9wJ1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyAoIWNodW5ranNvbi5jaG9pY2VzPy5sZW5ndGggfHwgIWNodW5ranNvbj8uY2hvaWNlcz8uWzBdPy5kZWx0YT8uY29udGVudClcclxuICAgICAgICAgICAgICAgICAgICApXHJcbiAgICAgICAgICAgICAgICApIHsgXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0NvbXBsZXRlZCA9IHRydWU7IC8vIOagh+iusOWujOaIkCA9PiDnrYnlvoVpbnRlcnZhbOaOqOmAgVxyXG4gICAgICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKFwiZGF0YTogW0RPTkVdXCIsb3B0aW9ucz8uaXNEaXJlY3QsdGhpcy5pc0NvbXBsZXRlZClcclxuICAgICAgICAgICAgICAgICAgICBpZihvcHRpb25zPy5pc0RpcmVjdCAmJiB0aGlzLmlzQ29tcGxldGVkKXtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dCh7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByb2xlOlwiYXNzaXN0YW50XCIsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjaWQ6Y2h1bmtqc29uPy5bJ2lkJ10sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50OnRoaXMuY29udGVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlOnRydWUsIC8vIOaOqOmAgeWujOaIkFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlZEF0Om5ldyBEYXRlKClcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7IC8vIFVuc3Vic2NyaWJlIHdoZW4gZG9uZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zPy5vbkNvbXBsZXRlJiZvcHRpb25zLm9uQ29tcGxldGUoe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcm9sZTpcImFzc2lzdGFudFwiLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2lkOmNodW5ranNvbj8uWydpZCddLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudDp0aGlzLmNvbnRlbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wbGV0ZTp0cnVlLCAvLyDmjqjpgIHlrozmiJBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZWRBdDpuZXcgRGF0ZSgpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLmNvbXBsZXRlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coY2h1bmspXHJcbiAgICAgICAgICAgICAgICBpZihjaHVuay5pbmRleE9mKFwiZGF0YTpcXCB7XCIpPi0xKXtcclxuICAgICAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhjaHVuaylcclxuICAgICAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhjaHVua2pzb24/LmNob2ljZXM/LlswXT8uZGVsdGEpXHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IHdvcmRzID0gY2h1bmtqc29uPy5jaG9pY2VzPy5bMF0/LmRlbHRhPy5jb250ZW50IHx8IFwiXCJcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRCdWZmZXIucHVzaCh3b3Jkcyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vIOa2iOaBr+i/lOWbnuaooeW8j++8muWumuaXtuWZqOaOqOmAge+8jOaooeaLn+mAkOWtl+i+k+WHulxyXG4gICAgICAgICAgICAgICAgICAgIGlmKG9wdGlvbnM/LmlzRGlyZWN0KXtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29udGVudCArPSAod29yZHMgfHwgXCJcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8g6buY6K6k57Sv5Yqg5raI5oGv57uT5p6cXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZighdGhpcy5pc0NvbXBsZXRlZCl7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dCh7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvbGU6XCJhc3Npc3RhbnRcIixcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2lkOmNodW5ranNvbj8uWydpZCddLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50OnRoaXMuY29udGVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlZEF0Om5ldyBEYXRlKClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZighb3B0aW9ucz8uaXNEaXJlY3QmJiF0aGlzLmNvbnRlbnRQdXNoZXIpe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRQdXNoZXIgPSBzZXRJbnRlcnZhbCgoKT0+e1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5pc0NvbXBsZXRlZCAmJiB0aGlzLmNvbnRlbnRCdWZmZXI/Lmxlbmd0aD09MCl7IC8vIOaOqOmAgeWujOavle+8jOa4hemZpOiuoeaXtuWZqFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm5leHQoe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb2xlOlwiYXNzaXN0YW50XCIsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNpZDpjaHVua2pzb24/LlsnaWQnXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudDp0aGlzLmNvbnRlbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlOnRydWUsIC8vIOaOqOmAgeWujOaIkFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVkQXQ6bmV3IERhdGUoKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7IC8vIFVuc3Vic2NyaWJlIHdoZW4gZG9uZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5jb250ZW50UHVzaGVyKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLmNvbXBsZXRlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZih0aGlzLmNvbnRlbnRCdWZmZXI/Lmxlbmd0aD49MCl7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYodGhpcy5jb250ZW50QnVmZmVyPy5sZW5ndGg+MCl7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY29udGVudCArPSB0aGlzLmNvbnRlbnRCdWZmZXIuc2hpZnQoKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5uZXh0KHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm9sZTpcImFzc2lzdGFudFwiLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaWQ6Y2h1bmtqc29uPy5bJ2lkJ10sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ6dGhpcy5jb250ZW50LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVkQXQ6bmV3IERhdGUoKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sb3B0aW9ucz8uaW50VGltZSlcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2codGhpcy5jb250ZW50KVxyXG4gICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSlcclxuICAgICAgICByZXR1cm4gJG1lc3NhZ2VSZWNlaXZlci5waXBlKFxyXG4gICAgICAgICAgICBidWZmZXJUaW1lKDEwMCksIC8vIOavjzEwMG1z5pS26ZuG5raI5oGvXHJcbiAgICAgICAgICAgIGNvbmNhdE1hcChtZXNzYWdlcyA9PiBtZXNzYWdlcyksIC8vIOS9v+eUqCBjb25jYXRNYXAg6YCQ5Liq5Y+R6YCB5raI5oGvXHJcbiAgICAgICAgICAgIGRlbGF5KDIwMCkgLy8g5bu26L+fMjAwbXPovpPlh7rmr4/mnaHmtojmga9cclxuICAgICAgICApXHJcbiAgICB9XHJcbn1cclxuXHJcblxyXG5mdW5jdGlvbiBjaHVua1RvSnNvbihjaHVuayl7XHJcbiAgICBsZXQgY2h1bmtqc29uOmFueVxyXG4gICAgdHJ5e1xyXG4gICAgICAgIGNodW5ranNvbiA9IEpTT04ucGFyc2UoY2h1bmsucmVwbGFjZUFsbChcImRhdGE6XFwgXCIsXCJcIikpO1xyXG4gICAgfWNhdGNoKGVycmRqKXtcclxuICAgICAgICAvLyBjb25zb2xlLmVycm9yKGVycmRqKVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIGNodW5ranNvbiB8fCB7fVxyXG59XHJcbmZ1bmN0aW9uIFJlcXVlc3RGbW9kZUNoYXRBcGkoYXBpcGF0aCwgYm9keSwgbWV0aG9kID0gXCJQT1NUXCIpIHtcclxuICAgIHJldHVybiBuZXcgT2JzZXJ2YWJsZSgob2JzZXJ2ZXI6IE9ic2VydmVyPGFueT4pID0+IHtcclxuICAgICAgICBsZXQgdXJsID0gQVBJX0JBU0UgKyBhcGlwYXRoO1xyXG4gICAgICAgIGxldCBBUElfVE9LRU4gPSBQYXJzZS5Vc2VyLmN1cnJlbnQoKT8uZ2V0U2Vzc2lvblRva2VuKCkgfHwgbG9jYWxTdG9yYWdlLmdldEl0ZW0oXCJGTU9ERV9BSV9UT0tFTlwiKTtcclxuICAgICAgICAgICAgLy8g6YCa6L+HYm9keeS8oOmAknRva2Vu5Y+C5pWw77yM6YG/5YWNbm8tY29yc+aooeW8j+S4i0F1dGhvcml6dGlvbuWktOmDqOaXoOaViFxyXG4gICAgICAgIGxldCBBVVRIX1RPS0VOID0gYEJlYXJlciAke0FQSV9UT0tFTn1gXHJcbiAgICAgICAgYm9keS50b2tlbiA9IEFVVEhfVE9LRU47XHJcbiAgICAgICAgaWYoYm9keSkgYm9keSA9IEpTT04uc3RyaW5naWZ5KGJvZHkpXHJcbiAgICAgICAgLy8gY29uc29sZS5sb2codXJsLGJvZHkpXHJcbiAgICAgICAgZmV0Y2godXJsLCB7XHJcbiAgICAgICAgICAgIFwiaGVhZGVyc1wiOiB7XHJcbiAgICAgICAgICAgICAgICAvLyBcIkF1dGhvcml6YXRpb25cIjogQVVUSF9UT0tFTixcclxuICAgICAgICAgICAgICAgIFwiQ29udGVudC1UeXBlXCI6IFwidGV4dC9wbGFpbjsgY2hhcnNldD11dGYtOFwiLFxyXG4gICAgICAgICAgICAgICAgXCJDYWNoZS1Db250cm9sXCI6IFwibm8tY2FjaGVcIlxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBcImJvZHlcIjogYm9keSB8fCBudWxsLFxyXG4gICAgICAgICAgICBcIm1ldGhvZFwiOiBtZXRob2QsXHJcbiAgICAgICAgICAgIFwiY3JlZGVudGlhbHNcIjpcIm9taXRcIixcclxuICAgICAgICAgICAgXCJtb2RlXCI6IFwiY29yc1wiXHJcbiAgICAgICAgfSkudGhlbihyZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgIGxldCBpc1N0cmVhbSA9IHRydWUgfHwgcmVzcG9uc2UuaGVhZGVycz8uZ2V0KFwiQ29udGVudC1UeXBlXCIpPy5pbmRleE9mKFwidGV4dC9ldmVudC1zdHJlYW1cIikgPiAtMVxyXG4gICAgICAgICAgICBsZXQgcmVtYWluaW5nRGF0YSA9IGBgO1xyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gcHJvY2Vzc0RhdGEoZGF0YSkge1xyXG4gICAgICAgICAgICAgICAgbGV0IGNvbWJpbmVkRGF0YSA9IHJlbWFpbmluZ0RhdGEgKyBkYXRhO1xyXG4gICAgICAgICAgICAgICAgbGV0IG1lc3NhZ2VzID0gY29tYmluZWREYXRhLnNwbGl0KCdcXG4nKTtcclxuICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgIGlmKG1lc3NhZ2VzPy5sZW5ndGg+MSl7IC8vIOiHs+WwkeWIhuWJsjLmnaHmtojmga/ml7bov5vooYzlpITnkIZcclxuICAgICAgICAgICAgICAgICAgICAvLyDlpITnkIbmr4/kuKrlrozmlbTnmoTmtojmga9cclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG1lc3NhZ2VzLmxlbmd0aCAtIDE7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgbWVzc2FnZSA9IG1lc3NhZ2VzW2ldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5uZXh0KG1lc3NhZ2UpXHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyDkv53lrZjmnIDlkI7kuIDkuKrkuI3lrozmlbTnmoTmtojmga9cclxuICAgICAgICAgICAgICAgICAgICByZW1haW5pbmdEYXRhID0gbWVzc2FnZXNbbWVzc2FnZXMubGVuZ3RoIC0gMV07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKGlzU3RyZWFtKSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgZ3JlYWRlciA9IHJlc3BvbnNlLmJvZHk/LmdldFJlYWRlcigpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigpO1xyXG5cclxuICAgICAgICAgICAgICAgIGxldCByc3RyZWFtID0gbmV3IFJlYWRhYmxlU3RyZWFtKHtcclxuICAgICAgICAgICAgICAgICAgICBzdGFydChjb250cm9sbGVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHJlYWQoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmVhZGVyLnJlYWQoKS50aGVuKCh7IGRvbmUsIHZhbHVlIH0pID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZG9uZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXIuY2xvc2UoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5jb21wbGV0ZSgpOyAvLyBDb21wbGV0ZSB0aGUgb2JzZXJ2ZXIgd2hlbiBzdHJlYW0gcHJvY2Vzc2luZyBpcyBkb25lXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sbGVyLmVucXVldWUodmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICByZWFkKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgbGV0IHJlYWRlciA9IHJzdHJlYW0uZ2V0UmVhZGVyKCk7XHJcblxyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gcHJvY2Vzc1N0cmVhbShyZXN1bHQ6IFJlYWRhYmxlU3RyZWFtUmVhZFJlc3VsdDxhbnk+KTp2b2lkIHwgUHJvbWlzZUxpa2U8dm9pZD4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGxldCB7IGRvbmUsIHZhbHVlIH0gPSByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRvbmUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IHRleHQgPSBkZWNvZGVyLmRlY29kZSh2YWx1ZSlcclxuICAgICAgICAgICAgICAgICAgICBwcm9jZXNzRGF0YSh0ZXh0KSAvLyBFbWl0IGVhY2ggY2h1bmsgb2YgZGF0YVxyXG4gICAgICAgICAgICAgICAgICAgIHJlYWRlci5yZWFkKCkudGhlbihwcm9jZXNzU3RyZWFtKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICByZWFkZXIucmVhZCgpLnRoZW4ocHJvY2Vzc1N0cmVhbSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IG9ic2VydmVyLmVycm9yKGVycm9yKSk7IC8vIEhhbmRsZSBhbnkgZXJyb3JzXHJcblxyXG4gICAgICAgIC8vIFJldHVybiB0aGUgc3Vic2NyaXB0aW9uIGxvZ2ljXHJcbiAgICAgICAgcmV0dXJuICgpID0+IHtcclxuICAgICAgICAgICAgLy8gQ2xlYW4gdXAgbG9naWMsIGlmIG5lZWRlZFxyXG4gICAgICAgIH07XHJcbiAgICB9KTtcclxuICB9XHJcbiAgXHJcbiAgZnVuY3Rpb24gSnNvblRvRm9ybURhdGEoanNvbikge1xyXG4gICAgY29uc3QgZm9ybURhdGEgPSBuZXcgRm9ybURhdGEoKTtcclxuICBcclxuICAgIGZ1bmN0aW9uIGFwcGVuZEZvcm1EYXRhKGRhdGEsIHBhdGggPSAnJykge1xyXG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xyXG4gICAgICAgIGRhdGEuZm9yRWFjaCgodmFsdWUsIGluZGV4KSA9PiB7XHJcbiAgICAgICAgICBhcHBlbmRGb3JtRGF0YSh2YWx1ZSwgYCR7cGF0aH1bJHtpbmRleH1dYCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGRhdGEgPT09ICdvYmplY3QnICYmIGRhdGEgIT09IG51bGwpIHtcclxuICAgICAgICBPYmplY3Qua2V5cyhkYXRhKS5mb3JFYWNoKGtleSA9PiB7XHJcbiAgICAgICAgICBjb25zdCBuZXdQYXRoID0gcGF0aCA/IGAke3BhdGh9LiR7a2V5fWAgOiBrZXk7XHJcbiAgICAgICAgICBhcHBlbmRGb3JtRGF0YShkYXRhW2tleV0sIG5ld1BhdGgpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGZvcm1EYXRhLmFwcGVuZChwYXRoLCBkYXRhKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIFxyXG4gICAgYXBwZW5kRm9ybURhdGEoanNvbik7XHJcbiAgXHJcbiAgICByZXR1cm4gZm9ybURhdGE7XHJcbiAgfVxyXG5cclxuXHJcblxyXG4gIC8qKlxyXG4gKiDkvb/nlKhBSeeUn+aIkOespuWQiOaMh+Wumue7k+aehOeahEpTT07mlbDmja5cclxuICogQHBhcmFtIHByb21wdCDku7vliqHopoHmsYLnmoTmlbTkvZPmj5DnpLror41cclxuICogQHBhcmFtIGpzb25TY2hlbWEg5pyf5pyb55qESlNPTue7k+aehOaPj+i/sO+8iOeUqOS6juaPkOekuuivje+8iVxyXG4gKiBAcGFyYW0gb25NZXNzYWdlIOWunuaXtueUn+aIkOWGheWuueWbnuiwg1xyXG4gKiBAcGFyYW0gcmV0cnlDb3VudCDph43or5XmrKHmlbDvvIzpu5jorqTkuLox5qyhXHJcbiAqIEByZXR1cm5zIOino+aekOWQjueahEpTT07lr7nosaFcclxuICovXHJcbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjb21wbGV0aW9uSlNPTihcclxuICAgIHByb21wdDogc3RyaW5nLFxyXG4gICAganNvblNjaGVtYTogc3RyaW5nLFxyXG4gICAgb25NZXNzYWdlPzogKGNvbnRlbnQ6IHN0cmluZykgPT4gdm9pZCxcclxuICAgIHJldHJ5Q291bnQ6IG51bWJlciA9IDEsXHJcbiAgICBvcHRpb25zPzphbnl8e1xyXG4gICAgICAgIG1vZGVsOnN0cmluZ1xyXG4gICAgICAgIHRoaW5raW5nPzp7dHlwZTpcImVuYWJsZWRcInxcImRpc2FibGVkXCJ8XCJhdXRvXCJ9LFxyXG4gICAgICAgIG1heF90b2tlbnM/Om51bWJlclxyXG4gICAgfVxyXG4pOiBQcm9taXNlPGFueT4ge1xyXG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XHJcbiAgICBsZXQgY3VycmVudFJldHJ5ID0gMDtcclxuICAgIFxyXG4gICAgY29uc3QgYXR0ZW1wdENvbXBsZXRpb24gPSBhc3luYyAoKTogUHJvbWlzZTxhbnk+ID0+IHtcclxuICAgICAgICAvLyAxLiDmnoTlu7rmj5DnpLror41cclxuICAgICAgICBjb25zdCBKc29uUmVzdWx0UGFyc2VQcm9tcHQgPSBg6K+35Lil5qC85oyJ54Wn5Lul5LiL6KaB5rGC55Sf5oiQSlNPTuaVsOaNru+8mlxyXG4tIOaVsOaNrue7k+aehOimgeaxgu+8miR7anNvblNjaGVtYX1cclxuLSDov5Tlm57kuIDkuKrlrozmlbTnmoRKU09O5a+56LGh77yM6K+356Gu5L+dSlNPTuagvOW8j+WujOaVtO+8jOS4jeimgemBl+a8j+S7u+S9leagh+eCueespuWPt1xyXG4tIOazqOaEj+i/lOWbnueahEpTT07moLzlvI/mr4/kuKpLRVnpg73mnIlcIlwi5YyF6KO55ZKMVmFsdWXkuYvpl7Tpg73mnIk6XHJcbi0g5rOo5oSPXCJcIuWtl+espuS4suWGheWGjeWHuueOsFwi56ym5Y+36ZyA6KaB55SoXFxcXFxcXCLovazkuYlcclxuYDtcclxuXHJcbiAgICAgICAgLy8gMi4g5Yid5aeL5YyW5raI5oGv5YiX6KGoXHJcbiAgICAgICAgY29uc3QgbWVzc2FnZUxpc3QgPSBbXHJcbiAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgIHJvbGU6IFwidXNlclwiLFxyXG4gICAgICAgICAgICAgICAgY29udGVudDogcHJvbXB0ICsgSnNvblJlc3VsdFBhcnNlUHJvbXB0XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICBdO1xyXG5cclxuICAgICAgICAvLyAzLiDliJvlu7pGbW9kZUNoYXRDb21wbGV0aW9u5a6e5L6LXHJcbiAgICAgICAgb3B0aW9ucy5yZXNwb25zZV9mb3JtYXQgPSB7IFwidHlwZVwiOiBcImpzb25fb2JqZWN0XCIgfVxyXG4gICAgICAgIGNvbnN0IGNvbXBsZXRpb24gPSBuZXcgRm1vZGVDaGF0Q29tcGxldGlvbihtZXNzYWdlTGlzdCxvcHRpb25zKTtcclxuICAgICAgICBcclxuICAgICAgICAvLyA0LiDlrZjlgqjntK/np6/lhoXlrrlcclxuICAgICAgICBsZXQgZnVsbENvbnRlbnQgPSBcIlwiO1xyXG4gICAgICAgIFxyXG4gICAgICAgIC8vIDUuIOi/lOWbnlByb21pc2XvvIzlpITnkIblvILmraXmtYHlvI/lk43lupRcclxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBzZW5kJCA9IGNvbXBsZXRpb24uc2VuZENvbXBsZXRpb24oe2lzRGlyZWN0OnRydWUsbWF4X3Rva2VuczozMjc2OH0pLnN1YnNjcmliZSh7XHJcbiAgICAgICAgICAgICAgICBuZXh0OiAobWVzc2FnZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIOWkhOeQhua2iOaBr+WGheWuuVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZT8uY29udGVudCA9PT0gXCJzdHJpbmdcIikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmdWxsQ29udGVudCA9IG1lc3NhZ2UuY29udGVudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIOiwg+eUqOWbnuiwg+WHveaVsO+8jOWunuaXtuaOqOmAgeeUn+aIkOWGheWuuVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAob25NZXNzYWdlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbk1lc3NhZ2UoZnVsbENvbnRlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgIC8vIOajgOafpeaYr+WQpuWujOaIkFxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChtZXNzYWdlLmNvbXBsZXRlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyA2LiDmnIDnu4hKU09O5o+Q5Y+WXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBqc29uT2JqZWN0ID0gZXh0cmFjdEpTT04oZnVsbENvbnRlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGpzb25PYmplY3QpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGpzb25PYmplY3QpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCLmnKrog73ku47lk43lupTkuK3mj5Dlj5bmnInmlYjnmoRKU09O5a+56LGhXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlOmFueSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihgSlNPTuino+aekOWksei0pSAo56ysJHtjdXJyZW50UmV0cnkgKyAxfeasoeWwneivlSk6YCwgZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhcIuWOn+Wni+WGheWuuTpcIiwgZnVsbENvbnRlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihg55Sf5oiQ55qE5ZON5bqU5LiN56ym5ZCISlNPTuagvOW8jzogJHtlLm1lc3NhZ2V9YCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyDnu5PmnZ/orqLpmIVcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VuZCQudW5zdWJzY3JpYmUoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZXJyb3I6IChlcnJvcikgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJDb21wbGV0aW9u6K+35rGC5aSx6LSlOlwiLCBlcnJvcik7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VuZCQudW5zdWJzY3JpYmUoKTtcclxuICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gICAgLy8g6YeN6K+V6YC76L6RXHJcbiAgICB3aGlsZSAoY3VycmVudFJldHJ5IDw9IHJldHJ5Q291bnQpIHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBhdHRlbXB0Q29tcGxldGlvbigpO1xyXG4gICAgICAgICAgICBpZiAoY3VycmVudFJldHJ5ID4gMCkge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coYEpTT07nlJ/miJDmiJDlip/vvIzph43or5XkuoYgJHtjdXJyZW50UmV0cnl9IOasoWApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICAgICAgY3VycmVudFJldHJ5Kys7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBpZiAoY3VycmVudFJldHJ5IDw9IHJldHJ5Q291bnQpIHtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUud2Fybihg56ysICR7Y3VycmVudFJldHJ5fSDmrKHlsJ3or5XlpLHotKXvvIzmraPlnKjph43or5UuLi4g6ZSZ6K+v5L+h5oGvOmAsIGVycm9yLm1lc3NhZ2UpO1xyXG4gICAgICAgICAgICAgICAgLy8g5Y+v5Lul5re75Yqg5bu26L+f6YG/5YWN6L+H5b+r6YeN6K+VXHJcbiAgICAgICAgICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgMTAwMCkpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihgSlNPTueUn+aIkOWksei0pe+8jOW3sumHjeivlSAke3JldHJ5Q291bnR9IOasoe+8jOacgOe7iOmUmeivrzpgLCBlcnJvcik7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYOe7j+i/hyAke3JldHJ5Q291bnR9IOasoemHjeivleWQjuS7jeaXoOazleeUn+aIkOacieaViEpTT046ICR7ZXJyb3IubWVzc2FnZX1gKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIOS7juWtl+espuS4suS4reaPkOWPlkpTT07lr7nosaHvvIjlop7lvLrniYjvvIlcclxuICogQHBhcmFtIHN0ciDljIXlkKtKU09O55qE5a2X56ym5LiyXHJcbiAqIEByZXR1cm5zIOino+aekOWQjueahEpTT07lr7nosaHmiJZudWxsXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZXh0cmFjdEpTT04oc3RyOiBzdHJpbmcpOiBhbnkge1xyXG4gICAgLy8gY29uc29sZS5sb2coXCJmdWxsQ29udGVudFwiLHN0cilcclxuICAgIC8vIOmmluWFiOWwneivleebtOaOpeino+aekOaVtOS4quWtl+espuS4slxyXG4gICAgdHJ5IHtcclxuICAgICAgICByZXR1cm4gSlNPTi5wYXJzZShzdHIudHJpbSgpKTtcclxuICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAvLyDlpoLmnpznm7TmjqXop6PmnpDlpLHotKXvvIzliJnlsJ3or5Xmj5Dlj5ZKU09O54mH5q61XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IHN0YWNrID0gMDtcclxuICAgIGxldCBzdGFydEluZGV4ID0gLTE7XHJcbiAgICBsZXQgcmVzdWx0ID0gbnVsbDtcclxuXHJcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGlmIChzdHJbaV0gPT09ICd7Jykge1xyXG4gICAgICAgICAgICBpZiAoc3RhY2sgPT09IDApIHN0YXJ0SW5kZXggPSBpO1xyXG4gICAgICAgICAgICBzdGFjaysrO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoc3RyW2ldID09PSAnfScpIHtcclxuICAgICAgICAgICAgc3RhY2stLTtcclxuICAgICAgICAgICAgaWYgKHN0YWNrID09PSAwICYmIHN0YXJ0SW5kZXggIT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGpzb25TdHIgPSBzdHIuc2xpY2Uoc3RhcnRJbmRleCwgaSArIDEpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IEpTT04ucGFyc2UoanNvblN0cik7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8g57un57ut5bCd6K+V5LiL5LiA5Liq5Y+v6IO955qEIEpTT05cclxuICAgICAgICAgICAgICAgICAgICBzdGFydEluZGV4ID0gLTE7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8g5aaC5p6c6L+Y5piv5rKh5pyJ5om+5Yiw5pyJ5pWISlNPTu+8jOWwneivleS/ruWkjeW4uOingeeahEpTT07moLzlvI/pl67pophcclxuICAgIGlmICghcmVzdWx0KSB7XHJcbiAgICAgICAgcmVzdWx0ID0gdHJ5Rml4QW5kUGFyc2VKU09OKHN0cik7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxuLyoqXHJcbiAqIOWwneivleS/ruWkjeW4uOingeeahEpTT07moLzlvI/pl67popjlubbop6PmnpBcclxuICogQHBhcmFtIHN0ciDlj6/og73mnInmoLzlvI/pl67popjnmoRKU09O5a2X56ym5LiyXHJcbiAqIEByZXR1cm5zIOino+aekOWQjueahEpTT07lr7nosaHmiJZudWxsXHJcbiAqL1xyXG5mdW5jdGlvbiB0cnlGaXhBbmRQYXJzZUpTT04oc3RyOiBzdHJpbmcpOiBhbnkge1xyXG4gICAgLy8g5o+Q5Y+W5Y+v6IO955qESlNPTumDqOWIhlxyXG4gICAgY29uc3QganNvbk1hdGNoID0gc3RyLm1hdGNoKC9cXHtbXFxzXFxTXSpcXH0vKTtcclxuICAgIGlmICghanNvbk1hdGNoKSByZXR1cm4gbnVsbDtcclxuICAgIFxyXG4gICAgbGV0IGpzb25TdHIgPSBqc29uTWF0Y2hbMF07XHJcbiAgICBcclxuICAgIC8vIOWwneivleS/ruWkjeW4uOingemXrumimFxyXG4gICAgY29uc3QgZml4ZXMgPSBbXHJcbiAgICAgICAgLy8g56e76Zmk5pyr5bC+5aSa5L2Z55qE6YCX5Y+3XHJcbiAgICAgICAgKHM6IHN0cmluZykgPT4gcy5yZXBsYWNlKC8sKFxccypbfVxcXV0pL2csICckMScpLFxyXG4gICAgICAgIC8vIOehruS/neWxnuaAp+WQjeacieW8leWPt1xyXG4gICAgICAgIChzOiBzdHJpbmcpID0+IHMucmVwbGFjZSgvKFt7LF1cXHMqKShbYS16QS1aXyRdW2EtekEtWjAtOV8kXSopXFxzKjovZywgJyQxXCIkMlwiOicpLFxyXG4gICAgICAgIC8vIOS/ruWkjeWNleW8leWPt+S4uuWPjOW8leWPt1xyXG4gICAgICAgIChzOiBzdHJpbmcpID0+IHMucmVwbGFjZSgvJy9nLCAnXCInKSxcclxuICAgICAgICAvLyDnp7vpmaTms6jph4pcclxuICAgICAgICAoczogc3RyaW5nKSA9PiBzLnJlcGxhY2UoL1xcL1xcKltcXHNcXFNdKj9cXCpcXC8vZywgJycpLnJlcGxhY2UoL1xcL1xcLy4qJC9nbSwgJycpLFxyXG4gICAgXTtcclxuICAgIFxyXG4gICAgZm9yIChjb25zdCBmaXggb2YgZml4ZXMpIHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBjb25zdCBmaXhlZFN0ciA9IGZpeChqc29uU3RyKTtcclxuICAgICAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UoZml4ZWRTdHIpO1xyXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgLy8g57un57ut5bCd6K+V5LiL5LiA5Liq5L+u5aSN5pa55rOVXHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgXHJcbiAgICByZXR1cm4gbnVsbDtcclxufSJdfQ==
|
|
8
|
+
import{bufferTime,concatMap,delay,Observable}from"rxjs";const API_BASE="https://server.fmode.cn/api/apig/aigc/gpt";import{FmodeParse}from"@fmode/parse";const Parse=FmodeParse.with("nova");export class FmodeChatCompletion{constructor(e,t){this.content="",this.contentBuffer=[],this.isCompleted=!1,this.indexOfList=Number(e.length),this.messages=e,this.model=t?.model||"fmode-1.6-cn",this.max_tokens=t?.max_tokens||32768}sendCompletion(e={messages:[]}){e.intTime=e?.intTime||50,e.isDirect=e?.isDirect||!1,e?.isDirect&&(e.intTime=1);let t={messages:this.messages,stream:!0,model:this.model,temperature:e?.temperature||.5,presence_penalty:e?.presence_penalty||0,frequency_penalty:e?.frequency_penalty||0};return this.model.indexOf("1.6")>-1&&(t.thinking=t.thinking||{type:"disabled"}),e?.max_tokens&&(t.max_tokens=e?.max_tokens||this.max_tokens),new Observable((n=>{let o=RequestFmodeChatApi("/v1/chat/completions",t).subscribe((t=>{let r,s=String(t);try{r=chunkToJson(s)}catch(e){}if(("data: [DONE]"==s||r?.created&&r?.choices?.[0]?.finish_reason)&&(this.isCompleted=!0,e?.isDirect&&this.isCompleted&&(n.next({role:"assistant",content:this.content,complete:!0,createdAt:new Date}),o.unsubscribe(),e?.onComplete&&e.onComplete({role:"assistant",content:this.content,complete:!0,createdAt:new Date}),n.complete())),s.indexOf("data: {")>-1){let t=r?.choices?.[0]?.delta?.content||"";this.contentBuffer.push(t),e?.isDirect&&(this.content+=t||"",this.isCompleted||n.next({role:"assistant",cid:r?.id,content:this.content,createdAt:new Date})),e?.isDirect||this.contentPusher||(this.contentPusher=setInterval((()=>{this.isCompleted&&0==this.contentBuffer?.length&&(n.next({role:"assistant",cid:r?.id,content:this.content,complete:!0,createdAt:new Date}),o.unsubscribe(),clearInterval(this.contentPusher),n.complete()),this.contentBuffer?.length>=0&&(this.contentBuffer?.length>0&&(this.content+=this.contentBuffer.shift()),n.next({role:"assistant",cid:r?.id,content:this.content,createdAt:new Date}))}),e?.intTime))}}))})).pipe(bufferTime(100),concatMap((e=>e)),delay(200))}}function chunkToJson(e){let t;try{t=JSON.parse(e.replaceAll("data: ",""))}catch(e){}return t||{}}function RequestFmodeChatApi(e,t,n="POST"){return new Observable((o=>{let r=API_BASE+e,s=`Bearer ${Parse.User.current()?.getSessionToken()||localStorage.getItem("FMODE_AI_TOKEN")}`;return t.token=s,t&&(t=JSON.stringify(t)),fetch(r,{headers:{"Content-Type":"text/plain; charset=utf-8","Cache-Control":"no-cache"},body:t||null,method:n,credentials:"omit",mode:"cors"}).then((e=>{let t="";{let n=e.body?.getReader();const r=new TextDecoder;let s=new ReadableStream({start(e){!function read(){n.read().then((({done:t,value:n})=>{if(t)return e.close(),void o.complete();e.enqueue(n),read()}))}()}}).getReader();s.read().then((function processStream(e){let{done:n,value:c}=e;n||(!function processData(e){let n=(t+e).split("\n");if(n?.length>1){for(let e=0;e<n.length-1;e++){let t=n[e];o.next(t)}t=n[n.length-1]}}(r.decode(c)),s.read().then(processStream))}))}})).catch((e=>o.error(e))),()=>{}}))}function JsonToFormData(e){const t=new FormData;return function appendFormData(e,n=""){Array.isArray(e)?e.forEach(((e,t)=>{appendFormData(e,`${n}[${t}]`)})):"object"==typeof e&&null!==e?Object.keys(e).forEach((t=>{const o=n?`${n}.${t}`:t;appendFormData(e[t],o)})):t.append(n,e)}(e),t}export async function completionJSON(e,t,n,o=1,r){r=r||{};let s=0;const attemptCompletion=async()=>{const o=[{role:"user",content:e+`请严格按照以下要求生成JSON数据:\n- 数据结构要求:${t}\n- 返回一个完整的JSON对象,请确保JSON格式完整,不要遗漏任何标点符号\n- 注意返回的JSON格式每个KEY都有""包裹和Value之间都有:\n- 注意""字符串内再出现"符号需要用\\"转义\n`}];r.response_format={type:"json_object"};const c=new FmodeChatCompletion(o,r);let a="";return new Promise(((e,t)=>{const o=c.sendCompletion({isDirect:!0,max_tokens:32768}).subscribe({next:r=>{if("string"==typeof r?.content&&(a=r.content,n&&n(a)),r.complete){try{const t=extractJSON(a);if(!t)throw new Error("未能从响应中提取有效的JSON对象");e(t)}catch(e){console.error(`JSON解析失败 (第${s+1}次尝试):`,e),t(new Error(`生成的响应不符合JSON格式: ${e.message}`))}o.unsubscribe()}},error:e=>{console.error("Completion请求失败:",e),o.unsubscribe(),t(e)}})}))};for(;s<=o;)try{const e=await attemptCompletion();return s>0&&console.log(`JSON生成成功,重试了 ${s} 次`),e}catch(e){if(s++,!(s<=o))throw console.error(`JSON生成失败,已重试 ${o} 次,最终错误:`,e),new Error(`经过 ${o} 次重试后仍无法生成有效JSON: ${e.message}`);console.warn(`第 ${s} 次尝试失败,正在重试... 错误信息:`,e.message),await new Promise((e=>setTimeout(e,1e3)))}}export function extractJSON(e){try{return JSON.parse(e.trim())}catch(e){}let t=0,n=-1,o=null;for(let r=0;r<e.length;r++)if("{"===e[r])0===t&&(n=r),t++;else if("}"===e[r]&&(t--,0===t&&-1!==n))try{const t=e.slice(n,r+1);o=JSON.parse(t);break}catch(e){n=-1}return o||(o=tryFixAndParseJSON(e)),o}function tryFixAndParseJSON(e){const t=e.match(/\{[\s\S]*\}/);if(!t)return null;let n=t[0];const o=[e=>e.replace(/,(\s*[}\]])/g,"$1"),e=>e.replace(/([{,]\s*)([a-zA-Z_$][a-zA-Z0-9_$]*)\s*:/g,'$1"$2":'),e=>e.replace(/'/g,'"'),e=>e.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\/\/.*$/gm,"")];for(const e of o)try{const t=e(n);return JSON.parse(t)}catch(e){}return null}
|
|
9
|
+
var MODULE_PATH_NEED = `6K+l5paH5Lu25piv5pys6aG555uu55qE5LiA6YOo5YiGIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBDb21wb25lbnRzIGluIEZtb2RlIEluYy4KICAgIOeJiOadg+aJgOaciSDCqSDmnKrmnaXpo57pqawgwqkg5rGf6KW/6ISR5o6n56eR5oqA5pyJ6ZmQ5YWs5Y+4IENvcHlyaWdodCDCqSBGbW9kZSBUZWNobm9sb2d5IENvLiwgTHRkLgogICAg5L+d55WZ5omA5pyJ5p2D5YipIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAgICDkuKXnpoHlnKjmnKrnu4/mjojmnYPnmoTmg4XlhrXkuIvvvIzpgJrov4fku7vkvZXlqpLku4vlpI3liLbmraTmlofku7YgVW5hdXRob3JpemVkIGNvcHlpbmcgb2YgdGhpcyBmaWxlLCB2aWEgYW55IG1lZGl1bSBpcyBzdHJpY3RseSBwcm9oaWJpdGVkCiAgICDor6Xmlofku7bmmK/kuJPmnInnmoTmnLrlr4bmlofku7YgUHJvcHJpZXRhcnkgYW5kIGNvbmZpZGVudGlhbAogICAKICAgIENvcHlyaWdodCAyMDIxLW5vdyBGbW9kZSBJbmMuIHN1cHBvcnRAZm1vZGUuY24uIDE4NjA3MDA3MDczLgogICAg5L+d55WZ5omA5pyJ5p2D5YipIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogICAgUEFUSDovaG9tZS9yeWFuL3dvcmtzcGFjZS9ub3ZhL25vdmEtYWRtaW4vZGlzdC9mbW9kZS1uZy9lc20yMDIyL2xpYi9jb3JlL2FnZW50L2NoYXQvY29tcGxldGlvbi9mbW9kZS1jb21wbGV0aW9uLm1qcw==`
|
|
10
|
+
|
|
@@ -1,2 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
|
|
2
|
+
/**
|
|
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/completion/index.mjs
|
|
7
|
+
*/
|
|
8
|
+
export*from"./fmode-completion";
|
|
9
|
+
var MODULE_PATH_NEED = `6K+l5paH5Lu25piv5pys6aG555uu55qE5LiA6YOo5YiGIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBDb21wb25lbnRzIGluIEZtb2RlIEluYy4KICAgIOeJiOadg+aJgOaciSDCqSDmnKrmnaXpo57pqawgwqkg5rGf6KW/6ISR5o6n56eR5oqA5pyJ6ZmQ5YWs5Y+4IENvcHlyaWdodCDCqSBGbW9kZSBUZWNobm9sb2d5IENvLiwgTHRkLgogICAg5L+d55WZ5omA5pyJ5p2D5YipIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAgICDkuKXnpoHlnKjmnKrnu4/mjojmnYPnmoTmg4XlhrXkuIvvvIzpgJrov4fku7vkvZXlqpLku4vlpI3liLbmraTmlofku7YgVW5hdXRob3JpemVkIGNvcHlpbmcgb2YgdGhpcyBmaWxlLCB2aWEgYW55IG1lZGl1bSBpcyBzdHJpY3RseSBwcm9oaWJpdGVkCiAgICDor6Xmlofku7bmmK/kuJPmnInnmoTmnLrlr4bmlofku7YgUHJvcHJpZXRhcnkgYW5kIGNvbmZpZGVudGlhbAogICAKICAgIENvcHlyaWdodCAyMDIxLW5vdyBGbW9kZSBJbmMuIHN1cHBvcnRAZm1vZGUuY24uIDE4NjA3MDA3MDczLgogICAg5L+d55WZ5omA5pyJ5p2D5YipIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogICAgUEFUSDovaG9tZS9yeWFuL3dvcmtzcGFjZS9ub3ZhL25vdmEtYWRtaW4vZGlzdC9mbW9kZS1uZy9lc20yMDIyL2xpYi9jb3JlL2FnZW50L2NoYXQvY29tcGxldGlvbi9pbmRleC5tanM=`
|
|
10
|
+
|
|
@@ -1,2 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
|
|
2
|
+
/**
|
|
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/completion/int-gpt-chat-options.mjs
|
|
7
|
+
*/
|
|
8
|
+
export{};
|
|
9
|
+
var MODULE_PATH_NEED = `6K+l5paH5Lu25piv5pys6aG555uu55qE5LiA6YOo5YiGIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBDb21wb25lbnRzIGluIEZtb2RlIEluYy4KICAgIOeJiOadg+aJgOaciSDCqSDmnKrmnaXpo57pqawgwqkg5rGf6KW/6ISR5o6n56eR5oqA5pyJ6ZmQ5YWs5Y+4IENvcHlyaWdodCDCqSBGbW9kZSBUZWNobm9sb2d5IENvLiwgTHRkLgogICAg5L+d55WZ5omA5pyJ5p2D5YipIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAgICDkuKXnpoHlnKjmnKrnu4/mjojmnYPnmoTmg4XlhrXkuIvvvIzpgJrov4fku7vkvZXlqpLku4vlpI3liLbmraTmlofku7YgVW5hdXRob3JpemVkIGNvcHlpbmcgb2YgdGhpcyBmaWxlLCB2aWEgYW55IG1lZGl1bSBpcyBzdHJpY3RseSBwcm9oaWJpdGVkCiAgICDor6Xmlofku7bmmK/kuJPmnInnmoTmnLrlr4bmlofku7YgUHJvcHJpZXRhcnkgYW5kIGNvbmZpZGVudGlhbAogICAKICAgIENvcHlyaWdodCAyMDIxLW5vdyBGbW9kZSBJbmMuIHN1cHBvcnRAZm1vZGUuY24uIDE4NjA3MDA3MDczLgogICAg5L+d55WZ5omA5pyJ5p2D5YipIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogICAgUEFUSDovaG9tZS9yeWFuL3dvcmtzcGFjZS9ub3ZhL25vdmEtYWRtaW4vZGlzdC9mbW9kZS1uZy9lc20yMDIyL2xpYi9jb3JlL2FnZW50L2NoYXQvY29tcGxldGlvbi9pbnQtZ3B0LWNoYXQtb3B0aW9ucy5tanM=`
|
|
10
|
+
|