@sinequa/assistant 3.4.3 → 3.5.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.
@@ -0,0 +1,13 @@
1
+ import { OnChanges, SimpleChanges } from '@angular/core';
2
+ import { Chart } from 'chart.js';
3
+ import * as i0 from "@angular/core";
4
+ export declare class ChartComponent implements OnChanges {
5
+ rawChartData: string;
6
+ chart: Chart;
7
+ private debounceTimer;
8
+ constructor();
9
+ ngOnChanges(changes: SimpleChanges): void;
10
+ private initializeChart;
11
+ static ɵfac: i0.ɵɵFactoryDeclaration<ChartComponent, never>;
12
+ static ɵcmp: i0.ɵɵComponentDeclaration<ChartComponent, "sq-assistant-chart", never, { "rawChartData": "rawChartData"; }, {}, never, never, true>;
13
+ }
@@ -23,6 +23,9 @@ export declare class ChatMessageComponent implements OnChanges, AfterViewInit {
23
23
  canEdit: boolean;
24
24
  canRegenerate: boolean;
25
25
  canCopy: boolean;
26
+ canDebug: boolean;
27
+ canLike: boolean;
28
+ canDislike: boolean;
26
29
  openDocument: EventEmitter<{
27
30
  reference: ChatContextAttachment;
28
31
  partId?: number | undefined;
@@ -37,6 +40,7 @@ export declare class ChatMessageComponent implements OnChanges, AfterViewInit {
37
40
  regenerate: EventEmitter<ChatMessage>;
38
41
  like: EventEmitter<ChatMessage>;
39
42
  dislike: EventEmitter<ChatMessage>;
43
+ debug: EventEmitter<ChatMessage>;
40
44
  processor: Processor;
41
45
  references: string[];
42
46
  referenceMap: Map<string, ChatContextAttachment>;
@@ -45,10 +49,11 @@ export declare class ChatMessageComponent implements OnChanges, AfterViewInit {
45
49
  iconSize: number;
46
50
  liked: boolean;
47
51
  disliked: boolean;
48
- get name(): string;
49
52
  constructor(searchService: SearchService, ui: UIService, principalService: PrincipalWebService, cdr: ChangeDetectorRef, el: ElementRef);
50
53
  ngOnChanges(changes: SimpleChanges): void;
51
54
  ngAfterViewInit(): void;
55
+ get name(): string;
56
+ get isAdmin(): boolean;
52
57
  /**
53
58
  * This Unified plugin looks a text nodes and replaces any reference in the
54
59
  * form [1], [2.3], etc. with custom nodes of type "chat-reference".
@@ -64,9 +69,11 @@ export declare class ChatMessageComponent implements OnChanges, AfterViewInit {
64
69
  * Match all references in a given message
65
70
  */
66
71
  getReferenceMatches(content: string): RegExpMatchArray[];
67
- copyToClipboard(message: ChatMessage): void;
72
+ private _copyToClipboard;
73
+ copyMessage(message: ChatMessage): void;
74
+ copyCode(code: string): void;
68
75
  openAttachmentPreview(attachment: ChatContextAttachment, partId?: number): void;
69
76
  openOriginalAttachment(attachment: ChatContextAttachment, partId?: number): void;
70
77
  static ɵfac: i0.ɵɵFactoryDeclaration<ChatMessageComponent, never>;
71
- static ɵcmp: i0.ɵɵComponentDeclaration<ChatMessageComponent, "sq-chat-message", never, { "message": "message"; "conversation": "conversation"; "suggestedActions": "suggestedActions"; "assistantMessageIcon": "assistantMessageIcon"; "userMessageIcon": "userMessageIcon"; "streaming": "streaming"; "canEdit": "canEdit"; "canRegenerate": "canRegenerate"; "canCopy": "canCopy"; }, { "openDocument": "openDocument"; "openPreview": "openPreview"; "suggestAction": "suggestAction"; "edit": "edit"; "copy": "copy"; "regenerate": "regenerate"; "like": "like"; "dislike": "dislike"; }, never, never, true>;
78
+ static ɵcmp: i0.ɵɵComponentDeclaration<ChatMessageComponent, "sq-chat-message", never, { "message": "message"; "conversation": "conversation"; "suggestedActions": "suggestedActions"; "assistantMessageIcon": "assistantMessageIcon"; "userMessageIcon": "userMessageIcon"; "streaming": "streaming"; "canEdit": "canEdit"; "canRegenerate": "canRegenerate"; "canCopy": "canCopy"; "canDebug": "canDebug"; "canLike": "canLike"; "canDislike": "canDislike"; }, { "openDocument": "openDocument"; "openPreview": "openPreview"; "suggestAction": "suggestAction"; "edit": "edit"; "copy": "copy"; "regenerate": "regenerate"; "like": "like"; "dislike": "dislike"; "debug": "debug"; }, never, never, true>;
72
79
  }
@@ -6,7 +6,7 @@ import { AppService, Query } from "@sinequa/core/app-utils";
6
6
  import { PrincipalWebService } from "@sinequa/core/web-services";
7
7
  import { BehaviorSubject, Subscription } from "rxjs";
8
8
  import { ChatService } from "./chat.service";
9
- import { ChatContextAttachment, ChatConfig, ChatMessage, GllmModelDescription, MessageHandler, RawMessage, SuggestedAction, InitChat } from "./types";
9
+ import { ChatContextAttachment, ChatConfig, ChatMessage, GllmModelDescription, MessageHandler, RawMessage, SuggestedAction, InitChat, DebugMessage } from "./types";
10
10
  import { InstanceManagerService } from "./instance-manager.service";
11
11
  import { WebSocketChatService } from "./websocket-chat.service";
12
12
  import { LoginService } from "@sinequa/core/login";
@@ -970,10 +970,7 @@ export declare class ChatComponent extends AbstractFacet implements OnInit, OnCh
970
970
  partname: string;
971
971
  }[];
972
972
  }[];
973
- documentlanguages: string[]; /**
974
- * Send a "like" event on clicking on the thumb-up icon of an assistant's message
975
- * @param rank The rank of the message to like
976
- */
973
+ documentlanguages: string[];
977
974
  documentweight: string;
978
975
  modified: string;
979
976
  indexationtime: string;
@@ -1073,6 +1070,8 @@ export declare class ChatComponent extends AbstractFacet implements OnInit, OnCh
1073
1070
  questionInput?: ElementRef<HTMLTextAreaElement>;
1074
1071
  loadingTpl?: TemplateRef<any>;
1075
1072
  reportIssueTpl?: TemplateRef<any>;
1073
+ tokenConsumptionTpl?: TemplateRef<any>;
1074
+ debugMessagesTpl?: TemplateRef<any>;
1076
1075
  chatService: ChatService;
1077
1076
  config: ChatConfig;
1078
1077
  messages$: BehaviorSubject<ChatMessage[] | undefined>;
@@ -1095,11 +1094,14 @@ export declare class ChatComponent extends AbstractFacet implements OnInit, OnCh
1095
1094
  messageRelatedIssue?: ChatMessage;
1096
1095
  issueRank?: number;
1097
1096
  showReportIssue: boolean;
1097
+ debugMessages: DebugMessage[] | undefined;
1098
+ showDebugMessages: boolean;
1098
1099
  private _previousQuery;
1099
1100
  constructor();
1100
1101
  ngOnInit(): void;
1101
1102
  ngOnChanges(changes: SimpleChanges): void;
1102
1103
  ngOnDestroy(): void;
1104
+ get isAdmin(): boolean;
1103
1105
  /**
1104
1106
  * Instantiate the chat service based on the provided @input protocol
1105
1107
  * This chat service instance will then be stored in the instanceManagerService with provided @input instanceId as a key
@@ -1198,14 +1200,33 @@ export declare class ChatComponent extends AbstractFacet implements OnInit, OnCh
1198
1200
  * Close the issue reporting dialog.
1199
1201
  */
1200
1202
  ignoreIssue(): void;
1203
+ /**
1204
+ * Handle the click on a reference's 'open preview'.
1205
+ * @param data
1206
+ */
1201
1207
  openAttachmentPreview(data: {
1202
1208
  reference: ChatContextAttachment;
1203
1209
  partId?: number;
1204
1210
  }): void;
1211
+ /**
1212
+ * Handle the click on a reference's 'open original document'.
1213
+ * @param data
1214
+ */
1205
1215
  openOriginalAttachment(data: {
1206
1216
  reference: ChatContextAttachment;
1207
1217
  partId?: number;
1208
1218
  }): void;
1219
+ /**
1220
+ * Handle the click on a suggested action.
1221
+ * @param action Suggested action.
1222
+ * @param index Rank of the message in the chatHistory related to the suggested action.
1223
+ */
1224
+ suggestActionClick(action: SuggestedAction, index: number): void;
1225
+ /**
1226
+ * Handle the click on the 'show log info' button of a message.
1227
+ * @param message The message of the ChatHistory to show its debug messages
1228
+ */
1229
+ showDebug(message: ChatMessage): void;
1209
1230
  static ɵfac: i0.ɵɵFactoryDeclaration<ChatComponent, never>;
1210
- static ɵcmp: i0.ɵɵComponentDeclaration<ChatComponent, "sq-chat-v3", never, { "instanceId": "instanceId"; "query": "query"; "queryChangeShouldTriggerReload": "queryChangeShouldTriggerReload"; "protocol": "protocol"; "messageHandlers": "messageHandlers"; "automaticScrollToLastResponse": "automaticScrollToLastResponse"; "chat": "chat"; "assistantMessageIcon": "assistantMessageIcon"; "userMessageIcon": "userMessageIcon"; }, { "data": "data"; "openDocument": "openDocument"; "openPreview": "openPreview"; "suggestAction": "suggestAction"; "loading$": "loading"; "_config": "config"; }, ["loadingTpl", "reportIssueTpl"], never, true>;
1231
+ static ɵcmp: i0.ɵɵComponentDeclaration<ChatComponent, "sq-chat-v3", never, { "instanceId": "instanceId"; "query": "query"; "queryChangeShouldTriggerReload": "queryChangeShouldTriggerReload"; "protocol": "protocol"; "messageHandlers": "messageHandlers"; "automaticScrollToLastResponse": "automaticScrollToLastResponse"; "chat": "chat"; "assistantMessageIcon": "assistantMessageIcon"; "userMessageIcon": "userMessageIcon"; }, { "data": "data"; "openDocument": "openDocument"; "openPreview": "openPreview"; "suggestAction": "suggestAction"; "loading$": "loading"; "_config": "config"; }, ["loadingTpl", "reportIssueTpl", "tokenConsumptionTpl", "debugMessagesTpl"], never, true>;
1211
1232
  }
@@ -0,0 +1,17 @@
1
+ import { AfterViewInit } from "@angular/core";
2
+ import { DebugMessage } from "../types";
3
+ import { UIService } from "@sinequa/components/utils";
4
+ import * as i0 from "@angular/core";
5
+ export declare class DebugMessageComponent implements AfterViewInit {
6
+ ui: UIService;
7
+ data: DebugMessage[] | undefined;
8
+ level: number;
9
+ parentColor: string;
10
+ constructor(ui: UIService);
11
+ ngAfterViewInit(): void;
12
+ isObject(value: any): boolean;
13
+ getRowClass(item: DebugMessage, index: number): string;
14
+ copyToClipboard(code: any): void;
15
+ static ɵfac: i0.ɵɵFactoryDeclaration<DebugMessageComponent, never>;
16
+ static ɵcmp: i0.ɵɵComponentDeclaration<DebugMessageComponent, "sq-debug-message", never, { "data": "data"; "level": "level"; "parentColor": "parentColor"; }, {}, never, never, true>;
17
+ }
package/chat/types.d.ts CHANGED
@@ -11,6 +11,7 @@ import { Query } from '@sinequa/core/app-utils';
11
11
  export interface RawMessage {
12
12
  role: string;
13
13
  content: string;
14
+ messageType?: 'CHART' | 'MARKDOWN';
14
15
  additionalProperties: {
15
16
  [key: string]: any;
16
17
  };
@@ -26,10 +27,12 @@ export interface ChatMessage extends RawMessage {
26
27
  $progress?: ChatProgress[];
27
28
  $attachment?: ChatContextAttachment[];
28
29
  $suggestedAction?: SuggestedAction[];
30
+ $debug?: DebugMessage[];
29
31
  forcedWorkflow?: string;
30
32
  query?: Query;
31
33
  isUserInput?: boolean;
32
34
  usageMetrics?: ChatUsageMetrics;
35
+ additionalWorkflowProperties?: any;
33
36
  [key: string]: any;
34
37
  };
35
38
  }
@@ -168,6 +171,9 @@ export interface ServiceSettings extends z.infer<typeof serviceSettingsSchema> {
168
171
  declare const additionalServiceSettingsSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
169
172
  export interface AdditionalServiceSettings extends z.infer<typeof additionalServiceSettingsSchema> {
170
173
  }
174
+ declare const additionalWorkflowPropertiesSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
175
+ export interface additionalWorkflowProperties extends z.infer<typeof additionalWorkflowPropertiesSchema> {
176
+ }
171
177
  declare const uiSettingsSchema: z.ZodObject<{
172
178
  display: z.ZodBoolean;
173
179
  servicesModels: z.ZodBoolean;
@@ -457,7 +463,6 @@ export declare const chatConfigSchema: z.ZodObject<{
457
463
  displaySystemPrompt: boolean;
458
464
  displayUserPrompt: boolean;
459
465
  }>;
460
- additionalServiceSettings: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
461
466
  savedChatSettings: z.ZodObject<{
462
467
  enabled: z.ZodBoolean;
463
468
  display: z.ZodBoolean;
@@ -481,7 +486,10 @@ export declare const chatConfigSchema: z.ZodObject<{
481
486
  displayUserQuotaConsumption?: boolean | undefined;
482
487
  displayChatTokensConsumption?: boolean | undefined;
483
488
  }>;
489
+ additionalServiceSettings: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
490
+ additionalWorkflowProperties: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
484
491
  }, "strip", z.ZodTypeAny, {
492
+ additionalWorkflowProperties: {};
485
493
  connectionSettings: {
486
494
  signalRTransport: "None" | "WebSockets" | "ServerSentEvents" | "LongPolling";
487
495
  signalRLogLevel: "None" | "Critical" | "Debug" | "Error" | "Information" | "Trace" | "Warning";
@@ -523,7 +531,6 @@ export declare const chatConfigSchema: z.ZodObject<{
523
531
  displaySystemPrompt: boolean;
524
532
  displayUserPrompt: boolean;
525
533
  };
526
- additionalServiceSettings: {};
527
534
  savedChatSettings: {
528
535
  display: boolean;
529
536
  enabled: boolean;
@@ -533,7 +540,9 @@ export declare const chatConfigSchema: z.ZodObject<{
533
540
  displayUserQuotaConsumption?: boolean | undefined;
534
541
  displayChatTokensConsumption?: boolean | undefined;
535
542
  };
543
+ additionalServiceSettings: {};
536
544
  }, {
545
+ additionalWorkflowProperties: {};
537
546
  connectionSettings: {
538
547
  signalRTransport: "None" | "WebSockets" | "ServerSentEvents" | "LongPolling";
539
548
  signalRLogLevel: "None" | "Critical" | "Debug" | "Error" | "Information" | "Trace" | "Warning";
@@ -575,7 +584,6 @@ export declare const chatConfigSchema: z.ZodObject<{
575
584
  displaySystemPrompt: boolean;
576
585
  displayUserPrompt: boolean;
577
586
  };
578
- additionalServiceSettings: {};
579
587
  savedChatSettings: {
580
588
  display: boolean;
581
589
  enabled: boolean;
@@ -585,6 +593,7 @@ export declare const chatConfigSchema: z.ZodObject<{
585
593
  displayUserQuotaConsumption?: boolean | undefined;
586
594
  displayChatTokensConsumption?: boolean | undefined;
587
595
  };
596
+ additionalServiceSettings: {};
588
597
  }>;
589
598
  export interface ChatConfig extends z.infer<typeof chatConfigSchema> {
590
599
  }
@@ -662,6 +671,7 @@ export declare type HistoryEvent = {
662
671
  history: RawMessage[];
663
672
  executionTime: string;
664
673
  };
674
+ export declare type DebugMessageEvent = DebugMessage;
665
675
  /**
666
676
  * Data emitted by the http chat endpoint
667
677
  */
@@ -689,6 +699,22 @@ export interface ChatUsageMetrics {
689
699
  completionTokenCount: number;
690
700
  tokenizerType: string;
691
701
  }
702
+ export interface KvObject {
703
+ data: {
704
+ key: string;
705
+ value: any;
706
+ };
707
+ type: 'KV';
708
+ isError: boolean;
709
+ }
710
+ export interface ListObject {
711
+ name: string;
712
+ type: 'LIST';
713
+ isError: boolean;
714
+ items: (KvObject | ListObject)[];
715
+ expanded: boolean;
716
+ }
717
+ export declare type DebugMessage = KvObject | ListObject;
692
718
  export declare type MessageHandler<T> = {
693
719
  handler: (data: T) => void;
694
720
  isGlobalHandler: boolean;
@@ -17,6 +17,7 @@ export declare class WebSocketChatService extends ChatService {
17
17
  private _executionTime;
18
18
  private _attachments;
19
19
  private _suggestedActions;
20
+ private _debugMessages;
20
21
  signalRService: SignalRWebService;
21
22
  authenticationService: AuthenticationService;
22
23
  constructor();
@@ -0,0 +1,40 @@
1
+ import { Component, Input } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { Chart, registerables } from 'chart.js';
4
+ import * as i0 from "@angular/core";
5
+ Chart.register(...registerables);
6
+ export class ChartComponent {
7
+ constructor() { }
8
+ ngOnChanges(changes) {
9
+ if (changes['rawChartData']) {
10
+ clearTimeout(this.debounceTimer);
11
+ this.debounceTimer = setTimeout(() => this.initializeChart(), 300);
12
+ }
13
+ }
14
+ initializeChart() {
15
+ Chart.getChart('chart-canvas')?.destroy();
16
+ const canvasElement = document.getElementById('chart-canvas');
17
+ if (canvasElement) {
18
+ try {
19
+ let chartInput = this.rawChartData.match(/<chartjs>({[\s\S]*?)<\/chartjs>/)?.[1]?.trim().replace(/'/g, '"');
20
+ let chartConfig = JSON.parse(chartInput);
21
+ this.chart = new Chart('chart-canvas', chartConfig);
22
+ }
23
+ catch (error) {
24
+ console.error('Invalid chart configuration, check the assistant configuration: ', error);
25
+ }
26
+ }
27
+ else {
28
+ console.error('Chart Canvas is not found');
29
+ }
30
+ }
31
+ }
32
+ ChartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: ChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
33
+ ChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: ChartComponent, isStandalone: true, selector: "sq-assistant-chart", inputs: { rawChartData: "rawChartData" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"chart-container\">\n <canvas id=\"chart-canvas\">{{ chart }}</canvas>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
34
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: ChartComponent, decorators: [{
35
+ type: Component,
36
+ args: [{ selector: 'sq-assistant-chart', standalone: true, imports: [CommonModule], template: "<div class=\"chart-container\">\n <canvas id=\"chart-canvas\">{{ chart }}</canvas>\n</div>\n" }]
37
+ }], ctorParameters: function () { return []; }, propDecorators: { rawChartData: [{
38
+ type: Input
39
+ }] } });
40
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhcnQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYXNzaXN0YW50L2NoYXQvY2hhcnRzL2NoYXJ0L2NoYXJ0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Fzc2lzdGFudC9jaGF0L2NoYXJ0cy9jaGFydC9jaGFydC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQWEsU0FBUyxFQUFFLEtBQUssRUFBaUIsTUFBTSxlQUFlLENBQUM7QUFDM0UsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFLE1BQU0sVUFBVSxDQUFBOztBQUUvQyxLQUFLLENBQUMsUUFBUSxDQUFDLEdBQUcsYUFBYSxDQUFDLENBQUM7QUFTakMsTUFBTSxPQUFPLGNBQWM7SUFNekIsZ0JBQWdCLENBQUM7SUFFakIsV0FBVyxDQUFDLE9BQXNCO1FBQ2hDLElBQUksT0FBTyxDQUFDLGNBQWMsQ0FBQyxFQUFFO1lBQzNCLFlBQVksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDakMsSUFBSSxDQUFDLGFBQWEsR0FBRyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1NBQ3BFO0lBQ0gsQ0FBQztJQUVPLGVBQWU7UUFDckIsS0FBSyxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQztRQUUxQyxNQUFNLGFBQWEsR0FBRyxRQUFRLENBQUMsY0FBYyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBRTlELElBQUcsYUFBYSxFQUFDO1lBQ2YsSUFBRztnQkFDRCxJQUFJLFVBQVUsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxpQ0FBaUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxHQUFHLENBQVcsQ0FBQztnQkFDdEgsSUFBSSxXQUFXLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQztnQkFFekMsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLEtBQUssQ0FBQyxjQUFjLEVBQUUsV0FBVyxDQUFDLENBQUM7YUFFckQ7WUFBQyxPQUFPLEtBQUssRUFBRTtnQkFDZCxPQUFPLENBQUMsS0FBSyxDQUFDLGtFQUFrRSxFQUFFLEtBQUssQ0FBQyxDQUFDO2FBQzFGO1NBRUY7YUFDSTtZQUNILE9BQU8sQ0FBQyxLQUFLLENBQUMsMkJBQTJCLENBQUMsQ0FBQztTQUM1QztJQUNILENBQUM7OzJHQW5DVSxjQUFjOytGQUFkLGNBQWMsNklDYjNCLGlHQUdBLHlERE1ZLFlBQVk7MkZBSVgsY0FBYztrQkFQMUIsU0FBUzsrQkFDRSxvQkFBb0IsY0FDbEIsSUFBSSxXQUNQLENBQUMsWUFBWSxDQUFDOzBFQUtkLFlBQVk7c0JBQXBCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBPbkNoYW5nZXMsIENvbXBvbmVudCwgSW5wdXQsIFNpbXBsZUNoYW5nZXMgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBDaGFydCwgcmVnaXN0ZXJhYmxlcyB9IGZyb20gJ2NoYXJ0LmpzJ1xuXG5DaGFydC5yZWdpc3RlciguLi5yZWdpc3RlcmFibGVzKTtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnc3EtYXNzaXN0YW50LWNoYXJ0JyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZV0sXG4gIHRlbXBsYXRlVXJsOiAnLi9jaGFydC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2NoYXJ0LmNvbXBvbmVudC5jc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBDaGFydENvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcyB7XG4gIEBJbnB1dCgpIHJhd0NoYXJ0RGF0YTogc3RyaW5nO1xuXG4gIHB1YmxpYyBjaGFydDogQ2hhcnQ7XG4gIHByaXZhdGUgZGVib3VuY2VUaW1lcjogYW55O1xuXG4gIGNvbnN0cnVjdG9yKCkgeyB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmIChjaGFuZ2VzWydyYXdDaGFydERhdGEnXSkge1xuICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuZGVib3VuY2VUaW1lcik7XG4gICAgICB0aGlzLmRlYm91bmNlVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHRoaXMuaW5pdGlhbGl6ZUNoYXJ0KCksIDMwMCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBpbml0aWFsaXplQ2hhcnQoKSB7XG4gICAgQ2hhcnQuZ2V0Q2hhcnQoJ2NoYXJ0LWNhbnZhcycpPy5kZXN0cm95KCk7XG5cbiAgICBjb25zdCBjYW52YXNFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2NoYXJ0LWNhbnZhcycpO1xuXG4gICAgaWYoY2FudmFzRWxlbWVudCl7XG4gICAgICB0cnl7XG4gICAgICAgIGxldCBjaGFydElucHV0ID0gdGhpcy5yYXdDaGFydERhdGEubWF0Y2goLzxjaGFydGpzPih7W1xcc1xcU10qPyk8XFwvY2hhcnRqcz4vKT8uWzFdPy50cmltKCkucmVwbGFjZSgvJy9nLCAnXCInKSBhcyBzdHJpbmc7XG4gICAgICAgIGxldCBjaGFydENvbmZpZyA9IEpTT04ucGFyc2UoY2hhcnRJbnB1dCk7ICBcbiAgIFxuICAgICAgICB0aGlzLmNoYXJ0ID0gbmV3IENoYXJ0KCdjaGFydC1jYW52YXMnLCBjaGFydENvbmZpZyk7XG5cbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ludmFsaWQgY2hhcnQgY29uZmlndXJhdGlvbiwgY2hlY2sgdGhlIGFzc2lzdGFudCBjb25maWd1cmF0aW9uOiAnLCBlcnJvcik7XG4gICAgICB9XG5cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdDaGFydCBDYW52YXMgaXMgbm90IGZvdW5kJyk7XG4gICAgfVxuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwiY2hhcnQtY29udGFpbmVyXCI+XG4gICAgPGNhbnZhcyBpZD1cImNoYXJ0LWNhbnZhc1wiPnt7IGNoYXJ0IH19PC9jYW52YXM+XG48L2Rpdj5cbiJdfQ==