fmode-ng 0.0.39 → 0.0.41
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/esm2022/fmode-ng.mjs +5 -10
- package/esm2022/lib/aigc/agent/agent.prompt.mjs +122 -10
- package/esm2022/lib/aigc/agent/index.mjs +2 -10
- package/esm2022/lib/aigc/avatar/avatar.module.mjs +45 -10
- package/esm2022/lib/aigc/avatar/comp-avatar-particle/avatar.role.mjs +2 -10
- package/esm2022/lib/aigc/avatar/comp-avatar-particle/comp-avatar-particle.component.mjs +315 -10
- package/esm2022/lib/aigc/avatar/comp-avatar-particle/index.mjs +3 -10
- package/esm2022/lib/aigc/avatar/comp-avatar-particle/role-points.class.mjs +57 -10
- package/esm2022/lib/aigc/avatar/comp-avatar-role-image/comp-avatar-role-image.component.mjs +97 -10
- package/esm2022/lib/aigc/avatar/comp-avatar-role-video/comp-avatar-role-video.component.mjs +104 -10
- package/esm2022/lib/aigc/avatar/comp-avatar-talk/comp-avatar-talk.component.mjs +111 -10
- package/esm2022/lib/aigc/avatar/index.mjs +8 -10
- package/esm2022/lib/aigc/avatar/interface-avatar-role.mjs +2 -10
- package/esm2022/lib/aigc/avatar/modal-chat-voice-input/modal-chat-voice-input.component.mjs +166 -8
- package/esm2022/lib/aigc/chat/chat-header-area/comp-header-area.component.mjs +36 -10
- package/esm2022/lib/aigc/chat/chat-header-area/index.mjs +2 -10
- package/esm2022/lib/aigc/chat/chat-list/chat-list.component.mjs +141 -8
- package/esm2022/lib/aigc/chat/chat-list/index.mjs +2 -10
- package/esm2022/lib/aigc/chat/chat-message-area/comp-message-area.component.mjs +40 -10
- package/esm2022/lib/aigc/chat/chat-message-area/index.mjs +2 -10
- package/esm2022/lib/aigc/chat/chat-message-card/comp-message-card.component.mjs +92 -10
- package/esm2022/lib/aigc/chat/chat-message-card/index.mjs +2 -10
- package/esm2022/lib/aigc/chat/chat-modal-input/index.mjs +2 -10
- package/esm2022/lib/aigc/chat/chat-modal-input/modal-audio-message/modal-audio-message.component.mjs +207 -8
- package/esm2022/lib/aigc/chat/chat-modal-input/modal-input.component.mjs +236 -10
- package/esm2022/lib/aigc/chat/chat-panel/chat-panel.component.mjs +137 -10
- package/esm2022/lib/aigc/chat/comp-role-prompt/comp-role-prompt.component.mjs +69 -10
- package/esm2022/lib/aigc/chat/comp-role-prompt/index.mjs +2 -10
- package/esm2022/lib/aigc/chat/index.mjs +8 -10
- package/esm2022/lib/aigc/comp-markdown-preview/clipboard.service.mjs +82 -10
- package/esm2022/lib/aigc/comp-markdown-preview/markdown-parse.mjs +269 -8
- package/esm2022/lib/aigc/comp-markdown-preview/markdown-preview.component.mjs +51 -10
- package/esm2022/lib/aigc/comp-markdown-preview/markdown-preview.module.mjs +24 -10
- package/esm2022/lib/aigc/comp-markdown-preview/plugins/md-mathjax/index.mjs +94 -10
- package/esm2022/lib/aigc/index.mjs +13 -10
- package/esm2022/lib/aigc/service-fmai/fmai.service.mjs +21 -10
- package/esm2022/lib/aigc/service-fmai/service-chat/chat-class.mjs +736 -8
- package/esm2022/lib/aigc/service-fmai/service-chat/chat.service.mjs +181 -8
- package/esm2022/lib/aigc/service-fmai/service-chat/index.mjs +7 -10
- package/esm2022/lib/aigc/service-fmai/service-chat/mask-list.mjs +194 -9
- package/esm2022/lib/aigc/service-fmai/service-chat/pipes/chat-content.pipe.mjs +27 -10
- package/esm2022/lib/aigc/service-fmai/service-chat/pipes/hidexml.pipe.mjs +27 -10
- package/esm2022/lib/aigc/service-fmai/service-chat/utilnow.pipe.mjs +68 -10
- package/esm2022/lib/aigc/service-fmai/service-imagine/imagine.service.mjs +229 -8
- package/esm2022/lib/aigc/service-fmai/service-imagine/index.mjs +2 -10
- package/esm2022/lib/aigc/voice/audio.player.mjs +52 -10
- package/esm2022/lib/aigc/voice/class-asr.mjs +79 -8
- package/esm2022/lib/aigc/voice/fmode-voice.service.mjs +501 -8
- package/esm2022/lib/aigc/voice/index.mjs +3 -10
- package/esm2022/lib/aigc/voice/lib/pcm2wav.mjs +38 -10
- package/esm2022/lib/aigc/voice/lib/resample.mjs +34 -10
- package/esm2022/lib/aigc/voice/tts/fmode-tts-class.mjs +233 -8
- package/esm2022/lib/aigc/voice/tts/index.mjs +2 -10
- package/esm2022/lib/map/comp-poi-picker/comp-poi-picker.component.mjs +190 -10
- package/esm2022/lib/map/comp-poi-picker/comp-poi-picker.module.mjs +33 -10
- package/esm2022/lib/map/index.mjs +4 -10
- package/esm2022/lib/map/map.module.mjs +61 -10
- package/esm2022/lib/map/page-loca-scatter/page-loca-scatter.component.mjs +110 -10
- package/esm2022/lib/map/page-map.start/page-map.start.component.mjs +98 -8
- package/esm2022/lib/map/page-plan-route/page-plan-route.component.mjs +100 -8
- package/esm2022/lib/nova-cloud/index.mjs +2 -10
- package/esm2022/lib/nova-cloud/nova-cloud.service.mjs +148 -10
- package/esm2022/lib/platform/cross.service.mjs +63 -10
- package/esm2022/lib/platform/index.mjs +2 -10
- package/esm2022/lib/social/index.mjs +2 -10
- package/esm2022/lib/social/wechat/wechat-jssdk.service.mjs +236 -8
- package/esm2022/lib/storage/comp-hwobs-manager/hwobs-manager.component.mjs +59 -10
- package/esm2022/lib/storage/index.mjs +5 -10
- package/esm2022/lib/storage/service-hwobs/hwobs.service.mjs +130 -8
- package/esm2022/lib/storage/service-upload/index.mjs +2 -10
- package/esm2022/lib/storage/service-upload/nova-upload.service.mjs +462 -8
- package/esm2022/lib/storage/service-upload/util-file-md5.mjs +28 -10
- package/esm2022/lib/storage/storage.module.mjs +41 -10
- package/esm2022/lib/user/account/account.service.mjs +221 -10
- package/esm2022/lib/user/captcha/captcha.component.mjs +135 -10
- package/esm2022/lib/user/comp-user-avatar/comp-user-avatar.component.mjs +62 -10
- package/esm2022/lib/user/index.mjs +17 -10
- package/esm2022/lib/user/login/auth.guard.mjs +28 -10
- package/esm2022/lib/user/login/auth.service.mjs +373 -8
- package/esm2022/lib/user/login/login.component.mjs +913 -10
- package/esm2022/lib/user/modal-user-login/modal-user-login.component.mjs +273 -10
- package/esm2022/lib/user/profile/auth-profile.guard.mjs +27 -10
- package/esm2022/lib/user/profile/auth-profile.service.mjs +122 -10
- package/esm2022/lib/user/profile/profile-bind/profile-bind.component.mjs +115 -10
- package/esm2022/lib/user/profile/profile.module.mjs +57 -10
- package/esm2022/lib/user/staff/index.mjs +4 -10
- package/esm2022/lib/user/staff/staff.guard.mjs +26 -10
- package/esm2022/lib/user/staff/staff.module.mjs +18 -10
- package/esm2022/lib/user/staff/staff.service.mjs +85 -10
- package/esm2022/lib/user/user-name.pipe.mjs +29 -10
- package/esm2022/lib/user/user.module.mjs +106 -10
- package/esm2022/lib/video/fm-video/fm-video.component.mjs +67 -10
- package/esm2022/lib/video/index.mjs +2 -10
- package/esm2022/public-api.mjs +13 -10
- package/fesm2022/fmode-ng.mjs +8895 -7
- package/fesm2022/fmode-ng.mjs.map +1 -1
- package/lib/user/login/auth.service.d.ts +18 -3
- package/lib/user/modal-user-login/modal-user-login.component.d.ts +4 -2
- package/package.json +1 -1
- package/LICENSE.md +0 -8
|
@@ -1,10 +1,503 @@
|
|
|
1
|
-
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
// import RecorderManager from "./lib/xunfei-recorder"
|
|
3
|
+
// import {RecorderManager} from "./lib/recorder/recorder-manager"
|
|
4
|
+
import Recorder from 'recorder-core';
|
|
5
|
+
import 'recorder-core/src/engine/pcm';
|
|
6
|
+
import 'recorder-core/src/engine/wav';
|
|
7
|
+
import 'recorder-core/src/extensions/waveview';
|
|
8
|
+
import CryptoJS from "crypto-js";
|
|
9
|
+
import { pcmtoWav } from './lib/pcm2wav';
|
|
10
|
+
import { convertFrameBufferToBase64, resampleBuffer } from './lib/resample';
|
|
11
|
+
import { WebSpeech } from './class-asr';
|
|
12
|
+
import { Platform } from '@ionic/angular';
|
|
13
|
+
import { Diagnostic } from '@awesome-cordova-plugins/diagnostic/ngx';
|
|
14
|
+
import * as i0 from "@angular/core";
|
|
15
|
+
import * as i1 from "@ionic/angular";
|
|
16
|
+
import * as i2 from "@awesome-cordova-plugins/diagnostic/ngx";
|
|
17
|
+
// import { FmodeTTSXunfei } fro./class-tts-xunfei.ts.bakfei'
|
|
18
|
+
export class FmodeVoiceService {
|
|
19
|
+
constructor(platform, diagnostic) {
|
|
20
|
+
this.platform = platform;
|
|
21
|
+
this.diagnostic = diagnostic;
|
|
22
|
+
/**
|
|
23
|
+
* 讯飞TTS语音合成
|
|
24
|
+
*/
|
|
25
|
+
// ttsXunfei = new FmodeTTSXunfei()
|
|
26
|
+
/**
|
|
27
|
+
* WebSpeech 语音库
|
|
28
|
+
*/
|
|
29
|
+
this.webSpeech = WebSpeech;
|
|
30
|
+
/**
|
|
31
|
+
* 用户操作:完成录音,并处理转录结果
|
|
32
|
+
*/
|
|
33
|
+
this.isUserFinish = false;
|
|
34
|
+
this.recordWavBlob = null;
|
|
35
|
+
this.recordPcmBlob = null;
|
|
36
|
+
this.recordDuration = 0;
|
|
37
|
+
this.recordType = "pcm";
|
|
38
|
+
this.encodingType = "raw";
|
|
39
|
+
this.connStatus = ""; // 录音中 建立连接中 关闭连接中
|
|
40
|
+
this.btnStatus = "UNDEFINED"; // "UNDEFINED" "CONNECTING" "OPEN" "CLOSING" "CLOSED"
|
|
41
|
+
this.resultText = "";
|
|
42
|
+
this.resultTextTemp = "";
|
|
43
|
+
/**
|
|
44
|
+
* 获取websocket url
|
|
45
|
+
* 该接口需要后端提供,这里为了方便前端处理
|
|
46
|
+
*/
|
|
47
|
+
this.APPID = "50f4a46c";
|
|
48
|
+
this.API_SECRET = "NzFlNmFhZDJjMDNkZGM3NzI0Mzg2OGNm";
|
|
49
|
+
this.API_KEY = "106ddc40dfd4b9ca6d7b47c70fada749";
|
|
50
|
+
this.requestPermission();
|
|
51
|
+
// this.recorder.on("start",() => {
|
|
52
|
+
// })
|
|
53
|
+
// this.recorder.on("frameRecorded", ({ isLastFrame, frameBuffer }) => {
|
|
54
|
+
// if (this.iatWS.readyState === this.iatWS.OPEN) {
|
|
55
|
+
// this.iatWS.send(
|
|
56
|
+
// JSON.stringify({
|
|
57
|
+
// data: {
|
|
58
|
+
// status: isLastFrame ? 2 : 1,
|
|
59
|
+
// format: "audio/L16;rate=16000",
|
|
60
|
+
// encoding: this.encodingType,
|
|
61
|
+
// audio: this.toBase64(frameBuffer),
|
|
62
|
+
// },
|
|
63
|
+
// })
|
|
64
|
+
// );
|
|
65
|
+
// if (isLastFrame) {
|
|
66
|
+
// this.changeBtnStatus("CLOSING");
|
|
67
|
+
// }
|
|
68
|
+
// }
|
|
69
|
+
// })
|
|
70
|
+
// this.recorder.on("stop",() => {
|
|
71
|
+
// })
|
|
72
|
+
}
|
|
73
|
+
/**()
|
|
74
|
+
* 用户操作:录音按钮快捷触发操作
|
|
75
|
+
*/
|
|
76
|
+
toggleRecord() {
|
|
77
|
+
console.log(this.btnStatus);
|
|
78
|
+
if (this.btnStatus === "UNDEFINED" || this.btnStatus === "CLOSED") {
|
|
79
|
+
// 开始讲话`
|
|
80
|
+
this.startTalk();
|
|
81
|
+
}
|
|
82
|
+
else if (this.btnStatus === "CONNECTING" || this.btnStatus === "OPEN") {
|
|
83
|
+
// 结束录音 并发送消息等待回复
|
|
84
|
+
this.finishTalk();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
finishTalk() {
|
|
88
|
+
this.isUserFinish = true;
|
|
89
|
+
this.onBeforeFinishTalk && this.onBeforeFinishTalk();
|
|
90
|
+
this.recordStop();
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* 用户操作:开始讲话,实时转录语言
|
|
94
|
+
*/
|
|
95
|
+
async startTalk(evnet) {
|
|
96
|
+
this.resultText = "";
|
|
97
|
+
this.resultTextTemp = "";
|
|
98
|
+
this.onBeforeStartTalk && this.onBeforeStartTalk();
|
|
99
|
+
event?.preventDefault();
|
|
100
|
+
await this.openWithPriviledge();
|
|
101
|
+
setTimeout(() => {
|
|
102
|
+
this.connectWebSocket();
|
|
103
|
+
}, 100);
|
|
104
|
+
this.onAfterStartTalk && this.onAfterStartTalk();
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* 用户操作:取消讲话,且不发送结果
|
|
108
|
+
*/
|
|
109
|
+
cancelTalk() {
|
|
110
|
+
this.onBeforeCancelTalk && this.onBeforeCancelTalk();
|
|
111
|
+
this.recordStop(); // 停止录制
|
|
112
|
+
this.iatWS?.close(); // 断开连接
|
|
113
|
+
this.resultText = null; // 设置转录结果为空
|
|
114
|
+
this.onAfterCancelTalk && this.onAfterCancelTalk();
|
|
115
|
+
}
|
|
2
116
|
/**
|
|
3
|
-
*
|
|
4
|
-
* 版权所有 © 未来飞马 © 江西脑控科技有限公司 Copyright © Fmode Technology Co., Ltd.
|
|
5
|
-
* 保留所有权利 All Rights Reserved.
|
|
6
|
-
* /home/ryan/workspace/nova/nova-admin/dist/fmode-ng/esm2022/lib/aigc/voice/fmode-voice.service.mjs
|
|
117
|
+
* 程序逻辑
|
|
7
118
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
119
|
+
async recordStart() {
|
|
120
|
+
this.createRecorder();
|
|
121
|
+
await this.openWithPriviledge();
|
|
122
|
+
this.recorder.start();
|
|
123
|
+
this.changeBtnStatus("OPEN");
|
|
124
|
+
this.onAfterRecordStart && this.onAfterRecordStart();
|
|
125
|
+
}
|
|
126
|
+
recordStop() {
|
|
127
|
+
return new Promise((resolve) => {
|
|
128
|
+
clearInterval(this.countdownInterval);
|
|
129
|
+
this.changeBtnStatus("CLOSED");
|
|
130
|
+
this.recorder?.stop(async (blob, duration) => {
|
|
131
|
+
//录音结束后,发送录音结束帧
|
|
132
|
+
try {
|
|
133
|
+
this.iatWS.send(JSON.stringify({ "data": { "status": 2, "format": "audio/L16;rate=16000", "encoding": this.encodingType, "audio": "" } }));
|
|
134
|
+
}
|
|
135
|
+
catch (err) { }
|
|
136
|
+
//简单利用URL生成本地文件地址,注意不用了时需要revokeObjectURL,否则霸占内存
|
|
137
|
+
//此地址只能本地使用,比如赋值给audio.src进行播放,赋值给a.href然后a.click()进行下载(a需提供download="xxx.mp3"属性)
|
|
138
|
+
let localUrl = (window.URL || webkitURL).createObjectURL(blob);
|
|
139
|
+
console.log(blob, localUrl, "时长:" + duration + "ms");
|
|
140
|
+
this.recordPcmBlob = blob;
|
|
141
|
+
this.recordWavBlob = await this.pcmBlobToWavBlob(blob, 44100);
|
|
142
|
+
this.recordDuration = duration;
|
|
143
|
+
console.log("this.recordWavBlob", this.recordWavBlob);
|
|
144
|
+
setTimeout(() => {
|
|
145
|
+
if (this.isUserFinish) {
|
|
146
|
+
this.onAfterFinishTalk && this.onAfterFinishTalk();
|
|
147
|
+
this.isUserFinish = false;
|
|
148
|
+
}
|
|
149
|
+
}, 2000);
|
|
150
|
+
this.recorder?.close(); //释放录音资源,当然可以不释放,后面可以连续调用start;但不释放时系统或浏览器会一直提示在录音,最佳操作是录完就close掉
|
|
151
|
+
this.recorder = null;
|
|
152
|
+
//已经拿到blob文件对象想干嘛就干嘛:立即播放、上传、下载保存
|
|
153
|
+
/*** 【立即播放例子】 ***/
|
|
154
|
+
// this.audioPlayer= new Audio();
|
|
155
|
+
// this.audioPlayer.controls=true;
|
|
156
|
+
// this.audioPlayer.src=localUrl;
|
|
157
|
+
console.log("localUrl", localUrl);
|
|
158
|
+
// 等待语音转义完成,处理转录结果
|
|
159
|
+
// 需要准确判断websocket已经close了
|
|
160
|
+
resolve(true);
|
|
161
|
+
}, (msg) => {
|
|
162
|
+
console.log("录音失败:" + msg);
|
|
163
|
+
this.recorder.close(); //可以通过stop方法的第3个参数来自动调用close
|
|
164
|
+
this.recorder = null;
|
|
165
|
+
resolve(null);
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
playRecord() {
|
|
170
|
+
this.playPCM(this.recordPcmBlob, 44100);
|
|
171
|
+
}
|
|
172
|
+
async pcmBlobToWavBlob(pcmBlob, sampleRate) {
|
|
173
|
+
return new Promise(resolve => {
|
|
174
|
+
let fileReader = new FileReader();
|
|
175
|
+
// 读取Blob数据
|
|
176
|
+
fileReader.onload = function (event) {
|
|
177
|
+
let pcmData = event.target.result;
|
|
178
|
+
// Convert PCM data to WAV format
|
|
179
|
+
let wavBlob = pcmtoWav(pcmData, sampleRate, 1, 16);
|
|
180
|
+
resolve(wavBlob);
|
|
181
|
+
};
|
|
182
|
+
// 将Blob转换为ArrayBuffer
|
|
183
|
+
fileReader.readAsArrayBuffer(pcmBlob);
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
async playPCM(pcmBlob, sampleRate) {
|
|
187
|
+
let wavBlob = await this.pcmBlobToWavBlob(pcmBlob, sampleRate);
|
|
188
|
+
let wavUrl = window.URL.createObjectURL(wavBlob);
|
|
189
|
+
let audio = new Audio();
|
|
190
|
+
audio.src = wavUrl;
|
|
191
|
+
audio.play();
|
|
192
|
+
}
|
|
193
|
+
async playBuffers() {
|
|
194
|
+
// let audioBuffer = []
|
|
195
|
+
// this.buffers.forEach(buffer=>{
|
|
196
|
+
// audioBuffer.push(buffer)
|
|
197
|
+
// })
|
|
198
|
+
let audioBlob = await this.BuffersToBlob(this.buffers);
|
|
199
|
+
this.playPCM(audioBlob, 44100);
|
|
200
|
+
}
|
|
201
|
+
BuffersToBlob(buffers) {
|
|
202
|
+
let audioBuffer = [];
|
|
203
|
+
buffers.forEach(buffer => {
|
|
204
|
+
buffer.forEach(int16 => {
|
|
205
|
+
audioBuffer.push(int16);
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
return new Blob([audioBuffer], { type: 'audio/pcm' });
|
|
209
|
+
}
|
|
210
|
+
// 将录音数据分割为每次发送的音频片段 1280字节
|
|
211
|
+
splitAudioData(audioData) {
|
|
212
|
+
const segmentSize = 1280; // 目标切片大小,单位为字节
|
|
213
|
+
const segmentCount = Math.ceil(audioData.length / segmentSize); // 切片数量
|
|
214
|
+
const segments = [];
|
|
215
|
+
for (let i = 0; i < segmentCount; i++) {
|
|
216
|
+
const start = i * segmentSize;
|
|
217
|
+
const end = start + segmentSize;
|
|
218
|
+
const segment = audioData.slice(start, end);
|
|
219
|
+
segments.push(segment);
|
|
220
|
+
}
|
|
221
|
+
return segments;
|
|
222
|
+
}
|
|
223
|
+
BufferToBlob(buffer) {
|
|
224
|
+
return new Blob([buffer], { type: 'audio/pcm' });
|
|
225
|
+
}
|
|
226
|
+
createRecorder() {
|
|
227
|
+
if (this.recorder)
|
|
228
|
+
return;
|
|
229
|
+
this.recorder = Recorder({
|
|
230
|
+
type: this.recordType, sampleRate: 44100, bitRate: 16 //pcm格式,指定采样率hz、比特率kbps,其他参数使用默认配置;注意:是数字的参数必须提供数字,不要用字符串;需要使用的type类型,需提前把格式支持文件加载进来,比如使用wav格式需要提前加载wav.js编码引擎
|
|
231
|
+
,
|
|
232
|
+
onProcess: (buffers, powerLevel, bufferDuration, bufferSampleRate, newBufferIdx, asyncEnd) => {
|
|
233
|
+
//录音实时回调,大约1秒调用12次本回调,buffers为开始到现在的所有录音pcm数据块(16位小端LE)
|
|
234
|
+
//可利用extensions/sonic.js插件实时变速变调,此插件计算量巨大,onProcess需要返回true开启异步模式
|
|
235
|
+
//可实时上传(发送)数据,配合Recorder.SampleData方法,将buffers中的新数据连续的转换成pcm上传,或使用mock方法将新数据连续的转码成其他格式上传,可以参考文档里面的:Demo片段列表 -> 实时转码并上传-通用版;基于本功能可以做到:实时转发数据、实时保存数据、实时语音识别(ASR)等
|
|
236
|
+
// 实时发送录音至接口
|
|
237
|
+
// console.log("asyncEnd:",asyncEnd)
|
|
238
|
+
// console.log(buffers.length,bufferDuration,bufferSampleRate,newBufferIdx)
|
|
239
|
+
let isLastFrame = false && this.btnStatus == "CLOSED"; // 主动关闭作为最后帧
|
|
240
|
+
// 录音默认为 44100 采样率 pcm不支持再process中实时转换
|
|
241
|
+
// 需要压缩为 16000 上传
|
|
242
|
+
let frameBuffer = buffers.length && buffers[buffers.length - 1];
|
|
243
|
+
this.buffers = buffers;
|
|
244
|
+
frameBuffer = resampleBuffer(frameBuffer, 44100, 16000);
|
|
245
|
+
// this.playPCM(this.BufferToBlob(frameBuffer),16000) // 切片数据播放,采样率测试
|
|
246
|
+
if (this.iatWS.readyState === this.iatWS.OPEN) {
|
|
247
|
+
if (this.disableASR)
|
|
248
|
+
return;
|
|
249
|
+
this.iatWS.send(JSON.stringify({
|
|
250
|
+
data: {
|
|
251
|
+
status: isLastFrame ? 2 : 1,
|
|
252
|
+
format: "audio/L16;rate=16000",
|
|
253
|
+
encoding: this.encodingType,
|
|
254
|
+
audio: convertFrameBufferToBase64(frameBuffer) // this.toBase64(audioData),
|
|
255
|
+
},
|
|
256
|
+
}));
|
|
257
|
+
if (isLastFrame) {
|
|
258
|
+
this.changeBtnStatus("CLOSING");
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
//可实时绘制波形(extensions目录内的waveview.js、wavesurfer.view.js、frequency.histogram.view.js插件功能)
|
|
262
|
+
this.waveClient?.input(buffers[buffers.length - 1], powerLevel, bufferSampleRate);
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
async openWithPriviledge() {
|
|
267
|
+
console.log(this.btnStatus);
|
|
268
|
+
await this.requestPermission();
|
|
269
|
+
this.createRecorder();
|
|
270
|
+
if (Recorder.IsOpen())
|
|
271
|
+
return true;
|
|
272
|
+
return new Promise(resolve => {
|
|
273
|
+
//var dialog=createDelayDialog(); 我们可以选择性的弹一个对话框:为了防止移动端浏览器存在第三种情况:用户忽略,并且(或者国产系统UC系)浏览器没有任何回调,此处demo省略了弹窗的代码
|
|
274
|
+
this.recorder.open(() => {
|
|
275
|
+
//dialog&&dialog.Cancel(); 如果开启了弹框,此处需要取消
|
|
276
|
+
//rec.start() 此处可以立即开始录音,但不建议这样编写,因为open是一个延迟漫长的操作,通过两次用户操作来分别调用open和start是推荐的最佳流程
|
|
277
|
+
//创建可视化,指定一个要显示的div
|
|
278
|
+
let waveDiv = document.querySelector(".record-wave");
|
|
279
|
+
if (waveDiv) { // 存在波形区域时,加载渲染组件
|
|
280
|
+
console.log(waveDiv);
|
|
281
|
+
if (Recorder.WaveView)
|
|
282
|
+
this.waveClient = Recorder.WaveView({ elem: ".record-wave" });
|
|
283
|
+
}
|
|
284
|
+
resolve(true);
|
|
285
|
+
}, (msg, isUserNotAllow) => {
|
|
286
|
+
//dialog&&dialog.Cancel(); 如果开启了弹框,此处需要取消
|
|
287
|
+
console.log((isUserNotAllow ? "UserNotAllow," : "") + "无法录音:" + msg);
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
getWebSocketUrl() {
|
|
292
|
+
// 请求地址根据语种不同变化
|
|
293
|
+
let url = "wss://iat-api.xfyun.cn/v2/iat";
|
|
294
|
+
let host = "iat-api.xfyun.cn";
|
|
295
|
+
let apiKey = this.API_KEY;
|
|
296
|
+
let apiSecret = this.API_SECRET;
|
|
297
|
+
let date = new Date().toUTCString();
|
|
298
|
+
let algorithm = "hmac-sha256";
|
|
299
|
+
let headers = "host date request-line";
|
|
300
|
+
let signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v2/iat HTTP/1.1`;
|
|
301
|
+
let signatureSha = CryptoJS.HmacSHA256(signatureOrigin, apiSecret);
|
|
302
|
+
let signature = CryptoJS.enc.Base64.stringify(signatureSha);
|
|
303
|
+
let authorizationOrigin = `api_key="${apiKey}", algorithm="${algorithm}", headers="${headers}", signature="${signature}"`;
|
|
304
|
+
let authorization = btoa(authorizationOrigin);
|
|
305
|
+
url = `${url}?authorization=${authorization}&date=${date}&host=${host}`;
|
|
306
|
+
return url;
|
|
307
|
+
}
|
|
308
|
+
toBase64(buffer) {
|
|
309
|
+
var binary = "";
|
|
310
|
+
var bytes = new Uint8Array(buffer);
|
|
311
|
+
var len = bytes.byteLength;
|
|
312
|
+
for (var i = 0; i < len; i++) {
|
|
313
|
+
binary += String.fromCharCode(bytes[i]);
|
|
314
|
+
}
|
|
315
|
+
return window.btoa(binary);
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* 倒计时:最长支持60秒实时语音转录,如果持续7-10秒无声音,服务端将自动CLOSE链接
|
|
319
|
+
*/
|
|
320
|
+
countdown() {
|
|
321
|
+
let seconds = 60;
|
|
322
|
+
this.connStatus = `录音中(${seconds}s)`;
|
|
323
|
+
this.countdownInterval = setInterval(() => {
|
|
324
|
+
seconds = seconds - 1;
|
|
325
|
+
console.log(seconds);
|
|
326
|
+
if (seconds <= 0) {
|
|
327
|
+
clearInterval(this.countdownInterval);
|
|
328
|
+
this.recordStop();
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
this.connStatus = `录音中(${seconds}s)`;
|
|
332
|
+
}
|
|
333
|
+
}, 1000);
|
|
334
|
+
}
|
|
335
|
+
changeBtnStatus(status) {
|
|
336
|
+
this.btnStatus = status;
|
|
337
|
+
if (status === "CONNECTING") {
|
|
338
|
+
this.connStatus = "建立连接中";
|
|
339
|
+
}
|
|
340
|
+
else if (status === "OPEN") {
|
|
341
|
+
this.countdown();
|
|
342
|
+
}
|
|
343
|
+
else if (status === "CLOSING") {
|
|
344
|
+
this.connStatus = "关闭连接中";
|
|
345
|
+
}
|
|
346
|
+
else if (status === "CLOSED") {
|
|
347
|
+
this.connStatus = "开始录音";
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
renderResult(resultData) {
|
|
351
|
+
// 识别结束
|
|
352
|
+
let jsonData = JSON.parse(resultData);
|
|
353
|
+
// console.log(jsonData.data.result)
|
|
354
|
+
if (jsonData.data && jsonData.data.result) {
|
|
355
|
+
let data = jsonData.data.result;
|
|
356
|
+
let str = "";
|
|
357
|
+
let ws = data.ws;
|
|
358
|
+
for (let i = 0; i < ws.length; i++) {
|
|
359
|
+
str = str + ws[i].cw[0].w;
|
|
360
|
+
console.log(str);
|
|
361
|
+
}
|
|
362
|
+
// 开启wpgs会有此字段(前提:在控制台开通动态修正功能)
|
|
363
|
+
// 取值为 "apd"时表示该片结果是追加到前面的最终结果;取值为"rpl" 时表示替换前面的部分结果,替换范围为rg字段
|
|
364
|
+
if (data.pgs) {
|
|
365
|
+
if (data.pgs === "apd") {
|
|
366
|
+
// 将this.resultTextTemp同步给this.resultText
|
|
367
|
+
this.resultText = this.resultTextTemp;
|
|
368
|
+
}
|
|
369
|
+
// 将结果存储在this.resultTextTemp中
|
|
370
|
+
this.resultTextTemp = this.resultText + str;
|
|
371
|
+
}
|
|
372
|
+
else {
|
|
373
|
+
this.resultText = this.resultText + str;
|
|
374
|
+
}
|
|
375
|
+
this.resultTextTemp || this.resultText || "";
|
|
376
|
+
console.log("diff temp", this.resultTextTemp);
|
|
377
|
+
console.log("diff result", this.resultText);
|
|
378
|
+
}
|
|
379
|
+
if (jsonData.code === 0 && jsonData.data.status === 2) {
|
|
380
|
+
this.iatWS.close();
|
|
381
|
+
}
|
|
382
|
+
if (jsonData.code !== 0) {
|
|
383
|
+
this.iatWS.close();
|
|
384
|
+
console.error(jsonData);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
connectWebSocket() {
|
|
388
|
+
console.log("connectWebSocket");
|
|
389
|
+
const websocketUrl = this.getWebSocketUrl();
|
|
390
|
+
if ("WebSocket" in window) {
|
|
391
|
+
this.iatWS = new WebSocket(websocketUrl);
|
|
392
|
+
}
|
|
393
|
+
else if ("MozWebSocket" in window) {
|
|
394
|
+
// this.iatWS = new MozWebSocket(websocketUrl); // Moz兼容
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
alert("浏览器不支持WebSocket");
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
console.log("connectWebSocket", this.btnStatus);
|
|
401
|
+
this.changeBtnStatus("CONNECTING");
|
|
402
|
+
this.iatWS.onopen = (e) => {
|
|
403
|
+
// 开始录音
|
|
404
|
+
this.recordStart();
|
|
405
|
+
var params = {
|
|
406
|
+
common: {
|
|
407
|
+
app_id: this.APPID,
|
|
408
|
+
},
|
|
409
|
+
business: {
|
|
410
|
+
language: "zh_cn",
|
|
411
|
+
domain: "iat",
|
|
412
|
+
accent: "mandarin",
|
|
413
|
+
vad_eos: 5000,
|
|
414
|
+
dwa: "wpgs",
|
|
415
|
+
},
|
|
416
|
+
data: {
|
|
417
|
+
status: 0,
|
|
418
|
+
format: "audio/L16;rate=16000",
|
|
419
|
+
encoding: this.encodingType,
|
|
420
|
+
// encoding: "speex-wb",
|
|
421
|
+
},
|
|
422
|
+
};
|
|
423
|
+
this.iatWS.send(JSON.stringify(params));
|
|
424
|
+
};
|
|
425
|
+
this.iatWS.onmessage = (e) => {
|
|
426
|
+
console.log("onmessage" + this.resultText);
|
|
427
|
+
this.renderResult(e.data);
|
|
428
|
+
};
|
|
429
|
+
this.iatWS.onerror = (e) => {
|
|
430
|
+
console.error("error", e);
|
|
431
|
+
this.recordStop();
|
|
432
|
+
this.changeBtnStatus("CLOSED");
|
|
433
|
+
};
|
|
434
|
+
this.iatWS.onclose = async (e) => {
|
|
435
|
+
// 5秒停顿会导致结束录制
|
|
436
|
+
console.log("onclose" + this.resultText);
|
|
437
|
+
console.error("close", e);
|
|
438
|
+
await this.recordStop();
|
|
439
|
+
this.changeBtnStatus("CLOSED");
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* 移动端兼容方法
|
|
444
|
+
*/
|
|
445
|
+
/**
|
|
446
|
+
* 移动端上传专用方法
|
|
447
|
+
* @returns
|
|
448
|
+
*/
|
|
449
|
+
isCapacitor() {
|
|
450
|
+
return this.platform.is("capacitor") || this.platform.is("cordova");
|
|
451
|
+
}
|
|
452
|
+
async requestPermission() {
|
|
453
|
+
if (!this.isCapacitor())
|
|
454
|
+
return;
|
|
455
|
+
try {
|
|
456
|
+
await this.requestStoagePermission();
|
|
457
|
+
await this.requestCameraPermission();
|
|
458
|
+
await this.requestMicPermission();
|
|
459
|
+
await this.requestRecordAudioPermission();
|
|
460
|
+
}
|
|
461
|
+
catch (err) {
|
|
462
|
+
console.error(err);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
async requestRecordAudioPermission() {
|
|
466
|
+
let data = await this.diagnostic.requestRuntimePermissions([this.diagnostic.permission.RECORD_AUDIO]);
|
|
467
|
+
console.log("record permission request:", data);
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
async requestMicPermission() {
|
|
471
|
+
let isAvailable = await this.diagnostic.isMicrophoneAuthorized();
|
|
472
|
+
console.log("permisson_MIC:", isAvailable);
|
|
473
|
+
if (!isAvailable) {
|
|
474
|
+
let data = await this.diagnostic.requestMicrophoneAuthorization();
|
|
475
|
+
}
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
async requestStoagePermission() {
|
|
479
|
+
let isAvailable = await this.diagnostic.isExternalStorageAuthorized();
|
|
480
|
+
console.log("permisson_STORAGE:", isAvailable);
|
|
481
|
+
if (!isAvailable) {
|
|
482
|
+
let data = await this.diagnostic.requestExternalStorageAuthorization();
|
|
483
|
+
}
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
async requestCameraPermission() {
|
|
487
|
+
let isAvailable = await this.diagnostic.isCameraAuthorized();
|
|
488
|
+
console.log("permisson_Camera:", isAvailable);
|
|
489
|
+
if (!isAvailable) {
|
|
490
|
+
let data = await this.diagnostic.requestCameraAuthorization();
|
|
491
|
+
}
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FmodeVoiceService, deps: [{ token: i1.Platform }, { token: i2.Diagnostic }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
495
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FmodeVoiceService, providedIn: 'root' }); }
|
|
496
|
+
}
|
|
497
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FmodeVoiceService, decorators: [{
|
|
498
|
+
type: Injectable,
|
|
499
|
+
args: [{
|
|
500
|
+
providedIn: 'root'
|
|
501
|
+
}]
|
|
502
|
+
}], ctorParameters: () => [{ type: i1.Platform }, { type: i2.Diagnostic }] });
|
|
503
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm1vZGUtdm9pY2Uuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Ztb2RlLW5nL3NyYy9saWIvYWlnYy92b2ljZS9mbW9kZS12b2ljZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBZ0IsVUFBVSxFQUFVLE1BQU0sZUFBZSxDQUFDO0FBQ2pFLHNEQUFzRDtBQUN0RCxrRUFBa0U7QUFDbEUsT0FBTyxRQUFRLE1BQU0sZUFBZSxDQUFBO0FBQ3BDLE9BQU8sOEJBQThCLENBQUE7QUFDckMsT0FBTyw4QkFBOEIsQ0FBQTtBQUNyQyxPQUFPLHVDQUF1QyxDQUFBO0FBQzlDLE9BQU8sUUFBUSxNQUFNLFdBQVcsQ0FBQTtBQUNoQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSwwQkFBMEIsRUFBaUIsY0FBYyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDM0YsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN4QyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDMUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHlDQUF5QyxDQUFDOzs7O0FBQ3JFLDZEQUE2RDtBQUs3RCxNQUFNLE9BQU8saUJBQWlCO0lBYzVCLFlBQ1UsUUFBaUIsRUFDakIsVUFBc0I7UUFEdEIsYUFBUSxHQUFSLFFBQVEsQ0FBUztRQUNqQixlQUFVLEdBQVYsVUFBVSxDQUFZO1FBVmhDOztXQUVHO1FBQ0gsbUNBQW1DO1FBQ25DOztXQUVHO1FBQ0gsY0FBUyxHQUFHLFNBQVMsQ0FBQTtRQWlEdEI7O1dBRUc7UUFDSCxpQkFBWSxHQUFXLEtBQUssQ0FBQztRQW9HNUIsa0JBQWEsR0FBUSxJQUFJLENBQUE7UUFDekIsa0JBQWEsR0FBUSxJQUFJLENBQUE7UUFDekIsbUJBQWMsR0FBVSxDQUFDLENBQUM7UUFnRTFCLGVBQVUsR0FBRyxLQUFLLENBQUE7UUFDbEIsaUJBQVksR0FBRyxLQUFLLENBQUE7UUFvRXBCLGVBQVUsR0FBRyxFQUFFLENBQUEsQ0FBQyxrQkFBa0I7UUFFbEMsY0FBUyxHQUFHLFdBQVcsQ0FBQyxDQUFDLHFEQUFxRDtRQVE5RSxlQUFVLEdBQUcsRUFBRSxDQUFDO1FBQ2hCLG1CQUFjLEdBQUcsRUFBRSxDQUFDO1FBR3BCOzs7V0FHRztRQUNILFVBQUssR0FBRyxVQUFVLENBQUM7UUFDbkIsZUFBVSxHQUFHLGtDQUFrQyxDQUFDO1FBQ2hELFlBQU8sR0FBRyxrQ0FBa0MsQ0FBQztRQTlTM0MsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDekIsbUNBQW1DO1FBQ25DLEtBQUs7UUFFTCx3RUFBd0U7UUFDeEUscURBQXFEO1FBQ3JELHVCQUF1QjtRQUN2Qix5QkFBeUI7UUFDekIsa0JBQWtCO1FBQ2xCLHlDQUF5QztRQUN6Qyw0Q0FBNEM7UUFDNUMseUNBQXlDO1FBQ3pDLCtDQUErQztRQUMvQyxhQUFhO1FBQ2IsV0FBVztRQUNYLFNBQVM7UUFDVCx5QkFBeUI7UUFDekIseUNBQXlDO1FBQ3pDLFFBQVE7UUFDUixNQUFNO1FBQ04sS0FBSztRQUVMLGtDQUFrQztRQUNsQyxLQUFLO0lBR1AsQ0FBQztJQUtEOztPQUVHO0lBQ0YsWUFBWTtRQUNYLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFBO1FBQzNCLElBQUksSUFBSSxDQUFDLFNBQVMsS0FBSyxXQUFXLElBQUksSUFBSSxDQUFDLFNBQVMsS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUNsRSxRQUFRO1lBQ1IsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFBO1FBQ2xCLENBQUM7YUFBTSxJQUFJLElBQUksQ0FBQyxTQUFTLEtBQUssWUFBWSxJQUFJLElBQUksQ0FBQyxTQUFTLEtBQUssTUFBTSxFQUFFLENBQUM7WUFDeEUsaUJBQWlCO1lBQ2pCLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQTtRQUNuQixDQUFDO0lBQ0gsQ0FBQztJQUtGLFVBQVU7UUFDUCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztRQUN6QixJQUFJLENBQUMsa0JBQWtCLElBQUUsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUE7UUFDbEQsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFBO0lBQ3BCLENBQUM7SUFHQTs7T0FFRztJQUNILEtBQUssQ0FBQyxTQUFTLENBQUMsS0FBTTtRQUNwQixJQUFJLENBQUMsVUFBVSxHQUFHLEVBQUUsQ0FBQTtRQUNwQixJQUFJLENBQUMsY0FBYyxHQUFHLEVBQUUsQ0FBQTtRQUN4QixJQUFJLENBQUMsaUJBQWlCLElBQUUsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUE7UUFDaEQsS0FBSyxFQUFFLGNBQWMsRUFBRSxDQUFBO1FBQ3ZCLE1BQU0sSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUE7UUFDL0IsVUFBVSxDQUFDLEdBQUcsRUFBRTtZQUNkLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFBO1FBQ3pCLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUVSLElBQUksQ0FBQyxnQkFBZ0IsSUFBRSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQTtJQUNoRCxDQUFDO0lBSUQ7O09BRUc7SUFDSCxVQUFVO1FBQ1IsSUFBSSxDQUFDLGtCQUFrQixJQUFFLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFBO1FBQ2xELElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLE9BQU87UUFDMUIsSUFBSSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLE9BQU87UUFDNUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsQ0FBQyxXQUFXO1FBQ25DLElBQUksQ0FBQyxpQkFBaUIsSUFBRSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQTtJQUNsRCxDQUFDO0lBUUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsV0FBVztRQUNmLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN0QixNQUFNLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFBO1FBQy9CLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDdEIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM3QixJQUFJLENBQUMsa0JBQWtCLElBQUUsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUE7SUFDcEQsQ0FBQztJQUNELFVBQVU7UUFDUixPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFDLEVBQUU7WUFDNUIsYUFBYSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1lBQ3RDLElBQUksQ0FBQyxlQUFlLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDL0IsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLElBQVMsRUFBQyxRQUFlLEVBQUMsRUFBRTtnQkFDbkQsZUFBZTtnQkFDZixJQUFHLENBQUM7b0JBQ0YsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQ2IsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFDLE1BQU0sRUFBQyxFQUFDLFFBQVEsRUFBQyxDQUFDLEVBQUMsUUFBUSxFQUFDLHNCQUFzQixFQUFDLFVBQVUsRUFBQyxJQUFJLENBQUMsWUFBWSxFQUFDLE9BQU8sRUFBQyxFQUFFLEVBQUMsRUFBQyxDQUFDLENBQzVHLENBQUM7Z0JBQ04sQ0FBQztnQkFBQSxPQUFNLEdBQUcsRUFBQyxDQUFDLENBQUEsQ0FBQztnQkFFYixnREFBZ0Q7Z0JBQ2hELGlGQUFpRjtnQkFDakYsSUFBSSxRQUFRLEdBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxJQUFFLFNBQVMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDM0QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUMsUUFBUSxFQUFDLEtBQUssR0FBQyxRQUFRLEdBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQy9DLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDO2dCQUMxQixJQUFJLENBQUMsYUFBYSxHQUFHLE1BQU0sSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksRUFBQyxLQUFLLENBQUMsQ0FBQztnQkFDN0QsSUFBSSxDQUFDLGNBQWMsR0FBRyxRQUFRLENBQUM7Z0JBQy9CLE9BQU8sQ0FBQyxHQUFHLENBQUMsb0JBQW9CLEVBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFBO2dCQUNwRCxVQUFVLENBQUMsR0FBRyxFQUFFO29CQUNkLElBQUcsSUFBSSxDQUFDLFlBQVksRUFBQyxDQUFDO3dCQUNwQixJQUFJLENBQUMsaUJBQWlCLElBQUUsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUE7d0JBQ2hELElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDO29CQUM1QixDQUFDO2dCQUNILENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDVCxJQUFJLENBQUMsUUFBUSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUEsaUVBQWlFO2dCQUN4RixJQUFJLENBQUMsUUFBUSxHQUFDLElBQUksQ0FBQztnQkFFbkIsaUNBQWlDO2dCQUVqQyxrQkFBa0I7Z0JBQ2xCLGlDQUFpQztnQkFDakMsa0NBQWtDO2dCQUNsQyxpQ0FBaUM7Z0JBQ2pDLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxFQUFDLFFBQVEsQ0FBQyxDQUFBO2dCQUNoQyxrQkFBa0I7Z0JBQ2xCLDBCQUEwQjtnQkFDMUIsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2xCLENBQUMsRUFBQyxDQUFDLEdBQUcsRUFBQyxFQUFFO2dCQUNMLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxHQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUN6QixJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUEsNEJBQTRCO2dCQUNsRCxJQUFJLENBQUMsUUFBUSxHQUFDLElBQUksQ0FBQztnQkFDbkIsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFBO1lBQ2pCLENBQUMsQ0FBQyxDQUFBO1FBQ0osQ0FBQyxDQUFDLENBQUE7SUFDSixDQUFDO0lBSUQsVUFBVTtRQUNSLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBQyxLQUFLLENBQUMsQ0FBQTtJQUN4QyxDQUFDO0lBQ0QsS0FBSyxDQUFDLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxVQUFVO1FBQ3hDLE9BQU8sSUFBSSxPQUFPLENBQUMsT0FBTyxDQUFBLEVBQUU7WUFDMUIsSUFBSSxVQUFVLEdBQUcsSUFBSSxVQUFVLEVBQUUsQ0FBQztZQUVsQyxXQUFXO1lBQ1gsVUFBVSxDQUFDLE1BQU0sR0FBRyxVQUFTLEtBQUs7Z0JBQ2hDLElBQUksT0FBTyxHQUFPLEtBQUssQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDO2dCQUN0QyxpQ0FBaUM7Z0JBQ2pDLElBQUksT0FBTyxHQUFHLFFBQVEsQ0FBQyxPQUFPLEVBQUUsVUFBVSxFQUFDLENBQUMsRUFBQyxFQUFFLENBQUMsQ0FBQztnQkFDakQsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFBO1lBQ2xCLENBQUMsQ0FBQztZQUVGLHNCQUFzQjtZQUN0QixVQUFVLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDeEMsQ0FBQyxDQUFDLENBQUE7SUFDSixDQUFDO0lBQ0QsS0FBSyxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsVUFBVTtRQUMvQixJQUFJLE9BQU8sR0FBRyxNQUFNLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUMsVUFBVSxDQUFDLENBQUM7UUFDOUQsSUFBSSxNQUFNLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLENBQUE7UUFDaEQsSUFBSSxLQUFLLEdBQUcsSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUN4QixLQUFLLENBQUMsR0FBRyxHQUFHLE1BQU0sQ0FBQztRQUNuQixLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDZixDQUFDO0lBRUQsS0FBSyxDQUFDLFdBQVc7UUFDZix1QkFBdUI7UUFDdkIsaUNBQWlDO1FBQ2pDLDZCQUE2QjtRQUM3QixLQUFLO1FBQ0wsSUFBSSxTQUFTLEdBQUcsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUN0RCxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBQyxLQUFLLENBQUMsQ0FBQTtJQUMvQixDQUFDO0lBQ0QsYUFBYSxDQUFDLE9BQU87UUFDbkIsSUFBSSxXQUFXLEdBQU8sRUFBRSxDQUFBO1FBQ3hCLE9BQU8sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFBLEVBQUU7WUFDdEIsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUEsRUFBRTtnQkFDcEIsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQTtZQUN6QixDQUFDLENBQUMsQ0FBQTtRQUNKLENBQUMsQ0FBQyxDQUFBO1FBQ0YsT0FBTyxJQUFJLElBQUksQ0FBQyxDQUFDLFdBQVcsQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxDQUFDLENBQUM7SUFDeEQsQ0FBQztJQUNELDJCQUEyQjtJQUMxQixjQUFjLENBQUMsU0FBUztRQUN2QixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsQ0FBQyxlQUFlO1FBQ3pDLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFDLE9BQU87UUFDdkUsTUFBTSxRQUFRLEdBQUcsRUFBRSxDQUFDO1FBRXBCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxZQUFZLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUN0QyxNQUFNLEtBQUssR0FBRyxDQUFDLEdBQUcsV0FBVyxDQUFDO1lBQzlCLE1BQU0sR0FBRyxHQUFHLEtBQUssR0FBRyxXQUFXLENBQUM7WUFDaEMsTUFBTSxPQUFPLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFFNUMsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN6QixDQUFDO1FBRUQsT0FBTyxRQUFRLENBQUM7SUFDbEIsQ0FBQztJQUNELFlBQVksQ0FBQyxNQUFNO1FBQ2pCLE9BQU8sSUFBSSxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFHRCxjQUFjO1FBQ1osSUFBRyxJQUFJLENBQUMsUUFBUTtZQUFFLE9BQU07UUFDeEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7WUFDdkIsSUFBSSxFQUFDLElBQUksQ0FBQyxVQUFVLEVBQUMsVUFBVSxFQUFDLEtBQUssRUFBQyxPQUFPLEVBQUMsRUFBRSxDQUFDLDhHQUE4Rzs7WUFDOUosU0FBUyxFQUFDLENBQUMsT0FBTyxFQUFDLFVBQVUsRUFBQyxjQUFjLEVBQUMsZ0JBQWdCLEVBQUMsWUFBWSxFQUFDLFFBQVEsRUFBQyxFQUFFO2dCQUNuRix1REFBdUQ7Z0JBQ3ZELGlFQUFpRTtnQkFDakUsK0pBQStKO2dCQUMvSixZQUFZO2dCQUNaLG9DQUFvQztnQkFDcEMsMkVBQTJFO2dCQUMzRSxJQUFJLFdBQVcsR0FBRyxLQUFLLElBQUksSUFBSSxDQUFDLFNBQVMsSUFBRSxRQUFRLENBQUMsQ0FBQyxZQUFZO2dCQUNqRSxzQ0FBc0M7Z0JBQ3RDLGlCQUFpQjtnQkFDakIsSUFBSSxXQUFXLEdBQUcsT0FBTyxDQUFDLE1BQU0sSUFBRSxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sR0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDNUQsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUE7Z0JBQ3RCLFdBQVcsR0FBRyxjQUFjLENBQUMsV0FBVyxFQUFDLEtBQUssRUFBQyxLQUFLLENBQUMsQ0FBQztnQkFDdEQscUVBQXFFO2dCQUVyRSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxLQUFLLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7b0JBQzFDLElBQUcsSUFBSSxDQUFDLFVBQVU7d0JBQUUsT0FBTTtvQkFDMUIsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQ2IsSUFBSSxDQUFDLFNBQVMsQ0FBQzt3QkFDYixJQUFJLEVBQUU7NEJBQ0osTUFBTSxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDOzRCQUMzQixNQUFNLEVBQUUsc0JBQXNCOzRCQUM5QixRQUFRLEVBQUUsSUFBSSxDQUFDLFlBQVk7NEJBQzNCLEtBQUssRUFBRSwwQkFBMEIsQ0FBQyxXQUFXLENBQUMsQ0FBQSw0QkFBNEI7eUJBQzNFO3FCQUNGLENBQUMsQ0FDSCxDQUFDO29CQUVOLElBQUksV0FBVyxFQUFFLENBQUM7d0JBQ2hCLElBQUksQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLENBQUM7b0JBQ2xDLENBQUM7Z0JBQ0gsQ0FBQztnQkFDRCx1RkFBdUY7Z0JBQ3ZGLElBQUksQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFDLENBQUMsQ0FBQyxFQUFDLFVBQVUsRUFBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ2xGLENBQUM7U0FDSixDQUFDLENBQUM7SUFDSCxDQUFDO0lBRUQsS0FBSyxDQUFDLGtCQUFrQjtRQUN0QixPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQTtRQUMzQixNQUFNLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQy9CLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN0QixJQUFHLFFBQVEsQ0FBQyxNQUFNLEVBQUU7WUFBRSxPQUFPLElBQUksQ0FBQTtRQUNqQyxPQUFPLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQSxFQUFFO1lBQzFCLDZHQUE2RztZQUM3RyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFFLEVBQUU7Z0JBQ3JCLHlDQUF5QztnQkFDekMsa0ZBQWtGO2dCQUNsRixtQkFBbUI7Z0JBQ25CLElBQUksT0FBTyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsY0FBYyxDQUFDLENBQUM7Z0JBQ3JELElBQUcsT0FBTyxFQUFDLENBQUMsQ0FBQyxpQkFBaUI7b0JBQzVCLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUE7b0JBQ3BCLElBQUcsUUFBUSxDQUFDLFFBQVE7d0JBQUMsSUFBSSxDQUFDLFVBQVUsR0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLEVBQUMsSUFBSSxFQUFDLGNBQWMsRUFBQyxDQUFDLENBQUM7Z0JBQ2hGLENBQUM7Z0JBQ0QsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2xCLENBQUMsRUFBQyxDQUFDLEdBQUcsRUFBQyxjQUFjLEVBQUMsRUFBRTtnQkFDcEIseUNBQXlDO2dCQUN6QyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsY0FBYyxDQUFBLENBQUMsQ0FBQSxlQUFlLENBQUEsQ0FBQyxDQUFBLEVBQUUsQ0FBQyxHQUFDLE9BQU8sR0FBQyxHQUFHLENBQUMsQ0FBQztZQUNqRSxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFBO0lBRUYsQ0FBQztJQXVCRCxlQUFlO1FBQ2IsZUFBZTtRQUNmLElBQUksR0FBRyxHQUFHLCtCQUErQixDQUFDO1FBQzFDLElBQUksSUFBSSxHQUFHLGtCQUFrQixDQUFDO1FBRTlCLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUM7UUFDMUIsSUFBSSxTQUFTLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQztRQUNoQyxJQUFJLElBQUksR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3BDLElBQUksU0FBUyxHQUFHLGFBQWEsQ0FBQztRQUM5QixJQUFJLE9BQU8sR0FBRyx3QkFBd0IsQ0FBQztRQUN2QyxJQUFJLGVBQWUsR0FBRyxTQUFTLElBQUksV0FBVyxJQUFJLHdCQUF3QixDQUFDO1FBQzNFLElBQUksWUFBWSxHQUFHLFFBQVEsQ0FBQyxVQUFVLENBQUMsZUFBZSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ25FLElBQUksU0FBUyxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUM1RCxJQUFJLG1CQUFtQixHQUFHLFlBQVksTUFBTSxpQkFBaUIsU0FBUyxlQUFlLE9BQU8saUJBQWlCLFNBQVMsR0FBRyxDQUFDO1FBQzFILElBQUksYUFBYSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBQzlDLEdBQUcsR0FBRyxHQUFHLEdBQUcsa0JBQWtCLGFBQWEsU0FBUyxJQUFJLFNBQVMsSUFBSSxFQUFFLENBQUM7UUFDeEUsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDO0lBRUQsUUFBUSxDQUFDLE1BQU07UUFDYixJQUFJLE1BQU0sR0FBRyxFQUFFLENBQUM7UUFDaEIsSUFBSSxLQUFLLEdBQUcsSUFBSSxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDbkMsSUFBSSxHQUFHLEdBQUcsS0FBSyxDQUFDLFVBQVUsQ0FBQztRQUMzQixLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDN0IsTUFBTSxJQUFJLE1BQU0sQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDMUMsQ0FBQztRQUNELE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUM3QixDQUFDO0lBRUQ7O09BRUc7SUFDSCxTQUFTO1FBQ1AsSUFBSSxPQUFPLEdBQUcsRUFBRSxDQUFDO1FBQ2pCLElBQUksQ0FBQyxVQUFVLEdBQUcsT0FBTyxPQUFPLElBQUksQ0FBQztRQUNyQyxJQUFJLENBQUMsaUJBQWlCLEdBQUcsV0FBVyxDQUFDLEdBQUcsRUFBRTtZQUN4QyxPQUFPLEdBQUcsT0FBTyxHQUFHLENBQUMsQ0FBQztZQUN0QixPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3JCLElBQUksT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUNqQixhQUFhLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUM7Z0JBQ3RDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUNwQixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sSUFBSSxDQUFDLFVBQVUsR0FBRyxPQUFPLE9BQU8sSUFBSSxDQUFDO1lBQ3ZDLENBQUM7UUFDSCxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDWCxDQUFDO0lBRUQsZUFBZSxDQUFDLE1BQU07UUFDcEIsSUFBSSxDQUFDLFNBQVMsR0FBRyxNQUFNLENBQUM7UUFDeEIsSUFBSSxNQUFNLEtBQUssWUFBWSxFQUFFLENBQUM7WUFDNUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxPQUFPLENBQUM7UUFDNUIsQ0FBQzthQUFNLElBQUksTUFBTSxLQUFLLE1BQU0sRUFBRSxDQUFDO1lBQzdCLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUNuQixDQUFDO2FBQU0sSUFBSSxNQUFNLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDaEMsSUFBSSxDQUFDLFVBQVUsR0FBRyxPQUFPLENBQUM7UUFDNUIsQ0FBQzthQUFNLElBQUksTUFBTSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQy9CLElBQUksQ0FBQyxVQUFVLEdBQUcsTUFBTSxDQUFDO1FBQzNCLENBQUM7SUFDSCxDQUFDO0lBRUQsWUFBWSxDQUFDLFVBQVU7UUFDckIsT0FBTztRQUNQLElBQUksUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDdEMsb0NBQW9DO1FBQ3BDLElBQUksUUFBUSxDQUFDLElBQUksSUFBSSxRQUFRLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQzFDLElBQUksSUFBSSxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO1lBQ2hDLElBQUksR0FBRyxHQUFHLEVBQUUsQ0FBQztZQUNiLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDakIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztnQkFDbkMsR0FBRyxHQUFHLEdBQUcsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDMUIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQTtZQUNsQixDQUFDO1lBQ0QsK0JBQStCO1lBQy9CLDhEQUE4RDtZQUM5RCxJQUFJLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztnQkFDYixJQUFJLElBQUksQ0FBQyxHQUFHLEtBQUssS0FBSyxFQUFFLENBQUM7b0JBQ3ZCLHlDQUF5QztvQkFDekMsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDO2dCQUN4QyxDQUFDO2dCQUNELDZCQUE2QjtnQkFDN0IsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsVUFBVSxHQUFHLEdBQUcsQ0FBQztZQUM5QyxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBVSxHQUFHLEdBQUcsQ0FBQztZQUMxQyxDQUFDO1lBQ0MsSUFBSSxDQUFDLGNBQWMsSUFBSSxJQUFJLENBQUMsVUFBVSxJQUFJLEVBQUUsQ0FBQztZQUMvQyxPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUE7WUFDNUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFBO1FBQzVDLENBQUM7UUFDRCxJQUFJLFFBQVEsQ0FBQyxJQUFJLEtBQUssQ0FBQyxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3RELElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDckIsQ0FBQztRQUNELElBQUksUUFBUSxDQUFDLElBQUksS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN4QixJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ25CLE9BQU8sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDMUIsQ0FBQztJQUNILENBQUM7SUFFRCxnQkFBZ0I7UUFDZCxPQUFPLENBQUMsR0FBRyxDQUFDLGtCQUFrQixDQUFDLENBQUM7UUFDaEMsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQzVDLElBQUksV0FBVyxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQzFCLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxTQUFTLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDM0MsQ0FBQzthQUFNLElBQUksY0FBYyxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ3BDLHdEQUF3RDtRQUMxRCxDQUFDO2FBQU0sQ0FBQztZQUNOLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1lBQ3pCLE9BQU87UUFDVCxDQUFDO1FBQ0QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsRUFBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDL0MsSUFBSSxDQUFDLGVBQWUsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNuQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFO1lBQ3hCLE9BQU87WUFDUCxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDbkIsSUFBSSxNQUFNLEdBQUc7Z0JBQ1gsTUFBTSxFQUFFO29CQUNOLE1BQU0sRUFBRSxJQUFJLENBQUMsS0FBSztpQkFDbkI7Z0JBQ0QsUUFBUSxFQUFFO29CQUNSLFFBQVEsRUFBRSxPQUFPO29CQUNqQixNQUFNLEVBQUUsS0FBSztvQkFDYixNQUFNLEVBQUUsVUFBVTtvQkFDbEIsT0FBTyxFQUFFLElBQUk7b0JBQ2IsR0FBRyxFQUFFLE1BQU07aUJBQ1o7Z0JBQ0QsSUFBSSxFQUFFO29CQUNKLE1BQU0sRUFBRSxDQUFDO29CQUNULE1BQU0sRUFBRSxzQkFBc0I7b0JBQzlCLFFBQVEsRUFBRSxJQUFJLENBQUMsWUFBWTtvQkFDM0Isd0JBQXdCO2lCQUN6QjthQUNGLENBQUM7WUFDRixJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFDMUMsQ0FBQyxDQUFDO1FBQ0YsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBRTtZQUMzQixPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsR0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUE7WUFDeEMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDNUIsQ0FBQyxDQUFDO1FBQ0YsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBRTtZQUN6QixPQUFPLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBQyxDQUFDLENBQUMsQ0FBQztZQUN6QixJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDbEIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNqQyxDQUFDLENBQUM7UUFDRixJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxLQUFLLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDL0IsY0FBYztZQUNkLE9BQU8sQ0FBQyxHQUFHLENBQUMsU0FBUyxHQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQTtZQUN0QyxPQUFPLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBQyxDQUFDLENBQUMsQ0FBQTtZQUN4QixNQUFNLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUN4QixJQUFJLENBQUMsZUFBZSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRWpDLENBQUMsQ0FBQztJQUNKLENBQUM7SUFFRDs7T0FFRztJQUVGOzs7TUFHRTtJQUNELFdBQVc7UUFDVCxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFBO0lBQ3JFLENBQUM7SUFDRCxLQUFLLENBQUMsaUJBQWlCO1FBQ3JCLElBQUcsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFO1lBQUUsT0FBTTtRQUM5QixJQUFHLENBQUM7WUFDRixNQUFNLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1lBQ3JDLE1BQU0sSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7WUFDckMsTUFBTSxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztZQUNsQyxNQUFNLElBQUksQ0FBQyw0QkFBNEIsRUFBRSxDQUFDO1FBQzVDLENBQUM7UUFBQSxPQUFNLEdBQUcsRUFBQyxDQUFDO1lBQ1YsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQTtRQUNwQixDQUFDO0lBQ0gsQ0FBQztJQUNELEtBQUssQ0FBQyw0QkFBNEI7UUFDaEMsSUFBSSxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLHlCQUF5QixDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQTtRQUNyRyxPQUFPLENBQUMsR0FBRyxDQUFDLDRCQUE0QixFQUFDLElBQUksQ0FBQyxDQUFBO1FBQzlDLE9BQU07SUFDVixDQUFDO0lBQ0MsS0FBSyxDQUFDLG9CQUFvQjtRQUN0QixJQUFJLFdBQVcsR0FBRyxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsc0JBQXNCLEVBQUUsQ0FBQTtRQUNoRSxPQUFPLENBQUMsR0FBRyxDQUFDLGdCQUFnQixFQUFFLFdBQVcsQ0FBQyxDQUFBO1FBQzFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNqQixJQUFJLElBQUksR0FBRyxNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsOEJBQThCLEVBQUUsQ0FBQTtRQUNuRSxDQUFDO1FBQ0QsT0FBTTtJQUNWLENBQUM7SUFDRCxLQUFLLENBQUMsdUJBQXVCO1FBQ3pCLElBQUksV0FBVyxHQUFHLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQywyQkFBMkIsRUFBRSxDQUFBO1FBQ3JFLE9BQU8sQ0FBQyxHQUFHLENBQUMsb0JBQW9CLEVBQUUsV0FBVyxDQUFDLENBQUE7UUFDOUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ2pCLElBQUksSUFBSSxHQUFHLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxtQ0FBbUMsRUFBRSxDQUFBO1FBQ3hFLENBQUM7UUFDRCxPQUFNO0lBQ1YsQ0FBQztJQUNELEtBQUssQ0FBQyx1QkFBdUI7UUFDM0IsSUFBSSxXQUFXLEdBQUcsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLGtCQUFrQixFQUFFLENBQUE7UUFDNUQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsRUFBRSxXQUFXLENBQUMsQ0FBQTtRQUM3QyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDakIsSUFBSSxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLDBCQUEwQixFQUFFLENBQUE7UUFDL0QsQ0FBQztRQUNELE9BQU07SUFDVixDQUFDOytHQTNnQlUsaUJBQWlCO21IQUFqQixpQkFBaUIsY0FGaEIsTUFBTTs7NEZBRVAsaUJBQWlCO2tCQUg3QixVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEV2ZW50RW1pdHRlciwgSW5qZWN0YWJsZSwgT3V0cHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG4vLyBpbXBvcnQgUmVjb3JkZXJNYW5hZ2VyIGZyb20gXCIuL2xpYi94dW5mZWktcmVjb3JkZXJcIlxuLy8gaW1wb3J0IHtSZWNvcmRlck1hbmFnZXJ9IGZyb20gXCIuL2xpYi9yZWNvcmRlci9yZWNvcmRlci1tYW5hZ2VyXCJcbmltcG9ydCBSZWNvcmRlciBmcm9tICdyZWNvcmRlci1jb3JlJ1xuaW1wb3J0ICdyZWNvcmRlci1jb3JlL3NyYy9lbmdpbmUvcGNtJ1xuaW1wb3J0ICdyZWNvcmRlci1jb3JlL3NyYy9lbmdpbmUvd2F2J1xuaW1wb3J0ICdyZWNvcmRlci1jb3JlL3NyYy9leHRlbnNpb25zL3dhdmV2aWV3J1xuaW1wb3J0IENyeXB0b0pTIGZyb20gXCJjcnlwdG8tanNcIlxuaW1wb3J0IHsgcGNtdG9XYXYgfSBmcm9tICcuL2xpYi9wY20yd2F2JztcbmltcG9ydCB7IGNvbnZlcnRGcmFtZUJ1ZmZlclRvQmFzZTY0LCByZXNhbXBsZUF1ZGlvLCByZXNhbXBsZUJ1ZmZlciB9IGZyb20gJy4vbGliL3Jlc2FtcGxlJztcbmltcG9ydCB7IFdlYlNwZWVjaCB9IGZyb20gJy4vY2xhc3MtYXNyJztcbmltcG9ydCB7IFBsYXRmb3JtIH0gZnJvbSAnQGlvbmljL2FuZ3VsYXInO1xuaW1wb3J0IHsgRGlhZ25vc3RpYyB9IGZyb20gJ0Bhd2Vzb21lLWNvcmRvdmEtcGx1Z2lucy9kaWFnbm9zdGljL25neCc7XG4vLyBpbXBvcnQgeyBGbW9kZVRUU1h1bmZlaSB9IGZyby4vY2xhc3MtdHRzLXh1bmZlaS50cy5iYWtmZWknXG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIEZtb2RlVm9pY2VTZXJ2aWNlIHtcblxuICAvKipcbiAgICog5YWz6ZetQVNS77ya55So5LqO5rWL6K+V5YW25LuW5Yqf6IO95pe277yM5Y+v5YWz6ZetQVNS6IqC55yB6K+t6Z+z5o6l5Y+j5raI6ICXXG4gICAqL1xuICBkaXNhYmxlQVNSOmZhbHNlO1xuICAvKipcbiAgICog6K6v6aOeVFRT6K+t6Z+z5ZCI5oiQXG4gICAqL1xuICAvLyB0dHNYdW5mZWkgPSBuZXcgRm1vZGVUVFNYdW5mZWkoKVxuICAvKipcbiAgICogV2ViU3BlZWNoIOivremfs+W6k1xuICAgKi9cbiAgd2ViU3BlZWNoID0gV2ViU3BlZWNoXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcGxhdGZvcm06UGxhdGZvcm0sXG4gICAgcHJpdmF0ZSBkaWFnbm9zdGljOiBEaWFnbm9zdGljLCBcbiAgKSB7IFxuICAgIHRoaXMucmVxdWVzdFBlcm1pc3Npb24oKTtcbiAgICAvLyB0aGlzLnJlY29yZGVyLm9uKFwic3RhcnRcIiwoKSA9PiB7XG4gICAgLy8gfSlcblxuICAgIC8vIHRoaXMucmVjb3JkZXIub24oXCJmcmFtZVJlY29yZGVkXCIsICh7IGlzTGFzdEZyYW1lLCBmcmFtZUJ1ZmZlciB9KSA9PiB7XG4gICAgLy8gICBpZiAodGhpcy5pYXRXUy5yZWFkeVN0YXRlID09PSB0aGlzLmlhdFdTLk9QRU4pIHtcbiAgICAvLyAgICAgdGhpcy5pYXRXUy5zZW5kKFxuICAgIC8vICAgICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAvLyAgICAgICAgIGRhdGE6IHtcbiAgICAvLyAgICAgICAgICAgc3RhdHVzOiBpc0xhc3RGcmFtZSA/IDIgOiAxLFxuICAgIC8vICAgICAgICAgICBmb3JtYXQ6IFwiYXVkaW8vTDE2O3JhdGU9MTYwMDBcIixcbiAgICAvLyAgICAgICAgICAgZW5jb2Rpbmc6IHRoaXMuZW5jb2RpbmdUeXBlLFxuICAgIC8vICAgICAgICAgICBhdWRpbzogdGhpcy50b0Jhc2U2NChmcmFtZUJ1ZmZlciksXG4gICAgLy8gICAgICAgICB9LFxuICAgIC8vICAgICAgIH0pXG4gICAgLy8gICAgICk7XG4gICAgLy8gICAgIGlmIChpc0xhc3RGcmFtZSkge1xuICAgIC8vICAgICAgIHRoaXMuY2hhbmdlQnRuU3RhdHVzKFwiQ0xPU0lOR1wiKTtcbiAgICAvLyAgICAgfVxuICAgIC8vICAgfVxuICAgIC8vIH0pXG5cbiAgICAvLyB0aGlzLnJlY29yZGVyLm9uKFwic3RvcFwiLCgpID0+IHtcbiAgICAvLyB9KVxuXG5cbiAgfVxuXG5cblxuICBvblJlc3VsdFRleHRDaGFuZ2VkOkZ1bmN0aW9uXG4gIC8qKigpXG4gICAqIOeUqOaIt+aTjeS9nO+8muW9lemfs+aMiemSruW/q+aNt+inpuWPkeaTjeS9nFxuICAgKi9cbiAgIHRvZ2dsZVJlY29yZCgpe1xuICAgIGNvbnNvbGUubG9nKHRoaXMuYnRuU3RhdHVzKVxuICAgIGlmICh0aGlzLmJ0blN0YXR1cyA9PT0gXCJVTkRFRklORURcIiB8fCB0aGlzLmJ0blN0YXR1cyA9PT0gXCJDTE9TRURcIikge1xuICAgICAgLy8g5byA5aeL6K6y6K+dYFxuICAgICAgdGhpcy5zdGFydFRhbGsoKVxuICAgIH0gZWxzZSBpZiAodGhpcy5idG5TdGF0dXMgPT09IFwiQ09OTkVDVElOR1wiIHx8IHRoaXMuYnRuU3RhdHVzID09PSBcIk9QRU5cIikge1xuICAgICAgLy8g57uT5p2f5b2V6Z+zIOW5tuWPkemAgea2iOaBr+etieW+heWbnuWkjVxuICAgICAgdGhpcy5maW5pc2hUYWxrKClcbiAgICB9XG4gIH1cbiAvKipcbiAgICog55So5oi35pON5L2c77ya5a6M5oiQ5b2V6Z+z77yM5bm25aSE55CG6L2s5b2V57uT5p6cXG4gICovXG4gaXNVc2VyRmluaXNoOmJvb2xlYW4gPSBmYWxzZTtcbiBmaW5pc2hUYWxrKCl7XG4gICAgdGhpcy5pc1VzZXJGaW5pc2ggPSB0cnVlO1xuICAgIHRoaXMub25CZWZvcmVGaW5pc2hUYWxrJiZ0aGlzLm9uQmVmb3JlRmluaXNoVGFsaygpXG4gICAgdGhpcy5yZWNvcmRTdG9wKClcbiB9XG4gb25CZWZvcmVGaW5pc2hUYWxrOiBGdW5jdGlvblxuIG9uQWZ0ZXJGaW5pc2hUYWxrOiBGdW5jdGlvblxuICAvKipcbiAgICog55So5oi35pON5L2c77ya5byA5aeL6K6y6K+d77yM5a6e5pe26L2s5b2V6K+t6KiAXG4gICAqL1xuICBhc3luYyBzdGFydFRhbGsoZXZuZXQ/KXtcbiAgICB0aGlzLnJlc3VsdFRleHQgPSBcIlwiXG4gICAgdGhpcy5yZXN1bHRUZXh0VGVtcCA9IFwiXCJcbiAgICB0aGlzLm9uQmVmb3JlU3RhcnRUYWxrJiZ0aGlzLm9uQmVmb3JlU3RhcnRUYWxrKClcbiAgICBldmVudD8ucHJldmVudERlZmF1bHQoKVxuICAgIGF3YWl0IHRoaXMub3BlbldpdGhQcml2aWxlZGdlKClcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuY29ubmVjdFdlYlNvY2tldCgpXG4gICAgfSwgMTAwKTtcblxuICAgIHRoaXMub25BZnRlclN0YXJ0VGFsayYmdGhpcy5vbkFmdGVyU3RhcnRUYWxrKClcbiAgfVxuICBvbkJlZm9yZVN0YXJ0VGFsazogRnVuY3Rpb25cbiAgb25BZnRlclN0YXJ0VGFsazogRnVuY3Rpb25cbiAgXG4gIC8qKlxuICAgKiDnlKjmiLfmk43kvZzvvJrlj5bmtojorrLor53vvIzkuJTkuI3lj5HpgIHnu5PmnpxcbiAgICovXG4gIGNhbmNlbFRhbGsoKXtcbiAgICB0aGlzLm9uQmVmb3JlQ2FuY2VsVGFsayYmdGhpcy5vbkJlZm9yZUNhbmNlbFRhbGsoKVxuICAgIHRoaXMucmVjb3JkU3RvcCgpOyAvLyDlgZzmraLlvZXliLZcbiAgICB0aGlzLmlhdFdTPy5jbG9zZSgpOyAvLyDmlq3lvIDov57mjqVcbiAgICB0aGlzLnJlc3VsdFRleHQgPSBudWxsOyAvLyDorr7nva7ovazlvZXnu5PmnpzkuLrnqbpcbiAgICB0aGlzLm9uQWZ0ZXJDYW5jZWxUYWxrJiZ0aGlzLm9uQWZ0ZXJDYW5jZWxUYWxrKClcbiAgfVxuICAvKipcbiAgICog5pON5L2c5Zue6LCDXG4gICAqL1xuICBvbkJlZm9yZUNhbmNlbFRhbGs6IEZ1bmN0aW9uXG4gIG9uQWZ0ZXJDYW5jZWxUYWxrOiBGdW5jdGlvblxuICBvbkFmdGVyUmVjb3JkU3RhcnQ6IEZ1bmN0aW9uXG5cbiAgLyoqXG4gICAqIOeoi+W6j+mAu+i+kVxuICAgKi9cbiAgYXN5bmMgcmVjb3JkU3RhcnQoKXtcbiAgICB0aGlzLmNyZWF0ZVJlY29yZGVyKCk7XG4gICAgYXdhaXQgdGhpcy5vcGVuV2l0aFByaXZpbGVkZ2UoKVxuICAgIHRoaXMucmVjb3JkZXIuc3RhcnQoKTtcbiAgICB0aGlzLmNoYW5nZUJ0blN0YXR1cyhcIk9QRU5cIik7XG4gICAgdGhpcy5vbkFmdGVyUmVjb3JkU3RhcnQmJnRoaXMub25BZnRlclJlY29yZFN0YXJ0KClcbiAgfVxuICByZWNvcmRTdG9wKCl7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKT0+e1xuICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLmNvdW50ZG93bkludGVydmFsKTtcbiAgICAgIHRoaXMuY2hhbmdlQnRuU3RhdHVzKFwiQ0xPU0VEXCIpO1xuICAgICAgdGhpcy5yZWNvcmRlcj8uc3RvcChhc3luYyAoYmxvYjpCbG9iLGR1cmF0aW9uOm51bWJlcik9PntcbiAgICAgICAgICAvL+W9lemfs+e7k+adn+WQju+8jOWPkemAgeW9lemfs+e7k+adn+W4p1xuICAgICAgICAgIHRyeXtcbiAgICAgICAgICAgIHRoaXMuaWF0V1Muc2VuZChcbiAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkoe1wiZGF0YVwiOntcInN0YXR1c1wiOjIsXCJmb3JtYXRcIjpcImF1ZGlvL0wxNjtyYXRlPTE2MDAwXCIsXCJlbmNvZGluZ1wiOnRoaXMuZW5jb2RpbmdUeXBlLFwiYXVkaW9cIjpcIlwifX0pXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgfWNhdGNoKGVycil7fVxuXG4gICAgICAgICAgLy/nroDljZXliKnnlKhVUkznlJ/miJDmnKzlnLDmlofku7blnLDlnYDvvIzms6jmhI/kuI3nlKjkuobml7bpnIDopoFyZXZva2VPYmplY3RVUkzvvIzlkKbliJnpnLjljaDlhoXlrZhcbiAgICAgICAgICAvL+atpOWcsOWdgOWPquiDveacrOWcsOS9v+eUqO+8jOavlOWmgui1i+WAvOe7mWF1ZGlvLnNyY+i/m+ihjOaSreaUvu+8jOi1i+WAvOe7mWEuaHJlZueEtuWQjmEuY2xpY2soKei/m+ihjOS4i+i9ve+8iGHpnIDmj5Dkvptkb3dubG9hZD1cInh4eC5tcDNcIuWxnuaAp++8iVxuICAgICAgICAgIGxldCBsb2NhbFVybD0od2luZG93LlVSTHx8d2Via2l0VVJMKS5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgICAgICAgY29uc29sZS5sb2coYmxvYixsb2NhbFVybCxcIuaXtumVvzpcIitkdXJhdGlvbitcIm1zXCIpO1xuICAgICAgICAgIHRoaXMucmVjb3JkUGNtQmxvYiA9IGJsb2I7XG4gICAgICAgICAgdGhpcy5yZWNvcmRXYXZCbG9iID0gYXdhaXQgdGhpcy5wY21CbG9iVG9XYXZCbG9iKGJsb2IsNDQxMDApO1xuICAgICAgICAgIHRoaXMucmVjb3JkRHVyYXRpb24gPSBkdXJhdGlvbjtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcInRoaXMucmVjb3JkV2F2QmxvYlwiLHRoaXMucmVjb3JkV2F2QmxvYilcbiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIGlmKHRoaXMuaXNVc2VyRmluaXNoKXtcbiAgICAgICAgICAgICAgdGhpcy5vbkFmdGVyRmluaXNoVGFsayYmdGhpcy5vbkFmdGVyRmluaXNoVGFsaygpXG4gICAgICAgICAgICAgIHRoaXMuaXNVc2VyRmluaXNoID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSwgMjAwMCk7XG4gICAgICAgICAgdGhpcy5yZWNvcmRlcj8uY2xvc2UoKTsvL+mHiuaUvuW9lemfs+i1hOa6kO+8jOW9k+eEtuWPr+S7peS4jemHiuaUvu+8jOWQjumdouWPr+S7pei/nue7reiwg+eUqHN0YXJ077yb5L2G5LiN6YeK5pS+5pe257O757uf5oiW5rWP6KeI5Zmo5Lya5LiA55u05o+Q56S65Zyo5b2V6Z+z77yM5pyA5L2z5pON5L2c5piv5b2V5a6M5bCxY2xvc2XmjolcbiAgICAgICAgICB0aGlzLnJlY29yZGVyPW51bGw7XG4gICAgICAgICAgXG4gICAgICAgICAgLy/lt7Lnu4/mi7/liLBibG9i5paH5Lu25a+56LGh5oOz5bmy5Zib5bCx5bmy5Zib77ya56uL5Y2z5pKt5pS+44CB5LiK5Lyg44CB5LiL6L295L+d5a2YXG4gICAgICAgICAgXG4gICAgICAgICAgLyoqKiDjgJDnq4vljbPmkq3mlL7kvovlrZDjgJEgKioqL1xuICAgICAgICAgIC8vIHRoaXMuYXVkaW9QbGF5ZXI9IG5ldyBBdWRpbygpO1xuICAgICAgICAgIC8vIHRoaXMuYXVkaW9QbGF5ZXIuY29udHJvbHM9dHJ1ZTtcbiAgICAgICAgICAvLyB0aGlzLmF1ZGlvUGxheWVyLnNyYz1sb2NhbFVybDtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcImxvY2FsVXJsXCIsbG9jYWxVcmwpXG4gICAgICAgICAgLy8g562J5b6F6K+t6Z+z6L2s5LmJ5a6M5oiQ77yM5aSE55CG6L2s5b2V57uT5p6cXG4gICAgICAgICAgLy8g6ZyA6KaB5YeG56Gu5Yik5patd2Vic29ja2V05bey57uPY2xvc2XkuoZcbiAgICAgICAgICByZXNvbHZlKHRydWUpO1xuICAgICAgfSwobXNnKT0+e1xuICAgICAgICAgIGNvbnNvbGUubG9nKFwi5b2V6Z+z5aSx6LSlOlwiK21zZyk7XG4gICAgICAgICAgdGhpcy5yZWNvcmRlci5jbG9zZSgpOy8v5Y+v5Lul6YCa6L+Hc3RvcOaWueazleeahOesrDPkuKrlj4LmlbDmnaXoh6rliqjosIPnlKhjbG9zZVxuICAgICAgICAgIHRoaXMucmVjb3JkZXI9bnVsbDtcbiAgICAgICAgICByZXNvbHZlKG51bGwpXG4gICAgICB9KVxuICAgIH0pXG4gIH1cbiAgcmVjb3JkV2F2QmxvYjpCbG9iID0gbnVsbFxuICByZWNvcmRQY21CbG9iOkJsb2IgPSBudWxsXG4gIHJlY29yZER1cmF0aW9uOm51bWJlciA9IDA7XG4gIHBsYXlSZWNvcmQoKXtcbiAgICB0aGlzLnBsYXlQQ00odGhpcy5yZWNvcmRQY21CbG9iLDQ0MTAwKVxuICB9XG4gIGFzeW5jIHBjbUJsb2JUb1dhdkJsb2IocGNtQmxvYiwgc2FtcGxlUmF0ZSk6UHJvbWlzZTxCbG9iPntcbiAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZT0+e1xuICAgICAgbGV0IGZpbGVSZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpO1xuICAgICAgXG4gICAgICAvLyDor7vlj5ZCbG9i5pWw5o2uXG4gICAgICBmaWxlUmVhZGVyLm9ubG9hZCA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICAgIGxldCBwY21EYXRhOmFueSA9IGV2ZW50LnRhcmdldC5yZXN1bHQ7XG4gICAgICAgIC8vIENvbnZlcnQgUENNIGRhdGEgdG8gV0FWIGZvcm1hdFxuICAgICAgICBsZXQgd2F2QmxvYiA9IHBjbXRvV2F2KHBjbURhdGEsIHNhbXBsZVJhdGUsMSwxNik7XG4gICAgICAgIHJlc29sdmUod2F2QmxvYilcbiAgICAgIH07XG4gICAgICBcbiAgICAgIC8vIOWwhkJsb2LovazmjaLkuLpBcnJheUJ1ZmZlclxuICAgICAgZmlsZVJlYWRlci5yZWFkQXNBcnJheUJ1ZmZlcihwY21CbG9iKTtcbiAgICB9KVxuICB9XG4gIGFzeW5jIHBsYXlQQ00ocGNtQmxvYiwgc2FtcGxlUmF0ZSkge1xuICAgIGxldCB3YXZCbG9iID0gYXdhaXQgdGhpcy5wY21CbG9iVG9XYXZCbG9iKHBjbUJsb2Isc2FtcGxlUmF0ZSk7XG4gICAgbGV0IHdhdlVybCA9IHdpbmRvdy5VUkwuY3JlYXRlT2JqZWN0VVJMKHdhdkJsb2IpXG4gICAgbGV0IGF1ZGlvID0gbmV3IEF1ZGlvKCk7XG4gICAgYXVkaW8uc3JjID0gd2F2VXJsO1xuICAgIGF1ZGlvLnBsYXkoKTtcbiAgfVxuICBidWZmZXJzOkFycmF5PGFueT5cbiAgYXN5bmMgcGxheUJ1ZmZlcnMoKXtcbiAgICAvLyBsZXQgYXVkaW9CdWZmZXIgPSBbXVxuICAgIC8vIHRoaXMuYnVmZmVycy5mb3JFYWNoKGJ1ZmZlcj0+e1xuICAgIC8vICAgYXVkaW9CdWZmZXIucHVzaChidWZmZXIpXG4gICAgLy8gfSlcbiAgICBsZXQgYXVkaW9CbG9iID0gYXdhaXQgdGhpcy5CdWZmZXJzVG9CbG9iKHRoaXMuYnVmZmVycylcbiAgICB0aGlzLnBsYXlQQ00oYXVkaW9CbG9iLDQ0MTAwKVxuICB9XG4gIEJ1ZmZlcnNUb0Jsb2IoYnVmZmVycykge1xuICAgIGxldCBhdWRpb0J1ZmZlcjphbnkgPSBbXVxuICAgIGJ1ZmZlcnMuZm9yRWFjaChidWZmZXI9PntcbiAgICAgIGJ1ZmZlci5mb3JFYWNoKGludDE2PT57XG4gICAgICAgIGF1ZGlvQnVmZmVyLnB1c2goaW50MTYpXG4gICAgICB9KVxuICAgIH0pXG4gICAgcmV0dXJuIG5ldyBCbG9iKFthdWRpb0J1ZmZlcl0sIHsgdHlwZTogJ2F1ZGlvL3BjbScgfSk7XG4gIH1cbiAgLy8g5bCG5b2V6Z+z5pWw5o2u5YiG5Ymy5Li65q+P5qyh5Y+R6YCB55qE6Z+z6aKR54mH5q61IDEyODDlrZfoioJcbiAgIHNwbGl0QXVkaW9EYXRhKGF1ZGlvRGF0YSkge1xuICAgIGNvbnN0IHNlZ21lbnRTaXplID0gMTI4MDsgLy8g55uu5qCH5YiH54mH5aSn5bCP77yM5Y2V5L2N5Li65a2X6IqCXG4gICAgY29uc3Qgc2VnbWVudENvdW50ID0gTWF0aC5jZWlsKGF1ZGlvRGF0YS5sZW5ndGggLyBzZWdtZW50U2l6ZSk7IC8vIOWIh+eJh+aVsOmHj1xuICAgIGNvbnN0IHNlZ21lbnRzID0gW107XG4gIFxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VnbWVudENvdW50OyBpKyspIHtcbiAgICAgIGNvbnN0IHN0YXJ0ID0gaSAqIHNlZ21lbnRTaXplO1xuICAgICAgY29uc3QgZW5kID0gc3RhcnQgKyBzZWdtZW50U2l6ZTtcbiAgICAgIGNvbnN0IHNlZ21lbnQgPSBhdWRpb0RhdGEuc2xpY2Uoc3RhcnQsIGVuZCk7XG4gIFxuICAgICAgc2VnbWVudHMucHVzaChzZWdtZW50KTtcbiAgICB9XG4gIFxuICAgIHJldHVybiBzZWdtZW50cztcbiAgfVxuICBCdWZmZXJUb0Jsb2IoYnVmZmVyKSB7XG4gICAgcmV0dXJuIG5ldyBCbG9iKFtidWZmZXJdLCB7IHR5cGU6ICdhdWRpby9wY20nIH0pO1xuICB9XG4gIHJlY29yZFR5cGUgPSBcInBjbVwiXG4gIGVuY29kaW5nVHlwZSA9IFwicmF3XCJcbiAgY3JlYXRlUmVjb3JkZXIoKXtcbiAgICBpZih0aGlzLnJlY29yZGVyKSByZXR1cm5cbiAgICB0aGlzLnJlY29yZGVyID0gUmVjb3JkZXIoeyAvL+acrOmFjee9ruWPguaVsOivt+WPguiAg+S4i+mdoueahOaWh+aho++8jOacieivpue7huS7i+e7jVxuICAgICAgdHlwZTp0aGlzLnJlY29yZFR5cGUsc2FtcGxlUmF0ZTo0NDEwMCxiaXRSYXRlOjE2IC8vcGNt5qC85byP77yM5oyH5a6a6YeH5qC3546HaHrjgIHmr5TnibnnjodrYnBz77yM5YW25LuW5Y+C5pWw5L2/55So6buY6K6k6YWN572u77yb5rOo5oSP77ya5piv5pWw5a2X55qE5Y+C5pWw5b+F6aG75o+Q5L6b5pWw5a2X77yM5LiN6KaB55So5a2X56ym5Liy77yb6ZyA6KaB5L2/55So55qEdHlwZeexu+Wei++8jOmcgOaPkOWJjeaKiuagvOW8j+aUr+aMgeaWh+S7tuWKoOi9vei/m+adpe+8jOavlOWmguS9v+eUqHdhduagvOW8j+mcgOimgeaPkOWJjeWKoOi9vXdhdi5qc+e8lueggeW8leaTjlxuICAgICAgLG9uUHJvY2VzczooYnVmZmVycyxwb3dlckxldmVsLGJ1ZmZlckR1cmF0aW9uLGJ1ZmZlclNhbXBsZVJhdGUsbmV3QnVmZmVySWR4LGFzeW5jRW5kKT0+e1xuICAgICAgICAgIC8v5b2V6Z+z5a6e5pe25Zue6LCD77yM5aSn57qmMeenkuiwg+eUqDEy5qyh5pys5Zue6LCD77yMYnVmZmVyc+S4uuW8gOWni+WIsOeOsOWcqOeahOaJgOacieW9lemfs3BjbeaVsOaNruWdlygxNuS9jeWwj+err0xFKVxuICAgICAgICAgIC8v5Y+v5Yip55SoZXh0ZW5zaW9ucy9zb25pYy5qc+aPkuS7tuWunuaXtuWPmOmAn+WPmOiwg++8jOatpOaPkuS7tuiuoeeul+mHj+W3qOWkp++8jG9uUHJvY2Vzc+mcgOimgei/lOWbnnRydWXlvIDlkK/lvILmraXmqKHlvI9cbiAgICAgICAgICAvL+WPr+WunuaXtuS4iuS8oO+8iOWPkemAge+8ieaVsOaNru+8jOmFjeWQiFJlY29yZGVyLlNhbXBsZURhdGHmlrnms5XvvIzlsIZidWZmZXJz5Lit55qE5paw5pWw5o2u6L+e57ut55qE6L2s5o2i5oiQcGNt5LiK5Lyg77yM5oiW5L2/55SobW9ja+aWueazleWwhuaWsOaVsOaNrui/nue7reeahOi9rOeggeaIkOWFtuS7luagvOW8j+S4iuS8oO+8jOWPr+S7peWPguiAg+aWh+aho+mHjOmdoueahO+8mkRlbW/niYfmrrXliJfooaggLT4g5a6e5pe26L2s56CB5bm25LiK5LygLemAmueUqOeJiO+8m+WfuuS6juacrOWKn+iDveWPr+S7peWBmuWIsO+8muWunuaXtui9rOWPkeaVsOaNruOAgeWunuaXtuS/neWtmOaVsOaNruOAgeWunuaXtuivremfs+ivhuWIq++8iEFTUu+8ieetiVxuICAgICAgICAgIC8vIOWunuaXtuWPkemAgeW9lemfs+iHs+aOpeWPo1xuICAgICAgICAgIC8vIGNvbnNvbGUubG9nKFwiYXN5bmNFbmQ6XCIsYXN5bmNFbmQpXG4gICAgICAgICAgLy8gY29uc29sZS5sb2coYnVmZmVycy5sZW5ndGgsYnVmZmVyRHVyYXRpb24sYnVmZmVyU2FtcGxlUmF0ZSxuZXdCdWZmZXJJZHgpXG4gICAgICAgICAgbGV0IGlzTGFzdEZyYW1lID0gZmFsc2UgJiYgdGhpcy5idG5TdGF0dXM9PVwiQ0xPU0VEXCI7IC8vIOS4u+WKqOWFs+mXreS9nOS4uuacgOWQjuW4p1xuICAgICAgICAgIC8vIOW9lemfs+m7mOiupOS4uiA0NDEwMCDph4fmoLfnjocgcGNt5LiN5pSv5oyB5YaNcHJvY2Vzc+S4reWunuaXtui9rOaNolxuICAgICAgICAgIC8vIOmcgOimgeWOi+e8qeS4uiAxNjAwMCDkuIrkvKBcbiAgICAgICAgICBsZXQgZnJhbWVCdWZmZXIgPSBidWZmZXJzLmxlbmd0aCYmYnVmZmVyc1tidWZmZXJzLmxlbmd0aC0xXTtcbiAgICAgICAgICB0aGlzLmJ1ZmZlcnMgPSBidWZmZXJzXG4gICAgICAgICAgZnJhbWVCdWZmZXIgPSByZXNhbXBsZUJ1ZmZlcihmcmFtZUJ1ZmZlciw0NDEwMCwxNjAwMCk7XG4gICAgICAgICAgLy8gdGhpcy5wbGF5UENNKHRoaXMuQnVmZmVyVG9CbG9iKGZyYW1lQnVmZmVyKSwxNjAwMCkgLy8g5YiH54mH5pWw5o2u5pKt5pS+77yM6YeH5qC3546H5rWL6K+VXG5cbiAgICAgICAgICBpZiAodGhpcy5pYXRXUy5yZWFkeVN0YXRlID09PSB0aGlzLmlhdFdTLk9QRU4pIHtcbiAgICAgICAgICAgICAgICBpZih0aGlzLmRpc2FibGVBU1IpIHJldHVyblxuICAgICAgICAgICAgICAgIHRoaXMuaWF0V1Muc2VuZChcbiAgICAgICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgICAgICAgIHN0YXR1czogaXNMYXN0RnJhbWUgPyAyIDogMSxcbiAgICAgICAgICAgICAgICAgICAgICBmb3JtYXQ6IFwiYXVkaW8vTDE2O3JhdGU9MTYwMDBcIixcbiAgICAgICAgICAgICAgICAgICAgICBlbmNvZGluZzogdGhpcy5lbmNvZGluZ1R5cGUsXG4gICAgICAgICAgICAgICAgICAgICAgYXVkaW86IGNvbnZlcnRGcmFtZUJ1ZmZlclRvQmFzZTY0KGZyYW1lQnVmZmVyKS8vIHRoaXMudG9CYXNlNjQoYXVkaW9EYXRhKSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgXG4gICAgICAgICAgICBpZiAoaXNMYXN0RnJhbWUpIHtcbiAgICAgICAgICAgICAgdGhpcy5jaGFuZ2VCdG5TdGF0dXMoXCJDTE9TSU5HXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICAvL+WPr+WunuaXtue7mOWItuazouW9ou+8iGV4dGVuc2lvbnPnm67lvZXlhoXnmoR3YXZldmlldy5qc+OAgXdhdmVzdXJmZXIudmlldy5qc+OAgWZyZXF1ZW5jeS5oaXN0b2dyYW0udmlldy5qc+aPkuS7tuWKn+iDve+8iVxuICAgICAgICAgIHRoaXMud2F2ZUNsaWVudD8uaW5wdXQoYnVmZmVyc1tidWZmZXJzLmxlbmd0aC0xXSxwb3dlckxldmVsLGJ1ZmZlclNhbXBsZVJhdGUpO1xuICAgICAgfVxuICB9KTtcbiAgfVxuICBcbiAgYXN5bmMgb3BlbldpdGhQcml2aWxlZGdlKCl7XG4gICAgY29uc29sZS5sb2codGhpcy5idG5TdGF0dXMpXG4gICAgYXdhaXQgdGhpcy5yZXF1ZXN0UGVybWlzc2lvbigpO1xuICAgIHRoaXMuY3JlYXRlUmVjb3JkZXIoKTtcbiAgICBpZihSZWNvcmRlci5Jc09wZW4oKSkgcmV0dXJuIHRydWVcbiAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZT0+e1xuICAgICAgLy92YXIgZGlhbG9nPWNyZWF0ZURlbGF5RGlhbG9nKCk7IOaIkeS7rOWPr+S7pemAieaLqeaAp+eahOW8ueS4gOS4quWvueivneahhu+8muS4uuS6humYsuatouenu+WKqOerr+a1j+iniOWZqOWtmOWcqOesrOS4ieenjeaDheWGte+8mueUqOaIt+W/veeVpe+8jOW5tuS4lO+8iOaIluiAheWbveS6p+ezu+e7n1VD57O777yJ5rWP6KeI5Zmo5rKh5pyJ5Lu75L2V5Zue6LCD77yM5q2k5aSEZGVtb+ecgeeVpeS6huW8ueeql+eahOS7o+eggVxuICAgICAgdGhpcy5yZWNvcmRlci5vcGVuKCgpPT57Ly/miZPlvIDpuqblhYvpo47mjojmnYPojrflvpfnm7jlhbPotYTmupBcbiAgICAgICAgLy9kaWFsb2cmJmRpYWxvZy5DYW5jZWwoKTsg5aaC5p6c5byA5ZCv5LqG5by55qGG77yM5q2k5aSE6ZyA6KaB5Y+W5raIXG4gICAgICAgIC8vcmVjLnN0YXJ0KCkg5q2k5aSE5Y+v5Lul56uL5Y2z5byA5aeL5b2V6Z+z77yM5L2G5LiN5bu66K6u6L+Z5qC357yW5YaZ77yM5Zug5Li6b3BlbuaYr+S4gOS4quW7tui/n+a8q+mVv+eahOaTjeS9nO+8jOmAmui/h+S4pOasoeeUqOaIt+aTjeS9nOadpeWIhuWIq+iwg+eUqG9wZW7lkoxzdGFydOaYr+aOqOiNkOeahOacgOS9s+a1geeoi1xuICAgICAgICAvL+WIm+W7uuWPr+inhuWMlu+8jOaMh+WumuS4gOS4quimgeaYvuekuueahGRpdlxuICAgICAgICBsZXQgd2F2ZURpdiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIucmVjb3JkLXdhdmVcIik7XG4gICAgICAgIGlmKHdhdmVEaXYpeyAvLyDlrZjlnKjms6LlvaLljLrln5/ml7bvvIzliqDovb3muLLmn5Pnu4Tku7ZcbiAgICAgICAgICBjb25zb2xlLmxvZyh3YXZlRGl2KVxuICAgICAgICAgIGlmKFJlY29yZGVyLldhdmVWaWV3KXRoaXMud2F2ZUNsaWVudD1SZWNvcmRlci5XYXZlVmlldyh7ZWxlbTpcIi5yZWNvcmQtd2F2ZVwifSk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzb2x2ZSh0cnVlKTtcbiAgICB9LChtc2csaXNVc2VyTm90QWxsb3cpPT57Ly/nlKjmiLfmi5Lnu53mnKrmjojmnYPmiJbkuI3mlK/mjIFcbiAgICAgICAgLy9kaWFsb2cmJmRpYWxvZy5DYW5jZWwoKTsg5aaC5p6c5byA5ZCv5LqG5by55qGG77yM5q2k5aSE6ZyA6KaB5Y+W5raIXG4gICAgICAgIGNvbnNvbGUubG9nKChpc1VzZXJOb3RBbGxvdz9cIlVzZXJOb3RBbGxvd++8jFwiOlwiXCIpK1wi5peg5rOV5b2V6Z+zOlwiK21zZyk7XG4gICAgfSk7XG4gIH0pXG5cbiAgfVxuXG4gIGNvbm5TdGF0dXMgPSBcIlwiIC8vIOW9lemfs+S4rSDlu7rnq4vov57mjqXkuK0g5YWz6Zet6L+e5o6l5LitXG5cbiAgYnRuU3RhdHVzID0gXCJVTkRFRklORURcIjsgLy8gXCJVTkRFRklORURcIiBcIkNPTk5FQ1RJTkdcIiBcIk9QRU5cIiBcIkNMT1NJTkdcIiBcIkNMT1NFRFwiXG5cbiAgd2F2ZUNsaWVudDphbnkgLy8g55So5oi35rOi5b2iXG4gIHJlY29yZGVyOmFueVxuICAvLyByZWNvcmRlciA9IG5ldyBSZWNvcmRlck1hbmFnZXIoKTtcbiAgLy8gcmVjb3JkZXIgPSBuZXcgUmVjb3JkZXJNYW5hZ2VyKFwiLi9saWIveHVuZmVpLXJlY29yZGVyXCIpO1xuICBcbiAgaWF0V1M7XG4gIHJlc3VsdFRleHQgPSBcIlwiO1xuICByZXN1bHRUZXh0VGVtcCA9IFwiXCI7XG4gIGNvdW50ZG93bkludGVydmFsO1xuXG4gIC8qKlxuICAgKiDojrflj5Z3ZWJzb2NrZXQgdXJsXG4gICAqIOivpeaOpeWPo+mcgOimgeWQjuerr+aPkOS+m++8jOi/memHjOS4uuS6huaWueS+v+WJjeerr+WkhOeQhlxuICAgKi9cbiAgQVBQSUQgPSBcIjUwZjRhNDZjXCI7XG4gIEFQSV9TRUNSRVQgPSBcIk56RmxObUZoWkRKak1ETmtaR00zTnpJME16ZzJPR05tXCI7XG4gIEFQSV9LRVkgPSBcIjEwNmRkYzQwZGZkNGI5Y2E2ZDdiNDdjNzBmYWRhNzQ5XCI7XG4gIGdldFdlYlNvY2tldFVybCgpIHtcbiAgICAvLyDor7fmsYLlnLDlnYDmoLnmja7or63np43kuI3lkIzlj5jljJZcbiAgICBsZXQgdXJsID0gXCJ3c3M6Ly9pYXQtYXBpLnhmeXVuLmNuL3YyL2lhdFwiO1xuICAgIGxldCBob3N0ID0gXCJpYXQtYXBpLnhmeXVuLmNuXCI7XG4gICAgXG4gICAgbGV0IGFwaUtleSA9IHRoaXMuQVBJX0tFWTtcbiAgICBsZXQgYXBpU2VjcmV0ID0gdGhpcy5BUElfU0VDUkVUO1xuICAgIGxldCBkYXRlID0gbmV3IERhdGUoKS50b1VUQ1N0cmluZygpO1xuICAgIGxldCBhbGdvcml0aG0gPSBcImhtYWMtc2hhMjU2XCI7XG4gICAgbGV0IGhlYWRlcnMgPSBcImhvc3QgZGF0ZSByZXF1ZXN0LWxpbmVcIjtcbiAgICBsZXQgc2lnbmF0dXJlT3JpZ2luID0gYGhvc3Q6ICR7aG9zdH1cXG5kYXRlOiAke2RhdGV9XFxuR0VUIC92Mi9pYXQgSFRUUC8xLjFgO1xuICAgIGxldCBzaWduYXR1cmVTaGEgPSBDcnlwdG9KUy5IbWFjU0hBMjU2KHNpZ25hdHVyZU9yaWdpbiwgYXBpU2VjcmV0KTtcbiAgICBsZXQgc2lnbmF0dXJlID0gQ3J5cHRvSlMuZW5jLkJhc2U2NC5zdHJpbmdpZnkoc2lnbmF0dXJlU2hhKTtcbiAgICBsZXQgYXV0aG9yaXphdGlvbk9yaWdpbiA9IGBhcGlfa2V5PVwiJHthcGlLZXl9XCIsIGFsZ29yaXRobT1cIiR7YWxnb3JpdGhtfVwiLCBoZWFkZXJzPVwiJHtoZWFkZXJzfVwiLCBzaWduYXR1cmU9XCIke3NpZ25hdHVyZX1cImA7XG4gICAgbGV0IGF1dGhvcml6YXRpb24gPSBidG9hKGF1dGhvcml6YXRpb25PcmlnaW4pO1xuICAgIHVybCA9IGAke3VybH0/YXV0aG9yaXphdGlvbj0ke2F1dGhvcml6YXRpb259JmRhdGU9JHtkYXRlfSZob3N0PSR7aG9zdH1gO1xuICAgIHJldHVybiB1cmw7XG4gIH1cblxuICB0b0Jhc2U2NChidWZmZXIpIHtcbiAgICB2YXIgYmluYXJ5ID0gXCJcIjtcbiAgICB2YXIgYnl0ZXMgPSBuZXcgVWludDhBcnJheShidWZmZXIpO1xuICAgIHZhciBsZW4gPSBieXRlcy5ieXRlTGVuZ3RoO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIGJpbmFyeSArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ5dGVzW2ldKTtcbiAgICB9XG4gICAgcmV0dXJuIHdpbmRvdy5idG9hKGJpbmFyeSk7XG4gIH1cblxuICAvKipcbiAgICog5YCS6K6h5pe277ya5pyA6ZW/5pSv5oyBNjDnp5Llrp7ml7bor63pn7PovazlvZXvvIzlpoLmnpzmjIHnu603LTEw56eS5peg5aOw6Z+z77yM5pyN5Yqh56uv5bCG6Ieq5YqoQ0xPU0Xpk77mjqVcbiAgICovXG4gIGNvdW50ZG93bigpIHtcbiAgICBsZXQgc2Vjb25kcyA9IDYwO1xuICAgIHRoaXMuY29ublN0YXR1cyA9IGDlvZXpn7PkuK3vvIgke3NlY29uZHN9c++8iWA7XG4gICAgdGhpcy5jb3VudGRvd25JbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgIHNlY29uZHMgPSBzZWNvbmRzIC0gMTtcbiAgICAgIGNvbnNvbGUubG9nKHNlY29uZHMpO1xuICAgICAgaWYgKHNlY29uZHMgPD0gMCkge1xuICAgICAgICBjbGVhckludGVydmFsKHRoaXMuY291bnRkb3duSW50ZXJ2YWwpO1xuICAgICAgICB0aGlzLnJlY29yZFN0b3AoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuY29ublN0YXR1cyA9IGDlvZXpn7PkuK3vvIgke3NlY29uZHN9c++8iWA7XG4gICAgICB9XG4gICAgfSwgMTAwMCk7XG4gIH1cblxuICBjaGFuZ2VCdG5TdGF0dXMoc3RhdHVzKSB7XG4gICAgdGhpcy5idG5TdGF0dXMgPSBzdGF0dXM7XG4gICAgaWYgKHN0YXR1cyA9PT0gXCJDT05ORUNUSU5HXCIpIHtcbiAgICAgIHRoaXMuY29ublN0YXR1cyA9IFwi5bu656uL6L+e5o6l5LitXCI7XG4gICAgfSBlbHNlIGlmIChzdGF0dXMgPT09IFwiT1BFTlwiKSB7XG4gICAgICB0aGlzLmNvdW50ZG93bigpO1xuICAgIH0gZWxzZSBpZiAoc3RhdHVzID09PSBcIkNMT1NJTkdcIikge1xuICAgICAgdGhpcy5jb25uU3RhdHVzID0gXCLlhbPpl63ov57mjqXkuK1cIjtcbiAgICB9IGVsc2UgaWYgKHN0YXR1cyA9PT0gXCJDTE9TRURcIikge1xuICAgICAgdGhpcy5jb25uU3RhdHVzID0gXCLlvIDlp4vlvZXpn7NcIjtcbiAgICB9XG4gIH1cblxuICByZW5kZXJSZXN1bHQocmVzdWx0RGF0YSkge1xuICAgIC8vIOivhuWIq+e7k+adn1xuICAgIGxldCBqc29uRGF0YSA9IEpTT04ucGFyc2UocmVzdWx0RGF0YSk7XG4gICAgLy8gY29uc29sZS5sb2coanNvbkRhdGEuZGF0YS5yZXN1bHQpXG4gICAgaWYgKGpzb25EYXRhLmRhdGEgJiYganNvbkRhdGEuZGF0YS5yZXN1bHQpIHtcbiAgICAgIGxldCBkYXRhID0ganNvbkRhdGEuZGF0YS5yZXN1bHQ7XG4gICAgICBsZXQgc3RyID0gXCJcIjtcbiAgICAgIGxldCB3cyA9IGRhdGEud3M7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHdzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHN0ciA9IHN0ciArIHdzW2ldLmN3WzBdLnc7XG4gICAgICAgIGNvbnNvbGUubG9nKHN0cilcbiAgICAgIH1cbiAgICAgIC8vIOW8gOWQr3dwZ3PkvJrmnInmraTlrZfmrrUo5YmN5o+Q77ya5Zyo5o6n5Yi25Y+w5byA6YCa5Yqo5oCB5L+u5q2j5Yqf6IO9KVxuICAgICAgLy8g5Y+W5YC85Li6IFwiYXBkXCLml7booajnpLror6XniYfnu5PmnpzmmK/ov73liqDliLDliY3pnaLnmoTmnIDnu4jnu5PmnpzvvJvlj5blgLzkuLpcInJwbFwiIOaXtuihqOekuuabv+aNouWJjemdoueahOmDqOWIhue7k+aenO+8jOabv+aNouiMg+WbtOS4unJn5a2X5q61XG4gICAgICBpZiAoZGF0YS5wZ3MpIHtcbiAgICAgICAgaWYgKGRhdGEucGdzID09PSBcImFwZFwiKSB7XG4gICAgICAgICAgLy8g5bCGdGhpcy5yZXN1bHRUZXh0VGVtcOWQjOatpee7mXRoaXMucmVzdWx0VGV4dFxuICAgICAgICAgIHRoaXMucmVzdWx0VGV4dCA9IHRoaXMucmVzdWx0VGV4dFRlbXA7XG4gICAgICAgIH1cbiAgICAgICAgLy8g5bCG57uT5p6c5a2Y5YKo5ZyodGhpcy5yZXN1bHRUZXh0VGVtcOS4rVxuICAgICAgICB0aGlzLnJlc3VsdFRleHRUZW1wID0gdGhpcy5yZXN1bHRUZXh0ICsgc3RyO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5yZXN1bHRUZXh0ID0gdGhpcy5yZXN1bHRUZXh0ICsgc3RyO1xuICAgICAgfVxuICAgICAgICB0aGlzLnJlc3VsdFRleHRUZW1wIHx8IHRoaXMucmVzdWx0VGV4dCB8fCBcIlwiO1xuICAgICAgY29uc29sZS5sb2coXCJkaWZmIHRlbXBcIix0aGlzLnJlc3VsdFRleHRUZW1wKVxuICAgICAgY29uc29sZS5sb2coXCJkaWZmIHJlc3VsdFwiLHRoaXMucmVzdWx0VGV4dClcbiAgICB9XG4gICAgaWYgKGpzb25EYXRhLmNvZGUgPT09IDAgJiYganNvbkRhdGEuZGF0YS5zdGF0dXMgPT09IDIpIHtcbiAgICAgIHRoaXMuaWF0V1MuY2xvc2UoKTtcbiAgICB9XG4gICAgaWYgKGpzb25EYXRhLmNvZGUgIT09IDApIHtcbiAgICAgIHRoaXMuaWF0V1MuY2xvc2UoKTtcbiAgICAgIGNvbnNvbGUuZXJyb3IoanNvbkRhdGEpO1xuICAgIH1cbiAgfVxuXG4gIGNvbm5lY3RXZWJTb2NrZXQoKSB7XG4gICAgY29uc29sZS5sb2coXCJjb25uZWN0V2ViU29ja2V0XCIpO1xuICAgIGNvbnN0IHdlYnNvY2tldFVybCA9IHRoaXMuZ2V0V2ViU29ja2V0VXJsKCk7XG4gICAgaWYgKFwiV2ViU29ja2V0XCIgaW4gd2luZG93KSB7XG4gICAgICB0aGlzLmlhdFdTID0gbmV3IFdlYlNvY2tldCh3ZWJzb2NrZXRVcmwpO1xuICAgIH0gZWxzZSBpZiAoXCJNb3pXZWJTb2NrZXRcIiBpbiB3aW5kb3cpIHtcbiAgICAgIC8vIHRoaXMuaWF0V1MgPSBuZXcgTW96V2ViU29ja2V0KHdlYnNvY2tldFVybCk7IC8vIE1veuWFvOWuuVxuICAgIH0gZWxzZSB7XG4gICAgICBhbGVydChcIua1j+iniOWZqOS4jeaUr+aMgVdlYlNvY2tldFwiKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc29sZS5sb2coXCJjb25uZWN0V2ViU29ja2V0XCIsdGhpcy5idG5TdGF0dXMpO1xuICAgIHRoaXMuY2hhbmdlQnRuU3RhdHVzKFwiQ09OTkVDVElOR1wiKTtcbiAgICB0aGlzLmlhdFdTLm9ub3BlbiA9IChlKSA9PiB7XG4gICAgICAvLyDlvIDlp4vlvZXpn7NcbiAgICAgIHRoaXMucmVjb3JkU3RhcnQoKTtcbiAgICAgIHZhciBwYXJhbXMgPSB7XG4gICAgICAgIGNvbW1vbjoge1xuICAgICAgICAgIGFwcF9pZDogdGhpcy5BUFBJRCxcbiAgICAgICAgfSxcbiAgICAgICAgYnVzaW5lc3M6IHtcbiAgICAgICAgICBsYW5ndWFnZTogXCJ6aF9jblwiLFxuICAgICAgICAgIGRvbWFpbjogXCJpYXRcIixcbiAgICAgICAgICBhY2NlbnQ6IFwibWFuZGFyaW5cIixcbiAgICAgICAgICB2YWRfZW9zOiA1MDAwLFxuICAgICAgICAgIGR3YTogXCJ3cGdzXCIsXG4gICAgICAgIH0sXG4gICAgICAgIGRhdGE6IHtcbiAgICAgICAgICBzdGF0dXM6IDAsXG4gICAgICAgICAgZm9ybWF0OiBcImF1ZGlvL0wxNjtyYXRlPTE2MDAwXCIsXG4gICAgICAgICAgZW5jb2Rpbmc6IHRoaXMuZW5jb2RpbmdUeXBlLFxuICAgICAgICAgIC8vIGVuY29kaW5nOiBcInNwZWV4LXdiXCIsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgICAgdGhpcy5pYXRXUy5zZW5kKEpTT04uc3RyaW5naWZ5KHBhcmFtcykpO1xuICAgIH07XG4gICAgdGhpcy5pYXRXUy5vbm1lc3NhZ2UgPSAoZSkgPT4ge1xuICAgICAgY29uc29sZS5sb2coXCJvbm1lc3NhZ2VcIit0aGlzLnJlc3VsdFRleHQpXG4gICAgICB0aGlzLnJlbmRlclJlc3VsdChlLmRhdGEpO1xuICAgIH07XG4gICAgdGhpcy5pYXRXUy5vbmVycm9yID0gKGUpID0+IHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXCJlcnJvclwiLGUpO1xuICAgICAgdGhpcy5yZWNvcmRTdG9wKCk7XG4gICAgICB0aGlzLmNoYW5nZUJ0blN0YXR1cyhcIkNMT1NFRFwiKTtcbiAgICB9O1xuICAgIHRoaXMuaWF0V1Mub25jbG9zZSA9IGFzeW5jIChlKSA9PiB7XG4gICAgICAvLyA156eS5YGc6aG/5Lya5a+86Ie057uT5p2f5b2V5Yi2XG4gICAgICBjb25zb2xlLmxvZyhcIm9uY2xvc2VcIit0aGlzLnJlc3VsdFRleHQpXG4gICAgICBjb25zb2xlLmVycm9yKFwiY2xvc2VcIixlKVxuICAgICAgYXdhaXQgdGhpcy5yZWNvcmRTdG9wKCk7XG4gICAgICB0aGlzLmNoYW5nZUJ0blN0YXR1cyhcIkNMT1NFRFwiKTtcblxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICog56e75Yqo56uv5YW85a655pa55rOVXG4gICAqL1xuXG4gICAvKipcbiAgICog56e75Yqo56uv5LiK5Lyg5LiT55So5pa55rOVXG4gICAqIEByZXR1cm5zIFxuICAgKi9cbiAgICBpc0NhcGFjaXRvcigpe1xuICAgICAgcmV0dXJuIHRoaXMucGxhdGZvcm0uaXMoXCJjYXBhY2l0b3JcIikgfHwgdGhpcy5wbGF0Zm9ybS5pcyhcImNvcmRvdmFcIilcbiAgICB9XG4gICAgYXN5bmMgcmVxdWVzdFBlcm1pc3Npb24oKXtcbiAgICAgIGlmKCF0aGlzLmlzQ2FwYWNpdG9yKCkpIHJldHVyblxuICAgICAgdHJ5e1xuICAgICAgICBhd2FpdCB0aGlzLnJlcXVlc3RTdG9hZ2VQZXJtaXNzaW9uKCk7XG4gICAgICAgIGF3YWl0IHRoaXMucmVxdWVzdENhbWVyYVBlcm1pc3Npb24oKTtcbiAgICAgICAgYXdhaXQgdGhpcy5yZXF1ZXN0TWljUGVybWlzc2lvbigpO1xuICAgICAgICBhd2FpdCB0aGlzLnJlcXVlc3RSZWNvcmRBdWRpb1Blcm1pc3Npb24oKTtcbiAgICAgIH1jYXRjaChlcnIpe1xuICAgICAgICBjb25zb2xlLmVycm9yKGVycilcbiAgICAgIH1cbiAgICB9XG4gICAgYXN5bmMgcmVxdWVzdFJlY29yZEF1ZGlvUGVybWlzc2lvbigpe1xuICAgICAgbGV0IGRhdGEgPSBhd2FpdCB0aGlzLmRpYWdub3N0aWMucmVxdWVzdFJ1bnRpbWVQZXJtaXNzaW9ucyhbdGhpcy5kaWFnbm9zdGljLnBlcm1pc3Npb24uUkVDT1JEX0FVRElPXSlcbiAgICAgIGNvbnNvbGUubG9nKFwicmVjb3JkIHBlcm1pc3Npb24gcmVxdWVzdDpcIixkYXRhKVxuICAgICAgcmV0dXJuXG4gIH1cbiAgICBhc3luYyByZXF1ZXN0TWljUGVybWlzc2lvbigpe1xuICAgICAgICBsZXQgaXNBdmFpbGFibGUgPSBhd2FpdCB0aGlzLmRpYWdub3N0aWMuaXNNaWNyb3Bob25lQXV0aG9yaXplZCgpXG4gICAgICAgIGNvbnNvbGUubG9nKFwicGVybWlzc29uX01JQzpcIiwgaXNBdmFpbGFibGUpXG4gICAgICAgIGlmICghaXNBdmFpbGFibGUpIHtcbiAgICAgICAgICBsZXQgZGF0YSA9IGF3YWl0IHRoaXMuZGlhZ25vc3RpYy5yZXF1ZXN0TWljcm9waG9uZUF1dGhvcml6YXRpb24oKVxuICAgICAgICB9XG4gICAgICAgIHJldHVyblxuICAgIH1cbiAgICBhc3luYyByZXF1ZXN0U3RvYWdlUGVybWlzc2lvbigpe1xuICAgICAgICBsZXQgaXNBdmFpbGFibGUgPSBhd2FpdCB0aGlzLmRpYWdub3N0aWMuaXNFeHRlcm5hbFN0b3JhZ2VBdXRob3JpemVkKClcbiAgICAgICAgY29uc29sZS5sb2coXCJwZXJtaXNzb25fU1RPUkFHRTpcIiwgaXNBdmFpbGFibGUpXG4gICAgICAgIGlmICghaXNBdmFpbGFibGUpIHtcbiAgICAgICAgICBsZXQgZGF0YSA9IGF3YWl0IHRoaXMuZGlhZ25vc3RpYy5yZXF1ZXN0RXh0ZXJuYWxTdG9yYWdlQXV0aG9yaXphdGlvbigpXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuXG4gICAgfVxuICAgIGFzeW5jIHJlcXVlc3RDYW1lcmFQZXJtaXNzaW9uKCl7XG4gICAgICBsZXQgaXNBdmFpbGFibGUgPSBhd2FpdCB0aGlzLmRpYWdub3N0aWMuaXNDYW1lcmFBdXRob3JpemVkKClcbiAgICAgIGNvbnNvbGUubG9nKFwicGVybWlzc29uX0NhbWVyYTpcIiwgaXNBdmFpbGFibGUpXG4gICAgICBpZiAoIWlzQXZhaWxhYmxlKSB7XG4gICAgICAgIGxldCBkYXRhID0gYXdhaXQgdGhpcy5kaWFnbm9zdGljLnJlcXVlc3RDYW1lcmFBdXRob3JpemF0aW9uKClcbiAgICAgIH1cbiAgICAgIHJldHVyblxuICB9XG59XG4iXX0=
|
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
* 版权所有 © 未来飞马 © 江西脑控科技有限公司 Copyright © Fmode Technology Co., Ltd.
|
|
5
|
-
* 保留所有权利 All Rights Reserved.
|
|
6
|
-
* /home/ryan/workspace/nova/nova-admin/dist/fmode-ng/esm2022/lib/aigc/voice/index.mjs
|
|
7
|
-
*/
|
|
8
|
-
export*from"./fmode-voice.service";export*from"./audio.player";
|
|
9
|
-
var MODULE_PATH_NEED = `6K+l5paH5Lu25piv5pys6aG555uu55qE5LiA6YOo5YiGIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIHRoZSBDb21wb25lbnRzIGluIEZtb2RlIEluYy4KICAgIOeJiOadg+aJgOaciSDCqSDmnKrmnaXpo57pqawgwqkg5rGf6KW/6ISR5o6n56eR5oqA5pyJ6ZmQ5YWs5Y+4IENvcHlyaWdodCDCqSBGbW9kZSBUZWNobm9sb2d5IENvLiwgTHRkLgogICAg5L+d55WZ5omA5pyJ5p2D5YipIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAgICDkuKXnpoHlnKjmnKrnu4/mjojmnYPnmoTmg4XlhrXkuIvvvIzpgJrov4fku7vkvZXlqpLku4vlpI3liLbmraTmlofku7YgVW5hdXRob3JpemVkIGNvcHlpbmcgb2YgdGhpcyBmaWxlLCB2aWEgYW55IG1lZGl1bSBpcyBzdHJpY3RseSBwcm9oaWJpdGVkCiAgICDor6Xmlofku7bmmK/kuJPmnInnmoTmnLrlr4bmlofku7YgUHJvcHJpZXRhcnkgYW5kIGNvbmZpZGVudGlhbAogICAKICAgIENvcHlyaWdodCAyMDIxLW5vdyBGbW9kZSBJbmMuIHN1cHBvcnRAZm1vZGUuY24uIDE4NjA3MDA3MDczLgogICAg5L+d55WZ5omA5pyJ5p2D5YipIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgogICAgUEFUSDovaG9tZS9yeWFuL3dvcmtzcGFjZS9ub3ZhL25vdmEtYWRtaW4vZGlzdC9mbW9kZS1uZy9lc20yMDIyL2xpYi9haWdjL3ZvaWNlL2luZGV4Lm1qcw==`
|
|
10
|
-
|
|
1
|
+
export * from "./fmode-voice.service";
|
|
2
|
+
export * from "./audio.player";
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9mbW9kZS1uZy9zcmMvbGliL2FpZ2Mvdm9pY2UvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyx1QkFBdUIsQ0FBQTtBQUNyQyxjQUFjLGdCQUFnQixDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0ICogZnJvbSBcIi4vZm1vZGUtdm9pY2Uuc2VydmljZVwiXG5leHBvcnQgKiBmcm9tIFwiLi9hdWRpby5wbGF5ZXJcIiJdfQ==
|