@hivegpt/hiveai-angular 0.0.416 → 0.0.417

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.
@@ -26,6 +26,8 @@ export class VoiceAgentModalComponent {
26
26
  this.isUserSpeaking = false;
27
27
  this.audioLevels = [];
28
28
  this.isSpeaking = false;
29
+ /** Once user or bot has spoken, show "Ready" instead of "Connected" when idle in call. */
30
+ this.hasLeftConnectedOnce = false;
29
31
  this.subscriptions = [];
30
32
  this.isConnecting = false;
31
33
  }
@@ -51,6 +53,12 @@ export class VoiceAgentModalComponent {
51
53
  this.subscriptions.push(this.voiceAgentService.callState$.subscribe(state => {
52
54
  this.callState = state;
53
55
  this.isSpeaking = state === 'talking';
56
+ if (state === 'listening' || state === 'talking') {
57
+ this.hasLeftConnectedOnce = true;
58
+ }
59
+ if (state === 'idle' || state === 'ended') {
60
+ this.hasLeftConnectedOnce = false;
61
+ }
54
62
  }));
55
63
  this.subscriptions.push(this.voiceAgentService.statusText$.subscribe(text => {
56
64
  this.statusText = text;
@@ -103,7 +111,7 @@ export class VoiceAgentModalComponent {
103
111
  const n = Math.min(100, Math.max(0, level !== null && level !== void 0 ? level : 0));
104
112
  return 3 + (n / 100) * 17;
105
113
  }
106
- /** Status label for active call: Talking..., Listening, Connected, or Connecting... */
114
+ /** Status label for active call. "Connected" only once; then "Ready" when idle in call. */
107
115
  get statusLabel() {
108
116
  if (this.callState === 'connecting')
109
117
  return this.statusText || 'Connecting...';
@@ -111,8 +119,9 @@ export class VoiceAgentModalComponent {
111
119
  return 'Talking...';
112
120
  if (this.callState === 'listening')
113
121
  return 'Listening';
114
- if (this.callState === 'connected')
115
- return 'Connected';
122
+ if (this.callState === 'connected') {
123
+ return this.hasLeftConnectedOnce ? 'Listening' : 'Connected';
124
+ }
116
125
  return this.statusText || '';
117
126
  }
118
127
  /** Call Again: reset to idle then start a new call. */
@@ -124,6 +133,10 @@ export class VoiceAgentModalComponent {
124
133
  backToChat() {
125
134
  this.endCall();
126
135
  }
136
+ /** End call but keep modal open to show Call Ended + Call Again / Back to Chat. */
137
+ hangUp() {
138
+ this.disconnect();
139
+ }
127
140
  endCall() {
128
141
  var _a;
129
142
  this.disconnect();
@@ -134,7 +147,7 @@ export class VoiceAgentModalComponent {
134
147
  VoiceAgentModalComponent.decorators = [
135
148
  { type: Component, args: [{
136
149
  selector: 'hivegpt-voice-agent-modal',
137
- template: "<div class=\"voice-agent-modal-overlay\" (click)=\"endCall()\">\n <div\n class=\"voice-container voice-agent-modal\"\n (click)=\"$event.stopPropagation()\"\n >\n <!-- Header -->\n <div class=\"header\">\n <div class=\"header-left\">\n <div class=\"header-icon\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M12 1C8.13 1 5 4.13 5 8V14C5 17.87 8.13 21 12 21C15.87 21 19 17.87 19 14V8C19 4.13 15.87 1 12 1Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M12 23C10.34 23 9 21.66 9 20H15C15 21.66 13.66 23 12 23Z\"\n fill=\"currentColor\"\n />\n </svg>\n </div>\n <span class=\"header-title\">Voice</span>\n </div>\n <button\n class=\"close-button\"\n (click)=\"endCall()\"\n type=\"button\"\n aria-label=\"Close\"\n >\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M18 6L6 18M6 6L18 18\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n </div>\n\n <!-- Avatar Section with glow -->\n <div class=\"avatar-section\">\n <div class=\"avatar-glow\"></div>\n <div class=\"avatar-wrapper\" [class.speaking]=\"isSpeaking\">\n <img class=\"avatar-image\" [src]=\"displayAvatarUrl\" alt=\"Nia\" />\n </div>\n </div>\n\n <!-- Agent Info: Nia + Collaboration Manager AI Agent Specialist -->\n <div class=\"agent-info\">\n <div class=\"agent-name\">\n Nia\n <span class=\"ai-badge\">AI</span>\n </div>\n <p class=\"agent-role\">Collaboration Manager AI Agent Specialist</p>\n </div>\n\n <!-- Start Call (when idle only) -->\n <div *ngIf=\"callState === 'idle'\" class=\"start-call-section\">\n <p *ngIf=\"statusText === 'Connection failed'\" class=\"error-message\">\n {{ statusText }}\n </p>\n <button\n class=\"start-call-button\"\n type=\"button\"\n [disabled]=\"isConnecting\"\n (click)=\"startCall()\"\n >\n <span *ngIf=\"isConnecting\">Connecting...</span>\n <span *ngIf=\"!isConnecting && statusText === 'Connection failed'\"\n >Retry</span\n >\n <span *ngIf=\"!isConnecting && statusText !== 'Connection failed'\"\n >Start Call</span\n >\n </button>\n </div>\n\n <!-- Call Ended: status + Call Again / Back to Chat -->\n <div *ngIf=\"callState === 'ended'\" class=\"call-ended-section\">\n <p class=\"call-ended-status\">\n <span class=\"status-text\">Call Ended</span>\n <span class=\"status-timer\">{{ duration }}</span>\n </p>\n <div class=\"call-ended-controls\">\n <button\n class=\"action-btn\"\n type=\"button\"\n (click)=\"callAgain()\"\n title=\"Call Again\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\" />\n <path d=\"M3 3v5h5\" />\n </svg>\n Call Again\n </button>\n <button\n class=\"action-btn\"\n type=\"button\"\n (click)=\"backToChat()\"\n title=\"Back to Chat\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </svg>\n Back to Chat\n </button>\n </div>\n </div>\n\n <!-- Status (when connecting or in-call: Talking... / Listening / Connected + timer) -->\n <div\n class=\"status-indicator status-inline\"\n *ngIf=\"callState !== 'idle' && callState !== 'ended'\"\n >\n <div *ngIf=\"callState === 'connecting'\" class=\"status-connecting\">\n <svg\n class=\"spinner\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-dasharray=\"31.416\"\n stroke-dashoffset=\"31.416\"\n >\n <animate\n attributeName=\"stroke-dasharray\"\n dur=\"2s\"\n values=\"0 31.416;15.708 15.708;0 31.416;0 31.416\"\n repeatCount=\"indefinite\"\n />\n <animate\n attributeName=\"stroke-dashoffset\"\n dur=\"2s\"\n values=\"0;-15.708;-31.416;-31.416\"\n repeatCount=\"indefinite\"\n />\n </circle>\n </svg>\n <span class=\"status-text\">{{ statusText }}</span>\n </div>\n <div\n *ngIf=\"callState !== 'connecting'\"\n class=\"status-connected status-inline-row\"\n >\n <span class=\"status-text\">{{ statusLabel }}</span>\n <span class=\"status-timer\">{{ duration }}</span>\n </div>\n </div>\n\n <!-- Waveform -->\n <div\n *ngIf=\"\n callState === 'connected' ||\n callState === 'listening' ||\n callState === 'talking'\n \"\n class=\"waveform-container\"\n >\n <div class=\"waveform-bars\">\n <div\n *ngFor=\"let level of audioLevels; let i = index\"\n class=\"waveform-bar\"\n [style.height.px]=\"getWaveformHeight(level)\"\n ></div>\n </div>\n </div>\n\n <!-- Call Controls (when connected) -->\n <div\n class=\"controls\"\n *ngIf=\"\n callState === 'connected' ||\n callState === 'listening' ||\n callState === 'talking'\n \"\n >\n <div\n style=\"\n display: flex;\n align-items: center;\n gap: 2px;\n flex-direction: column;\n \"\n >\n <button\n class=\"control-btn mic-btn\"\n [class.muted]=\"isMicMuted\"\n (click)=\"toggleMic()\"\n type=\"button\"\n [title]=\"isMicMuted ? 'Unmute' : 'Mute'\"\n >\n <!-- Microphone icon (unmuted) -->\n <svg\n *ngIf=\"!isMicMuted\"\n width=\"24\"\n height=\"24\"\n viewBox=\"-5 0 32 32\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"currentColor\"\n >\n <g transform=\"translate(-105, -307)\">\n <path\n d=\"M111,314 C111,311.238 113.239,309 116,309 C118.761,309 121,311.238 121,314 L121,324 C121,326.762 118.761,329 116,329 C113.239,329 111,326.762 111,324 L111,314 L111,314 Z M116,331 C119.866,331 123,327.866 123,324 L123,314 C123,310.134 119.866,307 116,307 C112.134,307 109,310.134 109,314 L109,324 C109,327.866 112.134,331 116,331 L116,331 Z M127,326 L125,326 C124.089,330.007 120.282,333 116,333 C111.718,333 107.911,330.007 107,326 L105,326 C105.883,330.799 110.063,334.51 115,334.955 L115,337 L114,337 C113.448,337 113,337.448 113,338 C113,338.553 113.448,339 114,339 L118,339 C118.552,339 119,338.553 119,338 C119,337.448 118.552,337 118,337 L117,337 L117,334.955 C121.937,334.51 126.117,330.799 127,326 L127,326 Z\"\n />\n </g>\n </svg>\n <!-- Microphone icon (muted) -->\n <svg\n *ngIf=\"isMicMuted\"\n width=\"24\"\n height=\"24\"\n viewBox=\"-5 0 32 32\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"currentColor\"\n >\n <g transform=\"translate(-105, -307)\">\n <path\n d=\"M111,314 C111,311.238 113.239,309 116,309 C118.761,309 121,311.238 121,314 L121,324 C121,326.762 118.761,329 116,329 C113.239,329 111,326.762 111,324 L111,314 L111,314 Z M116,331 C119.866,331 123,327.866 123,324 L123,314 C123,310.134 119.866,307 116,307 C112.134,307 109,310.134 109,314 L109,324 C109,327.866 112.134,331 116,331 L116,331 Z M127,326 L125,326 C124.089,330.007 120.282,333 116,333 C111.718,333 107.911,330.007 107,326 L105,326 C105.883,330.799 110.063,334.51 115,334.955 L115,337 L114,337 C113.448,337 113,337.448 113,338 C113,338.553 113.448,339 114,339 L118,339 C118.552,339 119,338.553 119,338 C119,337.448 118.552,337 118,337 L117,337 L117,334.955 C121.937,334.51 126.117,330.799 127,326 L127,326 Z\"\n />\n </g>\n <path\n d=\"M2 2 L30 30\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n <span class=\"control-label\">Mute</span>\n </div>\n\n <div\n style=\"\n display: flex;\n align-items: center;\n gap: 2px;\n flex-direction: column;\n \"\n >\n <button\n class=\"control-btn end-call-btn\"\n (click)=\"endCall()\"\n type=\"button\"\n title=\"End Call\"\n >\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M18 6L6 18M6 6L18 18\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n <span class=\"control-label\">End Call</span>\n </div>\n </div>\n </div>\n</div>\n",
150
+ template: "<div class=\"voice-agent-modal-overlay\" (click)=\"endCall()\">\n <div\n class=\"voice-container voice-agent-modal\"\n (click)=\"$event.stopPropagation()\"\n >\n <!-- Header -->\n <div class=\"header\">\n <div class=\"header-left\">\n <div class=\"header-icon\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M12 1C8.13 1 5 4.13 5 8V14C5 17.87 8.13 21 12 21C15.87 21 19 17.87 19 14V8C19 4.13 15.87 1 12 1Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M12 23C10.34 23 9 21.66 9 20H15C15 21.66 13.66 23 12 23Z\"\n fill=\"currentColor\"\n />\n </svg>\n </div>\n <span class=\"header-title\">Voice</span>\n </div>\n <button\n class=\"close-button\"\n (click)=\"endCall()\"\n type=\"button\"\n aria-label=\"Close\"\n >\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M18 6L6 18M6 6L18 18\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n </div>\n\n <!-- Avatar Section with glow -->\n <div class=\"avatar-section\">\n <div class=\"avatar-glow\"></div>\n <div class=\"avatar-wrapper\" [class.speaking]=\"isSpeaking\">\n <img class=\"avatar-image\" [src]=\"displayAvatarUrl\" alt=\"Nia\" />\n </div>\n </div>\n\n <!-- Agent Info: Nia + Collaboration Manager AI Agent Specialist -->\n <div class=\"agent-info\">\n <div class=\"agent-name\">\n Nia\n <span class=\"ai-badge\">AI</span>\n </div>\n <p class=\"agent-role\">Collaboration Manager AI Agent Specialist</p>\n </div>\n\n <!-- Start Call (when idle only) -->\n <div *ngIf=\"callState === 'idle'\" class=\"start-call-section\">\n <p *ngIf=\"statusText === 'Connection failed'\" class=\"error-message\">\n {{ statusText }}\n </p>\n <button\n class=\"start-call-button\"\n type=\"button\"\n [disabled]=\"isConnecting\"\n (click)=\"startCall()\"\n >\n <span *ngIf=\"isConnecting\">Connecting...</span>\n <span *ngIf=\"!isConnecting && statusText === 'Connection failed'\"\n >Retry</span\n >\n <span *ngIf=\"!isConnecting && statusText !== 'Connection failed'\"\n >Start Call</span\n >\n </button>\n </div>\n\n <!-- Call Ended: status + Call Again / Back to Chat -->\n <div *ngIf=\"callState === 'ended'\" class=\"call-ended-section\">\n <p class=\"call-ended-status\">\n <span class=\"status-text\">Call Ended</span>\n <span class=\"status-timer\">{{ duration }}</span>\n </p>\n <div class=\"call-ended-controls\">\n <button\n class=\"action-btn\"\n type=\"button\"\n (click)=\"callAgain()\"\n title=\"Call Again\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\" />\n <path d=\"M3 3v5h5\" />\n </svg>\n Call Again\n </button>\n <button\n class=\"action-btn\"\n type=\"button\"\n (click)=\"backToChat()\"\n title=\"Back to Chat\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </svg>\n Back to Chat\n </button>\n </div>\n </div>\n\n <!-- Status (when connecting or in-call: Talking... / Listening / Connected + timer) -->\n <div\n class=\"status-indicator status-inline\"\n *ngIf=\"callState !== 'idle' && callState !== 'ended'\"\n >\n <div *ngIf=\"callState === 'connecting'\" class=\"status-connecting\">\n <svg\n class=\"spinner\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-dasharray=\"31.416\"\n stroke-dashoffset=\"31.416\"\n >\n <animate\n attributeName=\"stroke-dasharray\"\n dur=\"2s\"\n values=\"0 31.416;15.708 15.708;0 31.416;0 31.416\"\n repeatCount=\"indefinite\"\n />\n <animate\n attributeName=\"stroke-dashoffset\"\n dur=\"2s\"\n values=\"0;-15.708;-31.416;-31.416\"\n repeatCount=\"indefinite\"\n />\n </circle>\n </svg>\n <span class=\"status-text\">{{ statusText }}</span>\n </div>\n <div\n *ngIf=\"callState !== 'connecting'\"\n class=\"status-connected status-inline-row\"\n >\n <span class=\"status-text\">{{ statusLabel }}</span>\n <span class=\"status-timer\">{{ duration }}</span>\n </div>\n </div>\n\n <!-- Waveform -->\n <div\n *ngIf=\"\n callState === 'connected' ||\n callState === 'listening' ||\n callState === 'talking'\n \"\n class=\"waveform-container\"\n >\n <div class=\"waveform-bars\">\n <div\n *ngFor=\"let level of audioLevels; let i = index\"\n class=\"waveform-bar\"\n [style.height.px]=\"getWaveformHeight(level)\"\n ></div>\n </div>\n </div>\n\n <!-- Call Controls (when connected) -->\n <div\n class=\"controls\"\n *ngIf=\"\n callState === 'connected' ||\n callState === 'listening' ||\n callState === 'talking'\n \"\n >\n <div\n style=\"\n display: flex;\n align-items: center;\n gap: 2px;\n flex-direction: column;\n \"\n >\n <button\n class=\"control-btn mic-btn\"\n [class.muted]=\"isMicMuted\"\n (click)=\"toggleMic()\"\n type=\"button\"\n [title]=\"isMicMuted ? 'Unmute' : 'Mute'\"\n >\n <!-- Microphone icon (unmuted) -->\n <svg\n *ngIf=\"!isMicMuted\"\n width=\"24\"\n height=\"24\"\n viewBox=\"-5 0 32 32\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"currentColor\"\n >\n <g transform=\"translate(-105, -307)\">\n <path\n d=\"M111,314 C111,311.238 113.239,309 116,309 C118.761,309 121,311.238 121,314 L121,324 C121,326.762 118.761,329 116,329 C113.239,329 111,326.762 111,324 L111,314 L111,314 Z M116,331 C119.866,331 123,327.866 123,324 L123,314 C123,310.134 119.866,307 116,307 C112.134,307 109,310.134 109,314 L109,324 C109,327.866 112.134,331 116,331 L116,331 Z M127,326 L125,326 C124.089,330.007 120.282,333 116,333 C111.718,333 107.911,330.007 107,326 L105,326 C105.883,330.799 110.063,334.51 115,334.955 L115,337 L114,337 C113.448,337 113,337.448 113,338 C113,338.553 113.448,339 114,339 L118,339 C118.552,339 119,338.553 119,338 C119,337.448 118.552,337 118,337 L117,337 L117,334.955 C121.937,334.51 126.117,330.799 127,326 L127,326 Z\"\n />\n </g>\n </svg>\n <!-- Microphone icon (muted) -->\n <svg\n *ngIf=\"isMicMuted\"\n width=\"24\"\n height=\"24\"\n viewBox=\"-5 0 32 32\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"currentColor\"\n >\n <g transform=\"translate(-105, -307)\">\n <path\n d=\"M111,314 C111,311.238 113.239,309 116,309 C118.761,309 121,311.238 121,314 L121,324 C121,326.762 118.761,329 116,329 C113.239,329 111,326.762 111,324 L111,314 L111,314 Z M116,331 C119.866,331 123,327.866 123,324 L123,314 C123,310.134 119.866,307 116,307 C112.134,307 109,310.134 109,314 L109,324 C109,327.866 112.134,331 116,331 L116,331 Z M127,326 L125,326 C124.089,330.007 120.282,333 116,333 C111.718,333 107.911,330.007 107,326 L105,326 C105.883,330.799 110.063,334.51 115,334.955 L115,337 L114,337 C113.448,337 113,337.448 113,338 C113,338.553 113.448,339 114,339 L118,339 C118.552,339 119,338.553 119,338 C119,337.448 118.552,337 118,337 L117,337 L117,334.955 C121.937,334.51 126.117,330.799 127,326 L127,326 Z\"\n />\n </g>\n <path\n d=\"M2 2 L30 30\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n <span class=\"control-label\">Mute</span>\n </div>\n\n <div\n style=\"\n display: flex;\n align-items: center;\n gap: 2px;\n flex-direction: column;\n \"\n >\n <button\n class=\"control-btn end-call-btn\"\n (click)=\"hangUp()\"\n type=\"button\"\n title=\"End Call\"\n >\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M18 6L6 18M6 6L18 18\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n <span class=\"control-label\">End Call</span>\n </div>\n </div>\n </div>\n</div>\n",
138
151
  styles: [":host{display:block}.voice-agent-modal-overlay{align-items:flex-end;backdrop-filter:blur(4px);background:rgba(0,0,0,.5);bottom:0;display:flex;font-family:Segoe UI,Tahoma,Geneva,Verdana,sans-serif;justify-content:flex-end;left:0;padding:24px;position:fixed;right:0;top:0;z-index:99999}.voice-container.voice-agent-modal{align-items:center;animation:modalEnter .3s ease-out;background:#fff;border-radius:30px;box-shadow:0 10px 40px rgba(0,0,0,.1);display:flex;flex-direction:column;max-width:440px;min-height:600px;padding:30px;position:relative;text-align:center;width:100%}@keyframes modalEnter{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}.header{justify-content:space-between;margin-bottom:5px;width:100%}.header,.header-left{align-items:center;display:flex}.header-left{gap:8px}.header-icon{align-items:center;background:#0f172a;border-radius:50%;color:#fff;display:flex;height:28px;justify-content:center;width:28px}.header-title{color:#0f172a;font-size:18px;font-weight:500}.close-button{align-items:center;background:none;border:none;color:#0f172a;cursor:pointer;display:flex;justify-content:center;padding:8px;transition:color .2s}.close-button:hover{color:#475569}.avatar-section{margin-bottom:24px;position:relative}.avatar-wrapper{align-items:center;background:#0ea5a4;background:linear-gradient(135deg,#ccfbf1,#0ea5a4);border-radius:50%;display:flex;height:180px;justify-content:center;padding:6px;position:relative;width:180px}.avatar-image{-o-object-fit:cover;border:4px solid #fff;border-radius:50%;height:100%;object-fit:cover;width:100%}.avatar-glow{background:radial-gradient(circle,rgba(14,165,164,.2) 0,transparent 70%);height:240px;left:50%;pointer-events:none;position:absolute;top:50%;transform:translate(-50%,-50%);width:240px;z-index:-1}.avatar-wrapper.speaking{animation:avatarPulse 2s ease-in-out infinite}@keyframes avatarPulse{0%,to{box-shadow:0 0 0 0 rgba(14,165,164,.4)}50%{box-shadow:0 0 0 15px rgba(14,165,164,0)}}.agent-info{margin-bottom:40px}.agent-name{align-items:center;color:#0f172a;display:flex;font-size:24px;font-weight:700;gap:8px;justify-content:center;margin-bottom:8px}.ai-badge{background:#0ea5a4;border-radius:6px;color:#fff;font-size:10px;font-weight:700;padding:2px 6px}.agent-role{color:#0f172a;font-size:16px;font-weight:500;margin:0}.start-call-section{align-items:center;display:flex;flex-direction:column;gap:16px;margin-bottom:24px}.error-message{color:#dc2626;font-size:14px;margin:0}.start-call-button{background:#0ea5a4;border:none;border-radius:12px;color:#fff;cursor:pointer;font-size:16px;font-weight:600;padding:14px 32px;transition:background .2s}.start-call-button:hover:not(:disabled){background:#0d9488}.start-call-button:disabled{cursor:not-allowed;opacity:.7}.status-indicator{justify-content:center;margin-bottom:10px}.status-connecting,.status-indicator{align-items:center;display:flex;gap:12px}.spinner{animation:spin 1s linear infinite;color:#0ea5a4}@keyframes spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.status-text{font-weight:400}.status-text,.status-timer{color:#0f172a;font-size:16px}.status-timer{font-weight:500}.status-connected{align-items:center;display:flex;flex-direction:column;gap:4px}.status-inline .status-inline-row{align-items:center;flex-direction:row;gap:8px}.call-ended-section{align-items:center;display:flex;flex-direction:column;gap:16px;margin-bottom:24px}.call-ended-status{align-items:center;color:#0f172a;display:flex;font-size:16px;gap:8px;justify-content:center;margin:0}.call-ended-status .status-text{font-weight:400}.call-ended-status .status-timer{font-weight:500}.call-ended-controls{align-items:center;display:flex;flex-wrap:wrap;gap:16px;justify-content:center}.action-btn{align-items:center;background:#fff;border:1px solid #e2e8f0;border-radius:24px;color:#0f172a;cursor:pointer;display:flex;font-size:14px;font-weight:500;gap:8px;padding:12px 24px;transition:background .2s ease}.action-btn:hover{background:#f8fafc}.waveform-container{margin-bottom:10px;padding:0 20px}.waveform-bars,.waveform-container{align-items:center;display:flex;gap:3px;height:60px;justify-content:center}.waveform-bar{background:linear-gradient(180deg,#94a3b8,#64748b);border-radius:2px;box-shadow:0 0 3px rgba(100,116,139,.2);max-height:20px;min-height:3px;transition:height .15s ease-in-out;width:3px}.waveform-bar:nth-child(2n){background:linear-gradient(180deg,#cbd5e1,#94a3b8)}.waveform-bar:nth-child(3n){background:linear-gradient(180deg,#64748b,#475569)}.controls{gap:24px;width:100%}.control-btn,.controls{align-items:center;display:flex;justify-content:center}.control-btn{border:none;border-radius:50%;cursor:pointer;flex-direction:column;gap:4px;height:60px;transition:transform .2s ease;width:60px}.control-btn:hover{transform:scale(1.05)}.control-btn:active{transform:scale(.95)}.control-label{color:#0f172a;font-size:12px;font-weight:500}.mic-btn{background:#e2e8f0}.mic-btn,.mic-btn .control-label{color:#475569}.mic-btn.muted{background:#e2e8f0;color:#475569}.end-call-btn{background:#ef4444;color:#fff}.end-call-btn .control-label{color:#fff}.end-call-btn:hover{background:#dc2626}"]
139
152
  },] }
140
153
  ];
@@ -157,4 +170,4 @@ VoiceAgentModalComponent.propDecorators = {
157
170
  agentRole: [{ type: Input }],
158
171
  agentAvatar: [{ type: Input }]
159
172
  };
160
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidm9pY2UtYWdlbnQtbW9kYWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2hpdHRoYWt1ci9oaXZlLWdwdC9IaXZlQUktUGFja2FnZXMvQW5ndWxhci9wcm9qZWN0cy9oaXZlZ3B0L2V2ZW50c2dwdC1hbmd1bGFyL3NyYy8iLCJzb3VyY2VzIjpbImxpYi9jb21wb25lbnRzL3ZvaWNlLWFnZW50L2NvbXBvbmVudHMvdm9pY2UtYWdlbnQtbW9kYWwvdm9pY2UtYWdlbnQtbW9kYWwuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBcUIsTUFBTSxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFcEcsT0FBTyxFQUFFLGlCQUFpQixFQUFhLE1BQU0sb0NBQW9DLENBQUM7QUFDbEYsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDN0UsT0FBTyxFQUFFLGtCQUFrQixFQUFFLDBCQUEwQixFQUFvQixNQUFNLDBCQUEwQixDQUFDO0FBTzVHLE1BQU0sT0FBTyx3QkFBd0I7SUFpQm5DLFlBQ1MsaUJBQW9DLEVBQ3BDLGFBQW1DLEVBQ2xDLFFBQWtCO1FBRm5CLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBbUI7UUFDcEMsa0JBQWEsR0FBYixhQUFhLENBQXNCO1FBQ2xDLGFBQVEsR0FBUixRQUFRLENBQVU7UUFuQmxCLFVBQUssR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBS2xDLFdBQU0sR0FBVyxFQUFFLENBQUM7UUFDcEIsZUFBVSxHQUFXLEVBQUUsQ0FBQztRQUN4QixhQUFRLEdBQVcsRUFBRSxDQUFDO1FBQ3RCLG9CQUFlLEdBQVcsV0FBVyxDQUFDO1FBQ3RDLGNBQVMsR0FBVyxjQUFjLENBQUM7UUFDbkMsY0FBUyxHQUFXLHFCQUFxQixDQUFDO1FBRzNDLG1CQUFjLEdBQTRCLElBQUksQ0FBQztRQUMvQyxvQkFB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LEtBQUssV0FBVztZQUFFLE9BQU8sV0FBVyxDQUFDO1FBQ3ZELE9BQU8sSUFBSSxDQUFDLFVBQVUsSUFBSSxFQUFFLENBQUM7SUFDL0IsQ0FBQztJQUVELHVEQUF1RDtJQUN2RCxTQUFTO1FBQ1AsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3JDLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztJQUNuQixDQUFDO0lBRUQsZ0RBQWdEO0lBQ2hELFVBQVU7UUFDUixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDakIsQ0FBQztJQUVELE9BQU87O1FBQ0wsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ2xCLE1BQUEsSUFBSSxDQUFDLGVBQWUsK0NBQXBCLElBQUksQ0FBb0IsQ0FBQztRQUN6QixJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ3BCLENBQUM7OztZQXZLRixTQUFTLFNBQUM7Z0JBQ1QsUUFBUSxFQUFFLDJCQUEyQjtnQkFDckMsODBVQUFpRDs7YUFFbEQ7OztZQVJRLGlCQUFpQjtZQUNqQixvQkFBb0I7WUFIdUMsUUFBUTs7O29CQVl6RSxNQUFNO3FCQUNOLEtBQUs7b0JBQ0wsS0FBSztvQkFDTCxLQUFLOzZCQUNMLEtBQUs7cUJBQ0wsS0FBSzt5QkFDTCxLQUFLO3VCQUNMLEtBQUs7OEJBQ0wsS0FBSzt3QkFDTCxLQUFLO3dCQUNMLEtBQUs7MEJBQ0wsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE9uSW5pdCwgT25EZXN0cm95LCBPdXRwdXQsIEV2ZW50RW1pdHRlciwgSW5qZWN0b3IgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgVm9pY2VBZ2VudFNlcnZpY2UsIENhbGxTdGF0ZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3ZvaWNlLWFnZW50LnNlcnZpY2UnO1xuaW1wb3J0IHsgQXVkaW9BbmFseXplclNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9hdWRpby1hbmFseXplci5zZXJ2aWNlJztcbmltcG9ydCB7IFZPSUNFX01PREFMX0NPTkZJRywgVk9JQ0VfTU9EQUxfQ0xPU0VfQ0FMTEJBQ0ssIFZvaWNlTW9kYWxDb25maWcgfSBmcm9tICcuLi8uLi92b2ljZS1tb2RhbC10b2tlbnMnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdoaXZlZ3B0LXZvaWNlLWFnZW50LW1vZGFsJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3ZvaWNlLWFnZW50LW1vZGFsLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vdm9pY2UtYWdlbnQtbW9kYWwuY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBWb2ljZUFnZW50TW9kYWxDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XG4gIEBPdXRwdXQoKSBjbG9zZSA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcbiAgQElucHV0KCkgYXBpVXJsITogc3RyaW5nO1xuICBASW5wdXQoKSB0b2tlbiE6IHN0cmluZztcbiAgQElucHV0KCkgYm90SWQhOiBzdHJpbmc7XG4gIEBJbnB1dCgpIGNvbnZlcnNhdGlvbklkITogc3RyaW5nO1xuICBASW5wdXQoKSBhcGlLZXk6IHN0cmluZyA9ICcnO1xuICBASW5wdXQoKSBldmVudFRva2VuOiBzdHJpbmcgPSAnJztcbiAgQElucHV0KCkgZXZlbnRVcmw6IHN0cmluZyA9ICcnO1xuICBASW5wdXQoKSBkb21haW5BdXRob3JpdHk6IHN0cmluZyA9ICdwcm9kLWxpdGUnO1xuICBASW5wdXQoKSBhZ2VudE5hbWU6IHN0cmluZyA9ICdBSSBBc3Npc3RhbnQnO1xuICBASW5wdXQoKSBhZ2VudFJvbGU6IHN0cmluZyA9ICdBSSBBZ2VudCBTcGVjaWFsaXN0JztcbiAgQElucHV0KCkgYWdlbnRBdmF0YXI/OiBzdHJpbmc7XG5cbiAgcHJpdmF0ZSBpbmplY3RlZENvbmZpZzogVm9pY2VNb2RhbENvbmZpZyB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIG9uQ2xvc2VDYWxsYmFjazogKCgpID0+IHZvaWQpIHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHZvaWNlQWdlbnRTZXJ2aWNlOiBWb2ljZUFnZW50U2VydmljZSxcbiAgICBwdWJsaWMgYXVkaW9BbmFseXplcjogQXVkaW9BbmFseXplclNlcnZpY2UsXG4gICAgcHJpdmF0ZSBpbmplY3RvcjogSW5qZWN0b3JcbiAgKSB7fVxuXG4gIC8qKiBIYXJkY29kZWQgdm9pY2UgYWdlbnQgYXZhdGFyIChOaWEpLiAqL1xuICByZWFkb25seSBkaXNwbGF5QXZhdGFyVXJsID0gJ2h0dHBzOi8vd3d3LmpvdGZvcm0uY29tL3VwbG9hZHMvbWVobWV0a2FyYWthc2xpL2Zvcm1fZmlsZXMvMTU2NDU5MzY2NzY3NmE4ZTg1ZjIzNzU4Ljg2OTQ1NTM3X2ljb24ucG5nJztcblxuICBjYWxsU3RhdGU6IENhbGxTdGF0ZSA9ICdpZGxlJztcbiAgc3RhdHVzVGV4dDogc3RyaW5nID0gJyc7XG4gIGR1cmF0aW9uOiBzdHJpbmcgPSAnMDA6MDAnO1xuICBpc01pY011dGVkOiBib29sZWFuID0gZmFsc2U7XG4gIGlzVXNlclNwZWFraW5nOiBib29sZWFuID0gZmFsc2U7XG4gIGF1ZGlvTGV2ZWxzOiBudW1iZXJbXSA9IFtdO1xuICBpc1NwZWFraW5nOiBib29sZWFuID0gZmFsc2U7XG5cbiAgcHJpdmF0ZSBzdWJzY3JpcHRpb25zOiBTdWJzY3JpcHRpb25bXSA9IFtdO1xuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIC8vIFdoZW4gb3BlbmVkIHZpYSBPdmVybGF5LCBjb25maWcgaXMgcHJvdmlkZWQgYnkgaW5qZWN0aW9uXG4gICAgdGhpcy5pbmplY3RlZENvbmZpZyA9IHRoaXMuaW5qZWN0b3IuZ2V0KFZPSUNFX01PREFMX0NPTkZJRywgbnVsbCk7XG4gICAgdGhpcy5vbkNsb3NlQ2FsbGJhY2sgPSB0aGlzLmluamVjdG9yLmdldChWT0lDRV9NT0RBTF9DTE9TRV9DQUxMQkFDSywgbnVsbCk7XG4gICAgaWYgKHRoaXMuaW5qZWN0ZWRDb25maWcpIHtcbiAgICAgIHRoaXMuYXBpVXJsID0gdGhpcy5pbmplY3RlZENvbmZpZy5hcGlVcmw7XG4gICAgICB0aGlzLnRva2VuID0gdGhpcy5pbmplY3RlZENvbmZpZy50b2tlbjtcbiAgICAgIHRoaXMuYm90SWQgPSB0aGlzLmluamVjdGVkQ29uZmlnLmJvdElkO1xuICAgICAgdGhpcy5jb252ZXJzYXRpb25JZCA9IHRoaXMuaW5qZWN0ZWRDb25maWcuY29udmVyc2F0aW9uSWQ7XG4gICAgICB0aGlzLmFwaUtleSA9IHRoaXMuaW5qZWN0ZWRDb25maWcuYXBpS2V5ID8/ICcnO1xuICAgICAgdGhpcy5ldmVudFRva2VuID0gdGhpcy5pbmplY3RlZENvbmZpZy5ldmVudFRva2VuID8/ICcnO1xuICAgICAgdGhpcy5ldmVudFVybCA9IHRoaXMuaW5qZWN0ZWRDb25maWcuZXZlbnRVcmwgPz8gJyc7XG4gICAgICB0aGlzLmRvbWFpbkF1dGhvcml0eSA9IHRoaXMuaW5qZWN0ZWRDb25maWcuZG9tYWluQXV0aG9yaXR5ID8/ICdwcm9kLWxpdGUnO1xuICAgICAgdGhpcy5hZ2VudE5hbWUgPSB0aGlzLmluamVjdGVkQ29uZmlnLmFnZW50TmFtZSA/PyB0aGlzLmFnZW50TmFtZTtcbiAgICAgIHRoaXMuYWdlbnRSb2xlID0gdGhpcy5pbmplY3RlZENvbmZpZy5hZ2VudFJvbGUgPz8gdGhpcy5hZ2VudFJvbGU7XG4gICAgICB0aGlzLmFnZW50QXZhdGFyID0gdGhpcy5pbmplY3RlZENvbmZpZy5hZ2VudEF2YXRhcjtcbiAgICB9XG5cbiAgICAvLyBTdWJzY3JpYmUgdG8gb2JzZXJ2YWJsZXNcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMucHVzaChcbiAgICAgIHRoaXMudm9pY2VBZ2VudFNlcnZpY2UuY2FsbFN0YXRlJC5zdWJzY3JpYmUoc3RhdGUgPT4ge1xuICAgICAgICB0aGlzLmNhbGxTdGF0ZSA9IHN0YXRlO1xuICAgICAgICB0aGlzLmlzU3BlYWtpbmcgPSBzdGF0ZSA9PT0gJ3RhbGtpbmcnO1xuICAgICAgfSlcbiAgICApO1xuXG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLnB1c2goXG4gICAgICB0aGlzLnZvaWNlQWdlbnRTZXJ2aWNlLnN0YXR1c1RleHQkLnN1YnNjcmliZSh0ZXh0ID0+IHtcbiAgICAgICAgdGhpcy5zdGF0dXNUZXh0ID0gdGV4dDtcbiAgICAgIH0pXG4gICAgKTtcblxuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5wdXNoKFxuICAgICAgdGhpcy52b2ljZUFnZW50U2VydmljZS5kdXJhdGlvbiQuc3Vic2NyaWJlKGR1cmF0aW9uID0+IHtcbiAgICAgICAgdGhpcy5kdXJhdGlvbiA9IGR1cmF0aW9uO1xuICAgICAgfSlcbiAgICApO1xuXG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLnB1c2goXG4gICAgICB0aGlzLnZvaWNlQWdlbnRTZXJ2aWNlLmlzTWljTXV0ZWQkLnN1YnNjcmliZShtdXRlZCA9PiB7XG4gICAgICAgIHRoaXMuaXNNaWNNdXRlZCA9IG11dGVkO1xuICAgICAgfSlcbiAgICApO1xuXG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLnB1c2goXG4gICAgICB0aGlzLnZvaWNlQWdlbnRTZXJ2aWNlLmlzVXNlclNwZWFraW5nJC5zdWJzY3JpYmUoc3BlYWtpbmcgPT4ge1xuICAgICAgICB0aGlzLmlzVXNlclNwZWFraW5nID0gc3BlYWtpbmc7XG4gICAgICB9KVxuICAgICk7XG5cbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMucHVzaChcbiAgICAgIHRoaXMudm9pY2VBZ2VudFNlcnZpY2UuYXVkaW9MZXZlbHMkLnN1YnNjcmliZShsZXZlbHMgPT4ge1xuICAgICAgICB0aGlzLmF1ZGlvTGV2ZWxzID0gbGV2ZWxzO1xuICAgICAgfSlcbiAgICApO1xuXG4gICAgLy8gTW9kYWwgb3BlbnMgaW4gaWRsZSBzdGF0ZTsgdXNlciBjbGlja3MgXCJTdGFydCBDYWxsXCIgdG8gY29ubmVjdCAobm8gYXV0by1jb25uZWN0KS5cbiAgICB0aGlzLnZvaWNlQWdlbnRTZXJ2aWNlLnJlc2V0VG9JZGxlKCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuZm9yRWFjaChzdWIgPT4gc3ViLnVuc3Vic2NyaWJlKCkpO1xuICAgIHRoaXMuZGlzY29ubmVjdCgpO1xuICB9XG5cbiAgaXNDb25uZWN0aW5nOiBib29sZWFuID0gZmFsc2U7XG5cbiAgYXN5bmMgc3RhcnRDYWxsKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLmlzQ29ubmVjdGluZyB8fCAodGhpcy5jYWxsU3RhdGUgIT09ICdpZGxlJyAmJiB0aGlzLmNhbGxTdGF0ZSAhPT0gJ2VuZGVkJykpIHJldHVybjtcbiAgICB0aGlzLmlzQ29ubmVjdGluZyA9IHRydWU7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMudm9pY2VBZ2VudFNlcnZpY2UuY29ubmVjdChcbiAgICAgICAgdGhpcy5hcGlVcmwsXG4gICAgICAgIHRoaXMudG9rZW4sXG4gICAgICAgIHRoaXMuYm90SWQsXG4gICAgICAgIHRoaXMuY29udmVyc2F0aW9uSWQsXG4gICAgICAgIHRoaXMuYXBpS2V5LFxuICAgICAgICB0aGlzLmV2ZW50VG9rZW4sXG4gICAgICAgIHRoaXMuZXZlbnRVcmwsXG4gICAgICAgIHRoaXMuZG9tYWluQXV0aG9yaXR5XG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdGYWlsZWQgdG8gY29ubmVjdCB2b2ljZSBhZ2VudDonLCBlcnJvcik7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuaXNDb25uZWN0aW5nID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZGlzY29ubmVjdCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLnZvaWNlQWdlbnRTZXJ2aWNlLmRpc2Nvbm5lY3QoKTtcbiAgfVxuXG4gIHRvZ2dsZU1pYygpOiB2b2lkIHtcbiAgICB0aGlzLnZvaWNlQWdlbnRTZXJ2aWNlLnRvZ2dsZU1pYygpO1xuICB9XG5cbiAgLyoqIE1hcCBhdWRpbyBsZXZlbCAoMOKAkzEwMCkgdG8gd2F2ZWZvcm0gYmFyIGhlaWdodCBpbiBweCAoM+KAkzIwKS4gKi9cbiAgZ2V0V2F2ZWZvcm1IZWlnaHQobGV2ZWw6IG51bWJlcik6IG51bWJlciB7XG4gICAgY29uc3QgbiA9IE1hdGgubWluKDEwMCwgTWF0aC5tYXgoMCwgbGV2ZWwgPz8gMCkpO1xuICAgIHJldHVybiAzICsgKG4gLyAxMDApICogMTc7XG4gIH1cblxuICAvKiogU3RhdHVzIGxhYmVsIGZvciBhY3RpdmUgY2FsbDogVGFsa2luZy4uLiwgTGlzdGVuaW5nLCBDb25uZWN0ZWQsIG9yIENvbm5lY3RpbmcuLi4gKi9cbiAgZ2V0IHN0YXR1c0xhYmVsKCk6IHN0cmluZyB7XG4gICAgaWYgKHRoaXMuY2FsbFN0YXRlID09PSAnY29ubmVjdGluZycpIHJldHVybiB0aGlzLnN0YXR1c1RleHQgfHwgJ0Nvbm5lY3RpbmcuLi4nO1xuICAgIGlmICh0aGlzLmNhbGxTdGF0ZSA9PT0gJ3RhbGtpbmcnKSByZXR1cm4gJ1RhbGtpbmcuLi4nO1xuICAgIGlmICh0aGlzLmNhbGxTdGF0ZSA9PT0gJ2xpc3RlbmluZycpIHJldHVybiAnTGlzdGVuaW5nJztcbiAgICBpZiAodGhpcy5jYWxsU3RhdGUgPT09ICdjb25uZWN0ZWQnKSByZXR1cm4gJ0Nvbm5lY3RlZCc7XG4gICAgcmV0dXJuIHRoaXMuc3RhdHVzVGV4dCB8fCAnJztcbiAgfVxuXG4gIC8qKiBDYWxsIEFnYWluOiByZXNldCB0byBpZGxlIHRoZW4gc3RhcnQgYSBuZXcgY2FsbC4gKi9cbiAgY2FsbEFnYWluKCk6IHZvaWQge1xuICAgIHRoaXMudm9pY2VBZ2VudFNlcnZpY2UucmVzZXRUb0lkbGUoKTtcbiAgICB0aGlzLnN0YXJ0Q2FsbCgpO1xuICB9XG5cbiAgLyoqIEJhY2sgdG8gQ2hhdDogY2xvc2UgbW9kYWwgYW5kIGRpc2Nvbm5lY3QuICovXG4gIGJhY2tUb0NoYXQoKTogdm9pZCB7XG4gICAgdGhpcy5lbmRDYWxsKCk7XG4gIH1cblxuICBlbmRDYWxsKCk6IHZvaWQge1xuICAgIHRoaXMuZGlzY29ubmVjdCgpO1xuICAgIHRoaXMub25DbG9zZUNhbGxiYWNrPy4oKTtcbiAgICB0aGlzLmNsb3NlLmVtaXQoKTtcbiAgfVxufVxuIl19
173
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidm9pY2UtYWdlbnQtbW9kYWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Ii9Vc2Vycy9yb2hpdHRoYWt1ci9oaXZlLWdwdC9IaXZlQUktUGFja2FnZXMvQW5ndWxhci9wcm9qZWN0cy9oaXZlZ3B0L2V2ZW50c2dwdC1hbmd1bGFyL3NyYy8iLCJzb3VyY2VzIjpbImxpYi9jb21wb25lbnRzL3ZvaWNlLWFnZW50L2NvbXBvbmVudHMvdm9pY2UtYWdlbnQtbW9kYWwvdm9pY2UtYWdlbnQtbW9kYWwuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBcUIsTUFBTSxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFcEcsT0FBTyxFQUFFLGlCQUFpQixFQUFhLE1BQU0sb0NBQW9DLENBQUM7QUFDbEYsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDN0UsT0FBTyxFQUFFLGtCQUFrQixFQUFFLDBCQUEwQixFQUFvQixNQUFNLDBCQUEwQixDQUFDO0FBTzVHLE1BQU0sT0FBTyx3QkFBd0I7SUFpQm5DLFlBQ1MsaUJBQW9DLEVBQ3BDLGFBQW1DLEVBQ2xDLFFBQWtCO1FBRm5CLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBbUI7UUFDcEMsa0JBQWEsR0FBYixhQUFhLENBQXNCO1FBQ2xDLGFBQVEsR0FBUixRQUFRLENBQVU7UUFuQmxCLFVBQUssR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBS2xDLFdBQU0sR0FBVyxFQUFFLENBQUM7UUFDcEIsZUFBVSxHQUFXLEVBQUUsQ0FBQztRQUN4QixhQUFRLEdBQVcsRUFBRSxDQUFDO1FBQ3RCLG9CQUFlLEdBQVcsV0FBVyxDQUFDO1FBQ3RDLGNBQVMsR0FBVyxjQUFjLENBQUM7UUFDbkMsY0FBUyxHQUFXLHFCQUFxQixDQUFDO1FBRzNDLG1CQUFjLEdBQTRCLElBQUksQ0FBQztRQUMvQyxvQkFB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QUs7NkJBQ0wsS0FBSztxQkFDTCxLQUFLO3lCQUNMLEtBQUs7dUJBQ0wsS0FBSzs4QkFDTCxLQUFLO3dCQUNMLEtBQUs7d0JBQ0wsS0FBSzswQkFDTCxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT25Jbml0LCBPbkRlc3Ryb3ksIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBJbmplY3RvciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBWb2ljZUFnZW50U2VydmljZSwgQ2FsbFN0YXRlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvdm9pY2UtYWdlbnQuc2VydmljZSc7XG5pbXBvcnQgeyBBdWRpb0FuYWx5emVyU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2F1ZGlvLWFuYWx5emVyLnNlcnZpY2UnO1xuaW1wb3J0IHsgVk9JQ0VfTU9EQUxfQ09ORklHLCBWT0lDRV9NT0RBTF9DTE9TRV9DQUxMQkFDSywgVm9pY2VNb2RhbENvbmZpZyB9IGZyb20gJy4uLy4uL3ZvaWNlLW1vZGFsLXRva2Vucyc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2hpdmVncHQtdm9pY2UtYWdlbnQtbW9kYWwnLFxuICB0ZW1wbGF0ZVVybDogJy4vdm9pY2UtYWdlbnQtbW9kYWwuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi92b2ljZS1hZ2VudC1tb2RhbC5jb21wb25lbnQuc2NzcyddXG59KVxuZXhwb3J0IGNsYXNzIFZvaWNlQWdlbnRNb2RhbENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgQE91dHB1dCgpIGNsb3NlID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICBASW5wdXQoKSBhcGlVcmwhOiBzdHJpbmc7XG4gIEBJbnB1dCgpIHRva2VuITogc3RyaW5nO1xuICBASW5wdXQoKSBib3RJZCE6IHN0cmluZztcbiAgQElucHV0KCkgY29udmVyc2F0aW9uSWQhOiBzdHJpbmc7XG4gIEBJbnB1dCgpIGFwaUtleTogc3RyaW5nID0gJyc7XG4gIEBJbnB1dCgpIGV2ZW50VG9rZW46IHN0cmluZyA9ICcnO1xuICBASW5wdXQoKSBldmVudFVybDogc3RyaW5nID0gJyc7XG4gIEBJbnB1dCgpIGRvbWFpbkF1dGhvcml0eTogc3RyaW5nID0gJ3Byb2QtbGl0ZSc7XG4gIEBJbnB1dCgpIGFnZW50TmFtZTogc3RyaW5nID0gJ0FJIEFzc2lzdGFudCc7XG4gIEBJbnB1dCgpIGFnZW50Um9sZTogc3RyaW5nID0gJ0FJIEFnZW50IFNwZWNpYWxpc3QnO1xuICBASW5wdXQoKSBhZ2VudEF2YXRhcj86IHN0cmluZztcblxuICBwcml2YXRlIGluamVjdGVkQ29uZmlnOiBWb2ljZU1vZGFsQ29uZmlnIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgb25DbG9zZUNhbGxiYWNrOiAoKCkgPT4gdm9pZCkgfCBudWxsID0gbnVsbDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgdm9pY2VBZ2VudFNlcnZpY2U6IFZvaWNlQWdlbnRTZXJ2aWNlLFxuICAgIHB1YmxpYyBhdWRpb0FuYWx5emVyOiBBdWRpb0FuYWx5emVyU2VydmljZSxcbiAgICBwcml2YXRlIGluamVjdG9yOiBJbmplY3RvclxuICApIHt9XG5cbiAgLyoqIEhhcmRjb2RlZCB2b2ljZSBhZ2VudCBhdmF0YXIgKE5pYSkuICovXG4gIHJlYWRvbmx5IGRpc3BsYXlBdmF0YXJVcmwgPSAnaHR0cHM6Ly93d3cuam90Zm9ybS5jb20vdXBsb2Fkcy9tZWhtZXRrYXJha2FzbGkvZm9ybV9maWxlcy8xNTY0NTkzNjY3Njc2YThlODVmMjM3NTguODY5NDU1MzdfaWNvbi5wbmcnO1xuXG4gIGNhbGxTdGF0ZTogQ2FsbFN0YXRlID0gJ2lkbGUnO1xuICBzdGF0dXNUZXh0OiBzdHJpbmcgPSAnJztcbiAgZHVyYXRpb246IHN0cmluZyA9ICcwMDowMCc7XG4gIGlzTWljTXV0ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgaXNVc2VyU3BlYWtpbmc6IGJvb2xlYW4gPSBmYWxzZTtcbiAgYXVkaW9MZXZlbHM6IG51bWJlcltdID0gW107XG4gIGlzU3BlYWtpbmc6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAvKiogT25jZSB1c2VyIG9yIGJvdCBoYXMgc3Bva2VuLCBzaG93IFwiUmVhZHlcIiBpbnN0ZWFkIG9mIFwiQ29ubmVjdGVkXCIgd2hlbiBpZGxlIGluIGNhbGwuICovXG4gIHByaXZhdGUgaGFzTGVmdENvbm5lY3RlZE9uY2U6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBwcml2YXRlIHN1YnNjcmlwdGlvbnM6IFN1YnNjcmlwdGlvbltdID0gW107XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgLy8gV2hlbiBvcGVuZWQgdmlhIE92ZXJsYXksIGNvbmZpZyBpcyBwcm92aWRlZCBieSBpbmplY3Rpb25cbiAgICB0aGlzLmluamVjdGVkQ29uZmlnID0gdGhpcy5pbmplY3Rvci5nZXQoVk9JQ0VfTU9EQUxfQ09ORklHLCBudWxsKTtcbiAgICB0aGlzLm9uQ2xvc2VDYWxsYmFjayA9IHRoaXMuaW5qZWN0b3IuZ2V0KFZPSUNFX01PREFMX0NMT1NFX0NBTExCQUNLLCBudWxsKTtcbiAgICBpZiAodGhpcy5pbmplY3RlZENvbmZpZykge1xuICAgICAgdGhpcy5hcGlVcmwgPSB0aGlzLmluamVjdGVkQ29uZmlnLmFwaVVybDtcbiAgICAgIHRoaXMudG9rZW4gPSB0aGlzLmluamVjdGVkQ29uZmlnLnRva2VuO1xuICAgICAgdGhpcy5ib3RJZCA9IHRoaXMuaW5qZWN0ZWRDb25maWcuYm90SWQ7XG4gICAgICB0aGlzLmNvbnZlcnNhdGlvbklkID0gdGhpcy5pbmplY3RlZENvbmZpZy5jb252ZXJzYXRpb25JZDtcbiAgICAgIHRoaXMuYXBpS2V5ID0gdGhpcy5pbmplY3RlZENvbmZpZy5hcGlLZXkgPz8gJyc7XG4gICAgICB0aGlzLmV2ZW50VG9rZW4gPSB0aGlzLmluamVjdGVkQ29uZmlnLmV2ZW50VG9rZW4gPz8gJyc7XG4gICAgICB0aGlzLmV2ZW50VXJsID0gdGhpcy5pbmplY3RlZENvbmZpZy5ldmVudFVybCA/PyAnJztcbiAgICAgIHRoaXMuZG9tYWluQXV0aG9yaXR5ID0gdGhpcy5pbmplY3RlZENvbmZpZy5kb21haW5BdXRob3JpdHkgPz8gJ3Byb2QtbGl0ZSc7XG4gICAgICB0aGlzLmFnZW50TmFtZSA9IHRoaXMuaW5qZWN0ZWRDb25maWcuYWdlbnROYW1lID8/IHRoaXMuYWdlbnROYW1lO1xuICAgICAgdGhpcy5hZ2VudFJvbGUgPSB0aGlzLmluamVjdGVkQ29uZmlnLmFnZW50Um9sZSA/PyB0aGlzLmFnZW50Um9sZTtcbiAgICAgIHRoaXMuYWdlbnRBdmF0YXIgPSB0aGlzLmluamVjdGVkQ29uZmlnLmFnZW50QXZhdGFyO1xuICAgIH1cblxuICAgIC8vIFN1YnNjcmliZSB0byBvYnNlcnZhYmxlc1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5wdXNoKFxuICAgICAgdGhpcy52b2ljZUFnZW50U2VydmljZS5jYWxsU3RhdGUkLnN1YnNjcmliZShzdGF0ZSA9PiB7XG4gICAgICAgIHRoaXMuY2FsbFN0YXRlID0gc3RhdGU7XG4gICAgICAgIHRoaXMuaXNTcGVha2luZyA9IHN0YXRlID09PSAndGFsa2luZyc7XG4gICAgICAgIGlmIChzdGF0ZSA9PT0gJ2xpc3RlbmluZycgfHwgc3RhdGUgPT09ICd0YWxraW5nJykge1xuICAgICAgICAgIHRoaXMuaGFzTGVmdENvbm5lY3RlZE9uY2UgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzdGF0ZSA9PT0gJ2lkbGUnIHx8IHN0YXRlID09PSAnZW5kZWQnKSB7XG4gICAgICAgICAgdGhpcy5oYXNMZWZ0Q29ubmVjdGVkT25jZSA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICk7XG5cbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMucHVzaChcbiAgICAgIHRoaXMudm9pY2VBZ2VudFNlcnZpY2Uuc3RhdHVzVGV4dCQuc3Vic2NyaWJlKHRleHQgPT4ge1xuICAgICAgICB0aGlzLnN0YXR1c1RleHQgPSB0ZXh0O1xuICAgICAgfSlcbiAgICApO1xuXG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLnB1c2goXG4gICAgICB0aGlzLnZvaWNlQWdlbnRTZXJ2aWNlLmR1cmF0aW9uJC5zdWJzY3JpYmUoZHVyYXRpb24gPT4ge1xuICAgICAgICB0aGlzLmR1cmF0aW9uID0gZHVyYXRpb247XG4gICAgICB9KVxuICAgICk7XG5cbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMucHVzaChcbiAgICAgIHRoaXMudm9pY2VBZ2VudFNlcnZpY2UuaXNNaWNNdXRlZCQuc3Vic2NyaWJlKG11dGVkID0+IHtcbiAgICAgICAgdGhpcy5pc01pY011dGVkID0gbXV0ZWQ7XG4gICAgICB9KVxuICAgICk7XG5cbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMucHVzaChcbiAgICAgIHRoaXMudm9pY2VBZ2VudFNlcnZpY2UuaXNVc2VyU3BlYWtpbmckLnN1YnNjcmliZShzcGVha2luZyA9PiB7XG4gICAgICAgIHRoaXMuaXNVc2VyU3BlYWtpbmcgPSBzcGVha2luZztcbiAgICAgIH0pXG4gICAgKTtcblxuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5wdXNoKFxuICAgICAgdGhpcy52b2ljZUFnZW50U2VydmljZS5hdWRpb0xldmVscyQuc3Vic2NyaWJlKGxldmVscyA9PiB7XG4gICAgICAgIHRoaXMuYXVkaW9MZXZlbHMgPSBsZXZlbHM7XG4gICAgICB9KVxuICAgICk7XG5cbiAgICAvLyBNb2RhbCBvcGVucyBpbiBpZGxlIHN0YXRlOyB1c2VyIGNsaWNrcyBcIlN0YXJ0IENhbGxcIiB0byBjb25uZWN0IChubyBhdXRvLWNvbm5lY3QpLlxuICAgIHRoaXMudm9pY2VBZ2VudFNlcnZpY2UucmVzZXRUb0lkbGUoKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5mb3JFYWNoKHN1YiA9PiBzdWIudW5zdWJzY3JpYmUoKSk7XG4gICAgdGhpcy5kaXNjb25uZWN0KCk7XG4gIH1cblxuICBpc0Nvbm5lY3Rpbmc6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBhc3luYyBzdGFydENhbGwoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuaXNDb25uZWN0aW5nIHx8ICh0aGlzLmNhbGxTdGF0ZSAhPT0gJ2lkbGUnICYmIHRoaXMuY2FsbFN0YXRlICE9PSAnZW5kZWQnKSkgcmV0dXJuO1xuICAgIHRoaXMuaXNDb25uZWN0aW5nID0gdHJ1ZTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy52b2ljZUFnZW50U2VydmljZS5jb25uZWN0KFxuICAgICAgICB0aGlzLmFwaVVybCxcbiAgICAgICAgdGhpcy50b2tlbixcbiAgICAgICAgdGhpcy5ib3RJZCxcbiAgICAgICAgdGhpcy5jb252ZXJzYXRpb25JZCxcbiAgICAgICAgdGhpcy5hcGlLZXksXG4gICAgICAgIHRoaXMuZXZlbnRUb2tlbixcbiAgICAgICAgdGhpcy5ldmVudFVybCxcbiAgICAgICAgdGhpcy5kb21haW5BdXRob3JpdHlcbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCB0byBjb25uZWN0IHZvaWNlIGFnZW50OicsIGVycm9yKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5pc0Nvbm5lY3RpbmcgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBkaXNjb25uZWN0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMudm9pY2VBZ2VudFNlcnZpY2UuZGlzY29ubmVjdCgpO1xuICB9XG5cbiAgdG9nZ2xlTWljKCk6IHZvaWQge1xuICAgIHRoaXMudm9pY2VBZ2VudFNlcnZpY2UudG9nZ2xlTWljKCk7XG4gIH1cblxuICAvKiogTWFwIGF1ZGlvIGxldmVsICgw4oCTMTAwKSB0byB3YXZlZm9ybSBiYXIgaGVpZ2h0IGluIHB4ICgz4oCTMjApLiAqL1xuICBnZXRXYXZlZm9ybUhlaWdodChsZXZlbDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBjb25zdCBuID0gTWF0aC5taW4oMTAwLCBNYXRoLm1heCgwLCBsZXZlbCA/PyAwKSk7XG4gICAgcmV0dXJuIDMgKyAobiAvIDEwMCkgKiAxNztcbiAgfVxuXG4gIC8qKiBTdGF0dXMgbGFiZWwgZm9yIGFjdGl2ZSBjYWxsLiBcIkNvbm5lY3RlZFwiIG9ubHkgb25jZTsgdGhlbiBcIlJlYWR5XCIgd2hlbiBpZGxlIGluIGNhbGwuICovXG4gIGdldCBzdGF0dXNMYWJlbCgpOiBzdHJpbmcge1xuICAgIGlmICh0aGlzLmNhbGxTdGF0ZSA9PT0gJ2Nvbm5lY3RpbmcnKSByZXR1cm4gdGhpcy5zdGF0dXNUZXh0IHx8ICdDb25uZWN0aW5nLi4uJztcbiAgICBpZiAodGhpcy5jYWxsU3RhdGUgPT09ICd0YWxraW5nJykgcmV0dXJuICdUYWxraW5nLi4uJztcbiAgICBpZiAodGhpcy5jYWxsU3RhdGUgPT09ICdsaXN0ZW5pbmcnKSByZXR1cm4gJ0xpc3RlbmluZyc7XG4gICAgaWYgKHRoaXMuY2FsbFN0YXRlID09PSAnY29ubmVjdGVkJykge1xuICAgICAgcmV0dXJuIHRoaXMuaGFzTGVmdENvbm5lY3RlZE9uY2UgPyAnTGlzdGVuaW5nJyA6ICdDb25uZWN0ZWQnO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5zdGF0dXNUZXh0IHx8ICcnO1xuICB9XG5cbiAgLyoqIENhbGwgQWdhaW46IHJlc2V0IHRvIGlkbGUgdGhlbiBzdGFydCBhIG5ldyBjYWxsLiAqL1xuICBjYWxsQWdhaW4oKTogdm9pZCB7XG4gICAgdGhpcy52b2ljZUFnZW50U2VydmljZS5yZXNldFRvSWRsZSgpO1xuICAgIHRoaXMuc3RhcnRDYWxsKCk7XG4gIH1cblxuICAvKiogQmFjayB0byBDaGF0OiBjbG9zZSBtb2RhbCBhbmQgZGlzY29ubmVjdC4gKi9cbiAgYmFja1RvQ2hhdCgpOiB2b2lkIHtcbiAgICB0aGlzLmVuZENhbGwoKTtcbiAgfVxuXG4gIC8qKiBFbmQgY2FsbCBidXQga2VlcCBtb2RhbCBvcGVuIHRvIHNob3cgQ2FsbCBFbmRlZCArIENhbGwgQWdhaW4gLyBCYWNrIHRvIENoYXQuICovXG4gIGhhbmdVcCgpOiB2b2lkIHtcbiAgICB0aGlzLmRpc2Nvbm5lY3QoKTtcbiAgfVxuXG4gIGVuZENhbGwoKTogdm9pZCB7XG4gICAgdGhpcy5kaXNjb25uZWN0KCk7XG4gICAgdGhpcy5vbkNsb3NlQ2FsbGJhY2s/LigpO1xuICAgIHRoaXMuY2xvc2UuZW1pdCgpO1xuICB9XG59XG4iXX0=
@@ -864,6 +864,8 @@ class VoiceAgentModalComponent {
864
864
  this.isUserSpeaking = false;
865
865
  this.audioLevels = [];
866
866
  this.isSpeaking = false;
867
+ /** Once user or bot has spoken, show "Ready" instead of "Connected" when idle in call. */
868
+ this.hasLeftConnectedOnce = false;
867
869
  this.subscriptions = [];
868
870
  this.isConnecting = false;
869
871
  }
@@ -889,6 +891,12 @@ class VoiceAgentModalComponent {
889
891
  this.subscriptions.push(this.voiceAgentService.callState$.subscribe(state => {
890
892
  this.callState = state;
891
893
  this.isSpeaking = state === 'talking';
894
+ if (state === 'listening' || state === 'talking') {
895
+ this.hasLeftConnectedOnce = true;
896
+ }
897
+ if (state === 'idle' || state === 'ended') {
898
+ this.hasLeftConnectedOnce = false;
899
+ }
892
900
  }));
893
901
  this.subscriptions.push(this.voiceAgentService.statusText$.subscribe(text => {
894
902
  this.statusText = text;
@@ -941,7 +949,7 @@ class VoiceAgentModalComponent {
941
949
  const n = Math.min(100, Math.max(0, level !== null && level !== void 0 ? level : 0));
942
950
  return 3 + (n / 100) * 17;
943
951
  }
944
- /** Status label for active call: Talking..., Listening, Connected, or Connecting... */
952
+ /** Status label for active call. "Connected" only once; then "Ready" when idle in call. */
945
953
  get statusLabel() {
946
954
  if (this.callState === 'connecting')
947
955
  return this.statusText || 'Connecting...';
@@ -949,8 +957,9 @@ class VoiceAgentModalComponent {
949
957
  return 'Talking...';
950
958
  if (this.callState === 'listening')
951
959
  return 'Listening';
952
- if (this.callState === 'connected')
953
- return 'Connected';
960
+ if (this.callState === 'connected') {
961
+ return this.hasLeftConnectedOnce ? 'Listening' : 'Connected';
962
+ }
954
963
  return this.statusText || '';
955
964
  }
956
965
  /** Call Again: reset to idle then start a new call. */
@@ -962,6 +971,10 @@ class VoiceAgentModalComponent {
962
971
  backToChat() {
963
972
  this.endCall();
964
973
  }
974
+ /** End call but keep modal open to show Call Ended + Call Again / Back to Chat. */
975
+ hangUp() {
976
+ this.disconnect();
977
+ }
965
978
  endCall() {
966
979
  var _a;
967
980
  this.disconnect();
@@ -972,7 +985,7 @@ class VoiceAgentModalComponent {
972
985
  VoiceAgentModalComponent.decorators = [
973
986
  { type: Component, args: [{
974
987
  selector: 'hivegpt-voice-agent-modal',
975
- template: "<div class=\"voice-agent-modal-overlay\" (click)=\"endCall()\">\n <div\n class=\"voice-container voice-agent-modal\"\n (click)=\"$event.stopPropagation()\"\n >\n <!-- Header -->\n <div class=\"header\">\n <div class=\"header-left\">\n <div class=\"header-icon\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M12 1C8.13 1 5 4.13 5 8V14C5 17.87 8.13 21 12 21C15.87 21 19 17.87 19 14V8C19 4.13 15.87 1 12 1Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M12 23C10.34 23 9 21.66 9 20H15C15 21.66 13.66 23 12 23Z\"\n fill=\"currentColor\"\n />\n </svg>\n </div>\n <span class=\"header-title\">Voice</span>\n </div>\n <button\n class=\"close-button\"\n (click)=\"endCall()\"\n type=\"button\"\n aria-label=\"Close\"\n >\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M18 6L6 18M6 6L18 18\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n </div>\n\n <!-- Avatar Section with glow -->\n <div class=\"avatar-section\">\n <div class=\"avatar-glow\"></div>\n <div class=\"avatar-wrapper\" [class.speaking]=\"isSpeaking\">\n <img class=\"avatar-image\" [src]=\"displayAvatarUrl\" alt=\"Nia\" />\n </div>\n </div>\n\n <!-- Agent Info: Nia + Collaboration Manager AI Agent Specialist -->\n <div class=\"agent-info\">\n <div class=\"agent-name\">\n Nia\n <span class=\"ai-badge\">AI</span>\n </div>\n <p class=\"agent-role\">Collaboration Manager AI Agent Specialist</p>\n </div>\n\n <!-- Start Call (when idle only) -->\n <div *ngIf=\"callState === 'idle'\" class=\"start-call-section\">\n <p *ngIf=\"statusText === 'Connection failed'\" class=\"error-message\">\n {{ statusText }}\n </p>\n <button\n class=\"start-call-button\"\n type=\"button\"\n [disabled]=\"isConnecting\"\n (click)=\"startCall()\"\n >\n <span *ngIf=\"isConnecting\">Connecting...</span>\n <span *ngIf=\"!isConnecting && statusText === 'Connection failed'\"\n >Retry</span\n >\n <span *ngIf=\"!isConnecting && statusText !== 'Connection failed'\"\n >Start Call</span\n >\n </button>\n </div>\n\n <!-- Call Ended: status + Call Again / Back to Chat -->\n <div *ngIf=\"callState === 'ended'\" class=\"call-ended-section\">\n <p class=\"call-ended-status\">\n <span class=\"status-text\">Call Ended</span>\n <span class=\"status-timer\">{{ duration }}</span>\n </p>\n <div class=\"call-ended-controls\">\n <button\n class=\"action-btn\"\n type=\"button\"\n (click)=\"callAgain()\"\n title=\"Call Again\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\" />\n <path d=\"M3 3v5h5\" />\n </svg>\n Call Again\n </button>\n <button\n class=\"action-btn\"\n type=\"button\"\n (click)=\"backToChat()\"\n title=\"Back to Chat\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </svg>\n Back to Chat\n </button>\n </div>\n </div>\n\n <!-- Status (when connecting or in-call: Talking... / Listening / Connected + timer) -->\n <div\n class=\"status-indicator status-inline\"\n *ngIf=\"callState !== 'idle' && callState !== 'ended'\"\n >\n <div *ngIf=\"callState === 'connecting'\" class=\"status-connecting\">\n <svg\n class=\"spinner\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-dasharray=\"31.416\"\n stroke-dashoffset=\"31.416\"\n >\n <animate\n attributeName=\"stroke-dasharray\"\n dur=\"2s\"\n values=\"0 31.416;15.708 15.708;0 31.416;0 31.416\"\n repeatCount=\"indefinite\"\n />\n <animate\n attributeName=\"stroke-dashoffset\"\n dur=\"2s\"\n values=\"0;-15.708;-31.416;-31.416\"\n repeatCount=\"indefinite\"\n />\n </circle>\n </svg>\n <span class=\"status-text\">{{ statusText }}</span>\n </div>\n <div\n *ngIf=\"callState !== 'connecting'\"\n class=\"status-connected status-inline-row\"\n >\n <span class=\"status-text\">{{ statusLabel }}</span>\n <span class=\"status-timer\">{{ duration }}</span>\n </div>\n </div>\n\n <!-- Waveform -->\n <div\n *ngIf=\"\n callState === 'connected' ||\n callState === 'listening' ||\n callState === 'talking'\n \"\n class=\"waveform-container\"\n >\n <div class=\"waveform-bars\">\n <div\n *ngFor=\"let level of audioLevels; let i = index\"\n class=\"waveform-bar\"\n [style.height.px]=\"getWaveformHeight(level)\"\n ></div>\n </div>\n </div>\n\n <!-- Call Controls (when connected) -->\n <div\n class=\"controls\"\n *ngIf=\"\n callState === 'connected' ||\n callState === 'listening' ||\n callState === 'talking'\n \"\n >\n <div\n style=\"\n display: flex;\n align-items: center;\n gap: 2px;\n flex-direction: column;\n \"\n >\n <button\n class=\"control-btn mic-btn\"\n [class.muted]=\"isMicMuted\"\n (click)=\"toggleMic()\"\n type=\"button\"\n [title]=\"isMicMuted ? 'Unmute' : 'Mute'\"\n >\n <!-- Microphone icon (unmuted) -->\n <svg\n *ngIf=\"!isMicMuted\"\n width=\"24\"\n height=\"24\"\n viewBox=\"-5 0 32 32\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"currentColor\"\n >\n <g transform=\"translate(-105, -307)\">\n <path\n d=\"M111,314 C111,311.238 113.239,309 116,309 C118.761,309 121,311.238 121,314 L121,324 C121,326.762 118.761,329 116,329 C113.239,329 111,326.762 111,324 L111,314 L111,314 Z M116,331 C119.866,331 123,327.866 123,324 L123,314 C123,310.134 119.866,307 116,307 C112.134,307 109,310.134 109,314 L109,324 C109,327.866 112.134,331 116,331 L116,331 Z M127,326 L125,326 C124.089,330.007 120.282,333 116,333 C111.718,333 107.911,330.007 107,326 L105,326 C105.883,330.799 110.063,334.51 115,334.955 L115,337 L114,337 C113.448,337 113,337.448 113,338 C113,338.553 113.448,339 114,339 L118,339 C118.552,339 119,338.553 119,338 C119,337.448 118.552,337 118,337 L117,337 L117,334.955 C121.937,334.51 126.117,330.799 127,326 L127,326 Z\"\n />\n </g>\n </svg>\n <!-- Microphone icon (muted) -->\n <svg\n *ngIf=\"isMicMuted\"\n width=\"24\"\n height=\"24\"\n viewBox=\"-5 0 32 32\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"currentColor\"\n >\n <g transform=\"translate(-105, -307)\">\n <path\n d=\"M111,314 C111,311.238 113.239,309 116,309 C118.761,309 121,311.238 121,314 L121,324 C121,326.762 118.761,329 116,329 C113.239,329 111,326.762 111,324 L111,314 L111,314 Z M116,331 C119.866,331 123,327.866 123,324 L123,314 C123,310.134 119.866,307 116,307 C112.134,307 109,310.134 109,314 L109,324 C109,327.866 112.134,331 116,331 L116,331 Z M127,326 L125,326 C124.089,330.007 120.282,333 116,333 C111.718,333 107.911,330.007 107,326 L105,326 C105.883,330.799 110.063,334.51 115,334.955 L115,337 L114,337 C113.448,337 113,337.448 113,338 C113,338.553 113.448,339 114,339 L118,339 C118.552,339 119,338.553 119,338 C119,337.448 118.552,337 118,337 L117,337 L117,334.955 C121.937,334.51 126.117,330.799 127,326 L127,326 Z\"\n />\n </g>\n <path\n d=\"M2 2 L30 30\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n <span class=\"control-label\">Mute</span>\n </div>\n\n <div\n style=\"\n display: flex;\n align-items: center;\n gap: 2px;\n flex-direction: column;\n \"\n >\n <button\n class=\"control-btn end-call-btn\"\n (click)=\"endCall()\"\n type=\"button\"\n title=\"End Call\"\n >\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M18 6L6 18M6 6L18 18\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n <span class=\"control-label\">End Call</span>\n </div>\n </div>\n </div>\n</div>\n",
988
+ template: "<div class=\"voice-agent-modal-overlay\" (click)=\"endCall()\">\n <div\n class=\"voice-container voice-agent-modal\"\n (click)=\"$event.stopPropagation()\"\n >\n <!-- Header -->\n <div class=\"header\">\n <div class=\"header-left\">\n <div class=\"header-icon\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M12 1C8.13 1 5 4.13 5 8V14C5 17.87 8.13 21 12 21C15.87 21 19 17.87 19 14V8C19 4.13 15.87 1 12 1Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M12 23C10.34 23 9 21.66 9 20H15C15 21.66 13.66 23 12 23Z\"\n fill=\"currentColor\"\n />\n </svg>\n </div>\n <span class=\"header-title\">Voice</span>\n </div>\n <button\n class=\"close-button\"\n (click)=\"endCall()\"\n type=\"button\"\n aria-label=\"Close\"\n >\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M18 6L6 18M6 6L18 18\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n </div>\n\n <!-- Avatar Section with glow -->\n <div class=\"avatar-section\">\n <div class=\"avatar-glow\"></div>\n <div class=\"avatar-wrapper\" [class.speaking]=\"isSpeaking\">\n <img class=\"avatar-image\" [src]=\"displayAvatarUrl\" alt=\"Nia\" />\n </div>\n </div>\n\n <!-- Agent Info: Nia + Collaboration Manager AI Agent Specialist -->\n <div class=\"agent-info\">\n <div class=\"agent-name\">\n Nia\n <span class=\"ai-badge\">AI</span>\n </div>\n <p class=\"agent-role\">Collaboration Manager AI Agent Specialist</p>\n </div>\n\n <!-- Start Call (when idle only) -->\n <div *ngIf=\"callState === 'idle'\" class=\"start-call-section\">\n <p *ngIf=\"statusText === 'Connection failed'\" class=\"error-message\">\n {{ statusText }}\n </p>\n <button\n class=\"start-call-button\"\n type=\"button\"\n [disabled]=\"isConnecting\"\n (click)=\"startCall()\"\n >\n <span *ngIf=\"isConnecting\">Connecting...</span>\n <span *ngIf=\"!isConnecting && statusText === 'Connection failed'\"\n >Retry</span\n >\n <span *ngIf=\"!isConnecting && statusText !== 'Connection failed'\"\n >Start Call</span\n >\n </button>\n </div>\n\n <!-- Call Ended: status + Call Again / Back to Chat -->\n <div *ngIf=\"callState === 'ended'\" class=\"call-ended-section\">\n <p class=\"call-ended-status\">\n <span class=\"status-text\">Call Ended</span>\n <span class=\"status-timer\">{{ duration }}</span>\n </p>\n <div class=\"call-ended-controls\">\n <button\n class=\"action-btn\"\n type=\"button\"\n (click)=\"callAgain()\"\n title=\"Call Again\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\" />\n <path d=\"M3 3v5h5\" />\n </svg>\n Call Again\n </button>\n <button\n class=\"action-btn\"\n type=\"button\"\n (click)=\"backToChat()\"\n title=\"Back to Chat\"\n >\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\n </svg>\n Back to Chat\n </button>\n </div>\n </div>\n\n <!-- Status (when connecting or in-call: Talking... / Listening / Connected + timer) -->\n <div\n class=\"status-indicator status-inline\"\n *ngIf=\"callState !== 'idle' && callState !== 'ended'\"\n >\n <div *ngIf=\"callState === 'connecting'\" class=\"status-connecting\">\n <svg\n class=\"spinner\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-dasharray=\"31.416\"\n stroke-dashoffset=\"31.416\"\n >\n <animate\n attributeName=\"stroke-dasharray\"\n dur=\"2s\"\n values=\"0 31.416;15.708 15.708;0 31.416;0 31.416\"\n repeatCount=\"indefinite\"\n />\n <animate\n attributeName=\"stroke-dashoffset\"\n dur=\"2s\"\n values=\"0;-15.708;-31.416;-31.416\"\n repeatCount=\"indefinite\"\n />\n </circle>\n </svg>\n <span class=\"status-text\">{{ statusText }}</span>\n </div>\n <div\n *ngIf=\"callState !== 'connecting'\"\n class=\"status-connected status-inline-row\"\n >\n <span class=\"status-text\">{{ statusLabel }}</span>\n <span class=\"status-timer\">{{ duration }}</span>\n </div>\n </div>\n\n <!-- Waveform -->\n <div\n *ngIf=\"\n callState === 'connected' ||\n callState === 'listening' ||\n callState === 'talking'\n \"\n class=\"waveform-container\"\n >\n <div class=\"waveform-bars\">\n <div\n *ngFor=\"let level of audioLevels; let i = index\"\n class=\"waveform-bar\"\n [style.height.px]=\"getWaveformHeight(level)\"\n ></div>\n </div>\n </div>\n\n <!-- Call Controls (when connected) -->\n <div\n class=\"controls\"\n *ngIf=\"\n callState === 'connected' ||\n callState === 'listening' ||\n callState === 'talking'\n \"\n >\n <div\n style=\"\n display: flex;\n align-items: center;\n gap: 2px;\n flex-direction: column;\n \"\n >\n <button\n class=\"control-btn mic-btn\"\n [class.muted]=\"isMicMuted\"\n (click)=\"toggleMic()\"\n type=\"button\"\n [title]=\"isMicMuted ? 'Unmute' : 'Mute'\"\n >\n <!-- Microphone icon (unmuted) -->\n <svg\n *ngIf=\"!isMicMuted\"\n width=\"24\"\n height=\"24\"\n viewBox=\"-5 0 32 32\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"currentColor\"\n >\n <g transform=\"translate(-105, -307)\">\n <path\n d=\"M111,314 C111,311.238 113.239,309 116,309 C118.761,309 121,311.238 121,314 L121,324 C121,326.762 118.761,329 116,329 C113.239,329 111,326.762 111,324 L111,314 L111,314 Z M116,331 C119.866,331 123,327.866 123,324 L123,314 C123,310.134 119.866,307 116,307 C112.134,307 109,310.134 109,314 L109,324 C109,327.866 112.134,331 116,331 L116,331 Z M127,326 L125,326 C124.089,330.007 120.282,333 116,333 C111.718,333 107.911,330.007 107,326 L105,326 C105.883,330.799 110.063,334.51 115,334.955 L115,337 L114,337 C113.448,337 113,337.448 113,338 C113,338.553 113.448,339 114,339 L118,339 C118.552,339 119,338.553 119,338 C119,337.448 118.552,337 118,337 L117,337 L117,334.955 C121.937,334.51 126.117,330.799 127,326 L127,326 Z\"\n />\n </g>\n </svg>\n <!-- Microphone icon (muted) -->\n <svg\n *ngIf=\"isMicMuted\"\n width=\"24\"\n height=\"24\"\n viewBox=\"-5 0 32 32\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"currentColor\"\n >\n <g transform=\"translate(-105, -307)\">\n <path\n d=\"M111,314 C111,311.238 113.239,309 116,309 C118.761,309 121,311.238 121,314 L121,324 C121,326.762 118.761,329 116,329 C113.239,329 111,326.762 111,324 L111,314 L111,314 Z M116,331 C119.866,331 123,327.866 123,324 L123,314 C123,310.134 119.866,307 116,307 C112.134,307 109,310.134 109,314 L109,324 C109,327.866 112.134,331 116,331 L116,331 Z M127,326 L125,326 C124.089,330.007 120.282,333 116,333 C111.718,333 107.911,330.007 107,326 L105,326 C105.883,330.799 110.063,334.51 115,334.955 L115,337 L114,337 C113.448,337 113,337.448 113,338 C113,338.553 113.448,339 114,339 L118,339 C118.552,339 119,338.553 119,338 C119,337.448 118.552,337 118,337 L117,337 L117,334.955 C121.937,334.51 126.117,330.799 127,326 L127,326 Z\"\n />\n </g>\n <path\n d=\"M2 2 L30 30\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n <span class=\"control-label\">Mute</span>\n </div>\n\n <div\n style=\"\n display: flex;\n align-items: center;\n gap: 2px;\n flex-direction: column;\n \"\n >\n <button\n class=\"control-btn end-call-btn\"\n (click)=\"hangUp()\"\n type=\"button\"\n title=\"End Call\"\n >\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M18 6L6 18M6 6L18 18\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n </button>\n <span class=\"control-label\">End Call</span>\n </div>\n </div>\n </div>\n</div>\n",
976
989
  styles: [":host{display:block}.voice-agent-modal-overlay{align-items:flex-end;backdrop-filter:blur(4px);background:rgba(0,0,0,.5);bottom:0;display:flex;font-family:Segoe UI,Tahoma,Geneva,Verdana,sans-serif;justify-content:flex-end;left:0;padding:24px;position:fixed;right:0;top:0;z-index:99999}.voice-container.voice-agent-modal{align-items:center;animation:modalEnter .3s ease-out;background:#fff;border-radius:30px;box-shadow:0 10px 40px rgba(0,0,0,.1);display:flex;flex-direction:column;max-width:440px;min-height:600px;padding:30px;position:relative;text-align:center;width:100%}@keyframes modalEnter{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}.header{justify-content:space-between;margin-bottom:5px;width:100%}.header,.header-left{align-items:center;display:flex}.header-left{gap:8px}.header-icon{align-items:center;background:#0f172a;border-radius:50%;color:#fff;display:flex;height:28px;justify-content:center;width:28px}.header-title{color:#0f172a;font-size:18px;font-weight:500}.close-button{align-items:center;background:none;border:none;color:#0f172a;cursor:pointer;display:flex;justify-content:center;padding:8px;transition:color .2s}.close-button:hover{color:#475569}.avatar-section{margin-bottom:24px;position:relative}.avatar-wrapper{align-items:center;background:#0ea5a4;background:linear-gradient(135deg,#ccfbf1,#0ea5a4);border-radius:50%;display:flex;height:180px;justify-content:center;padding:6px;position:relative;width:180px}.avatar-image{-o-object-fit:cover;border:4px solid #fff;border-radius:50%;height:100%;object-fit:cover;width:100%}.avatar-glow{background:radial-gradient(circle,rgba(14,165,164,.2) 0,transparent 70%);height:240px;left:50%;pointer-events:none;position:absolute;top:50%;transform:translate(-50%,-50%);width:240px;z-index:-1}.avatar-wrapper.speaking{animation:avatarPulse 2s ease-in-out infinite}@keyframes avatarPulse{0%,to{box-shadow:0 0 0 0 rgba(14,165,164,.4)}50%{box-shadow:0 0 0 15px rgba(14,165,164,0)}}.agent-info{margin-bottom:40px}.agent-name{align-items:center;color:#0f172a;display:flex;font-size:24px;font-weight:700;gap:8px;justify-content:center;margin-bottom:8px}.ai-badge{background:#0ea5a4;border-radius:6px;color:#fff;font-size:10px;font-weight:700;padding:2px 6px}.agent-role{color:#0f172a;font-size:16px;font-weight:500;margin:0}.start-call-section{align-items:center;display:flex;flex-direction:column;gap:16px;margin-bottom:24px}.error-message{color:#dc2626;font-size:14px;margin:0}.start-call-button{background:#0ea5a4;border:none;border-radius:12px;color:#fff;cursor:pointer;font-size:16px;font-weight:600;padding:14px 32px;transition:background .2s}.start-call-button:hover:not(:disabled){background:#0d9488}.start-call-button:disabled{cursor:not-allowed;opacity:.7}.status-indicator{justify-content:center;margin-bottom:10px}.status-connecting,.status-indicator{align-items:center;display:flex;gap:12px}.spinner{animation:spin 1s linear infinite;color:#0ea5a4}@keyframes spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.status-text{font-weight:400}.status-text,.status-timer{color:#0f172a;font-size:16px}.status-timer{font-weight:500}.status-connected{align-items:center;display:flex;flex-direction:column;gap:4px}.status-inline .status-inline-row{align-items:center;flex-direction:row;gap:8px}.call-ended-section{align-items:center;display:flex;flex-direction:column;gap:16px;margin-bottom:24px}.call-ended-status{align-items:center;color:#0f172a;display:flex;font-size:16px;gap:8px;justify-content:center;margin:0}.call-ended-status .status-text{font-weight:400}.call-ended-status .status-timer{font-weight:500}.call-ended-controls{align-items:center;display:flex;flex-wrap:wrap;gap:16px;justify-content:center}.action-btn{align-items:center;background:#fff;border:1px solid #e2e8f0;border-radius:24px;color:#0f172a;cursor:pointer;display:flex;font-size:14px;font-weight:500;gap:8px;padding:12px 24px;transition:background .2s ease}.action-btn:hover{background:#f8fafc}.waveform-container{margin-bottom:10px;padding:0 20px}.waveform-bars,.waveform-container{align-items:center;display:flex;gap:3px;height:60px;justify-content:center}.waveform-bar{background:linear-gradient(180deg,#94a3b8,#64748b);border-radius:2px;box-shadow:0 0 3px rgba(100,116,139,.2);max-height:20px;min-height:3px;transition:height .15s ease-in-out;width:3px}.waveform-bar:nth-child(2n){background:linear-gradient(180deg,#cbd5e1,#94a3b8)}.waveform-bar:nth-child(3n){background:linear-gradient(180deg,#64748b,#475569)}.controls{gap:24px;width:100%}.control-btn,.controls{align-items:center;display:flex;justify-content:center}.control-btn{border:none;border-radius:50%;cursor:pointer;flex-direction:column;gap:4px;height:60px;transition:transform .2s ease;width:60px}.control-btn:hover{transform:scale(1.05)}.control-btn:active{transform:scale(.95)}.control-label{color:#0f172a;font-size:12px;font-weight:500}.mic-btn{background:#e2e8f0}.mic-btn,.mic-btn .control-label{color:#475569}.mic-btn.muted{background:#e2e8f0;color:#475569}.end-call-btn{background:#ef4444;color:#fff}.end-call-btn .control-label{color:#fff}.end-call-btn:hover{background:#dc2626}"]
977
990
  },] }
978
991
  ];