@aakash58/chatbot 1.1.22 → 1.1.25

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.
Files changed (168) hide show
  1. package/fesm2022/aakash58-chatbot.mjs +684 -654
  2. package/fesm2022/aakash58-chatbot.mjs.map +1 -1
  3. package/index.d.ts +374 -3
  4. package/package.json +2 -4
  5. package/esm2022/aakash58-chatbot.mjs +0 -5
  6. package/esm2022/lib/app/chat/chat-ui-state.service.mjs +0 -170
  7. package/esm2022/lib/app/chat/chat.service.mjs +0 -445
  8. package/esm2022/lib/app/chat/components/chat-button/chat-button.component.mjs +0 -50
  9. package/esm2022/lib/app/chat/components/chat-footer/chat-footer.component.mjs +0 -12
  10. package/esm2022/lib/app/chat/components/chat-header/chat-header.component.mjs +0 -66
  11. package/esm2022/lib/app/chat/components/chat-history-sidebar/chat-history-sidebar.component.mjs +0 -186
  12. package/esm2022/lib/app/chat/components/chat-window/chat-window.component.mjs +0 -312
  13. package/esm2022/lib/app/chat/components/message-input/message-input.component.mjs +0 -36
  14. package/esm2022/lib/app/chat/components/message-list/message-list.component.mjs +0 -115
  15. package/esm2022/lib/app/chat/model/chat-history.model.mjs +0 -2
  16. package/esm2022/lib/app/chat/model/chat-request.model.mjs +0 -2
  17. package/esm2022/lib/app/chat/model/chat-response.model.mjs +0 -2
  18. package/esm2022/lib/app/chat/model/chat-session.model.mjs +0 -2
  19. package/esm2022/lib/app/chat/model/chat-stream-message.model.mjs +0 -2
  20. package/esm2022/lib/app/chat/model/chat-stream-response.model.mjs +0 -2
  21. package/esm2022/lib/app/chat/services/chat-api.service.mjs +0 -61
  22. package/esm2022/lib/app/chat/services/chat-audio.service.mjs +0 -50
  23. package/esm2022/lib/app/chat/services/chat-history.service.mjs +0 -252
  24. package/esm2022/lib/app/login/login-form.component.mjs +0 -46
  25. package/esm2022/lib/app/personalization/personalization-dialog.component.mjs +0 -194
  26. package/esm2022/lib/app/personalization/personalization.service.mjs +0 -149
  27. package/esm2022/lib/app/personalization/sections/account/account-section.component.mjs +0 -122
  28. package/esm2022/lib/app/personalization/sections/preferences/color-picker-dialog.component.mjs +0 -86
  29. package/esm2022/lib/app/personalization/sections/preferences/preferences-section.component.mjs +0 -115
  30. package/esm2022/lib/app/personalization/sections/profile/profile-section.component.mjs +0 -29
  31. package/esm2022/lib/app/personalization/sections/settings/setting-section.component.mjs +0 -30
  32. package/esm2022/lib/app/personalization/sections/terms/terms-section.component.mjs +0 -12
  33. package/esm2022/lib/constant/doohbot-constant.mjs +0 -28
  34. package/esm2022/lib/constant/html-entities.mjs +0 -9
  35. package/esm2022/lib/constant/utf8.mjs +0 -10
  36. package/esm2022/lib/core/app-const.mjs +0 -61
  37. package/esm2022/lib/core/auth/account-api.service.mjs +0 -40
  38. package/esm2022/lib/core/auth/auth.service.mjs +0 -391
  39. package/esm2022/lib/core/auth/models/auth-result.model.mjs +0 -3
  40. package/esm2022/lib/core/auth/models/federated-login-request.model.mjs +0 -6
  41. package/esm2022/lib/core/auth/models/login-request.model.mjs +0 -6
  42. package/esm2022/lib/core/auth/storage.service.mjs +0 -110
  43. package/esm2022/lib/core/directives/draggable/draggable-dialog.directive.mjs +0 -112
  44. package/esm2022/lib/core/directives/fullscreen/fullscreen.directive.mjs +0 -55
  45. package/esm2022/lib/core/directives/resizable/resizable-dialog.directive.mjs +0 -179
  46. package/esm2022/lib/core/environments/environment.mjs +0 -15
  47. package/esm2022/lib/core/environments/environment.prod.mjs +0 -15
  48. package/esm2022/lib/core/helpers/crypto-helper.service.mjs +0 -52
  49. package/esm2022/lib/core/http/http-stream.service.mjs +0 -97
  50. package/esm2022/lib/core/http/http.service.mjs +0 -103
  51. package/esm2022/lib/core/interceptors/auth.interceptor.mjs +0 -96
  52. package/esm2022/lib/core/interceptors/license.interceptor.mjs +0 -44
  53. package/esm2022/lib/core/models/api-config.model.mjs +0 -18
  54. package/esm2022/lib/core/models/api-request.model.mjs +0 -2
  55. package/esm2022/lib/core/models/api-response.model.mjs +0 -8
  56. package/esm2022/lib/core/models/doohbot-config.model.mjs +0 -18
  57. package/esm2022/lib/core/models/license.model.mjs +0 -2
  58. package/esm2022/lib/core/models/message.mjs +0 -2
  59. package/esm2022/lib/core/models/theme-config.model.mjs +0 -2
  60. package/esm2022/lib/core/services/core-config.service.mjs +0 -52
  61. package/esm2022/lib/core/services/license.service.mjs +0 -145
  62. package/esm2022/lib/core/services/markdown.service.mjs +0 -64
  63. package/esm2022/lib/core/services/theme.service.mjs +0 -248
  64. package/esm2022/lib/core/types/auth-mode.type.mjs +0 -2
  65. package/esm2022/lib/core/types/auth-status.type.mjs +0 -5
  66. package/esm2022/lib/core/types/chat-stream.type.mjs +0 -2
  67. package/esm2022/lib/core/types/message-role.type.mjs +0 -2
  68. package/esm2022/lib/core/types/prompt-mode.type.mjs +0 -5
  69. package/esm2022/lib/core/types/snackbar-error.type.mjs +0 -5
  70. package/esm2022/lib/core/types/tenant-resolution-strategy.type.mjs +0 -2
  71. package/esm2022/lib/core/utils/logger.service.mjs +0 -42
  72. package/esm2022/lib/doohbot-input.mjs +0 -20
  73. package/esm2022/lib/doohbot.component.mjs +0 -444
  74. package/esm2022/lib/predefined_messages.mjs +0 -15
  75. package/esm2022/lib/shared/chips/chips.component.mjs +0 -28
  76. package/esm2022/lib/shared/dialog/dialog.component.mjs +0 -36
  77. package/esm2022/lib/shared/dialog/dialog.service.mjs +0 -64
  78. package/esm2022/lib/shared/dialog/dialog.utils.mjs +0 -85
  79. package/esm2022/lib/shared/dropdown-menu/dropdown-menu.component.mjs +0 -29
  80. package/esm2022/lib/shared/input-dialog/input-dialog.component.mjs +0 -38
  81. package/esm2022/lib/shared/menu-item/menu-item.component.mjs +0 -24
  82. package/esm2022/lib/shared/pipes/simple-markdown.pipe.mjs +0 -27
  83. package/esm2022/lib/shared/snackbar/snackbar.component.mjs +0 -43
  84. package/esm2022/lib/shared/snackbar/snackbar.service.mjs +0 -46
  85. package/esm2022/lib/shared/snackbar/snackbar.utils.mjs +0 -43
  86. package/esm2022/public-api.mjs +0 -37
  87. package/lib/app/chat/chat-ui-state.service.d.ts +0 -96
  88. package/lib/app/chat/chat.service.d.ts +0 -88
  89. package/lib/app/chat/components/chat-button/chat-button.component.d.ts +0 -16
  90. package/lib/app/chat/components/chat-footer/chat-footer.component.d.ts +0 -5
  91. package/lib/app/chat/components/chat-header/chat-header.component.d.ts +0 -24
  92. package/lib/app/chat/components/chat-history-sidebar/chat-history-sidebar.component.d.ts +0 -49
  93. package/lib/app/chat/components/chat-window/chat-window.component.d.ts +0 -107
  94. package/lib/app/chat/components/message-input/message-input.component.d.ts +0 -12
  95. package/lib/app/chat/components/message-list/message-list.component.d.ts +0 -40
  96. package/lib/app/chat/model/chat-history.model.d.ts +0 -51
  97. package/lib/app/chat/model/chat-request.model.d.ts +0 -10
  98. package/lib/app/chat/model/chat-response.model.d.ts +0 -9
  99. package/lib/app/chat/model/chat-session.model.d.ts +0 -12
  100. package/lib/app/chat/model/chat-stream-message.model.d.ts +0 -5
  101. package/lib/app/chat/model/chat-stream-response.model.d.ts +0 -10
  102. package/lib/app/chat/services/chat-api.service.d.ts +0 -30
  103. package/lib/app/chat/services/chat-audio.service.d.ts +0 -19
  104. package/lib/app/chat/services/chat-history.service.d.ts +0 -53
  105. package/lib/app/login/login-form.component.d.ts +0 -20
  106. package/lib/app/personalization/personalization-dialog.component.d.ts +0 -53
  107. package/lib/app/personalization/personalization.service.d.ts +0 -66
  108. package/lib/app/personalization/sections/account/account-section.component.d.ts +0 -30
  109. package/lib/app/personalization/sections/preferences/color-picker-dialog.component.d.ts +0 -17
  110. package/lib/app/personalization/sections/preferences/preferences-section.component.d.ts +0 -27
  111. package/lib/app/personalization/sections/profile/profile-section.component.d.ts +0 -17
  112. package/lib/app/personalization/sections/settings/setting-section.component.d.ts +0 -10
  113. package/lib/app/personalization/sections/terms/terms-section.component.d.ts +0 -5
  114. package/lib/constant/doohbot-constant.d.ts +0 -12
  115. package/lib/constant/html-entities.d.ts +0 -8
  116. package/lib/constant/utf8.d.ts +0 -9
  117. package/lib/core/app-const.d.ts +0 -11
  118. package/lib/core/auth/account-api.service.d.ts +0 -20
  119. package/lib/core/auth/auth.service.d.ts +0 -90
  120. package/lib/core/auth/models/auth-result.model.d.ts +0 -4
  121. package/lib/core/auth/models/federated-login-request.model.d.ts +0 -5
  122. package/lib/core/auth/models/login-request.model.d.ts +0 -6
  123. package/lib/core/auth/storage.service.d.ts +0 -21
  124. package/lib/core/directives/draggable/draggable-dialog.directive.d.ts +0 -23
  125. package/lib/core/directives/fullscreen/fullscreen.directive.d.ts +0 -14
  126. package/lib/core/directives/resizable/resizable-dialog.directive.d.ts +0 -30
  127. package/lib/core/environments/environment.d.ts +0 -7
  128. package/lib/core/environments/environment.prod.d.ts +0 -7
  129. package/lib/core/helpers/crypto-helper.service.d.ts +0 -12
  130. package/lib/core/http/http-stream.service.d.ts +0 -18
  131. package/lib/core/http/http.service.d.ts +0 -20
  132. package/lib/core/interceptors/auth.interceptor.d.ts +0 -18
  133. package/lib/core/interceptors/license.interceptor.d.ts +0 -11
  134. package/lib/core/models/api-config.model.d.ts +0 -58
  135. package/lib/core/models/api-request.model.d.ts +0 -77
  136. package/lib/core/models/api-response.model.d.ts +0 -6
  137. package/lib/core/models/doohbot-config.model.d.ts +0 -81
  138. package/lib/core/models/license.model.d.ts +0 -23
  139. package/lib/core/models/message.d.ts +0 -16
  140. package/lib/core/models/theme-config.model.d.ts +0 -28
  141. package/lib/core/services/core-config.service.d.ts +0 -23
  142. package/lib/core/services/license.service.d.ts +0 -33
  143. package/lib/core/services/markdown.service.d.ts +0 -8
  144. package/lib/core/services/theme.service.d.ts +0 -40
  145. package/lib/core/types/auth-mode.type.d.ts +0 -4
  146. package/lib/core/types/auth-status.type.d.ts +0 -4
  147. package/lib/core/types/chat-stream.type.d.ts +0 -4
  148. package/lib/core/types/message-role.type.d.ts +0 -4
  149. package/lib/core/types/prompt-mode.type.d.ts +0 -4
  150. package/lib/core/types/snackbar-error.type.d.ts +0 -4
  151. package/lib/core/types/tenant-resolution-strategy.type.d.ts +0 -4
  152. package/lib/core/utils/logger.service.d.ts +0 -11
  153. package/lib/doohbot-input.d.ts +0 -19
  154. package/lib/doohbot.component.d.ts +0 -108
  155. package/lib/predefined_messages.d.ts +0 -2
  156. package/lib/shared/chips/chips.component.d.ts +0 -10
  157. package/lib/shared/dialog/dialog.component.d.ts +0 -19
  158. package/lib/shared/dialog/dialog.service.d.ts +0 -29
  159. package/lib/shared/dialog/dialog.utils.d.ts +0 -41
  160. package/lib/shared/dropdown-menu/dropdown-menu.component.d.ts +0 -11
  161. package/lib/shared/input-dialog/input-dialog.component.d.ts +0 -20
  162. package/lib/shared/menu-item/menu-item.component.d.ts +0 -9
  163. package/lib/shared/pipes/simple-markdown.pipe.d.ts +0 -10
  164. package/lib/shared/snackbar/snackbar.component.d.ts +0 -14
  165. package/lib/shared/snackbar/snackbar.service.d.ts +0 -19
  166. package/lib/shared/snackbar/snackbar.utils.d.ts +0 -33
  167. package/public-api.d.ts +0 -11
  168. package/src/assets/bot.mp3 +0 -0
@@ -1,445 +0,0 @@
1
- import { Injectable, signal, inject, computed } from '@angular/core';
2
- import { Subject, lastValueFrom } from 'rxjs';
3
- import { ChatHistoryService } from './services/chat-history.service';
4
- // Extracted Services
5
- import { ChatApiService } from './services/chat-api.service';
6
- import { ChatAudioService } from './services/chat-audio.service';
7
- import { SnackbarUtils } from '../../shared/snackbar/snackbar.utils';
8
- import { DOOHBOT_ADVANCED_CONFIG } from '../../core/models/doohbot-config.model';
9
- import logger from '../../core/utils/logger.service';
10
- import { AuthService } from './../../core/auth/auth.service';
11
- import { ChatUIStateService } from './chat-ui-state.service';
12
- import { PersonalizationService } from '../personalization/personalization.service';
13
- import * as i0 from "@angular/core";
14
- export class ChatService {
15
- getFallbackReply() {
16
- return "I'm sorry 😔, I didn't understand that.";
17
- }
18
- getFallbackError() {
19
- return 'Something went wrong. Please try again.';
20
- }
21
- constructor() {
22
- // Dependencies
23
- this.apiService = inject(ChatApiService);
24
- this.authService = inject(AuthService);
25
- this.audioService = inject(ChatAudioService);
26
- this.config = inject(DOOHBOT_ADVANCED_CONFIG, { optional: true });
27
- this.chatHistoryService = inject(ChatHistoryService);
28
- this.chatUIStateService = inject(ChatUIStateService);
29
- this.personalization = inject(PersonalizationService);
30
- this.chatSessions = this.chatHistoryService.sessions;
31
- // Public messages signal for current context
32
- this.messages = signal([]);
33
- /**
34
- * Determine if suggestion chips should be shown
35
- */
36
- this.showSuggestionChips = computed(() => {
37
- const msgs = this.messages();
38
- if (msgs.length === 0)
39
- return false;
40
- const lastBotMsg = [...msgs].reverse().find((m) => m.sender === 'assistant');
41
- return lastBotMsg?.showSuggestions === true;
42
- });
43
- // Active session
44
- this.activeSession = null;
45
- // UI state signals (Keep these here as they are relevant to the Chat UI state)
46
- this.isLoadingApi = signal(false);
47
- this.apiError = signal(null);
48
- this.isBotTyping = signal(false);
49
- this.promptMode = signal('markdown');
50
- this.isStreaming = signal(true); //! `isStreaming` is set to true by default
51
- this.messagesStream = [];
52
- this.currentResponse = '';
53
- this.cancelSubject = new Subject();
54
- logger.log('ChatService: Initialized');
55
- // Initialize prompt mode from config if available
56
- if (this.config?.promptMode) {
57
- this.promptMode.set(this.config.promptMode);
58
- }
59
- }
60
- //! ==================== STATE MANAGEMENT ====================
61
- /**
62
- * Generate a unique session ID
63
- */
64
- generateSessionId() {
65
- if (typeof crypto !== 'undefined' && crypto.randomUUID) {
66
- return `session_${crypto.randomUUID()}`;
67
- }
68
- return `session_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`;
69
- }
70
- /**
71
- * Create a new chat session
72
- */
73
- createSession(userId) {
74
- return {
75
- id: this.generateSessionId(),
76
- timestamp: new Date(),
77
- title: 'New Conversation',
78
- messages: [],
79
- userId,
80
- };
81
- }
82
- /**
83
- * Start a new chat session
84
- */
85
- startNewSession() {
86
- // this.cancelRequest(); //! Cancel any ongoing request before starting new session
87
- const userId = this.authService.getUserId();
88
- this.isBotTyping.set(false);
89
- this.isLoadingApi.set(false);
90
- this.activeSession = this.createSession(userId);
91
- this.messages.set([]);
92
- }
93
- /**
94
- * Load an existing session
95
- */
96
- loadSession(session) {
97
- logger.log('[ChatService] Loading session:', session.id, 'Messages:', session.messages.length);
98
- this.activeSession = session;
99
- this.messages.set([...session.messages]);
100
- logger.log('[ChatService] Messages signal updated. Current count:', this.messages().length);
101
- }
102
- /**
103
- * Get active session
104
- */
105
- getActiveSession() {
106
- return this.activeSession;
107
- }
108
- /**
109
- * Clear messages for current session and start new one
110
- */
111
- clearMessages() {
112
- this.messages.set([]);
113
- this.startNewSession();
114
- }
115
- /**
116
- * Add message to current session
117
- */
118
- addMessage(message) {
119
- const newMessage = { ...message, timestamp: new Date() };
120
- // Update current messages signal
121
- this.messages.update((msgs) => [...msgs, newMessage]);
122
- // Save to active session (Server handles actual storage, UI just adds to local signal for immediate feedback)
123
- if (message.sender === 'assistant') {
124
- this.audioService.playBotSound();
125
- }
126
- }
127
- /**
128
- * Continue a chat session
129
- */
130
- continueSession(sessionId) {
131
- logger.log(`[ChatService] continuing session: ${sessionId}`);
132
- this.chatHistoryService.loadSessionMessages(sessionId).subscribe((messages) => {
133
- const loadedMessages = messages || [];
134
- const sessionFromList = this.chatSessions().find((s) => s.id === sessionId);
135
- if (sessionFromList) {
136
- sessionFromList.messages = loadedMessages;
137
- this.loadSession(sessionFromList);
138
- }
139
- else {
140
- const timestamp = loadedMessages.length > 0
141
- ? loadedMessages[loadedMessages.length - 1].timestamp || new Date()
142
- : new Date();
143
- const userId = this.authService.getUserId();
144
- const newSession = {
145
- id: sessionId,
146
- timestamp: timestamp,
147
- title: 'Previous Conversation',
148
- messages: loadedMessages,
149
- userId,
150
- };
151
- this.loadSession(newSession);
152
- }
153
- this.audioService.unlockAudio();
154
- this.chatUIStateService.openChat();
155
- });
156
- }
157
- //! ==================== MESSAGE PROCESSING ====================
158
- /**
159
- * Process a user message: add it, get bot reply, and add bot reply
160
- */
161
- async sendMessage(text, maxLength = 1000) {
162
- const trimmedText = text.trim();
163
- if (!trimmedText) {
164
- return;
165
- }
166
- if (trimmedText.length > maxLength) {
167
- SnackbarUtils.error(`Message exceeds maximum length of ${maxLength} characters.`);
168
- return;
169
- }
170
- //! Cancel any ongoing request before starting a new one
171
- if (this.isBotTyping()) {
172
- this.cancelRequest();
173
- }
174
- const currentSessionId = this.activeSession?.id;
175
- this.addMessage({
176
- sender: 'user',
177
- text: text,
178
- completed: true,
179
- isHistory: false,
180
- id: Date.now().toString(),
181
- timestamp: new Date(),
182
- });
183
- this.isBotTyping.set(true);
184
- try {
185
- const response = await this.getBotReply(text);
186
- // Check if session has changed while waiting for response
187
- if (this.activeSession?.id !== currentSessionId) {
188
- logger.log(`[ChatService] Ignoring response for session: ${currentSessionId} as active session is now: ${this.activeSession?.id}`);
189
- return;
190
- }
191
- const isFallback = response === this.getFallbackReply();
192
- // Only add completion message if it wasn't handled by streaming (response is not empty string)
193
- if (response !== '') {
194
- this.addMessage({
195
- sender: 'assistant',
196
- text: response,
197
- completed: true,
198
- isHistory: false,
199
- id: Date.now().toString(),
200
- showSuggestions: false, //! Don't show suggestions for fallback reply
201
- });
202
- }
203
- }
204
- finally {
205
- // Only reset typing if we are still in the same session, or if we want to be safe (though resetting false is usually harmless)
206
- if (this.activeSession?.id === currentSessionId) {
207
- this.isBotTyping.set(false);
208
- }
209
- }
210
- }
211
- //! ==================== API CALLS ====================
212
- async getBotReply(userText) {
213
- logger.log('Requesting bot reply for:', userText);
214
- try {
215
- this.isLoadingApi.set(true);
216
- this.apiError.set(null);
217
- const request = this.buildChatRequest(userText);
218
- //! chat endpoints
219
- if (this.isStreaming()) {
220
- return await this.stream(request);
221
- }
222
- else {
223
- return await this.ask(request);
224
- }
225
- }
226
- catch (error) {
227
- SnackbarUtils.error('An error occurred while getting the bot reply.');
228
- return this.getFallbackError();
229
- }
230
- }
231
- /**
232
- * Builds a chat request payload with the given user text and optional active session
233
- * @param {string} userInput - The text provided by the user
234
- * @returns {ChatRequest} - A chat request payload with the user text and optional active session
235
- * @memberof ChatService
236
- */
237
- buildChatRequest(userText) {
238
- const instructions = this.personalization.getFormattedInstructions();
239
- const finalQuestion = instructions ? `${instructions}\n\n${userText}` : userText;
240
- const request = {
241
- question: finalQuestion,
242
- organization_id: this.authService.getOrganizationId() || '',
243
- prompt_mode: this.promptMode(),
244
- custom_instructions: instructions,
245
- };
246
- if (this.activeSession && !this.activeSession.id.startsWith('session_')) {
247
- request.response_id = this.activeSession.id;
248
- logger.log('>>>> conversation continued:', this.activeSession.id);
249
- }
250
- else {
251
- logger.log('>>>> new conversation started');
252
- }
253
- return request;
254
- }
255
- // ! Ask api endpoint
256
- async ask(request) {
257
- logger.log('>>>>Using Standard Chat Endpoint<<<<');
258
- const responseSubject = new Subject();
259
- const currentSessionId = this.activeSession?.id;
260
- this.streamSubscription = this.apiService.sendMessage(request, true).subscribe({
261
- next: (response) => {
262
- if (this.activeSession?.id === currentSessionId) {
263
- this.isLoadingApi.set(false);
264
- }
265
- if (response?.success && response.data) {
266
- if (this.activeSession?.id === currentSessionId) {
267
- this.mapSessionId(response.data.id);
268
- }
269
- responseSubject.next(response.data.content || this.getFallbackError());
270
- }
271
- else {
272
- responseSubject.next(this.getFallbackError());
273
- }
274
- responseSubject.complete();
275
- },
276
- error: (error) => {
277
- logger.error('Ask error:', error);
278
- if (this.activeSession?.id === currentSessionId) {
279
- this.isLoadingApi.set(false);
280
- this.isBotTyping.set(false);
281
- }
282
- responseSubject.next(this.getFallbackError());
283
- responseSubject.complete();
284
- },
285
- });
286
- // Handle manual cancellation
287
- const cancelSub = this.cancelSubject.subscribe(() => {
288
- responseSubject.next(''); // Resolve with empty string if cancelled
289
- responseSubject.complete();
290
- });
291
- try {
292
- return await lastValueFrom(responseSubject);
293
- }
294
- finally {
295
- cancelSub.unsubscribe();
296
- }
297
- }
298
- // ! Stream api endpoint
299
- async stream(request) {
300
- logger.log('>>>>Using Stream Chat Endpoint<<<<');
301
- this.currentResponse = '';
302
- this.isBotTyping.set(true);
303
- const assistantMessage = {
304
- id: Date.now().toString(),
305
- sender: 'assistant',
306
- text: '',
307
- chunks: [],
308
- timestamp: new Date(),
309
- completed: false,
310
- isHistory: false,
311
- showSuggestions: false,
312
- };
313
- // Add empty bubble after first chunk has been received
314
- this.addMessage(assistantMessage);
315
- const streamComplete$ = new Subject();
316
- let hasStarted = false;
317
- // Handle manual cancellation for stream
318
- const cancelSub = this.cancelSubject.subscribe(() => {
319
- if (!streamComplete$.closed) {
320
- streamComplete$.next('');
321
- streamComplete$.complete();
322
- }
323
- });
324
- this.streamSubscription = this.apiService.sendMessageStream(request).subscribe({
325
- next: (chunk) => {
326
- if (!hasStarted) {
327
- hasStarted = true;
328
- this.isBotTyping.set(false);
329
- // replace response_id in message id
330
- this.messages.update((msgs) => msgs.map((m) => m.id === assistantMessage.id
331
- ? {
332
- ...m,
333
- ...{ id: chunk.id },
334
- }
335
- : m));
336
- assistantMessage.id = chunk.id;
337
- // Map the session ID to the backend-generated one
338
- this.mapSessionId(chunk.response_id || chunk.id);
339
- }
340
- const text = chunk.content ?? '';
341
- if (!text)
342
- return;
343
- // keep message in sync without regeneration
344
- this.messages.update((msgs) => msgs.map((m) => m.id === assistantMessage.id
345
- ? {
346
- ...m,
347
- chunks: [...(m.chunks ?? []), text], // immutable append
348
- }
349
- : m));
350
- // const message = this.messages().find((m) => m.id === assistantMessage.id);
351
- // logger.log('Appending chunk to assistant message:', message?.chunks);
352
- },
353
- complete: () => {
354
- this.isLoadingApi.set(false);
355
- // Mark the chunk stream compelted
356
- this.messages.update((msgs) => msgs.map((m) => (m.id === assistantMessage.id ? { ...m, completed: true } : m)));
357
- // const message = this.messages().find((m) => m.id === assistantMessage.id);
358
- // this.currentResponse += message?.chunks?.join('') ?? '';
359
- // logger.log('Appending chunk to assistant message:', message?.text);
360
- // logger.log('Appending chunk to assistant message:', message?.chunks);
361
- streamComplete$.next(this.currentResponse);
362
- streamComplete$.complete();
363
- },
364
- error: (error) => {
365
- logger.error('Chat error:', error);
366
- SnackbarUtils.error('An error occurred during reply.');
367
- this.isLoadingApi.set(false);
368
- this.isBotTyping.set(false);
369
- SnackbarUtils.error('An error occurred during reply.');
370
- if (!hasStarted)
371
- this.addMessage(assistantMessage);
372
- if (!assistantMessage.text)
373
- assistantMessage.text = this.getFallbackError();
374
- // mark completed, do NOT rebuild content
375
- this.messages.update((msgs) => msgs.map((m) => m.id === assistantMessage.id
376
- ? {
377
- ...m,
378
- completed: true,
379
- isHistory: false,
380
- text: assistantMessage.text,
381
- }
382
- : m));
383
- streamComplete$.next('');
384
- streamComplete$.complete();
385
- // this.finalizeStreamError(assistantMessage, hasStarted, streamComplete$);
386
- },
387
- });
388
- try {
389
- await lastValueFrom(streamComplete$);
390
- }
391
- finally {
392
- cancelSub.unsubscribe();
393
- }
394
- return '';
395
- }
396
- //! -----------------------------------------
397
- cancelRequest() {
398
- this.cancelSubject.next();
399
- // Reset UI states immediately
400
- this.isLoadingApi.set(false);
401
- this.isBotTyping.set(false);
402
- this.currentResponse = '';
403
- if (this.streamSubscription) {
404
- logger.log('Cancelling ongoing chat request...');
405
- this.streamSubscription.unsubscribe();
406
- this.streamSubscription = undefined;
407
- // Clean up assistant messages:
408
- // Remove if completely empty
409
- // Mark as completed if it has content
410
- this.messages.update((msgs) => msgs
411
- .filter((m) => !(m.sender === 'assistant' &&
412
- !m.completed &&
413
- !m.text &&
414
- (!m.chunks || m.chunks.length === 0)))
415
- .map((m) => (m.sender === 'assistant' && !m.completed ? { ...m, completed: true } : m)));
416
- }
417
- }
418
- //! ==================== AUDIO ====================
419
- unlockAudio() {
420
- this.audioService.unlockAudio();
421
- }
422
- /**
423
- * Map local placeholder session ID to backend-generated ID
424
- */
425
- mapSessionId(responseId) {
426
- if (!responseId || !this.activeSession || !this.activeSession.id.startsWith('session_')) {
427
- return;
428
- }
429
- const oldId = this.activeSession.id;
430
- logger.log(`[ChatService] Mapping local session ${oldId} → backend ID ${responseId}`);
431
- // Update active session subject
432
- this.activeSession.id = responseId;
433
- // Trigger history refresh to get the server-generated title
434
- this.chatHistoryService.invalidateCache();
435
- }
436
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ChatService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
437
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ChatService, providedIn: 'root' }); }
438
- }
439
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ChatService, decorators: [{
440
- type: Injectable,
441
- args: [{
442
- providedIn: 'root',
443
- }]
444
- }], ctorParameters: () => [] });
445
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhdC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZG9vaGJvdC9zcmMvbGliL2FwcC9jaGF0L2NoYXQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3JFLE9BQU8sRUFBZ0IsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUU1RCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUVyRSxxQkFBcUI7QUFDckIsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQzdELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ2pFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUVyRSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQztBQUdqRixPQUFPLE1BQU0sTUFBTSxpQ0FBaUMsQ0FBQztBQUdyRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFFN0QsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDN0QsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sNENBQTRDLENBQUM7O0FBS3BGLE1BQU0sT0FBTyxXQUFXO0lBd0N0QixnQkFBZ0I7UUFDZCxPQUFPLHlDQUF5QyxDQUFDO0lBQ25ELENBQUM7SUFFRCxnQkFBZ0I7UUFDZCxPQUFPLHlDQUF5QyxDQUFDO0lBQ25ELENBQUM7SUFFRDtRQS9DQSxlQUFlO1FBQ1AsZUFBVSxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUNwQyxnQkFBVyxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUNsQyxp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OzRGQUVQLFdBQVc7a0JBSHZCLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgc2lnbmFsLCBpbmplY3QsIGNvbXB1dGVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiwgU3ViamVjdCwgbGFzdFZhbHVlRnJvbSB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBDaGF0U2Vzc2lvbiB9IGZyb20gJy4vbW9kZWwvY2hhdC1zZXNzaW9uLm1vZGVsJztcclxuaW1wb3J0IHsgQ2hhdEhpc3RvcnlTZXJ2aWNlIH0gZnJvbSAnLi9zZXJ2aWNlcy9jaGF0LWhpc3Rvcnkuc2VydmljZSc7XHJcblxyXG4vLyBFeHRyYWN0ZWQgU2VydmljZXNcclxuaW1wb3J0IHsgQ2hhdEFwaVNlcnZpY2UgfSBmcm9tICcuL3NlcnZpY2VzL2NoYXQtYXBpLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBDaGF0QXVkaW9TZXJ2aWNlIH0gZnJvbSAnLi9zZXJ2aWNlcy9jaGF0LWF1ZGlvLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBTbmFja2JhclV0aWxzIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3NuYWNrYmFyL3NuYWNrYmFyLnV0aWxzJztcclxuaW1wb3J0IHsgQ2hhdEFwaUVycm9yIH0gZnJvbSAnLi4vLi4vY29yZS9tb2RlbHMvYXBpLXJlcXVlc3QubW9kZWwnO1xyXG5pbXBvcnQgeyBET09IQk9UX0FEVkFOQ0VEX0NPTkZJRyB9IGZyb20gJy4uLy4uL2NvcmUvbW9kZWxzL2Rvb2hib3QtY29uZmlnLm1vZGVsJztcclxuaW1wb3J0IHsgTWVzc2FnZSB9IGZyb20gJy4uLy4uL2NvcmUvbW9kZWxzL21lc3NhZ2UnO1xyXG5pbXBvcnQgeyBQcm9tcHRNb2RlIH0gZnJvbSAnLi4vLi4vY29yZS90eXBlcy9wcm9tcHQtbW9kZS50eXBlJztcclxuaW1wb3J0IGxvZ2dlciBmcm9tICcuLi8uLi9jb3JlL3V0aWxzL2xvZ2dlci5zZXJ2aWNlJztcclxuaW1wb3J0IHsgQ2hhdFJlcXVlc3QgfSBmcm9tICcuL21vZGVsL2NoYXQtcmVxdWVzdC5tb2RlbCc7XHJcbmltcG9ydCB7IENoYXRTdHJlYW1NZXNzYWdlIH0gZnJvbSAnLi9tb2RlbC9jaGF0LXN0cmVhbS1tZXNzYWdlLm1vZGVsJztcclxuaW1wb3J0IHsgQXV0aFNlcnZpY2UgfSBmcm9tICcuLy4uLy4uL2NvcmUvYXV0aC9hdXRoLnNlcnZpY2UnO1xyXG5cclxuaW1wb3J0IHsgQ2hhdFVJU3RhdGVTZXJ2aWNlIH0gZnJvbSAnLi9jaGF0LXVpLXN0YXRlLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBQZXJzb25hbGl6YXRpb25TZXJ2aWNlIH0gZnJvbSAnLi4vcGVyc29uYWxpemF0aW9uL3BlcnNvbmFsaXphdGlvbi5zZXJ2aWNlJztcclxuXHJcbkBJbmplY3RhYmxlKHtcclxuICBwcm92aWRlZEluOiAncm9vdCcsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBDaGF0U2VydmljZSB7XHJcbiAgLy8gRGVwZW5kZW5jaWVzXHJcbiAgcHJpdmF0ZSBhcGlTZXJ2aWNlID0gaW5qZWN0KENoYXRBcGlTZXJ2aWNlKTtcclxuICBwcml2YXRlIGF1dGhTZXJ2aWNlID0gaW5qZWN0KEF1dGhTZXJ2aWNlKTtcclxuICBwcml2YXRlIGF1ZGlvU2VydmljZSA9IGluamVjdChDaGF0QXVkaW9TZXJ2aWNlKTtcclxuICBwcml2YXRlIGNvbmZpZyA9IGluamVjdChET09IQk9UX0FEVkFOQ0VEX0NPTkZJRywgeyBvcHRpb25hbDogdHJ1ZSB9KTtcclxuICBwcml2YXRlIGNoYXRIaXN0b3J5U2VydmljZSA9IGluamVjdChDaGF0SGlzdG9yeVNlcnZpY2UpO1xyXG4gIHByaXZhdGUgY2hhdFVJU3RhdGVTZXJ2aWNlID0gaW5qZWN0KENoYXRVSVN0YXRlU2VydmljZSk7XHJcbiAgcHJpdmF0ZSBwZXJzb25hbGl6YXRpb24gPSBpbmplY3QoUGVyc29uYWxpemF0aW9uU2VydmljZSk7XHJcbiAgcHJpdmF0ZSBjaGF0U2Vzc2lvbnMgPSB0aGlzLmNoYXRIaXN0b3J5U2VydmljZS5zZXNzaW9ucztcclxuXHJcbiAgLy8gUHVibGljIG1lc3NhZ2VzIHNpZ25hbCBmb3IgY3VycmVudCBjb250ZXh0XHJcbiAgcHVibGljIG1lc3NhZ2VzID0gc2lnbmFsPE1lc3NhZ2VbXT4oW10pO1xyXG5cclxuICAvKipcclxuICAgKiBEZXRlcm1pbmUgaWYgc3VnZ2VzdGlvbiBjaGlwcyBzaG91bGQgYmUgc2hvd25cclxuICAgKi9cclxuICBwdWJsaWMgc2hvd1N1Z2dlc3Rpb25DaGlwcyA9IGNvbXB1dGVkKCgpID0+IHtcclxuICAgIGNvbnN0IG1zZ3MgPSB0aGlzLm1lc3NhZ2VzKCk7XHJcbiAgICBpZiAobXNncy5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTtcclxuICAgIGNvbnN0IGxhc3RCb3RNc2cgPSBbLi4ubXNnc10ucmV2ZXJzZSgpLmZpbmQoKG0pID0+IG0uc2VuZGVyID09PSAnYXNzaXN0YW50Jyk7XHJcbiAgICByZXR1cm4gbGFzdEJvdE1zZz8uc2hvd1N1Z2dlc3Rpb25zID09PSB0cnVlO1xyXG4gIH0pO1xyXG5cclxuICAvLyBBY3RpdmUgc2Vzc2lvblxyXG4gIHByaXZhdGUgYWN0aXZlU2Vzc2lvbjogQ2hhdFNlc3Npb24gfCBudWxsID0gbnVsbDtcclxuXHJcbiAgLy8gVUkgc3RhdGUgc2lnbmFscyAoS2VlcCB0aGVzZSBoZXJlIGFzIHRoZXkgYXJlIHJlbGV2YW50IHRvIHRoZSBDaGF0IFVJIHN0YXRlKVxyXG4gIHB1YmxpYyBpc0xvYWRpbmdBcGkgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xyXG4gIHB1YmxpYyBhcGlFcnJvciA9IHNpZ25hbDxDaGF0QXBpRXJyb3IgfCBudWxsPihudWxsKTtcclxuICBwdWJsaWMgaXNCb3RUeXBpbmcgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xyXG4gIHB1YmxpYyBwcm9tcHRNb2RlID0gc2lnbmFsPFByb21wdE1vZGU+KCdtYXJrZG93bicpO1xyXG4gIHB1YmxpYyBpc1N0cmVhbWluZyA9IHNpZ25hbDxib29sZWFuPih0cnVlKTsgLy8hIGBpc1N0cmVhbWluZ2AgaXMgc2V0IHRvIHRydWUgYnkgZGVmYXVsdFxyXG5cclxuICBtZXNzYWdlc1N0cmVhbTogQXJyYXk8Q2hhdFN0cmVhbU1lc3NhZ2U+ID0gW107XHJcbiAgY3VycmVudFJlc3BvbnNlID0gJyc7XHJcblxyXG4gIHByaXZhdGUgc3RyZWFtU3Vic2NyaXB0aW9uPzogU3Vic2NyaXB0aW9uO1xyXG4gIHByaXZhdGUgY2FuY2VsU3ViamVjdCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XHJcblxyXG4gIGdldEZhbGxiYWNrUmVwbHkoKTogc3RyaW5nIHtcclxuICAgIHJldHVybiBcIkknbSBzb3JyeSDwn5iULCBJIGRpZG4ndCB1bmRlcnN0YW5kIHRoYXQuXCI7XHJcbiAgfVxyXG5cclxuICBnZXRGYWxsYmFja0Vycm9yKCk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gJ1NvbWV0aGluZyB3ZW50IHdyb25nLiBQbGVhc2UgdHJ5IGFnYWluLic7XHJcbiAgfVxyXG5cclxuICBjb25zdHJ1Y3RvcigpIHtcclxuICAgIGxvZ2dlci5sb2coJ0NoYXRTZXJ2aWNlOiBJbml0aWFsaXplZCcpO1xyXG5cclxuICAgIC8vIEluaXRpYWxpemUgcHJvbXB0IG1vZGUgZnJvbSBjb25maWcgaWYgYXZhaWxhYmxlXHJcbiAgICBpZiAodGhpcy5jb25maWc/LnByb21wdE1vZGUpIHtcclxuICAgICAgdGhpcy5wcm9tcHRNb2RlLnNldCh0aGlzLmNvbmZpZy5wcm9tcHRNb2RlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vISA9PT09PT09PT09PT09PT09PT09PSBTVEFURSBNQU5BR0VNRU5UID09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gIC8qKlxyXG4gICAqIEdlbmVyYXRlIGEgdW5pcXVlIHNlc3Npb24gSURcclxuICAgKi9cclxuICBwcml2YXRlIGdlbmVyYXRlU2Vzc2lvbklkKCk6IHN0cmluZyB7XHJcbiAgICBpZiAodHlwZW9mIGNyeXB0byAhPT0gJ3VuZGVmaW5lZCcgJiYgY3J5cHRvLnJhbmRvbVVVSUQpIHtcclxuICAgICAgcmV0dXJuIGBzZXNzaW9uXyR7Y3J5cHRvLnJhbmRvbVVVSUQoKX1gO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGBzZXNzaW9uXyR7RGF0ZS5ub3coKX1fJHtNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zdWJzdHJpbmcoMiwgMTUpfWA7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDcmVhdGUgYSBuZXcgY2hhdCBzZXNzaW9uXHJcbiAgICovXHJcbiAgY3JlYXRlU2Vzc2lvbih1c2VySWQ6IHN0cmluZyk6IENoYXRTZXNzaW9uIHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgIGlkOiB0aGlzLmdlbmVyYXRlU2Vzc2lvbklkKCksXHJcbiAgICAgIHRpbWVzdGFtcDogbmV3IERhdGUoKSxcclxuICAgICAgdGl0bGU6ICdOZXcgQ29udmVyc2F0aW9uJyxcclxuICAgICAgbWVzc2FnZXM6IFtdLFxyXG4gICAgICB1c2VySWQsXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU3RhcnQgYSBuZXcgY2hhdCBzZXNzaW9uXHJcbiAgICovXHJcbiAgcHVibGljIHN0YXJ0TmV3U2Vzc2lvbigpOiB2b2lkIHtcclxuICAgIC8vIHRoaXMuY2FuY2VsUmVxdWVzdCgpOyAvLyEgQ2FuY2VsIGFueSBvbmdvaW5nIHJlcXVlc3QgYmVmb3JlIHN0YXJ0aW5nIG5ldyBzZXNzaW9uXHJcbiAgICBjb25zdCB1c2VySWQgPSB0aGlzLmF1dGhTZXJ2aWNlLmdldFVzZXJJZCgpO1xyXG5cclxuICAgIHRoaXMuaXNCb3RUeXBpbmcuc2V0KGZhbHNlKTtcclxuICAgIHRoaXMuaXNMb2FkaW5nQXBpLnNldChmYWxzZSk7XHJcblxyXG4gICAgdGhpcy5hY3RpdmVTZXNzaW9uID0gdGhpcy5jcmVhdGVTZXNzaW9uKHVzZXJJZCk7XHJcbiAgICB0aGlzLm1lc3NhZ2VzLnNldChbXSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBMb2FkIGFuIGV4aXN0aW5nIHNlc3Npb25cclxuICAgKi9cclxuICBwdWJsaWMgbG9hZFNlc3Npb24oc2Vzc2lvbjogQ2hhdFNlc3Npb24pOiB2b2lkIHtcclxuICAgIGxvZ2dlci5sb2coJ1tDaGF0U2VydmljZV0gTG9hZGluZyBzZXNzaW9uOicsIHNlc3Npb24uaWQsICdNZXNzYWdlczonLCBzZXNzaW9uLm1lc3NhZ2VzLmxlbmd0aCk7XHJcbiAgICB0aGlzLmFjdGl2ZVNlc3Npb24gPSBzZXNzaW9uO1xyXG4gICAgdGhpcy5tZXNzYWdlcy5zZXQoWy4uLnNlc3Npb24ubWVzc2FnZXNdKTtcclxuICAgIGxvZ2dlci5sb2coJ1tDaGF0U2VydmljZV0gTWVzc2FnZXMgc2lnbmFsIHVwZGF0ZWQuIEN1cnJlbnQgY291bnQ6JywgdGhpcy5tZXNzYWdlcygpLmxlbmd0aCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgYWN0aXZlIHNlc3Npb25cclxuICAgKi9cclxuICBwdWJsaWMgZ2V0QWN0aXZlU2Vzc2lvbigpOiBDaGF0U2Vzc2lvbiB8IG51bGwge1xyXG4gICAgcmV0dXJuIHRoaXMuYWN0aXZlU2Vzc2lvbjtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENsZWFyIG1lc3NhZ2VzIGZvciBjdXJyZW50IHNlc3Npb24gYW5kIHN0YXJ0IG5ldyBvbmVcclxuICAgKi9cclxuICBjbGVhck1lc3NhZ2VzKCk6IHZvaWQge1xyXG4gICAgdGhpcy5tZXNzYWdlcy5zZXQoW10pO1xyXG4gICAgdGhpcy5zdGFydE5ld1Nlc3Npb24oKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEFkZCBtZXNzYWdlIHRvIGN1cnJlbnQgc2Vzc2lvblxyXG4gICAqL1xyXG4gIHB1YmxpYyBhZGRNZXNzYWdlKG1lc3NhZ2U6IE1lc3NhZ2UpOiB2b2lkIHtcclxuICAgIGNvbnN0IG5ld01lc3NhZ2UgPSB7IC4uLm1lc3NhZ2UsIHRpbWVzdGFtcDogbmV3IERhdGUoKSB9O1xyXG5cclxuICAgIC8vIFVwZGF0ZSBjdXJyZW50IG1lc3NhZ2VzIHNpZ25hbFxyXG4gICAgdGhpcy5tZXNzYWdlcy51cGRhdGUoKG1zZ3MpID0+IFsuLi5tc2dzLCBuZXdNZXNzYWdlXSk7XHJcblxyXG4gICAgLy8gU2F2ZSB0byBhY3RpdmUgc2Vzc2lvbiAoU2VydmVyIGhhbmRsZXMgYWN0dWFsIHN0b3JhZ2UsIFVJIGp1c3QgYWRkcyB0byBsb2NhbCBzaWduYWwgZm9yIGltbWVkaWF0ZSBmZWVkYmFjaylcclxuICAgIGlmIChtZXNzYWdlLnNlbmRlciA9PT0gJ2Fzc2lzdGFudCcpIHtcclxuICAgICAgdGhpcy5hdWRpb1NlcnZpY2UucGxheUJvdFNvdW5kKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDb250aW51ZSBhIGNoYXQgc2Vzc2lvblxyXG4gICAqL1xyXG4gIHB1YmxpYyBjb250aW51ZVNlc3Npb24oc2Vzc2lvbklkOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIGxvZ2dlci5sb2coYFtDaGF0U2VydmljZV0gY29udGludWluZyBzZXNzaW9uOiAke3Nlc3Npb25JZH1gKTtcclxuICAgIHRoaXMuY2hhdEhpc3RvcnlTZXJ2aWNlLmxvYWRTZXNzaW9uTWVzc2FnZXMoc2Vzc2lvbklkKS5zdWJzY3JpYmUoKG1lc3NhZ2VzKSA9PiB7XHJcbiAgICAgIGNvbnN0IGxvYWRlZE1lc3NhZ2VzID0gbWVzc2FnZXMgfHwgW107XHJcbiAgICAgIGNvbnN0IHNlc3Npb25Gcm9tTGlzdCA9IHRoaXMuY2hhdFNlc3Npb25zKCkuZmluZCgocykgPT4gcy5pZCA9PT0gc2Vzc2lvbklkKTtcclxuXHJcbiAgICAgIGlmIChzZXNzaW9uRnJvbUxpc3QpIHtcclxuICAgICAgICBzZXNzaW9uRnJvbUxpc3QubWVzc2FnZXMgPSBsb2FkZWRNZXNzYWdlcztcclxuICAgICAgICB0aGlzLmxvYWRTZXNzaW9uKHNlc3Npb25Gcm9tTGlzdCk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgY29uc3QgdGltZXN0YW1wID1cclxuICAgICAgICAgIGxvYWRlZE1lc3NhZ2VzLmxlbmd0aCA+IDBcclxuICAgICAgICAgICAgPyBsb2FkZWRNZXNzYWdlc1tsb2FkZWRNZXNzYWdlcy5sZW5ndGggLSAxXS50aW1lc3RhbXAgfHwgbmV3IERhdGUoKVxyXG4gICAgICAgICAgICA6IG5ldyBEYXRlKCk7XHJcblxyXG4gICAgICAgIGNvbnN0IHVzZXJJZCA9IHRoaXMuYXV0aFNlcnZpY2UuZ2V0VXNlcklkKCk7XHJcblxyXG4gICAgICAgIGNvbnN0IG5ld1Nlc3Npb246IENoYXRTZXNzaW9uID0ge1xyXG4gICAgICAgICAgaWQ6IHNlc3Npb25JZCxcclxuICAgICAgICAgIHRpbWVzdGFtcDogdGltZXN0YW1wLFxyXG4gICAgICAgICAgdGl0bGU6ICdQcmV2aW91cyBDb252ZXJzYXRpb24nLFxyXG4gICAgICAgICAgbWVzc2FnZXM6IGxvYWRlZE1lc3NhZ2VzLFxyXG4gICAgICAgICAgdXNlcklkLFxyXG4gICAgICAgIH07XHJcbiAgICAgICAgdGhpcy5sb2FkU2Vzc2lvbihuZXdTZXNzaW9uKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdGhpcy5hdWRpb1NlcnZpY2UudW5sb2NrQXVkaW8oKTtcclxuICAgICAgdGhpcy5jaGF0VUlTdGF0ZVNlcnZpY2Uub3BlbkNoYXQoKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLy8hID09PT09PT09PT09PT09PT09PT09IE1FU1NBR0UgUFJPQ0VTU0lORyA9PT09PT09PT09PT09PT09PT09PVxyXG5cclxuICAvKipcclxuICAgKiBQcm9jZXNzIGEgdXNlciBtZXNzYWdlOiBhZGQgaXQsIGdldCBib3QgcmVwbHksIGFuZCBhZGQgYm90IHJlcGx5XHJcbiAgICovXHJcbiAgcHVibGljIGFzeW5jIHNlbmRNZXNzYWdlKHRleHQ6IHN0cmluZywgbWF4TGVuZ3RoOiBudW1iZXIgPSAxMDAwKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBjb25zdCB0cmltbWVkVGV4dCA9IHRleHQudHJpbSgpO1xyXG4gICAgaWYgKCF0cmltbWVkVGV4dCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRyaW1tZWRUZXh0Lmxlbmd0aCA+IG1heExlbmd0aCkge1xyXG4gICAgICBTbmFja2JhclV0aWxzLmVycm9yKGBNZXNzYWdlIGV4Y2VlZHMgbWF4aW11bSBsZW5ndGggb2YgJHttYXhMZW5ndGh9IGNoYXJhY3RlcnMuYCk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICAvLyEgQ2FuY2VsIGFueSBvbmdvaW5nIHJlcXVlc3QgYmVmb3JlIHN0YXJ0aW5nIGEgbmV3IG9uZVxyXG4gICAgaWYgKHRoaXMuaXNCb3RUeXBpbmcoKSkge1xyXG4gICAgICB0aGlzLmNhbmNlbFJlcXVlc3QoKTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBjdXJyZW50U2Vzc2lvbklkID0gdGhpcy5hY3RpdmVTZXNzaW9uPy5pZDtcclxuXHJcbiAgICB0aGlzLmFkZE1lc3NhZ2Uoe1xyXG4gICAgICBzZW5kZXI6ICd1c2VyJyxcclxuICAgICAgdGV4dDogdGV4dCxcclxuICAgICAgY29tcGxldGVkOiB0cnVlLFxyXG4gICAgICBpc0hpc3Rvcnk6IGZhbHNlLFxyXG4gICAgICBpZDogRGF0ZS5ub3coKS50b1N0cmluZygpLFxyXG4gICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKCksXHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLmlzQm90VHlwaW5nLnNldCh0cnVlKTtcclxuXHJcbiAgICB0cnkge1xyXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuZ2V0Qm90UmVwbHkodGV4dCk7XHJcblxyXG4gICAgICAvLyBDaGVjayBpZiBzZXNzaW9uIGhhcyBjaGFuZ2VkIHdoaWxlIHdhaXRpbmcgZm9yIHJlc3BvbnNlXHJcbiAgICAgIGlmICh0aGlzLmFjdGl2ZVNlc3Npb24/LmlkICE9PSBjdXJyZW50U2Vzc2lvbklkKSB7XHJcbiAgICAgICAgbG9nZ2VyLmxvZyhcclxuICAgICAgICAgIGBbQ2hhdFNlcnZpY2VdIElnbm9yaW5nIHJlc3BvbnNlIGZvciBzZXNzaW9uOiAke2N1cnJlbnRTZXNzaW9uSWR9IGFzIGFjdGl2ZSBzZXNzaW9uIGlzIG5vdzogJHt0aGlzLmFjdGl2ZVNlc3Npb24/LmlkfWAsXHJcbiAgICAgICAgKTtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGNvbnN0IGlzRmFsbGJhY2sgPSByZXNwb25zZSA9PT0gdGhpcy5nZXRGYWxsYmFja1JlcGx5KCk7XHJcblxyXG4gICAgICAvLyBPbmx5IGFkZCBjb21wbGV0aW9uIG1lc3NhZ2UgaWYgaXQgd2Fzbid0IGhhbmRsZWQgYnkgc3RyZWFtaW5nIChyZXNwb25zZSBpcyBub3QgZW1wdHkgc3RyaW5nKVxyXG4gICAgICBpZiAocmVzcG9uc2UgIT09ICcnKSB7XHJcbiAgICAgICAgdGhpcy5hZGRNZXNzYWdlKHtcclxuICAgICAgICAgIHNlbmRlcjogJ2Fzc2lzdGFudCcsXHJcbiAgICAgICAgICB0ZXh0OiByZXNwb25zZSxcclxuICAgICAgICAgIGNvbXBsZXRlZDogdHJ1ZSxcclxuICAgICAgICAgIGlzSGlzdG9yeTogZmFsc2UsXHJcbiAgICAgICAgICBpZDogRGF0ZS5ub3coKS50b1N0cmluZygpLFxyXG4gICAgICAgICAgc2hvd1N1Z2dlc3Rpb25zOiBmYWxzZSwgLy8hIERvbid0IHNob3cgc3VnZ2VzdGlvbnMgZm9yIGZhbGxiYWNrIHJlcGx5XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgIH0gZmluYWxseSB7XHJcbiAgICAgIC8vIE9ubHkgcmVzZXQgdHlwaW5nIGlmIHdlIGFyZSBzdGlsbCBpbiB0aGUgc2FtZSBzZXNzaW9uLCBvciBpZiB3ZSB3YW50IHRvIGJlIHNhZmUgKHRob3VnaCByZXNldHRpbmcgZmFsc2UgaXMgdXN1YWxseSBoYXJtbGVzcylcclxuICAgICAgaWYgKHRoaXMuYWN0aXZlU2Vzc2lvbj8uaWQgPT09IGN1cnJlbnRTZXNzaW9uSWQpIHtcclxuICAgICAgICB0aGlzLmlzQm90VHlwaW5nLnNldChmYWxzZSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vISA9PT09PT09PT09PT09PT09PT09PSBBUEkgQ0FMTFMgPT09PT09PT09PT09PT09PT09PT1cclxuXHJcbiAgYXN5bmMgZ2V0Qm90UmVwbHkodXNlclRleHQ6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XHJcbiAgICBsb2dnZXIubG9nKCdSZXF1ZXN0aW5nIGJvdCByZXBseSBmb3I6JywgdXNlclRleHQpO1xyXG5cclxuICAgIHRyeSB7XHJcbiAgICAgIHRoaXMuaXNMb2FkaW5nQXBpLnNldCh0cnVlKTtcclxuICAgICAgdGhpcy5hcGlFcnJvci5zZXQobnVsbCk7XHJcblxyXG4gICAgICBjb25zdCByZXF1ZXN0ID0gdGhpcy5idWlsZENoYXRSZXF1ZXN0KHVzZXJUZXh0KTtcclxuXHJcbiAgICAgIC8vISBjaGF0IGVuZHBvaW50c1xyXG4gICAgICBpZiAodGhpcy5pc1N0cmVhbWluZygpKSB7XHJcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc3RyZWFtKHJlcXVlc3QpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmFzayhyZXF1ZXN0KTtcclxuICAgICAgfVxyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgU25hY2tiYXJVdGlscy5lcnJvcignQW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgZ2V0dGluZyB0aGUgYm90IHJlcGx5LicpO1xyXG4gICAgICByZXR1cm4gdGhpcy5nZXRGYWxsYmFja0Vycm9yKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBCdWlsZHMgYSBjaGF0IHJlcXVlc3QgcGF5bG9hZCB3aXRoIHRoZSBnaXZlbiB1c2VyIHRleHQgYW5kIG9wdGlvbmFsIGFjdGl2ZSBzZXNzaW9uXHJcbiAgICogQHBhcmFtIHtzdHJpbmd9IHVzZXJJbnB1dCAtIFRoZSB0ZXh0IHByb3ZpZGVkIGJ5IHRoZSB1c2VyXHJcbiAgICogQHJldHVybnMge0NoYXRSZXF1ZXN0fSAtIEEgY2hhdCByZXF1ZXN0IHBheWxvYWQgd2l0aCB0aGUgdXNlciB0ZXh0IGFuZCBvcHRpb25hbCBhY3RpdmUgc2Vzc2lvblxyXG4gICAqIEBtZW1iZXJvZiBDaGF0U2VydmljZVxyXG4gICAqL1xyXG5cclxuICBwcml2YXRlIGJ1aWxkQ2hhdFJlcXVlc3QodXNlclRleHQ6IHN0cmluZyk6IENoYXRSZXF1ZXN0IHtcclxuICAgIGNvbnN0IGluc3RydWN0aW9ucyA9IHRoaXMucGVyc29uYWxpemF0aW9uLmdldEZvcm1hdHRlZEluc3RydWN0aW9ucygpO1xyXG4gICAgY29uc3QgZmluYWxRdWVzdGlvbiA9IGluc3RydWN0aW9ucyA/IGAke2luc3RydWN0aW9uc31cXG5cXG4ke3VzZXJUZXh0fWAgOiB1c2VyVGV4dDtcclxuXHJcbiAgICBjb25zdCByZXF1ZXN0OiBDaGF0UmVxdWVzdCA9IHtcclxuICAgICAgcXVlc3Rpb246IGZpbmFsUXVlc3Rpb24sXHJcbiAgICAgIG9yZ2FuaXphdGlvbl9pZDogdGhpcy5hdXRoU2VydmljZS5nZXRPcmdhbml6YXRpb25JZCgpIHx8ICcnLFxyXG4gICAgICBwcm9tcHRfbW9kZTogdGhpcy5wcm9tcHRNb2RlKCksXHJcbiAgICAgIGN1c3RvbV9pbnN0cnVjdGlvbnM6IGluc3RydWN0aW9ucyxcclxuICAgIH07XHJcblxyXG4gICAgaWYgKHRoaXMuYWN0aXZlU2Vzc2lvbiAmJiAhdGhpcy5hY3RpdmVTZXNzaW9uLmlkLnN0YXJ0c1dpdGgoJ3Nlc3Npb25fJykpIHtcclxuICAgICAgcmVxdWVzdC5yZXNwb25zZV9pZCA9IHRoaXMuYWN0aXZlU2Vzc2lvbi5pZDtcclxuICAgICAgbG9nZ2VyLmxvZygnPj4+PiBjb252ZXJzYXRpb24gY29udGludWVkOicsIHRoaXMuYWN0aXZlU2Vzc2lvbi5pZCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBsb2dnZXIubG9nKCc+Pj4+IG5ldyBjb252ZXJzYXRpb24gc3RhcnRlZCcpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiByZXF1ZXN0O1xyXG4gIH1cclxuXHJcbiAgLy8gISBBc2sgYXBpIGVuZHBvaW50XHJcbiAgcHJpdmF0ZSBhc3luYyBhc2socmVxdWVzdDogQ2hhdFJlcXVlc3QpOiBQcm9taXNlPHN0cmluZz4ge1xyXG4gICAgbG9nZ2VyLmxvZygnPj4+PlVzaW5nIFN0YW5kYXJkIENoYXQgRW5kcG9pbnQ8PDw8Jyk7XHJcblxyXG4gICAgY29uc3QgcmVzcG9uc2VTdWJqZWN0ID0gbmV3IFN1YmplY3Q8c3RyaW5nPigpO1xyXG5cclxuICAgIGNvbnN0IGN1cnJlbnRTZXNzaW9uSWQgPSB0aGlzLmFjdGl2ZVNlc3Npb24/LmlkO1xyXG5cclxuICAgIHRoaXMuc3RyZWFtU3Vic2NyaXB0aW9uID0gdGhpcy5hcGlTZXJ2aWNlLnNlbmRNZXNzYWdlKHJlcXVlc3QsIHRydWUpLnN1YnNjcmliZSh7XHJcbiAgICAgIG5leHQ6IChyZXNwb25zZSkgPT4ge1xyXG4gICAgICAgIGlmICh0aGlzLmFjdGl2ZVNlc3Npb24/LmlkID09PSBjdXJyZW50U2Vzc2lvbklkKSB7XHJcbiAgICAgICAgICB0aGlzLmlzTG9hZGluZ0FwaS5zZXQoZmFsc2UpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAocmVzcG9uc2U/LnN1Y2Nlc3MgJiYgcmVzcG9uc2UuZGF0YSkge1xyXG4gICAgICAgICAgaWYgKHRoaXMuYWN0aXZlU2Vzc2lvbj8uaWQgPT09IGN1cnJlbnRTZXNzaW9uSWQpIHtcclxuICAgICAgICAgICAgdGhpcy5tYXBTZXNzaW9uSWQocmVzcG9uc2UuZGF0YS5pZCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICByZXNwb25zZVN1YmplY3QubmV4dChyZXNwb25zZS5kYXRhLmNvbnRlbnQgfHwgdGhpcy5nZXRGYWxsYmFja0Vycm9yKCkpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICByZXNwb25zZVN1YmplY3QubmV4dCh0aGlzLmdldEZhbGxiYWNrRXJyb3IoKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJlc3BvbnNlU3ViamVjdC5jb21wbGV0ZSgpO1xyXG4gICAgICB9LFxyXG4gICAgICBlcnJvcjogKGVycm9yKSA9PiB7XHJcbiAgICAgICAgbG9nZ2VyLmVycm9yKCdBc2sgZXJyb3I6JywgZXJyb3IpO1xyXG4gICAgICAgIGlmICh0aGlzLmFjdGl2ZVNlc3Npb24/LmlkID09PSBjdXJyZW50U2Vzc2lvbklkKSB7XHJcbiAgICAgICAgICB0aGlzLmlzTG9hZGluZ0FwaS5zZXQoZmFsc2UpO1xyXG4gICAgICAgICAgdGhpcy5pc0JvdFR5cGluZy5zZXQoZmFsc2UpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXNwb25zZVN1YmplY3QubmV4dCh0aGlzLmdldEZhbGxiYWNrRXJyb3IoKSk7XHJcbiAgICAgICAgcmVzcG9uc2VTdWJqZWN0LmNvbXBsZXRlKCk7XHJcbiAgICAgIH0sXHJcbiAgICB9KTtcclxuXHJcbiAgICAvLyBIYW5kbGUgbWFudWFsIGNhbmNlbGxhdGlvblxyXG4gICAgY29uc3QgY2FuY2VsU3ViID0gdGhpcy5jYW5jZWxTdWJqZWN0LnN1YnNjcmliZSgoKSA9PiB7XHJcbiAgICAgIHJlc3BvbnNlU3ViamVjdC5uZXh0KCcnKTsgLy8gUmVzb2x2ZSB3aXRoIGVtcHR5IHN0cmluZyBpZiBjYW5jZWxsZWRcclxuICAgICAgcmVzcG9uc2VTdWJqZWN0LmNvbXBsZXRlKCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICB0cnkge1xyXG4gICAgICByZXR1cm4gYXdhaXQgbGFzdFZhbHVlRnJvbShyZXNwb25zZVN1YmplY3QpO1xyXG4gICAgfSBmaW5hbGx5IHtcclxuICAgICAgY2FuY2VsU3ViLnVuc3Vic2NyaWJlKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyAhIFN0cmVhbSBhcGkgZW5kcG9pbnRcclxuICBwcml2YXRlIGFzeW5jIHN0cmVhbShyZXF1ZXN0OiBDaGF0UmVxdWVzdCk6IFByb21pc2U8c3RyaW5nPiB7XHJcbiAgICBsb2dnZXIubG9nKCc+Pj4+VXNpbmcgU3RyZWFtIENoYXQgRW5kcG9pbnQ8PDw8Jyk7XHJcblxyXG4gICAgdGhpcy5jdXJyZW50UmVzcG9uc2UgPSAnJztcclxuICAgIHRoaXMuaXNCb3RUeXBpbmcuc2V0KHRydWUpO1xyXG5cclxuICAgIGNvbnN0IGFzc2lzdGFudE1lc3NhZ2U6IE1lc3NhZ2UgPSB7XHJcbiAgICAgIGlkOiBEYXRlLm5vdygpLnRvU3RyaW5nKCksXHJcbiAgICAgIHNlbmRlcjogJ2Fzc2lzdGFudCcsXHJcbiAgICAgIHRleHQ6ICcnLFxyXG4gICAgICBjaHVua3M6IFtdLFxyXG4gICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKCksXHJcbiAgICAgIGNvbXBsZXRlZDogZmFsc2UsXHJcbiAgICAgIGlzSGlzdG9yeTogZmFsc2UsXHJcbiAgICAgIHNob3dTdWdnZXN0aW9uczogZmFsc2UsXHJcbiAgICB9O1xyXG5cclxuICAgIC8vIEFkZCBlbXB0eSBidWJibGUgYWZ0ZXIgZmlyc3QgY2h1bmsgaGFzIGJlZW4gcmVjZWl2ZWRcclxuICAgIHRoaXMuYWRkTWVzc2FnZShhc3Npc3RhbnRNZXNzYWdlKTtcclxuXHJcbiAgICBjb25zdCBzdHJlYW1Db21wbGV0ZSQgPSBuZXcgU3ViamVjdDxzdHJpbmc+KCk7XHJcbiAgICBsZXQgaGFzU3RhcnRlZCA9IGZhbHNlO1xyXG5cclxuICAgIC8vIEhhbmRsZSBtYW51YWwgY2FuY2VsbGF0aW9uIGZvciBzdHJlYW1cclxuICAgIGNvbnN0IGNhbmNlbFN1YiA9IHRoaXMuY2FuY2VsU3ViamVjdC5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICBpZiAoIXN0cmVhbUNvbXBsZXRlJC5jbG9zZWQpIHtcclxuICAgICAgICBzdHJlYW1Db21wbGV0ZSQubmV4dCgnJyk7XHJcbiAgICAgICAgc3RyZWFtQ29tcGxldGUkLmNvbXBsZXRlKCk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuc3RyZWFtU3Vic2NyaXB0aW9uID0gdGhpcy5hcGlTZXJ2aWNlLnNlbmRNZXNzYWdlU3RyZWFtKHJlcXVlc3QpLnN1YnNjcmliZSh7XHJcbiAgICAgIG5leHQ6IChjaHVuaykgPT4ge1xyXG4gICAgICAgIGlmICghaGFzU3RhcnRlZCkge1xyXG4gICAgICAgICAgaGFzU3RhcnRlZCA9IHRydWU7XHJcbiAgICAgICAgICB0aGlzLmlzQm90VHlwaW5nLnNldChmYWxzZSk7XHJcblxyXG4gICAgICAgICAgLy8gcmVwbGFjZSByZXNwb25zZV9pZCBpbiBtZXNzYWdlIGlkXHJcbiAgICAgICAgICB0aGlzLm1lc3NhZ2VzLnVwZGF0ZSgobXNncykgPT5cclxuICAgICAgICAgICAgbXNncy5tYXAoKG0pID0+XHJcbiAgICAgICAgICAgICAgbS5pZCA9PT0gYXNzaXN0YW50TWVzc2FnZS5pZFxyXG4gICAgICAgICAgICAgICAgPyB7XHJcbiAgICAgICAgICAgICAgICAgIC4uLm0sXHJcbiAgICAgICAgICAgICAgICAgIC4uLnsgaWQ6IGNodW5rLmlkIH0sXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICA6IG0sXHJcbiAgICAgICAgICAgICksXHJcbiAgICAgICAgICApO1xyXG5cclxuICAgICAgICAgIGFzc2lzdGFudE1lc3NhZ2UuaWQgPSBjaHVuay5pZDtcclxuXHJcbiAgICAgICAgICAvLyBNYXAgdGhlIHNlc3Npb24gSUQgdG8gdGhlIGJhY2tlbmQtZ2VuZXJhdGVkIG9uZVxyXG4gICAgICAgICAgdGhpcy5tYXBTZXNzaW9uSWQoY2h1bmsucmVzcG9uc2VfaWQgfHwgY2h1bmsuaWQpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgdGV4dCA9IGNodW5rLmNvbnRlbnQgPz8gJyc7XHJcbiAgICAgICAgaWYgKCF0ZXh0KSByZXR1cm47XHJcblxyXG4gICAgICAgIC8vIGtlZXAgbWVzc2FnZSBpbiBzeW5jIHdpdGhvdXQgcmVnZW5lcmF0aW9uXHJcbiAgICAgICAgdGhpcy5tZXNzYWdlcy51cGRhdGUoKG1zZ3MpID0+XHJcbiAgICAgICAgICBtc2dzLm1hcCgobSkgPT5cclxuICAgICAgICAgICAgbS5pZCA9PT0gYXNzaXN0YW50TWVzc2FnZS5pZFxyXG4gICAgICAgICAgICAgID8ge1xyXG4gICAgICAgICAgICAgICAgLi4ubSxcclxuICAgICAgICAgICAgICAgIGNodW5rczogWy4uLihtLmNodW5rcyA/PyBbXSksIHRleHRdLCAvLyBpbW11dGFibGUgYXBwZW5kXHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIDogbSxcclxuICAgICAgICAgICksXHJcbiAgICAgICAgKTtcclxuXHJcbiAgICAgICAgLy8gY29uc3QgbWVzc2FnZSA9IHRoaXMubWVzc2FnZXMoKS5maW5kKChtKSA9PiBtLmlkID09PSBhc3Npc3RhbnRNZXNzYWdlLmlkKTtcclxuICAgICAgICAvLyBsb2dnZXIubG9nKCdBcHBlbmRpbmcgY2h1bmsgdG8gYXNzaXN0YW50IG1lc3NhZ2U6JywgbWVzc2FnZT8uY2h1bmtzKTtcclxuICAgICAgfSxcclxuICAgICAgY29tcGxldGU6ICgpID0+IHtcclxuICAgICAgICB0aGlzLmlzTG9hZGluZ0FwaS5zZXQoZmFsc2UpO1xyXG5cclxuICAgICAgICAvLyBNYXJrIHRoZSBjaHVuayBzdHJlYW0gY29tcGVsdGVkXHJcbiAgICAgICAgdGhpcy5tZXNzYWdlcy51cGRhdGUoKG1zZ3MpID0+XHJcbiAgICAgICAgICBtc2dzLm1hcCgobSkgPT4gKG0uaWQgPT09IGFzc2lzdGFudE1lc3NhZ2UuaWQgPyB7IC4uLm0sIGNvbXBsZXRlZDogdHJ1ZSB9IDogbSkpLFxyXG4gICAgICAgICk7XHJcblxyXG4gICAgICAgIC8vIGNvbnN0IG1lc3NhZ2UgPSB0aGlzLm1lc3NhZ2VzKCkuZmluZCgobSkgPT4gbS5pZCA9PT0gYXNzaXN0YW50TWVzc2FnZS5pZCk7XHJcbiAgICAgICAgLy8gdGhpcy5jdXJyZW50UmVzcG9uc2UgKz0gbWVzc2FnZT8uY2h1bmtzPy5qb2luKCcnKSA/PyAnJztcclxuXHJcbiAgICAgICAgLy8gbG9nZ2VyLmxvZygnQXBwZW5kaW5nIGNodW5rIHRvIGFzc2lzdGFudCBtZXNzYWdlOicsIG1lc3NhZ2U/LnRleHQpO1xyXG4gICAgICAgIC8vIGxvZ2dlci5sb2coJ0FwcGVuZGluZyBjaHVuayB0byBhc3Npc3RhbnQgbWVzc2FnZTonLCBtZXNzYWdlPy5jaHVua3MpO1xyXG5cclxuICAgICAgICBzdHJlYW1Db21wbGV0ZSQubmV4dCh0aGlzLmN1cnJlbnRSZXNwb25zZSk7XHJcbiAgICAgICAgc3RyZWFtQ29tcGxldGUkLmNvbXBsZXRlKCk7XHJcbiAgICAgIH0sXHJcbiAgICAgIGVycm9yOiAoZXJyb3IpID0+IHtcclxuICAgICAgICBsb2dnZXIuZXJyb3IoJ0NoYXQgZXJyb3I6JywgZXJyb3IpO1xyXG4gICAgICAgIFNuYWNrYmFyVXRpbHMuZXJyb3IoJ0FuIGVycm9yIG9jY3VycmVkIGR1cmluZyByZXBseS4nKTtcclxuXHJcbiAgICAgICAgdGhpcy5pc0xvYWRpbmdBcGkuc2V0KGZhbHNlKTtcclxuICAgICAgICB0aGlzLmlzQm90VHlwaW5nLnNldChmYWxzZSk7XHJcbiAgICAgICAgU25hY2tiYXJVdGlscy5lcnJvcignQW4gZXJyb3Igb2NjdXJyZWQgZHVyaW5nIHJlcGx5LicpO1xyXG5cclxuICAgICAgICBpZiAoIWhhc1N0YXJ0ZWQpIHRoaXMuYWRkTWVzc2FnZShhc3Npc3RhbnRNZXNzYWdlKTtcclxuICAgICAgICBpZiAoIWFzc2lzdGFudE1lc3NhZ2UudGV4dCkgYXNzaXN0YW50TWVzc2FnZS50ZXh0ID0gdGhpcy5nZXRGYWxsYmFja0Vycm9yKCk7XHJcblxyXG4gICAgICAgIC8vIG1hcmsgY29tcGxldGVkLCBkbyBOT1QgcmVidWlsZCBjb250ZW50XHJcbiAgICAgICAgdGhpcy5tZXNzYWdlcy51cGRhdGUoKG1zZ3MpID0+XHJcbiAgICAgICAgICBtc2dzLm1hcCgobSkgPT5cclxuICAgICAgICAgICAgbS5pZCA9PT0gYXNzaXN0YW50TWVzc2FnZS5pZFxyXG4gICAgICAgICAgICAgID8ge1xyXG4gICAgICAgICAgICAgICAgLi4ubSxcclxuICAgICAgICAgICAgICAgIGNvbXBsZXRlZDogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIGlzSGlzdG9yeTogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICB0ZXh0OiBhc3Npc3RhbnRNZXNzYWdlLnRleHQsXHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIDogbSxcclxuICAgICAgICAgICksXHJcbiAgICAgICAgKTtcclxuXHJcbiAgICAgICAgc3RyZWFtQ29tcGxldGUkLm5leHQoJycpO1xyXG4gICAgICAgIHN0cmVhbUNvbXBsZXRlJC5jb21wbGV0ZSgpO1xyXG4gICAgICAgIC8vIHRoaXMuZmluYWxpemVTdHJlYW1FcnJvcihhc3Npc3RhbnRNZXNzYWdlLCBoYXNTdGFydGVkLCBzdHJlYW1Db21wbGV0ZSQpO1xyXG4gICAgICB9LFxyXG4gICAgfSk7XHJcblxyXG4gICAgdHJ5IHtcclxuICAgICAgYXdhaXQgbGFzdFZhbHVlRnJvbShzdHJlYW1Db21wbGV0ZSQpO1xyXG4gICAgfSBmaW5hbGx5IHtcclxuICAgICAgY2FuY2VsU3ViLnVuc3Vic2NyaWJlKCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gJyc7XHJcbiAgfVxyXG5cclxuICAvLyEgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcbiAgY2FuY2VsUmVxdWVzdCgpOiB2b2lkIHtcclxuICAgIHRoaXMuY2FuY2VsU3ViamVjdC5uZXh0KCk7XHJcblxyXG4gICAgLy8gUmVzZXQgVUkgc3RhdGVzIGltbWVkaWF0ZWx5XHJcbiAgICB0aGlzLmlzTG9hZGluZ0FwaS5zZXQoZmFsc2UpO1xyXG4gICAgdGhpcy5pc0JvdFR5cGluZy5zZXQoZmFsc2UpO1xyXG4gICAgdGhpcy5jdXJyZW50UmVzcG9uc2UgPSAnJztcclxuXHJcbiAgICBpZiAodGhpcy5zdHJlYW1TdWJzY3JpcHRpb24pIHtcclxuICAgICAgbG9nZ2VyLmxvZygnQ2FuY2VsbGluZyBvbmdvaW5nIGNoYXQgcmVxdWVzdC4uLicpO1xyXG4gICAgICB0aGlzLnN0cmVhbVN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xyXG4gICAgICB0aGlzLnN0cmVhbVN1YnNjcmlwdGlvbiA9IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgIC8vIENsZWFuIHVwIGFzc2lzdGFudCBtZXNzYWdlczpcclxuICAgICAgLy8gUmVtb3ZlIGlmIGNvbXBsZXRlbHkgZW1wdHlcclxuICAgICAgLy8gTWFyayBhcyBjb21wbGV0ZWQgaWYgaXQgaGFzIGNvbnRlbnRcclxuICAgICAgdGhpcy5tZXNzYWdlcy51cGRhdGUoKG1zZ3MpID0+XHJcbiAgICAgICAgbXNnc1xyXG4gICAgICAgICAgLmZpbHRlcihcclxuICAgICAgICAgICAgKG0pID0+XHJcbiAgICAgICAgICAgICAgIShcclxuICAgICAgICAgICAgICAgIG0uc2VuZGVyID09PSAnYXNzaXN0YW50JyAmJlxyXG4gICAgICAgICAgICAgICAgIW0uY29tcGxldGVkICYmXHJcbiAgICAgICAgICAgICAgICAhbS50ZXh0ICYmXHJcbiAgICAgICAgICAgICAgICAoIW0uY2h1bmtzIHx8IG0uY2h1bmtzLmxlbmd0aCA9PT0gMClcclxuICAgICAgICAgICAgICApLFxyXG4gICAgICAgICAgKVxyXG4gICAgICAgICAgLm1hcCgobSkgPT4gKG0uc2VuZGVyID09PSAnYXNzaXN0YW50JyAmJiAhbS5jb21wbGV0ZWQgPyB7IC4uLm0sIGNvbXBsZXRlZDogdHJ1ZSB9IDogbSkpLFxyXG4gICAgICApO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8hID09PT09PT09PT09PT09PT09PT09IEFVRElPID09PT09PT09PT09PT09PT09PT09XHJcblxyXG4gIHB1YmxpYyB1bmxvY2tBdWRpbygpOiB2b2lkIHtcclxuICAgIHRoaXMuYXVkaW9TZXJ2aWNlLnVubG9ja0F1ZGlvKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBNYXAgbG9jYWwgcGxhY2Vob2xkZXIgc2Vzc2lvbiBJRCB0byBiYWNrZW5kLWdlbmVyYXRlZCBJRFxyXG4gICAqL1xyXG4gIHByaXZhdGUgbWFwU2Vzc2lvbklkKHJlc3BvbnNlSWQ/OiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIGlmICghcmVzcG9uc2VJZCB8fCAhdGhpcy5hY3RpdmVTZXNzaW9uIHx8ICF0aGlzLmFjdGl2ZVNlc3Npb24uaWQuc3RhcnRzV2l0aCgnc2Vzc2lvbl8nKSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3Qgb2xkSWQgPSB0aGlzLmFjdGl2ZVNlc3Npb24uaWQ7XHJcbiAgICBsb2dnZXIubG9nKGBbQ2hhdFNlcnZpY2VdIE1hcHBpbmcgbG9jYWwgc2Vzc2lvbiAke29sZElkfSDihpIgYmFja2VuZCBJRCAke3Jlc3BvbnNlSWR9YCk7XHJcblxyXG4gICAgLy8gVXBkYXRlIGFjdGl2ZSBzZXNzaW9uIHN1YmplY3RcclxuICAgIHRoaXMuYWN0aXZlU2Vzc2lvbi5pZCA9IHJlc3BvbnNlSWQ7XHJcblxyXG4gICAgLy8gVHJpZ2dlciBoaXN0b3J5IHJlZnJlc2ggdG8gZ2V0IHRoZSBzZXJ2ZXItZ2VuZXJhdGVkIHRpdGxlXHJcbiAgICB0aGlzLmNoYXRIaXN0b3J5U2VydmljZS5pbnZhbGlkYXRlQ2FjaGUoKTtcclxuICB9XHJcbn1cclxuIl19
@@ -1,50 +0,0 @@
1
- import { Component, EventEmitter, Input, Output } from '@angular/core';
2
- import { CommonModule } from '@angular/common';
3
- import { MatIconModule } from '@angular/material/icon';
4
- import * as i0 from "@angular/core";
5
- import * as i1 from "@angular/common";
6
- export class ChatButtonComponent {
7
- constructor() {
8
- this.buttonStyle = 'fab';
9
- this.isChatOpen = false;
10
- this.unreadCount = 0;
11
- this.appTitle = 'Chat';
12
- this.appLogoUrl = '';
13
- this.appTextLogoUrl = '';
14
- this.toggle = new EventEmitter();
15
- }
16
- get isSidebar() {
17
- return this.buttonStyle.startsWith('sidebar');
18
- }
19
- get sidebarPosition() {
20
- if (!this.isSidebar)
21
- return 'center';
22
- if (this.buttonStyle === 'sidebar')
23
- return 'center';
24
- return this.buttonStyle.split('-')[1];
25
- }
26
- onToggle() {
27
- this.toggle.emit();
28
- }
29
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ChatButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
30
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: ChatButtonComponent, isStandalone: true, selector: "app-chat-button", inputs: { buttonStyle: "buttonStyle", isChatOpen: "isChatOpen", unreadCount: "unreadCount", appTitle: "appTitle", appLogoUrl: "appLogoUrl", appTextLogoUrl: "appTextLogoUrl" }, outputs: { toggle: "toggle" }, ngImport: i0, template: "<!-- fab -->\r\n@if (buttonStyle === 'fab' && !isChatOpen) {\r\n <button class=\"chat-fab\" (click)=\"onToggle()\">\r\n <!-- <mat-icon>{{ chatIcon }}</mat-icon> -->\r\n <img style=\"width: 30px; height: 30px\" [src]=\"appLogoUrl\" />\r\n <!-- <div class=\"chat-logo\"></div> -->\r\n @if (unreadCount > 0) {\r\n <span class=\"alert-badge\">\r\n {{ unreadCount > 9 ? '9+' : unreadCount }}\r\n </span>\r\n }\r\n </button>\r\n}\r\n\r\n<!-- sidebar button -->\r\n@if (isSidebar && !isChatOpen) {\r\n <button class=\"chat-sidebar\" (click)=\"onToggle()\" [ngClass]=\"sidebarPosition\">\r\n <!-- <h2 style=\"transform: rotate(-90deg); font-size: 16px\">{{ appTitle }}</h2> -->\r\n <img style=\"transform: rotate(-90deg); width: 100px; height: 45px\" [src]=\"appTextLogoUrl\" />\r\n\r\n @if (unreadCount > 0) {\r\n <span class=\"alert-badge\">\r\n {{ unreadCount > 9 ? '9+' : unreadCount }}\r\n </span>\r\n }\r\n </button>\r\n}\r\n", styles: [".chat-sidebar{position:fixed;right:0;width:40px;height:120px;border-radius:16px 0 0 16px;background:var(--background-color);color:var(--white);border:none;box-shadow:var(--border-shadow-color);display:flex;justify-content:center;align-items:center;cursor:pointer;z-index:1000}.chat-sidebar.disabled{background:transparent;border-radius:0}.chat-sidebar h2{margin:0;font-size:12px;transform:rotate(-90deg);white-space:nowrap}.chat-sidebar .alert-badge{position:absolute;bottom:15px;right:30px;width:18px;height:18px;border-radius:50%;background:var(--red);color:var(--white);font-size:10px;display:flex;align-items:center;justify-content:center}.chat-sidebar.center{top:50%;transform:translateY(-50%)}.chat-sidebar.top{top:calc(50% - 45vh);transform:none}.chat-sidebar.bottom{top:calc(50% + 30vh);transform:none}.chat-fab{position:fixed;bottom:24px;right:24px;width:56px;height:56px;border-radius:50%;background:var(--background-color);color:var(--white);box-shadow:0 6px 16px rgba(var(--black-rgb),.2);border:none;cursor:pointer;z-index:1000;display:flex;align-items:center;justify-content:center}.chat-fab svg,.chat-fab mat-icon{width:24px;height:24px}.chat-fab:hover{transform:scale(1.1)}.alert-badge{position:absolute;top:-4px;right:-4px;background:var(--red);color:var(--white);border-radius:50%;min-width:18px;height:18px;font-size:11px;display:flex;align-items:center;justify-content:center;font-weight:700;line-height:1}.chat-logo{width:45px;height:45px;mask:url(/assets/logo.svg) no-repeat center;-webkit-mask-size:contain;mask-size:contain;background-color:var(--mat-sys-on-primary)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatIconModule }] }); }
31
- }
32
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ChatButtonComponent, decorators: [{
33
- type: Component,
34
- args: [{ selector: 'app-chat-button', standalone: true, imports: [CommonModule, MatIconModule], template: "<!-- fab -->\r\n@if (buttonStyle === 'fab' && !isChatOpen) {\r\n <button class=\"chat-fab\" (click)=\"onToggle()\">\r\n <!-- <mat-icon>{{ chatIcon }}</mat-icon> -->\r\n <img style=\"width: 30px; height: 30px\" [src]=\"appLogoUrl\" />\r\n <!-- <div class=\"chat-logo\"></div> -->\r\n @if (unreadCount > 0) {\r\n <span class=\"alert-badge\">\r\n {{ unreadCount > 9 ? '9+' : unreadCount }}\r\n </span>\r\n }\r\n </button>\r\n}\r\n\r\n<!-- sidebar button -->\r\n@if (isSidebar && !isChatOpen) {\r\n <button class=\"chat-sidebar\" (click)=\"onToggle()\" [ngClass]=\"sidebarPosition\">\r\n <!-- <h2 style=\"transform: rotate(-90deg); font-size: 16px\">{{ appTitle }}</h2> -->\r\n <img style=\"transform: rotate(-90deg); width: 100px; height: 45px\" [src]=\"appTextLogoUrl\" />\r\n\r\n @if (unreadCount > 0) {\r\n <span class=\"alert-badge\">\r\n {{ unreadCount > 9 ? '9+' : unreadCount }}\r\n </span>\r\n }\r\n </button>\r\n}\r\n", styles: [".chat-sidebar{position:fixed;right:0;width:40px;height:120px;border-radius:16px 0 0 16px;background:var(--background-color);color:var(--white);border:none;box-shadow:var(--border-shadow-color);display:flex;justify-content:center;align-items:center;cursor:pointer;z-index:1000}.chat-sidebar.disabled{background:transparent;border-radius:0}.chat-sidebar h2{margin:0;font-size:12px;transform:rotate(-90deg);white-space:nowrap}.chat-sidebar .alert-badge{position:absolute;bottom:15px;right:30px;width:18px;height:18px;border-radius:50%;background:var(--red);color:var(--white);font-size:10px;display:flex;align-items:center;justify-content:center}.chat-sidebar.center{top:50%;transform:translateY(-50%)}.chat-sidebar.top{top:calc(50% - 45vh);transform:none}.chat-sidebar.bottom{top:calc(50% + 30vh);transform:none}.chat-fab{position:fixed;bottom:24px;right:24px;width:56px;height:56px;border-radius:50%;background:var(--background-color);color:var(--white);box-shadow:0 6px 16px rgba(var(--black-rgb),.2);border:none;cursor:pointer;z-index:1000;display:flex;align-items:center;justify-content:center}.chat-fab svg,.chat-fab mat-icon{width:24px;height:24px}.chat-fab:hover{transform:scale(1.1)}.alert-badge{position:absolute;top:-4px;right:-4px;background:var(--red);color:var(--white);border-radius:50%;min-width:18px;height:18px;font-size:11px;display:flex;align-items:center;justify-content:center;font-weight:700;line-height:1}.chat-logo{width:45px;height:45px;mask:url(/assets/logo.svg) no-repeat center;-webkit-mask-size:contain;mask-size:contain;background-color:var(--mat-sys-on-primary)}\n"] }]
35
- }], propDecorators: { buttonStyle: [{
36
- type: Input
37
- }], isChatOpen: [{
38
- type: Input
39
- }], unreadCount: [{
40
- type: Input
41
- }], appTitle: [{
42
- type: Input
43
- }], appLogoUrl: [{
44
- type: Input
45
- }], appTextLogoUrl: [{
46
- type: Input
47
- }], toggle: [{
48
- type: Output
49
- }] } });
50
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhdC1idXR0b24uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZG9vaGJvdC9zcmMvbGliL2FwcC9jaGF0L2NvbXBvbmVudHMvY2hhdC1idXR0b24vY2hhdC1idXR0b24uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZG9vaGJvdC9zcmMvbGliL2FwcC9jaGF0L2NvbXBvbmVudHMvY2hhdC1idXR0b24vY2hhdC1idXR0b24uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN2RSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHdCQUF3QixDQUFDOzs7QUFTdkQsTUFBTSxPQUFPLG1CQUFtQjtJQVBoQztRQVFXLGdCQUFXLEdBQXlELEtBQUssQ0FBQztRQUMxRSxlQUFVLEdBQVksS0FBSyxDQUFDO1FBQzVCLGdCQUFXLEdBQVcsQ0FBQyxDQUFDO1FBQ3hCLGFBQVEsR0FBVyxNQUFNLENBQUM7UUFDMUIsZUFBVSxHQUFXLEVBQUUsQ0FBQztRQUN4QixtQkFBYyxHQUFXLEVBQUUsQ0FBQztRQUUzQixXQUFNLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztLQWU3QztJQWJDLElBQUksU0FBUztRQUNYLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDaEQsQ0FBQztJQUVELElBQUksZUFBZTtRQUNqQixJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVM7WUFBRSxPQUFPLFFBQVEsQ0FBQztRQUNyQyxJQUFJLElBQUksQ0FBQyxXQUFXLEtBQUssU0FBUztZQUFFLE9BQU8sUUFBUSxDQUFDO1FBQ3BELE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFnQyxDQUFDO0lBQ3ZFLENBQUM7SUFFRCxRQUFRO1FBQ04sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNyQixDQUFDOytHQXRCVSxtQkFBbUI7bUdBQW5CLG1CQUFtQiwwUkNYaEMsODlCQTJCQSxrbkREcEJZLFlBQVksNEhBQUUsYUFBYTs7NEZBSTFCLG1CQUFtQjtrQkFQL0IsU0FBUzsrQkFDRSxpQkFBaUIsY0FDZixJQUFJLFdBQ1AsQ0FBQyxZQUFZLEVBQUUsYUFBYSxDQUFDOzhCQUs3QixXQUFXO3NCQUFuQixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csY0FBYztzQkFBdEIsS0FBSztnQkFFSSxNQUFNO3NCQUFmLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE91dHB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQgeyBNYXRJY29uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaWNvbic7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2FwcC1jaGF0LWJ1dHRvbicsXHJcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcclxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBNYXRJY29uTW9kdWxlXSxcclxuICB0ZW1wbGF0ZVVybDogJy4vY2hhdC1idXR0b24uY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL2NoYXQtYnV0dG9uLmNvbXBvbmVudC5zY3NzJ10sXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBDaGF0QnV0dG9uQ29tcG9uZW50IHtcclxuICBASW5wdXQoKSBidXR0b25TdHlsZTogJ2ZhYicgfCAnc2lkZWJhcicgfCAnc2lkZWJhci10b3AnIHwgJ3NpZGViYXItYm90dG9tJyA9ICdmYWInO1xyXG4gIEBJbnB1dCgpIGlzQ2hhdE9wZW46IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASW5wdXQoKSB1bnJlYWRDb3VudDogbnVtYmVyID0gMDtcclxuICBASW5wdXQoKSBhcHBUaXRsZTogc3RyaW5nID0gJ0NoYXQnO1xyXG4gIEBJbnB1dCgpIGFwcExvZ29Vcmw6IHN0cmluZyA9ICcnO1xyXG4gIEBJbnB1dCgpIGFwcFRleHRMb2dvVXJsOiBzdHJpbmcgPSAnJztcclxuXHJcbiAgQE91dHB1dCgpIHRvZ2dsZSA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcclxuXHJcbiAgZ2V0IGlzU2lkZWJhcigpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLmJ1dHRvblN0eWxlLnN0YXJ0c1dpdGgoJ3NpZGViYXInKTtcclxuICB9XHJcblxyXG4gIGdldCBzaWRlYmFyUG9zaXRpb24oKTogJ3RvcCcgfCAnY2VudGVyJyB8ICdib3R0b20nIHtcclxuICAgIGlmICghdGhpcy5pc1NpZGViYXIpIHJldHVybiAnY2VudGVyJztcclxuICAgIGlmICh0aGlzLmJ1dHRvblN0eWxlID09PSAnc2lkZWJhcicpIHJldHVybiAnY2VudGVyJztcclxuICAgIHJldHVybiB0aGlzLmJ1dHRvblN0eWxlLnNwbGl0KCctJylbMV0gYXMgJ3RvcCcgfCAnY2VudGVyJyB8ICdib3R0b20nO1xyXG4gIH1cclxuXHJcbiAgb25Ub2dnbGUoKSB7XHJcbiAgICB0aGlzLnRvZ2dsZS5lbWl0KCk7XHJcbiAgfVxyXG59XHJcbiIsIjwhLS0gZmFiIC0tPlxyXG5AaWYgKGJ1dHRvblN0eWxlID09PSAnZmFiJyAmJiAhaXNDaGF0T3Blbikge1xyXG4gIDxidXR0b24gY2xhc3M9XCJjaGF0LWZhYlwiIChjbGljayk9XCJvblRvZ2dsZSgpXCI+XHJcbiAgICA8IS0tIDxtYXQtaWNvbj57eyBjaGF0SWNvbiB9fTwvbWF0LWljb24+IC0tPlxyXG4gICAgPGltZyBzdHlsZT1cIndpZHRoOiAzMHB4OyBoZWlnaHQ6IDMwcHhcIiBbc3JjXT1cImFwcExvZ29VcmxcIiAvPlxyXG4gICAgPCEtLSA8ZGl2IGNsYXNzPVwiY2hhdC1sb2dvXCI+PC9kaXY+IC0tPlxyXG4gICAgQGlmICh1bnJlYWRDb3VudCA+IDApIHtcclxuICAgICAgPHNwYW4gY2xhc3M9XCJhbGVydC1iYWRnZVwiPlxyXG4gICAgICAgIHt7IHVucmVhZENvdW50ID4gOSA/ICc5KycgOiB1bnJlYWRDb3VudCB9fVxyXG4gICAgICA8L3NwYW4+XHJcbiAgICB9XHJcbiAgPC9idXR0b24+XHJcbn1cclxuXHJcbjwhLS0gc2lkZWJhciBidXR0b24gLS0+XHJcbkBpZiAoaXNTaWRlYmFyICYmICFpc0NoYXRPcGVuKSB7XHJcbiAgPGJ1dHRvbiBjbGFzcz1cImNoYXQtc2lkZWJhclwiIChjbGljayk9XCJvblRvZ2dsZSgpXCIgW25nQ2xhc3NdPVwic2lkZWJhclBvc2l0aW9uXCI+XHJcbiAgICA8IS0tIDxoMiBzdHlsZT1cInRyYW5zZm9ybTogcm90YXRlKC05MGRlZyk7IGZvbnQtc2l6ZTogMTZweFwiPnt7IGFwcFRpdGxlIH19PC9oMj4gLS0+XHJcbiAgICA8aW1nIHN0eWxlPVwidHJhbnNmb3JtOiByb3RhdGUoLTkwZGVnKTsgd2lkdGg6IDEwMHB4OyBoZWlnaHQ6IDQ1cHhcIiBbc3JjXT1cImFwcFRleHRMb2dvVXJsXCIgLz5cclxuXHJcbiAgICBAaWYgKHVucmVhZENvdW50ID4gMCkge1xyXG4gICAgICA8c3BhbiBjbGFzcz1cImFsZXJ0LWJhZGdlXCI+XHJcbiAgICAgICAge3sgdW5yZWFkQ291bnQgPiA5ID8gJzkrJyA6IHVucmVhZENvdW50IH19XHJcbiAgICAgIDwvc3Bhbj5cclxuICAgIH1cclxuICA8L2J1dHRvbj5cclxufVxyXG4iXX0=
@@ -1,12 +0,0 @@
1
- import { Component, ChangeDetectionStrategy } from '@angular/core';
2
- import { CommonModule } from '@angular/common';
3
- import * as i0 from "@angular/core";
4
- export class ChatFooterComponent {
5
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ChatFooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: ChatFooterComponent, isStandalone: true, selector: "app-chat-footer", ngImport: i0, template: "<div class=\"terms-conditions\">\r\n <!-- Terms and conditions relocated to Personalization Hub -->\r\n</div>", styles: [".terms-conditions{padding:10px 15px;text-align:center;font-size:.8rem;background-color:var(--background-color);border-top:1px solid var(--background-color);border-bottom-left-radius:inherit;border-bottom-right-radius:inherit}.terms-conditions a{color:var(--secondary-text-color);text-decoration:none;transition:color .2s ease}.terms-conditions a:hover{color:var(--primary-color);text-decoration:underline}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
7
- }
8
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ChatFooterComponent, decorators: [{
9
- type: Component,
10
- args: [{ selector: 'app-chat-footer', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"terms-conditions\">\r\n <!-- Terms and conditions relocated to Personalization Hub -->\r\n</div>", styles: [".terms-conditions{padding:10px 15px;text-align:center;font-size:.8rem;background-color:var(--background-color);border-top:1px solid var(--background-color);border-bottom-left-radius:inherit;border-bottom-right-radius:inherit}.terms-conditions a{color:var(--secondary-text-color);text-decoration:none;transition:color .2s ease}.terms-conditions a:hover{color:var(--primary-color);text-decoration:underline}\n"] }]
11
- }] });
12
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhdC1mb290ZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZG9vaGJvdC9zcmMvbGliL2FwcC9jaGF0L2NvbXBvbmVudHMvY2hhdC1mb290ZXIvY2hhdC1mb290ZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZG9vaGJvdC9zcmMvbGliL2FwcC9jaGF0L2NvbXBvbmVudHMvY2hhdC1mb290ZXIvY2hhdC1mb290ZXIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSx1QkFBdUIsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7O0FBVS9DLE1BQU0sT0FBTyxtQkFBbUI7K0dBQW5CLG1CQUFtQjttR0FBbkIsbUJBQW1CLDJFQ1hoQyxrSEFFTSxnZERJTSxZQUFZOzs0RkFLWCxtQkFBbUI7a0JBUi9CLFNBQVM7K0JBQ0UsaUJBQWlCLGNBQ2YsSUFBSSxXQUNQLENBQUMsWUFBWSxDQUFDLG1CQUdOLHVCQUF1QixDQUFDLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIENoYW5nZURldGVjdGlvblN0cmF0ZWd5IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2FwcC1jaGF0LWZvb3RlcicsXHJcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcclxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlXSxcclxuICB0ZW1wbGF0ZVVybDogJy4vY2hhdC1mb290ZXIuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL2NoYXQtZm9vdGVyLmNvbXBvbmVudC5zY3NzJ10sXHJcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBDaGF0Rm9vdGVyQ29tcG9uZW50IHt9XHJcbiIsIjxkaXYgY2xhc3M9XCJ0ZXJtcy1jb25kaXRpb25zXCI+XHJcbiAgICA8IS0tIFRlcm1zIGFuZCBjb25kaXRpb25zIHJlbG9jYXRlZCB0byBQZXJzb25hbGl6YXRpb24gSHViIC0tPlxyXG48L2Rpdj4iXX0=