@hivegpt/hiveai-angular 0.0.593 → 0.0.596
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/environments/environment.d.ts.map +1 -1
- package/esm2020/environments/environment.mjs +15 -0
- package/esm2020/hivegpt-hiveai-angular.mjs +5 -0
- package/esm2020/lib/components/NotificationSocket.mjs +45 -0
- package/esm2020/lib/components/bot-html-editor/bot-html-editor.component.mjs +113 -0
- package/esm2020/lib/components/bot.service.mjs +45 -0
- package/esm2020/lib/components/chat-drawer/chat-drawer.component.mjs +3904 -0
- package/esm2020/lib/components/chatbot/chatbot.component.mjs +95 -0
- package/esm2020/lib/components/conversation.service.mjs +58 -0
- package/esm2020/lib/components/socket-service.service.mjs +65 -0
- package/esm2020/lib/components/translations/translation.service.mjs +244 -0
- package/esm2020/lib/components/video-player/video-player.component.mjs +131 -0
- package/esm2020/lib/components/voice-agent/components/voice-agent-modal/voice-agent-modal.component.mjs +187 -0
- package/esm2020/lib/components/voice-agent/services/audio-analyzer.service.mjs +127 -0
- package/esm2020/lib/components/voice-agent/services/voice-agent.service.mjs +352 -0
- package/esm2020/lib/components/voice-agent/voice-agent.module.mjs +37 -0
- package/esm2020/lib/components/voice-agent/voice-modal-tokens.mjs +4 -0
- package/esm2020/lib/hivegpt.module.mjs +28 -0
- package/esm2020/lib/models/video.mjs +2 -0
- package/esm2020/lib/pipes/safe-html.pipe.mjs +20 -0
- package/esm2020/lib/services/platform-token-refresh.service.mjs +177 -0
- package/esm2020/lib/utils/utils.mjs +36 -0
- package/esm2020/public-api.mjs +15 -0
- package/fesm2015/hivegpt-hiveai-angular.mjs +5605 -0
- package/fesm2015/hivegpt-hiveai-angular.mjs.map +1 -0
- package/fesm2020/hivegpt-hiveai-angular.mjs +5606 -0
- package/fesm2020/hivegpt-hiveai-angular.mjs.map +1 -0
- package/hivegpt-hiveai-angular.d.ts.map +1 -1
- package/index.d.ts +6 -0
- package/lib/components/NotificationSocket.d.ts +6 -1
- package/lib/components/NotificationSocket.d.ts.map +1 -1
- package/lib/components/bot-html-editor/bot-html-editor.component.d.ts +3 -0
- package/lib/components/bot-html-editor/bot-html-editor.component.d.ts.map +1 -1
- package/lib/components/bot.service.d.ts +5 -1
- package/lib/components/bot.service.d.ts.map +1 -1
- package/lib/components/chat-drawer/chat-drawer.component.d.ts +7 -3
- package/lib/components/chat-drawer/chat-drawer.component.d.ts.map +1 -1
- package/lib/components/chatbot/chatbot.component.d.ts +3 -0
- package/lib/components/chatbot/chatbot.component.d.ts.map +1 -1
- package/lib/components/conversation.service.d.ts +3 -0
- package/lib/components/conversation.service.d.ts.map +1 -1
- package/lib/components/socket-service.service.d.ts +7 -3
- package/lib/components/socket-service.service.d.ts.map +1 -1
- package/lib/components/translations/translation.service.d.ts +3 -0
- package/lib/components/translations/translation.service.d.ts.map +1 -1
- package/lib/components/video-player/video-player.component.d.ts +3 -0
- package/lib/components/video-player/video-player.component.d.ts.map +1 -1
- package/lib/components/voice-agent/components/voice-agent-modal/voice-agent-modal.component.d.ts +3 -0
- package/lib/components/voice-agent/components/voice-agent-modal/voice-agent-modal.component.d.ts.map +1 -1
- package/lib/components/voice-agent/services/audio-analyzer.service.d.ts +3 -0
- package/lib/components/voice-agent/services/audio-analyzer.service.d.ts.map +1 -1
- package/lib/components/voice-agent/services/voice-agent.service.d.ts +4 -1
- package/lib/components/voice-agent/services/voice-agent.service.d.ts.map +1 -1
- package/lib/components/voice-agent/voice-agent.module.d.ts +6 -0
- package/lib/components/voice-agent/voice-agent.module.d.ts.map +1 -1
- package/lib/components/voice-agent/voice-modal-tokens.d.ts.map +1 -1
- package/lib/hivegpt.module.d.ts +16 -0
- package/lib/hivegpt.module.d.ts.map +1 -1
- package/lib/models/video.d.ts.map +1 -1
- package/lib/pipes/safe-html.pipe.d.ts +3 -0
- package/lib/pipes/safe-html.pipe.d.ts.map +1 -1
- package/lib/services/platform-token-refresh.service.d.ts +3 -0
- package/lib/services/platform-token-refresh.service.d.ts.map +1 -1
- package/lib/utils/utils.d.ts.map +1 -1
- package/package.json +24 -12
- package/public-api.d.ts +2 -0
- package/public-api.d.ts.map +1 -1
- package/bundles/hivegpt-hiveai-angular.umd.js +0 -6285
- package/bundles/hivegpt-hiveai-angular.umd.js.map +0 -1
- package/bundles/hivegpt-hiveai-angular.umd.min.js +0 -2
- package/bundles/hivegpt-hiveai-angular.umd.min.js.map +0 -1
- package/esm2015/environments/environment.js +0 -15
- package/esm2015/hivegpt-hiveai-angular.js +0 -13
- package/esm2015/lib/components/NotificationSocket.js +0 -39
- package/esm2015/lib/components/bot-html-editor/bot-html-editor.component.js +0 -112
- package/esm2015/lib/components/bot.service.js +0 -50
- package/esm2015/lib/components/chat-drawer/chat-drawer.component.js +0 -3809
- package/esm2015/lib/components/chatbot/chatbot.component.js +0 -57
- package/esm2015/lib/components/conversation.service.js +0 -57
- package/esm2015/lib/components/socket-service.service.js +0 -79
- package/esm2015/lib/components/translations/translation.service.js +0 -244
- package/esm2015/lib/components/video-player/video-player.component.js +0 -123
- package/esm2015/lib/components/voice-agent/components/voice-agent-modal/voice-agent-modal.component.js +0 -192
- package/esm2015/lib/components/voice-agent/services/audio-analyzer.service.js +0 -125
- package/esm2015/lib/components/voice-agent/services/voice-agent.service.js +0 -364
- package/esm2015/lib/components/voice-agent/voice-agent.module.js +0 -29
- package/esm2015/lib/components/voice-agent/voice-modal-tokens.js +0 -4
- package/esm2015/lib/hivegpt.module.js +0 -23
- package/esm2015/lib/models/video.js +0 -2
- package/esm2015/lib/pipes/safe-html.pipe.js +0 -19
- package/esm2015/lib/services/platform-token-refresh.service.js +0 -173
- package/esm2015/lib/utils/utils.js +0 -38
- package/esm2015/public-api.js +0 -13
- package/fesm2015/hivegpt-hiveai-angular.js +0 -5484
- package/fesm2015/hivegpt-hiveai-angular.js.map +0 -1
- package/hivegpt-hiveai-angular.d.ts +0 -13
- package/hivegpt-hiveai-angular.metadata.json +0 -1
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { Injectable } from '@angular/core';
|
|
2
|
+
import { BehaviorSubject } from 'rxjs';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
/**
|
|
5
|
+
* Audio analyzer for waveform visualization and local (mic) speaking detection.
|
|
6
|
+
* VoiceAgentService may combine this with WebSocket server events for call state.
|
|
7
|
+
*/
|
|
8
|
+
export class AudioAnalyzerService {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.audioContext = null;
|
|
11
|
+
this.analyserNode = null;
|
|
12
|
+
this.dataArray = null;
|
|
13
|
+
this.animationFrameId = null;
|
|
14
|
+
this.isRunning = false;
|
|
15
|
+
this.audioLevelsSubject = new BehaviorSubject([]);
|
|
16
|
+
this.isUserSpeakingSubject = new BehaviorSubject(false);
|
|
17
|
+
// Adaptive noise floor detection
|
|
18
|
+
this.noiseFloor = 0;
|
|
19
|
+
this.noiseFloorSamples = [];
|
|
20
|
+
this.NOISE_FLOOR_SAMPLE_COUNT = 30;
|
|
21
|
+
this.SPEAKING_THRESHOLD_MULTIPLIER = 2.5;
|
|
22
|
+
this.WAVEFORM_BAR_COUNT = 60;
|
|
23
|
+
// Amplify raw amplitude so normal speech (±10–20 units) maps to visible levels
|
|
24
|
+
this.SENSITIVITY_MULTIPLIER = 5;
|
|
25
|
+
this.audioLevels$ = this.audioLevelsSubject.asObservable();
|
|
26
|
+
this.isUserSpeaking$ = this.isUserSpeakingSubject.asObservable();
|
|
27
|
+
}
|
|
28
|
+
start(stream) {
|
|
29
|
+
if (this.isRunning) {
|
|
30
|
+
this.stop();
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
|
|
34
|
+
const source = this.audioContext.createMediaStreamSource(stream);
|
|
35
|
+
this.analyserNode = this.audioContext.createAnalyser();
|
|
36
|
+
this.analyserNode.fftSize = 2048;
|
|
37
|
+
this.analyserNode.smoothingTimeConstant = 0.4;
|
|
38
|
+
const bufferLength = this.analyserNode.frequencyBinCount;
|
|
39
|
+
this.dataArray = new Uint8Array(bufferLength);
|
|
40
|
+
source.connect(this.analyserNode);
|
|
41
|
+
this.isRunning = true;
|
|
42
|
+
this.noiseFloorSamples = [];
|
|
43
|
+
this.noiseFloor = 0;
|
|
44
|
+
this.analyze();
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
console.error('Error starting audio analyzer:', error);
|
|
48
|
+
this.stop();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
stop() {
|
|
52
|
+
this.isRunning = false;
|
|
53
|
+
if (this.animationFrameId !== null) {
|
|
54
|
+
cancelAnimationFrame(this.animationFrameId);
|
|
55
|
+
this.animationFrameId = null;
|
|
56
|
+
}
|
|
57
|
+
if (this.analyserNode) {
|
|
58
|
+
this.analyserNode.disconnect();
|
|
59
|
+
this.analyserNode = null;
|
|
60
|
+
}
|
|
61
|
+
if (this.audioContext && this.audioContext.state !== 'closed') {
|
|
62
|
+
this.audioContext.close().catch(console.error);
|
|
63
|
+
this.audioContext = null;
|
|
64
|
+
}
|
|
65
|
+
this.dataArray = null;
|
|
66
|
+
this.audioLevelsSubject.next([]);
|
|
67
|
+
this.isUserSpeakingSubject.next(false);
|
|
68
|
+
}
|
|
69
|
+
analyze() {
|
|
70
|
+
if (!this.isRunning || !this.analyserNode || !this.dataArray) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
this.analyserNode.getByteTimeDomainData(this.dataArray);
|
|
74
|
+
// Calculate RMS (Root Mean Square) volume
|
|
75
|
+
const rms = this.calculateRMS(this.dataArray);
|
|
76
|
+
// Learn noise floor during initial samples
|
|
77
|
+
if (this.noiseFloorSamples.length < this.NOISE_FLOOR_SAMPLE_COUNT) {
|
|
78
|
+
this.noiseFloorSamples.push(rms);
|
|
79
|
+
if (this.noiseFloorSamples.length === this.NOISE_FLOOR_SAMPLE_COUNT) {
|
|
80
|
+
// Calculate average noise floor
|
|
81
|
+
const sum = this.noiseFloorSamples.reduce((a, b) => a + b, 0);
|
|
82
|
+
this.noiseFloor = sum / this.NOISE_FLOOR_SAMPLE_COUNT;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
// Update noise floor adaptively (moving average)
|
|
87
|
+
this.noiseFloor = this.noiseFloor * 0.99 + rms * 0.01;
|
|
88
|
+
}
|
|
89
|
+
// Detect if user is speaking
|
|
90
|
+
const threshold = this.noiseFloor * this.SPEAKING_THRESHOLD_MULTIPLIER;
|
|
91
|
+
const isSpeaking = rms > threshold;
|
|
92
|
+
this.isUserSpeakingSubject.next(isSpeaking);
|
|
93
|
+
// Generate waveform bars
|
|
94
|
+
const bars = this.generateWaveformBars(this.dataArray);
|
|
95
|
+
this.audioLevelsSubject.next(bars);
|
|
96
|
+
this.animationFrameId = requestAnimationFrame(() => this.analyze());
|
|
97
|
+
}
|
|
98
|
+
calculateRMS(data) {
|
|
99
|
+
let sum = 0;
|
|
100
|
+
for (let i = 0; i < data.length; i++) {
|
|
101
|
+
const normalized = (data[i] - 128) / 128;
|
|
102
|
+
sum += normalized * normalized;
|
|
103
|
+
}
|
|
104
|
+
return Math.sqrt(sum / data.length);
|
|
105
|
+
}
|
|
106
|
+
generateWaveformBars(data) {
|
|
107
|
+
const bars = [];
|
|
108
|
+
const step = Math.floor(data.length / this.WAVEFORM_BAR_COUNT);
|
|
109
|
+
for (let i = 0; i < this.WAVEFORM_BAR_COUNT; i++) {
|
|
110
|
+
const index = i * step;
|
|
111
|
+
const value = data[index];
|
|
112
|
+
// Normalize and amplify so quiet speech produces visible movement
|
|
113
|
+
const normalized = Math.abs((value - 128) / 128) * 100 * this.SENSITIVITY_MULTIPLIER;
|
|
114
|
+
bars.push(Math.min(100, Math.max(0, normalized)));
|
|
115
|
+
}
|
|
116
|
+
return bars;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
AudioAnalyzerService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AudioAnalyzerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
120
|
+
AudioAnalyzerService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AudioAnalyzerService, providedIn: 'root' });
|
|
121
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AudioAnalyzerService, decorators: [{
|
|
122
|
+
type: Injectable,
|
|
123
|
+
args: [{
|
|
124
|
+
providedIn: 'root'
|
|
125
|
+
}]
|
|
126
|
+
}] });
|
|
127
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXVkaW8tYW5hbHl6ZXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2hpdmVncHQvZXZlbnRzZ3B0LWFuZ3VsYXIvc3JjL2xpYi9jb21wb25lbnRzL3ZvaWNlLWFnZW50L3NlcnZpY2VzL2F1ZGlvLWFuYWx5emVyLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsZUFBZSxFQUFjLE1BQU0sTUFBTSxDQUFDOztBQUVuRDs7O0dBR0c7QUFJSCxNQUFNLE9BQU8sb0JBQW9CO0lBSGpDO1FBSVUsaUJBQVksR0FBd0IsSUFBSSxDQUFDO1FBQ3pDLGlCQUFZLEdBQXdCLElBQUksQ0FBQztRQUN6QyxjQUFTLEdBQXNCLElBQUksQ0FBQztRQUNwQyxxQkFBZ0IsR0FBa0IsSUFBSSxDQUFDO1FBQ3ZDLGNBQVMsR0FBRyxLQUFLLENBQUM7UUFFbEIsdUJBQWtCLEdBQUcsSUFBSSxlQUFlLENBQVcsRUFBRSxDQUFDLENBQUM7UUFDdkQsMEJBQXFCLEdBQUcsSUFBSSxlQUFlLENBQVUsS0FBSyxDQUFDLENBQUM7UUFFcEUsaUNBQWlDO1FBQ3pCLGVBQVUsR0FBRyxDQUFDLENBQUM7UUFDZixzQkFBaUIsR0FBYSxFQUFFLENBQUM7UUFDeEIsNkJBQXdCLEdBQUcsRUFBRSxDQUFDO1FBQzlCLGtDQUE2QixHQUFHLEdBQUcsQ0FBQztRQUNwQyx1QkFBa0IsR0FBRyxFQUFFLENBQUM7UUFDekMsK0VBQStFO1FBQzlELDJCQUFzQixHQUFHLENBQUMsQ0FBQztRQUU1QyxpQkFBWSxHQUF5QixJQUFJLENBQUMsa0JBQWtCLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDNUUsb0JBQWUsR0FBd0IsSUFBSSxDQUFDLHFCQUFxQixDQUFDLFlBQVksRUFBRSxDQUFDO0tBZ0hsRjtJQTlHQyxLQUFL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LFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuXG4vKipcbiAqIEF1ZGlvIGFuYWx5emVyIGZvciB3YXZlZm9ybSB2aXN1YWxpemF0aW9uIGFuZCBsb2NhbCAobWljKSBzcGVha2luZyBkZXRlY3Rpb24uXG4gKiBWb2ljZUFnZW50U2VydmljZSBtYXkgY29tYmluZSB0aGlzIHdpdGggV2ViU29ja2V0IHNlcnZlciBldmVudHMgZm9yIGNhbGwgc3RhdGUuXG4gKi9cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIEF1ZGlvQW5hbHl6ZXJTZXJ2aWNlIHtcbiAgcHJpdmF0ZSBhdWRpb0NvbnRleHQ6IEF1ZGlvQ29udGV4dCB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGFuYWx5c2VyTm9kZTogQW5hbHlzZXJOb2RlIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgZGF0YUFycmF5OiBVaW50OEFycmF5IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgYW5pbWF0aW9uRnJhbWVJZDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgaXNSdW5uaW5nID0gZmFsc2U7XG5cbiAgcHJpdmF0ZSBhdWRpb0xldmVsc1N1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PG51bWJlcltdPihbXSk7XG4gIHByaXZhdGUgaXNVc2VyU3BlYWtpbmdTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihmYWxzZSk7XG5cbiAgLy8gQWRhcHRpdmUgbm9pc2UgZmxvb3IgZGV0ZWN0aW9uXG4gIHByaXZhdGUgbm9pc2VGbG9vciA9IDA7XG4gIHByaXZhdGUgbm9pc2VGbG9vclNhbXBsZXM6IG51bWJlcltdID0gW107XG4gIHByaXZhdGUgcmVhZG9ubHkgTk9JU0VfRkxPT1JfU0FNUExFX0NPVU5UID0gMzA7XG4gIHByaXZhdGUgcmVhZG9ubHkgU1BFQUtJTkdfVEhSRVNIT0xEX01VTFRJUExJRVIgPSAyLjU7XG4gIHByaXZhdGUgcmVhZG9ubHkgV0FWRUZPUk1fQkFSX0NPVU5UID0gNjA7XG4gIC8vIEFtcGxpZnkgcmF3IGFtcGxpdHVkZSBzbyBub3JtYWwgc3BlZWNoICjCsTEw4oCTMjAgdW5pdHMpIG1hcHMgdG8gdmlzaWJsZSBsZXZlbHNcbiAgcHJpdmF0ZSByZWFkb25seSBTRU5TSVRJVklUWV9NVUxUSVBMSUVSID0gNTtcblxuICBhdWRpb0xldmVscyQ6IE9ic2VydmFibGU8bnVtYmVyW10+ID0gdGhpcy5hdWRpb0xldmVsc1N1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gIGlzVXNlclNwZWFraW5nJDogT2JzZXJ2YWJsZTxib29sZWFuPiA9IHRoaXMuaXNVc2VyU3BlYWtpbmdTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuXG4gIHN0YXJ0KHN0cmVhbTogTWVkaWFTdHJlYW0pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pc1J1bm5pbmcpIHtcbiAgICAgIHRoaXMuc3RvcCgpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICB0aGlzLmF1ZGlvQ29udGV4dCA9IG5ldyAod2luZG93LkF1ZGlvQ29udGV4dCB8fCAod2luZG93IGFzIGFueSkud2Via2l0QXVkaW9Db250ZXh0KSgpO1xuICAgICAgY29uc3Qgc291cmNlID0gdGhpcy5hdWRpb0NvbnRleHQuY3JlYXRlTWVkaWFTdHJlYW1Tb3VyY2Uoc3RyZWFtKTtcbiAgICAgIFxuICAgICAgdGhpcy5hbmFseXNlck5vZGUgPSB0aGlzLmF1ZGlvQ29udGV4dC5jcmVhdGVBbmFseXNlcigpO1xuICAgICAgdGhpcy5hbmFseXNlck5vZGUuZmZ0U2l6ZSA9IDIwNDg7XG4gICAgICB0aGlzLmFuYWx5c2VyTm9kZS5zbW9vdGhpbmdUaW1lQ29uc3RhbnQgPSAwLjQ7XG4gICAgICBcbiAgICAgIGNvbnN0IGJ1ZmZlckxlbmd0aCA9IHRoaXMuYW5hbHlzZXJOb2RlLmZyZXF1ZW5jeUJpbkNvdW50O1xuICAgICAgdGhpcy5kYXRhQXJyYXkgPSBuZXcgVWludDhBcnJheShidWZmZXJMZW5ndGgpO1xuICAgICAgXG4gICAgICBzb3VyY2UuY29ubmVjdCh0aGlzLmFuYWx5c2VyTm9kZSk7XG4gICAgICBcbiAgICAgIHRoaXMuaXNSdW5uaW5nID0gdHJ1ZTtcbiAgICAgIHRoaXMubm9pc2VGbG9vclNhbXBsZXMgPSBbXTtcbiAgICAgIHRoaXMubm9pc2VGbG9vciA9IDA7XG4gICAgICBcbiAgICAgIHRoaXMuYW5hbHl6ZSgpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBzdGFydGluZyBhdWRpbyBhbmFseXplcjonLCBlcnJvcik7XG4gICAgICB0aGlzLnN0b3AoKTtcbiAgICB9XG4gIH1cblxuICBzdG9wKCk6IHZvaWQge1xuICAgIHRoaXMuaXNSdW5uaW5nID0gZmFsc2U7XG4gICAgXG4gICAgaWYgKHRoaXMuYW5pbWF0aW9uRnJhbWVJZCAhPT0gbnVsbCkge1xuICAgICAgY2FuY2VsQW5pbWF0aW9uRnJhbWUodGhpcy5hbmltYXRpb25GcmFtZUlkKTtcbiAgICAgIHRoaXMuYW5pbWF0aW9uRnJhbWVJZCA9IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuYW5hbHlzZXJOb2RlKSB7XG4gICAgICB0aGlzLmFuYWx5c2VyTm9kZS5kaXNjb25uZWN0KCk7XG4gICAgICB0aGlzLmFuYWx5c2VyTm9kZSA9IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuYXVkaW9Db250ZXh0ICYmIHRoaXMuYXVkaW9Db250ZXh0LnN0YXRlICE9PSAnY2xvc2VkJykge1xuICAgICAgdGhpcy5hdWRpb0NvbnRleHQuY2xvc2UoKS5jYXRjaChjb25zb2xlLmVycm9yKTtcbiAgICAgIHRoaXMuYXVkaW9Db250ZXh0ID0gbnVsbDtcbiAgICB9XG5cbiAgICB0aGlzLmRhdGFBcnJheSA9IG51bGw7XG4gICAgdGhpcy5hdWRpb0xldmVsc1N1YmplY3QubmV4dChbXSk7XG4gICAgdGhpcy5pc1VzZXJTcGVha2luZ1N1YmplY3QubmV4dChmYWxzZSk7XG4gIH1cblxuICBwcml2YXRlIGFuYWx5emUoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmlzUnVubmluZyB8fCAhdGhpcy5hbmFseXNlck5vZGUgfHwgIXRoaXMuZGF0YUFycmF5KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5hbmFseXNlck5vZGUuZ2V0Qnl0ZVRpbWVEb21haW5EYXRhKHRoaXMuZGF0YUFycmF5KTtcbiAgICBcbiAgICAvLyBDYWxjdWxhdGUgUk1TIChSb290IE1lYW4gU3F1YXJlKSB2b2x1bWVcbiAgICBjb25zdCBybXMgPSB0aGlzLmNhbGN1bGF0ZVJNUyh0aGlzLmRhdGFBcnJheSk7XG4gICAgXG4gICAgLy8gTGVhcm4gbm9pc2UgZmxvb3IgZHVyaW5nIGluaXRpYWwgc2FtcGxlc1xuICAgIGlmICh0aGlzLm5vaXNlRmxvb3JTYW1wbGVzLmxlbmd0aCA8IHRoaXMuTk9JU0VfRkxPT1JfU0FNUExFX0NPVU5UKSB7XG4gICAgICB0aGlzLm5vaXNlRmxvb3JTYW1wbGVzLnB1c2gocm1zKTtcbiAgICAgIGlmICh0aGlzLm5vaXNlRmxvb3JTYW1wbGVzLmxlbmd0aCA9PT0gdGhpcy5OT0lTRV9GTE9PUl9TQU1QTEVfQ09VTlQpIHtcbiAgICAgICAgLy8gQ2FsY3VsYXRlIGF2ZXJhZ2Ugbm9pc2UgZmxvb3JcbiAgICAgICAgY29uc3Qgc3VtID0gdGhpcy5ub2lzZUZsb29yU2FtcGxlcy5yZWR1Y2UoKGEsIGIpID0+IGEgKyBiLCAwKTtcbiAgICAgICAgdGhpcy5ub2lzZUZsb29yID0gc3VtIC8gdGhpcy5OT0lTRV9GTE9PUl9TQU1QTEVfQ09VTlQ7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFVwZGF0ZSBub2lzZSBmbG9vciBhZGFwdGl2ZWx5IChtb3ZpbmcgYXZlcmFnZSlcbiAgICAgIHRoaXMubm9pc2VGbG9vciA9IHRoaXMubm9pc2VGbG9vciAqIDAuOTkgKyBybXMgKiAwLjAxO1xuICAgIH1cblxuICAgIC8vIERldGVjdCBpZiB1c2VyIGlzIHNwZWFraW5nXG4gICAgY29uc3QgdGhyZXNob2xkID0gdGhpcy5ub2lzZUZsb29yICogdGhpcy5TUEVBS0lOR19USFJFU0hPTERfTVVMVElQTElFUjtcbiAgICBjb25zdCBpc1NwZWFraW5nID0gcm1zID4gdGhyZXNob2xkO1xuICAgIHRoaXMuaXNVc2VyU3BlYWtpbmdTdWJqZWN0Lm5leHQoaXNTcGVha2luZyk7XG5cbiAgICAvLyBHZW5lcmF0ZSB3YXZlZm9ybSBiYXJzXG4gICAgY29uc3QgYmFycyA9IHRoaXMuZ2VuZXJhdGVXYXZlZm9ybUJhcnModGhpcy5kYXRhQXJyYXkpO1xuICAgIHRoaXMuYXVkaW9MZXZlbHNTdWJqZWN0Lm5leHQoYmFycyk7XG5cbiAgICB0aGlzLmFuaW1hdGlvbkZyYW1lSWQgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4gdGhpcy5hbmFseXplKCkpO1xuICB9XG5cbiAgcHJpdmF0ZSBjYWxjdWxhdGVSTVMoZGF0YTogVWludDhBcnJheSk6IG51bWJlciB7XG4gICAgbGV0IHN1bSA9IDA7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBub3JtYWxpemVkID0gKGRhdGFbaV0gLSAxMjgpIC8gMTI4O1xuICAgICAgc3VtICs9IG5vcm1hbGl6ZWQgKiBub3JtYWxpemVkO1xuICAgIH1cbiAgICByZXR1cm4gTWF0aC5zcXJ0KHN1bSAvIGRhdGEubGVuZ3RoKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2VuZXJhdGVXYXZlZm9ybUJhcnMoZGF0YTogVWludDhBcnJheSk6IG51bWJlcltdIHtcbiAgICBjb25zdCBiYXJzOiBudW1iZXJbXSA9IFtdO1xuICAgIGNvbnN0IHN0ZXAgPSBNYXRoLmZsb29yKGRhdGEubGVuZ3RoIC8gdGhpcy5XQVZFRk9STV9CQVJfQ09VTlQpO1xuICAgIFxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5XQVZFRk9STV9CQVJfQ09VTlQ7IGkrKykge1xuICAgICAgY29uc3QgaW5kZXggPSBpICogc3RlcDtcbiAgICAgIGNvbnN0IHZhbHVlID0gZGF0YVtpbmRleF07XG4gICAgICAvLyBOb3JtYWxpemUgYW5kIGFtcGxpZnkgc28gcXVpZXQgc3BlZWNoIHByb2R1Y2VzIHZpc2libGUgbW92ZW1lbnRcbiAgICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSBNYXRoLmFicygodmFsdWUgLSAxMjgpIC8gMTI4KSAqIDEwMCAqIHRoaXMuU0VOU0lUSVZJVFlfTVVMVElQTElFUjtcbiAgICAgIGJhcnMucHVzaChNYXRoLm1pbigxMDAsIE1hdGgubWF4KDAsIG5vcm1hbGl6ZWQpKSk7XG4gICAgfVxuICAgIFxuICAgIHJldHVybiBiYXJzO1xuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
import { isPlatformBrowser } from '@angular/common';
|
|
2
|
+
import { Inject, Injectable, PLATFORM_ID } from '@angular/core';
|
|
3
|
+
import { BehaviorSubject, Subject, Subscription } from 'rxjs';
|
|
4
|
+
import { take } from 'rxjs/operators';
|
|
5
|
+
import { PipecatClient, RTVIEvent } from '@pipecat-ai/client-js';
|
|
6
|
+
import { WebSocketTransport } from '@pipecat-ai/websocket-transport';
|
|
7
|
+
import * as i0 from "@angular/core";
|
|
8
|
+
import * as i1 from "./audio-analyzer.service";
|
|
9
|
+
import * as i2 from "../../../services/platform-token-refresh.service";
|
|
10
|
+
/**
|
|
11
|
+
* Voice agent orchestrator using the official PipecatClient SDK.
|
|
12
|
+
*
|
|
13
|
+
* Audio flow (mirrors the React reference implementation):
|
|
14
|
+
* - Local mic: acquired by PipecatClient.initDevices(); local track fed to
|
|
15
|
+
* AudioAnalyzerService for waveform visualisation.
|
|
16
|
+
* - Bot audio: received as a MediaStreamTrack via RTVIEvent.TrackStarted,
|
|
17
|
+
* played through a hidden <audio> element.
|
|
18
|
+
* - All binary protobuf framing / RTVI protocol handled by
|
|
19
|
+
* @pipecat-ai/client-js + @pipecat-ai/websocket-transport.
|
|
20
|
+
*/
|
|
21
|
+
export class VoiceAgentService {
|
|
22
|
+
constructor(audioAnalyzer, platformTokenRefresh, ngZone,
|
|
23
|
+
/** `Object` not `object` — ngc metadata collection rejects the `object` type in DI params. */
|
|
24
|
+
platformId) {
|
|
25
|
+
this.audioAnalyzer = audioAnalyzer;
|
|
26
|
+
this.platformTokenRefresh = platformTokenRefresh;
|
|
27
|
+
this.ngZone = ngZone;
|
|
28
|
+
this.platformId = platformId;
|
|
29
|
+
this.callStateSubject = new BehaviorSubject('idle');
|
|
30
|
+
this.statusTextSubject = new BehaviorSubject('');
|
|
31
|
+
this.durationSubject = new BehaviorSubject('00:00');
|
|
32
|
+
this.isMicMutedSubject = new BehaviorSubject(false);
|
|
33
|
+
this.isUserSpeakingSubject = new BehaviorSubject(false);
|
|
34
|
+
this.audioLevelsSubject = new BehaviorSubject([]);
|
|
35
|
+
this.userTranscriptSubject = new Subject();
|
|
36
|
+
this.botTranscriptSubject = new Subject();
|
|
37
|
+
this.callStartTime = 0;
|
|
38
|
+
this.durationInterval = null;
|
|
39
|
+
this.pcClient = null;
|
|
40
|
+
this.botAudioElement = null;
|
|
41
|
+
this.lifecycleToken = 0;
|
|
42
|
+
this.subscriptions = new Subscription();
|
|
43
|
+
this.destroy$ = new Subject();
|
|
44
|
+
this.callState$ = this.callStateSubject.asObservable();
|
|
45
|
+
this.statusText$ = this.statusTextSubject.asObservable();
|
|
46
|
+
this.duration$ = this.durationSubject.asObservable();
|
|
47
|
+
this.isMicMuted$ = this.isMicMutedSubject.asObservable();
|
|
48
|
+
this.isUserSpeaking$ = this.isUserSpeakingSubject.asObservable();
|
|
49
|
+
this.audioLevels$ = this.audioLevelsSubject.asObservable();
|
|
50
|
+
this.userTranscript$ = this.userTranscriptSubject.asObservable();
|
|
51
|
+
this.botTranscript$ = this.botTranscriptSubject.asObservable();
|
|
52
|
+
this.subscriptions.add(this.audioAnalyzer.audioLevels$.subscribe((levels) => this.audioLevelsSubject.next(levels)));
|
|
53
|
+
}
|
|
54
|
+
ngOnDestroy() {
|
|
55
|
+
this.destroy$.next();
|
|
56
|
+
this.subscriptions.unsubscribe();
|
|
57
|
+
void this.disconnect();
|
|
58
|
+
}
|
|
59
|
+
/** Reset to idle (e.g. when modal re-opens so user can click Start Call). */
|
|
60
|
+
resetToIdle() {
|
|
61
|
+
void this.prepareFreshSession();
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Hard reset voice session so each modal open starts from a clean state.
|
|
65
|
+
* Closes any previous client and prevents stale callbacks from mutating UI state.
|
|
66
|
+
*/
|
|
67
|
+
async prepareFreshSession() {
|
|
68
|
+
this.lifecycleToken += 1;
|
|
69
|
+
this.stopDurationTimer();
|
|
70
|
+
this.callStartTime = 0;
|
|
71
|
+
this.audioAnalyzer.stop();
|
|
72
|
+
this.stopBotAudio();
|
|
73
|
+
this.isUserSpeakingSubject.next(false);
|
|
74
|
+
this.isMicMutedSubject.next(false);
|
|
75
|
+
this.durationSubject.next('00:00');
|
|
76
|
+
this.statusTextSubject.next('');
|
|
77
|
+
this.callStateSubject.next('idle');
|
|
78
|
+
await this.cleanupPipecatClient();
|
|
79
|
+
}
|
|
80
|
+
async connect(apiUrl, token, botId, conversationId, apiKey, eventToken, eventId, eventUrl, domainAuthority, usersApiUrl) {
|
|
81
|
+
if (this.callStateSubject.value !== 'idle') {
|
|
82
|
+
console.warn('[HiveGpt Voice] Call already in progress');
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const connectToken = ++this.lifecycleToken;
|
|
86
|
+
try {
|
|
87
|
+
this.callStateSubject.next('connecting');
|
|
88
|
+
this.statusTextSubject.next('Connecting...');
|
|
89
|
+
let accessToken = token;
|
|
90
|
+
if (usersApiUrl && isPlatformBrowser(this.platformId)) {
|
|
91
|
+
try {
|
|
92
|
+
const ensured = await this.platformTokenRefresh
|
|
93
|
+
.ensureValidAccessToken(token, usersApiUrl)
|
|
94
|
+
.pipe(take(1))
|
|
95
|
+
.toPromise();
|
|
96
|
+
if (ensured?.accessToken)
|
|
97
|
+
accessToken = ensured.accessToken;
|
|
98
|
+
}
|
|
99
|
+
catch (e) {
|
|
100
|
+
console.warn('[HiveGpt Voice] Token refresh failed', e);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const baseUrl = apiUrl.replace(/\/$/, '');
|
|
104
|
+
const pcClient = new PipecatClient({
|
|
105
|
+
transport: new WebSocketTransport(),
|
|
106
|
+
enableMic: true,
|
|
107
|
+
enableCam: false,
|
|
108
|
+
callbacks: {
|
|
109
|
+
onConnected: () => this.ngZone.run(() => {
|
|
110
|
+
if (!this.isLifecycleActive(connectToken))
|
|
111
|
+
return;
|
|
112
|
+
this.onPipecatConnected();
|
|
113
|
+
}),
|
|
114
|
+
onDisconnected: () => this.ngZone.run(() => {
|
|
115
|
+
if (!this.isLifecycleActive(connectToken))
|
|
116
|
+
return;
|
|
117
|
+
this.onPipecatDisconnected();
|
|
118
|
+
}),
|
|
119
|
+
onBotReady: () => this.ngZone.run(() => {
|
|
120
|
+
if (!this.isLifecycleActive(connectToken))
|
|
121
|
+
return;
|
|
122
|
+
this.onBotReady();
|
|
123
|
+
}),
|
|
124
|
+
onUserTranscript: (data) => this.ngZone.run(() => this.isLifecycleActive(connectToken) &&
|
|
125
|
+
this.userTranscriptSubject.next({ text: data.text, final: !!data.final })),
|
|
126
|
+
onBotTranscript: (data) => this.ngZone.run(() => {
|
|
127
|
+
if (!this.isLifecycleActive(connectToken))
|
|
128
|
+
return;
|
|
129
|
+
this.botTranscriptSubject.next(data.text);
|
|
130
|
+
}),
|
|
131
|
+
onError: (err) => {
|
|
132
|
+
this.ngZone.run(() => {
|
|
133
|
+
if (!this.isLifecycleActive(connectToken))
|
|
134
|
+
return;
|
|
135
|
+
console.error('[HiveGpt Voice] PipecatClient error', err);
|
|
136
|
+
this.callStateSubject.next('ended');
|
|
137
|
+
this.statusTextSubject.next('Connection failed');
|
|
138
|
+
});
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
this.pcClient = pcClient;
|
|
143
|
+
// Bot audio arrives as a MediaStreamTrack — wire to a hidden <audio> element
|
|
144
|
+
pcClient.on(RTVIEvent.TrackStarted, (track, participant) => {
|
|
145
|
+
if (!this.isLifecycleActive(connectToken))
|
|
146
|
+
return;
|
|
147
|
+
if (!participant?.local && track.kind === 'audio') {
|
|
148
|
+
this.ngZone.run(() => this.setupBotAudioTrack(track));
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
// Speaking state comes straight from RTVI events
|
|
152
|
+
pcClient.on(RTVIEvent.BotStartedSpeaking, () => this.ngZone.run(() => {
|
|
153
|
+
if (!this.isLifecycleActive(connectToken))
|
|
154
|
+
return;
|
|
155
|
+
this.onBotStartedSpeaking();
|
|
156
|
+
}));
|
|
157
|
+
pcClient.on(RTVIEvent.BotStoppedSpeaking, () => this.ngZone.run(() => {
|
|
158
|
+
if (!this.isLifecycleActive(connectToken))
|
|
159
|
+
return;
|
|
160
|
+
this.onBotStoppedSpeaking();
|
|
161
|
+
}));
|
|
162
|
+
pcClient.on(RTVIEvent.UserStartedSpeaking, () => this.ngZone.run(() => {
|
|
163
|
+
if (!this.isLifecycleActive(connectToken))
|
|
164
|
+
return;
|
|
165
|
+
this.isUserSpeakingSubject.next(true);
|
|
166
|
+
this.callStateSubject.next('listening');
|
|
167
|
+
this.statusTextSubject.next('Listening...');
|
|
168
|
+
}));
|
|
169
|
+
pcClient.on(RTVIEvent.UserStoppedSpeaking, () => this.ngZone.run(() => {
|
|
170
|
+
if (!this.isLifecycleActive(connectToken))
|
|
171
|
+
return;
|
|
172
|
+
this.isUserSpeakingSubject.next(false);
|
|
173
|
+
if (this.callStateSubject.value === 'listening') {
|
|
174
|
+
// Brief 'Processing...' while we wait for the bot to respond.
|
|
175
|
+
this.callStateSubject.next('connected');
|
|
176
|
+
this.statusTextSubject.next('Processing...');
|
|
177
|
+
}
|
|
178
|
+
}));
|
|
179
|
+
// Acquire mic (triggers browser permission prompt)
|
|
180
|
+
await pcClient.initDevices();
|
|
181
|
+
// Build headers using the browser Headers API (required by pipecat's APIRequest type)
|
|
182
|
+
const requestHeaders = new Headers();
|
|
183
|
+
requestHeaders.append('Authorization', `Bearer ${accessToken}`);
|
|
184
|
+
requestHeaders.append('x-api-key', apiKey);
|
|
185
|
+
requestHeaders.append('hive-bot-id', botId);
|
|
186
|
+
requestHeaders.append('domain-authority', domainAuthority);
|
|
187
|
+
requestHeaders.append('eventUrl', eventUrl);
|
|
188
|
+
requestHeaders.append('eventId', eventId);
|
|
189
|
+
requestHeaders.append('eventToken', eventToken);
|
|
190
|
+
requestHeaders.append('ngrok-skip-browser-warning', 'true');
|
|
191
|
+
// POST to /ai/ask-voice-socket → receives { ws_url } → WebSocketTransport connects
|
|
192
|
+
await pcClient.startBotAndConnect({
|
|
193
|
+
endpoint: `${baseUrl}/ai/ask-voice-socket`,
|
|
194
|
+
headers: requestHeaders,
|
|
195
|
+
requestData: {
|
|
196
|
+
bot_id: botId,
|
|
197
|
+
conversation_id: conversationId,
|
|
198
|
+
voice: 'alloy',
|
|
199
|
+
},
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
if (!this.isLifecycleActive(connectToken))
|
|
204
|
+
return;
|
|
205
|
+
console.error('[HiveGpt Voice] connect failed', error);
|
|
206
|
+
this.callStateSubject.next('ended');
|
|
207
|
+
await this.cleanupPipecatClient();
|
|
208
|
+
this.statusTextSubject.next('Connection failed');
|
|
209
|
+
throw error;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
onPipecatConnected() {
|
|
213
|
+
// Start the duration timer from the moment the session is live.
|
|
214
|
+
this.callStartTime = Date.now();
|
|
215
|
+
this.startDurationTimer();
|
|
216
|
+
this.callStateSubject.next('connected');
|
|
217
|
+
this.statusTextSubject.next('Connected');
|
|
218
|
+
// Preserve any mute action the user made during "connecting".
|
|
219
|
+
const shouldBeMuted = this.isMicMutedSubject.value;
|
|
220
|
+
this.pcClient?.enableMic(!shouldBeMuted);
|
|
221
|
+
this.isMicMutedSubject.next(shouldBeMuted);
|
|
222
|
+
this.startLocalMicAnalyzer();
|
|
223
|
+
}
|
|
224
|
+
onPipecatDisconnected() {
|
|
225
|
+
this.stopDurationTimer();
|
|
226
|
+
this.callStartTime = 0;
|
|
227
|
+
this.audioAnalyzer.stop();
|
|
228
|
+
this.stopBotAudio();
|
|
229
|
+
this.callStateSubject.next('ended');
|
|
230
|
+
this.statusTextSubject.next('Call Ended');
|
|
231
|
+
}
|
|
232
|
+
onBotReady() {
|
|
233
|
+
// Retry track wiring in case tracks weren't ready at onConnected.
|
|
234
|
+
this.startLocalMicAnalyzer();
|
|
235
|
+
const botTrack = this.pcClient?.tracks()
|
|
236
|
+
?.bot?.audio;
|
|
237
|
+
if (botTrack)
|
|
238
|
+
this.setupBotAudioTrack(botTrack);
|
|
239
|
+
// Bot is initialised — signal that we're now waiting for user input.
|
|
240
|
+
this.statusTextSubject.next('Listening...');
|
|
241
|
+
}
|
|
242
|
+
startLocalMicAnalyzer() {
|
|
243
|
+
const localTrack = this.pcClient?.tracks()
|
|
244
|
+
?.local?.audio;
|
|
245
|
+
if (localTrack) {
|
|
246
|
+
this.audioAnalyzer.start(new MediaStream([localTrack]));
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
onBotStartedSpeaking() {
|
|
250
|
+
this.callStateSubject.next('talking');
|
|
251
|
+
this.statusTextSubject.next('Talking...');
|
|
252
|
+
// Mark user as no longer speaking when bot takes the turn.
|
|
253
|
+
this.isUserSpeakingSubject.next(false);
|
|
254
|
+
}
|
|
255
|
+
onBotStoppedSpeaking() {
|
|
256
|
+
if (this.callStateSubject.value === 'talking') {
|
|
257
|
+
this.callStateSubject.next('connected');
|
|
258
|
+
this.statusTextSubject.next('Listening...');
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
setupBotAudioTrack(track) {
|
|
262
|
+
if (!this.botAudioElement) {
|
|
263
|
+
this.botAudioElement = new Audio();
|
|
264
|
+
this.botAudioElement.autoplay = true;
|
|
265
|
+
}
|
|
266
|
+
const existing = this.botAudioElement.srcObject
|
|
267
|
+
?.getAudioTracks()[0];
|
|
268
|
+
if (existing?.id === track.id)
|
|
269
|
+
return;
|
|
270
|
+
this.botAudioElement.srcObject = new MediaStream([track]);
|
|
271
|
+
this.botAudioElement.play().catch((err) => console.warn('[HiveGpt Voice] Bot audio play blocked', err));
|
|
272
|
+
}
|
|
273
|
+
stopBotAudio() {
|
|
274
|
+
if (this.botAudioElement) {
|
|
275
|
+
try {
|
|
276
|
+
this.botAudioElement.pause();
|
|
277
|
+
this.botAudioElement.srcObject
|
|
278
|
+
?.getAudioTracks()
|
|
279
|
+
.forEach((t) => t.stop());
|
|
280
|
+
this.botAudioElement.srcObject = null;
|
|
281
|
+
}
|
|
282
|
+
catch {
|
|
283
|
+
// ignore
|
|
284
|
+
}
|
|
285
|
+
this.botAudioElement = null;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
async disconnect() {
|
|
289
|
+
this.lifecycleToken += 1;
|
|
290
|
+
this.stopDurationTimer();
|
|
291
|
+
this.callStartTime = 0;
|
|
292
|
+
this.audioAnalyzer.stop();
|
|
293
|
+
this.stopBotAudio();
|
|
294
|
+
await this.cleanupPipecatClient();
|
|
295
|
+
this.callStateSubject.next('ended');
|
|
296
|
+
this.statusTextSubject.next('Call Ended');
|
|
297
|
+
}
|
|
298
|
+
isLifecycleActive(token) {
|
|
299
|
+
return token === this.lifecycleToken;
|
|
300
|
+
}
|
|
301
|
+
async cleanupPipecatClient() {
|
|
302
|
+
if (this.pcClient) {
|
|
303
|
+
try {
|
|
304
|
+
await this.pcClient.disconnect();
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
// ignore
|
|
308
|
+
}
|
|
309
|
+
this.pcClient = null;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
toggleMic() {
|
|
313
|
+
const nextMuted = !this.isMicMutedSubject.value;
|
|
314
|
+
// Reflect the user's intent immediately, even if connect is still in progress.
|
|
315
|
+
this.isMicMutedSubject.next(nextMuted);
|
|
316
|
+
if (this.pcClient) {
|
|
317
|
+
this.pcClient.enableMic(!nextMuted);
|
|
318
|
+
}
|
|
319
|
+
if (nextMuted)
|
|
320
|
+
this.isUserSpeakingSubject.next(false);
|
|
321
|
+
}
|
|
322
|
+
startDurationTimer() {
|
|
323
|
+
const tick = () => {
|
|
324
|
+
if (this.callStartTime > 0) {
|
|
325
|
+
const elapsed = Math.floor((Date.now() - this.callStartTime) / 1000);
|
|
326
|
+
const m = Math.floor(elapsed / 60);
|
|
327
|
+
const s = elapsed % 60;
|
|
328
|
+
this.durationSubject.next(`${m}:${String(s).padStart(2, '0')}`);
|
|
329
|
+
}
|
|
330
|
+
};
|
|
331
|
+
tick();
|
|
332
|
+
this.durationInterval = setInterval(tick, 1000);
|
|
333
|
+
}
|
|
334
|
+
stopDurationTimer() {
|
|
335
|
+
if (this.durationInterval) {
|
|
336
|
+
clearInterval(this.durationInterval);
|
|
337
|
+
this.durationInterval = null;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
VoiceAgentService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: VoiceAgentService, deps: [{ token: i1.AudioAnalyzerService }, { token: i2.PlatformTokenRefreshService }, { token: i0.NgZone }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
342
|
+
VoiceAgentService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: VoiceAgentService, providedIn: 'root' });
|
|
343
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: VoiceAgentService, decorators: [{
|
|
344
|
+
type: Injectable,
|
|
345
|
+
args: [{
|
|
346
|
+
providedIn: 'root',
|
|
347
|
+
}]
|
|
348
|
+
}], ctorParameters: function () { return [{ type: i1.AudioAnalyzerService }, { type: i2.PlatformTokenRefreshService }, { type: i0.NgZone }, { type: Object, decorators: [{
|
|
349
|
+
type: Inject,
|
|
350
|
+
args: [PLATFORM_ID]
|
|
351
|
+
}] }]; } });
|
|
352
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidm9pY2UtYWdlbnQuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2hpdmVncHQvZXZlbnRzZ3B0LWFuZ3VsYXIvc3JjL2xpYi9jb21wb25lbnRzL3ZvaWNlLWFnZW50L3NlcnZpY2VzL3ZvaWNlLWFnZW50LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDcEQsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQXFCLFdBQVcsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRixPQUFPLEVBQUUsZUFBZSxFQUFjLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDMUUsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3RDLE9BQU8sRUFBRSxhQUFhLEVBQUUsU0FBUyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDakUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0saUNBQWlDLENBQUM7Ozs7QUFpQnJFOzs7Ozs7Ozs7O0dBVUc7QUFJSCxNQUFNLE9BQU8saUJBQWlCO0lBNkI1QixZQUNVLGFBQW1DLEVBQ25DLG9CQUFpRCxFQUNqRCxNQUFjO0lBQ3RCLDhGQUE4RjtJQUNqRSxVQUFrQjtRQUp2QyxrQkFBYSxHQUFiLGFBQWEsQ0FBc0I7UUFDbkMseUJBQW9CLEdBQXBCLG9CQUFvQixDQUE2QjtRQUNqRCxXQUFNLEdBQU4sTUFBTSxDQUFRO1FBRU8sZUFBVSxHQUFWLFVBQVUsQ0FBUTtRQWpDekMscUJBQWdCLEdBQUcsSUFBSSxlQUFlLENBQVksTUFBTSxDQUFDLENBQUM7UUFDMUQsc0JBQWlCLEdBQUcsSUFBSSxlQUFlLENBQVMsRUFBRSxDQUFDLENBQUM7UUFDcEQsb0JBQWUsR0FBRyxJQUFJLGVBQWUsQ0FBUyxPQUFPLENBQUMsQ0FBQztRQUN2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LGdCQUFnQixHQUFHLElBQUksQ0FBQztTQUM5QjtJQUNILENBQUM7OytHQWpYVSxpQkFBaUIsdUhBa0NsQixXQUFXO21IQWxDVixpQkFBaUIsY0FGaEIsTUFBTTs0RkFFUCxpQkFBaUI7a0JBSDdCLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25COzswQkFtQ0ksTUFBTTsyQkFBQyxXQUFXIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaXNQbGF0Zm9ybUJyb3dzZXIgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgSW5qZWN0LCBJbmplY3RhYmxlLCBOZ1pvbmUsIE9uRGVzdHJveSwgUExBVEZPUk1fSUQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgT2JzZXJ2YWJsZSwgU3ViamVjdCwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0YWtlIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgUGlwZWNhdENsaWVudCwgUlRWSUV2ZW50IH0gZnJvbSAnQHBpcGVjYXQtYWkvY2xpZW50LWpzJztcbmltcG9ydCB7IFdlYlNvY2tldFRyYW5zcG9ydCB9IGZyb20gJ0BwaXBlY2F0LWFpL3dlYnNvY2tldC10cmFuc3BvcnQnO1xuaW1wb3J0IHsgUGxhdGZvcm1Ub2tlblJlZnJlc2hTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvcGxhdGZvcm0tdG9rZW4tcmVmcmVzaC5zZXJ2aWNlJztcbmltcG9ydCB7IEF1ZGlvQW5hbHl6ZXJTZXJ2aWNlIH0gZnJvbSAnLi9hdWRpby1hbmFseXplci5zZXJ2aWNlJztcblxuZXhwb3J0IHR5cGUgQ2FsbFN0YXRlID1cbiAgfCAnaWRsZSdcbiAgfCAnY29ubmVjdGluZydcbiAgfCAnY29ubmVjdGVkJ1xuICB8ICdsaXN0ZW5pbmcnXG4gIHwgJ3RhbGtpbmcnXG4gIHwgJ2VuZGVkJztcblxuZXhwb3J0IGludGVyZmFjZSBUcmFuc2NyaXB0RGF0YSB7XG4gIHRleHQ6IHN0cmluZztcbiAgZmluYWw6IGJvb2xlYW47XG59XG5cbi8qKlxuICogVm9pY2UgYWdlbnQgb3JjaGVzdHJhdG9yIHVzaW5nIHRoZSBvZmZpY2lhbCBQaXBlY2F0Q2xpZW50IFNESy5cbiAqXG4gKiBBdWRpbyBmbG93IChtaXJyb3JzIHRoZSBSZWFjdCByZWZlcmVuY2UgaW1wbGVtZW50YXRpb24pOlxuICogIC0gTG9jYWwgbWljOiBhY3F1aXJlZCBieSBQaXBlY2F0Q2xpZW50LmluaXREZXZpY2VzKCk7IGxvY2FsIHRyYWNrIGZlZCB0b1xuICogICAgQXVkaW9BbmFseXplclNlcnZpY2UgZm9yIHdhdmVmb3JtIHZpc3VhbGlzYXRpb24uXG4gKiAgLSBCb3QgYXVkaW86IHJlY2VpdmVkIGFzIGEgTWVkaWFTdHJlYW1UcmFjayB2aWEgUlRWSUV2ZW50LlRyYWNrU3RhcnRlZCxcbiAqICAgIHBsYXllZCB0aHJvdWdoIGEgaGlkZGVuIDxhdWRpbz4gZWxlbWVudC5cbiAqICAtIEFsbCBiaW5hcnkgcHJvdG9idWYgZnJhbWluZyAvIFJUVkkgcHJvdG9jb2wgaGFuZGxlZCBieVxuICogICAgQHBpcGVjYXQtYWkvY2xpZW50LWpzICsgQHBpcGVjYXQtYWkvd2Vic29ja2V0LXRyYW5zcG9ydC5cbiAqL1xuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIFZvaWNlQWdlbnRTZXJ2aWNlIGltcGxlbWVudHMgT25EZXN0cm95IHtcbiAgcHJpdmF0ZSBjYWxsU3RhdGVTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxDYWxsU3RhdGU+KCdpZGxlJyk7XG4gIHByaXZhdGUgc3RhdHVzVGV4dFN1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PHN0cmluZz4oJycpO1xuICBwcml2YXRlIGR1cmF0aW9uU3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8c3RyaW5nPignMDA6MDAnKTtcbiAgcHJpdmF0ZSBpc01pY011dGVkU3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oZmFsc2UpO1xuICBwcml2YXRlIGlzVXNlclNwZWFraW5nU3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oZmFsc2UpO1xuICBwcml2YXRlIGF1ZGlvTGV2ZWxzU3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8bnVtYmVyW10+KFtdKTtcbiAgcHJpdmF0ZSB1c2VyVHJhbnNjcmlwdFN1YmplY3QgPSBuZXcgU3ViamVjdDxUcmFuc2NyaXB0RGF0YT4oKTtcbiAgcHJpdmF0ZSBib3RUcmFuc2NyaXB0U3ViamVjdCA9IG5ldyBTdWJqZWN0PHN0cmluZz4oKTtcblxuICBwcml2YXRlIGNhbGxTdGFydFRpbWUgPSAwO1xuICBwcml2YXRlIGR1cmF0aW9uSW50ZXJ2YWw6IFJldHVyblR5cGU8dHlwZW9mIHNldEludGVydmFsPiB8IG51bGwgPSBudWxsO1xuXG4gIHByaXZhdGUgcGNDbGllbnQ6IFBpcGVjYXRDbGllbnQgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBib3RBdWRpb0VsZW1lbnQ6IEhUTUxBdWRpb0VsZW1lbnQgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBsaWZlY3ljbGVUb2tlbiA9IDA7XG5cbiAgcHJpdmF0ZSBzdWJzY3JpcHRpb25zID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuICBwcml2YXRlIGRlc3Ryb3kkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICBjYWxsU3RhdGUkOiBPYnNlcnZhYmxlPENhbGxTdGF0ZT4gPSB0aGlzLmNhbGxTdGF0ZVN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gIHN0YXR1c1RleHQkOiBPYnNlcnZhYmxlPHN0cmluZz4gPSB0aGlzLnN0YXR1c1RleHRTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICBkdXJhdGlvbiQ6IE9ic2VydmFibGU8c3RyaW5nPiA9IHRoaXMuZHVyYXRpb25TdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICBpc01pY011dGVkJDogT2JzZXJ2YWJsZTxib29sZWFuPiA9IHRoaXMuaXNNaWNNdXRlZFN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gIGlzVXNlclNwZWFraW5nJDogT2JzZXJ2YWJsZTxib29sZWFuPiA9IHRoaXMuaXNVc2VyU3BlYWtpbmdTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICBhdWRpb0xldmVscyQ6IE9ic2VydmFibGU8bnVtYmVyW10+ID0gdGhpcy5hdWRpb0xldmVsc1N1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gIHVzZXJUcmFuc2NyaXB0JDogT2JzZXJ2YWJsZTxUcmFuc2NyaXB0RGF0YT4gPSB0aGlzLnVzZXJUcmFuc2NyaXB0U3ViamVjdC5hc09ic2VydmFibGUoKTtcbiAgYm90VHJhbnNjcmlwdCQ6IE9ic2VydmFibGU8c3RyaW5nPiA9IHRoaXMuYm90VHJhbnNjcmlwdFN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBhdWRpb0FuYWx5emVyOiBBdWRpb0FuYWx5emVyU2VydmljZSxcbiAgICBwcml2YXRlIHBsYXRmb3JtVG9rZW5SZWZyZXNoOiBQbGF0Zm9ybVRva2VuUmVmcmVzaFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZSxcbiAgICAvKiogYE9iamVjdGAgbm90IGBvYmplY3RgIOKAlCBuZ2MgbWV0YWRhdGEgY29sbGVjdGlvbiByZWplY3RzIHRoZSBgb2JqZWN0YCB0eXBlIGluIERJIHBhcmFtcy4gKi9cbiAgICBASW5qZWN0KFBMQVRGT1JNX0lEKSBwcml2YXRlIHBsYXRmb3JtSWQ6IE9iamVjdCxcbiAgKSB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmFkZChcbiAgICAgIHRoaXMuYXVkaW9BbmFseXplci5hdWRpb0xldmVscyQuc3Vic2NyaWJlKChsZXZlbHMpID0+XG4gICAgICAgIHRoaXMuYXVkaW9MZXZlbHNTdWJqZWN0Lm5leHQobGV2ZWxzKSxcbiAgICAgICksXG4gICAgKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuZGVzdHJveSQubmV4dCgpO1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy51bnN1YnNjcmliZSgpO1xuICAgIHZvaWQgdGhpcy5kaXNjb25uZWN0KCk7XG4gIH1cblxuICAvKiogUmVzZXQgdG8gaWRsZSAoZS5nLiB3aGVuIG1vZGFsIHJlLW9wZW5zIHNvIHVzZXIgY2FuIGNsaWNrIFN0YXJ0IENhbGwpLiAqL1xuICByZXNldFRvSWRsZSgpOiB2b2lkIHtcbiAgICB2b2lkIHRoaXMucHJlcGFyZUZyZXNoU2Vzc2lvbigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhhcmQgcmVzZXQgdm9pY2Ugc2Vzc2lvbiBzbyBlYWNoIG1vZGFsIG9wZW4gc3RhcnRzIGZyb20gYSBjbGVhbiBzdGF0ZS5cbiAgICogQ2xvc2VzIGFueSBwcmV2aW91cyBjbGllbnQgYW5kIHByZXZlbnRzIHN0YWxlIGNhbGxiYWNrcyBmcm9tIG11dGF0aW5nIFVJIHN0YXRlLlxuICAgKi9cbiAgYXN5bmMgcHJlcGFyZUZyZXNoU2Vzc2lvbigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLmxpZmVjeWNsZVRva2VuICs9IDE7XG4gICAgdGhpcy5zdG9wRHVyYXRpb25UaW1lcigpO1xuICAgIHRoaXMuY2FsbFN0YXJ0VGltZSA9IDA7XG4gICAgdGhpcy5hdWRpb0FuYWx5emVyLnN0b3AoKTtcbiAgICB0aGlzLnN0b3BCb3RBdWRpbygpO1xuICAgIHRoaXMuaXNVc2VyU3BlYWtpbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICAgIHRoaXMuaXNNaWNNdXRlZFN1YmplY3QubmV4dChmYWxzZSk7XG4gICAgdGhpcy5kdXJhdGlvblN1YmplY3QubmV4dCgnMDA6MDAnKTtcbiAgICB0aGlzLnN0YXR1c1RleHRTdWJqZWN0Lm5leHQoJycpO1xuICAgIHRoaXMuY2FsbFN0YXRlU3ViamVjdC5uZXh0KCdpZGxlJyk7XG4gICAgYXdhaXQgdGhpcy5jbGVhbnVwUGlwZWNhdENsaWVudCgpO1xuICB9XG5cbiAgYXN5bmMgY29ubmVjdChcbiAgICBhcGlVcmw6IHN0cmluZyxcbiAgICB0b2tlbjogc3RyaW5nLFxuICAgIGJvdElkOiBzdHJpbmcsXG4gICAgY29udmVyc2F0aW9uSWQ6IHN0cmluZyxcbiAgICBhcGlLZXk6IHN0cmluZyxcbiAgICBldmVudFRva2VuOiBzdHJpbmcsXG4gICAgZXZlbnRJZDogc3RyaW5nLFxuICAgIGV2ZW50VXJsOiBzdHJpbmcsXG4gICAgZG9tYWluQXV0aG9yaXR5OiBzdHJpbmcsXG4gICAgdXNlcnNBcGlVcmw/OiBzdHJpbmcsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLmNhbGxTdGF0ZVN1YmplY3QudmFsdWUgIT09ICdpZGxlJykge1xuICAgICAgY29uc29sZS53YXJuKCdbSGl2ZUdwdCBWb2ljZV0gQ2FsbCBhbHJlYWR5IGluIHByb2dyZXNzJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgY29ubmVjdFRva2VuID0gKyt0aGlzLmxpZmVjeWNsZVRva2VuO1xuXG4gICAgdHJ5IHtcbiAgICAgIHRoaXMuY2FsbFN0YXRlU3ViamVjdC5uZXh0KCdjb25uZWN0aW5nJyk7XG4gICAgICB0aGlzLnN0YXR1c1RleHRTdWJqZWN0Lm5leHQoJ0Nvbm5lY3RpbmcuLi4nKTtcblxuICAgICAgbGV0IGFjY2Vzc1Rva2VuID0gdG9rZW47XG4gICAgICBpZiAodXNlcnNBcGlVcmwgJiYgaXNQbGF0Zm9ybUJyb3dzZXIodGhpcy5wbGF0Zm9ybUlkKSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IGVuc3VyZWQgPSBhd2FpdCB0aGlzLnBsYXRmb3JtVG9rZW5SZWZyZXNoXG4gICAgICAgICAgICAuZW5zdXJlVmFsaWRBY2Nlc3NUb2tlbih0b2tlbiwgdXNlcnNBcGlVcmwpXG4gICAgICAgICAgICAucGlwZSh0YWtlKDEpKVxuICAgICAgICAgICAgLnRvUHJvbWlzZSgpO1xuICAgICAgICAgIGlmIChlbnN1cmVkPy5hY2Nlc3NUb2tlbikgYWNjZXNzVG9rZW4gPSBlbnN1cmVkLmFjY2Vzc1Rva2VuO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKCdbSGl2ZUdwdCBWb2ljZV0gVG9rZW4gcmVmcmVzaCBmYWlsZWQnLCBlKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBiYXNlVXJsID0gYXBpVXJsLnJlcGxhY2UoL1xcLyQvLCAnJyk7XG5cbiAgICAgIGNvbnN0IHBjQ2xpZW50ID0gbmV3IFBpcGVjYXRDbGllbnQoe1xuICAgICAgICB0cmFuc3BvcnQ6IG5ldyBXZWJTb2NrZXRUcmFuc3BvcnQoKSxcbiAgICAgICAgZW5hYmxlTWljOiB0cnVlLFxuICAgICAgICBlbmFibGVDYW06IGZhbHNlLFxuICAgICAgICBjYWxsYmFja3M6IHtcbiAgICAgICAgICBvbkNvbm5lY3RlZDogKCkgPT5cbiAgICAgICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgICAgIGlmICghdGhpcy5pc0xpZmVjeWNsZUFjdGl2ZShjb25uZWN0VG9rZW4pKSByZXR1cm47XG4gICAgICAgICAgICAgIHRoaXMub25QaXBlY2F0Q29ubmVjdGVkKCk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICBvbkRpc2Nvbm5lY3RlZDogKCkgPT5cbiAgICAgICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgICAgIGlmICghdGhpcy5pc0xpZmVjeWNsZUFjdGl2ZShjb25uZWN0VG9rZW4pKSByZXR1cm47XG4gICAgICAgICAgICAgIHRoaXMub25QaXBlY2F0RGlzY29ubmVjdGVkKCk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICBvbkJvdFJlYWR5OiAoKSA9PlxuICAgICAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKCF0aGlzLmlzTGlmZWN5Y2xlQWN0aXZlKGNvbm5lY3RUb2tlbikpIHJldHVybjtcbiAgICAgICAgICAgICAgdGhpcy5vbkJvdFJlYWR5KCk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICBvblVzZXJUcmFuc2NyaXB0OiAoZGF0YSkgPT5cbiAgICAgICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PlxuICAgICAgICAgICAgICB0aGlzLmlzTGlmZWN5Y2xlQWN0aXZlKGNvbm5lY3RUb2tlbikgJiZcbiAgICAgICAgICAgICAgdGhpcy51c2VyVHJhbnNjcmlwdFN1YmplY3QubmV4dCh7IHRleHQ6IGRhdGEudGV4dCwgZmluYWw6ICEhZGF0YS5maW5hbCB9KSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgb25Cb3RUcmFuc2NyaXB0OiAoZGF0YSkgPT5cbiAgICAgICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgICAgIGlmICghdGhpcy5pc0xpZmVjeWNsZUFjdGl2ZShjb25uZWN0VG9rZW4pKSByZXR1cm47XG4gICAgICAgICAgICAgIHRoaXMuYm90VHJhbnNjcmlwdFN1YmplY3QubmV4dChkYXRhLnRleHQpO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgb25FcnJvcjogKGVycikgPT4ge1xuICAgICAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKCF0aGlzLmlzTGlmZWN5Y2xlQWN0aXZlKGNvbm5lY3RUb2tlbikpIHJldHVybjtcbiAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignW0hpdmVHcHQgVm9pY2VdIFBpcGVjYXRDbGllbnQgZXJyb3InLCBlcnIpO1xuICAgICAgICAgICAgICB0aGlzLmNhbGxTdGF0ZVN1YmplY3QubmV4dCgnZW5kZWQnKTtcbiAgICAgICAgICAgICAgdGhpcy5zdGF0dXNUZXh0U3ViamVjdC5uZXh0KCdDb25uZWN0aW9uIGZhaWxlZCcpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLnBjQ2xpZW50ID0gcGNDbGllbnQ7XG5cbiAgICAgIC8vIEJvdCBhdWRpbyBhcnJpdmVzIGFzIGEgTWVkaWFTdHJlYW1UcmFjayDigJQgd2lyZSB0byBhIGhpZGRlbiA8YXVkaW8+IGVsZW1lbnRcbiAgICAgIHBjQ2xpZW50Lm9uKFxuICAgICAgICBSVFZJRXZlbnQuVHJhY2tTdGFydGVkLFxuICAgICAgICAodHJhY2s6IE1lZGlhU3RyZWFtVHJhY2ssIHBhcnRpY2lwYW50PzogeyBsb2NhbD86IGJvb2xlYW4gfSkgPT4ge1xuICAgICAgICAgIGlmICghdGhpcy5pc0xpZmVjeWNsZUFjdGl2ZShjb25uZWN0VG9rZW4pKSByZXR1cm47XG4gICAgICAgICAgaWYgKCFwYXJ0aWNpcGFudD8ubG9jYWwgJiYgdHJhY2sua2luZCA9PT0gJ2F1ZGlvJykge1xuICAgICAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMuc2V0dXBCb3RBdWRpb1RyYWNrKHRyYWNrKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgLy8gU3BlYWtpbmcgc3RhdGUgY29tZXMgc3RyYWlnaHQgZnJvbSBSVFZJIGV2ZW50c1xuICAgICAgcGNDbGllbnQub24oUlRWSUV2ZW50LkJvdFN0YXJ0ZWRTcGVha2luZywgKCkgPT5cbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgICBpZiAoIXRoaXMuaXNMaWZlY3ljbGVBY3RpdmUoY29ubmVjdFRva2VuKSkgcmV0dXJuO1xuICAgICAgICAgIHRoaXMub25Cb3RTdGFydGVkU3BlYWtpbmcoKTtcbiAgICAgICAgfSksXG4gICAgICApO1xuICAgICAgcGNDbGllbnQub24oUlRWSUV2ZW50LkJvdFN0b3BwZWRTcGVha2luZywgKCkgPT5cbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgICBpZiAoIXRoaXMuaXNMaWZlY3ljbGVBY3RpdmUoY29ubmVjdFRva2VuKSkgcmV0dXJuO1xuICAgICAgICAgIHRoaXMub25Cb3RTdG9wcGVkU3BlYWtpbmcoKTtcbiAgICAgICAgfSksXG4gICAgICApO1xuICAgICAgcGNDbGllbnQub24oUlRWSUV2ZW50LlVzZXJTdGFydGVkU3BlYWtpbmcsICgpID0+XG4gICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgaWYgKCF0aGlzLmlzTGlmZWN5Y2xlQWN0aXZlKGNvbm5lY3RUb2tlbikpIHJldHVybjtcbiAgICAgICAgICB0aGlzLmlzVXNlclNwZWFraW5nU3ViamVjdC5uZXh0KHRydWUpO1xuICAgICAgICAgIHRoaXMuY2FsbFN0YXRlU3ViamVjdC5uZXh0KCdsaXN0ZW5pbmcnKTtcbiAgICAgICAgICB0aGlzLnN0YXR1c1RleHRTdWJqZWN0Lm5leHQoJ0xpc3RlbmluZy4uLicpO1xuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgICBwY0NsaWVudC5vbihSVFZJRXZlbnQuVXNlclN0b3BwZWRTcGVha2luZywgKCkgPT5cbiAgICAgICAgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHtcbiAgICAgICAgICBpZiAoIXRoaXMuaXNMaWZlY3ljbGVBY3RpdmUoY29ubmVjdFRva2VuKSkgcmV0dXJuO1xuICAgICAgICAgIHRoaXMuaXNVc2VyU3BlYWtpbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICAgICAgICAgIGlmICh0aGlzLmNhbGxTdGF0ZVN1YmplY3QudmFsdWUgPT09ICdsaXN0ZW5pbmcnKSB7XG4gICAgICAgICAgICAvLyBCcmllZiAnUHJvY2Vzc2luZy4uLicgd2hpbGUgd2Ugd2FpdCBmb3IgdGhlIGJvdCB0byByZXNwb25kLlxuICAgICAgICAgICAgdGhpcy5jYWxsU3RhdGVTdWJqZWN0Lm5leHQoJ2Nvbm5lY3RlZCcpO1xuICAgICAgICAgICAgdGhpcy5zdGF0dXNUZXh0U3ViamVjdC5uZXh0KCdQcm9jZXNzaW5nLi4uJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIC8vIEFjcXVpcmUgbWljICh0cmlnZ2VycyBicm93c2VyIHBlcm1pc3Npb24gcHJvbXB0KVxuICAgICAgYXdhaXQgcGNDbGllbnQuaW5pdERldmljZXMoKTtcblxuICAgICAgLy8gQnVpbGQgaGVhZGVycyB1c2luZyB0aGUgYnJvd3NlciBIZWFkZXJzIEFQSSAocmVxdWlyZWQgYnkgcGlwZWNhdCdzIEFQSVJlcXVlc3QgdHlwZSlcbiAgICAgIGNvbnN0IHJlcXVlc3RIZWFkZXJzID0gbmV3IEhlYWRlcnMoKTtcbiAgICAgIHJlcXVlc3RIZWFkZXJzLmFwcGVuZCgnQXV0aG9yaXphdGlvbicsIGBCZWFyZXIgJHthY2Nlc3NUb2tlbn1gKTtcbiAgICAgIHJlcXVlc3RIZWFkZXJzLmFwcGVuZCgneC1hcGkta2V5JywgYXBpS2V5KTtcbiAgICAgIHJlcXVlc3RIZWFkZXJzLmFwcGVuZCgnaGl2ZS1ib3QtaWQnLCBib3RJZCk7XG4gICAgICByZXF1ZXN0SGVhZGVycy5hcHBlbmQoJ2RvbWFpbi1hdXRob3JpdHknLCBkb21haW5BdXRob3JpdHkpO1xuICAgICAgcmVxdWVzdEhlYWRlcnMuYXBwZW5kKCdldmVudFVybCcsIGV2ZW50VXJsKTtcbiAgICAgIHJlcXVlc3RIZWFkZXJzLmFwcGVuZCgnZXZlbnRJZCcsIGV2ZW50SWQpO1xuICAgICAgcmVxdWVzdEhlYWRlcnMuYXBwZW5kKCdldmVudFRva2VuJywgZXZlbnRUb2tlbik7XG4gICAgICByZXF1ZXN0SGVhZGVycy5hcHBlbmQoJ25ncm9rLXNraXAtYnJvd3Nlci13YXJuaW5nJywgJ3RydWUnKTtcblxuICAgICAgLy8gUE9TVCB0byAvYWkvYXNrLXZvaWNlLXNvY2tldCDihpIgcmVjZWl2ZXMgeyB3c191cmwgfSDihpIgV2ViU29ja2V0VHJhbnNwb3J0IGNvbm5lY3RzXG4gICAgICBhd2FpdCBwY0NsaWVudC5zdGFydEJvdEFuZENvbm5lY3Qoe1xuICAgICAgICBlbmRwb2ludDogYCR7YmFzZVVybH0vYWkvYXNrLXZvaWNlLXNvY2tldGAsXG4gICAgICAgIGhlYWRlcnM6IHJlcXVlc3RIZWFkZXJzLFxuICAgICAgICByZXF1ZXN0RGF0YToge1xuICAgICAgICAgIGJvdF9pZDogYm90SWQsXG4gICAgICAgICAgY29udmVyc2F0aW9uX2lkOiBjb252ZXJzYXRpb25JZCxcbiAgICAgICAgICB2b2ljZTogJ2FsbG95JyxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoIXRoaXMuaXNMaWZlY3ljbGVBY3RpdmUoY29ubmVjdFRva2VuKSkgcmV0dXJuO1xuICAgICAgY29uc29sZS5lcnJvcignW0hpdmVHcHQgVm9pY2VdIGNvbm5lY3QgZmFpbGVkJywgZXJyb3IpO1xuICAgICAgdGhpcy5jYWxsU3RhdGVTdWJqZWN0Lm5leHQoJ2VuZGVkJyk7XG4gICAgICBhd2FpdCB0aGlzLmNsZWFudXBQaXBlY2F0Q2xpZW50KCk7XG4gICAgICB0aGlzLnN0YXR1c1RleHRTdWJqZWN0Lm5leHQoJ0Nvbm5lY3Rpb24gZmFpbGVkJyk7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG9uUGlwZWNhdENvbm5lY3RlZCgpOiB2b2lkIHtcbiAgICAvLyBTdGFydCB0aGUgZHVyYXRpb24gdGltZXIgZnJvbSB0aGUgbW9tZW50IHRoZSBzZXNzaW9uIGlzIGxpdmUuXG4gICAgdGhpcy5jYWxsU3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICB0aGlzLnN0YXJ0RHVyYXRpb25UaW1lcigpO1xuICAgIHRoaXMuY2FsbFN0YXRlU3ViamVjdC5uZXh0KCdjb25uZWN0ZWQnKTtcbiAgICB0aGlzLnN0YXR1c1RleHRTdWJqZWN0Lm5leHQoJ0Nvbm5lY3RlZCcpO1xuICAgIC8vIFByZXNlcnZlIGFueSBtdXRlIGFjdGlvbiB0aGUgdXNlciBtYWRlIGR1cmluZyBcImNvbm5lY3RpbmdcIi5cbiAgICBjb25zdCBzaG91bGRCZU11dGVkID0gdGhpcy5pc01pY011dGVkU3ViamVjdC52YWx1ZTtcbiAgICB0aGlzLnBjQ2xpZW50Py5lbmFibGVNaWMoIXNob3VsZEJlTXV0ZWQpO1xuICAgIHRoaXMuaXNNaWNNdXRlZFN1YmplY3QubmV4dChzaG91bGRCZU11dGVkKTtcbiAgICB0aGlzLnN0YXJ0TG9jYWxNaWNBbmFseXplcigpO1xuICB9XG5cbiAgcHJpdmF0ZSBvblBpcGVjYXREaXNjb25uZWN0ZWQoKTogdm9pZCB7XG4gICAgdGhpcy5zdG9wRHVyYXRpb25UaW1lcigpO1xuICAgIHRoaXMuY2FsbFN0YXJ0VGltZSA9IDA7XG4gICAgdGhpcy5hdWRpb0FuYWx5emVyLnN0b3AoKTtcbiAgICB0aGlzLnN0b3BCb3RBdWRpbygpO1xuICAgIHRoaXMuY2FsbFN0YXRlU3ViamVjdC5uZXh0KCdlbmRlZCcpO1xuICAgIHRoaXMuc3RhdHVzVGV4dFN1YmplY3QubmV4dCgnQ2FsbCBFbmRlZCcpO1xuICB9XG5cbiAgcHJpdmF0ZSBvbkJvdFJlYWR5KCk6IHZvaWQge1xuICAgIC8vIFJldHJ5IHRyYWNrIHdpcmluZyBpbiBjYXNlIHRyYWNrcyB3ZXJlbid0IHJlYWR5IGF0IG9uQ29ubmVjdGVkLlxuICAgIHRoaXMuc3RhcnRMb2NhbE1pY0FuYWx5emVyKCk7XG4gICAgY29uc3QgYm90VHJhY2sgPSAodGhpcy5wY0NsaWVudD8udHJhY2tzKCkgYXMgeyBib3Q/OiB7IGF1ZGlvPzogTWVkaWFTdHJlYW1UcmFjayB9IH0pXG4gICAgICA/LmJvdD8uYXVkaW87XG4gICAgaWYgKGJvdFRyYWNrKSB0aGlzLnNldHVwQm90QXVkaW9UcmFjayhib3RUcmFjayk7XG4gICAgLy8gQm90IGlzIGluaXRpYWxpc2VkIOKAlCBzaWduYWwgdGhhdCB3ZSdyZSBub3cgd2FpdGluZyBmb3IgdXNlciBpbnB1dC5cbiAgICB0aGlzLnN0YXR1c1RleHRTdWJqZWN0Lm5leHQoJ0xpc3RlbmluZy4uLicpO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGFydExvY2FsTWljQW5hbHl6ZXIoKTogdm9pZCB7XG4gICAgY29uc3QgbG9jYWxUcmFjayA9ICh0aGlzLnBjQ2xpZW50Py50cmFja3MoKSBhcyB7IGxvY2FsPzogeyBhdWRpbz86IE1lZGlhU3RyZWFtVHJhY2sgfSB9KVxuICAgICAgPy5sb2NhbD8uYXVkaW87XG4gICAgaWYgKGxvY2FsVHJhY2spIHtcbiAgICAgIHRoaXMuYXVkaW9BbmFseXplci5zdGFydChuZXcgTWVkaWFTdHJlYW0oW2xvY2FsVHJhY2tdKSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBvbkJvdFN0YXJ0ZWRTcGVha2luZygpOiB2b2lkIHtcbiAgICB0aGlzLmNhbGxTdGF0ZVN1YmplY3QubmV4dCgndGFsa2luZycpO1xuICAgIHRoaXMuc3RhdHVzVGV4dFN1YmplY3QubmV4dCgnVGFsa2luZy4uLicpO1xuICAgIC8vIE1hcmsgdXNlciBhcyBubyBsb25nZXIgc3BlYWtpbmcgd2hlbiBib3QgdGFrZXMgdGhlIHR1cm4uXG4gICAgdGhpcy5pc1VzZXJTcGVha2luZ1N1YmplY3QubmV4dChmYWxzZSk7XG4gIH1cblxuICBwcml2YXRlIG9uQm90U3RvcHBlZFNwZWFraW5nKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmNhbGxTdGF0ZVN1YmplY3QudmFsdWUgPT09ICd0YWxraW5nJykge1xuICAgICAgdGhpcy5jYWxsU3RhdGVTdWJqZWN0Lm5leHQoJ2Nvbm5lY3RlZCcpO1xuICAgICAgdGhpcy5zdGF0dXNUZXh0U3ViamVjdC5uZXh0KCdMaXN0ZW5pbmcuLi4nKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNldHVwQm90QXVkaW9UcmFjayh0cmFjazogTWVkaWFTdHJlYW1UcmFjayk6IHZvaWQge1xuICAgIGlmICghdGhpcy5ib3RBdWRpb0VsZW1lbnQpIHtcbiAgICAgIHRoaXMuYm90QXVkaW9FbGVtZW50ID0gbmV3IEF1ZGlvKCk7XG4gICAgICB0aGlzLmJvdEF1ZGlvRWxlbWVudC5hdXRvcGxheSA9IHRydWU7XG4gICAgfVxuICAgIGNvbnN0IGV4aXN0aW5nID0gKHRoaXMuYm90QXVkaW9FbGVtZW50LnNyY09iamVjdCBhcyBNZWRpYVN0cmVhbSB8IG51bGwpXG4gICAgICA/LmdldEF1ZGlvVHJhY2tzKClbMF07XG4gICAgaWYgKGV4aXN0aW5nPy5pZCA9PT0gdHJhY2suaWQpIHJldHVybjtcblxuICAgIHRoaXMuYm90QXVkaW9FbGVtZW50LnNyY09iamVjdCA9IG5ldyBNZWRpYVN0cmVhbShbdHJhY2tdKTtcbiAgICB0aGlzLmJvdEF1ZGlvRWxlbWVudC5wbGF5KCkuY2F0Y2goKGVycikgPT5cbiAgICAgIGNvbnNvbGUud2FybignW0hpdmVHcHQgVm9pY2VdIEJvdCBhdWRpbyBwbGF5IGJsb2NrZWQnLCBlcnIpLFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHN0b3BCb3RBdWRpbygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5ib3RBdWRpb0VsZW1lbnQpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHRoaXMuYm90QXVkaW9FbGVtZW50LnBhdXNlKCk7XG4gICAgICAgICh0aGlzLmJvdEF1ZGlvRWxlbWVudC5zcmNPYmplY3QgYXMgTWVkaWFTdHJlYW0gfCBudWxsKVxuICAgICAgICAgID8uZ2V0QXVkaW9UcmFja3MoKVxuICAgICAgICAgIC5mb3JFYWNoKCh0KSA9PiB0LnN0b3AoKSk7XG4gICAgICAgIHRoaXMuYm90QXVkaW9FbGVtZW50LnNyY09iamVjdCA9IG51bGw7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gaWdub3JlXG4gICAgICB9XG4gICAgICB0aGlzLmJvdEF1ZGlvRWxlbWVudCA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZGlzY29ubmVjdCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLmxpZmVjeWNsZVRva2VuICs9IDE7XG4gICAgdGhpcy5zdG9wRHVyYXRpb25UaW1lcigpO1xuICAgIHRoaXMuY2FsbFN0YXJ0VGltZSA9IDA7XG4gICAgdGhpcy5hdWRpb0FuYWx5emVyLnN0b3AoKTtcbiAgICB0aGlzLnN0b3BCb3RBdWRpbygpO1xuICAgIGF3YWl0IHRoaXMuY2xlYW51cFBpcGVjYXRDbGllbnQoKTtcbiAgICB0aGlzLmNhbGxTdGF0ZVN1YmplY3QubmV4dCgnZW5kZWQnKTtcbiAgICB0aGlzLnN0YXR1c1RleHRTdWJqZWN0Lm5leHQoJ0NhbGwgRW5kZWQnKTtcbiAgfVxuXG4gIHByaXZhdGUgaXNMaWZlY3ljbGVBY3RpdmUodG9rZW46IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0b2tlbiA9PT0gdGhpcy5saWZlY3ljbGVUb2tlbjtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgY2xlYW51cFBpcGVjYXRDbGllbnQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMucGNDbGllbnQpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRoaXMucGNDbGllbnQuZGlzY29ubmVjdCgpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIGlnbm9yZVxuICAgICAgfVxuICAgICAgdGhpcy5wY0NsaWVudCA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgdG9nZ2xlTWljKCk6IHZvaWQge1xuICAgIGNvbnN0IG5leHRNdXRlZCA9ICF0aGlzLmlzTWljTXV0ZWRTdWJqZWN0LnZhbHVlO1xuICAgIC8vIFJlZmxlY3QgdGhlIHVzZXIncyBpbnRlbnQgaW1tZWRpYXRlbHksIGV2ZW4gaWYgY29ubmVjdCBpcyBzdGlsbCBpbiBwcm9ncmVzcy5cbiAgICB0aGlzLmlzTWljTXV0ZWRTdWJqZWN0Lm5leHQobmV4dE11dGVkKTtcbiAgICBpZiAodGhpcy5wY0NsaWVudCkge1xuICAgICAgdGhpcy5wY0NsaWVudC5lbmFibGVNaWMoIW5leHRNdXRlZCk7XG4gICAgfVxuICAgIGlmIChuZXh0TXV0ZWQpIHRoaXMuaXNVc2VyU3BlYWtpbmdTdWJqZWN0Lm5leHQoZmFsc2UpO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGFydER1cmF0aW9uVGltZXIoKTogdm9pZCB7XG4gICAgY29uc3QgdGljayA9ICgpID0+IHtcbiAgICAgIGlmICh0aGlzLmNhbGxTdGFydFRpbWUgPiAwKSB7XG4gICAgICAgIGNvbnN0IGVsYXBzZWQgPSBNYXRoLmZsb29yKChEYXRlLm5vdygpIC0gdGhpcy5jYWxsU3RhcnRUaW1lKSAvIDEwMDApO1xuICAgICAgICBjb25zdCBtID0gTWF0aC5mbG9vcihlbGFwc2VkIC8gNjApO1xuICAgICAgICBjb25zdCBzID0gZWxhcHNlZCAlIDYwO1xuICAgICAgICB0aGlzLmR1cmF0aW9uU3ViamVjdC5uZXh0KGAke219OiR7U3RyaW5nKHMpLnBhZFN0YXJ0KDIsICcwJyl9YCk7XG4gICAgICB9XG4gICAgfTtcbiAgICB0aWNrKCk7XG4gICAgdGhpcy5kdXJhdGlvbkludGVydmFsID0gc2V0SW50ZXJ2YWwodGljaywgMTAwMCk7XG4gIH1cblxuICBwcml2YXRlIHN0b3BEdXJhdGlvblRpbWVyKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmR1cmF0aW9uSW50ZXJ2YWwpIHtcbiAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5kdXJhdGlvbkludGVydmFsKTtcbiAgICAgIHRoaXMuZHVyYXRpb25JbnRlcnZhbCA9IG51bGw7XG4gICAgfVxuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { NgModule } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { VoiceAgentModalComponent } from './components/voice-agent-modal/voice-agent-modal.component';
|
|
4
|
+
import { VoiceAgentService } from './services/voice-agent.service';
|
|
5
|
+
import { AudioAnalyzerService } from './services/audio-analyzer.service';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
/**
|
|
8
|
+
* Voice agent module. Uses @pipecat-ai/client-js + @pipecat-ai/websocket-transport
|
|
9
|
+
* (peer dependencies) for WebSocket transport, RTVI protocol, and audio.
|
|
10
|
+
*/
|
|
11
|
+
export class VoiceAgentModule {
|
|
12
|
+
}
|
|
13
|
+
VoiceAgentModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: VoiceAgentModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
14
|
+
VoiceAgentModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: VoiceAgentModule, declarations: [VoiceAgentModalComponent], imports: [CommonModule], exports: [VoiceAgentModalComponent] });
|
|
15
|
+
VoiceAgentModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: VoiceAgentModule, providers: [
|
|
16
|
+
VoiceAgentService,
|
|
17
|
+
AudioAnalyzerService,
|
|
18
|
+
], imports: [CommonModule] });
|
|
19
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: VoiceAgentModule, decorators: [{
|
|
20
|
+
type: NgModule,
|
|
21
|
+
args: [{
|
|
22
|
+
declarations: [
|
|
23
|
+
VoiceAgentModalComponent
|
|
24
|
+
],
|
|
25
|
+
imports: [
|
|
26
|
+
CommonModule
|
|
27
|
+
],
|
|
28
|
+
providers: [
|
|
29
|
+
VoiceAgentService,
|
|
30
|
+
AudioAnalyzerService,
|
|
31
|
+
],
|
|
32
|
+
exports: [
|
|
33
|
+
VoiceAgentModalComponent
|
|
34
|
+
]
|
|
35
|
+
}]
|
|
36
|
+
}] });
|
|
37
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidm9pY2UtYWdlbnQubW9kdWxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvaGl2ZWdwdC9ldmVudHNncHQtYW5ndWxhci9zcmMvbGliL2NvbXBvbmVudHMvdm9pY2UtYWdlbnQvdm9pY2UtYWdlbnQubW9kdWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDekMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLDREQUE0RCxDQUFDO0FBQ3RHLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ25FLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLG1DQUFtQyxDQUFDOztBQUV6RTs7O0dBR0c7QUFnQkgsTUFBTSxPQUFPLGdCQUFnQjs7OEdBQWhCLGdCQUFnQjsrR0FBaEIsZ0JBQWdCLGlCQWJ6Qix3QkFBd0IsYUFHeEIsWUFBWSxhQU9aLHdCQUF3QjsrR0FHZixnQkFBZ0IsYUFSaEI7UUFDVCxpQkFBaUI7UUFDakIsb0JBQW9CO0tBQ3JCLFlBTEMsWUFBWTs0RkFVSCxnQkFBZ0I7a0JBZjVCLFFBQVE7bUJBQUM7b0JBQ1IsWUFBWSxFQUFFO3dCQUNaLHdCQUF3QjtxQkFDekI7b0JBQ0QsT0FBTyxFQUFFO3dCQUNQLFlBQVk7cUJBQ2I7b0JBQ0QsU0FBUyxFQUFFO3dCQUNULGlCQUFpQjt3QkFDakIsb0JBQW9CO3FCQUNyQjtvQkFDRCxPQUFPLEVBQUU7d0JBQ1Asd0JBQXdCO3FCQUN6QjtpQkFDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE5nTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgVm9pY2VBZ2VudE1vZGFsQ29tcG9uZW50IH0gZnJvbSAnLi9jb21wb25lbnRzL3ZvaWNlLWFnZW50LW1vZGFsL3ZvaWNlLWFnZW50LW1vZGFsLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBWb2ljZUFnZW50U2VydmljZSB9IGZyb20gJy4vc2VydmljZXMvdm9pY2UtYWdlbnQuc2VydmljZSc7XG5pbXBvcnQgeyBBdWRpb0FuYWx5emVyU2VydmljZSB9IGZyb20gJy4vc2VydmljZXMvYXVkaW8tYW5hbHl6ZXIuc2VydmljZSc7XG5cbi8qKlxuICogVm9pY2UgYWdlbnQgbW9kdWxlLiBVc2VzIEBwaXBlY2F0LWFpL2NsaWVudC1qcyArIEBwaXBlY2F0LWFpL3dlYnNvY2tldC10cmFuc3BvcnRcbiAqIChwZWVyIGRlcGVuZGVuY2llcykgZm9yIFdlYlNvY2tldCB0cmFuc3BvcnQsIFJUVkkgcHJvdG9jb2wsIGFuZCBhdWRpby5cbiAqL1xuQE5nTW9kdWxlKHtcbiAgZGVjbGFyYXRpb25zOiBbXG4gICAgVm9pY2VBZ2VudE1vZGFsQ29tcG9uZW50XG4gIF0sXG4gIGltcG9ydHM6IFtcbiAgICBDb21tb25Nb2R1bGVcbiAgXSxcbiAgcHJvdmlkZXJzOiBbXG4gICAgVm9pY2VBZ2VudFNlcnZpY2UsXG4gICAgQXVkaW9BbmFseXplclNlcnZpY2UsXG4gIF0sXG4gIGV4cG9ydHM6IFtcbiAgICBWb2ljZUFnZW50TW9kYWxDb21wb25lbnRcbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBWb2ljZUFnZW50TW9kdWxlIHsgfVxuIl19
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { InjectionToken } from '@angular/core';
|
|
2
|
+
export const VOICE_MODAL_CONFIG = new InjectionToken('VOICE_MODAL_CONFIG');
|
|
3
|
+
export const VOICE_MODAL_CLOSE_CALLBACK = new InjectionToken('VOICE_MODAL_CLOSE_CALLBACK');
|
|
4
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidm9pY2UtbW9kYWwtdG9rZW5zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvaGl2ZWdwdC9ldmVudHNncHQtYW5ndWxhci9zcmMvbGliL2NvbXBvbmVudHMvdm9pY2UtYWdlbnQvdm9pY2UtbW9kYWwtdG9rZW5zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFvQi9DLE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLElBQUksY0FBYyxDQUFtQixvQkFBb0IsQ0FBQyxDQUFDO0FBQzdGLE1BQU0sQ0FBQyxNQUFNLDBCQUEwQixHQUFHLElBQUksY0FBYyxDQUFhLDRCQUE0QixDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3Rpb25Ub2tlbiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFZvaWNlTW9kYWxDb25maWcge1xuICBhcGlVcmw6IHN0cmluZztcbiAgdG9rZW46IHN0cmluZztcbiAgYm90SWQ6IHN0cmluZztcbiAgY29udmVyc2F0aW9uSWQ6IHN0cmluZztcbiAgYXBpS2V5OiBzdHJpbmc7XG4gIGV2ZW50VG9rZW46IHN0cmluZztcbiAgLyoqIEV2ZW50IHNjb3BlIGlkIChzYW1lIGFzIGhvc3QgYGV2ZW50SWRgIC8gQVBJIGBldmVudHMvOmV2ZW50SWQvLi4uYCkuICovXG4gIGV2ZW50SWQ6IHN0cmluZztcbiAgZXZlbnRVcmw6IHN0cmluZztcbiAgZG9tYWluQXV0aG9yaXR5OiBzdHJpbmc7XG4gIGFnZW50TmFtZTogc3RyaW5nO1xuICBhZ2VudFJvbGU6IHN0cmluZztcbiAgYWdlbnRBdmF0YXI/OiBzdHJpbmc7XG4gIC8qKiBTYW1lIGJhc2UgYXMgaG9zdCBgVVNFUlNfQVBJYCAoZS5nLiBgaHR0cHM6Ly9lcy11c2VyLnNvY2lhbDI3LmNvbS9hcGlgKSBmb3IgcHJvYWN0aXZlIHRva2VuIHJlZnJlc2guICovXG4gIHVzZXJzQXBpVXJsPzogc3RyaW5nO1xufVxuXG5leHBvcnQgY29uc3QgVk9JQ0VfTU9EQUxfQ09ORklHID0gbmV3IEluamVjdGlvblRva2VuPFZvaWNlTW9kYWxDb25maWc+KCdWT0lDRV9NT0RBTF9DT05GSUcnKTtcbmV4cG9ydCBjb25zdCBWT0lDRV9NT0RBTF9DTE9TRV9DQUxMQkFDSyA9IG5ldyBJbmplY3Rpb25Ub2tlbjwoKSA9PiB2b2lkPignVk9JQ0VfTU9EQUxfQ0xPU0VfQ0FMTEJBQ0snKTtcbiJdfQ==
|