aril 1.1.75 → 1.1.76

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.
@@ -1,140 +0,0 @@
1
- import { Component } from '@angular/core';
2
- import { FormsModule } from '@angular/forms';
3
- import { ButtonModule } from 'primeng/button';
4
- import { IconFieldModule } from 'primeng/iconfield';
5
- import { InputIconModule } from 'primeng/inputicon';
6
- import { InputTextModule } from 'primeng/inputtext';
7
- import { MessagesModule } from 'primeng/messages';
8
- import { RadioButtonModule } from 'primeng/radiobutton';
9
- import { RatingModule } from 'primeng/rating';
10
- import { SidebarModule } from 'primeng/sidebar';
11
- import { BehaviorSubject, firstValueFrom } from 'rxjs';
12
- import { API_CONFIGS } from 'aril/boot/config/api';
13
- import { ButtonComponent } from 'aril/ui/button';
14
- import { TextAreaComponent } from 'aril/ui/textArea';
15
- import * as i0 from "@angular/core";
16
- import * as i1 from "@angular/common/http";
17
- import * as i2 from "keycloak-angular";
18
- import * as i3 from "primeng/api";
19
- import * as i4 from "primeng/sidebar";
20
- import * as i5 from "@angular/forms";
21
- import * as i6 from "primeng/inputtext";
22
- import * as i7 from "primeng/messages";
23
- import * as i8 from "primeng/rating";
24
- export class AppChatbotComponent {
25
- constructor(http, keycloak) {
26
- this.http = http;
27
- this.keycloak = keycloak;
28
- this.chatbotVisible = false;
29
- this.queryList = new BehaviorSubject([]);
30
- this.historyList = new BehaviorSubject([]);
31
- this.isTyping = false;
32
- this.typingText = '.';
33
- this.visibleGiveFeedback = false;
34
- this.feedbackComments = '';
35
- this.feedbackRating = 0;
36
- this.baseUrl = API_CONFIGS.aiApi;
37
- this.username = this.keycloak.getUsername();
38
- }
39
- sendRequest() {
40
- this.fetchData();
41
- }
42
- async getHistory() {
43
- try {
44
- await this.http
45
- .get(this.baseUrl + 'history?project=CRM' + '&user_name=' + this.username)
46
- .subscribe((response) => {
47
- this.historyList.next(response);
48
- });
49
- }
50
- catch (error) {
51
- console.log(error);
52
- }
53
- }
54
- async fetchData() {
55
- this.startTyping();
56
- const request = {
57
- project: 'CRM',
58
- user_name: this.username,
59
- query: this.questionQuery
60
- };
61
- try {
62
- const result = await firstValueFrom(this.http.post(this.baseUrl + 'chat', request));
63
- if (result && result.answer) {
64
- this.queryList.next([...this.queryList.value, { question: this.questionQuery, answer: result.answer }]);
65
- }
66
- }
67
- catch (error) {
68
- this.error = error;
69
- }
70
- finally {
71
- this.questionQuery = '';
72
- this.stopTyping();
73
- }
74
- }
75
- onVisible() {
76
- this.getHistory();
77
- this.chatbotVisible = true;
78
- }
79
- startTyping() {
80
- this.isTyping = true;
81
- let dots = 0;
82
- this.typingInterval = setInterval(() => {
83
- dots = (dots + 1) % 4;
84
- this.typingText = '.'.repeat(dots);
85
- }, 300);
86
- }
87
- stopTyping() {
88
- clearInterval(this.typingInterval);
89
- this.isTyping = false;
90
- }
91
- giveFeedback() {
92
- this.visibleGiveFeedback = true;
93
- }
94
- async sendFeedback() {
95
- const request = {
96
- project: 'CRM',
97
- user_name: this.username,
98
- rating: this.feedbackRating,
99
- comments: this.feedbackComments
100
- };
101
- try {
102
- const result = await firstValueFrom(this.http.post(this.baseUrl + 'feedback', request));
103
- if (result) {
104
- this.feedBackResult = result.message;
105
- }
106
- }
107
- catch (error) {
108
- this.error = error;
109
- }
110
- finally {
111
- this.visibleGiveFeedback = false;
112
- this.feedbackComments = '';
113
- this.feedbackRating = 0;
114
- }
115
- }
116
- cancelFeedback() {
117
- this.visibleGiveFeedback = false;
118
- this.feedbackComments = '';
119
- this.feedbackRating = 0;
120
- }
121
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: AppChatbotComponent, deps: [{ token: i1.HttpClient }, { token: i2.KeycloakService }], target: i0.ɵɵFactoryTarget.Component }); }
122
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.1.2", type: AppChatbotComponent, isStandalone: true, selector: "app-chatbot", ngImport: i0, template: "<button class=\"layout-config-button p-link\" type=\"button\" (click)=\"chatbotVisible=true\">\r\n\t<i class=\"pi pi-comments\"></i>\r\n</button>\r\n\r\n<p-sidebar\r\n\t[(visible)]=\"chatbotVisible\"\r\n\tposition=\"right\"\r\n\tstyleClass=\"w-30rem flex flex-column\"\r\n\t[style]=\"{ height: '100%' }\">\r\n\t<ng-template pTemplate=\"header\">\r\n\t\t<div class=\"custom-sidebar-header\">\r\n\t\t\t<span class=\"header-title\">THOR Asistan</span>\r\n\t\t\t<i class=\"pi pi-thumbs-up custom-icon\" (click)=\"giveFeedback()\" (keypress)=\"giveFeedback()\"></i>\r\n\t\t</div>\r\n\t</ng-template>\r\n\r\n\t<div class=\"flex flex-column flex-1\">\r\n\t\t<p-messages severity=\"info\">\r\n\t\t\t<ng-template pTemplate>\r\n\t\t\t\t<i class=\"pi pi-info-circle text-xl\"></i>\r\n\t\t\t\t<div class=\"ml-2\">Sorular\u0131n\u0131n cevab\u0131na buradan ula\u015Fabilirsin.</div>\r\n\t\t\t</ng-template>\r\n\t\t</p-messages>\r\n\t</div>\r\n\r\n\t<div class=\"flex flex-column flex-1 query-details\" style=\"height: 85%; position: relative\">\r\n\t\t<div class=\"query-history\" style=\"flex: 1; max-height: 85%; overflow-y: auto; padding-right: 0.5rem\">\r\n\t\t\t@if (historyList.getValue().length > 0) {\r\n\t\t\t\t@for (historyItem of historyList.getValue(); track $index) {\r\n\t\t\t\t\t<div class=\"flex flex-column mb-2\">\r\n\t\t\t\t\t\t<div class=\"card shadow-none flex-1 flex align-items-center\" style=\"background-color: #e2e4e5\">\r\n\t\t\t\t\t\t\t<i class=\"pi pi-user text-xl\"></i>\r\n\t\t\t\t\t\t\t<div class=\"ml-4\">{{ historyItem.query }}</div>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t\t<div class=\"flex flex-column mb-2\">\r\n\t\t\t\t\t\t<div class=\"card shadow-none flex-1 flex align-items-center ml-5\">\r\n\t\t\t\t\t\t\t<i class=\"pi pi-comment text-xl\"></i>\r\n\t\t\t\t\t\t\t<div class=\"ml-4\">{{ historyItem.answer }}</div>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t@if (queryList.getValue().length > 0) {\r\n\t\t\t\t@for (item of queryList.getValue(); track $index) {\r\n\t\t\t\t\t<div class=\"flex flex-column mb-2\">\r\n\t\t\t\t\t\t<div class=\"card shadow-none flex-1 flex align-items-center\" style=\"background-color: #e2e4e5\">\r\n\t\t\t\t\t\t\t<i class=\"pi pi-user text-xl\"></i>\r\n\t\t\t\t\t\t\t<div class=\"ml-4 text-lg\">{{ item.question }}</div>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t\t<div class=\"flex flex-column\">\r\n\t\t\t\t\t\t<div class=\"card shadow-none flex-1 flex align-items-center ml-5\">\r\n\t\t\t\t\t\t\t<i class=\"pi pi-comment text-xl\"></i>\r\n\t\t\t\t\t\t\t<div class=\"ml-4 text-lg\">{{ item.answer }}</div>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t@if (visibleGiveFeedback) {\r\n\t\t\t\t<div class=\"flex mb-2\">\r\n\t\t\t\t\t<div class=\"card custom-card\" style=\"background-color: #e2e4e5\">\r\n\t\t\t\t\t\t<div>\r\n\t\t\t\t\t\t\t<span>Geri bildirimlerinizi buradan g\u00F6nderebilirsiniz.</span>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t<div>\r\n\t\t\t\t\t\t\t<p-rating [(ngModel)]=\"feedbackRating\" [stars]=\"5\" />\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t<div class=\"text-lg\">\r\n\t\t\t\t\t\t\t<aril-text-area [rows]=\"5\" [cols]=\"30\" pTextarea [(ngModel)]=\"feedbackComments\"></aril-text-area>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t<div>\r\n <aril-button label=\"G\u00F6nder\" color=\"danger\" icon=\"SEND\" [outlined]=\"true\" (clickEvent)=\"sendFeedback()\">\r\n </aril-button>\r\n\t\t\t\t\t\t\t<aril-button label=\"Vazge\u00E7\" color=\"danger\" icon=\"TIMES\" [outlined]=\"true\" (clickEvent)=\"cancelFeedback()\">\r\n </aril-button>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\t\t\t}\r\n\t\t</div>\r\n\r\n\t\t@if (isTyping) {\r\n\t\t\t<div\r\n\t\t\t\tclass=\"typing-indicator\"\r\n\t\t\t\tstyle=\"font-size: 16px; font-weight: 900; padding: 6px; width: 10%; text-align: center\">\r\n\t\t\t\t{{ typingText }}\r\n\t\t\t</div>\r\n\t\t}\r\n\r\n\t\t<div class=\"search-container\" style=\"position: absolute; bottom: 0; width: 100%; background: white\">\r\n\t\t\t<div class=\"search-box\" style=\"display: flex; align-items: center; gap: 0.5rem\">\r\n\t\t\t\t\t<input\r\n\t\t\t\t\t\tstyle=\"flex: 1; width: 100%\"\r\n\t\t\t\t\t\ttype=\"text\"\r\n\t\t\t\t\t\tpInputText\r\n\t\t\t\t\t\tplaceholder=\"Sorunu yaz...\"\r\n\t\t\t\t\t\t[(ngModel)]=\"questionQuery\"\r\n\t\t\t\t\t\tclass=\"flex-1\"\r\n\t\t\t\t\t\tmaxlength=\"500\" />\r\n\t\t\t\t<aril-button label=\"G\u00F6nder\" color=\"danger\" icon=\"SEND\" [outlined]=\"true\" (clickEvent)=\"sendRequest()\">\r\n\t\t\t\t</aril-button>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t</div>\r\n</p-sidebar>\r\n", styles: ["@charset \"UTF-8\";::ng-deep .p-sidebar .p-sidebar-header{background-color:var(--primary-color)!important;color:#fff!important}::ng-deep .p-sidebar .p-sidebar-close i{color:#fff!important}.custom-sidebar-header{display:flex;align-items:center;justify-content:space-between;padding:.5rem}.header-title{font-size:16px;font-weight:700}.custom-icon{font-size:1.5rem;color:#fff;cursor:pointer;margin-left:1rem}.custom-card{display:flex;flex-direction:column;gap:.5rem}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: SidebarModule }, { kind: "component", type: i4.Sidebar, selector: "p-sidebar", inputs: ["appendTo", "blockScroll", "style", "styleClass", "ariaCloseLabel", "autoZIndex", "baseZIndex", "modal", "dismissible", "showCloseIcon", "closeOnEscape", "transitionOptions", "visible", "position", "fullScreen"], outputs: ["onShow", "onHide", "visibleChange"] }, { kind: "ngmodule", type: RadioButtonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: InputIconModule }, { kind: "ngmodule", type: IconFieldModule }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i6.InputText, selector: "[pInputText]", inputs: ["variant"] }, { kind: "ngmodule", type: MessagesModule }, { kind: "component", type: i7.Messages, selector: "p-messages", inputs: ["value", "closable", "style", "styleClass", "enableService", "key", "escape", "severity", "showTransitionOptions", "hideTransitionOptions"], outputs: ["valueChange", "onClose"] }, { kind: "component", type: TextAreaComponent, selector: "aril-text-area[ngModel], aril-text-area[formControl], aril-text-area[formControlName]", inputs: ["rows", "cols", "isAutoResize", "tabindex", "placeholder"] }, { kind: "ngmodule", type: RatingModule }, { kind: "component", type: i8.Rating, selector: "p-rating", inputs: ["disabled", "readonly", "stars", "cancel", "iconOnClass", "iconOnStyle", "iconOffClass", "iconOffStyle", "iconCancelClass", "iconCancelStyle", "autofocus"], outputs: ["onRate", "onCancel", "onFocus", "onBlur"] }, { kind: "component", type: ButtonComponent, selector: "aril-button:not([click])", inputs: ["label", "loading", "disabled", "raised", "rounded", "text", "outlined", "badge", "size", "icon", "iconPos", "color"], outputs: ["clickEvent"] }] }); }
123
- }
124
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: AppChatbotComponent, decorators: [{
125
- type: Component,
126
- args: [{ standalone: true, selector: 'app-chatbot', imports: [
127
- ButtonModule,
128
- SidebarModule,
129
- RadioButtonModule,
130
- FormsModule,
131
- InputIconModule,
132
- IconFieldModule,
133
- InputTextModule,
134
- MessagesModule,
135
- TextAreaComponent,
136
- RatingModule,
137
- ButtonComponent
138
- ], template: "<button class=\"layout-config-button p-link\" type=\"button\" (click)=\"chatbotVisible=true\">\r\n\t<i class=\"pi pi-comments\"></i>\r\n</button>\r\n\r\n<p-sidebar\r\n\t[(visible)]=\"chatbotVisible\"\r\n\tposition=\"right\"\r\n\tstyleClass=\"w-30rem flex flex-column\"\r\n\t[style]=\"{ height: '100%' }\">\r\n\t<ng-template pTemplate=\"header\">\r\n\t\t<div class=\"custom-sidebar-header\">\r\n\t\t\t<span class=\"header-title\">THOR Asistan</span>\r\n\t\t\t<i class=\"pi pi-thumbs-up custom-icon\" (click)=\"giveFeedback()\" (keypress)=\"giveFeedback()\"></i>\r\n\t\t</div>\r\n\t</ng-template>\r\n\r\n\t<div class=\"flex flex-column flex-1\">\r\n\t\t<p-messages severity=\"info\">\r\n\t\t\t<ng-template pTemplate>\r\n\t\t\t\t<i class=\"pi pi-info-circle text-xl\"></i>\r\n\t\t\t\t<div class=\"ml-2\">Sorular\u0131n\u0131n cevab\u0131na buradan ula\u015Fabilirsin.</div>\r\n\t\t\t</ng-template>\r\n\t\t</p-messages>\r\n\t</div>\r\n\r\n\t<div class=\"flex flex-column flex-1 query-details\" style=\"height: 85%; position: relative\">\r\n\t\t<div class=\"query-history\" style=\"flex: 1; max-height: 85%; overflow-y: auto; padding-right: 0.5rem\">\r\n\t\t\t@if (historyList.getValue().length > 0) {\r\n\t\t\t\t@for (historyItem of historyList.getValue(); track $index) {\r\n\t\t\t\t\t<div class=\"flex flex-column mb-2\">\r\n\t\t\t\t\t\t<div class=\"card shadow-none flex-1 flex align-items-center\" style=\"background-color: #e2e4e5\">\r\n\t\t\t\t\t\t\t<i class=\"pi pi-user text-xl\"></i>\r\n\t\t\t\t\t\t\t<div class=\"ml-4\">{{ historyItem.query }}</div>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t\t<div class=\"flex flex-column mb-2\">\r\n\t\t\t\t\t\t<div class=\"card shadow-none flex-1 flex align-items-center ml-5\">\r\n\t\t\t\t\t\t\t<i class=\"pi pi-comment text-xl\"></i>\r\n\t\t\t\t\t\t\t<div class=\"ml-4\">{{ historyItem.answer }}</div>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t@if (queryList.getValue().length > 0) {\r\n\t\t\t\t@for (item of queryList.getValue(); track $index) {\r\n\t\t\t\t\t<div class=\"flex flex-column mb-2\">\r\n\t\t\t\t\t\t<div class=\"card shadow-none flex-1 flex align-items-center\" style=\"background-color: #e2e4e5\">\r\n\t\t\t\t\t\t\t<i class=\"pi pi-user text-xl\"></i>\r\n\t\t\t\t\t\t\t<div class=\"ml-4 text-lg\">{{ item.question }}</div>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t\t<div class=\"flex flex-column\">\r\n\t\t\t\t\t\t<div class=\"card shadow-none flex-1 flex align-items-center ml-5\">\r\n\t\t\t\t\t\t\t<i class=\"pi pi-comment text-xl\"></i>\r\n\t\t\t\t\t\t\t<div class=\"ml-4 text-lg\">{{ item.answer }}</div>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t@if (visibleGiveFeedback) {\r\n\t\t\t\t<div class=\"flex mb-2\">\r\n\t\t\t\t\t<div class=\"card custom-card\" style=\"background-color: #e2e4e5\">\r\n\t\t\t\t\t\t<div>\r\n\t\t\t\t\t\t\t<span>Geri bildirimlerinizi buradan g\u00F6nderebilirsiniz.</span>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t<div>\r\n\t\t\t\t\t\t\t<p-rating [(ngModel)]=\"feedbackRating\" [stars]=\"5\" />\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t<div class=\"text-lg\">\r\n\t\t\t\t\t\t\t<aril-text-area [rows]=\"5\" [cols]=\"30\" pTextarea [(ngModel)]=\"feedbackComments\"></aril-text-area>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t\t<div>\r\n <aril-button label=\"G\u00F6nder\" color=\"danger\" icon=\"SEND\" [outlined]=\"true\" (clickEvent)=\"sendFeedback()\">\r\n </aril-button>\r\n\t\t\t\t\t\t\t<aril-button label=\"Vazge\u00E7\" color=\"danger\" icon=\"TIMES\" [outlined]=\"true\" (clickEvent)=\"cancelFeedback()\">\r\n </aril-button>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\t\t\t}\r\n\t\t</div>\r\n\r\n\t\t@if (isTyping) {\r\n\t\t\t<div\r\n\t\t\t\tclass=\"typing-indicator\"\r\n\t\t\t\tstyle=\"font-size: 16px; font-weight: 900; padding: 6px; width: 10%; text-align: center\">\r\n\t\t\t\t{{ typingText }}\r\n\t\t\t</div>\r\n\t\t}\r\n\r\n\t\t<div class=\"search-container\" style=\"position: absolute; bottom: 0; width: 100%; background: white\">\r\n\t\t\t<div class=\"search-box\" style=\"display: flex; align-items: center; gap: 0.5rem\">\r\n\t\t\t\t\t<input\r\n\t\t\t\t\t\tstyle=\"flex: 1; width: 100%\"\r\n\t\t\t\t\t\ttype=\"text\"\r\n\t\t\t\t\t\tpInputText\r\n\t\t\t\t\t\tplaceholder=\"Sorunu yaz...\"\r\n\t\t\t\t\t\t[(ngModel)]=\"questionQuery\"\r\n\t\t\t\t\t\tclass=\"flex-1\"\r\n\t\t\t\t\t\tmaxlength=\"500\" />\r\n\t\t\t\t<aril-button label=\"G\u00F6nder\" color=\"danger\" icon=\"SEND\" [outlined]=\"true\" (clickEvent)=\"sendRequest()\">\r\n\t\t\t\t</aril-button>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t</div>\r\n</p-sidebar>\r\n", styles: ["@charset \"UTF-8\";::ng-deep .p-sidebar .p-sidebar-header{background-color:var(--primary-color)!important;color:#fff!important}::ng-deep .p-sidebar .p-sidebar-close i{color:#fff!important}.custom-sidebar-header{display:flex;align-items:center;justify-content:space-between;padding:.5rem}.header-title{font-size:16px;font-weight:700}.custom-icon{font-size:1.5rem;color:#fff;cursor:pointer;margin-left:1rem}.custom-card{display:flex;flex-direction:column;gap:.5rem}\n"] }]
139
- }], ctorParameters: () => [{ type: i1.HttpClient }, { type: i2.KeycloakService }] });
140
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLmNoYXRib3QuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYXJpbC90aGVtZS9sYXlvdXQvYXBwL2NoYXRib3QvYXBwLmNoYXRib3QuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYXJpbC90aGVtZS9sYXlvdXQvYXBwL2NoYXRib3QvYXBwLmNoYXRib3QuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMxQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFN0MsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDcEQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ3BELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDOUMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBR2hELE9BQU8sRUFBRSxlQUFlLEVBQUUsY0FBYyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXZELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNuRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDakQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sa0JBQWtCLENBQUM7Ozs7Ozs7Ozs7QUFxQnJELE1BQU0s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QixHQUFHLEtBQUssQ0FBQztRQUNqQyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsRUFBRSxDQUFDO1FBQzNCLElBQUksQ0FBQyxjQUFjLEdBQUcsQ0FBQyxDQUFDO0lBQ3pCLENBQUM7OEdBN0dXLG1CQUFtQjtrR0FBbkIsbUJBQW1CLHVFQ3hDaEMsdW1KQTRHQSwwZ0JEbkZFLFlBQVkscUlBQ1osYUFBYSw0V0FDYixpQkFBaUIsOEJBQ2pCLFdBQVcsaXhCQUNYLGVBQWUsOEJBQ2YsZUFBZSw4QkFDZixlQUFlLHdIQUNmLGNBQWMsNFJBQ2QsaUJBQWlCLHNNQUNqQixZQUFZLHlUQUNaLGVBQWU7OzJGQUtKLG1CQUFtQjtrQkFuQi9CLFNBQVM7aUNBQ0csSUFBSSxZQUNOLGFBQWEsV0FDZDt3QkFDUixZQUFZO3dCQUNaLGFBQWE7d0JBQ2IsaUJBQWlCO3dCQUNqQixXQUFXO3dCQUNYLGVBQWU7d0JBQ2YsZUFBZTt3QkFDZixlQUFlO3dCQUNmLGNBQWM7d0JBQ2QsaUJBQWlCO3dCQUNqQixZQUFZO3dCQUNaLGVBQWU7cUJBQ2YiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBAYW5ndWxhci1lc2xpbnQvY29tcG9uZW50LXNlbGVjdG9yICovXHJcbmltcG9ydCB7IEh0dHBDbGllbnQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XHJcbmltcG9ydCB7IENvbXBvbmVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuXHJcbmltcG9ydCB7IEJ1dHRvbk1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvYnV0dG9uJztcclxuaW1wb3J0IHsgSWNvbkZpZWxkTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9pY29uZmllbGQnO1xyXG5pbXBvcnQgeyBJbnB1dEljb25Nb2R1bGUgfSBmcm9tICdwcmltZW5nL2lucHV0aWNvbic7XHJcbmltcG9ydCB7IElucHV0VGV4dE1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvaW5wdXR0ZXh0JztcclxuaW1wb3J0IHsgTWVzc2FnZXNNb2R1bGUgfSBmcm9tICdwcmltZW5nL21lc3NhZ2VzJztcclxuaW1wb3J0IHsgUmFkaW9CdXR0b25Nb2R1bGUgfSBmcm9tICdwcmltZW5nL3JhZGlvYnV0dG9uJztcclxuaW1wb3J0IHsgUmF0aW5nTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9yYXRpbmcnO1xyXG5pbXBvcnQgeyBTaWRlYmFyTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9zaWRlYmFyJztcclxuXHJcbmltcG9ydCB7IEtleWNsb2FrU2VydmljZSB9IGZyb20gJ2tleWNsb2FrLWFuZ3VsYXInO1xyXG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIGZpcnN0VmFsdWVGcm9tIH0gZnJvbSAncnhqcyc7XHJcblxyXG5pbXBvcnQgeyBBUElfQ09ORklHUyB9IGZyb20gJ2FyaWwvYm9vdC9jb25maWcvYXBpJztcclxuaW1wb3J0IHsgQnV0dG9uQ29tcG9uZW50IH0gZnJvbSAnYXJpbC91aS9idXR0b24nO1xyXG5pbXBvcnQgeyBUZXh0QXJlYUNvbXBvbmVudCB9IGZyb20gJ2FyaWwvdWkvdGV4dEFyZWEnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcblx0c3RhbmRhbG9uZTogdHJ1ZSxcclxuXHRzZWxlY3RvcjogJ2FwcC1jaGF0Ym90JyxcclxuXHRpbXBvcnRzOiBbXHJcblx0XHRCdXR0b25Nb2R1bGUsXHJcblx0XHRTaWRlYmFyTW9kdWxlLFxyXG5cdFx0UmFkaW9CdXR0b25Nb2R1bGUsXHJcblx0XHRGb3Jtc01vZHVsZSxcclxuXHRcdElucHV0SWNvbk1vZHVsZSxcclxuXHRcdEljb25GaWVsZE1vZHVsZSxcclxuXHRcdElucHV0VGV4dE1vZHVsZSxcclxuXHRcdE1lc3NhZ2VzTW9kdWxlLFxyXG5cdFx0VGV4dEFyZWFDb21wb25lbnQsXHJcblx0XHRSYXRpbmdNb2R1bGUsXHJcblx0XHRCdXR0b25Db21wb25lbnRcclxuXHRdLFxyXG5cdHRlbXBsYXRlVXJsOiAnLi9hcHAuY2hhdGJvdC5jb21wb25lbnQuaHRtbCcsXHJcblx0c3R5bGVVcmw6ICcuL2FwcC5jaGF0Ym90LmNvbXBvbmVudC5zY3NzJ1xyXG59KVxyXG5leHBvcnQgY2xhc3MgQXBwQ2hhdGJvdENvbXBvbmVudCB7XHJcblx0Y2hhdGJvdFZpc2libGUgPSBmYWxzZTtcclxuXHRwcm9qZWN0TmFtZSE6IHN0cmluZztcclxuXHRxdWVzdGlvblF1ZXJ5ITogc3RyaW5nO1xyXG5cdHF1ZXJ5TGlzdDogQmVoYXZpb3JTdWJqZWN0PGFueVtdPiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8YW55W10+KFtdKTtcclxuXHRlcnJvciE6IHN0cmluZztcclxuXHRoaXN0b3J5TGlzdDogQmVoYXZpb3JTdWJqZWN0PGFueVtdPiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8YW55W10+KFtdKTtcclxuXHRpc1R5cGluZyA9IGZhbHNlO1xyXG5cdHR5cGluZ0ludGVydmFsOiBhbnk7XHJcblx0dHlwaW5nVGV4dCA9ICcuJztcclxuXHR1c2VybmFtZTogc3RyaW5nO1xyXG5cdHZpc2libGVHaXZlRmVlZGJhY2sgPSBmYWxzZTtcclxuXHRmZWVkYmFja0NvbW1lbnRzID0gJyc7XHJcblx0ZmVlZGJhY2tSYXRpbmcgPSAwO1xyXG5cdGZlZWRCYWNrUmVzdWx0ITogc3RyaW5nO1xyXG5cdGJhc2VVcmwgPSBBUElfQ09ORklHUy5haUFwaTtcclxuXHJcblx0Y29uc3RydWN0b3IoXHJcblx0XHRwcml2YXRlIHJlYWRvbmx5IGh0dHA6IEh0dHBDbGllbnQsXHJcblx0XHRwcml2YXRlIHJlYWRvbmx5IGtleWNsb2FrOiBLZXljbG9ha1NlcnZpY2VcclxuXHQpIHtcclxuXHRcdHRoaXMudXNlcm5hbWUgPSB0aGlzLmtleWNsb2FrLmdldFVzZXJuYW1lKCk7XHJcblx0fVxyXG5cclxuXHRzZW5kUmVxdWVzdCgpIHtcclxuXHRcdHRoaXMuZmV0Y2hEYXRhKCk7XHJcblx0fVxyXG5cclxuXHRhc3luYyBnZXRIaXN0b3J5KCkge1xyXG5cdFx0dHJ5IHtcclxuXHRcdFx0YXdhaXQgdGhpcy5odHRwXHJcblx0XHRcdFx0LmdldDxhbnlbXT4odGhpcy5iYXNlVXJsICsgJ2hpc3Rvcnk/cHJvamVjdD1DUk0nICsgJyZ1c2VyX25hbWU9JyArIHRoaXMudXNlcm5hbWUpXHJcblx0XHRcdFx0LnN1YnNjcmliZSgocmVzcG9uc2UpID0+IHtcclxuXHRcdFx0XHRcdHRoaXMuaGlzdG9yeUxpc3QubmV4dChyZXNwb25zZSk7XHJcblx0XHRcdFx0fSk7XHJcblx0XHR9IGNhdGNoIChlcnJvcikge1xyXG5cdFx0XHRjb25zb2xlLmxvZyhlcnJvcik7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRhc3luYyBmZXRjaERhdGEoKSB7XHJcblx0XHR0aGlzLnN0YXJ0VHlwaW5nKCk7XHJcblx0XHRjb25zdCByZXF1ZXN0ID0ge1xyXG5cdFx0XHRwcm9qZWN0OiAnQ1JNJyxcclxuXHRcdFx0dXNlcl9uYW1lOiB0aGlzLnVzZXJuYW1lLFxyXG5cdFx0XHRxdWVyeTogdGhpcy5xdWVzdGlvblF1ZXJ5XHJcblx0XHR9O1xyXG5cclxuXHRcdHRyeSB7XHJcblx0XHRcdGNvbnN0IHJlc3VsdCA9IGF3YWl0IGZpcnN0VmFsdWVGcm9tKHRoaXMuaHR0cC5wb3N0PGFueT4odGhpcy5iYXNlVXJsICsgJ2NoYXQnLCByZXF1ZXN0KSk7XHJcblx0XHRcdGlmIChyZXN1bHQgJiYgcmVzdWx0LmFuc3dlcikge1xyXG5cdFx0XHRcdHRoaXMucXVlcnlMaXN0Lm5leHQoWy4uLnRoaXMucXVlcnlMaXN0LnZhbHVlLCB7IHF1ZXN0aW9uOiB0aGlzLnF1ZXN0aW9uUXVlcnksIGFuc3dlcjogcmVzdWx0LmFuc3dlciB9XSk7XHJcblx0XHRcdH1cclxuXHRcdH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcclxuXHRcdFx0dGhpcy5lcnJvciA9IGVycm9yO1xyXG5cdFx0fSBmaW5hbGx5IHtcclxuXHRcdFx0dGhpcy5xdWVzdGlvblF1ZXJ5ID0gJyc7XHJcblx0XHRcdHRoaXMuc3RvcFR5cGluZygpO1xyXG5cdFx0fVxyXG5cdH1cclxuXHRvblZpc2libGUoKSB7XHJcblx0XHR0aGlzLmdldEhpc3RvcnkoKTtcclxuXHRcdHRoaXMuY2hhdGJvdFZpc2libGUgPSB0cnVlO1xyXG5cdH1cclxuXHJcblx0c3RhcnRUeXBpbmcoKSB7XHJcblx0XHR0aGlzLmlzVHlwaW5nID0gdHJ1ZTtcclxuXHRcdGxldCBkb3RzID0gMDtcclxuXHJcblx0XHR0aGlzLnR5cGluZ0ludGVydmFsID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xyXG5cdFx0XHRkb3RzID0gKGRvdHMgKyAxKSAlIDQ7XHJcblx0XHRcdHRoaXMudHlwaW5nVGV4dCA9ICcuJy5yZXBlYXQoZG90cyk7XHJcblx0XHR9LCAzMDApO1xyXG5cdH1cclxuXHJcblx0c3RvcFR5cGluZygpIHtcclxuXHRcdGNsZWFySW50ZXJ2YWwodGhpcy50eXBpbmdJbnRlcnZhbCk7XHJcblx0XHR0aGlzLmlzVHlwaW5nID0gZmFsc2U7XHJcblx0fVxyXG5cclxuXHRnaXZlRmVlZGJhY2soKSB7XHJcblx0XHR0aGlzLnZpc2libGVHaXZlRmVlZGJhY2sgPSB0cnVlO1xyXG5cdH1cclxuXHRhc3luYyBzZW5kRmVlZGJhY2soKSB7XHJcblx0XHRjb25zdCByZXF1ZXN0ID0ge1xyXG5cdFx0XHRwcm9qZWN0OiAnQ1JNJyxcclxuXHRcdFx0dXNlcl9uYW1lOiB0aGlzLnVzZXJuYW1lLFxyXG5cdFx0XHRyYXRpbmc6IHRoaXMuZmVlZGJhY2tSYXRpbmcsXHJcblx0XHRcdGNvbW1lbnRzOiB0aGlzLmZlZWRiYWNrQ29tbWVudHNcclxuXHRcdH07XHJcblxyXG5cdFx0dHJ5IHtcclxuXHRcdFx0Y29uc3QgcmVzdWx0ID0gYXdhaXQgZmlyc3RWYWx1ZUZyb20odGhpcy5odHRwLnBvc3Q8YW55Pih0aGlzLmJhc2VVcmwgKyAnZmVlZGJhY2snLCByZXF1ZXN0KSk7XHJcblx0XHRcdGlmIChyZXN1bHQpIHtcclxuXHRcdFx0XHR0aGlzLmZlZWRCYWNrUmVzdWx0ID0gcmVzdWx0Lm1lc3NhZ2U7XHJcblx0XHRcdH1cclxuXHRcdH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcclxuXHRcdFx0dGhpcy5lcnJvciA9IGVycm9yO1xyXG5cdFx0fSBmaW5hbGx5IHtcclxuXHRcdFx0dGhpcy52aXNpYmxlR2l2ZUZlZWRiYWNrID0gZmFsc2U7XHJcblx0XHRcdHRoaXMuZmVlZGJhY2tDb21tZW50cyA9ICcnO1xyXG5cdFx0XHR0aGlzLmZlZWRiYWNrUmF0aW5nID0gMDtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdGNhbmNlbEZlZWRiYWNrKCkge1xyXG5cdFx0dGhpcy52aXNpYmxlR2l2ZUZlZWRiYWNrID0gZmFsc2U7XHJcblx0XHR0aGlzLmZlZWRiYWNrQ29tbWVudHMgPSAnJztcclxuXHRcdHRoaXMuZmVlZGJhY2tSYXRpbmcgPSAwO1xyXG5cdH1cclxufVxyXG4iLCI8YnV0dG9uIGNsYXNzPVwibGF5b3V0LWNvbmZpZy1idXR0b24gcC1saW5rXCIgdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJjaGF0Ym90VmlzaWJsZT10cnVlXCI+XHJcblx0PGkgY2xhc3M9XCJwaSBwaS1jb21tZW50c1wiPjwvaT5cclxuPC9idXR0b24+XHJcblxyXG48cC1zaWRlYmFyXHJcblx0Wyh2aXNpYmxlKV09XCJjaGF0Ym90VmlzaWJsZVwiXHJcblx0cG9zaXRpb249XCJyaWdodFwiXHJcblx0c3R5bGVDbGFzcz1cInctMzByZW0gZmxleCBmbGV4LWNvbHVtblwiXHJcblx0W3N0eWxlXT1cInsgaGVpZ2h0OiAnMTAwJScgfVwiPlxyXG5cdDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJoZWFkZXJcIj5cclxuXHRcdDxkaXYgY2xhc3M9XCJjdXN0b20tc2lkZWJhci1oZWFkZXJcIj5cclxuXHRcdFx0PHNwYW4gY2xhc3M9XCJoZWFkZXItdGl0bGVcIj5USE9SIEFzaXN0YW48L3NwYW4+XHJcblx0XHRcdDxpIGNsYXNzPVwicGkgcGktdGh1bWJzLXVwIGN1c3RvbS1pY29uXCIgKGNsaWNrKT1cImdpdmVGZWVkYmFjaygpXCIgKGtleXByZXNzKT1cImdpdmVGZWVkYmFjaygpXCI+PC9pPlxyXG5cdFx0PC9kaXY+XHJcblx0PC9uZy10ZW1wbGF0ZT5cclxuXHJcblx0PGRpdiBjbGFzcz1cImZsZXggZmxleC1jb2x1bW4gZmxleC0xXCI+XHJcblx0XHQ8cC1tZXNzYWdlcyBzZXZlcml0eT1cImluZm9cIj5cclxuXHRcdFx0PG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT5cclxuXHRcdFx0XHQ8aSBjbGFzcz1cInBpIHBpLWluZm8tY2lyY2xlIHRleHQteGxcIj48L2k+XHJcblx0XHRcdFx0PGRpdiBjbGFzcz1cIm1sLTJcIj5Tb3J1bGFyxLFuxLFuIGNldmFixLFuYSBidXJhZGFuIHVsYcWfYWJpbGlyc2luLjwvZGl2PlxyXG5cdFx0XHQ8L25nLXRlbXBsYXRlPlxyXG5cdFx0PC9wLW1lc3NhZ2VzPlxyXG5cdDwvZGl2PlxyXG5cclxuXHQ8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbHVtbiBmbGV4LTEgcXVlcnktZGV0YWlsc1wiIHN0eWxlPVwiaGVpZ2h0OiA4NSU7IHBvc2l0aW9uOiByZWxhdGl2ZVwiPlxyXG5cdFx0PGRpdiBjbGFzcz1cInF1ZXJ5LWhpc3RvcnlcIiBzdHlsZT1cImZsZXg6IDE7IG1heC1oZWlnaHQ6IDg1JTsgb3ZlcmZsb3cteTogYXV0bzsgcGFkZGluZy1yaWdodDogMC41cmVtXCI+XHJcblx0XHRcdEBpZiAoaGlzdG9yeUxpc3QuZ2V0VmFsdWUoKS5sZW5ndGggPiAwKSB7XHJcblx0XHRcdFx0QGZvciAoaGlzdG9yeUl0ZW0gb2YgaGlzdG9yeUxpc3QuZ2V0VmFsdWUoKTsgdHJhY2sgJGluZGV4KSB7XHJcblx0XHRcdFx0XHQ8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbHVtbiBtYi0yXCI+XHJcblx0XHRcdFx0XHRcdDxkaXYgY2xhc3M9XCJjYXJkIHNoYWRvdy1ub25lIGZsZXgtMSBmbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiIHN0eWxlPVwiYmFja2dyb3VuZC1jb2xvcjogI2UyZTRlNVwiPlxyXG5cdFx0XHRcdFx0XHRcdDxpIGNsYXNzPVwicGkgcGktdXNlciB0ZXh0LXhsXCI+PC9pPlxyXG5cdFx0XHRcdFx0XHRcdDxkaXYgY2xhc3M9XCJtbC00XCI+e3sgaGlzdG9yeUl0ZW0ucXVlcnkgfX08L2Rpdj5cclxuXHRcdFx0XHRcdFx0PC9kaXY+XHJcblx0XHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0XHRcdDxkaXYgY2xhc3M9XCJmbGV4IGZsZXgtY29sdW1uIG1iLTJcIj5cclxuXHRcdFx0XHRcdFx0PGRpdiBjbGFzcz1cImNhcmQgc2hhZG93LW5vbmUgZmxleC0xIGZsZXggYWxpZ24taXRlbXMtY2VudGVyIG1sLTVcIj5cclxuXHRcdFx0XHRcdFx0XHQ8aSBjbGFzcz1cInBpIHBpLWNvbW1lbnQgdGV4dC14bFwiPjwvaT5cclxuXHRcdFx0XHRcdFx0XHQ8ZGl2IGNsYXNzPVwibWwtNFwiPnt7IGhpc3RvcnlJdGVtLmFuc3dlciB9fTwvZGl2PlxyXG5cdFx0XHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0XHRcdDwvZGl2PlxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0QGlmIChxdWVyeUxpc3QuZ2V0VmFsdWUoKS5sZW5ndGggPiAwKSB7XHJcblx0XHRcdFx0QGZvciAoaXRlbSBvZiBxdWVyeUxpc3QuZ2V0VmFsdWUoKTsgdHJhY2sgJGluZGV4KSB7XHJcblx0XHRcdFx0XHQ8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbHVtbiBtYi0yXCI+XHJcblx0XHRcdFx0XHRcdDxkaXYgY2xhc3M9XCJjYXJkIHNoYWRvdy1ub25lIGZsZXgtMSBmbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiIHN0eWxlPVwiYmFja2dyb3VuZC1jb2xvcjogI2UyZTRlNVwiPlxyXG5cdFx0XHRcdFx0XHRcdDxpIGNsYXNzPVwicGkgcGktdXNlciB0ZXh0LXhsXCI+PC9pPlxyXG5cdFx0XHRcdFx0XHRcdDxkaXYgY2xhc3M9XCJtbC00IHRleHQtbGdcIj57eyBpdGVtLnF1ZXN0aW9uIH19PC9kaXY+XHJcblx0XHRcdFx0XHRcdDwvZGl2PlxyXG5cdFx0XHRcdFx0PC9kaXY+XHJcblx0XHRcdFx0XHQ8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbHVtblwiPlxyXG5cdFx0XHRcdFx0XHQ8ZGl2IGNsYXNzPVwiY2FyZCBzaGFkb3ctbm9uZSBmbGV4LTEgZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIgbWwtNVwiPlxyXG5cdFx0XHRcdFx0XHRcdDxpIGNsYXNzPVwicGkgcGktY29tbWVudCB0ZXh0LXhsXCI+PC9pPlxyXG5cdFx0XHRcdFx0XHRcdDxkaXYgY2xhc3M9XCJtbC00IHRleHQtbGdcIj57eyBpdGVtLmFuc3dlciB9fTwvZGl2PlxyXG5cdFx0XHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0XHRcdDwvZGl2PlxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0QGlmICh2aXNpYmxlR2l2ZUZlZWRiYWNrKSB7XHJcblx0XHRcdFx0PGRpdiBjbGFzcz1cImZsZXggbWItMlwiPlxyXG5cdFx0XHRcdFx0PGRpdiBjbGFzcz1cImNhcmQgY3VzdG9tLWNhcmRcIiBzdHlsZT1cImJhY2tncm91bmQtY29sb3I6ICNlMmU0ZTVcIj5cclxuXHRcdFx0XHRcdFx0PGRpdj5cclxuXHRcdFx0XHRcdFx0XHQ8c3Bhbj5HZXJpIGJpbGRpcmltbGVyaW5pemkgYnVyYWRhbiBnw7ZuZGVyZWJpbGlyc2luaXouPC9zcGFuPlxyXG5cdFx0XHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0XHRcdFx0PGRpdj5cclxuXHRcdFx0XHRcdFx0XHQ8cC1yYXRpbmcgWyhuZ01vZGVsKV09XCJmZWVkYmFja1JhdGluZ1wiIFtzdGFyc109XCI1XCIgLz5cclxuXHRcdFx0XHRcdFx0PC9kaXY+XHJcblx0XHRcdFx0XHRcdDxkaXYgY2xhc3M9XCJ0ZXh0LWxnXCI+XHJcblx0XHRcdFx0XHRcdFx0PGFyaWwtdGV4dC1hcmVhIFtyb3dzXT1cIjVcIiBbY29sc109XCIzMFwiIHBUZXh0YXJlYSBbKG5nTW9kZWwpXT1cImZlZWRiYWNrQ29tbWVudHNcIj48L2FyaWwtdGV4dC1hcmVhPlxyXG5cdFx0XHRcdFx0XHQ8L2Rpdj5cclxuXHRcdFx0XHRcdFx0PGRpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhcmlsLWJ1dHRvbiBsYWJlbD1cIkfDtm5kZXJcIiBjb2xvcj1cImRhbmdlclwiIGljb249XCJTRU5EXCIgW291dGxpbmVkXT1cInRydWVcIiAoY2xpY2tFdmVudCk9XCJzZW5kRmVlZGJhY2soKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9hcmlsLWJ1dHRvbj5cclxuXHRcdFx0XHRcdFx0XHQ8YXJpbC1idXR0b24gbGFiZWw9XCJWYXpnZcOnXCIgY29sb3I9XCJkYW5nZXJcIiBpY29uPVwiVElNRVNcIiBbb3V0bGluZWRdPVwidHJ1ZVwiIChjbGlja0V2ZW50KT1cImNhbmNlbEZlZWRiYWNrKClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYXJpbC1idXR0b24+XHJcblx0XHRcdFx0XHRcdDwvZGl2PlxyXG5cdFx0XHRcdFx0PC9kaXY+XHJcblx0XHRcdFx0PC9kaXY+XHJcblx0XHRcdH1cclxuXHRcdDwvZGl2PlxyXG5cclxuXHRcdEBpZiAoaXNUeXBpbmcpIHtcclxuXHRcdFx0PGRpdlxyXG5cdFx0XHRcdGNsYXNzPVwidHlwaW5nLWluZGljYXRvclwiXHJcblx0XHRcdFx0c3R5bGU9XCJmb250LXNpemU6IDE2cHg7IGZvbnQtd2VpZ2h0OiA5MDA7IHBhZGRpbmc6IDZweDsgd2lkdGg6IDEwJTsgdGV4dC1hbGlnbjogY2VudGVyXCI+XHJcblx0XHRcdFx0e3sgdHlwaW5nVGV4dCB9fVxyXG5cdFx0XHQ8L2Rpdj5cclxuXHRcdH1cclxuXHJcblx0XHQ8ZGl2IGNsYXNzPVwic2VhcmNoLWNvbnRhaW5lclwiIHN0eWxlPVwicG9zaXRpb246IGFic29sdXRlOyBib3R0b206IDA7IHdpZHRoOiAxMDAlOyBiYWNrZ3JvdW5kOiB3aGl0ZVwiPlxyXG5cdFx0XHQ8ZGl2IGNsYXNzPVwic2VhcmNoLWJveFwiIHN0eWxlPVwiZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiAwLjVyZW1cIj5cclxuXHRcdFx0XHRcdDxpbnB1dFxyXG5cdFx0XHRcdFx0XHRzdHlsZT1cImZsZXg6IDE7IHdpZHRoOiAxMDAlXCJcclxuXHRcdFx0XHRcdFx0dHlwZT1cInRleHRcIlxyXG5cdFx0XHRcdFx0XHRwSW5wdXRUZXh0XHJcblx0XHRcdFx0XHRcdHBsYWNlaG9sZGVyPVwiU29ydW51IHlhei4uLlwiXHJcblx0XHRcdFx0XHRcdFsobmdNb2RlbCldPVwicXVlc3Rpb25RdWVyeVwiXHJcblx0XHRcdFx0XHRcdGNsYXNzPVwiZmxleC0xXCJcclxuXHRcdFx0XHRcdFx0bWF4bGVuZ3RoPVwiNTAwXCIgLz5cclxuXHRcdFx0XHQ8YXJpbC1idXR0b24gbGFiZWw9XCJHw7ZuZGVyXCIgY29sb3I9XCJkYW5nZXJcIiBpY29uPVwiU0VORFwiIFtvdXRsaW5lZF09XCJ0cnVlXCIgKGNsaWNrRXZlbnQpPVwic2VuZFJlcXVlc3QoKVwiPlxyXG5cdFx0XHRcdDwvYXJpbC1idXR0b24+XHJcblx0XHRcdDwvZGl2PlxyXG5cdFx0PC9kaXY+XHJcblx0PC9kaXY+XHJcbjwvcC1zaWRlYmFyPlxyXG4iXX0=
@@ -1,35 +0,0 @@
1
- import { HttpClient } from '@angular/common/http';
2
- import { KeycloakService } from 'keycloak-angular';
3
- import { BehaviorSubject } from 'rxjs';
4
- import * as i0 from "@angular/core";
5
- export declare class AppChatbotComponent {
6
- private readonly http;
7
- private readonly keycloak;
8
- chatbotVisible: boolean;
9
- projectName: string;
10
- questionQuery: string;
11
- queryList: BehaviorSubject<any[]>;
12
- error: string;
13
- historyList: BehaviorSubject<any[]>;
14
- isTyping: boolean;
15
- typingInterval: any;
16
- typingText: string;
17
- username: string;
18
- visibleGiveFeedback: boolean;
19
- feedbackComments: string;
20
- feedbackRating: number;
21
- feedBackResult: string;
22
- baseUrl: string;
23
- constructor(http: HttpClient, keycloak: KeycloakService);
24
- sendRequest(): void;
25
- getHistory(): Promise<void>;
26
- fetchData(): Promise<void>;
27
- onVisible(): void;
28
- startTyping(): void;
29
- stopTyping(): void;
30
- giveFeedback(): void;
31
- sendFeedback(): Promise<void>;
32
- cancelFeedback(): void;
33
- static ɵfac: i0.ɵɵFactoryDeclaration<AppChatbotComponent, never>;
34
- static ɵcmp: i0.ɵɵComponentDeclaration<AppChatbotComponent, "app-chatbot", never, {}, {}, never, never, true, never>;
35
- }
@@ -1,108 +0,0 @@
1
- <button class="layout-config-button p-link" type="button" (click)="chatbotVisible=true">
2
- <i class="pi pi-comments"></i>
3
- </button>
4
-
5
- <p-sidebar
6
- [(visible)]="chatbotVisible"
7
- position="right"
8
- styleClass="w-30rem flex flex-column"
9
- [style]="{ height: '100%' }">
10
- <ng-template pTemplate="header">
11
- <div class="custom-sidebar-header">
12
- <span class="header-title">THOR Asistan</span>
13
- <i class="pi pi-thumbs-up custom-icon" (click)="giveFeedback()" (keypress)="giveFeedback()"></i>
14
- </div>
15
- </ng-template>
16
-
17
- <div class="flex flex-column flex-1">
18
- <p-messages severity="info">
19
- <ng-template pTemplate>
20
- <i class="pi pi-info-circle text-xl"></i>
21
- <div class="ml-2">Sorularının cevabına buradan ulaşabilirsin.</div>
22
- </ng-template>
23
- </p-messages>
24
- </div>
25
-
26
- <div class="flex flex-column flex-1 query-details" style="height: 85%; position: relative">
27
- <div class="query-history" style="flex: 1; max-height: 85%; overflow-y: auto; padding-right: 0.5rem">
28
- @if (historyList.getValue().length > 0) {
29
- @for (historyItem of historyList.getValue(); track $index) {
30
- <div class="flex flex-column mb-2">
31
- <div class="card shadow-none flex-1 flex align-items-center" style="background-color: #e2e4e5">
32
- <i class="pi pi-user text-xl"></i>
33
- <div class="ml-4">{{ historyItem.query }}</div>
34
- </div>
35
- </div>
36
- <div class="flex flex-column mb-2">
37
- <div class="card shadow-none flex-1 flex align-items-center ml-5">
38
- <i class="pi pi-comment text-xl"></i>
39
- <div class="ml-4">{{ historyItem.answer }}</div>
40
- </div>
41
- </div>
42
- }
43
- }
44
-
45
- @if (queryList.getValue().length > 0) {
46
- @for (item of queryList.getValue(); track $index) {
47
- <div class="flex flex-column mb-2">
48
- <div class="card shadow-none flex-1 flex align-items-center" style="background-color: #e2e4e5">
49
- <i class="pi pi-user text-xl"></i>
50
- <div class="ml-4 text-lg">{{ item.question }}</div>
51
- </div>
52
- </div>
53
- <div class="flex flex-column">
54
- <div class="card shadow-none flex-1 flex align-items-center ml-5">
55
- <i class="pi pi-comment text-xl"></i>
56
- <div class="ml-4 text-lg">{{ item.answer }}</div>
57
- </div>
58
- </div>
59
- }
60
- }
61
-
62
- @if (visibleGiveFeedback) {
63
- <div class="flex mb-2">
64
- <div class="card custom-card" style="background-color: #e2e4e5">
65
- <div>
66
- <span>Geri bildirimlerinizi buradan gönderebilirsiniz.</span>
67
- </div>
68
- <div>
69
- <p-rating [(ngModel)]="feedbackRating" [stars]="5" />
70
- </div>
71
- <div class="text-lg">
72
- <aril-text-area [rows]="5" [cols]="30" pTextarea [(ngModel)]="feedbackComments"></aril-text-area>
73
- </div>
74
- <div>
75
- <aril-button label="Gönder" color="danger" icon="SEND" [outlined]="true" (clickEvent)="sendFeedback()">
76
- </aril-button>
77
- <aril-button label="Vazgeç" color="danger" icon="TIMES" [outlined]="true" (clickEvent)="cancelFeedback()">
78
- </aril-button>
79
- </div>
80
- </div>
81
- </div>
82
- }
83
- </div>
84
-
85
- @if (isTyping) {
86
- <div
87
- class="typing-indicator"
88
- style="font-size: 16px; font-weight: 900; padding: 6px; width: 10%; text-align: center">
89
- {{ typingText }}
90
- </div>
91
- }
92
-
93
- <div class="search-container" style="position: absolute; bottom: 0; width: 100%; background: white">
94
- <div class="search-box" style="display: flex; align-items: center; gap: 0.5rem">
95
- <input
96
- style="flex: 1; width: 100%"
97
- type="text"
98
- pInputText
99
- placeholder="Sorunu yaz..."
100
- [(ngModel)]="questionQuery"
101
- class="flex-1"
102
- maxlength="500" />
103
- <aril-button label="Gönder" color="danger" icon="SEND" [outlined]="true" (clickEvent)="sendRequest()">
104
- </aril-button>
105
- </div>
106
- </div>
107
- </div>
108
- </p-sidebar>
@@ -1,35 +0,0 @@
1
- ::ng-deep .p-sidebar .p-sidebar-header {
2
-
3
-
4
- background-color: var(--primary-color) !important;
5
- color: #ffffff !important;
6
- }
7
-
8
- ::ng-deep .p-sidebar .p-sidebar-close i {
9
- color: #fff !important;
10
- }
11
-
12
- .custom-sidebar-header {
13
- display: flex;
14
- align-items: center;
15
- justify-content: space-between;
16
- padding: 0.5rem;
17
- }
18
-
19
- .header-title {
20
- font-size: 16px;
21
- font-weight: 700;
22
- }
23
-
24
- .custom-icon {
25
- font-size: 1.5rem;
26
- color: #fff; /* Özel ikon rengi */
27
- cursor: pointer;
28
- margin-left: 1rem;
29
- }
30
-
31
- .custom-card {
32
- display: flex;
33
- flex-direction: column;
34
- gap: 0.5rem; /* Alt alta gelen öğeler arasında boşluk ekler */
35
- }
@@ -1,151 +0,0 @@
1
- /* eslint-disable @angular-eslint/component-selector */
2
- import { HttpClient } from '@angular/common/http';
3
- import { Component } from '@angular/core';
4
- import { FormsModule } from '@angular/forms';
5
-
6
- import { ButtonModule } from 'primeng/button';
7
- import { IconFieldModule } from 'primeng/iconfield';
8
- import { InputIconModule } from 'primeng/inputicon';
9
- import { InputTextModule } from 'primeng/inputtext';
10
- import { MessagesModule } from 'primeng/messages';
11
- import { RadioButtonModule } from 'primeng/radiobutton';
12
- import { RatingModule } from 'primeng/rating';
13
- import { SidebarModule } from 'primeng/sidebar';
14
-
15
- import { KeycloakService } from 'keycloak-angular';
16
- import { BehaviorSubject, firstValueFrom } from 'rxjs';
17
-
18
- import { API_CONFIGS } from 'aril/boot/config/api';
19
- import { ButtonComponent } from 'aril/ui/button';
20
- import { TextAreaComponent } from 'aril/ui/textArea';
21
-
22
- @Component({
23
- standalone: true,
24
- selector: 'app-chatbot',
25
- imports: [
26
- ButtonModule,
27
- SidebarModule,
28
- RadioButtonModule,
29
- FormsModule,
30
- InputIconModule,
31
- IconFieldModule,
32
- InputTextModule,
33
- MessagesModule,
34
- TextAreaComponent,
35
- RatingModule,
36
- ButtonComponent
37
- ],
38
- templateUrl: './app.chatbot.component.html',
39
- styleUrl: './app.chatbot.component.scss'
40
- })
41
- export class AppChatbotComponent {
42
- chatbotVisible = false;
43
- projectName!: string;
44
- questionQuery!: string;
45
- queryList: BehaviorSubject<any[]> = new BehaviorSubject<any[]>([]);
46
- error!: string;
47
- historyList: BehaviorSubject<any[]> = new BehaviorSubject<any[]>([]);
48
- isTyping = false;
49
- typingInterval: any;
50
- typingText = '.';
51
- username: string;
52
- visibleGiveFeedback = false;
53
- feedbackComments = '';
54
- feedbackRating = 0;
55
- feedBackResult!: string;
56
- baseUrl = API_CONFIGS.aiApi;
57
-
58
- constructor(
59
- private readonly http: HttpClient,
60
- private readonly keycloak: KeycloakService
61
- ) {
62
- this.username = this.keycloak.getUsername();
63
- }
64
-
65
- sendRequest() {
66
- this.fetchData();
67
- }
68
-
69
- async getHistory() {
70
- try {
71
- await this.http
72
- .get<any[]>(this.baseUrl + 'history?project=CRM' + '&user_name=' + this.username)
73
- .subscribe((response) => {
74
- this.historyList.next(response);
75
- });
76
- } catch (error) {
77
- console.log(error);
78
- }
79
- }
80
-
81
- async fetchData() {
82
- this.startTyping();
83
- const request = {
84
- project: 'CRM',
85
- user_name: this.username,
86
- query: this.questionQuery
87
- };
88
-
89
- try {
90
- const result = await firstValueFrom(this.http.post<any>(this.baseUrl + 'chat', request));
91
- if (result && result.answer) {
92
- this.queryList.next([...this.queryList.value, { question: this.questionQuery, answer: result.answer }]);
93
- }
94
- } catch (error: any) {
95
- this.error = error;
96
- } finally {
97
- this.questionQuery = '';
98
- this.stopTyping();
99
- }
100
- }
101
- onVisible() {
102
- this.getHistory();
103
- this.chatbotVisible = true;
104
- }
105
-
106
- startTyping() {
107
- this.isTyping = true;
108
- let dots = 0;
109
-
110
- this.typingInterval = setInterval(() => {
111
- dots = (dots + 1) % 4;
112
- this.typingText = '.'.repeat(dots);
113
- }, 300);
114
- }
115
-
116
- stopTyping() {
117
- clearInterval(this.typingInterval);
118
- this.isTyping = false;
119
- }
120
-
121
- giveFeedback() {
122
- this.visibleGiveFeedback = true;
123
- }
124
- async sendFeedback() {
125
- const request = {
126
- project: 'CRM',
127
- user_name: this.username,
128
- rating: this.feedbackRating,
129
- comments: this.feedbackComments
130
- };
131
-
132
- try {
133
- const result = await firstValueFrom(this.http.post<any>(this.baseUrl + 'feedback', request));
134
- if (result) {
135
- this.feedBackResult = result.message;
136
- }
137
- } catch (error: any) {
138
- this.error = error;
139
- } finally {
140
- this.visibleGiveFeedback = false;
141
- this.feedbackComments = '';
142
- this.feedbackRating = 0;
143
- }
144
- }
145
-
146
- cancelFeedback() {
147
- this.visibleGiveFeedback = false;
148
- this.feedbackComments = '';
149
- this.feedbackRating = 0;
150
- }
151
- }