genassist-chat-react 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +113 -0
- package/assets/chat-logo.png +0 -0
- package/dist/components/ChatMessage.d.ts +20 -0
- package/dist/components/ChatMessage.js +188 -0
- package/dist/components/GenAgentChat.d.ts +3 -0
- package/dist/components/GenAgentChat.js +520 -0
- package/dist/components/VoiceInput.d.ts +14 -0
- package/dist/components/VoiceInput.js +51 -0
- package/dist/hooks/useChat.d.ts +21 -0
- package/dist/hooks/useChat.js +256 -0
- package/dist/hooks/useVoiceInput.d.ts +16 -0
- package/dist/hooks/useVoiceInput.js +210 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/services/audioService.d.ts +17 -0
- package/dist/services/audioService.js +118 -0
- package/dist/services/chatService.d.ts +48 -0
- package/dist/services/chatService.js +376 -0
- package/dist/types/index.d.ts +42 -0
- package/dist/types/index.js +2 -0
- package/package.json +48 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
11
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
12
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
13
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
14
|
+
function step(op) {
|
|
15
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
16
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
17
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
18
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
19
|
+
switch (op[0]) {
|
|
20
|
+
case 0: case 1: t = op; break;
|
|
21
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
22
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
23
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
24
|
+
default:
|
|
25
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
26
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
27
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
28
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
29
|
+
if (t[2]) _.ops.pop();
|
|
30
|
+
_.trys.pop(); continue;
|
|
31
|
+
}
|
|
32
|
+
op = body.call(thisArg, _);
|
|
33
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
34
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
var AudioService = /** @class */ (function () {
|
|
38
|
+
function AudioService(config) {
|
|
39
|
+
this.ws = null;
|
|
40
|
+
this.audioChunks = [];
|
|
41
|
+
this.resolvePromise = null;
|
|
42
|
+
this.rejectPromise = null;
|
|
43
|
+
this.baseUrl = config.baseUrl;
|
|
44
|
+
this.apiKey = config.apiKey;
|
|
45
|
+
}
|
|
46
|
+
AudioService.prototype.textToSpeech = function (text_1) {
|
|
47
|
+
return __awaiter(this, arguments, void 0, function (text, voice) {
|
|
48
|
+
var _this = this;
|
|
49
|
+
if (voice === void 0) { voice = 'alloy'; }
|
|
50
|
+
return __generator(this, function (_a) {
|
|
51
|
+
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
52
|
+
_this.resolvePromise = resolve;
|
|
53
|
+
_this.rejectPromise = reject;
|
|
54
|
+
_this.audioChunks = [];
|
|
55
|
+
// Create WebSocket connection
|
|
56
|
+
var wsUrl = "".concat(_this.baseUrl.replace('http', 'ws'), "/api/voice/audio/tts?api_key=").concat(_this.apiKey);
|
|
57
|
+
_this.ws = new WebSocket(wsUrl);
|
|
58
|
+
_this.ws.onopen = function () {
|
|
59
|
+
var _a;
|
|
60
|
+
(_a = _this.ws) === null || _a === void 0 ? void 0 : _a.send(JSON.stringify({ text: text }));
|
|
61
|
+
};
|
|
62
|
+
_this.ws.onmessage = function (event) {
|
|
63
|
+
if (event.data instanceof Blob) {
|
|
64
|
+
_this.audioChunks.push(event.data);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
_this.ws.onclose = function () {
|
|
68
|
+
var _a, _b;
|
|
69
|
+
if (_this.audioChunks.length > 0) {
|
|
70
|
+
var audioBlob = new Blob(_this.audioChunks, { type: 'audio/mp3' });
|
|
71
|
+
(_a = _this.resolvePromise) === null || _a === void 0 ? void 0 : _a.call(_this, audioBlob);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
(_b = _this.rejectPromise) === null || _b === void 0 ? void 0 : _b.call(_this, new Error('No audio data received'));
|
|
75
|
+
}
|
|
76
|
+
_this.cleanup();
|
|
77
|
+
};
|
|
78
|
+
_this.ws.onerror = function (error) {
|
|
79
|
+
var _a;
|
|
80
|
+
(_a = _this.rejectPromise) === null || _a === void 0 ? void 0 : _a.call(_this, error);
|
|
81
|
+
_this.cleanup();
|
|
82
|
+
};
|
|
83
|
+
})];
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
};
|
|
87
|
+
AudioService.prototype.cleanup = function () {
|
|
88
|
+
if (this.ws) {
|
|
89
|
+
this.ws.close();
|
|
90
|
+
this.ws = null;
|
|
91
|
+
}
|
|
92
|
+
this.resolvePromise = null;
|
|
93
|
+
this.rejectPromise = null;
|
|
94
|
+
};
|
|
95
|
+
AudioService.prototype.playAudio = function (audioBlob) {
|
|
96
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
97
|
+
var audioUrl, audio;
|
|
98
|
+
return __generator(this, function (_a) {
|
|
99
|
+
audioUrl = URL.createObjectURL(audioBlob);
|
|
100
|
+
audio = new Audio(audioUrl);
|
|
101
|
+
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
102
|
+
audio.onended = function () {
|
|
103
|
+
URL.revokeObjectURL(audioUrl);
|
|
104
|
+
resolve();
|
|
105
|
+
};
|
|
106
|
+
audio.onerror = function (error) {
|
|
107
|
+
URL.revokeObjectURL(audioUrl);
|
|
108
|
+
reject(error);
|
|
109
|
+
};
|
|
110
|
+
audio.play().catch(reject);
|
|
111
|
+
})];
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
};
|
|
115
|
+
return AudioService;
|
|
116
|
+
}());
|
|
117
|
+
export { AudioService };
|
|
118
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXVkaW9TZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlcnZpY2VzL2F1ZGlvU2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFPQTtJQVFFLHNCQUFZLE1BQTBCO1FBTDlCLE9BQUUsR0FBcUIsSUFBSSxDQUFDO1FBQzVCLGdCQUFXLEdBQVcsRUFBRSxDQUFDO1FBQ3pCLG1CQUFjLEdBQW1DLElBQUksQ0FBQztRQUN0RCxrQkFBYSxHQUFvQyxJQUFJLENBQUM7UUFHNUQsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDO1FBQzlCLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUM5QixDQUFDO0lBRUssbUNBQVksR0FBbEI7NERBQW1CLElBQVksRUFBRSxLQUF1Qjs7WUFBdkIsc0JBQUEsRUFBQSxlQUF1Qjs7Z0JBQ3RELHNCQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07d0JBQ2pDLEtBQUksQ0FBQyxjQUFjLEdBQUcsT0FBTyxDQUFDO3dCQUM5QixLQUFJLENBQUMsYUFBYSxHQUFHLE1BQU0sQ0FBQzt3QkFDNUIsS0FBSSxDQUFDLFdBQVcsR0FBRyxFQUFFLENBQUM7d0JBRXRCLDhCQUE4Qjt3QkFDOUIsSUFBTSxLQUFLLEdBQUcsVUFBRyxLQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLDBDQUFnQyxLQUFJLENBQUMsTUFBTSxDQUFFLENBQUM7d0JBQ2pHLEtBQUksQ0FBQyxFQUFFLEdBQUcsSUFBSSxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7d0JBRS9CLEtBQUksQ0FBQyxFQUFFLENBQUMsTUFBTSxHQUFHOzs0QkFDZixNQUFBLEtBQUksQ0FBQyxFQUFFLDBDQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsSUFBSSxNQUFBLEVBQUUsQ0FBQyxDQUFDLENBQUM7d0JBQzFDLENBQUMsQ0FBQzt3QkFFRixLQUFJLENBQUMsRUFBRSxDQUFDLFNBQVMsR0FBRyxVQUFDLEtBQUs7NEJBQ3hCLElBQUksS0FBSyxDQUFDLElBQUksWUFBWSxJQUFJLEVBQUUsQ0FBQztnQ0FDL0IsS0FBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDOzRCQUNwQyxDQUFDO3dCQUNILENBQUMsQ0FBQzt3QkFFRixLQUFJLENBQUMsRUFBRSxDQUFDLE9BQU8sR0FBRzs7NEJBQ2hCLElBQUksS0FBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0NBQ2hDLElBQU0sU0FBUyxHQUFHLElBQUksSUFBSSxDQUFDLEtBQUksQ0FBQyxXQUFXLEVBQUUsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQztnQ0FDcEUsTUFBQSxLQUFJLENBQUMsY0FBYyxzREFBRyxTQUFTLENBQUMsQ0FBQzs0QkFDbkMsQ0FBQztpQ0FBTSxDQUFDO2dDQUNOLE1BQUEsS0FBSSxDQUFDLGFBQWEsc0RBQUcsSUFBSSxLQUFLLENBQUMsd0JBQXdCLENBQUMsQ0FBQyxDQUFDOzRCQUM1RCxDQUFDOzRCQUNELEtBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQzt3QkFDakIsQ0FBQyxDQUFDO3dCQUVGLEtBQUksQ0FBQyxFQUFFLENBQUMsT0FBTyxHQUFHLFVBQUMsS0FBSzs7NEJBQ3RCLE1BQUEsS0FBSSxDQUFDLGFBQWEsc0RBQUcsS0FBSyxDQUFDLENBQUM7NEJBQzVCLEtBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQzt3QkFDakIsQ0FBQyxDQUFDO29CQUNKLENBQUMsQ0FBQyxFQUFDOzs7S0FDSjtJQUVPLDhCQUFPLEdBQWY7UUFDRSxJQUFJLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNaLElBQUksQ0FBQyxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDaEIsSUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUM7UUFDakIsQ0FBQztRQUNELElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDO1FBQzNCLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDO0lBQzVCLENBQUM7SUFFSyxnQ0FBUyxHQUFmLFVBQWdCLFNBQWU7Ozs7Z0JBQ3ZCLFFBQVEsR0FBRyxHQUFHLENBQUMsZUFBZSxDQUFDLFNBQVMsQ0FBQyxDQUFDO2dCQUMxQyxLQUFLLEdBQUcsSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBRWxDLHNCQUFPLElBQUksT0FBTyxDQUFDLFVBQUMsT0FBTyxFQUFFLE1BQU07d0JBQ2pDLEtBQUssQ0FBQyxPQUFPLEdBQUc7NEJBQ2QsR0FBRyxDQUFDLGVBQWUsQ0FBQyxRQUFRLENBQUMsQ0FBQzs0QkFDOUIsT0FBTyxFQUFFLENBQUM7d0JBQ1osQ0FBQyxDQUFDO3dCQUVGLEtBQUssQ0FBQyxPQUFPLEdBQUcsVUFBQyxLQUFLOzRCQUNwQixHQUFHLENBQUMsZUFBZSxDQUFDLFFBQVEsQ0FBQyxDQUFDOzRCQUM5QixNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7d0JBQ2hCLENBQUMsQ0FBQzt3QkFFRixLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO29CQUM3QixDQUFDLENBQUMsRUFBQzs7O0tBQ0o7SUFDSCxtQkFBQztBQUFELENBQUMsQUE3RUQsSUE2RUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgYXhpb3MgZnJvbSAnYXhpb3MnO1xuXG5pbnRlcmZhY2UgQXVkaW9TZXJ2aWNlQ29uZmlnIHtcbiAgYmFzZVVybDogc3RyaW5nO1xuICBhcGlLZXk6IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIEF1ZGlvU2VydmljZSB7XG4gIHByaXZhdGUgYmFzZVVybDogc3RyaW5nO1xuICBwcml2YXRlIGFwaUtleTogc3RyaW5nO1xuICBwcml2YXRlIHdzOiBXZWJTb2NrZXQgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBhdWRpb0NodW5rczogQmxvYltdID0gW107XG4gIHByaXZhdGUgcmVzb2x2ZVByb21pc2U6ICgodmFsdWU6IEJsb2IpID0+IHZvaWQpIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgcmVqZWN0UHJvbWlzZTogKChyZWFzb24/OiBhbnkpID0+IHZvaWQpIHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IoY29uZmlnOiBBdWRpb1NlcnZpY2VDb25maWcpIHtcbiAgICB0aGlzLmJhc2VVcmwgPSBjb25maWcuYmFzZVVybDtcbiAgICB0aGlzLmFwaUtleSA9IGNvbmZpZy5hcGlLZXk7XG4gIH1cblxuICBhc3luYyB0ZXh0VG9TcGVlY2godGV4dDogc3RyaW5nLCB2b2ljZTogc3RyaW5nID0gJ2FsbG95Jyk6IFByb21pc2U8QmxvYj4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLnJlc29sdmVQcm9taXNlID0gcmVzb2x2ZTtcbiAgICAgIHRoaXMucmVqZWN0UHJvbWlzZSA9IHJlamVjdDtcbiAgICAgIHRoaXMuYXVkaW9DaHVua3MgPSBbXTtcblxuICAgICAgLy8gQ3JlYXRlIFdlYlNvY2tldCBjb25uZWN0aW9uXG4gICAgICBjb25zdCB3c1VybCA9IGAke3RoaXMuYmFzZVVybC5yZXBsYWNlKCdodHRwJywgJ3dzJyl9L2FwaS92b2ljZS9hdWRpby90dHM/YXBpX2tleT0ke3RoaXMuYXBpS2V5fWA7XG4gICAgICB0aGlzLndzID0gbmV3IFdlYlNvY2tldCh3c1VybCk7XG5cbiAgICAgIHRoaXMud3Mub25vcGVuID0gKCkgPT4ge1xuICAgICAgICB0aGlzLndzPy5zZW5kKEpTT04uc3RyaW5naWZ5KHsgdGV4dCB9KSk7XG4gICAgICB9O1xuXG4gICAgICB0aGlzLndzLm9ubWVzc2FnZSA9IChldmVudCkgPT4ge1xuICAgICAgICBpZiAoZXZlbnQuZGF0YSBpbnN0YW5jZW9mIEJsb2IpIHtcbiAgICAgICAgICB0aGlzLmF1ZGlvQ2h1bmtzLnB1c2goZXZlbnQuZGF0YSk7XG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIHRoaXMud3Mub25jbG9zZSA9ICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMuYXVkaW9DaHVua3MubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGNvbnN0IGF1ZGlvQmxvYiA9IG5ldyBCbG9iKHRoaXMuYXVkaW9DaHVua3MsIHsgdHlwZTogJ2F1ZGlvL21wMycgfSk7XG4gICAgICAgICAgdGhpcy5yZXNvbHZlUHJvbWlzZT8uKGF1ZGlvQmxvYik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5yZWplY3RQcm9taXNlPy4obmV3IEVycm9yKCdObyBhdWRpbyBkYXRhIHJlY2VpdmVkJykpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2xlYW51cCgpO1xuICAgICAgfTtcblxuICAgICAgdGhpcy53cy5vbmVycm9yID0gKGVycm9yKSA9PiB7XG4gICAgICAgIHRoaXMucmVqZWN0UHJvbWlzZT8uKGVycm9yKTtcbiAgICAgICAgdGhpcy5jbGVhbnVwKCk7XG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBjbGVhbnVwKCkge1xuICAgIGlmICh0aGlzLndzKSB7XG4gICAgICB0aGlzLndzLmNsb3NlKCk7XG4gICAgICB0aGlzLndzID0gbnVsbDtcbiAgICB9XG4gICAgdGhpcy5yZXNvbHZlUHJvbWlzZSA9IG51bGw7XG4gICAgdGhpcy5yZWplY3RQcm9taXNlID0gbnVsbDtcbiAgfVxuXG4gIGFzeW5jIHBsYXlBdWRpbyhhdWRpb0Jsb2I6IEJsb2IpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBhdWRpb1VybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYXVkaW9CbG9iKTtcbiAgICBjb25zdCBhdWRpbyA9IG5ldyBBdWRpbyhhdWRpb1VybCk7XG4gICAgXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGF1ZGlvLm9uZW5kZWQgPSAoKSA9PiB7XG4gICAgICAgIFVSTC5yZXZva2VPYmplY3RVUkwoYXVkaW9VcmwpO1xuICAgICAgICByZXNvbHZlKCk7XG4gICAgICB9O1xuICAgICAgXG4gICAgICBhdWRpby5vbmVycm9yID0gKGVycm9yKSA9PiB7XG4gICAgICAgIFVSTC5yZXZva2VPYmplY3RVUkwoYXVkaW9VcmwpO1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfTtcbiAgICAgIFxuICAgICAgYXVkaW8ucGxheSgpLmNhdGNoKHJlamVjdCk7XG4gICAgfSk7XG4gIH1cbn0gIl19
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { ChatMessage } from '../types';
|
|
2
|
+
export declare class ChatService {
|
|
3
|
+
private baseUrl;
|
|
4
|
+
private apiKey;
|
|
5
|
+
private metadata;
|
|
6
|
+
private conversationId;
|
|
7
|
+
private conversationCreateTime;
|
|
8
|
+
private isFinalized;
|
|
9
|
+
private webSocket;
|
|
10
|
+
private messageHandler;
|
|
11
|
+
private takeoverHandler;
|
|
12
|
+
private finalizedHandler;
|
|
13
|
+
private connectionStateHandler;
|
|
14
|
+
private storageKey;
|
|
15
|
+
private possibleQueries;
|
|
16
|
+
constructor(baseUrl: string, apiKey: string, metadata?: Record<string, any>);
|
|
17
|
+
setMessageHandler(handler: (message: ChatMessage) => void): void;
|
|
18
|
+
setTakeoverHandler(handler: () => void): void;
|
|
19
|
+
setFinalizedHandler(handler: () => void): void;
|
|
20
|
+
setConnectionStateHandler(handler: (state: 'connecting' | 'connected' | 'disconnected') => void): void;
|
|
21
|
+
getPossibleQueries(): string[];
|
|
22
|
+
/**
|
|
23
|
+
* Load a saved conversation ID from localStorage
|
|
24
|
+
*/
|
|
25
|
+
private loadSavedConversation;
|
|
26
|
+
/**
|
|
27
|
+
* Save the current conversation ID to localStorage
|
|
28
|
+
*/
|
|
29
|
+
private saveConversation;
|
|
30
|
+
/**
|
|
31
|
+
* Reset the current conversation by clearing the ID and websocket
|
|
32
|
+
*/
|
|
33
|
+
resetConversation(): void;
|
|
34
|
+
/**
|
|
35
|
+
* Check if there's a current conversation
|
|
36
|
+
*/
|
|
37
|
+
hasActiveConversation(): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Get the current conversation ID
|
|
40
|
+
*/
|
|
41
|
+
getConversationId(): string | null;
|
|
42
|
+
isConversationFinalized(): boolean;
|
|
43
|
+
startConversation(): Promise<string>;
|
|
44
|
+
sendMessage(message: string): Promise<void>;
|
|
45
|
+
connectWebSocket(): void;
|
|
46
|
+
disconnect(): void;
|
|
47
|
+
private adjustMessageTimestamps;
|
|
48
|
+
}
|
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
13
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
14
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
15
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
16
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
17
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
18
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
22
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
23
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
24
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
25
|
+
function step(op) {
|
|
26
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
27
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
28
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
29
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
30
|
+
switch (op[0]) {
|
|
31
|
+
case 0: case 1: t = op; break;
|
|
32
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
33
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
34
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
35
|
+
default:
|
|
36
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
37
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
38
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
39
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
40
|
+
if (t[2]) _.ops.pop();
|
|
41
|
+
_.trys.pop(); continue;
|
|
42
|
+
}
|
|
43
|
+
op = body.call(thisArg, _);
|
|
44
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
45
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
import axios from 'axios';
|
|
49
|
+
import { w3cwebsocket as WebSocket } from 'websocket';
|
|
50
|
+
var ChatService = /** @class */ (function () {
|
|
51
|
+
function ChatService(baseUrl, apiKey, metadata) {
|
|
52
|
+
this.conversationId = null;
|
|
53
|
+
this.conversationCreateTime = null; // Track conversation start time
|
|
54
|
+
this.isFinalized = false;
|
|
55
|
+
this.webSocket = null;
|
|
56
|
+
this.messageHandler = null;
|
|
57
|
+
this.takeoverHandler = null;
|
|
58
|
+
this.finalizedHandler = null;
|
|
59
|
+
this.connectionStateHandler = null;
|
|
60
|
+
this.storageKey = 'genassist_conversation';
|
|
61
|
+
this.possibleQueries = [];
|
|
62
|
+
this.baseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;
|
|
63
|
+
this.apiKey = apiKey;
|
|
64
|
+
this.metadata = metadata;
|
|
65
|
+
// Try to load a saved conversation ID from localStorage
|
|
66
|
+
this.loadSavedConversation();
|
|
67
|
+
}
|
|
68
|
+
ChatService.prototype.setMessageHandler = function (handler) {
|
|
69
|
+
this.messageHandler = handler;
|
|
70
|
+
};
|
|
71
|
+
ChatService.prototype.setTakeoverHandler = function (handler) {
|
|
72
|
+
this.takeoverHandler = handler;
|
|
73
|
+
};
|
|
74
|
+
ChatService.prototype.setFinalizedHandler = function (handler) {
|
|
75
|
+
this.finalizedHandler = handler;
|
|
76
|
+
};
|
|
77
|
+
ChatService.prototype.setConnectionStateHandler = function (handler) {
|
|
78
|
+
this.connectionStateHandler = handler;
|
|
79
|
+
};
|
|
80
|
+
ChatService.prototype.getPossibleQueries = function () {
|
|
81
|
+
return this.possibleQueries;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Load a saved conversation ID from localStorage
|
|
85
|
+
*/
|
|
86
|
+
ChatService.prototype.loadSavedConversation = function () {
|
|
87
|
+
try {
|
|
88
|
+
var savedConversation = localStorage.getItem(this.storageKey);
|
|
89
|
+
if (savedConversation) {
|
|
90
|
+
var _a = JSON.parse(savedConversation), conversationId = _a.conversationId, createTime = _a.createTime, isFinalized = _a.isFinalized;
|
|
91
|
+
this.conversationId = conversationId;
|
|
92
|
+
this.conversationCreateTime = createTime;
|
|
93
|
+
this.isFinalized = isFinalized || false;
|
|
94
|
+
console.log('Loaded saved conversation:', this.conversationId, 'Finalized:', this.isFinalized);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
console.error('Error loading saved conversation:', error);
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Save the current conversation ID to localStorage
|
|
103
|
+
*/
|
|
104
|
+
ChatService.prototype.saveConversation = function () {
|
|
105
|
+
try {
|
|
106
|
+
if (this.conversationId && this.conversationCreateTime) {
|
|
107
|
+
var conversationData = {
|
|
108
|
+
conversationId: this.conversationId,
|
|
109
|
+
createTime: this.conversationCreateTime,
|
|
110
|
+
isFinalized: this.isFinalized,
|
|
111
|
+
};
|
|
112
|
+
localStorage.setItem(this.storageKey, JSON.stringify(conversationData));
|
|
113
|
+
console.log('Saved conversation:', this.conversationId);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
console.error('Error saving conversation:', error);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
/**
|
|
121
|
+
* Reset the current conversation by clearing the ID and websocket
|
|
122
|
+
*/
|
|
123
|
+
ChatService.prototype.resetConversation = function () {
|
|
124
|
+
// Close the current websocket connection if it exists
|
|
125
|
+
if (this.webSocket) {
|
|
126
|
+
this.webSocket.close();
|
|
127
|
+
this.webSocket = null;
|
|
128
|
+
}
|
|
129
|
+
// Clear the conversation ID
|
|
130
|
+
this.conversationId = null;
|
|
131
|
+
this.conversationCreateTime = null;
|
|
132
|
+
this.isFinalized = false;
|
|
133
|
+
// Clear possible queries
|
|
134
|
+
this.possibleQueries = [];
|
|
135
|
+
// Remove from local storage
|
|
136
|
+
try {
|
|
137
|
+
localStorage.removeItem(this.storageKey);
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
console.error('Error removing conversation from storage:', error);
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* Check if there's a current conversation
|
|
145
|
+
*/
|
|
146
|
+
ChatService.prototype.hasActiveConversation = function () {
|
|
147
|
+
return !!this.conversationId;
|
|
148
|
+
};
|
|
149
|
+
/**
|
|
150
|
+
* Get the current conversation ID
|
|
151
|
+
*/
|
|
152
|
+
ChatService.prototype.getConversationId = function () {
|
|
153
|
+
return this.conversationId;
|
|
154
|
+
};
|
|
155
|
+
ChatService.prototype.isConversationFinalized = function () {
|
|
156
|
+
return this.isFinalized;
|
|
157
|
+
};
|
|
158
|
+
ChatService.prototype.startConversation = function () {
|
|
159
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
160
|
+
var requestBody, response, now, welcomeMessage, error_1;
|
|
161
|
+
return __generator(this, function (_a) {
|
|
162
|
+
switch (_a.label) {
|
|
163
|
+
case 0:
|
|
164
|
+
_a.trys.push([0, 2, , 3]);
|
|
165
|
+
requestBody = {
|
|
166
|
+
messages: [],
|
|
167
|
+
recorded_at: new Date().toISOString(),
|
|
168
|
+
data_source_id: "00000000-0000-0000-0000-000000000000"
|
|
169
|
+
};
|
|
170
|
+
if (this.metadata) {
|
|
171
|
+
requestBody.metadata = this.metadata;
|
|
172
|
+
}
|
|
173
|
+
return [4 /*yield*/, axios.post("".concat(this.baseUrl, "/api/conversations/in-progress/start"), requestBody, {
|
|
174
|
+
headers: {
|
|
175
|
+
'x-api-key': this.apiKey,
|
|
176
|
+
'Content-Type': 'application/json'
|
|
177
|
+
}
|
|
178
|
+
})];
|
|
179
|
+
case 1:
|
|
180
|
+
response = _a.sent();
|
|
181
|
+
this.conversationId = response.data.conversation_id;
|
|
182
|
+
// Store conversation create time (use from response if available, otherwise current time)
|
|
183
|
+
this.conversationCreateTime = response.data.create_time ? response.data.create_time / 1000 : Date.now() / 1000;
|
|
184
|
+
this.isFinalized = false;
|
|
185
|
+
this.saveConversation();
|
|
186
|
+
this.connectWebSocket();
|
|
187
|
+
// Store possible queries if available
|
|
188
|
+
if (response.data.agent_possible_queries && response.data.agent_possible_queries.length > 0) {
|
|
189
|
+
this.possibleQueries = response.data.agent_possible_queries;
|
|
190
|
+
}
|
|
191
|
+
// Process agent welcome message if available
|
|
192
|
+
if (response.data.agent_welcome_message && this.messageHandler) {
|
|
193
|
+
now = Date.now() / 1000;
|
|
194
|
+
welcomeMessage = {
|
|
195
|
+
create_time: now,
|
|
196
|
+
start_time: now - this.conversationCreateTime, // Relative to conversation start
|
|
197
|
+
end_time: (now - this.conversationCreateTime) + 0.01, // Relative to conversation start
|
|
198
|
+
speaker: 'agent',
|
|
199
|
+
text: response.data.agent_welcome_message
|
|
200
|
+
};
|
|
201
|
+
this.messageHandler(welcomeMessage);
|
|
202
|
+
}
|
|
203
|
+
return [2 /*return*/, response.data.conversation_id];
|
|
204
|
+
case 2:
|
|
205
|
+
error_1 = _a.sent();
|
|
206
|
+
console.error('Error starting conversation:', error_1);
|
|
207
|
+
throw error_1;
|
|
208
|
+
case 3: return [2 /*return*/];
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
};
|
|
213
|
+
ChatService.prototype.sendMessage = function (message) {
|
|
214
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
215
|
+
var now, chatMessage, error_2, errorMessage;
|
|
216
|
+
return __generator(this, function (_a) {
|
|
217
|
+
switch (_a.label) {
|
|
218
|
+
case 0:
|
|
219
|
+
if (!this.conversationId || !this.conversationCreateTime) {
|
|
220
|
+
throw new Error('Conversation not started');
|
|
221
|
+
}
|
|
222
|
+
now = Date.now() / 1000;
|
|
223
|
+
chatMessage = {
|
|
224
|
+
create_time: now,
|
|
225
|
+
start_time: now - this.conversationCreateTime, // Relative to conversation start
|
|
226
|
+
end_time: (now - this.conversationCreateTime) + 0.01, // Relative to conversation start
|
|
227
|
+
speaker: 'customer',
|
|
228
|
+
text: message
|
|
229
|
+
};
|
|
230
|
+
_a.label = 1;
|
|
231
|
+
case 1:
|
|
232
|
+
_a.trys.push([1, 3, , 4]);
|
|
233
|
+
return [4 /*yield*/, axios.patch("".concat(this.baseUrl, "/api/conversations/in-progress/update/").concat(this.conversationId), {
|
|
234
|
+
messages: [chatMessage]
|
|
235
|
+
}, {
|
|
236
|
+
headers: {
|
|
237
|
+
'x-api-key': this.apiKey,
|
|
238
|
+
'Content-Type': 'application/json'
|
|
239
|
+
}
|
|
240
|
+
})];
|
|
241
|
+
case 2:
|
|
242
|
+
_a.sent();
|
|
243
|
+
return [3 /*break*/, 4];
|
|
244
|
+
case 3:
|
|
245
|
+
error_2 = _a.sent();
|
|
246
|
+
console.error('Error sending message:', error_2);
|
|
247
|
+
// Check if this is the agent inactive error
|
|
248
|
+
if (error_2.response && error_2.response.data && error_2.response.data.error_key === 'AGENT_INACTIVE') {
|
|
249
|
+
// Create a custom message for the agent inactive error
|
|
250
|
+
if (this.messageHandler) {
|
|
251
|
+
errorMessage = {
|
|
252
|
+
create_time: now,
|
|
253
|
+
start_time: now - this.conversationCreateTime,
|
|
254
|
+
end_time: (now - this.conversationCreateTime) + 0.01,
|
|
255
|
+
speaker: 'special',
|
|
256
|
+
text: 'The agent is currently offline, please check back later. Thank you!'
|
|
257
|
+
};
|
|
258
|
+
this.messageHandler(errorMessage);
|
|
259
|
+
}
|
|
260
|
+
// Don't throw the error since we handled it with a message
|
|
261
|
+
return [2 /*return*/];
|
|
262
|
+
}
|
|
263
|
+
throw error_2;
|
|
264
|
+
case 4: return [2 /*return*/];
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
};
|
|
269
|
+
ChatService.prototype.connectWebSocket = function () {
|
|
270
|
+
var _this = this;
|
|
271
|
+
if (this.webSocket) {
|
|
272
|
+
this.webSocket.close();
|
|
273
|
+
}
|
|
274
|
+
if (!this.conversationId) {
|
|
275
|
+
throw new Error('Conversation ID is required for WebSocket connection');
|
|
276
|
+
}
|
|
277
|
+
if (this.connectionStateHandler)
|
|
278
|
+
this.connectionStateHandler('connecting');
|
|
279
|
+
var wsUrl = "".concat(this.baseUrl.replace('http', 'ws'), "/api/conversations/ws/").concat(this.conversationId, "?api_key=").concat(this.apiKey, "&lang=en&topics=message&topics=takeover&topics=finalize");
|
|
280
|
+
this.webSocket = new WebSocket(wsUrl);
|
|
281
|
+
this.webSocket.onopen = function () {
|
|
282
|
+
console.log('WebSocket connected');
|
|
283
|
+
if (_this.connectionStateHandler)
|
|
284
|
+
_this.connectionStateHandler('connected');
|
|
285
|
+
};
|
|
286
|
+
this.webSocket.onmessage = function (event) {
|
|
287
|
+
console.log('WebSocket message:', event.data);
|
|
288
|
+
try {
|
|
289
|
+
var data = JSON.parse(event.data);
|
|
290
|
+
if (data.type === 'message' && _this.messageHandler) {
|
|
291
|
+
if (Array.isArray(data.payload)) {
|
|
292
|
+
var messages = data.payload;
|
|
293
|
+
// Adjust timestamps to be relative to conversation start
|
|
294
|
+
var adjustedMessages = messages.map(function (msg) { return _this.adjustMessageTimestamps(msg); });
|
|
295
|
+
adjustedMessages.forEach(_this.messageHandler);
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
var adjustedMessage = _this.adjustMessageTimestamps(data.payload);
|
|
299
|
+
_this.messageHandler(adjustedMessage);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
else if (data.type === 'takeover') {
|
|
303
|
+
// Handle takeover event
|
|
304
|
+
console.log('Takeover event received');
|
|
305
|
+
// Create special message for the takeover indicator
|
|
306
|
+
if (_this.messageHandler) {
|
|
307
|
+
var now = Date.now() / 1000;
|
|
308
|
+
var takeoverMessage = {
|
|
309
|
+
create_time: now,
|
|
310
|
+
start_time: _this.conversationCreateTime ? now - _this.conversationCreateTime : 0,
|
|
311
|
+
end_time: _this.conversationCreateTime ? (now - _this.conversationCreateTime) + 0.01 : 0.01,
|
|
312
|
+
speaker: 'special',
|
|
313
|
+
text: 'Supervisor took over'
|
|
314
|
+
};
|
|
315
|
+
_this.messageHandler(takeoverMessage);
|
|
316
|
+
}
|
|
317
|
+
// Call the takeover handler if provided
|
|
318
|
+
if (_this.takeoverHandler) {
|
|
319
|
+
_this.takeoverHandler();
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
else if (data.type === 'finalize') {
|
|
323
|
+
// Handle finalized event
|
|
324
|
+
console.log('Finalized event received');
|
|
325
|
+
// Create special message for the finalized indicator
|
|
326
|
+
if (_this.messageHandler) {
|
|
327
|
+
var now = Date.now() / 1000;
|
|
328
|
+
var finalizedMessage = {
|
|
329
|
+
create_time: now,
|
|
330
|
+
start_time: _this.conversationCreateTime ? now - _this.conversationCreateTime : 0,
|
|
331
|
+
end_time: _this.conversationCreateTime ? (now - _this.conversationCreateTime) + 0.01 : 0.01,
|
|
332
|
+
speaker: 'special',
|
|
333
|
+
text: 'Conversation Finalized'
|
|
334
|
+
};
|
|
335
|
+
_this.messageHandler(finalizedMessage);
|
|
336
|
+
}
|
|
337
|
+
// Call the finalized handler if provided
|
|
338
|
+
if (_this.finalizedHandler) {
|
|
339
|
+
_this.finalizedHandler();
|
|
340
|
+
}
|
|
341
|
+
_this.isFinalized = true;
|
|
342
|
+
_this.saveConversation();
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
catch (error) {
|
|
346
|
+
console.error('Error parsing WebSocket message:', error);
|
|
347
|
+
}
|
|
348
|
+
};
|
|
349
|
+
this.webSocket.onerror = function (error) {
|
|
350
|
+
console.error('WebSocket error:', error);
|
|
351
|
+
if (_this.connectionStateHandler)
|
|
352
|
+
_this.connectionStateHandler('disconnected');
|
|
353
|
+
};
|
|
354
|
+
this.webSocket.onclose = function (event) {
|
|
355
|
+
console.log('WebSocket closed:', event.code, event.reason);
|
|
356
|
+
if (_this.connectionStateHandler)
|
|
357
|
+
_this.connectionStateHandler('disconnected');
|
|
358
|
+
};
|
|
359
|
+
};
|
|
360
|
+
ChatService.prototype.disconnect = function () {
|
|
361
|
+
if (this.webSocket) {
|
|
362
|
+
this.webSocket.close();
|
|
363
|
+
this.webSocket = null;
|
|
364
|
+
}
|
|
365
|
+
};
|
|
366
|
+
// Helper method to adjust message timestamps relative to conversation start
|
|
367
|
+
ChatService.prototype.adjustMessageTimestamps = function (message) {
|
|
368
|
+
if (!this.conversationCreateTime) {
|
|
369
|
+
return message;
|
|
370
|
+
}
|
|
371
|
+
return __assign(__assign({}, message), { start_time: message.start_time - this.conversationCreateTime, end_time: message.end_time - this.conversationCreateTime });
|
|
372
|
+
};
|
|
373
|
+
return ChatService;
|
|
374
|
+
}());
|
|
375
|
+
export { ChatService };
|
|
376
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhdFNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZXMvY2hhdFNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxPQUFPLEtBQUssTUFBTSxPQUFPLENBQUM7QUFDMUIsT0FBTyxFQUFFLFlBQVksSUFBSSxTQUFTLEVBQThCLE1BQU0sV0FBVyxDQUFDO0FBR2xGO0lBZUUscUJBQVksT0FBZSxFQUFFLE1BQWMsRUFBRSxRQUE4QjtRQVhuRSxtQkFBYyxHQUFrQixJQUFJLENBQUM7UUFDckMsMkJBQXNCLEdBQWtCLElBQUksQ0FBQyxDQUFDLGdDQUFnQztRQUM5RSxnQkFBVyxHQUFZLEtBQUssQ0FBQztRQUM3QixjQUFTLEdBQXFCLElBQUksQ0FBQztRQUNuQyxtQkFBYyxHQUE0QyxJQUFJLENBQUM7UUFDL0Qsb0JBQWUsR0FBd0IsSUFBSSxDQUFDO1FBQzVDLHFCQUFnQixHQUF3QixJQUFJLENBQUM7UUFDN0MsMkJBQXNCLEdBQTBFLElBQUksQ0FBQztRQUNyRyxlQUFVLEdBQUcsd0JBQXdCLENBQUM7UUFDdEMsb0JBQWUsR0FBYSxFQUFFLENBQUM7UUFHckMsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUM7UUFDdEUsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7UUFDekIsd0RBQXdEO1FBQ3hELElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO0lBQy9CLENBQUM7SUFFRCx1Q0FBaUIsR0FBakIsVUFBa0IsT0FBdUM7UUFDdkQsSUFBSSxDQUFDLGNBQWMsR0FBRyxPQUFPLENBQUM7SUFDaEMsQ0FBQztJQUVELHdDQUFrQixHQUFsQixVQUFtQixPQUFtQjtRQUNwQyxJQUFJLENBQUMsZUFBZSxHQUFHLE9BQU8sQ0FBQztJQUNqQyxDQUFDO0lBRUQseUNBQW1CLEdBQW5CLFVBQW9CLE9BQW1CO1FBQ3JDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxPQUFPLENBQUM7SUFDbEMsQ0FBQztJQUVELCtDQUF5QixHQUF6QixVQUEwQixPQUFxRTtRQUM3RixJQUFJLENBQUMsc0JBQXNCLEdBQUcsT0FBTyxDQUFDO0lBQ3hDLENBQUM7SUFFRCx3Q0FBa0IsR0FBbEI7UUFDRSxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUM7SUFDOUIsQ0FBQztJQUVEOztPQUVHO0lBQ0ssMkNBQXFCLEdBQTdCO1FBQ0UsSUFBSSxDQUFDO1lBQ0gsSUFBTSxpQkFBaUIsR0FBRyxZQUFZLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUNoRSxJQUFJLGlCQUFpQixFQUFFLENBQUM7Z0JBQ2hCLElBQUEsS0FBOEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxFQUF6RSxjQUFjLG9CQUFBLEVBQUUsVUFBVSxnQkFBQSxFQUFFLFdBQVcsaUJBQWtDLENBQUM7Z0JBQ2xGLElBQUksQ0FBQyxjQUFjLEdBQUcsY0FBYyxDQUFDO2dCQUNyQyxJQUFJLENBQUMsc0JBQXNCLEdBQUcsVUFBVSxDQUFDO2dCQUN6QyxJQUFJLENBQUMsV0FBVyxHQUFHLFdBQVcsSUFBSSxLQUFLLENBQUM7Z0JBQ3hDLE9BQU8sQ0FBQyxHQUFHLENBQUMsNEJBQTRCLEVBQUUsSUFBSSxDQUFDLGNBQWMsRUFBRSxZQUFZLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQ2pHLENBQUM7UUFDSCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE9BQU8sQ0FBQyxLQUFLLENBQUMsbUNBQW1DLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDNUQsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNLLHNDQUFnQixHQUF4QjtRQUNFLElBQUksQ0FBQztZQUNILElBQUksSUFBSSxDQUFDLGNBQWMsSUFBSSxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztnQkFDdkQsSUFBTSxnQkFBZ0IsR0FBRztvQkFDdkIsY0FBYyxFQUFFLElBQUksQ0FBQyxjQUFjO29CQUNuQyxVQUFVLEVBQUUsSUFBSSxDQUFDLHNCQUFzQjtvQkFDdkMsV0FBVyxFQUFFLElBQUksQ0FBQyxXQUFXO2lCQUM5QixDQUFDO2dCQUNGLFlBQVksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQztnQkFDeEUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxxQkFBcUIsRUFBRSxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7WUFDMUQsQ0FBQztRQUNILENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsT0FBTyxDQUFDLEtBQUssQ0FBQyw0QkFBNEIsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNyRCxDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0gsdUNBQWlCLEdBQWpCO1FBQ0Usc0RBQXNEO1FBQ3RELElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ25CLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDdkIsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7UUFDeEIsQ0FBQztRQUVELDRCQUE0QjtRQUM1QixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztRQUMzQixJQUFJLENBQUMsc0JBQXNCLEdBQUcsSUFBSSxDQUFDO1FBQ25DLElBQUksQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDO1FBRXpCLHlCQUF5QjtRQUN6QixJQUFJLENBQUMsZUFBZSxHQUFHLEVBQUUsQ0FBQztRQUUxQiw0QkFBNEI7UUFDNUIsSUFBSSxDQUFDO1lBQ0gsWUFBWSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDM0MsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixPQUFPLENBQUMsS0FBSyxDQUFDLDJDQUEyQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3BFLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSCwyQ0FBcUIsR0FBckI7UUFDRSxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDO0lBQy9CLENBQUM7SUFFRDs7T0FFRztJQUNILHVDQUFpQixHQUFqQjtRQUNFLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQztJQUM3QixDQUFDO0lBRUQsNkNBQXVCLEdBQXZCO1FBQ0UsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDO0lBQzFCLENBQUM7SUFFSyx1Q0FBaUIsR0FBdkI7Ozs7Ozs7d0JBRVUsV0FBVyxHQUFROzRCQUN2QixRQUFRLEVBQUUsRUFBRTs0QkFDWixXQUFXLEVBQUUsSUFBSSxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUU7NEJBQ3JDLGNBQWMsRUFBRSxzQ0FBc0M7eUJBQ3ZELENBQUM7d0JBRUYsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7NEJBQ2xCLFdBQVcsQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQzt3QkFDdkMsQ0FBQzt3QkFFZ0IscUJBQU0sS0FBSyxDQUFDLElBQUksQ0FDL0IsVUFBRyxJQUFJLENBQUMsT0FBTyx5Q0FBc0MsRUFDckQsV0FBVyxFQUNYO2dDQUNFLE9BQU8sRUFBRTtvQ0FDUCxXQUFXLEVBQUUsSUFBSSxDQUFDLE1BQU07b0NBQ3hCLGNBQWMsRUFBRSxrQkFBa0I7aUNBQ25DOzZCQUNGLENBQ0YsRUFBQTs7d0JBVEssUUFBUSxHQUFHLFNBU2hCO3dCQUVELElBQUksQ0FBQyxjQUFjLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUM7d0JBQ3BELDBGQUEwRjt3QkFDMUYsSUFBSSxDQUFDLHNCQUFzQixHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7d0JBQy9HLElBQUksQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDO3dCQUN6QixJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQzt3QkFDeEIsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7d0JBRXhCLHNDQUFzQzt3QkFDdEMsSUFBSSxRQUFRLENBQUMsSUFBSSxDQUFDLHNCQUFzQixJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsc0JBQXNCLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDOzRCQUM1RixJQUFJLENBQUMsZUFBZSxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsc0JBQXNCLENBQUM7d0JBQzlELENBQUM7d0JBRUQsNkNBQTZDO3dCQUM3QyxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMscUJBQXFCLElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDOzRCQUN6RCxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQzs0QkFDeEIsY0FBYyxHQUFnQjtnQ0FDbEMsV0FBVyxFQUFFLEdBQUc7Z0NBQ2hCLFVBQVUsRUFBRSxHQUFHLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixFQUFFLGlDQUFpQztnQ0FDaEYsUUFBUSxFQUFFLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxHQUFHLElBQUksRUFBRSxpQ0FBaUM7Z0NBQ3ZGLE9BQU8sRUFBRSxPQUFPO2dDQUNoQixJQUFJLEVBQUUsUUFBUSxDQUFDLElBQUksQ0FBQyxxQkFBcUI7NkJBQzFDLENBQUM7NEJBQ0YsSUFBSSxDQUFDLGNBQWMsQ0FBQyxjQUFjLENBQUMsQ0FBQzt3QkFDdEMsQ0FBQzt3QkFDRCxzQkFBTyxRQUFRLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBQzs7O3dCQUVyQyxPQUFPLENBQUMsS0FBSyxDQUFDLDhCQUE4QixFQUFFLE9BQUssQ0FBQyxDQUFDO3dCQUNyRCxNQUFNLE9BQUssQ0FBQzs7Ozs7S0FFZjtJQUVLLGlDQUFXLEdBQWpCLFVBQWtCLE9BQWU7Ozs7Ozt3QkFDL0IsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLElBQUksQ0FBQyxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQzs0QkFDekQsTUFBTSxJQUFJLEtBQUssQ0FBQywwQkFBMEIsQ0FBQyxDQUFDO3dCQUM5QyxDQUFDO3dCQUVLLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO3dCQUN4QixXQUFXLEdBQWdCOzRCQUMvQixXQUFXLEVBQUUsR0FBRzs0QkFDaEIsVUFBVSxFQUFFLEdBQUcsR0FBRyxJQUFJLENBQUMsc0JBQXNCLEVBQUUsaUNBQWlDOzRCQUNoRixRQUFRLEVBQUUsQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixDQUFDLEdBQUcsSUFBSSxFQUFFLGlDQUFpQzs0QkFDdkYsT0FBTyxFQUFFLFVBQVU7NEJBQ25CLElBQUksRUFBRSxPQUFPO3lCQUNkLENBQUM7Ozs7d0JBR0EscUJBQU0sS0FBSyxDQUFDLEtBQUssQ0FDZixVQUFHLElBQUksQ0FBQyxPQUFPLG1EQUF5QyxJQUFJLENBQUMsY0FBYyxDQUFFLEVBQzdFO2dDQUNFLFFBQVEsRUFBRSxDQUFDLFdBQVcsQ0FBQzs2QkFDeEIsRUFDRDtnQ0FDRSxPQUFPLEVBQUU7b0NBQ1AsV0FBVyxFQUFFLElBQUksQ0FBQyxNQUFNO29DQUN4QixjQUFjLEVBQUUsa0JBQWtCO2lDQUNuQzs2QkFDRixDQUNGLEVBQUE7O3dCQVhELFNBV0MsQ0FBQzs7Ozt3QkFFRixPQUFPLENBQUMsS0FBSyxDQUFDLHdCQUF3QixFQUFFLE9BQUssQ0FBQyxDQUFDO3dCQUUvQyw0Q0FBNEM7d0JBQzVDLElBQUksT0FBSyxDQUFDLFFBQVEsSUFBSSxPQUFLLENBQUMsUUFBUSxDQUFDLElBQUksSUFBSSxPQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxTQUFTLEtBQUssZ0JBQWdCLEVBQUUsQ0FBQzs0QkFDaEcsdURBQXVEOzRCQUN2RCxJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQ0FDbEIsWUFBWSxHQUFnQjtvQ0FDaEMsV0FBVyxFQUFFLEdBQUc7b0NBQ2hCLFVBQVUsRUFBRSxHQUFHLEdBQUcsSUFBSSxDQUFDLHNCQUFzQjtvQ0FDN0MsUUFBUSxFQUFFLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxHQUFHLElBQUk7b0NBQ3BELE9BQU8sRUFBRSxTQUFTO29DQUNsQixJQUFJLEVBQUUscUVBQXFFO2lDQUM1RSxDQUFDO2dDQUNGLElBQUksQ0FBQyxjQUFjLENBQUMsWUFBWSxDQUFDLENBQUM7NEJBQ3BDLENBQUM7NEJBQ0QsMkRBQTJEOzRCQUMzRCxzQkFBTzt3QkFDVCxDQUFDO3dCQUVELE1BQU0sT0FBSyxDQUFDOzs7OztLQUVmO0lBRUQsc0NBQWdCLEdBQWhCO1FBQUEsaUJBMkZDO1FBMUZDLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ25CLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDekIsQ0FBQztRQUVELElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDekIsTUFBTSxJQUFJLEtBQUssQ0FBQyxzREFBc0QsQ0FBQyxDQUFDO1FBQzFFLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxzQkFBc0I7WUFBRSxJQUFJLENBQUMsc0JBQXNCLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDM0UsSUFBTSxLQUFLLEdBQUcsVUFBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLG1DQUF5QixJQUFJLENBQUMsY0FBYyxzQkFBWSxJQUFJLENBQUMsTUFBTSw0REFBeUQsQ0FBQztRQUNoTCxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRXRDLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHO1lBQ3RCLE9BQU8sQ0FBQyxHQUFHLENBQUMscUJBQXFCLENBQUMsQ0FBQztZQUNuQyxJQUFJLEtBQUksQ0FBQyxzQkFBc0I7Z0JBQUUsS0FBSSxDQUFDLHNCQUFzQixDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQzVFLENBQUMsQ0FBQztRQUVGLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxHQUFHLFVBQUMsS0FBb0I7WUFDOUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDOUMsSUFBSSxDQUFDO2dCQUNILElBQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLElBQWMsQ0FBQyxDQUFDO2dCQUM5QyxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssU0FBUyxJQUFJLEtBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztvQkFDbkQsSUFBRyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO3dCQUMvQixJQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsT0FBd0IsQ0FBQTt3QkFDOUMseURBQXlEO3dCQUN6RCxJQUFNLGdCQUFnQixHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsVUFBQSxHQUFHLElBQUksT0FBQSxLQUFJLENBQUMsdUJBQXVCLENBQUMsR0FBRyxDQUFDLEVBQWpDLENBQWlDLENBQUMsQ0FBQzt3QkFDaEYsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLEtBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztvQkFDaEQsQ0FBQzt5QkFBTSxDQUFDO3dCQUNOLElBQU0sZUFBZSxHQUFHLEtBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsT0FBc0IsQ0FBQyxDQUFDO3dCQUNsRixLQUFJLENBQUMsY0FBYyxDQUFDLGVBQWUsQ0FBQyxDQUFDO29CQUN2QyxDQUFDO2dCQUNILENBQUM7cUJBQU0sSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLFVBQVUsRUFBRSxDQUFDO29CQUNwQyx3QkFBd0I7b0JBQ3hCLE9BQU8sQ0FBQyxHQUFHLENBQUMseUJBQXlCLENBQUMsQ0FBQztvQkFFdkMsb0RBQW9EO29CQUNwRCxJQUFJLEtBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQzt3QkFDeEIsSUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQzt3QkFDOUIsSUFBTSxlQUFlLEdBQWdCOzRCQUNuQyxXQUFXLEVBQUUsR0FBRzs0QkFDaEIsVUFBVSxFQUFFLEtBQUksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEtBQUksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLENBQUMsQ0FBQzs0QkFDL0UsUUFBUSxFQUFFLEtBQUksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsS0FBSSxDQUFDLHNCQUFzQixDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJOzRCQUN6RixPQUFPLEVBQUUsU0FBUzs0QkFDbEIsSUFBSSxFQUFFLHNCQUFzQjt5QkFDN0IsQ0FBQzt3QkFDRixLQUFJLENBQUMsY0FBYyxDQUFDLGVBQWUsQ0FBQyxDQUFDO29CQUN2QyxDQUFDO29CQUVELHdDQUF3QztvQkFDeEMsSUFBSSxLQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7d0JBQ3pCLEtBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztvQkFDekIsQ0FBQztnQkFDSCxDQUFDO3FCQUFNLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxVQUFVLEVBQUUsQ0FBQztvQkFDcEMseUJBQXlCO29CQUN6QixPQUFPLENBQUMsR0FBRyxDQUFDLDBCQUEwQixDQUFDLENBQUM7b0JBRXhDLHFEQUFxRDtvQkFDckQsSUFBSSxLQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7d0JBQ3hCLElBQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7d0JBQzlCLElBQU0sZ0JBQWdCLEdBQWdCOzRCQUNwQyxXQUFXLEVBQUUsR0FBRzs0QkFDaEIsVUFBVSxFQUFFLEtBQUksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEtBQUksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLENBQUMsQ0FBQzs0QkFDL0UsUUFBUSxFQUFFLEtBQUksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsS0FBSSxDQUFDLHNCQUFzQixDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJOzRCQUN6RixPQUFPLEVBQUUsU0FBUzs0QkFDbEIsSUFBSSxFQUFFLHdCQUF3Qjt5QkFDL0IsQ0FBQzt3QkFDRixLQUFJLENBQUMsY0FBYyxDQUFDLGdCQUFnQixDQUFDLENBQUM7b0JBQ3hDLENBQUM7b0JBRUQseUNBQXlDO29CQUN6QyxJQUFJLEtBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO3dCQUMxQixLQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztvQkFDMUIsQ0FBQztvQkFDRCxLQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztvQkFDeEIsS0FBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7Z0JBQzFCLENBQUM7WUFDSCxDQUFDO1lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztnQkFDZixPQUFPLENBQUMsS0FBSyxDQUFDLGtDQUFrQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQzNELENBQUM7UUFDSCxDQUFDLENBQUM7UUFFRixJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sR0FBRyxVQUFDLEtBQVk7WUFDcEMsT0FBTyxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUN6QyxJQUFJLEtBQUksQ0FBQyxzQkFBc0I7Z0JBQUUsS0FBSSxDQUFDLHNCQUFzQixDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQy9FLENBQUMsQ0FBQztRQUVGLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxHQUFHLFVBQUMsS0FBa0I7WUFDMUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUMzRCxJQUFJLEtBQUksQ0FBQyxzQkFBc0I7Z0JBQUUsS0FBSSxDQUFDLHNCQUFzQixDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQy9FLENBQUMsQ0FBQztJQUNKLENBQUM7SUFFRCxnQ0FBVSxHQUFWO1FBQ0UsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDbkIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztRQUN4QixDQUFDO0lBQ0gsQ0FBQztJQUVELDRFQUE0RTtJQUNwRSw2Q0FBdUIsR0FBL0IsVUFBZ0MsT0FBb0I7UUFDbEQsSUFBSSxDQUFDLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO1lBQ2pDLE9BQU8sT0FBTyxDQUFDO1FBQ2pCLENBQUM7UUFFRCw2QkFDSyxPQUFPLEtBQ1YsVUFBVSxFQUFFLE9BQU8sQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixFQUM1RCxRQUFRLEVBQUUsT0FBTyxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsc0JBQXNCLElBQ3hEO0lBQ0osQ0FBQztJQUNILGtCQUFDO0FBQUQsQ0FBQyxBQXJWRCxJQXFWQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBheGlvcyBmcm9tICdheGlvcyc7XG5pbXBvcnQgeyB3M2N3ZWJzb2NrZXQgYXMgV2ViU29ja2V0LCBJTWVzc2FnZUV2ZW50LCBJQ2xvc2VFdmVudCB9IGZyb20gJ3dlYnNvY2tldCc7XG5pbXBvcnQgeyBDaGF0TWVzc2FnZSwgU3RhcnRDb252ZXJzYXRpb25SZXNwb25zZSB9IGZyb20gJy4uL3R5cGVzJztcblxuZXhwb3J0IGNsYXNzIENoYXRTZXJ2aWNlIHtcbiAgcHJpdmF0ZSBiYXNlVXJsOiBzdHJpbmc7XG4gIHByaXZhdGUgYXBpS2V5OiBzdHJpbmc7XG4gIHByaXZhdGUgbWV0YWRhdGE6IFJlY29yZDxzdHJpbmcsIGFueT4gfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgY29udmVyc2F0aW9uSWQ6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGNvbnZlcnNhdGlvbkNyZWF0ZVRpbWU6IG51bWJlciB8IG51bGwgPSBudWxsOyAvLyBUcmFjayBjb252ZXJzYXRpb24gc3RhcnQgdGltZVxuICBwcml2YXRlIGlzRmluYWxpemVkOiBib29sZWFuID0gZmFsc2U7XG4gIHByaXZhdGUgd2ViU29ja2V0OiBXZWJTb2NrZXQgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBtZXNzYWdlSGFuZGxlcjogKChtZXNzYWdlOiBDaGF0TWVzc2FnZSkgPT4gdm9pZCkgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSB0YWtlb3ZlckhhbmRsZXI6ICgoKSA9PiB2b2lkKSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGZpbmFsaXplZEhhbmRsZXI6ICgoKSA9PiB2b2lkKSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGNvbm5lY3Rpb25TdGF0ZUhhbmRsZXI6ICgoc3RhdGU6ICdjb25uZWN0aW5nJyB8ICdjb25uZWN0ZWQnIHwgJ2Rpc2Nvbm5lY3RlZCcpID0+IHZvaWQpIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgc3RvcmFnZUtleSA9ICdnZW5hc3Npc3RfY29udmVyc2F0aW9uJztcbiAgcHJpdmF0ZSBwb3NzaWJsZVF1ZXJpZXM6IHN0cmluZ1tdID0gW107XG5cbiAgY29uc3RydWN0b3IoYmFzZVVybDogc3RyaW5nLCBhcGlLZXk6IHN0cmluZywgbWV0YWRhdGE/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSB7XG4gICAgdGhpcy5iYXNlVXJsID0gYmFzZVVybC5lbmRzV2l0aCgnLycpID8gYmFzZVVybC5zbGljZSgwLCAtMSkgOiBiYXNlVXJsO1xuICAgIHRoaXMuYXBpS2V5ID0gYXBpS2V5O1xuICAgIHRoaXMubWV0YWRhdGEgPSBtZXRhZGF0YTtcbiAgICAvLyBUcnkgdG8gbG9hZCBhIHNhdmVkIGNvbnZlcnNhdGlvbiBJRCBmcm9tIGxvY2FsU3RvcmFnZVxuICAgIHRoaXMubG9hZFNhdmVkQ29udmVyc2F0aW9uKCk7XG4gIH1cblxuICBzZXRNZXNzYWdlSGFuZGxlcihoYW5kbGVyOiAobWVzc2FnZTogQ2hhdE1lc3NhZ2UpID0+IHZvaWQpIHtcbiAgICB0aGlzLm1lc3NhZ2VIYW5kbGVyID0gaGFuZGxlcjtcbiAgfVxuXG4gIHNldFRha2VvdmVySGFuZGxlcihoYW5kbGVyOiAoKSA9PiB2b2lkKSB7XG4gICAgdGhpcy50YWtlb3ZlckhhbmRsZXIgPSBoYW5kbGVyO1xuICB9XG5cbiAgc2V0RmluYWxpemVkSGFuZGxlcihoYW5kbGVyOiAoKSA9PiB2b2lkKSB7XG4gICAgdGhpcy5maW5hbGl6ZWRIYW5kbGVyID0gaGFuZGxlcjtcbiAgfVxuXG4gIHNldENvbm5lY3Rpb25TdGF0ZUhhbmRsZXIoaGFuZGxlcjogKHN0YXRlOiAnY29ubmVjdGluZycgfCAnY29ubmVjdGVkJyB8ICdkaXNjb25uZWN0ZWQnKSA9PiB2b2lkKSB7XG4gICAgdGhpcy5jb25uZWN0aW9uU3RhdGVIYW5kbGVyID0gaGFuZGxlcjtcbiAgfVxuXG4gIGdldFBvc3NpYmxlUXVlcmllcygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMucG9zc2libGVRdWVyaWVzO1xuICB9XG5cbiAgLyoqXG4gICAqIExvYWQgYSBzYXZlZCBjb252ZXJzYXRpb24gSUQgZnJvbSBsb2NhbFN0b3JhZ2VcbiAgICovXG4gIHByaXZhdGUgbG9hZFNhdmVkQ29udmVyc2F0aW9uKCk6IHZvaWQge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBzYXZlZENvbnZlcnNhdGlvbiA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKHRoaXMuc3RvcmFnZUtleSk7XG4gICAgICBpZiAoc2F2ZWRDb252ZXJzYXRpb24pIHtcbiAgICAgICAgY29uc3QgeyBjb252ZXJzYXRpb25JZCwgY3JlYXRlVGltZSwgaXNGaW5hbGl6ZWQgfSA9IEpTT04ucGFyc2Uoc2F2ZWRDb252ZXJzYXRpb24pO1xuICAgICAgICB0aGlzLmNvbnZlcnNhdGlvbklkID0gY29udmVyc2F0aW9uSWQ7XG4gICAgICAgIHRoaXMuY29udmVyc2F0aW9uQ3JlYXRlVGltZSA9IGNyZWF0ZVRpbWU7XG4gICAgICAgIHRoaXMuaXNGaW5hbGl6ZWQgPSBpc0ZpbmFsaXplZCB8fCBmYWxzZTtcbiAgICAgICAgY29uc29sZS5sb2coJ0xvYWRlZCBzYXZlZCBjb252ZXJzYXRpb246JywgdGhpcy5jb252ZXJzYXRpb25JZCwgJ0ZpbmFsaXplZDonLCB0aGlzLmlzRmluYWxpemVkKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgbG9hZGluZyBzYXZlZCBjb252ZXJzYXRpb246JywgZXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTYXZlIHRoZSBjdXJyZW50IGNvbnZlcnNhdGlvbiBJRCB0byBsb2NhbFN0b3JhZ2VcbiAgICovXG4gIHByaXZhdGUgc2F2ZUNvbnZlcnNhdGlvbigpOiB2b2lkIHtcbiAgICB0cnkge1xuICAgICAgaWYgKHRoaXMuY29udmVyc2F0aW9uSWQgJiYgdGhpcy5jb252ZXJzYXRpb25DcmVhdGVUaW1lKSB7XG4gICAgICAgIGNvbnN0IGNvbnZlcnNhdGlvbkRhdGEgPSB7XG4gICAgICAgICAgY29udmVyc2F0aW9uSWQ6IHRoaXMuY29udmVyc2F0aW9uSWQsXG4gICAgICAgICAgY3JlYXRlVGltZTogdGhpcy5jb252ZXJzYXRpb25DcmVhdGVUaW1lLFxuICAgICAgICAgIGlzRmluYWxpemVkOiB0aGlzLmlzRmluYWxpemVkLFxuICAgICAgICB9O1xuICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSh0aGlzLnN0b3JhZ2VLZXksIEpTT04uc3RyaW5naWZ5KGNvbnZlcnNhdGlvbkRhdGEpKTtcbiAgICAgICAgY29uc29sZS5sb2coJ1NhdmVkIGNvbnZlcnNhdGlvbjonLCB0aGlzLmNvbnZlcnNhdGlvbklkKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcignRXJyb3Igc2F2aW5nIGNvbnZlcnNhdGlvbjonLCBlcnJvcik7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlc2V0IHRoZSBjdXJyZW50IGNvbnZlcnNhdGlvbiBieSBjbGVhcmluZyB0aGUgSUQgYW5kIHdlYnNvY2tldFxuICAgKi9cbiAgcmVzZXRDb252ZXJzYXRpb24oKTogdm9pZCB7XG4gICAgLy8gQ2xvc2UgdGhlIGN1cnJlbnQgd2Vic29ja2V0IGNvbm5lY3Rpb24gaWYgaXQgZXhpc3RzXG4gICAgaWYgKHRoaXMud2ViU29ja2V0KSB7XG4gICAgICB0aGlzLndlYlNvY2tldC5jbG9zZSgpO1xuICAgICAgdGhpcy53ZWJTb2NrZXQgPSBudWxsO1xuICAgIH1cbiAgICBcbiAgICAvLyBDbGVhciB0aGUgY29udmVyc2F0aW9uIElEXG4gICAgdGhpcy5jb252ZXJzYXRpb25JZCA9IG51bGw7XG4gICAgdGhpcy5jb252ZXJzYXRpb25DcmVhdGVUaW1lID0gbnVsbDtcbiAgICB0aGlzLmlzRmluYWxpemVkID0gZmFsc2U7XG5cbiAgICAvLyBDbGVhciBwb3NzaWJsZSBxdWVyaWVzXG4gICAgdGhpcy5wb3NzaWJsZVF1ZXJpZXMgPSBbXTtcbiAgICBcbiAgICAvLyBSZW1vdmUgZnJvbSBsb2NhbCBzdG9yYWdlXG4gICAgdHJ5IHtcbiAgICAgIGxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKHRoaXMuc3RvcmFnZUtleSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHJlbW92aW5nIGNvbnZlcnNhdGlvbiBmcm9tIHN0b3JhZ2U6JywgZXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiB0aGVyZSdzIGEgY3VycmVudCBjb252ZXJzYXRpb25cbiAgICovXG4gIGhhc0FjdGl2ZUNvbnZlcnNhdGlvbigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLmNvbnZlcnNhdGlvbklkO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgY3VycmVudCBjb252ZXJzYXRpb24gSURcbiAgICovXG4gIGdldENvbnZlcnNhdGlvbklkKCk6IHN0cmluZyB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLmNvbnZlcnNhdGlvbklkO1xuICB9XG5cbiAgaXNDb252ZXJzYXRpb25GaW5hbGl6ZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuaXNGaW5hbGl6ZWQ7XG4gIH1cblxuICBhc3luYyBzdGFydENvbnZlcnNhdGlvbigpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXF1ZXN0Qm9keTogYW55ID0ge1xuICAgICAgICBtZXNzYWdlczogW10sXG4gICAgICAgIHJlY29yZGVkX2F0OiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICAgIGRhdGFfc291cmNlX2lkOiBcIjAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMFwiXG4gICAgICB9O1xuXG4gICAgICBpZiAodGhpcy5tZXRhZGF0YSkge1xuICAgICAgICByZXF1ZXN0Qm9keS5tZXRhZGF0YSA9IHRoaXMubWV0YWRhdGE7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgYXhpb3MucG9zdDxTdGFydENvbnZlcnNhdGlvblJlc3BvbnNlPihcbiAgICAgICAgYCR7dGhpcy5iYXNlVXJsfS9hcGkvY29udmVyc2F0aW9ucy9pbi1wcm9ncmVzcy9zdGFydGAsXG4gICAgICAgIHJlcXVlc3RCb2R5LFxuICAgICAgICB7XG4gICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgJ3gtYXBpLWtleSc6IHRoaXMuYXBpS2V5LFxuICAgICAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJ1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcblxuICAgICAgdGhpcy5jb252ZXJzYXRpb25JZCA9IHJlc3BvbnNlLmRhdGEuY29udmVyc2F0aW9uX2lkO1xuICAgICAgLy8gU3RvcmUgY29udmVyc2F0aW9uIGNyZWF0ZSB0aW1lICh1c2UgZnJvbSByZXNwb25zZSBpZiBhdmFpbGFibGUsIG90aGVyd2lzZSBjdXJyZW50IHRpbWUpXG4gICAgICB0aGlzLmNvbnZlcnNhdGlvbkNyZWF0ZVRpbWUgPSByZXNwb25zZS5kYXRhLmNyZWF0ZV90aW1lID8gcmVzcG9uc2UuZGF0YS5jcmVhdGVfdGltZSAvIDEwMDAgOiBEYXRlLm5vdygpIC8gMTAwMDtcbiAgICAgIHRoaXMuaXNGaW5hbGl6ZWQgPSBmYWxzZTtcbiAgICAgIHRoaXMuc2F2ZUNvbnZlcnNhdGlvbigpO1xuICAgICAgdGhpcy5jb25uZWN0V2ViU29ja2V0KCk7XG5cbiAgICAgIC8vIFN0b3JlIHBvc3NpYmxlIHF1ZXJpZXMgaWYgYXZhaWxhYmxlXG4gICAgICBpZiAocmVzcG9uc2UuZGF0YS5hZ2VudF9wb3NzaWJsZV9xdWVyaWVzICYmIHJlc3BvbnNlLmRhdGEuYWdlbnRfcG9zc2libGVfcXVlcmllcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRoaXMucG9zc2libGVRdWVyaWVzID0gcmVzcG9uc2UuZGF0YS5hZ2VudF9wb3NzaWJsZV9xdWVyaWVzO1xuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBQcm9jZXNzIGFnZW50IHdlbGNvbWUgbWVzc2FnZSBpZiBhdmFpbGFibGVcbiAgICAgIGlmIChyZXNwb25zZS5kYXRhLmFnZW50X3dlbGNvbWVfbWVzc2FnZSAmJiB0aGlzLm1lc3NhZ2VIYW5kbGVyKSB7XG4gICAgICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCkgLyAxMDAwO1xuICAgICAgICBjb25zdCB3ZWxjb21lTWVzc2FnZTogQ2hhdE1lc3NhZ2UgPSB7XG4gICAgICAgICAgY3JlYXRlX3RpbWU6IG5vdyxcbiAgICAgICAgICBzdGFydF90aW1lOiBub3cgLSB0aGlzLmNvbnZlcnNhdGlvbkNyZWF0ZVRpbWUsIC8vIFJlbGF0aXZlIHRvIGNvbnZlcnNhdGlvbiBzdGFydFxuICAgICAgICAgIGVuZF90aW1lOiAobm93IC0gdGhpcy5jb252ZXJzYXRpb25DcmVhdGVUaW1lKSArIDAuMDEsIC8vIFJlbGF0aXZlIHRvIGNvbnZlcnNhdGlvbiBzdGFydFxuICAgICAgICAgIHNwZWFrZXI6ICdhZ2VudCcsXG4gICAgICAgICAgdGV4dDogcmVzcG9uc2UuZGF0YS5hZ2VudF93ZWxjb21lX21lc3NhZ2VcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5tZXNzYWdlSGFuZGxlcih3ZWxjb21lTWVzc2FnZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzcG9uc2UuZGF0YS5jb252ZXJzYXRpb25faWQ7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHN0YXJ0aW5nIGNvbnZlcnNhdGlvbjonLCBlcnJvcik7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICBhc3luYyBzZW5kTWVzc2FnZShtZXNzYWdlOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRoaXMuY29udmVyc2F0aW9uSWQgfHwgIXRoaXMuY29udmVyc2F0aW9uQ3JlYXRlVGltZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb252ZXJzYXRpb24gbm90IHN0YXJ0ZWQnKTtcbiAgICB9XG5cbiAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpIC8gMTAwMDtcbiAgICBjb25zdCBjaGF0TWVzc2FnZTogQ2hhdE1lc3NhZ2UgPSB7XG4gICAgICBjcmVhdGVfdGltZTogbm93LFxuICAgICAgc3RhcnRfdGltZTogbm93IC0gdGhpcy5jb252ZXJzYXRpb25DcmVhdGVUaW1lLCAvLyBSZWxhdGl2ZSB0byBjb252ZXJzYXRpb24gc3RhcnRcbiAgICAgIGVuZF90aW1lOiAobm93IC0gdGhpcy5jb252ZXJzYXRpb25DcmVhdGVUaW1lKSArIDAuMDEsIC8vIFJlbGF0aXZlIHRvIGNvbnZlcnNhdGlvbiBzdGFydFxuICAgICAgc3BlYWtlcjogJ2N1c3RvbWVyJyxcbiAgICAgIHRleHQ6IG1lc3NhZ2VcbiAgICB9O1xuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGF4aW9zLnBhdGNoKFxuICAgICAgICBgJHt0aGlzLmJhc2VVcmx9L2FwaS9jb252ZXJzYXRpb25zL2luLXByb2dyZXNzL3VwZGF0ZS8ke3RoaXMuY29udmVyc2F0aW9uSWR9YCxcbiAgICAgICAge1xuICAgICAgICAgIG1lc3NhZ2VzOiBbY2hhdE1lc3NhZ2VdXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAneC1hcGkta2V5JzogdGhpcy5hcGlLZXksXG4gICAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHNlbmRpbmcgbWVzc2FnZTonLCBlcnJvcik7XG4gICAgICBcbiAgICAgIC8vIENoZWNrIGlmIHRoaXMgaXMgdGhlIGFnZW50IGluYWN0aXZlIGVycm9yXG4gICAgICBpZiAoZXJyb3IucmVzcG9uc2UgJiYgZXJyb3IucmVzcG9uc2UuZGF0YSAmJiBlcnJvci5yZXNwb25zZS5kYXRhLmVycm9yX2tleSA9PT0gJ0FHRU5UX0lOQUNUSVZFJykge1xuICAgICAgICAvLyBDcmVhdGUgYSBjdXN0b20gbWVzc2FnZSBmb3IgdGhlIGFnZW50IGluYWN0aXZlIGVycm9yXG4gICAgICAgIGlmICh0aGlzLm1lc3NhZ2VIYW5kbGVyKSB7XG4gICAgICAgICAgY29uc3QgZXJyb3JNZXNzYWdlOiBDaGF0TWVzc2FnZSA9IHtcbiAgICAgICAgICAgIGNyZWF0ZV90aW1lOiBub3csXG4gICAgICAgICAgICBzdGFydF90aW1lOiBub3cgLSB0aGlzLmNvbnZlcnNhdGlvbkNyZWF0ZVRpbWUsXG4gICAgICAgICAgICBlbmRfdGltZTogKG5vdyAtIHRoaXMuY29udmVyc2F0aW9uQ3JlYXRlVGltZSkgKyAwLjAxLFxuICAgICAgICAgICAgc3BlYWtlcjogJ3NwZWNpYWwnLFxuICAgICAgICAgICAgdGV4dDogJ1RoZSBhZ2VudCBpcyBjdXJyZW50bHkgb2ZmbGluZSwgcGxlYXNlIGNoZWNrIGJhY2sgbGF0ZXIuIFRoYW5rIHlvdSEnXG4gICAgICAgICAgfTtcbiAgICAgICAgICB0aGlzLm1lc3NhZ2VIYW5kbGVyKGVycm9yTWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gRG9uJ3QgdGhyb3cgdGhlIGVycm9yIHNpbmNlIHdlIGhhbmRsZWQgaXQgd2l0aCBhIG1lc3NhZ2VcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgXG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICBjb25uZWN0V2ViU29ja2V0KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLndlYlNvY2tldCkge1xuICAgICAgdGhpcy53ZWJTb2NrZXQuY2xvc2UoKTtcbiAgICB9XG4gICAgXG4gICAgaWYgKCF0aGlzLmNvbnZlcnNhdGlvbklkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvbnZlcnNhdGlvbiBJRCBpcyByZXF1aXJlZCBmb3IgV2ViU29ja2V0IGNvbm5lY3Rpb24nKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jb25uZWN0aW9uU3RhdGVIYW5kbGVyKSB0aGlzLmNvbm5lY3Rpb25TdGF0ZUhhbmRsZXIoJ2Nvbm5lY3RpbmcnKTtcbiAgICBjb25zdCB3c1VybCA9IGAke3RoaXMuYmFzZVVybC5yZXBsYWNlKCdodHRwJywgJ3dzJyl9L2FwaS9jb252ZXJzYXRpb25zL3dzLyR7dGhpcy5jb252ZXJzYXRpb25JZH0/YXBpX2tleT0ke3RoaXMuYXBpS2V5fSZsYW5nPWVuJnRvcGljcz1tZXNzYWdlJnRvcGljcz10YWtlb3ZlciZ0b3BpY3M9ZmluYWxpemVgO1xuICAgIHRoaXMud2ViU29ja2V0ID0gbmV3IFdlYlNvY2tldCh3c1VybCk7XG5cbiAgICB0aGlzLndlYlNvY2tldC5vbm9wZW4gPSAoKSA9PiB7XG4gICAgICBjb25zb2xlLmxvZygnV2ViU29ja2V0IGNvbm5lY3RlZCcpO1xuICAgICAgaWYgKHRoaXMuY29ubmVjdGlvblN0YXRlSGFuZGxlcikgdGhpcy5jb25uZWN0aW9uU3RhdGVIYW5kbGVyKCdjb25uZWN0ZWQnKTtcbiAgICB9O1xuXG4gICAgdGhpcy53ZWJTb2NrZXQub25tZXNzYWdlID0gKGV2ZW50OiBJTWVzc2FnZUV2ZW50KSA9PiB7XG4gICAgICBjb25zb2xlLmxvZygnV2ViU29ja2V0IG1lc3NhZ2U6JywgZXZlbnQuZGF0YSk7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBkYXRhID0gSlNPTi5wYXJzZShldmVudC5kYXRhIGFzIHN0cmluZyk7XG4gICAgICAgIGlmIChkYXRhLnR5cGUgPT09ICdtZXNzYWdlJyAmJiB0aGlzLm1lc3NhZ2VIYW5kbGVyKSB7XG4gICAgICAgICAgaWYoQXJyYXkuaXNBcnJheShkYXRhLnBheWxvYWQpKSB7XG4gICAgICAgICAgICBjb25zdCBtZXNzYWdlcyA9IGRhdGEucGF5bG9hZCBhcyBDaGF0TWVzc2FnZVtdXG4gICAgICAgICAgICAvLyBBZGp1c3QgdGltZXN0YW1wcyB0byBiZSByZWxhdGl2ZSB0byBjb252ZXJzYXRpb24gc3RhcnRcbiAgICAgICAgICAgIGNvbnN0IGFkanVzdGVkTWVzc2FnZXMgPSBtZXNzYWdlcy5tYXAobXNnID0+IHRoaXMuYWRqdXN0TWVzc2FnZVRpbWVzdGFtcHMobXNnKSk7XG4gICAgICAgICAgICBhZGp1c3RlZE1lc3NhZ2VzLmZvckVhY2godGhpcy5tZXNzYWdlSGFuZGxlcik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGFkanVzdGVkTWVzc2FnZSA9IHRoaXMuYWRqdXN0TWVzc2FnZVRpbWVzdGFtcHMoZGF0YS5wYXlsb2FkIGFzIENoYXRNZXNzYWdlKTtcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZUhhbmRsZXIoYWRqdXN0ZWRNZXNzYWdlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoZGF0YS50eXBlID09PSAndGFrZW92ZXInKSB7XG4gICAgICAgICAgLy8gSGFuZGxlIHRha2VvdmVyIGV2ZW50XG4gICAgICAgICAgY29uc29sZS5sb2coJ1Rha2VvdmVyIGV2ZW50IHJlY2VpdmVkJyk7XG4gICAgICAgICAgXG4gICAgICAgICAgLy8gQ3JlYXRlIHNwZWNpYWwgbWVzc2FnZSBmb3IgdGhlIHRha2VvdmVyIGluZGljYXRvclxuICAgICAgICAgIGlmICh0aGlzLm1lc3NhZ2VIYW5kbGVyKSB7XG4gICAgICAgICAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpIC8gMTAwMDtcbiAgICAgICAgICAgIGNvbnN0IHRha2VvdmVyTWVzc2FnZTogQ2hhdE1lc3NhZ2UgPSB7XG4gICAgICAgICAgICAgIGNyZWF0ZV90aW1lOiBub3csXG4gICAgICAgICAgICAgIHN0YXJ0X3RpbWU6IHRoaXMuY29udmVyc2F0aW9uQ3JlYXRlVGltZSA/IG5vdyAtIHRoaXMuY29udmVyc2F0aW9uQ3JlYXRlVGltZSA6IDAsXG4gICAgICAgICAgICAgIGVuZF90aW1lOiB0aGlzLmNvbnZlcnNhdGlvbkNyZWF0ZVRpbWUgPyAobm93IC0gdGhpcy5jb252ZXJzYXRpb25DcmVhdGVUaW1lKSArIDAuMDEgOiAwLjAxLFxuICAgICAgICAgICAgICBzcGVha2VyOiAnc3BlY2lhbCcsXG4gICAgICAgICAgICAgIHRleHQ6ICdTdXBlcnZpc29yIHRvb2sgb3ZlcidcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2VIYW5kbGVyKHRha2VvdmVyTWVzc2FnZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIFxuICAgICAgICAgIC8vIENhbGwgdGhlIHRha2VvdmVyIGhhbmRsZXIgaWYgcHJvdmlkZWRcbiAgICAgICAgICBpZiAodGhpcy50YWtlb3ZlckhhbmRsZXIpIHtcbiAgICAgICAgICAgIHRoaXMudGFrZW92ZXJIYW5kbGVyKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGRhdGEudHlwZSA9PT0gJ2ZpbmFsaXplJykge1xuICAgICAgICAgIC8vIEhhbmRsZSBmaW5hbGl6ZWQgZXZlbnRcbiAgICAgICAgICBjb25zb2xlLmxvZygnRmluYWxpemVkIGV2ZW50IHJlY2VpdmVkJyk7XG4gICAgICAgICAgXG4gICAgICAgICAgLy8gQ3JlYXRlIHNwZWNpYWwgbWVzc2FnZSBmb3IgdGhlIGZpbmFsaXplZCBpbmRpY2F0b3JcbiAgICAgICAgICBpZiAodGhpcy5tZXNzYWdlSGFuZGxlcikge1xuICAgICAgICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKSAvIDEwMDA7XG4gICAgICAgICAgICBjb25zdCBmaW5hbGl6ZWRNZXNzYWdlOiBDaGF0TWVzc2FnZSA9IHtcbiAgICAgICAgICAgICAgY3JlYXRlX3RpbWU6IG5vdyxcbiAgICAgICAgICAgICAgc3RhcnRfdGltZTogdGhpcy5jb252ZXJzYXRpb25DcmVhdGVUaW1lID8gbm93IC0gdGhpcy5jb252ZXJzYXRpb25DcmVhdGVUaW1lIDogMCxcbiAgICAgICAgICAgICAgZW5kX3RpbWU6IHRoaXMuY29udmVyc2F0aW9uQ3JlYXRlVGltZSA/IChub3cgLSB0aGlzLmNvbnZlcnNhdGlvbkNyZWF0ZVRpbWUpICsgMC4wMSA6IDAuMDEsXG4gICAgICAgICAgICAgIHNwZWFrZXI6ICdzcGVjaWFsJyxcbiAgICAgICAgICAgICAgdGV4dDogJ0NvbnZlcnNhdGlvbiBGaW5hbGl6ZWQnXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdGhpcy5tZXNzYWdlSGFuZGxlcihmaW5hbGl6ZWRNZXNzYWdlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgXG4gICAgICAgICAgLy8gQ2FsbCB0aGUgZmluYWxpemVkIGhhbmRsZXIgaWYgcHJvdmlkZWRcbiAgICAgICAgICBpZiAodGhpcy5maW5hbGl6ZWRIYW5kbGVyKSB7XG4gICAgICAgICAgICB0aGlzLmZpbmFsaXplZEhhbmRsZXIoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5pc0ZpbmFsaXplZCA9IHRydWU7XG4gICAgICAgICAgdGhpcy5zYXZlQ29udmVyc2F0aW9uKCk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHBhcnNpbmcgV2ViU29ja2V0IG1lc3NhZ2U6JywgZXJyb3IpO1xuICAgICAgfVxuICAgIH07XG5cbiAgICB0aGlzLndlYlNvY2tldC5vbmVycm9yID0gKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgY29uc29sZS5lcnJvcignV2ViU29ja2V0IGVycm9yOicsIGVycm9yKTtcbiAgICAgIGlmICh0aGlzLmNvbm5lY3Rpb25TdGF0ZUhhbmRsZXIpIHRoaXMuY29ubmVjdGlvblN0YXRlSGFuZGxlcignZGlzY29ubmVjdGVkJyk7XG4gICAgfTtcblxuICAgIHRoaXMud2ViU29ja2V0Lm9uY2xvc2UgPSAoZXZlbnQ6IElDbG9zZUV2ZW50KSA9PiB7XG4gICAgICBjb25zb2xlLmxvZygnV2ViU29ja2V0IGNsb3NlZDonLCBldmVudC5jb2RlLCBldmVudC5yZWFzb24pO1xuICAgICAgaWYgKHRoaXMuY29ubmVjdGlvblN0YXRlSGFuZGxlcikgdGhpcy5jb25uZWN0aW9uU3RhdGVIYW5kbGVyKCdkaXNjb25uZWN0ZWQnKTtcbiAgICB9O1xuICB9XG5cbiAgZGlzY29ubmVjdCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy53ZWJTb2NrZXQpIHtcbiAgICAgIHRoaXMud2ViU29ja2V0LmNsb3NlKCk7XG4gICAgICB0aGlzLndlYlNvY2tldCA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgLy8gSGVscGVyIG1ldGhvZCB0byBhZGp1c3QgbWVzc2FnZSB0aW1lc3RhbXBzIHJlbGF0aXZlIHRvIGNvbnZlcnNhdGlvbiBzdGFydFxuICBwcml2YXRlIGFkanVzdE1lc3NhZ2VUaW1lc3RhbXBzKG1lc3NhZ2U6IENoYXRNZXNzYWdlKTogQ2hhdE1lc3NhZ2Uge1xuICAgIGlmICghdGhpcy5jb252ZXJzYXRpb25DcmVhdGVUaW1lKSB7XG4gICAgICByZXR1cm4gbWVzc2FnZTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4ubWVzc2FnZSxcbiAgICAgIHN0YXJ0X3RpbWU6IG1lc3NhZ2Uuc3RhcnRfdGltZSAtIHRoaXMuY29udmVyc2F0aW9uQ3JlYXRlVGltZSxcbiAgICAgIGVuZF90aW1lOiBtZXNzYWdlLmVuZF90aW1lIC0gdGhpcy5jb252ZXJzYXRpb25DcmVhdGVUaW1lXG4gICAgfTtcbiAgfVxufSAiXX0=
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export interface ChatMessage {
|
|
2
|
+
create_time: number;
|
|
3
|
+
start_time: number;
|
|
4
|
+
end_time: number;
|
|
5
|
+
speaker: 'customer' | 'agent' | 'special';
|
|
6
|
+
text: string;
|
|
7
|
+
}
|
|
8
|
+
export interface StartConversationResponse {
|
|
9
|
+
message: string;
|
|
10
|
+
conversation_id: string;
|
|
11
|
+
agent_welcome_message?: string;
|
|
12
|
+
agent_possible_queries?: string[];
|
|
13
|
+
create_time?: number;
|
|
14
|
+
}
|
|
15
|
+
export interface GenAgentChatProps {
|
|
16
|
+
baseUrl: string;
|
|
17
|
+
apiKey: string;
|
|
18
|
+
metadata?: Record<string, any>;
|
|
19
|
+
onError?: (error: Error) => void;
|
|
20
|
+
onTakeover?: () => void;
|
|
21
|
+
onFinalize?: () => void;
|
|
22
|
+
theme?: {
|
|
23
|
+
primaryColor?: string;
|
|
24
|
+
secondaryColor?: string;
|
|
25
|
+
fontFamily?: string;
|
|
26
|
+
fontSize?: string;
|
|
27
|
+
backgroundColor?: string;
|
|
28
|
+
textColor?: string;
|
|
29
|
+
};
|
|
30
|
+
headerTitle?: string;
|
|
31
|
+
placeholder?: string;
|
|
32
|
+
mode?: 'embedded' | 'floating';
|
|
33
|
+
floatingConfig?: {
|
|
34
|
+
position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
|
|
35
|
+
offset?: {
|
|
36
|
+
x?: number;
|
|
37
|
+
y?: number;
|
|
38
|
+
};
|
|
39
|
+
toggleButtonIcon?: React.ReactElement;
|
|
40
|
+
closeButtonIcon?: React.ReactElement;
|
|
41
|
+
};
|
|
42
|
+
}
|