@sinequa/assistant 3.9.11 → 3.10.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.
Files changed (110) hide show
  1. package/chat/chat-message/chat-message.component.d.ts +2 -4
  2. package/chat/chat.component.d.ts +4 -3
  3. package/chat/chat.service.d.ts +16 -1
  4. package/chat/custom-elements/components/code-block.component.d.ts +11 -0
  5. package/chat/custom-elements/components/document-reference.component.d.ts +13 -0
  6. package/chat/custom-elements/components/i18n/de.json +5 -0
  7. package/chat/custom-elements/components/i18n/en.json +5 -0
  8. package/chat/custom-elements/components/i18n/fr.json +5 -0
  9. package/chat/custom-elements/components/image-reference.component.d.ts +14 -0
  10. package/chat/custom-elements/components/page-reference.component.d.ts +14 -0
  11. package/chat/custom-elements/components/table-tools.component.d.ts +11 -0
  12. package/chat/custom-elements/custom-elements.config.d.ts +2 -0
  13. package/chat/{services → custom-elements}/custom-elements.service.d.ts +1 -0
  14. package/chat/documents-upload/documents-upload.service.d.ts +2 -2
  15. package/chat/fetch-patcher/app-injector.d.ts +9 -0
  16. package/chat/fetch-patcher/fetch-patcher.d.ts +31 -0
  17. package/chat/fetch-patcher/global-error-handler.service.d.ts +36 -0
  18. package/chat/fetch-patcher/handle-unauthorized-logic.d.ts +13 -0
  19. package/chat/markdown-it/markdown-it.config.d.ts +4 -0
  20. package/chat/markdown-it/plugins/document-reference.plugin.d.ts +8 -0
  21. package/chat/markdown-it/plugins/image-reference.plugin.d.ts +9 -0
  22. package/chat/markdown-it/plugins/page-reference.plugin.d.ts +9 -0
  23. package/chat/markdown-it/plugins/table-tools.plugin.d.ts +2 -0
  24. package/chat/public-api.d.ts +21 -2
  25. package/chat/{chat-reference → references/chat-reference}/chat-reference.component.d.ts +1 -1
  26. package/chat/references/chat-reference-image/chat-reference-image.component.d.ts +20 -0
  27. package/chat/references/chat-reference-page/chat-reference-page.component.d.ts +20 -0
  28. package/chat/references/i18n/de.json +4 -4
  29. package/chat/references/i18n/en.json +1 -1
  30. package/chat/references/i18n/fr.json +1 -1
  31. package/chat/saved-chats/i18n/de.json +2 -1
  32. package/chat/saved-chats/i18n/en.json +2 -1
  33. package/chat/saved-chats/i18n/fr.json +2 -1
  34. package/chat/saved-chats/saved-chats.component.d.ts +4 -0
  35. package/chat/saved-chats/saved-chats.service.d.ts +2 -2
  36. package/chat/services/assistant-metadata.service.d.ts +5 -1
  37. package/chat/services/signalR.web.service.d.ts +0 -11
  38. package/chat/smart-renderer/smart-renderer.d.ts +2 -0
  39. package/chat/token-progress-bar/i18n/en.json +1 -1
  40. package/chat/types/message-reference.types.d.ts +3 -0
  41. package/chat/types.d.ts +55 -35
  42. package/chat/version.d.ts +1 -0
  43. package/esm2022/chat/chat-message/chat-message.component.mjs +15 -12
  44. package/esm2022/chat/chat-settings-v3/chat-settings-v3.component.mjs +7 -4
  45. package/esm2022/chat/chat.component.mjs +39 -26
  46. package/esm2022/chat/chat.service.mjs +39 -5
  47. package/esm2022/chat/custom-elements/components/code-block.component.mjs +97 -0
  48. package/esm2022/chat/custom-elements/components/document-reference.component.mjs +85 -0
  49. package/esm2022/chat/custom-elements/components/image-reference.component.mjs +79 -0
  50. package/esm2022/chat/custom-elements/components/page-reference.component.mjs +79 -0
  51. package/esm2022/chat/custom-elements/components/table-tools.component.mjs +111 -0
  52. package/esm2022/chat/custom-elements/custom-elements.config.mjs +6 -0
  53. package/esm2022/chat/custom-elements/custom-elements.service.mjs +35 -0
  54. package/esm2022/chat/debug-message/debug-message.service.mjs +3 -3
  55. package/esm2022/chat/documents-upload/document-list/document-list.component.mjs +3 -3
  56. package/esm2022/chat/documents-upload/documents-upload.service.mjs +4 -4
  57. package/esm2022/chat/fetch-patcher/app-injector.mjs +19 -0
  58. package/esm2022/chat/fetch-patcher/fetch-patcher.mjs +62 -0
  59. package/esm2022/chat/fetch-patcher/global-error-handler.service.mjs +92 -0
  60. package/esm2022/chat/fetch-patcher/handle-unauthorized-logic.mjs +19 -0
  61. package/esm2022/chat/markdown-it/markdown-it.config.mjs +6 -0
  62. package/esm2022/chat/markdown-it/plugins/code-block.plugin.mjs +14 -0
  63. package/esm2022/chat/markdown-it/plugins/document-reference.plugin.mjs +66 -0
  64. package/esm2022/chat/markdown-it/plugins/image-reference.plugin.mjs +67 -0
  65. package/esm2022/chat/markdown-it/plugins/link.plugin.mjs +15 -0
  66. package/esm2022/chat/markdown-it/plugins/page-reference.plugin.mjs +67 -0
  67. package/esm2022/chat/markdown-it/plugins/table-tools.plugin.mjs +12 -0
  68. package/esm2022/chat/public-api.mjs +23 -3
  69. package/esm2022/chat/references/chat-reference/chat-reference.component.mjs +72 -0
  70. package/esm2022/chat/references/chat-reference-image/chat-reference-image.component.mjs +42 -0
  71. package/esm2022/chat/references/chat-reference-page/chat-reference-page.component.mjs +42 -0
  72. package/esm2022/chat/saved-chats/saved-chats.component.mjs +26 -6
  73. package/esm2022/chat/saved-chats/saved-chats.service.mjs +14 -10
  74. package/esm2022/chat/services/app.service.mjs +7 -2
  75. package/esm2022/chat/services/assistant-metadata.service.mjs +40 -9
  76. package/esm2022/chat/services/assistant-ws-frames.service.mjs +7 -4
  77. package/esm2022/chat/services/signalR-connection.service.mjs +3 -6
  78. package/esm2022/chat/services/signalR.web.service.mjs +3 -13
  79. package/esm2022/chat/services/user-settings.service.mjs +6 -3
  80. package/esm2022/chat/smart-renderer/smart-renderer.mjs +19 -18
  81. package/esm2022/chat/types/message-reference.types.mjs +1 -1
  82. package/esm2022/chat/types.mjs +10 -8
  83. package/esm2022/chat/utils/utils.service.mjs +11 -11
  84. package/esm2022/chat/version.mjs +3 -0
  85. package/fesm2022/sinequa-assistant-chat.mjs +2328 -2049
  86. package/fesm2022/sinequa-assistant-chat.mjs.map +1 -1
  87. package/package.json +6 -6
  88. package/chat/chat-reference/i18n/de.json +0 -4
  89. package/chat/chat-reference/i18n/en.json +0 -4
  90. package/chat/chat-reference/i18n/fr.json +0 -4
  91. package/chat/directives/copy-to-clipboard.directive.d.ts +0 -8
  92. package/chat/markdown-it-plugins/image-reference.plugin.d.ts +0 -3
  93. package/chat/markdown-it-plugins/page-reference.plugin.d.ts +0 -3
  94. package/chat/markdown-it-plugins/reference.plugin.d.ts +0 -7
  95. package/chat/references/inline-image-reference.d.ts +0 -21
  96. package/chat/references/inline-page-reference.d.ts +0 -21
  97. package/chat/references/references.component.d.ts +0 -43
  98. package/esm2022/chat/chat-reference/chat-reference.component.mjs +0 -74
  99. package/esm2022/chat/directives/copy-to-clipboard.directive.mjs +0 -68
  100. package/esm2022/chat/markdown-it-plugins/code-block.plugin.mjs +0 -14
  101. package/esm2022/chat/markdown-it-plugins/image-reference.plugin.mjs +0 -58
  102. package/esm2022/chat/markdown-it-plugins/link.plugin.mjs +0 -15
  103. package/esm2022/chat/markdown-it-plugins/page-reference.plugin.mjs +0 -60
  104. package/esm2022/chat/markdown-it-plugins/reference.plugin.mjs +0 -68
  105. package/esm2022/chat/references/inline-image-reference.mjs +0 -110
  106. package/esm2022/chat/references/inline-page-reference.mjs +0 -110
  107. package/esm2022/chat/references/references.component.mjs +0 -290
  108. package/esm2022/chat/services/custom-elements.service.mjs +0 -43
  109. /package/chat/{markdown-it-plugins → markdown-it/plugins}/code-block.plugin.d.ts +0 -0
  110. /package/chat/{markdown-it-plugins → markdown-it/plugins}/link.plugin.d.ts +0 -0
@@ -2,13 +2,11 @@ import { CommonModule } from "@angular/common";
2
2
  import { ChangeDetectionStrategy, Component, computed, EventEmitter, input, Input, Output, signal } from "@angular/core";
3
3
  import { provideTranslocoScope, TranslocoPipe } from '@jsverse/transloco';
4
4
  import { ChartComponent } from "../charts/chart/chart.component";
5
- import { ChatReferenceComponent } from "../chat-reference/chat-reference.component";
6
5
  import { InitialsAvatarComponent } from "../initials-avatar/initials-avatar.component";
7
6
  import { MessageContentPipe } from "../pipes/message-content.pipe";
8
- import { InlineImageReferenceComponent } from "../references/inline-image-reference";
9
- import { InlinePageReferenceComponent } from "../references/inline-page-reference";
10
7
  import { SmartRendererComponent } from "../smart-renderer/smart-renderer";
11
8
  import { TooltipDirective } from "../tooltip/tooltip.directive";
9
+ import { ChatReferenceComponent } from "../references/chat-reference/chat-reference.component";
12
10
  import * as i0 from "@angular/core";
13
11
  import * as i1 from "../services/ui.service";
14
12
  import * as i2 from "../services/principal.service";
@@ -87,6 +85,8 @@ export class ChatMessageComponent {
87
85
  const messageImageReference = Object.assign({
88
86
  article: this.referenceMap.get(doc)?.record,
89
87
  articleId: this.referenceMap.get(doc)?.recordId,
88
+ parts: [this.referenceMap.get(doc)?.parts?.[+part - 1]], // since it is not possible to locate the image by itself, we use the part in which it is contained
89
+ $partId: 1 // Always 1 for image references since parts array contains only one element referencing the part containing the image
90
90
  }, images[+image - 1]);
91
91
  // save reference in map for reference list
92
92
  if (!this.imageReferencesMap.has(ref))
@@ -101,6 +101,11 @@ export class ChatMessageComponent {
101
101
  const messagePageReference = Object.assign({
102
102
  article: this.referenceMap.get(doc)?.record,
103
103
  articleId: this.referenceMap.get(doc)?.recordId,
104
+ parts: [{
105
+ offset: pageRef.offSet,
106
+ length: pageRef.length
107
+ }], // parts here is an array with a single part representing the page reference
108
+ $partId: 1 // Always 1 for page references since parts array contains only one element referencing the page
104
109
  }, pageRef);
105
110
  // save reference in map for reference list
106
111
  if (!this.pageReferencesMap.has(ref))
@@ -166,12 +171,12 @@ export class ChatMessageComponent {
166
171
  this._copyToClipboard(content);
167
172
  this.copy.emit(message);
168
173
  }
169
- openAttachmentPreview(attachment, partId) {
170
- this.openPreview.emit({ reference: attachment, partId });
174
+ openAttachmentPreview(attachment) {
175
+ this.openPreview.emit({ reference: attachment });
171
176
  this.hideTooltip();
172
177
  }
173
- openOriginalAttachment(attachment, partId) {
174
- this.openDocument.emit({ reference: attachment, partId });
178
+ openOriginalAttachment(attachment) {
179
+ this.openDocument.emit({ reference: attachment });
175
180
  this.hideTooltip();
176
181
  }
177
182
  hideTooltip() {
@@ -181,7 +186,7 @@ export class ChatMessageComponent {
181
186
  });
182
187
  }
183
188
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ChatMessageComponent, deps: [{ token: i1.UIService }, { token: i2.PrincipalService }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
184
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: ChatMessageComponent, isStandalone: true, selector: "sq-chat-message", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: false, isRequired: false, transformFunction: null }, conversation: { classPropertyName: "conversation", publicName: "conversation", isSignal: false, isRequired: false, transformFunction: null }, suggestedActions: { classPropertyName: "suggestedActions", publicName: "suggestedActions", isSignal: false, isRequired: false, transformFunction: null }, assistantMessageIcon: { classPropertyName: "assistantMessageIcon", publicName: "assistantMessageIcon", isSignal: false, isRequired: false, transformFunction: null }, userMessageIcon: { classPropertyName: "userMessageIcon", publicName: "userMessageIcon", isSignal: false, isRequired: false, transformFunction: null }, connectionErrorMessageIcon: { classPropertyName: "connectionErrorMessageIcon", publicName: "connectionErrorMessageIcon", isSignal: false, isRequired: false, transformFunction: null }, searchWarningMessageIcon: { classPropertyName: "searchWarningMessageIcon", publicName: "searchWarningMessageIcon", isSignal: false, isRequired: false, transformFunction: null }, streaming: { classPropertyName: "streaming", publicName: "streaming", isSignal: false, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: false, isRequired: false, transformFunction: null }, canRegenerate: { classPropertyName: "canRegenerate", publicName: "canRegenerate", isSignal: false, isRequired: false, transformFunction: null }, canCopy: { classPropertyName: "canCopy", publicName: "canCopy", isSignal: false, isRequired: false, transformFunction: null }, canDebug: { classPropertyName: "canDebug", publicName: "canDebug", isSignal: false, isRequired: false, transformFunction: null }, canLike: { classPropertyName: "canLike", publicName: "canLike", isSignal: false, isRequired: false, transformFunction: null }, canDislike: { classPropertyName: "canDislike", publicName: "canDislike", isSignal: false, isRequired: false, transformFunction: null }, collapseReferences: { classPropertyName: "collapseReferences", publicName: "collapseReferences", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { openDocument: "openDocument", openPreview: "openPreview", suggestAction: "suggestAction", edit: "edit", copy: "copy", regenerate: "regenerate", like: "like", dislike: "dislike", debug: "debug" }, providers: [provideTranslocoScope('chat-message')], usesOnChanges: true, ngImport: i0, template: "<!-- Message icon -->\n<span class=\"message-icon\" [title]=\"message?.role\">\n <i class=\"d-block\" [style.width.px]=\"iconSize\" *ngIf=\"!message\"></i>\n <ng-container [ngSwitch]=\"message?.role\">\n <!-- For 'assistant' -->\n <i *ngSwitchCase=\"'assistant'\" [ngClass]=\"assistantMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n\n <!-- For 'user' -->\n <ng-container *ngSwitchCase=\"'user'\">\n <i *ngIf=\"!!userMessageIcon; else initialsAvatar\" [ngClass]=\"userMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n <ng-template #initialsAvatar>\n <sq-initials-avatar [fullName]=\"name\"></sq-initials-avatar>\n </ng-template>\n </ng-container>\n\n <!-- For 'connection-error' -->\n <ng-container *ngSwitchCase=\"'connection-error'\">\n <i *ngIf=\"!!connectionErrorMessageIcon; else defaultErrorIcon\" [ngClass]=\"connectionErrorMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n <ng-template #defaultErrorIcon>\n <svg [style.--sq-size.px]=\"iconSize\" class=\"connection-error\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <path fill=\"currentColor\" d=\"M17.1 292c-12.9-22.3-12.9-49.7 0-72L105.4 67.1c12.9-22.3 36.6-36 62.4-36l176.6 0c25.7 0 49.5 13.7 62.4 36L494.9 220c12.9 22.3 12.9 49.7 0 72L406.6 444.9c-12.9 22.3-36.6 36-62.4 36l-176.6 0c-25.7 0-49.5-13.7-62.4-36L17.1 292zM256 128c-13.3 0-24 10.7-24 24l0 112c0 13.3 10.7 24 24 24s24-10.7 24-24l0-112c0-13.3-10.7-24-24-24zm32 224a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z\"/>\n </svg>\n </ng-template>\n </ng-container>\n\n <!-- For 'search-warning' -->\n <ng-container *ngSwitchCase=\"'search-warning'\">\n <i *ngIf=\"!!searchWarningMessageIcon; else defaultWarningIcon\" [ngClass]=\"searchWarningMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n <ng-template #defaultWarningIcon>\n <svg [style.--sq-size.px]=\"iconSize\" class=\"search-warning\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 384 512\">\n <path fill=\"currentColor\" d=\"M272 384c9.6-31.9 29.5-59.1 49.2-86.2c0 0 0 0 0 0c5.2-7.1 10.4-14.2 15.4-21.4c19.8-28.5 31.4-63 31.4-100.3C368 78.8 289.2 0 192 0S16 78.8 16 176c0 37.3 11.6 71.9 31.4 100.3c5 7.2 10.2 14.3 15.4 21.4c0 0 0 0 0 0c19.8 27.1 39.7 54.4 49.2 86.2l160 0zM192 512c44.2 0 80-35.8 80-80l0-16-160 0 0 16c0 44.2 35.8 80 80 80zm0-448c13.3 0 24 10.7 24 24l0 112c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-112c0-13.3 10.7-24 24-24zM160 288a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z\"/>\n </svg>\n </ng-template>\n </ng-container>\n </ng-container>\n</span>\n\n<!-- Message body -->\n<div class=\"flex-grow-1 position-relative relative\" style=\"min-width: 0;\" [ngClass]=\"'message-'+message.role\">\n\n <!-- Progress steps -->\n <div *ngIf=\"message.additionalProperties.$progress as progress\" class=\"small ms-3 mb-2\">\n <details role=\"button\" class=\"select-none\" [open]=\"!collapseProgress\">\n <summary class=\"text-muted\">\n {{ 'chatMessage.viewProgress' | transloco }}\n </summary>\n <ul class=\"list-unstyled\">\n <li *ngFor=\"let step of progress\">\n <i class=\"fas fa-fw fa-check text-success\" *ngIf=\"step.done\"></i>\n <i class=\"fas fa-spinner fa-pulse step-ongoing\" *ngIf=\"!step.done && streaming\"></i>\n <i class=\"fa-solid fa-ban step-error\" *ngIf=\"!step.done && !streaming\"></i>\n <span class=\"ms-2 fw-bold\">{{step.title}}</span>\n <span *ngIf=\"step.content\" [innerHTML]=\"': ' + step.content\"></span>\n </li>\n </ul>\n </details>\n </div>\n\n <!-- Message content -->\n <div class=\"message-content\" *ngIf=\"message.content\">\n\n <!-- Custom rendering for WPS, to be remove with https://sinequa.atlassian.net/browse/ES-23710 -->\n <div *ngIf=\"message?.role === 'assistant' && message.messageType === 'CHART'\">\n <sq-assistant-chart [rawChartData]=\"message.content\"></sq-assistant-chart>\n </div>\n\n <!-- This section is responsible for customizing the template nodes used in the application.\n Template nodes are predefined structures that serve as blueprints for creating/customizing dynamic content -->\n\n\n @if(message?.role === 'assistant' && message.messageType !== 'CHART') {\n <SmartRenderer\n [message]=\"message.content | messageContent\"\n [context]=\"{\n getEmbeddedPageReference: getEmbeddedPageReference.bind(this),\n getEmbeddedImageReference: getEmbeddedImageReference.bind(this),\n referencesMap: referenceMap,\n references: processReferences.bind(this),\n rank: id()\n }\">\n </SmartRenderer>\n }\n\n <p *ngIf=\"message?.role === 'user'\">{{ message.content | messageContent }}</p>\n\n <!-- List of reference, if any -->\n @let referencesArray = references();\n @if (referencesArray?.length > 0 || imageReferencesMap?.size > 0 || pageReferencesMap?.size > 0) {\n <div class=\"references\">\n <details role=\"button\" class=\"select-none\" [open]=\"!collapseReferences\">\n <summary class=\"references-title\">{{ 'chatMessage.references' | transloco }}</summary>\n <ul>\n @for (reference of referencesArray; track $index) {\n @let attachment = referenceMap.get(reference);\n <!-- Only display the reference when the key is a integer not a decimal -->\n @if(attachment) {\n <li class=\"text-truncate\">\n <sq-chat-reference\n [class.expanded]=\"attachment?.$expanded\"\n [attachment]=\"attachment\"\n [reference]=\"reference\"\n [referenceMap]=\"referenceMap\"\n [images]=\"Array.from(imageReferencesMap.keys())\"\n [pages]=\"Array.from(pageReferencesMap.keys())\"\n (openPreview)=\"openAttachmentPreview($event)\"\n (openDocument)=\"openOriginalAttachment($event)\">\n </sq-chat-reference>\n </li>\n }\n }\n </ul>\n </details>\n </div>\n }\n </div>\n\n <!-- Edit / Regenerate floating actions -->\n <div class=\"sq-chat-message-actions\" *ngIf=\"message\">\n <!-- Common action buttons for \"user\" & \"assistant\" message -->\n <button class=\"btn btn-sm\" *ngIf=\"canCopy\" [sqTooltip]=\"'chatMessage.copyText' | transloco\" (click)=\"copyMessage(message)\">\n <i class=\"far fa-clipboard\"></i>\n </button>\n <!-- Action buttons for \"user\" message -->\n <button class=\"btn btn-sm\" *ngIf=\"canEdit\" [sqTooltip]=\"'chatMessage.editMessage' | transloco\" (click)=\"edit.emit(message)\">\n <i class=\"fas fa-edit\"></i>\n </button>\n <!-- Action buttons for \"assistant\" message -->\n <button class=\"btn btn-sm\" [class.bounce]=\"message.additionalProperties.$liked\" *ngIf=\"canLike\" [sqTooltip]=\"'chatMessage.likeAnswer' | transloco\" (click)=\"like.emit()\">\n <i *ngIf=\"!message.additionalProperties.$liked\" class=\"far fa-thumbs-up \"></i>\n <i *ngIf=\"message.additionalProperties.$liked\" class=\"fas fa-thumbs-up\"></i>\n </button>\n <button class=\"btn btn-sm\" [class.bounce]=\"message.additionalProperties.$disliked\" *ngIf=\"canDislike\" [sqTooltip]=\"'chatMessage.reportIssue' | transloco\" (click)=\"dislike.emit()\">\n <i *ngIf=\"!message.additionalProperties.$disliked\" class=\"far fa-thumbs-down \"></i>\n <i *ngIf=\"message.additionalProperties.$disliked\" class=\"fas fa-thumbs-down\"></i>\n </button>\n <button class=\"btn btn-sm\" *ngIf=\"canRegenerate\" [sqTooltip]=\"'chatMessage.regenerateResponse' | transloco\" (click)=\"regenerate.emit(message)\">\n <i class=\"fas fa-sync-alt\"></i>\n </button>\n <button class=\"btn btn-sm\" *ngIf=\"canDebug\" [sqTooltip]=\"'chatMessage.showLogInformation' | transloco\" (click)=\"debug.emit(message);\">\n <i class=\"far fa-list-alt\"></i>\n </button>\n </div>\n\n <!-- List of suggested actions, if any -->\n <div *ngIf=\"suggestedActions\" class=\"mt-2 message-suggestion\">\n <div class=\"suggested-action\" *ngFor=\"let suggestedAction of suggestedActions\" (click)=\"suggestAction.emit(suggestedAction)\">\n <div class=\"message-icon\" [style.width.px]=\"iconSize\"></div>\n <div class=\"message-content\">\n <p><i class=\"fas fa-clipboard-question\"></i> {{suggestedAction.content}}</p>\n </div>\n </div>\n </div>\n\n <ng-template #imageTooltipTpl let-ref>\n <InlineImageReference\n style=\"max-width: 30vw;\"\n [id]=\"ref.id\"\n [ref]=\"ref.obj\"\n (openPreview)=\"openAttachmentPreview($event)\"\n (openDocument)=\"openOriginalAttachment($event, $event.$partId)\"\n (openModal)=\"hideTooltip()\"\n />\n </ng-template>\n\n <ng-template #pageTooltipTpl let-ref>\n <InlinePageReference\n style=\"max-width: 30vw;\"\n [id]=\"ref.id\"\n [ref]=\"ref.obj\"\n (openPreview)=\"openAttachmentPreview($event)\"\n (openDocument)=\"openOriginalAttachment($event, $event.$partId)\"\n (openModal)=\"hideTooltip()\"\n />\n </ng-template>\n\n <ng-template #tooltipTpl let-ref>\n <sq-chat-reference\n *ngIf=\"!hiddenTooltip\"\n class=\"expanded\"\n [attachment]=\"ref\"\n [reference]=\"ref.contextId\"\n [partId]=\"ref.$partId\"\n (openPreview)=\"openAttachmentPreview($event, ref.$partId)\"\n (openDocument)=\"openOriginalAttachment($event, ref.$partId)\">\n </sq-chat-reference>\n </ng-template>\n\n</div>\n", styles: [".ast-primary{color:var(--ast-primary-color, #005DA7);background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover{background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover:hover{color:var(--ast-primary-color, #005DA7)}.ast-secondary{color:var(--ast-secondary-color, #FF732E);background-color:var(--ast-secondary-bg, #FFF8F1)}.ast-error{background-color:var(--ast-error-bg, rgba(249, 58, 55, .2));color:var(--ast-action-buttons-color, inherit)}.ast-error:hover{color:var(--ast-error-color, rgba(249, 58, 55, .7))}.ast-btn{border:0;text-align:left;padding-top:.5rem;padding-bottom:.5rem;display:flex;align-items:center}.dark{--ast-primary-bg: #0d0701;--ast-primary-color: #008cd1;--ast-secondary-bg: #00070e;--ast-secondary-color: #ffa258;--ast-input-bg: #070707;--ast-input-color: rgba(222, 218, 218, .75);--ast-muted-color: rgba(222, 218, 218, .75);--ast-saved-chat-hover-background: #262421;--ast-uploaded-doc-hover-background: #262421;--ast-message-table-border-color: #333333;--ast-message-table-tr-bg: #070707;--ast-message-table-tr-border-color: #222222;--ast-reference-icon-color: white;--ast-reference-icon-active-color: black;--ast-reference-passages-color: white;--ast-reference-expanded-hover-bg: #262421;--ast-message-reference-color: black;--ast-action-buttons-color: white;--ast-action-buttons-hover-color: #6dbee6;--ast-report-bg: #070707}:host{display:flex}:host:not(:hover):not(.last-message) .sq-chat-message-actions{visibility:hidden}.message-content{padding:var(--ast-message-padding, var(--ast-size-3, .75rem));border-radius:var(--ast-message-border-radius, var(--ast-size-4, 1rem));display:inline-block;max-width:100%;overflow-wrap:break-word;word-wrap:break-word;word-break:break-word}.message-content .references{margin-top:var(--ast-size-5, 1.25rem)}.message-content .references ul{border-left:.2rem solid var(--ast-secondary-color, #FF732E);padding-left:var(--ast-size-5, 1.25rem);margin-top:var(--ast-size-2, .5rem)}.message-content .references .references-title{font-weight:var(--font-weight-bold, 500)}.message-content ::ng-deep p:last-child{margin-bottom:0}.message-content ::ng-deep .placeholder-glow .placeholder{animation-duration:.4s;width:12px;height:var(--ast-size-4, 1rem);vertical-align:text-bottom}.message-content ::ng-deep img{max-width:100%}.message-content ::ng-deep table{display:table;border:1px solid;border-color:var(--ast-message-table-border-color, #ccc);border-collapse:collapse;margin:0;padding:0;min-width:100%;overflow-x:auto;table-layout:fixed}.message-content ::ng-deep table tr{background-color:var(--ast-message-table-tr-bg, #f8f8f8);border:1px solid;border-color:var(--ast-message-table-tr-border-color, #ddd);padding:.35em}.message-content ::ng-deep table th,.message-content ::ng-deep table td{padding:.625em;text-align:center}.message-content ::ng-deep table th{font-size:.85em;letter-spacing:.1em;text-transform:uppercase}.message-content ::ng-deep .reference{color:var(--ast-message-reference-color, black)!important}.message-content ::ng-deep ul,.message-content ::ng-deep ol{display:flex;flex-direction:column;gap:.5rem;padding-right:2rem;margin-left:0;margin-right:0;padding-left:40px;unicode-bidi:isolate;list-style:disc}.message-content ::ng-deep p:not(:first-child){margin-top:.5rem}.message-assistant .message-content{background:var(--ast-secondary-bg, #FFF8F1)}.message-connection-error .message-content{background:var(--ast-error-bg, rgba(249, 58, 55, .2))}.message-search-warning .message-content{background:var(--ast-warning-bg, #fff1b8);color:var(--ast-message-reference-color, inherit)}.message-user .message-content{background:var(--ast-primary-bg, #f2f8fe);font-weight:var(--ast-user-font-weight, var(--font-weight-bold, 500))}.message-user .message-content p{white-space:pre-line}.message-suggestion .message-content{background:var(--ast-input-bg, #F8F8F8);font-weight:var(--ast-user-font-weight, var(--font-weight-bold, 500));transition:background-color .5s ease,color .5s ease}.message-suggestion .message-content:hover{background:var(--ast-primary-bg, #f2f8fe);color:var(--ast-primary-color, #005DA7)}.message-suggestion .message-content p{white-space:pre-line}.message-suggestion .suggested-action{cursor:pointer}.message-suggestion .suggested-action+.suggested-action{margin-top:var(--ast-size-2, .5rem)}.sq-chat-message-actions{position:absolute;bottom:calc(0rem - var(--ast-size-5, 1.25rem));display:flex;z-index:999}.sq-chat-message-actions button{font-size:.75rem;color:var(--ast-action-buttons-color, #212529)}.sq-chat-message-actions button:hover{color:var(--ast-action-buttons-hover-color, var(--ast-primary-color, #005DA7))}.message-icon{margin-top:var(--ast-size-3, .75rem);margin-right:var(--ast-size-4, 1rem)}.connection-error{height:var(--sq-size);width:var(--sq-size);color:var(--ast-error-color, rgba(249, 58, 55, .7))}.search-warning{height:var(--sq-size);width:var(--sq-size);color:var(--ast-warning-color, #fed86f)}.step-success{color:var(--ast-primary-color, #005DA7)}.step-ongoing{color:var(--ast-secondary-color, #FF732E)}.step-error{color:var(--ast-error-color, rgba(249, 58, 55, .7))}.bounce{animation:bounce 2s ease}@keyframes bounce{10%{transform:translateY(0)}20%{transform:translateY(-15%)}30%{transform:translateY(0)}35%{transform:translateY(-7%)}37%{transform:translateY(0)}39%{transform:translateY(-3%)}40%{transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i3.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: TooltipDirective, selector: "[sqTooltip]", inputs: ["sqTooltip", "sqTooltipData", "sqTooltipTemplate", "placement", "fallbackPlacements", "delay", "hoverableTooltip", "tooltipClass"] }, { kind: "component", type: InitialsAvatarComponent, selector: "sq-initials-avatar", inputs: ["fullName", "size"] }, { kind: "component", type: ChatReferenceComponent, selector: "sq-chat-reference", inputs: ["reference", "attachment", "partId", "referenceMap", "images", "pages"], outputs: ["openDocument", "openPreview"] }, { kind: "component", type: ChartComponent, selector: "sq-assistant-chart", inputs: ["rawChartData"] }, { kind: "pipe", type: MessageContentPipe, name: "messageContent" }, { kind: "component", type: InlineImageReferenceComponent, selector: "InlineImageReference", inputs: ["id", "ref"], outputs: ["openPreview", "openDocument", "openModal"] }, { kind: "component", type: InlinePageReferenceComponent, selector: "InlinePageReference", inputs: ["id", "ref"], outputs: ["openPreview", "openDocument", "openModal"] }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }, { kind: "component", type: SmartRendererComponent, selector: "SmartRenderer", inputs: ["message", "context"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
189
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: ChatMessageComponent, isStandalone: true, selector: "sq-chat-message", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: false, isRequired: false, transformFunction: null }, conversation: { classPropertyName: "conversation", publicName: "conversation", isSignal: false, isRequired: false, transformFunction: null }, suggestedActions: { classPropertyName: "suggestedActions", publicName: "suggestedActions", isSignal: false, isRequired: false, transformFunction: null }, assistantMessageIcon: { classPropertyName: "assistantMessageIcon", publicName: "assistantMessageIcon", isSignal: false, isRequired: false, transformFunction: null }, userMessageIcon: { classPropertyName: "userMessageIcon", publicName: "userMessageIcon", isSignal: false, isRequired: false, transformFunction: null }, connectionErrorMessageIcon: { classPropertyName: "connectionErrorMessageIcon", publicName: "connectionErrorMessageIcon", isSignal: false, isRequired: false, transformFunction: null }, searchWarningMessageIcon: { classPropertyName: "searchWarningMessageIcon", publicName: "searchWarningMessageIcon", isSignal: false, isRequired: false, transformFunction: null }, streaming: { classPropertyName: "streaming", publicName: "streaming", isSignal: false, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: false, isRequired: false, transformFunction: null }, canRegenerate: { classPropertyName: "canRegenerate", publicName: "canRegenerate", isSignal: false, isRequired: false, transformFunction: null }, canCopy: { classPropertyName: "canCopy", publicName: "canCopy", isSignal: false, isRequired: false, transformFunction: null }, canDebug: { classPropertyName: "canDebug", publicName: "canDebug", isSignal: false, isRequired: false, transformFunction: null }, canLike: { classPropertyName: "canLike", publicName: "canLike", isSignal: false, isRequired: false, transformFunction: null }, canDislike: { classPropertyName: "canDislike", publicName: "canDislike", isSignal: false, isRequired: false, transformFunction: null }, collapseReferences: { classPropertyName: "collapseReferences", publicName: "collapseReferences", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { openDocument: "openDocument", openPreview: "openPreview", suggestAction: "suggestAction", edit: "edit", copy: "copy", regenerate: "regenerate", like: "like", dislike: "dislike", debug: "debug" }, providers: [provideTranslocoScope('chat-message')], usesOnChanges: true, ngImport: i0, template: "<!-- Message icon -->\n<span class=\"message-icon\" [title]=\"message?.role\">\n <i class=\"d-block\" [style.width.px]=\"iconSize\" *ngIf=\"!message\"></i>\n <ng-container [ngSwitch]=\"message?.role\">\n <!-- For 'assistant' -->\n <i *ngSwitchCase=\"'assistant'\" [ngClass]=\"assistantMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n\n <!-- For 'user' -->\n <ng-container *ngSwitchCase=\"'user'\">\n <i *ngIf=\"!!userMessageIcon; else initialsAvatar\" [ngClass]=\"userMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n <ng-template #initialsAvatar>\n <sq-initials-avatar [fullName]=\"name\"></sq-initials-avatar>\n </ng-template>\n </ng-container>\n\n <!-- For 'connection-error' -->\n <ng-container *ngSwitchCase=\"'connection-error'\">\n <i *ngIf=\"!!connectionErrorMessageIcon; else defaultErrorIcon\" [ngClass]=\"connectionErrorMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n <ng-template #defaultErrorIcon>\n <svg [style.--sq-size.px]=\"iconSize\" class=\"connection-error\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <path fill=\"currentColor\" d=\"M17.1 292c-12.9-22.3-12.9-49.7 0-72L105.4 67.1c12.9-22.3 36.6-36 62.4-36l176.6 0c25.7 0 49.5 13.7 62.4 36L494.9 220c12.9 22.3 12.9 49.7 0 72L406.6 444.9c-12.9 22.3-36.6 36-62.4 36l-176.6 0c-25.7 0-49.5-13.7-62.4-36L17.1 292zM256 128c-13.3 0-24 10.7-24 24l0 112c0 13.3 10.7 24 24 24s24-10.7 24-24l0-112c0-13.3-10.7-24-24-24zm32 224a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z\"/>\n </svg>\n </ng-template>\n </ng-container>\n\n <!-- For 'search-warning' -->\n <ng-container *ngSwitchCase=\"'search-warning'\">\n <i *ngIf=\"!!searchWarningMessageIcon; else defaultWarningIcon\" [ngClass]=\"searchWarningMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n <ng-template #defaultWarningIcon>\n <svg [style.--sq-size.px]=\"iconSize\" class=\"search-warning\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 384 512\">\n <path fill=\"currentColor\" d=\"M272 384c9.6-31.9 29.5-59.1 49.2-86.2c0 0 0 0 0 0c5.2-7.1 10.4-14.2 15.4-21.4c19.8-28.5 31.4-63 31.4-100.3C368 78.8 289.2 0 192 0S16 78.8 16 176c0 37.3 11.6 71.9 31.4 100.3c5 7.2 10.2 14.3 15.4 21.4c0 0 0 0 0 0c19.8 27.1 39.7 54.4 49.2 86.2l160 0zM192 512c44.2 0 80-35.8 80-80l0-16-160 0 0 16c0 44.2 35.8 80 80 80zm0-448c13.3 0 24 10.7 24 24l0 112c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-112c0-13.3 10.7-24 24-24zM160 288a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z\"/>\n </svg>\n </ng-template>\n </ng-container>\n </ng-container>\n</span>\n\n<!-- Message body -->\n<div class=\"flex-grow-1 position-relative relative\" style=\"min-width: 0;\" [ngClass]=\"'message-'+message.role\">\n\n <!-- Progress steps -->\n <div *ngIf=\"message.additionalProperties.$progress as progress\" class=\"small ms-3 mb-2\">\n <details role=\"button\" class=\"select-none\" [open]=\"!collapseProgress\">\n <summary class=\"text-muted\">\n {{ 'chatMessage.viewProgress' | transloco }}\n </summary>\n <ul class=\"list-unstyled\">\n <li *ngFor=\"let step of progress\">\n <i class=\"fas fa-fw fa-check text-success\" *ngIf=\"step.done\"></i>\n <i class=\"fas fa-spinner fa-pulse step-ongoing\" *ngIf=\"!step.done && streaming\"></i>\n <i class=\"fa-solid fa-ban step-error\" *ngIf=\"!step.done && !streaming\"></i>\n <span class=\"ms-2 fw-bold\">{{step.title}}</span>\n <span *ngIf=\"step.content\" [innerHTML]=\"': ' + step.content\"></span>\n </li>\n </ul>\n </details>\n </div>\n\n <!-- Message content -->\n <div class=\"message-content\" *ngIf=\"message.content\">\n\n <!-- Custom rendering for WPS, to be remove with https://sinequa.atlassian.net/browse/ES-23710 -->\n <div *ngIf=\"message?.role === 'assistant' && message.messageType === 'CHART'\">\n <sq-assistant-chart [rawChartData]=\"message.content\"></sq-assistant-chart>\n </div>\n\n <!-- This section is responsible for customizing the template nodes used in the application.\n Template nodes are predefined structures that serve as blueprints for creating/customizing dynamic content -->\n\n\n @if(message?.role === 'assistant' && message.messageType !== 'CHART') {\n <SmartRenderer\n [message]=\"message.content | messageContent\"\n [context]=\"{\n getEmbeddedPageReference: getEmbeddedPageReference.bind(this),\n getEmbeddedImageReference: getEmbeddedImageReference.bind(this),\n referencesMap: referenceMap,\n references: processReferences.bind(this),\n rank: id()\n }\">\n </SmartRenderer>\n }\n\n <p *ngIf=\"message?.role === 'user' || message?.role === 'search-warning' || message?.role === 'connection-error'\">{{ message.content | messageContent }}</p>\n\n <!-- List of reference, if any -->\n @let referencesArray = references();\n @if (referencesArray?.length > 0 || imageReferencesMap?.size > 0 || pageReferencesMap?.size > 0) {\n <div class=\"references\">\n <details role=\"button\" class=\"select-none\" [open]=\"!collapseReferences\">\n <summary class=\"references-title\">{{ 'chatMessage.references' | transloco }}</summary>\n <ul>\n @for (reference of referencesArray; track $index) {\n @let attachment = referenceMap.get(reference);\n <!-- Only display the reference when the key is a integer not a decimal -->\n @if(attachment) {\n <li class=\"text-truncate\">\n <sq-chat-reference\n [class.expanded]=\"attachment?.$expanded\"\n [attachment]=\"attachment\"\n [reference]=\"reference\"\n [referenceMap]=\"referenceMap\"\n [images]=\"Array.from(imageReferencesMap.keys())\"\n [pages]=\"Array.from(pageReferencesMap.keys())\"\n (openPreview)=\"openAttachmentPreview($event)\"\n (openDocument)=\"openOriginalAttachment($event)\">\n </sq-chat-reference>\n </li>\n }\n }\n </ul>\n </details>\n </div>\n }\n </div>\n\n <!-- Edit / Regenerate floating actions -->\n <div class=\"sq-chat-message-actions\" *ngIf=\"message\">\n <!-- Common action buttons for \"user\" & \"assistant\" message -->\n <button class=\"btn btn-sm\" *ngIf=\"canCopy\" [sqTooltip]=\"'chatMessage.copyText' | transloco\" (click)=\"copyMessage(message)\">\n <i class=\"far fa-clipboard\"></i>\n </button>\n <!-- Action buttons for \"user\" message -->\n <button class=\"btn btn-sm\" *ngIf=\"canEdit\" [sqTooltip]=\"'chatMessage.editMessage' | transloco\" (click)=\"edit.emit(message)\">\n <i class=\"fas fa-edit\"></i>\n </button>\n <!-- Action buttons for \"assistant\" message -->\n <button class=\"btn btn-sm\" [class.bounce]=\"message.additionalProperties.$liked\" *ngIf=\"canLike\" [sqTooltip]=\"'chatMessage.likeAnswer' | transloco\" (click)=\"like.emit()\">\n <i *ngIf=\"!message.additionalProperties.$liked\" class=\"far fa-thumbs-up \"></i>\n <i *ngIf=\"message.additionalProperties.$liked\" class=\"fas fa-thumbs-up\"></i>\n </button>\n <button class=\"btn btn-sm\" [class.bounce]=\"message.additionalProperties.$disliked\" *ngIf=\"canDislike\" [sqTooltip]=\"'chatMessage.reportIssue' | transloco\" (click)=\"dislike.emit()\">\n <i *ngIf=\"!message.additionalProperties.$disliked\" class=\"far fa-thumbs-down \"></i>\n <i *ngIf=\"message.additionalProperties.$disliked\" class=\"fas fa-thumbs-down\"></i>\n </button>\n <button class=\"btn btn-sm\" *ngIf=\"canRegenerate\" [sqTooltip]=\"'chatMessage.regenerateResponse' | transloco\" (click)=\"regenerate.emit(message)\">\n <i class=\"fas fa-sync-alt\"></i>\n </button>\n <button class=\"btn btn-sm\" *ngIf=\"canDebug\" [sqTooltip]=\"'chatMessage.showLogInformation' | transloco\" (click)=\"debug.emit(message);\">\n <i class=\"far fa-list-alt\"></i>\n </button>\n </div>\n\n <!-- List of suggested actions, if any -->\n <div *ngIf=\"suggestedActions\" class=\"mt-2 message-suggestion\">\n <div class=\"suggested-action\" *ngFor=\"let suggestedAction of suggestedActions\" (click)=\"suggestAction.emit(suggestedAction)\">\n <div class=\"message-icon\" [style.width.px]=\"iconSize\"></div>\n <div class=\"message-content\">\n <p><i class=\"fas {{suggestedAction.type === 'Submit' ? 'fa-paper-plane' : 'fa-comment-medical'}} me-1\"></i> {{suggestedAction.content}}</p>\n </div>\n </div>\n </div>\n\n</div>\n", styles: [".ast-primary{color:var(--ast-primary-color, #005DA7);background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover{background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover:hover{color:var(--ast-primary-color, #005DA7)}.ast-secondary{color:var(--ast-secondary-color, #FF732E);background-color:var(--ast-secondary-bg, #FFF8F1)}.ast-error{background-color:var(--ast-error-bg, rgba(249, 58, 55, .2));color:var(--ast-action-buttons-color, inherit)}.ast-error:hover{color:var(--ast-error-color, rgba(249, 58, 55, .7))}.ast-btn{border:0;text-align:left;padding-top:.5rem;padding-bottom:.5rem;display:flex;align-items:center}.dark{--ast-primary-bg: #0d0701;--ast-primary-color: #008cd1;--ast-secondary-bg: #00070e;--ast-secondary-color: #ffa258;--ast-input-bg: #070707;--ast-input-color: rgba(222, 218, 218, .75);--ast-muted-color: rgba(222, 218, 218, .75);--ast-saved-chat-hover-background: #262421;--ast-uploaded-doc-hover-background: #262421;--ast-message-table-border-color: #333333;--ast-message-table-tr-bg: #070707;--ast-message-table-tr-border-color: #222222;--ast-reference-icon-color: white;--ast-reference-icon-active-color: black;--ast-reference-passages-color: white;--ast-reference-expanded-hover-bg: #262421;--ast-message-reference-color: black;--ast-action-buttons-color: white;--ast-action-buttons-hover-color: #6dbee6;--ast-report-bg: #070707}:host{display:flex}:host:not(:hover):not(.last-message) .sq-chat-message-actions{visibility:hidden}.message-content{padding:var(--ast-message-padding, var(--ast-size-3, .75rem));border-radius:var(--ast-message-border-radius, var(--ast-size-4, 1rem));display:inline-block;max-width:100%;overflow-wrap:break-word;word-wrap:break-word;word-break:break-word}.message-content .references{margin-top:var(--ast-size-5, 1.25rem)}.message-content .references ul{border-left:.2rem solid var(--ast-secondary-color, #FF732E);padding-left:var(--ast-size-5, 1.25rem);margin-top:var(--ast-size-2, .5rem)}.message-content .references .references-title{font-weight:var(--font-weight-bold, 500)}.message-content ::ng-deep p:last-child{margin-bottom:0}.message-content ::ng-deep .placeholder-glow .placeholder{animation-duration:.4s;width:12px;height:var(--ast-size-4, 1rem);vertical-align:text-bottom}.message-content ::ng-deep img{max-width:100%}.message-content ::ng-deep table{display:table;border:1px solid;border-color:var(--ast-message-table-border-color, #ccc);border-collapse:collapse;margin:0;padding:0;min-width:100%;overflow-x:auto;table-layout:fixed}.message-content ::ng-deep table tr{background-color:var(--ast-message-table-tr-bg, #f8f8f8);border:1px solid;border-color:var(--ast-message-table-tr-border-color, #ddd);padding:.35em}.message-content ::ng-deep table th,.message-content ::ng-deep table td{padding:.625em;text-align:center}.message-content ::ng-deep table th{font-size:.85em;letter-spacing:.1em;text-transform:uppercase}.message-content ::ng-deep .reference{color:var(--ast-message-reference-color, black)!important}.message-content ::ng-deep ul,.message-content ::ng-deep ol{display:flex;flex-direction:column;gap:.5rem;padding-right:2rem;margin-left:0;margin-right:0;padding-left:40px;unicode-bidi:isolate;list-style:disc}.message-content ::ng-deep p:not(:first-child){margin-top:.5rem}.message-assistant .message-content{background:var(--ast-secondary-bg, #FFF8F1)}.message-connection-error .message-content{background:var(--ast-error-bg, rgba(249, 58, 55, .2))}.message-search-warning .message-content{background:var(--ast-warning-bg, #fff1b8);color:var(--ast-message-reference-color, inherit)}.message-user .message-content{background:var(--ast-primary-bg, #f2f8fe);font-weight:var(--ast-user-font-weight, var(--font-weight-bold, 500))}.message-user .message-content p{white-space:pre-line}.message-suggestion .message-content{background:var(--ast-input-bg, #F8F8F8);font-weight:var(--ast-user-font-weight, var(--font-weight-bold, 500));transition:background-color .5s ease,color .5s ease}.message-suggestion .message-content:hover{background:var(--ast-primary-bg, #f2f8fe);color:var(--ast-primary-color, #005DA7)}.message-suggestion .message-content p{white-space:pre-line}.message-suggestion .suggested-action{cursor:pointer}.message-suggestion .suggested-action+.suggested-action{margin-top:var(--ast-size-2, .5rem)}.sq-chat-message-actions{position:absolute;bottom:calc(0rem - var(--ast-size-5, 1.25rem));display:flex;z-index:999}.sq-chat-message-actions button{font-size:.75rem;color:var(--ast-action-buttons-color, #212529)}.sq-chat-message-actions button:hover{color:var(--ast-action-buttons-hover-color, var(--ast-primary-color, #005DA7))}.message-icon{margin-top:var(--ast-size-3, .75rem);margin-right:var(--ast-size-4, 1rem)}.connection-error{height:var(--sq-size);width:var(--sq-size);color:var(--ast-error-color, rgba(249, 58, 55, .7))}.search-warning{height:var(--sq-size);width:var(--sq-size);color:var(--ast-warning-color, #fed86f)}.step-success{color:var(--ast-primary-color, #005DA7)}.step-ongoing{color:var(--ast-secondary-color, #FF732E)}.step-error{color:var(--ast-error-color, rgba(249, 58, 55, .7))}.bounce{animation:bounce 2s ease}@keyframes bounce{10%{transform:translateY(0)}20%{transform:translateY(-15%)}30%{transform:translateY(0)}35%{transform:translateY(-7%)}37%{transform:translateY(0)}39%{transform:translateY(-3%)}40%{transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i3.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: TooltipDirective, selector: "[sqTooltip]", inputs: ["sqTooltip", "sqTooltipData", "sqTooltipTemplate", "placement", "fallbackPlacements", "delay", "hoverableTooltip", "tooltipClass"] }, { kind: "component", type: InitialsAvatarComponent, selector: "sq-initials-avatar", inputs: ["fullName", "size"] }, { kind: "component", type: ChatReferenceComponent, selector: "sq-chat-reference", inputs: ["reference", "attachment", "partId", "referenceMap", "images", "pages"], outputs: ["openDocument", "openPreview"] }, { kind: "component", type: ChartComponent, selector: "sq-assistant-chart", inputs: ["rawChartData"] }, { kind: "pipe", type: MessageContentPipe, name: "messageContent" }, { kind: "pipe", type: TranslocoPipe, name: "transloco" }, { kind: "component", type: SmartRendererComponent, selector: "SmartRenderer", inputs: ["message", "context"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
185
190
  }
186
191
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ChatMessageComponent, decorators: [{
187
192
  type: Component,
@@ -192,11 +197,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
192
197
  ChatReferenceComponent,
193
198
  ChartComponent,
194
199
  MessageContentPipe,
195
- InlineImageReferenceComponent,
196
- InlinePageReferenceComponent,
197
200
  TranslocoPipe,
198
201
  SmartRendererComponent
199
- ], providers: [provideTranslocoScope('chat-message')], template: "<!-- Message icon -->\n<span class=\"message-icon\" [title]=\"message?.role\">\n <i class=\"d-block\" [style.width.px]=\"iconSize\" *ngIf=\"!message\"></i>\n <ng-container [ngSwitch]=\"message?.role\">\n <!-- For 'assistant' -->\n <i *ngSwitchCase=\"'assistant'\" [ngClass]=\"assistantMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n\n <!-- For 'user' -->\n <ng-container *ngSwitchCase=\"'user'\">\n <i *ngIf=\"!!userMessageIcon; else initialsAvatar\" [ngClass]=\"userMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n <ng-template #initialsAvatar>\n <sq-initials-avatar [fullName]=\"name\"></sq-initials-avatar>\n </ng-template>\n </ng-container>\n\n <!-- For 'connection-error' -->\n <ng-container *ngSwitchCase=\"'connection-error'\">\n <i *ngIf=\"!!connectionErrorMessageIcon; else defaultErrorIcon\" [ngClass]=\"connectionErrorMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n <ng-template #defaultErrorIcon>\n <svg [style.--sq-size.px]=\"iconSize\" class=\"connection-error\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <path fill=\"currentColor\" d=\"M17.1 292c-12.9-22.3-12.9-49.7 0-72L105.4 67.1c12.9-22.3 36.6-36 62.4-36l176.6 0c25.7 0 49.5 13.7 62.4 36L494.9 220c12.9 22.3 12.9 49.7 0 72L406.6 444.9c-12.9 22.3-36.6 36-62.4 36l-176.6 0c-25.7 0-49.5-13.7-62.4-36L17.1 292zM256 128c-13.3 0-24 10.7-24 24l0 112c0 13.3 10.7 24 24 24s24-10.7 24-24l0-112c0-13.3-10.7-24-24-24zm32 224a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z\"/>\n </svg>\n </ng-template>\n </ng-container>\n\n <!-- For 'search-warning' -->\n <ng-container *ngSwitchCase=\"'search-warning'\">\n <i *ngIf=\"!!searchWarningMessageIcon; else defaultWarningIcon\" [ngClass]=\"searchWarningMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n <ng-template #defaultWarningIcon>\n <svg [style.--sq-size.px]=\"iconSize\" class=\"search-warning\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 384 512\">\n <path fill=\"currentColor\" d=\"M272 384c9.6-31.9 29.5-59.1 49.2-86.2c0 0 0 0 0 0c5.2-7.1 10.4-14.2 15.4-21.4c19.8-28.5 31.4-63 31.4-100.3C368 78.8 289.2 0 192 0S16 78.8 16 176c0 37.3 11.6 71.9 31.4 100.3c5 7.2 10.2 14.3 15.4 21.4c0 0 0 0 0 0c19.8 27.1 39.7 54.4 49.2 86.2l160 0zM192 512c44.2 0 80-35.8 80-80l0-16-160 0 0 16c0 44.2 35.8 80 80 80zm0-448c13.3 0 24 10.7 24 24l0 112c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-112c0-13.3 10.7-24 24-24zM160 288a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z\"/>\n </svg>\n </ng-template>\n </ng-container>\n </ng-container>\n</span>\n\n<!-- Message body -->\n<div class=\"flex-grow-1 position-relative relative\" style=\"min-width: 0;\" [ngClass]=\"'message-'+message.role\">\n\n <!-- Progress steps -->\n <div *ngIf=\"message.additionalProperties.$progress as progress\" class=\"small ms-3 mb-2\">\n <details role=\"button\" class=\"select-none\" [open]=\"!collapseProgress\">\n <summary class=\"text-muted\">\n {{ 'chatMessage.viewProgress' | transloco }}\n </summary>\n <ul class=\"list-unstyled\">\n <li *ngFor=\"let step of progress\">\n <i class=\"fas fa-fw fa-check text-success\" *ngIf=\"step.done\"></i>\n <i class=\"fas fa-spinner fa-pulse step-ongoing\" *ngIf=\"!step.done && streaming\"></i>\n <i class=\"fa-solid fa-ban step-error\" *ngIf=\"!step.done && !streaming\"></i>\n <span class=\"ms-2 fw-bold\">{{step.title}}</span>\n <span *ngIf=\"step.content\" [innerHTML]=\"': ' + step.content\"></span>\n </li>\n </ul>\n </details>\n </div>\n\n <!-- Message content -->\n <div class=\"message-content\" *ngIf=\"message.content\">\n\n <!-- Custom rendering for WPS, to be remove with https://sinequa.atlassian.net/browse/ES-23710 -->\n <div *ngIf=\"message?.role === 'assistant' && message.messageType === 'CHART'\">\n <sq-assistant-chart [rawChartData]=\"message.content\"></sq-assistant-chart>\n </div>\n\n <!-- This section is responsible for customizing the template nodes used in the application.\n Template nodes are predefined structures that serve as blueprints for creating/customizing dynamic content -->\n\n\n @if(message?.role === 'assistant' && message.messageType !== 'CHART') {\n <SmartRenderer\n [message]=\"message.content | messageContent\"\n [context]=\"{\n getEmbeddedPageReference: getEmbeddedPageReference.bind(this),\n getEmbeddedImageReference: getEmbeddedImageReference.bind(this),\n referencesMap: referenceMap,\n references: processReferences.bind(this),\n rank: id()\n }\">\n </SmartRenderer>\n }\n\n <p *ngIf=\"message?.role === 'user'\">{{ message.content | messageContent }}</p>\n\n <!-- List of reference, if any -->\n @let referencesArray = references();\n @if (referencesArray?.length > 0 || imageReferencesMap?.size > 0 || pageReferencesMap?.size > 0) {\n <div class=\"references\">\n <details role=\"button\" class=\"select-none\" [open]=\"!collapseReferences\">\n <summary class=\"references-title\">{{ 'chatMessage.references' | transloco }}</summary>\n <ul>\n @for (reference of referencesArray; track $index) {\n @let attachment = referenceMap.get(reference);\n <!-- Only display the reference when the key is a integer not a decimal -->\n @if(attachment) {\n <li class=\"text-truncate\">\n <sq-chat-reference\n [class.expanded]=\"attachment?.$expanded\"\n [attachment]=\"attachment\"\n [reference]=\"reference\"\n [referenceMap]=\"referenceMap\"\n [images]=\"Array.from(imageReferencesMap.keys())\"\n [pages]=\"Array.from(pageReferencesMap.keys())\"\n (openPreview)=\"openAttachmentPreview($event)\"\n (openDocument)=\"openOriginalAttachment($event)\">\n </sq-chat-reference>\n </li>\n }\n }\n </ul>\n </details>\n </div>\n }\n </div>\n\n <!-- Edit / Regenerate floating actions -->\n <div class=\"sq-chat-message-actions\" *ngIf=\"message\">\n <!-- Common action buttons for \"user\" & \"assistant\" message -->\n <button class=\"btn btn-sm\" *ngIf=\"canCopy\" [sqTooltip]=\"'chatMessage.copyText' | transloco\" (click)=\"copyMessage(message)\">\n <i class=\"far fa-clipboard\"></i>\n </button>\n <!-- Action buttons for \"user\" message -->\n <button class=\"btn btn-sm\" *ngIf=\"canEdit\" [sqTooltip]=\"'chatMessage.editMessage' | transloco\" (click)=\"edit.emit(message)\">\n <i class=\"fas fa-edit\"></i>\n </button>\n <!-- Action buttons for \"assistant\" message -->\n <button class=\"btn btn-sm\" [class.bounce]=\"message.additionalProperties.$liked\" *ngIf=\"canLike\" [sqTooltip]=\"'chatMessage.likeAnswer' | transloco\" (click)=\"like.emit()\">\n <i *ngIf=\"!message.additionalProperties.$liked\" class=\"far fa-thumbs-up \"></i>\n <i *ngIf=\"message.additionalProperties.$liked\" class=\"fas fa-thumbs-up\"></i>\n </button>\n <button class=\"btn btn-sm\" [class.bounce]=\"message.additionalProperties.$disliked\" *ngIf=\"canDislike\" [sqTooltip]=\"'chatMessage.reportIssue' | transloco\" (click)=\"dislike.emit()\">\n <i *ngIf=\"!message.additionalProperties.$disliked\" class=\"far fa-thumbs-down \"></i>\n <i *ngIf=\"message.additionalProperties.$disliked\" class=\"fas fa-thumbs-down\"></i>\n </button>\n <button class=\"btn btn-sm\" *ngIf=\"canRegenerate\" [sqTooltip]=\"'chatMessage.regenerateResponse' | transloco\" (click)=\"regenerate.emit(message)\">\n <i class=\"fas fa-sync-alt\"></i>\n </button>\n <button class=\"btn btn-sm\" *ngIf=\"canDebug\" [sqTooltip]=\"'chatMessage.showLogInformation' | transloco\" (click)=\"debug.emit(message);\">\n <i class=\"far fa-list-alt\"></i>\n </button>\n </div>\n\n <!-- List of suggested actions, if any -->\n <div *ngIf=\"suggestedActions\" class=\"mt-2 message-suggestion\">\n <div class=\"suggested-action\" *ngFor=\"let suggestedAction of suggestedActions\" (click)=\"suggestAction.emit(suggestedAction)\">\n <div class=\"message-icon\" [style.width.px]=\"iconSize\"></div>\n <div class=\"message-content\">\n <p><i class=\"fas fa-clipboard-question\"></i> {{suggestedAction.content}}</p>\n </div>\n </div>\n </div>\n\n <ng-template #imageTooltipTpl let-ref>\n <InlineImageReference\n style=\"max-width: 30vw;\"\n [id]=\"ref.id\"\n [ref]=\"ref.obj\"\n (openPreview)=\"openAttachmentPreview($event)\"\n (openDocument)=\"openOriginalAttachment($event, $event.$partId)\"\n (openModal)=\"hideTooltip()\"\n />\n </ng-template>\n\n <ng-template #pageTooltipTpl let-ref>\n <InlinePageReference\n style=\"max-width: 30vw;\"\n [id]=\"ref.id\"\n [ref]=\"ref.obj\"\n (openPreview)=\"openAttachmentPreview($event)\"\n (openDocument)=\"openOriginalAttachment($event, $event.$partId)\"\n (openModal)=\"hideTooltip()\"\n />\n </ng-template>\n\n <ng-template #tooltipTpl let-ref>\n <sq-chat-reference\n *ngIf=\"!hiddenTooltip\"\n class=\"expanded\"\n [attachment]=\"ref\"\n [reference]=\"ref.contextId\"\n [partId]=\"ref.$partId\"\n (openPreview)=\"openAttachmentPreview($event, ref.$partId)\"\n (openDocument)=\"openOriginalAttachment($event, ref.$partId)\">\n </sq-chat-reference>\n </ng-template>\n\n</div>\n", styles: [".ast-primary{color:var(--ast-primary-color, #005DA7);background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover{background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover:hover{color:var(--ast-primary-color, #005DA7)}.ast-secondary{color:var(--ast-secondary-color, #FF732E);background-color:var(--ast-secondary-bg, #FFF8F1)}.ast-error{background-color:var(--ast-error-bg, rgba(249, 58, 55, .2));color:var(--ast-action-buttons-color, inherit)}.ast-error:hover{color:var(--ast-error-color, rgba(249, 58, 55, .7))}.ast-btn{border:0;text-align:left;padding-top:.5rem;padding-bottom:.5rem;display:flex;align-items:center}.dark{--ast-primary-bg: #0d0701;--ast-primary-color: #008cd1;--ast-secondary-bg: #00070e;--ast-secondary-color: #ffa258;--ast-input-bg: #070707;--ast-input-color: rgba(222, 218, 218, .75);--ast-muted-color: rgba(222, 218, 218, .75);--ast-saved-chat-hover-background: #262421;--ast-uploaded-doc-hover-background: #262421;--ast-message-table-border-color: #333333;--ast-message-table-tr-bg: #070707;--ast-message-table-tr-border-color: #222222;--ast-reference-icon-color: white;--ast-reference-icon-active-color: black;--ast-reference-passages-color: white;--ast-reference-expanded-hover-bg: #262421;--ast-message-reference-color: black;--ast-action-buttons-color: white;--ast-action-buttons-hover-color: #6dbee6;--ast-report-bg: #070707}:host{display:flex}:host:not(:hover):not(.last-message) .sq-chat-message-actions{visibility:hidden}.message-content{padding:var(--ast-message-padding, var(--ast-size-3, .75rem));border-radius:var(--ast-message-border-radius, var(--ast-size-4, 1rem));display:inline-block;max-width:100%;overflow-wrap:break-word;word-wrap:break-word;word-break:break-word}.message-content .references{margin-top:var(--ast-size-5, 1.25rem)}.message-content .references ul{border-left:.2rem solid var(--ast-secondary-color, #FF732E);padding-left:var(--ast-size-5, 1.25rem);margin-top:var(--ast-size-2, .5rem)}.message-content .references .references-title{font-weight:var(--font-weight-bold, 500)}.message-content ::ng-deep p:last-child{margin-bottom:0}.message-content ::ng-deep .placeholder-glow .placeholder{animation-duration:.4s;width:12px;height:var(--ast-size-4, 1rem);vertical-align:text-bottom}.message-content ::ng-deep img{max-width:100%}.message-content ::ng-deep table{display:table;border:1px solid;border-color:var(--ast-message-table-border-color, #ccc);border-collapse:collapse;margin:0;padding:0;min-width:100%;overflow-x:auto;table-layout:fixed}.message-content ::ng-deep table tr{background-color:var(--ast-message-table-tr-bg, #f8f8f8);border:1px solid;border-color:var(--ast-message-table-tr-border-color, #ddd);padding:.35em}.message-content ::ng-deep table th,.message-content ::ng-deep table td{padding:.625em;text-align:center}.message-content ::ng-deep table th{font-size:.85em;letter-spacing:.1em;text-transform:uppercase}.message-content ::ng-deep .reference{color:var(--ast-message-reference-color, black)!important}.message-content ::ng-deep ul,.message-content ::ng-deep ol{display:flex;flex-direction:column;gap:.5rem;padding-right:2rem;margin-left:0;margin-right:0;padding-left:40px;unicode-bidi:isolate;list-style:disc}.message-content ::ng-deep p:not(:first-child){margin-top:.5rem}.message-assistant .message-content{background:var(--ast-secondary-bg, #FFF8F1)}.message-connection-error .message-content{background:var(--ast-error-bg, rgba(249, 58, 55, .2))}.message-search-warning .message-content{background:var(--ast-warning-bg, #fff1b8);color:var(--ast-message-reference-color, inherit)}.message-user .message-content{background:var(--ast-primary-bg, #f2f8fe);font-weight:var(--ast-user-font-weight, var(--font-weight-bold, 500))}.message-user .message-content p{white-space:pre-line}.message-suggestion .message-content{background:var(--ast-input-bg, #F8F8F8);font-weight:var(--ast-user-font-weight, var(--font-weight-bold, 500));transition:background-color .5s ease,color .5s ease}.message-suggestion .message-content:hover{background:var(--ast-primary-bg, #f2f8fe);color:var(--ast-primary-color, #005DA7)}.message-suggestion .message-content p{white-space:pre-line}.message-suggestion .suggested-action{cursor:pointer}.message-suggestion .suggested-action+.suggested-action{margin-top:var(--ast-size-2, .5rem)}.sq-chat-message-actions{position:absolute;bottom:calc(0rem - var(--ast-size-5, 1.25rem));display:flex;z-index:999}.sq-chat-message-actions button{font-size:.75rem;color:var(--ast-action-buttons-color, #212529)}.sq-chat-message-actions button:hover{color:var(--ast-action-buttons-hover-color, var(--ast-primary-color, #005DA7))}.message-icon{margin-top:var(--ast-size-3, .75rem);margin-right:var(--ast-size-4, 1rem)}.connection-error{height:var(--sq-size);width:var(--sq-size);color:var(--ast-error-color, rgba(249, 58, 55, .7))}.search-warning{height:var(--sq-size);width:var(--sq-size);color:var(--ast-warning-color, #fed86f)}.step-success{color:var(--ast-primary-color, #005DA7)}.step-ongoing{color:var(--ast-secondary-color, #FF732E)}.step-error{color:var(--ast-error-color, rgba(249, 58, 55, .7))}.bounce{animation:bounce 2s ease}@keyframes bounce{10%{transform:translateY(0)}20%{transform:translateY(-15%)}30%{transform:translateY(0)}35%{transform:translateY(-7%)}37%{transform:translateY(0)}39%{transform:translateY(-3%)}40%{transform:translateY(0)}}\n"] }]
202
+ ], providers: [provideTranslocoScope('chat-message')], template: "<!-- Message icon -->\n<span class=\"message-icon\" [title]=\"message?.role\">\n <i class=\"d-block\" [style.width.px]=\"iconSize\" *ngIf=\"!message\"></i>\n <ng-container [ngSwitch]=\"message?.role\">\n <!-- For 'assistant' -->\n <i *ngSwitchCase=\"'assistant'\" [ngClass]=\"assistantMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n\n <!-- For 'user' -->\n <ng-container *ngSwitchCase=\"'user'\">\n <i *ngIf=\"!!userMessageIcon; else initialsAvatar\" [ngClass]=\"userMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n <ng-template #initialsAvatar>\n <sq-initials-avatar [fullName]=\"name\"></sq-initials-avatar>\n </ng-template>\n </ng-container>\n\n <!-- For 'connection-error' -->\n <ng-container *ngSwitchCase=\"'connection-error'\">\n <i *ngIf=\"!!connectionErrorMessageIcon; else defaultErrorIcon\" [ngClass]=\"connectionErrorMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n <ng-template #defaultErrorIcon>\n <svg [style.--sq-size.px]=\"iconSize\" class=\"connection-error\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <path fill=\"currentColor\" d=\"M17.1 292c-12.9-22.3-12.9-49.7 0-72L105.4 67.1c12.9-22.3 36.6-36 62.4-36l176.6 0c25.7 0 49.5 13.7 62.4 36L494.9 220c12.9 22.3 12.9 49.7 0 72L406.6 444.9c-12.9 22.3-36.6 36-62.4 36l-176.6 0c-25.7 0-49.5-13.7-62.4-36L17.1 292zM256 128c-13.3 0-24 10.7-24 24l0 112c0 13.3 10.7 24 24 24s24-10.7 24-24l0-112c0-13.3-10.7-24-24-24zm32 224a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z\"/>\n </svg>\n </ng-template>\n </ng-container>\n\n <!-- For 'search-warning' -->\n <ng-container *ngSwitchCase=\"'search-warning'\">\n <i *ngIf=\"!!searchWarningMessageIcon; else defaultWarningIcon\" [ngClass]=\"searchWarningMessageIcon\" [style.--sq-size.px]=\"iconSize\"></i>\n <ng-template #defaultWarningIcon>\n <svg [style.--sq-size.px]=\"iconSize\" class=\"search-warning\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 384 512\">\n <path fill=\"currentColor\" d=\"M272 384c9.6-31.9 29.5-59.1 49.2-86.2c0 0 0 0 0 0c5.2-7.1 10.4-14.2 15.4-21.4c19.8-28.5 31.4-63 31.4-100.3C368 78.8 289.2 0 192 0S16 78.8 16 176c0 37.3 11.6 71.9 31.4 100.3c5 7.2 10.2 14.3 15.4 21.4c0 0 0 0 0 0c19.8 27.1 39.7 54.4 49.2 86.2l160 0zM192 512c44.2 0 80-35.8 80-80l0-16-160 0 0 16c0 44.2 35.8 80 80 80zm0-448c13.3 0 24 10.7 24 24l0 112c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-112c0-13.3 10.7-24 24-24zM160 288a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z\"/>\n </svg>\n </ng-template>\n </ng-container>\n </ng-container>\n</span>\n\n<!-- Message body -->\n<div class=\"flex-grow-1 position-relative relative\" style=\"min-width: 0;\" [ngClass]=\"'message-'+message.role\">\n\n <!-- Progress steps -->\n <div *ngIf=\"message.additionalProperties.$progress as progress\" class=\"small ms-3 mb-2\">\n <details role=\"button\" class=\"select-none\" [open]=\"!collapseProgress\">\n <summary class=\"text-muted\">\n {{ 'chatMessage.viewProgress' | transloco }}\n </summary>\n <ul class=\"list-unstyled\">\n <li *ngFor=\"let step of progress\">\n <i class=\"fas fa-fw fa-check text-success\" *ngIf=\"step.done\"></i>\n <i class=\"fas fa-spinner fa-pulse step-ongoing\" *ngIf=\"!step.done && streaming\"></i>\n <i class=\"fa-solid fa-ban step-error\" *ngIf=\"!step.done && !streaming\"></i>\n <span class=\"ms-2 fw-bold\">{{step.title}}</span>\n <span *ngIf=\"step.content\" [innerHTML]=\"': ' + step.content\"></span>\n </li>\n </ul>\n </details>\n </div>\n\n <!-- Message content -->\n <div class=\"message-content\" *ngIf=\"message.content\">\n\n <!-- Custom rendering for WPS, to be remove with https://sinequa.atlassian.net/browse/ES-23710 -->\n <div *ngIf=\"message?.role === 'assistant' && message.messageType === 'CHART'\">\n <sq-assistant-chart [rawChartData]=\"message.content\"></sq-assistant-chart>\n </div>\n\n <!-- This section is responsible for customizing the template nodes used in the application.\n Template nodes are predefined structures that serve as blueprints for creating/customizing dynamic content -->\n\n\n @if(message?.role === 'assistant' && message.messageType !== 'CHART') {\n <SmartRenderer\n [message]=\"message.content | messageContent\"\n [context]=\"{\n getEmbeddedPageReference: getEmbeddedPageReference.bind(this),\n getEmbeddedImageReference: getEmbeddedImageReference.bind(this),\n referencesMap: referenceMap,\n references: processReferences.bind(this),\n rank: id()\n }\">\n </SmartRenderer>\n }\n\n <p *ngIf=\"message?.role === 'user' || message?.role === 'search-warning' || message?.role === 'connection-error'\">{{ message.content | messageContent }}</p>\n\n <!-- List of reference, if any -->\n @let referencesArray = references();\n @if (referencesArray?.length > 0 || imageReferencesMap?.size > 0 || pageReferencesMap?.size > 0) {\n <div class=\"references\">\n <details role=\"button\" class=\"select-none\" [open]=\"!collapseReferences\">\n <summary class=\"references-title\">{{ 'chatMessage.references' | transloco }}</summary>\n <ul>\n @for (reference of referencesArray; track $index) {\n @let attachment = referenceMap.get(reference);\n <!-- Only display the reference when the key is a integer not a decimal -->\n @if(attachment) {\n <li class=\"text-truncate\">\n <sq-chat-reference\n [class.expanded]=\"attachment?.$expanded\"\n [attachment]=\"attachment\"\n [reference]=\"reference\"\n [referenceMap]=\"referenceMap\"\n [images]=\"Array.from(imageReferencesMap.keys())\"\n [pages]=\"Array.from(pageReferencesMap.keys())\"\n (openPreview)=\"openAttachmentPreview($event)\"\n (openDocument)=\"openOriginalAttachment($event)\">\n </sq-chat-reference>\n </li>\n }\n }\n </ul>\n </details>\n </div>\n }\n </div>\n\n <!-- Edit / Regenerate floating actions -->\n <div class=\"sq-chat-message-actions\" *ngIf=\"message\">\n <!-- Common action buttons for \"user\" & \"assistant\" message -->\n <button class=\"btn btn-sm\" *ngIf=\"canCopy\" [sqTooltip]=\"'chatMessage.copyText' | transloco\" (click)=\"copyMessage(message)\">\n <i class=\"far fa-clipboard\"></i>\n </button>\n <!-- Action buttons for \"user\" message -->\n <button class=\"btn btn-sm\" *ngIf=\"canEdit\" [sqTooltip]=\"'chatMessage.editMessage' | transloco\" (click)=\"edit.emit(message)\">\n <i class=\"fas fa-edit\"></i>\n </button>\n <!-- Action buttons for \"assistant\" message -->\n <button class=\"btn btn-sm\" [class.bounce]=\"message.additionalProperties.$liked\" *ngIf=\"canLike\" [sqTooltip]=\"'chatMessage.likeAnswer' | transloco\" (click)=\"like.emit()\">\n <i *ngIf=\"!message.additionalProperties.$liked\" class=\"far fa-thumbs-up \"></i>\n <i *ngIf=\"message.additionalProperties.$liked\" class=\"fas fa-thumbs-up\"></i>\n </button>\n <button class=\"btn btn-sm\" [class.bounce]=\"message.additionalProperties.$disliked\" *ngIf=\"canDislike\" [sqTooltip]=\"'chatMessage.reportIssue' | transloco\" (click)=\"dislike.emit()\">\n <i *ngIf=\"!message.additionalProperties.$disliked\" class=\"far fa-thumbs-down \"></i>\n <i *ngIf=\"message.additionalProperties.$disliked\" class=\"fas fa-thumbs-down\"></i>\n </button>\n <button class=\"btn btn-sm\" *ngIf=\"canRegenerate\" [sqTooltip]=\"'chatMessage.regenerateResponse' | transloco\" (click)=\"regenerate.emit(message)\">\n <i class=\"fas fa-sync-alt\"></i>\n </button>\n <button class=\"btn btn-sm\" *ngIf=\"canDebug\" [sqTooltip]=\"'chatMessage.showLogInformation' | transloco\" (click)=\"debug.emit(message);\">\n <i class=\"far fa-list-alt\"></i>\n </button>\n </div>\n\n <!-- List of suggested actions, if any -->\n <div *ngIf=\"suggestedActions\" class=\"mt-2 message-suggestion\">\n <div class=\"suggested-action\" *ngFor=\"let suggestedAction of suggestedActions\" (click)=\"suggestAction.emit(suggestedAction)\">\n <div class=\"message-icon\" [style.width.px]=\"iconSize\"></div>\n <div class=\"message-content\">\n <p><i class=\"fas {{suggestedAction.type === 'Submit' ? 'fa-paper-plane' : 'fa-comment-medical'}} me-1\"></i> {{suggestedAction.content}}</p>\n </div>\n </div>\n </div>\n\n</div>\n", styles: [".ast-primary{color:var(--ast-primary-color, #005DA7);background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover{background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover:hover{color:var(--ast-primary-color, #005DA7)}.ast-secondary{color:var(--ast-secondary-color, #FF732E);background-color:var(--ast-secondary-bg, #FFF8F1)}.ast-error{background-color:var(--ast-error-bg, rgba(249, 58, 55, .2));color:var(--ast-action-buttons-color, inherit)}.ast-error:hover{color:var(--ast-error-color, rgba(249, 58, 55, .7))}.ast-btn{border:0;text-align:left;padding-top:.5rem;padding-bottom:.5rem;display:flex;align-items:center}.dark{--ast-primary-bg: #0d0701;--ast-primary-color: #008cd1;--ast-secondary-bg: #00070e;--ast-secondary-color: #ffa258;--ast-input-bg: #070707;--ast-input-color: rgba(222, 218, 218, .75);--ast-muted-color: rgba(222, 218, 218, .75);--ast-saved-chat-hover-background: #262421;--ast-uploaded-doc-hover-background: #262421;--ast-message-table-border-color: #333333;--ast-message-table-tr-bg: #070707;--ast-message-table-tr-border-color: #222222;--ast-reference-icon-color: white;--ast-reference-icon-active-color: black;--ast-reference-passages-color: white;--ast-reference-expanded-hover-bg: #262421;--ast-message-reference-color: black;--ast-action-buttons-color: white;--ast-action-buttons-hover-color: #6dbee6;--ast-report-bg: #070707}:host{display:flex}:host:not(:hover):not(.last-message) .sq-chat-message-actions{visibility:hidden}.message-content{padding:var(--ast-message-padding, var(--ast-size-3, .75rem));border-radius:var(--ast-message-border-radius, var(--ast-size-4, 1rem));display:inline-block;max-width:100%;overflow-wrap:break-word;word-wrap:break-word;word-break:break-word}.message-content .references{margin-top:var(--ast-size-5, 1.25rem)}.message-content .references ul{border-left:.2rem solid var(--ast-secondary-color, #FF732E);padding-left:var(--ast-size-5, 1.25rem);margin-top:var(--ast-size-2, .5rem)}.message-content .references .references-title{font-weight:var(--font-weight-bold, 500)}.message-content ::ng-deep p:last-child{margin-bottom:0}.message-content ::ng-deep .placeholder-glow .placeholder{animation-duration:.4s;width:12px;height:var(--ast-size-4, 1rem);vertical-align:text-bottom}.message-content ::ng-deep img{max-width:100%}.message-content ::ng-deep table{display:table;border:1px solid;border-color:var(--ast-message-table-border-color, #ccc);border-collapse:collapse;margin:0;padding:0;min-width:100%;overflow-x:auto;table-layout:fixed}.message-content ::ng-deep table tr{background-color:var(--ast-message-table-tr-bg, #f8f8f8);border:1px solid;border-color:var(--ast-message-table-tr-border-color, #ddd);padding:.35em}.message-content ::ng-deep table th,.message-content ::ng-deep table td{padding:.625em;text-align:center}.message-content ::ng-deep table th{font-size:.85em;letter-spacing:.1em;text-transform:uppercase}.message-content ::ng-deep .reference{color:var(--ast-message-reference-color, black)!important}.message-content ::ng-deep ul,.message-content ::ng-deep ol{display:flex;flex-direction:column;gap:.5rem;padding-right:2rem;margin-left:0;margin-right:0;padding-left:40px;unicode-bidi:isolate;list-style:disc}.message-content ::ng-deep p:not(:first-child){margin-top:.5rem}.message-assistant .message-content{background:var(--ast-secondary-bg, #FFF8F1)}.message-connection-error .message-content{background:var(--ast-error-bg, rgba(249, 58, 55, .2))}.message-search-warning .message-content{background:var(--ast-warning-bg, #fff1b8);color:var(--ast-message-reference-color, inherit)}.message-user .message-content{background:var(--ast-primary-bg, #f2f8fe);font-weight:var(--ast-user-font-weight, var(--font-weight-bold, 500))}.message-user .message-content p{white-space:pre-line}.message-suggestion .message-content{background:var(--ast-input-bg, #F8F8F8);font-weight:var(--ast-user-font-weight, var(--font-weight-bold, 500));transition:background-color .5s ease,color .5s ease}.message-suggestion .message-content:hover{background:var(--ast-primary-bg, #f2f8fe);color:var(--ast-primary-color, #005DA7)}.message-suggestion .message-content p{white-space:pre-line}.message-suggestion .suggested-action{cursor:pointer}.message-suggestion .suggested-action+.suggested-action{margin-top:var(--ast-size-2, .5rem)}.sq-chat-message-actions{position:absolute;bottom:calc(0rem - var(--ast-size-5, 1.25rem));display:flex;z-index:999}.sq-chat-message-actions button{font-size:.75rem;color:var(--ast-action-buttons-color, #212529)}.sq-chat-message-actions button:hover{color:var(--ast-action-buttons-hover-color, var(--ast-primary-color, #005DA7))}.message-icon{margin-top:var(--ast-size-3, .75rem);margin-right:var(--ast-size-4, 1rem)}.connection-error{height:var(--sq-size);width:var(--sq-size);color:var(--ast-error-color, rgba(249, 58, 55, .7))}.search-warning{height:var(--sq-size);width:var(--sq-size);color:var(--ast-warning-color, #fed86f)}.step-success{color:var(--ast-primary-color, #005DA7)}.step-ongoing{color:var(--ast-secondary-color, #FF732E)}.step-error{color:var(--ast-error-color, rgba(249, 58, 55, .7))}.bounce{animation:bounce 2s ease}@keyframes bounce{10%{transform:translateY(0)}20%{transform:translateY(-15%)}30%{transform:translateY(0)}35%{transform:translateY(-7%)}37%{transform:translateY(0)}39%{transform:translateY(-3%)}40%{transform:translateY(0)}}\n"] }]
200
203
  }], ctorParameters: () => [{ type: i1.UIService }, { type: i2.PrincipalService }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }], propDecorators: { message: [{
201
204
  type: Input
202
205
  }], conversation: [{
@@ -246,4 +249,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
246
249
  }], debug: [{
247
250
  type: Output
248
251
  }] } });
249
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhdC1tZXNzYWdlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Fzc2lzdGFudC9jaGF0L2NoYXQtbWVzc2FnZS9jaGF0LW1lc3NhZ2UuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYXNzaXN0YW50L2NoYXQvY2hhdC1tZXNzYWdlL2NoYXQtbWVzc2FnZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUNMLHVCQUF1QixFQUV2QixTQUFTLEVBQ1QsUUFBUSxFQUVSLFlBQVksRUFDWixLQUFLLEVBQ0wsS0FBSyxFQUVMLE1BQU0sRUFDTixNQUFNLEVBRVAsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLHFCQUFxQixFQUFFLGFBQWEsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRTFFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNqRSxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQztBQUNwRixPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSw4Q0FBOEMsQ0FBQztBQUN2RixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUNuRSxPQUFPLEVBQUUsNkJBQTZCLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUNyRixPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUduRixPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUMxRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQzs7Ozs7QUF5QmhFLE1BQU0sT0FBTyxvQkFBb0I7SUFrRC9CLFlBQ1MsRUFBYSxFQUNiLGdCQUFrQyxFQUNsQyxHQUFzQixF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QUFsQyxLQUFLO2dCQUNHLHdCQUF3QjtzQkFBaEMsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLGtCQUFrQjtzQkFBMUIsS0FBSztnQkFDSSxZQUFZO3NCQUFyQixNQUFNO2dCQUlHLFdBQVc7c0JBQXBCLE1BQU07Z0JBSUcsYUFBYTtzQkFBdEIsTUFBTTtnQkFDRyxJQUFJO3NCQUFiLE1BQU07Z0JBQ0csSUFBSTtzQkFBYixNQUFNO2dCQUNHLFVBQVU7c0JBQW5CLE1BQU07Z0JBQ0csSUFBSTtzQkFBYixNQUFNO2dCQUNHLE9BQU87c0JBQWhCLE1BQU07Z0JBQ0csS0FBSztzQkFBZCxNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSBcIkBhbmd1bGFyL2NvbW1vblwiO1xuaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIGNvbXB1dGVkLFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIGlucHV0LFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPdXRwdXQsXG4gIHNpZ25hbCxcbiAgU2ltcGxlQ2hhbmdlc1xufSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgcHJvdmlkZVRyYW5zbG9jb1Njb3BlLCBUcmFuc2xvY29QaXBlIH0gZnJvbSAnQGpzdmVyc2UvdHJhbnNsb2NvJztcblxuaW1wb3J0IHsgQ2hhcnRDb21wb25lbnQgfSBmcm9tIFwiLi4vY2hhcnRzL2NoYXJ0L2NoYXJ0LmNvbXBvbmVudFwiO1xuaW1wb3J0IHsgQ2hhdFJlZmVyZW5jZUNvbXBvbmVudCB9IGZyb20gXCIuLi9jaGF0LXJlZmVyZW5jZS9jaGF0LXJlZmVyZW5jZS5jb21wb25lbnRcIjtcbmltcG9ydCB7IEluaXRpYWxzQXZhdGFyQ29tcG9uZW50IH0gZnJvbSBcIi4uL2luaXRpYWxzLWF2YXRhci9pbml0aWFscy1hdmF0YXIuY29tcG9uZW50XCI7XG5pbXBvcnQgeyBNZXNzYWdlQ29udGVudFBpcGUgfSBmcm9tIFwiLi4vcGlwZXMvbWVzc2FnZS1jb250ZW50LnBpcGVcIjtcbmltcG9ydCB7IElubGluZUltYWdlUmVmZXJlbmNlQ29tcG9uZW50IH0gZnJvbSBcIi4uL3JlZmVyZW5jZXMvaW5saW5lLWltYWdlLXJlZmVyZW5jZVwiO1xuaW1wb3J0IHsgSW5saW5lUGFnZVJlZmVyZW5jZUNvbXBvbmVudCB9IGZyb20gXCIuLi9yZWZlcmVuY2VzL2lubGluZS1wYWdlLXJlZmVyZW5jZVwiO1xuaW1wb3J0IHsgUHJpbmNpcGFsU2VydmljZSB9IGZyb20gXCIuLi9zZXJ2aWNlcy9wcmluY2lwYWwuc2VydmljZVwiO1xuaW1wb3J0IHsgVUlTZXJ2aWNlIH0gZnJvbSBcIi4uL3NlcnZpY2VzL3VpLnNlcnZpY2VcIjtcbmltcG9ydCB7IFNtYXJ0UmVuZGVyZXJDb21wb25lbnQgfSBmcm9tIFwiLi4vc21hcnQtcmVuZGVyZXIvc21hcnQtcmVuZGVyZXJcIjtcbmltcG9ydCB7IFRvb2x0aXBEaXJlY3RpdmUgfSBmcm9tIFwiLi4vdG9vbHRpcC90b29sdGlwLmRpcmVjdGl2ZVwiO1xuaW1wb3J0IHsgQ2hhdENvbnRleHRBdHRhY2htZW50LCBDaGF0TWVzc2FnZSwgU3VnZ2VzdGVkQWN0aW9uIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBUZXh0TWVzc2FnZUNvbnRlbnQgfSBmcm9tIFwiLi4vdHlwZXMvbWVzc2FnZS1jb250ZW50LnR5cGVzXCI7XG5pbXBvcnQgeyBNZXNzYWdlSW1hZ2VSZWZlcmVuY2UgfSBmcm9tIFwiLi4vdHlwZXMvbWVzc2FnZS1yZWZlcmVuY2UudHlwZXNcIjtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiBcInNxLWNoYXQtbWVzc2FnZVwiLFxuICB0ZW1wbGF0ZVVybDogXCIuL2NoYXQtbWVzc2FnZS5jb21wb25lbnQuaHRtbFwiLFxuICBzdHlsZVVybHM6IFtcIi4vY2hhdC1tZXNzYWdlLmNvbXBvbmVudC5zY3NzXCJdLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIENvbW1vbk1vZHVsZSxcbiAgICBUb29sdGlwRGlyZWN0aXZlLFxuICAgIEluaXRpYWxzQXZhdGFyQ29tcG9uZW50LFxuICAgIENoYXRSZWZlcmVuY2VDb21wb25lbnQsXG4gICAgQ2hhcnRDb21wb25lbnQsXG4gICAgTWVzc2FnZUNvbnRlbnRQaXBlLFxuICAgIElubGluZUltYWdlUmVmZXJlbmNlQ29tcG9uZW50LFxuICAgIElubGluZVBhZ2VSZWZlcmVuY2VDb21wb25lbnQsXG4gICAgVHJhbnNsb2NvUGlwZSxcbiAgICBTbWFydFJlbmRlcmVyQ29tcG9uZW50XG4gIF0sXG4gIHByb3ZpZGVyczogW3Byb3ZpZGVUcmFuc2xvY29TY29wZSgnY2hhdC1tZXNzYWdlJyldLFxufSlcbmV4cG9ydCBjbGFzcyBDaGF0TWVzc2FnZUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcyB7XG4gIGlkID0gaW5wdXQ8c3RyaW5nPigpO1xuXG4gIEBJbnB1dCgpIG1lc3NhZ2U6IENoYXRNZXNzYWdlO1xuICBASW5wdXQoKSBjb252ZXJzYXRpb246IENoYXRNZXNzYWdlW107XG4gIEBJbnB1dCgpIHN1Z2dlc3RlZEFjdGlvbnM6IFN1Z2dlc3RlZEFjdGlvbltdIHwgdW5kZWZpbmVkO1xuICBASW5wdXQoKSBhc3Npc3RhbnRNZXNzYWdlSWNvbjogc3RyaW5nO1xuICBASW5wdXQoKSB1c2VyTWVzc2FnZUljb246IHN0cmluZztcbiAgQElucHV0KCkgY29ubmVjdGlvbkVycm9yTWVzc2FnZUljb246IHN0cmluZztcbiAgQElucHV0KCkgc2VhcmNoV2FybmluZ01lc3NhZ2VJY29uOiBzdHJpbmc7XG4gIEBJbnB1dCgpIHN0cmVhbWluZzogYm9vbGVhbjtcbiAgQElucHV0KCkgY2FuRWRpdDogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBjYW5SZWdlbmVyYXRlOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIGNhbkNvcHk6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgY2FuRGVidWc6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgY2FuTGlrZTogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBjYW5EaXNsaWtlOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIGNvbGxhcHNlUmVmZXJlbmNlczogYm9vbGVhbiA9IHRydWU7XG4gIEBPdXRwdXQoKSBvcGVuRG9jdW1lbnQgPSBuZXcgRXZlbnRFbWl0dGVyPHtcbiAgICByZWZlcmVuY2U6IENoYXRDb250ZXh0QXR0YWNobWVudDtcbiAgICBwYXJ0SWQ/OiBudW1iZXI7XG4gIH0+KCk7XG4gIEBPdXRwdXQoKSBvcGVuUHJldmlldyA9IG5ldyBFdmVudEVtaXR0ZXI8e1xuICAgIHJlZmVyZW5jZTogQ2hhdENvbnRleHRBdHRhY2htZW50O1xuICAgIHBhcnRJZD86IG51bWJlcjtcbiAgfT4oKTtcbiAgQE91dHB1dCgpIHN1Z2dlc3RBY3Rpb24gPSBuZXcgRXZlbnRFbWl0dGVyPFN1Z2dlc3RlZEFjdGlvbj4oKTtcbiAgQE91dHB1dCgpIGVkaXQgPSBuZXcgRXZlbnRFbWl0dGVyPENoYXRNZXNzYWdlPigpO1xuICBAT3V0cHV0KCkgY29weSA9IG5ldyBFdmVudEVtaXR0ZXI8Q2hhdE1lc3NhZ2U+KCk7XG4gIEBPdXRwdXQoKSByZWdlbmVyYXRlID0gbmV3IEV2ZW50RW1pdHRlcjxDaGF0TWVzc2FnZT4oKTtcbiAgQE91dHB1dCgpIGxpa2UgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBkaXNsaWtlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgZGVidWcgPSBuZXcgRXZlbnRFbWl0dGVyPENoYXRNZXNzYWdlPigpO1xuXG4gIC8vIHNpZ25hbCBiYXNlZCBzZXQgb2YgcmVmZXJlbmNlcyB0byBhdm9pZCBkdXBsaWNhdGVzXG4gIHJlZnMgPSBzaWduYWw8bnVtYmVyW10+KFtdKTtcbiAgcmVmZXJlbmNlcyA9IGNvbXB1dGVkKCgpID0+XG4gICAgdGhpcy5yZWZzKCkuc2xpY2UoKS5zb3J0KChhLCBiKSA9PiBhIC0gYikubWFwKChyKSA9PiBcIlwiICsgcilcbiAgKTtcbiAgcmVmZXJlbmNlTWFwID0gbmV3IE1hcDxzdHJpbmcsIENoYXRDb250ZXh0QXR0YWNobWVudD4oKTtcbiAgaW1hZ2VSZWZlcmVuY2VzTWFwID0gbmV3IE1hcDxzdHJpbmcsIE1lc3NhZ2VJbWFnZVJlZmVyZW5jZT4oKTtcbiAgcGFnZVJlZmVyZW5jZXNNYXAgPSBuZXcgTWFwPHN0cmluZywgTWVzc2FnZUltYWdlUmVmZXJlbmNlPigpO1xuICBjb2xsYXBzZVByb2dyZXNzOiBib29sZWFuO1xuICBpY29uU2l6ZSA9IDI0O1xuXG4gIGhpZGRlblRvb2x0aXA6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAvLyB1c2VkIGJ5IHRoZSB0ZW1wbGF0ZVxuICBBcnJheSA9IEFycmF5O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyB1aTogVUlTZXJ2aWNlLFxuICAgIHB1YmxpYyBwcmluY2lwYWxTZXJ2aWNlOiBQcmluY2lwYWxTZXJ2aWNlLFxuICAgIHB1YmxpYyBjZHI6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIHB1YmxpYyBlbDogRWxlbWVudFJlZlxuICApIHt9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmIChjaGFuZ2VzLnN0cmVhbWluZykge1xuICAgICAgdGhpcy5jb2xsYXBzZVByb2dyZXNzID0gIXRoaXMuc3RyZWFtaW5nO1xuICAgIH1cblxuICAgIGlmICh0aGlzLm1lc3NhZ2U/LnJvbGUgPT09IFwiYXNzaXN0YW50XCIpIHtcbiAgICAgIHRoaXMucmVmZXJlbmNlTWFwLmNsZWFyKCk7XG4gICAgICBmb3IgKGxldCBtIG9mIHRoaXMuY29udmVyc2F0aW9uKSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBtLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRhdHRhY2htZW50ICYmXG4gICAgICAgICAgbS5hZGRpdGlvbmFsUHJvcGVydGllcy4kYXR0YWNobWVudC5sZW5ndGggPiAwXG4gICAgICAgICkge1xuICAgICAgICAgIGZvciAoY29uc3QgYXR0YWNobWVudCBvZiBtLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRhdHRhY2htZW50KSB7XG4gICAgICAgICAgICAvLyBza2lwIGVtcHR5IGF0dGFjaG1lbnRcbiAgICAgICAgICAgIGlmICghYXR0YWNobWVudCkgY29udGludWU7XG5cbiAgICAgICAgICAgIHRoaXMucmVmZXJlbmNlTWFwLnNldChcIlwiICsgYXR0YWNobWVudC5jb250ZXh0SWQsIHtcbiAgICAgICAgICAgICAgLi4uYXR0YWNobWVudCxcbiAgICAgICAgICAgICAgJHBhcnRJZDogYXR0YWNobWVudC5wYXJ0cz8uWzBdPy5wYXJ0SWQsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGlmICghIWF0dGFjaG1lbnQucGFydHMgJiYgYXR0YWNobWVudC5wYXJ0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXR0YWNobWVudC5wYXJ0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlZklkID0gYCR7YXR0YWNobWVudC5jb250ZXh0SWR9LiR7YXR0YWNobWVudC5wYXJ0c1tpXS5wYXJ0SWR9YDtcbiAgICAgICAgICAgICAgICB0aGlzLnJlZmVyZW5jZU1hcC5zZXQocmVmSWQsIHtcbiAgICAgICAgICAgICAgICAgIC4uLmF0dGFjaG1lbnQsXG4gICAgICAgICAgICAgICAgICAkcGFydElkOiBhdHRhY2htZW50LnBhcnRzPy5baV0/LnBhcnRJZCxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMucHJvY2Vzc01lc3NhZ2VUeXBlKG0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGdldEVtYmVkZGVkSW1hZ2VSZWZlcmVuY2UocmVmOiBzdHJpbmcpOiBNZXNzYWdlSW1hZ2VSZWZlcmVuY2UgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IFtkb2MsIHBhcnQsIGltYWdlXSA9IHJlZi5zcGxpdChcIi5cIik7XG4gICAgY29uc3QgaW1hZ2VzID0gdGhpcy5yZWZlcmVuY2VNYXAuZ2V0KGRvYyk/LnBhcnRzPy5bK3BhcnQgLSAxXT8uaW1hZ2VzO1xuXG4gICAgaWYgKCFpbWFnZXMgfHwgaW1hZ2VzLmxlbmd0aCA9PT0gMCB8fCB0eXBlb2YgaW1hZ2VzWzBdICE9PSBcIm9iamVjdFwiKVxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcblxuICAgIGNvbnN0IG1lc3NhZ2VJbWFnZVJlZmVyZW5jZTogTWVzc2FnZUltYWdlUmVmZXJlbmNlID0gT2JqZWN0LmFzc2lnbihcbiAgICAgIHtcbiAgICAgICAgYXJ0aWNsZTogdGhpcy5yZWZlcmVuY2VNYXAuZ2V0KGRvYyk/LnJlY29yZCxcbiAgICAgICAgYXJ0aWNsZUlkOiB0aGlzLnJlZmVyZW5jZU1hcC5nZXQoZG9jKT8ucmVjb3JkSWQsXG4gICAgICB9LFxuICAgICAgaW1hZ2VzWytpbWFnZSAtIDFdXG4gICAgKTtcblxuICAgIC8vIHNhdmUgcmVmZXJlbmNlIGluIG1hcCBmb3IgcmVmZXJlbmNlIGxpc3RcbiAgICBpZiAoIXRoaXMuaW1hZ2VSZWZlcmVuY2VzTWFwLmhhcyhyZWYpKVxuICAgICAgdGhpcy5pbWFnZVJlZmVyZW5jZXNNYXAuc2V0KHJlZiwgbWVzc2FnZUltYWdlUmVmZXJlbmNlKTtcblxuICAgIHJldHVybiBtZXNzYWdlSW1hZ2VSZWZlcmVuY2U7XG4gIH1cblxuICBnZXRFbWJlZGRlZFBhZ2VSZWZlcmVuY2UocmVmOiBzdHJpbmcpOiBNZXNzYWdlSW1hZ2VSZWZlcmVuY2UgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IFtkb2MsIHBhZ2VdID0gcmVmLnNwbGl0KFwiLlwiKTtcbiAgICBjb25zdCBwYWdlUmVmID0gdGhpcy5yZWZlcmVuY2VNYXAuZ2V0KGRvYyk/LnBhZ2VzPy5maW5kKHggPT4geC5wYWdlTnVtYmVyID09PSArcGFnZSk7XG5cbiAgICBpZiAoIXBhZ2VSZWYgfHwgdHlwZW9mIHBhZ2VSZWYgIT09IFwib2JqZWN0XCIpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICBjb25zdCBtZXNzYWdlUGFnZVJlZmVyZW5jZTogTWVzc2FnZUltYWdlUmVmZXJlbmNlID0gT2JqZWN0LmFzc2lnbihcbiAgICAgIHtcbiAgICAgICAgYXJ0aWNsZTogdGhpcy5yZWZlcmVuY2VNYXAuZ2V0KGRvYyk/LnJlY29yZCxcbiAgICAgICAgYXJ0aWNsZUlkOiB0aGlzLnJlZmVyZW5jZU1hcC5nZXQoZG9jKT8ucmVjb3JkSWQsXG4gICAgICB9LFxuICAgICAgcGFnZVJlZlxuICAgICk7XG5cbiAgICAvLyBzYXZlIHJlZmVyZW5jZSBpbiBtYXAgZm9yIHJlZmVyZW5jZSBsaXN0XG4gICAgaWYgKCF0aGlzLnBhZ2VSZWZlcmVuY2VzTWFwLmhhcyhyZWYpKVxuICAgICAgdGhpcy5wYWdlUmVmZXJlbmNlc01hcC5zZXQocmVmLCBtZXNzYWdlUGFnZVJlZmVyZW5jZSk7XG5cbiAgICByZXR1cm4gbWVzc2FnZVBhZ2VSZWZlcmVuY2U7XG4gIH1cblxuICBnZXQgbmFtZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiAhdGhpcy5wcmluY2lwYWxTZXJ2aWNlLnByaW5jaXBhbFxuICAgICAgPyBcIlwiXG4gICAgICA6ICh0aGlzLnByaW5jaXBhbFNlcnZpY2UucHJpbmNpcGFsW1wiZnVsbE5hbWVcIl0gYXMgc3RyaW5nKSB8fFxuICAgICAgICAgIHRoaXMucHJpbmNpcGFsU2VydmljZS5wcmluY2lwYWwubmFtZTtcbiAgfVxuXG4gIGdldCBpc0FkbWluKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnByaW5jaXBhbFNlcnZpY2UucHJpbmNpcGFsPy5pc0FkbWluaXN0cmF0b3IgfHwgZmFsc2U7XG4gIH1cblxuICBwcm9jZXNzTWVzc2FnZVR5cGUobWVzc2FnZTogQ2hhdE1lc3NhZ2UpIHtcbiAgICAvLyBQcm9jZXNzIG1lc3NhZ2UgdHlwZSB3aGVuIHNwZWMgaXMgZG9uZVxuICAgIC8vIG5vcCBmb3IgbmV3IG1lc3NhZ2UgdHlwZXNcbiAgICBpZiAodHlwZW9mIG1lc3NhZ2UuY29udGVudCAhPT0gXCJzdHJpbmdcIikgcmV0dXJuO1xuXG4gICAgLy8gTGVnYWN5IG1lc3NhZ2UgdHlwZVxuICAgIGlmIChtZXNzYWdlLmNvbnRlbnQuc3RhcnRzV2l0aChcIjxjaGFydGpzPlwiKSkge1xuICAgICAgbWVzc2FnZS5tZXNzYWdlVHlwZSA9IFwiQ0hBUlRcIjtcbiAgICB9IGVsc2Uge1xuICAgICAgbWVzc2FnZS5tZXNzYWdlVHlwZSA9IFwiTUFSS0RPV05cIjtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUHJvY2Vzc2VzIGEgcmVmZXJlbmNlIHN0cmluZyBieSB2YWxpZGF0aW5nIGFuZCBhZGRpbmcgaXQgdG8gdGhlIHNldCBvZiByZWZlcmVuY2VzIGlmIGFwcGxpY2FibGUuXG4gICAqXG4gICAqIC0gSWdub3JlcyBlbXB0eSBvciBmYWxzeSByZWZlcmVuY2VzLlxuICAgKiAtIElnbm9yZXMgcmVmZXJlbmNlcyB0aGF0IGFyZSBub3QgbnVtZXJpYy5cbiAgICogLSBJZ25vcmVzIHJlZmVyZW5jZXMgdGhhdCBhbHJlYWR5IGV4aXN0IGluIHRoZSBzZXQuXG4gICAqIC0gQ29udmVydHMgdGhlIHJlZmVyZW5jZSB0byBhIG51bWJlciBhbmQgYWRkcyBpdCB0byB0aGUgc2V0IG9mIHJlZmVyZW5jZXMuXG4gICAqXG4gICAqIEBwYXJhbSByZWYgLSBUaGUgcmVmZXJlbmNlIHN0cmluZyB0byBwcm9jZXNzLlxuICAgKi9cbiAgcHJvY2Vzc1JlZmVyZW5jZXMocmVmOiBzdHJpbmcpIHtcbiAgICBpZiAoIXJlZikgcmV0dXJuO1xuICAgIGlmIChpc05hTigrcmVmKSkgcmV0dXJuO1xuICAgIGNvbnN0IHJlZk51bSA9ICtyZWY7XG4gICAgaWYgKHRoaXMucmVmcygpLmluY2x1ZGVzKHJlZk51bSkpIHJldHVybjtcbiAgICB0aGlzLnJlZnMudXBkYXRlKGFyciA9PiBbLi4uYXJyLCByZWZOdW1dKTtcbiAgfVxuXG4gIHByaXZhdGUgX2NvcHlUb0NsaXBib2FyZChjb250ZW50OiBzdHJpbmcpIHtcbiAgICB0aGlzLnVpLmNvcHlUb0NsaXBib2FyZChjb250ZW50KTtcbiAgfVxuXG4gIGNvcHlNZXNzYWdlKG1lc3NhZ2U6IENoYXRNZXNzYWdlKSB7XG4gICAgbGV0IGNvbnRlbnQ6IHN0cmluZyA9IFwiXCI7XG5cbiAgICBpZiAodHlwZW9mIG1lc3NhZ2UuY29udGVudCA9PT0gXCJzdHJpbmdcIilcbiAgICAgIGNvbnRlbnQgPSBtZXNzYWdlLmNvbnRlbnQ7XG4gICAgZWxzZSBpZiAoQXJyYXkuaXNBcnJheShtZXNzYWdlLmNvbnRlbnQpKVxuICAgICAgY29udGVudCA9IChtZXNzYWdlLmNvbnRlbnRbMF0gYXMgVGV4dE1lc3NhZ2VDb250ZW50KS50ZXh0O1xuICAgIGVsc2Uge1xuICAgICAgY29uc29sZS5lcnJvcihcIlVuc3VwcG9ydGVkIG1lc3NhZ2UgY29udGVudCB0eXBlXCIsIHR5cGVvZiBtZXNzYWdlLmNvbnRlbnQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnRlbnQgPSBjb250ZW50LnJlcGxhY2VBbGwoL1xccypcXFtbXlxcXV0qXVxccyovZywgXCJcIik7XG5cbiAgICB0aGlzLl9jb3B5VG9DbGlwYm9hcmQoY29udGVudCk7XG4gICAgdGhpcy5jb3B5LmVtaXQobWVzc2FnZSk7XG4gIH1cblxuICBvcGVuQXR0YWNobWVudFByZXZpZXcoYXR0YWNobWVudDogQ2hhdENvbnRleHRBdHRhY2htZW50LCBwYXJ0SWQ/OiBudW1iZXIpIHtcbiAgICB0aGlzLm9wZW5QcmV2aWV3LmVtaXQoeyByZWZlcmVuY2U6IGF0dGFjaG1lbnQsIHBhcnRJZCB9KTtcbiAgICB0aGlzLmhpZGVUb29sdGlwKCk7XG4gIH1cblxuICBvcGVuT3JpZ2luYWxBdHRhY2htZW50KGF0dGFjaG1lbnQ6IENoYXRDb250ZXh0QXR0YWNobWVudCwgcGFydElkPzogbnVtYmVyKSB7XG4gICAgdGhpcy5vcGVuRG9jdW1lbnQuZW1pdCh7IHJlZmVyZW5jZTogYXR0YWNobWVudCwgcGFydElkIH0pO1xuICAgIHRoaXMuaGlkZVRvb2x0aXAoKTtcbiAgfVxuXG4gIGhpZGVUb29sdGlwKCk6IHZvaWQge1xuICAgIHRoaXMuaGlkZGVuVG9vbHRpcCA9IHRydWU7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLmhpZGRlblRvb2x0aXAgPSBmYWxzZTtcbiAgICB9KTtcbiAgfVxufVxuIiwiPCEtLSBNZXNzYWdlIGljb24gLS0+XG48c3BhbiBjbGFzcz1cIm1lc3NhZ2UtaWNvblwiIFt0aXRsZV09XCJtZXNzYWdlPy5yb2xlXCI+XG4gIDxpIGNsYXNzPVwiZC1ibG9ja1wiIFtzdHlsZS53aWR0aC5weF09XCJpY29uU2l6ZVwiICpuZ0lmPVwiIW1lc3NhZ2VcIj48L2k+XG4gIDxuZy1jb250YWluZXIgW25nU3dpdGNoXT1cIm1lc3NhZ2U/LnJvbGVcIj5cbiAgICA8IS0tIEZvciAnYXNzaXN0YW50JyAtLT5cbiAgICA8aSAqbmdTd2l0Y2hDYXNlPVwiJ2Fzc2lzdGFudCdcIiBbbmdDbGFzc109XCJhc3Npc3RhbnRNZXNzYWdlSWNvblwiIFtzdHlsZS4tLXNxLXNpemUucHhdPVwiaWNvblNpemVcIj48L2k+XG5cbiAgICA8IS0tIEZvciAndXNlcicgLS0+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3VzZXInXCI+XG4gICAgICA8aSAqbmdJZj1cIiEhdXNlck1lc3NhZ2VJY29uOyBlbHNlIGluaXRpYWxzQXZhdGFyXCIgW25nQ2xhc3NdPVwidXNlck1lc3NhZ2VJY29uXCIgW3N0eWxlLi0tc3Etc2l6ZS5weF09XCJpY29uU2l6ZVwiPjwvaT5cbiAgICAgIDxuZy10ZW1wbGF0ZSAjaW5pdGlhbHNBdmF0YXI+XG4gICAgICAgIDxzcS1pbml0aWFscy1hdmF0YXIgW2Z1bGxOYW1lXT1cIm5hbWVcIj48L3NxLWluaXRpYWxzLWF2YXRhcj5cbiAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgPC9uZy1jb250YWluZXI+XG5cbiAgICA8IS0tIEZvciAnY29ubmVjdGlvbi1lcnJvcicgLS0+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2Nvbm5lY3Rpb24tZXJyb3InXCI+XG4gICAgICA8aSAqbmdJZj1cIiEhY29ubmVjdGlvbkVycm9yTWVzc2FnZUljb247IGVsc2UgZGVmYXVsdEVycm9ySWNvblwiIFtuZ0NsYXNzXT1cImNvbm5lY3Rpb25FcnJvck1lc3NhZ2VJY29uXCIgW3N0eWxlLi0tc3Etc2l6ZS5weF09XCJpY29uU2l6ZVwiPjwvaT5cbiAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdEVycm9ySWNvbj5cbiAgICAgICAgPHN2ZyBbc3R5bGUuLS1zcS1zaXplLnB4XT1cImljb25TaXplXCIgY2xhc3M9XCJjb25uZWN0aW9uLWVycm9yXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgNTEyIDUxMlwiPlxuICAgICAgICAgIDxwYXRoIGZpbGw9XCJjdXJyZW50Q29sb3JcIiBkPVwiTTE3LjEgMjkyYy0xMi45LTIyLjMtMTIuOS00OS43IDAtNzJMMTA1LjQgNjcuMWMxMi45LTIyLjMgMzYuNi0zNiA2Mi40LTM2bDE3Ni42IDBjMjUuNyAwIDQ5LjUgMTMuNyA2Mi40IDM2TDQ5NC45IDIyMGMxMi45IDIyLjMgMTIuOSA0OS43IDAgNzJMNDA2LjYgNDQ0LjljLTEyLjkgMjIuMy0zNi42IDM2LTYyLjQgMzZsLTE3Ni42IDBjLTI1LjcgMC00OS41LTEzLjctNjIuNC0zNkwxNy4xIDI5MnpNMjU2IDEyOGMtMTMuMyAwLTI0IDEwLjctMjQgMjRsMCAxMTJjMCAxMy4zIDEwLjcgMjQgMjQgMjRzMjQtMTAuNyAyNC0yNGwwLTExMmMwLTEzLjMtMTAuNy0yNC0yNC0yNHptMzIgMjI0YTMyIDMyIDAgMSAwIC02NCAwIDMyIDMyIDAgMSAwIDY0IDB6XCIvPlxuICAgICAgICA8L3N2Zz5cbiAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgPC9uZy1jb250YWluZXI+XG5cbiAgICA8IS0tIEZvciAnc2VhcmNoLXdhcm5pbmcnIC0tPlxuICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidzZWFyY2gtd2FybmluZydcIj5cbiAgICAgIDxpICpuZ0lmPVwiISFzZWFyY2hXYXJuaW5nTWVzc2FnZUljb247IGVsc2UgZGVmYXVsdFdhcm5pbmdJY29uXCIgW25nQ2xhc3NdPVwic2VhcmNoV2FybmluZ01lc3NhZ2VJY29uXCIgW3N0eWxlLi0tc3Etc2l6ZS5weF09XCJpY29uU2l6ZVwiPjwvaT5cbiAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdFdhcm5pbmdJY29uPlxuICAgICAgICA8c3ZnIFtzdHlsZS4tLXNxLXNpemUucHhdPVwiaWNvblNpemVcIiBjbGFzcz1cInNlYXJjaC13YXJuaW5nXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMzg0IDUxMlwiPlxuICAgICAgICAgIDxwYXRoIGZpbGw9XCJjdXJyZW50Q29sb3JcIiBkPVwiTTI3MiAzODRjOS42LTMxLjkgMjkuNS01OS4xIDQ5LjItODYuMmMwIDAgMCAwIDAgMGM1LjItNy4xIDEwLjQtMTQuMiAxNS40LTIxLjRjMTkuOC0yOC41IDMxLjQtNjMgMzEuNC0xMDAuM0MzNjggNzguOCAyODkuMiAwIDE5MiAwUzE2IDc4LjggMTYgMTc2YzAgMzcuMyAxMS42IDcxLjkgMzEuNCAxMDAuM2M1IDcuMiAxMC4yIDE0LjMgMTUuNCAyMS40YzAgMCAwIDAgMCAwYzE5LjggMjcuMSAzOS43IDU0LjQgNDkuMiA4Ni4ybDE2MCAwek0xOTIgNTEyYzQ0LjIgMCA4MC0zNS44IDgwLTgwbDAtMTYtMTYwIDAgMCAxNmMwIDQ0LjIgMzUuOCA4MCA4MCA4MHptMC00NDhjMTMuMyAwIDI0IDEwLjcgMjQgMjRsMCAxMTJjMCAxMy4zLTEwLjcgMjQtMjQgMjRzLTI0LTEwLjctMjQtMjRsMC0xMTJjMC0xMy4zIDEwLjctMjQgMjQtMjR6TTE2MCAyODhhMzIgMzIgMCAxIDEgNjQgMCAzMiAzMiAwIDEgMSAtNjQgMHpcIi8+XG4gICAgICAgIDwvc3ZnPlxuICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgPC9uZy1jb250YWluZXI+XG48L3NwYW4+XG5cbjwhLS0gTWVzc2FnZSBib2R5IC0tPlxuPGRpdiBjbGFzcz1cImZsZXgtZ3Jvdy0xIHBvc2l0aW9uLXJlbGF0aXZlIHJlbGF0aXZlXCIgc3R5bGU9XCJtaW4td2lkdGg6IDA7XCIgW25nQ2xhc3NdPVwiJ21lc3NhZ2UtJyttZXNzYWdlLnJvbGVcIj5cblxuICA8IS0tIFByb2dyZXNzIHN0ZXBzIC0tPlxuICA8ZGl2ICpuZ0lmPVwibWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcy4kcHJvZ3Jlc3MgYXMgcHJvZ3Jlc3NcIiBjbGFzcz1cInNtYWxsIG1zLTMgbWItMlwiPlxuICAgIDxkZXRhaWxzIHJvbGU9XCJidXR0b25cIiBjbGFzcz1cInNlbGVjdC1ub25lXCIgW29wZW5dPVwiIWNvbGxhcHNlUHJvZ3Jlc3NcIj5cbiAgICAgIDxzdW1tYXJ5IGNsYXNzPVwidGV4dC1tdXRlZFwiPlxuICAgICAgICB7eyAnY2hhdE1lc3NhZ2Uudmlld1Byb2dyZXNzJyB8IHRyYW5zbG9jbyB9fVxuICAgICAgPC9zdW1tYXJ5PlxuICAgICAgPHVsIGNsYXNzPVwibGlzdC11bnN0eWxlZFwiPlxuICAgICAgICA8bGkgKm5nRm9yPVwibGV0IHN0ZXAgb2YgcHJvZ3Jlc3NcIj5cbiAgICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1mdyBmYS1jaGVjayB0ZXh0LXN1Y2Nlc3NcIiAqbmdJZj1cInN0ZXAuZG9uZVwiPjwvaT5cbiAgICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1zcGlubmVyIGZhLXB1bHNlIHN0ZXAtb25nb2luZ1wiICpuZ0lmPVwiIXN0ZXAuZG9uZSAmJiBzdHJlYW1pbmdcIj48L2k+XG4gICAgICAgICAgPGkgY2xhc3M9XCJmYS1zb2xpZCBmYS1iYW4gc3RlcC1lcnJvclwiICpuZ0lmPVwiIXN0ZXAuZG9uZSAmJiAhc3RyZWFtaW5nXCI+PC9pPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwibXMtMiBmdy1ib2xkXCI+e3tzdGVwLnRpdGxlfX08L3NwYW4+XG4gICAgICAgICAgPHNwYW4gKm5nSWY9XCJzdGVwLmNvbnRlbnRcIiBbaW5uZXJIVE1MXT1cIic6ICcgKyBzdGVwLmNvbnRlbnRcIj48L3NwYW4+XG4gICAgICAgIDwvbGk+XG4gICAgICA8L3VsPlxuICAgIDwvZGV0YWlscz5cbiAgPC9kaXY+XG5cbiAgPCEtLSBNZXNzYWdlIGNvbnRlbnQgLS0+XG4gIDxkaXYgY2xhc3M9XCJtZXNzYWdlLWNvbnRlbnRcIiAqbmdJZj1cIm1lc3NhZ2UuY29udGVudFwiPlxuXG4gICAgPCEtLSBDdXN0b20gcmVuZGVyaW5nIGZvciBXUFMsIHRvIGJlIHJlbW92ZSB3aXRoIGh0dHBzOi8vc2luZXF1YS5hdGxhc3NpYW4ubmV0L2Jyb3dzZS9FUy0yMzcxMCAtLT5cbiAgICA8ZGl2ICpuZ0lmPVwibWVzc2FnZT8ucm9sZSA9PT0gJ2Fzc2lzdGFudCcgJiYgbWVzc2FnZS5tZXNzYWdlVHlwZSA9PT0gJ0NIQVJUJ1wiPlxuICAgICAgPHNxLWFzc2lzdGFudC1jaGFydCBbcmF3Q2hhcnREYXRhXT1cIm1lc3NhZ2UuY29udGVudFwiPjwvc3EtYXNzaXN0YW50LWNoYXJ0PlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBUaGlzIHNlY3Rpb24gaXMgcmVzcG9uc2libGUgZm9yIGN1c3RvbWl6aW5nIHRoZSB0ZW1wbGF0ZSBub2RlcyB1c2VkIGluIHRoZSBhcHBsaWNhdGlvbi5cbiAgICAgICAgVGVtcGxhdGUgbm9kZXMgYXJlIHByZWRlZmluZWQgc3RydWN0dXJlcyB0aGF0IHNlcnZlIGFzIGJsdWVwcmludHMgZm9yIGNyZWF0aW5nL2N1c3RvbWl6aW5nIGR5bmFtaWMgY29udGVudCAtLT5cblxuXG4gICAgQGlmKG1lc3NhZ2U/LnJvbGUgPT09ICdhc3Npc3RhbnQnICYmIG1lc3NhZ2UubWVzc2FnZVR5cGUgIT09ICdDSEFSVCcpIHtcbiAgICAgIDxTbWFydFJlbmRlcmVyXG4gICAgICAgIFttZXNzYWdlXT1cIm1lc3NhZ2UuY29udGVudCB8IG1lc3NhZ2VDb250ZW50XCJcbiAgICAgICAgW2NvbnRleHRdPVwie1xuICAgICAgICAgIGdldEVtYmVkZGVkUGFnZVJlZmVyZW5jZTogZ2V0RW1iZWRkZWRQYWdlUmVmZXJlbmNlLmJpbmQodGhpcyksXG4gICAgICAgICAgZ2V0RW1iZWRkZWRJbWFnZVJlZmVyZW5jZTogZ2V0RW1iZWRkZWRJbWFnZVJlZmVyZW5jZS5iaW5kKHRoaXMpLFxuICAgICAgICAgIHJlZmVyZW5jZXNNYXA6IHJlZmVyZW5jZU1hcCxcbiAgICAgICAgICByZWZlcmVuY2VzOiBwcm9jZXNzUmVmZXJlbmNlcy5iaW5kKHRoaXMpLFxuICAgICAgICAgIHJhbms6IGlkKClcbiAgICAgICAgfVwiPlxuICAgICAgPC9TbWFydFJlbmRlcmVyPlxuICAgIH1cblxuICAgIDxwICpuZ0lmPVwibWVzc2FnZT8ucm9sZSA9PT0gJ3VzZXInXCI+e3sgbWVzc2FnZS5jb250ZW50IHwgbWVzc2FnZUNvbnRlbnQgfX08L3A+XG5cbiAgICA8IS0tIExpc3Qgb2YgcmVmZXJlbmNlLCBpZiBhbnkgLS0+XG4gIEBsZXQgcmVmZXJlbmNlc0FycmF5ID0gcmVmZXJlbmNlcygpO1xuICAgIEBpZiAocmVmZXJlbmNlc0FycmF5Py5sZW5ndGggPiAwIHx8IGltYWdlUmVmZXJlbmNlc01hcD8uc2l6ZSA+IDAgfHwgcGFnZVJlZmVyZW5jZXNNYXA/LnNpemUgPiAwKSB7XG4gICAgICA8ZGl2IGNsYXNzPVwicmVmZXJlbmNlc1wiPlxuICAgICAgICA8ZGV0YWlscyByb2xlPVwiYnV0dG9uXCIgY2xhc3M9XCJzZWxlY3Qtbm9uZVwiIFtvcGVuXT1cIiFjb2xsYXBzZVJlZmVyZW5jZXNcIj5cbiAgICAgICAgICA8c3VtbWFyeSBjbGFzcz1cInJlZmVyZW5jZXMtdGl0bGVcIj57eyAnY2hhdE1lc3NhZ2UucmVmZXJlbmNlcycgfCB0cmFuc2xvY28gfX08L3N1bW1hcnk+XG4gICAgICAgICAgPHVsPlxuICAgICAgICAgICAgQGZvciAocmVmZXJlbmNlIG9mIHJlZmVyZW5jZXNBcnJheTsgdHJhY2sgJGluZGV4KSB7XG4gICAgICAgICAgICAgIEBsZXQgYXR0YWNobWVudCA9IHJlZmVyZW5jZU1hcC5nZXQocmVmZXJlbmNlKTtcbiAgICAgICAgICAgICAgPCEtLSBPbmx5IGRpc3BsYXkgdGhlIHJlZmVyZW5jZSB3aGVuIHRoZSBrZXkgaXMgYSBpbnRlZ2VyIG5vdCBhIGRlY2ltYWwgLS0+XG4gICAgICAgICAgICAgICBAaWYoYXR0YWNobWVudCkge1xuICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cInRleHQtdHJ1bmNhdGVcIj5cbiAgICAgICAgICAgICAgICAgIDxzcS1jaGF0LXJlZmVyZW5jZVxuICAgICAgICAgICAgICAgICAgICBbY2xhc3MuZXhwYW5kZWRdPVwiYXR0YWNobWVudD8uJGV4cGFuZGVkXCJcbiAgICAgICAgICAgICAgICAgICAgW2F0dGFjaG1lbnRdPVwiYXR0YWNobWVudFwiXG4gICAgICAgICAgICAgICAgICAgIFtyZWZlcmVuY2VdPVwicmVmZXJlbmNlXCJcbiAgICAgICAgICAgICAgICAgICAgW3JlZmVyZW5jZU1hcF09XCJyZWZlcmVuY2VNYXBcIlxuICAgICAgICAgICAgICAgICAgICBbaW1hZ2VzXT1cIkFycmF5LmZyb20oaW1hZ2VSZWZlcmVuY2VzTWFwLmtleXMoKSlcIlxuICAgICAgICAgICAgICAgICAgICBbcGFnZXNdPVwiQXJyYXkuZnJvbShwYWdlUmVmZXJlbmNlc01hcC5rZXlzKCkpXCJcbiAgICAgICAgICAgICAgICAgICAgKG9wZW5QcmV2aWV3KT1cIm9wZW5BdHRhY2htZW50UHJldmlldygkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgKG9wZW5Eb2N1bWVudCk9XCJvcGVuT3JpZ2luYWxBdHRhY2htZW50KCRldmVudClcIj5cbiAgICAgICAgICAgICAgICAgIDwvc3EtY2hhdC1yZWZlcmVuY2U+XG4gICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC91bD5cbiAgICAgICAgPC9kZXRhaWxzPlxuICAgICAgPC9kaXY+XG4gICAgfVxuICA8L2Rpdj5cblxuICAgIDwhLS0gRWRpdCAvIFJlZ2VuZXJhdGUgZmxvYXRpbmcgYWN0aW9ucyAtLT5cbiAgPGRpdiBjbGFzcz1cInNxLWNoYXQtbWVzc2FnZS1hY3Rpb25zXCIgKm5nSWY9XCJtZXNzYWdlXCI+XG4gICAgPCEtLSBDb21tb24gYWN0aW9uIGJ1dHRvbnMgZm9yIFwidXNlclwiICYgXCJhc3Npc3RhbnRcIiBtZXNzYWdlIC0tPlxuICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNtXCIgKm5nSWY9XCJjYW5Db3B5XCIgW3NxVG9vbHRpcF09XCInY2hhdE1lc3NhZ2UuY29weVRleHQnIHwgdHJhbnNsb2NvXCIgKGNsaWNrKT1cImNvcHlNZXNzYWdlKG1lc3NhZ2UpXCI+XG4gICAgICA8aSBjbGFzcz1cImZhciBmYS1jbGlwYm9hcmRcIj48L2k+XG4gICAgPC9idXR0b24+XG4gICAgPCEtLSBBY3Rpb24gYnV0dG9ucyBmb3IgXCJ1c2VyXCIgbWVzc2FnZSAtLT5cbiAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1zbVwiICpuZ0lmPVwiY2FuRWRpdFwiIFtzcVRvb2x0aXBdPVwiJ2NoYXRNZXNzYWdlLmVkaXRNZXNzYWdlJyB8IHRyYW5zbG9jb1wiIChjbGljayk9XCJlZGl0LmVtaXQobWVzc2FnZSlcIj5cbiAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLWVkaXRcIj48L2k+XG4gICAgPC9idXR0b24+XG4gICAgPCEtLSBBY3Rpb24gYnV0dG9ucyBmb3IgXCJhc3Npc3RhbnRcIiBtZXNzYWdlIC0tPlxuICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNtXCIgW2NsYXNzLmJvdW5jZV09XCJtZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRsaWtlZFwiICpuZ0lmPVwiY2FuTGlrZVwiIFtzcVRvb2x0aXBdPVwiJ2NoYXRNZXNzYWdlLmxpa2VBbnN3ZXInIHwgdHJhbnNsb2NvXCIgKGNsaWNrKT1cImxpa2UuZW1pdCgpXCI+XG4gICAgICA8aSAqbmdJZj1cIiFtZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRsaWtlZFwiIGNsYXNzPVwiZmFyIGZhLXRodW1icy11cCBcIj48L2k+XG4gICAgICA8aSAqbmdJZj1cIm1lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMuJGxpa2VkXCIgY2xhc3M9XCJmYXMgZmEtdGh1bWJzLXVwXCI+PC9pPlxuICAgIDwvYnV0dG9uPlxuICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNtXCIgW2NsYXNzLmJvdW5jZV09XCJtZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRkaXNsaWtlZFwiICpuZ0lmPVwiY2FuRGlzbGlrZVwiIFtzcVRvb2x0aXBdPVwiJ2NoYXRNZXNzYWdlLnJlcG9ydElzc3VlJyB8IHRyYW5zbG9jb1wiIChjbGljayk9XCJkaXNsaWtlLmVtaXQoKVwiPlxuICAgICAgPGkgKm5nSWY9XCIhbWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcy4kZGlzbGlrZWRcIiBjbGFzcz1cImZhciBmYS10aHVtYnMtZG93biBcIj48L2k+XG4gICAgICA8aSAqbmdJZj1cIm1lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMuJGRpc2xpa2VkXCIgY2xhc3M9XCJmYXMgZmEtdGh1bWJzLWRvd25cIj48L2k+XG4gICAgPC9idXR0b24+XG4gICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc21cIiAqbmdJZj1cImNhblJlZ2VuZXJhdGVcIiBbc3FUb29sdGlwXT1cIidjaGF0TWVzc2FnZS5yZWdlbmVyYXRlUmVzcG9uc2UnIHwgdHJhbnNsb2NvXCIgKGNsaWNrKT1cInJlZ2VuZXJhdGUuZW1pdChtZXNzYWdlKVwiPlxuICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtc3luYy1hbHRcIj48L2k+XG4gICAgPC9idXR0b24+XG4gICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc21cIiAqbmdJZj1cImNhbkRlYnVnXCIgW3NxVG9vbHRpcF09XCInY2hhdE1lc3NhZ2Uuc2hvd0xvZ0luZm9ybWF0aW9uJyB8IHRyYW5zbG9jb1wiIChjbGljayk9XCJkZWJ1Zy5lbWl0KG1lc3NhZ2UpO1wiPlxuICAgICAgPGkgY2xhc3M9XCJmYXIgZmEtbGlzdC1hbHRcIj48L2k+XG4gICAgPC9idXR0b24+XG4gIDwvZGl2PlxuXG4gIDwhLS0gTGlzdCBvZiBzdWdnZXN0ZWQgYWN0aW9ucywgaWYgYW55IC0tPlxuICA8ZGl2ICpuZ0lmPVwic3VnZ2VzdGVkQWN0aW9uc1wiIGNsYXNzPVwibXQtMiBtZXNzYWdlLXN1Z2dlc3Rpb25cIj5cbiAgICA8ZGl2IGNsYXNzPVwic3VnZ2VzdGVkLWFjdGlvblwiICpuZ0Zvcj1cImxldCBzdWdnZXN0ZWRBY3Rpb24gb2Ygc3VnZ2VzdGVkQWN0aW9uc1wiIChjbGljayk9XCJzdWdnZXN0QWN0aW9uLmVtaXQoc3VnZ2VzdGVkQWN0aW9uKVwiPlxuICAgICAgPGRpdiBjbGFzcz1cIm1lc3NhZ2UtaWNvblwiIFtzdHlsZS53aWR0aC5weF09XCJpY29uU2l6ZVwiPjwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cIm1lc3NhZ2UtY29udGVudFwiPlxuICAgICAgICA8cD48aSBjbGFzcz1cImZhcyBmYS1jbGlwYm9hcmQtcXVlc3Rpb25cIj48L2k+IHt7c3VnZ2VzdGVkQWN0aW9uLmNvbnRlbnR9fTwvcD5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cblxuICA8bmctdGVtcGxhdGUgI2ltYWdlVG9vbHRpcFRwbCBsZXQtcmVmPlxuICAgIDxJbmxpbmVJbWFnZVJlZmVyZW5jZVxuICAgICAgc3R5bGU9XCJtYXgtd2lkdGg6IDMwdnc7XCJcbiAgICAgIFtpZF09XCJyZWYuaWRcIlxuICAgICAgW3JlZl09XCJyZWYub2JqXCJcbiAgICAgIChvcGVuUHJldmlldyk9XCJvcGVuQXR0YWNobWVudFByZXZpZXcoJGV2ZW50KVwiXG4gICAgICAob3BlbkRvY3VtZW50KT1cIm9wZW5PcmlnaW5hbEF0dGFjaG1lbnQoJGV2ZW50LCAkZXZlbnQuJHBhcnRJZClcIlxuICAgICAgKG9wZW5Nb2RhbCk9XCJoaWRlVG9vbHRpcCgpXCJcbiAgICAvPlxuICA8L25nLXRlbXBsYXRlPlxuXG4gIDxuZy10ZW1wbGF0ZSAjcGFnZVRvb2x0aXBUcGwgbGV0LXJlZj5cbiAgICA8SW5saW5lUGFnZVJlZmVyZW5jZVxuICAgICAgc3R5bGU9XCJtYXgtd2lkdGg6IDMwdnc7XCJcbiAgICAgIFtpZF09XCJyZWYuaWRcIlxuICAgICAgW3JlZl09XCJyZWYub2JqXCJcbiAgICAgIChvcGVuUHJldmlldyk9XCJvcGVuQXR0YWNobWVudFByZXZpZXcoJGV2ZW50KVwiXG4gICAgICAob3BlbkRvY3VtZW50KT1cIm9wZW5PcmlnaW5hbEF0dGFjaG1lbnQoJGV2ZW50LCAkZXZlbnQuJHBhcnRJZClcIlxuICAgICAgKG9wZW5Nb2RhbCk9XCJoaWRlVG9vbHRpcCgpXCJcbiAgICAvPlxuICA8L25nLXRlbXBsYXRlPlxuXG4gIDxuZy10ZW1wbGF0ZSAjdG9vbHRpcFRwbCBsZXQtcmVmPlxuICAgIDxzcS1jaGF0LXJlZmVyZW5jZVxuICAgICAgKm5nSWY9XCIhaGlkZGVuVG9vbHRpcFwiXG4gICAgICBjbGFzcz1cImV4cGFuZGVkXCJcbiAgICAgIFthdHRhY2htZW50XT1cInJlZlwiXG4gICAgICBbcmVmZXJlbmNlXT1cInJlZi5jb250ZXh0SWRcIlxuICAgICAgW3BhcnRJZF09XCJyZWYuJHBhcnRJZFwiXG4gICAgICAob3BlblByZXZpZXcpPVwib3BlbkF0dGFjaG1lbnRQcmV2aWV3KCRldmVudCwgcmVmLiRwYXJ0SWQpXCJcbiAgICAgIChvcGVuRG9jdW1lbnQpPVwib3Blbk9yaWdpbmFsQXR0YWNobWVudCgkZXZlbnQsIHJlZi4kcGFydElkKVwiPlxuICAgIDwvc3EtY2hhdC1yZWZlcmVuY2U+XG4gIDwvbmctdGVtcGxhdGU+XG5cbjwvZGl2PlxuIl19
252
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhdC1tZXNzYWdlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Fzc2lzdGFudC9jaGF0L2NoYXQtbWVzc2FnZS9jaGF0LW1lc3NhZ2UuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYXNzaXN0YW50L2NoYXQvY2hhdC1tZXNzYWdlL2NoYXQtbWVzc2FnZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUNMLHVCQUF1QixFQUV2QixTQUFTLEVBQ1QsUUFBUSxFQUVSLFlBQVksRUFDWixLQUFLLEVBQ0wsS0FBSyxFQUVMLE1BQU0sRUFDTixNQUFNLEVBRVAsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLHFCQUFxQixFQUFFLGFBQWEsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRTFFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNqRSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSw4Q0FBOEMsQ0FBQztBQUN2RixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUduRSxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUMxRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUloRSxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSx1REFBdUQsQ0FBQzs7Ozs7QUFvQi9GLE1BQU0sT0FBTyxvQkFBb0I7SUE0Qy9CLFlBQ1MsRUFBYSxFQUNiLGdCQUFrQyxFQUNsQyxHQUFzQixFQUN0QixFQUFjO1FBSGQsT0FBRSxHQUFGLEVBQUUsQ0FBVztRQUNiLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBa0I7UUFDbEMsUUFBRyxHQUFILEdBQUcsQ0FB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O2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csZ0JBQWdCO3NCQUF4QixLQUFLO2dCQUNHLG9CQUFvQjtzQkFBNUIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUNHLDBCQUEwQjtzQkFBbEMsS0FBSztnQkFDRyx3QkFBd0I7c0JBQWhDLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csYUFBYTtzQkFBckIsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxrQkFBa0I7c0JBQTFCLEtBQUs7Z0JBQ0ksWUFBWTtzQkFBckIsTUFBTTtnQkFDRyxXQUFXO3NCQUFwQixNQUFNO2dCQUNHLGFBQWE7c0JBQXRCLE1BQU07Z0JBQ0csSUFBSTtzQkFBYixNQUFNO2dCQUNHLElBQUk7c0JBQWIsTUFBTTtnQkFDRyxVQUFVO3NCQUFuQixNQUFNO2dCQUNHLElBQUk7c0JBQWIsTUFBTTtnQkFDRyxPQUFPO3NCQUFoQixNQUFNO2dCQUNHLEtBQUs7c0JBQWQsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gXCJAYW5ndWxhci9jb21tb25cIjtcbmltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBjb21wdXRlZCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBpbnB1dCxcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgT3V0cHV0LFxuICBzaWduYWwsXG4gIFNpbXBsZUNoYW5nZXNcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IHByb3ZpZGVUcmFuc2xvY29TY29wZSwgVHJhbnNsb2NvUGlwZSB9IGZyb20gJ0Bqc3ZlcnNlL3RyYW5zbG9jbyc7XG5cbmltcG9ydCB7IENoYXJ0Q29tcG9uZW50IH0gZnJvbSBcIi4uL2NoYXJ0cy9jaGFydC9jaGFydC5jb21wb25lbnRcIjtcbmltcG9ydCB7IEluaXRpYWxzQXZhdGFyQ29tcG9uZW50IH0gZnJvbSBcIi4uL2luaXRpYWxzLWF2YXRhci9pbml0aWFscy1hdmF0YXIuY29tcG9uZW50XCI7XG5pbXBvcnQgeyBNZXNzYWdlQ29udGVudFBpcGUgfSBmcm9tIFwiLi4vcGlwZXMvbWVzc2FnZS1jb250ZW50LnBpcGVcIjtcbmltcG9ydCB7IFByaW5jaXBhbFNlcnZpY2UgfSBmcm9tIFwiLi4vc2VydmljZXMvcHJpbmNpcGFsLnNlcnZpY2VcIjtcbmltcG9ydCB7IFVJU2VydmljZSB9IGZyb20gXCIuLi9zZXJ2aWNlcy91aS5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBTbWFydFJlbmRlcmVyQ29tcG9uZW50IH0gZnJvbSBcIi4uL3NtYXJ0LXJlbmRlcmVyL3NtYXJ0LXJlbmRlcmVyXCI7XG5pbXBvcnQgeyBUb29sdGlwRGlyZWN0aXZlIH0gZnJvbSBcIi4uL3Rvb2x0aXAvdG9vbHRpcC5kaXJlY3RpdmVcIjtcbmltcG9ydCB7IENoYXRDb250ZXh0QXR0YWNobWVudCwgQ2hhdE1lc3NhZ2UsIERvY3VtZW50UGFydCwgU3VnZ2VzdGVkQWN0aW9uIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBUZXh0TWVzc2FnZUNvbnRlbnQgfSBmcm9tIFwiLi4vdHlwZXMvbWVzc2FnZS1jb250ZW50LnR5cGVzXCI7XG5pbXBvcnQgeyBNZXNzYWdlSW1hZ2VSZWZlcmVuY2UgfSBmcm9tIFwiLi4vdHlwZXMvbWVzc2FnZS1yZWZlcmVuY2UudHlwZXNcIjtcbmltcG9ydCB7IENoYXRSZWZlcmVuY2VDb21wb25lbnQgfSBmcm9tIFwiLi4vcmVmZXJlbmNlcy9jaGF0LXJlZmVyZW5jZS9jaGF0LXJlZmVyZW5jZS5jb21wb25lbnRcIjtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiBcInNxLWNoYXQtbWVzc2FnZVwiLFxuICB0ZW1wbGF0ZVVybDogXCIuL2NoYXQtbWVzc2FnZS5jb21wb25lbnQuaHRtbFwiLFxuICBzdHlsZVVybHM6IFtcIi4vY2hhdC1tZXNzYWdlLmNvbXBvbmVudC5zY3NzXCJdLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIENvbW1vbk1vZHVsZSxcbiAgICBUb29sdGlwRGlyZWN0aXZlLFxuICAgIEluaXRpYWxzQXZhdGFyQ29tcG9uZW50LFxuICAgIENoYXRSZWZlcmVuY2VDb21wb25lbnQsXG4gICAgQ2hhcnRDb21wb25lbnQsXG4gICAgTWVzc2FnZUNvbnRlbnRQaXBlLFxuICAgIFRyYW5zbG9jb1BpcGUsXG4gICAgU21hcnRSZW5kZXJlckNvbXBvbmVudFxuICBdLFxuICBwcm92aWRlcnM6IFtwcm92aWRlVHJhbnNsb2NvU2NvcGUoJ2NoYXQtbWVzc2FnZScpXSxcbn0pXG5leHBvcnQgY2xhc3MgQ2hhdE1lc3NhZ2VDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMge1xuICBpZCA9IGlucHV0PHN0cmluZz4oKTtcblxuICBASW5wdXQoKSBtZXNzYWdlOiBDaGF0TWVzc2FnZTtcbiAgQElucHV0KCkgY29udmVyc2F0aW9uOiBDaGF0TWVzc2FnZVtdO1xuICBASW5wdXQoKSBzdWdnZXN0ZWRBY3Rpb25zOiBTdWdnZXN0ZWRBY3Rpb25bXSB8IHVuZGVmaW5lZDtcbiAgQElucHV0KCkgYXNzaXN0YW50TWVzc2FnZUljb246IHN0cmluZztcbiAgQElucHV0KCkgdXNlck1lc3NhZ2VJY29uOiBzdHJpbmc7XG4gIEBJbnB1dCgpIGNvbm5lY3Rpb25FcnJvck1lc3NhZ2VJY29uOiBzdHJpbmc7XG4gIEBJbnB1dCgpIHNlYXJjaFdhcm5pbmdNZXNzYWdlSWNvbjogc3RyaW5nO1xuICBASW5wdXQoKSBzdHJlYW1pbmc6IGJvb2xlYW47XG4gIEBJbnB1dCgpIGNhbkVkaXQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgY2FuUmVnZW5lcmF0ZTogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBjYW5Db3B5OiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIGNhbkRlYnVnOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIGNhbkxpa2U6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgY2FuRGlzbGlrZTogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBjb2xsYXBzZVJlZmVyZW5jZXM6IGJvb2xlYW4gPSB0cnVlO1xuICBAT3V0cHV0KCkgb3BlbkRvY3VtZW50ID0gbmV3IEV2ZW50RW1pdHRlcjx7IHJlZmVyZW5jZTogQ2hhdENvbnRleHRBdHRhY2htZW50IH0+KCk7XG4gIEBPdXRwdXQoKSBvcGVuUHJldmlldyA9IG5ldyBFdmVudEVtaXR0ZXI8eyByZWZlcmVuY2U6IENoYXRDb250ZXh0QXR0YWNobWVudCB9PigpO1xuICBAT3V0cHV0KCkgc3VnZ2VzdEFjdGlvbiA9IG5ldyBFdmVudEVtaXR0ZXI8U3VnZ2VzdGVkQWN0aW9uPigpO1xuICBAT3V0cHV0KCkgZWRpdCA9IG5ldyBFdmVudEVtaXR0ZXI8Q2hhdE1lc3NhZ2U+KCk7XG4gIEBPdXRwdXQoKSBjb3B5ID0gbmV3IEV2ZW50RW1pdHRlcjxDaGF0TWVzc2FnZT4oKTtcbiAgQE91dHB1dCgpIHJlZ2VuZXJhdGUgPSBuZXcgRXZlbnRFbWl0dGVyPENoYXRNZXNzYWdlPigpO1xuICBAT3V0cHV0KCkgbGlrZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIGRpc2xpa2UgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBkZWJ1ZyA9IG5ldyBFdmVudEVtaXR0ZXI8Q2hhdE1lc3NhZ2U+KCk7XG5cbiAgLy8gc2lnbmFsIGJhc2VkIHNldCBvZiByZWZlcmVuY2VzIHRvIGF2b2lkIGR1cGxpY2F0ZXNcbiAgcmVmcyA9IHNpZ25hbDxudW1iZXJbXT4oW10pO1xuICByZWZlcmVuY2VzID0gY29tcHV0ZWQoKCkgPT5cbiAgICB0aGlzLnJlZnMoKS5zbGljZSgpLnNvcnQoKGEsIGIpID0+IGEgLSBiKS5tYXAoKHIpID0+IFwiXCIgKyByKVxuICApO1xuICByZWZlcmVuY2VNYXAgPSBuZXcgTWFwPHN0cmluZywgQ2hhdENvbnRleHRBdHRhY2htZW50PigpO1xuICBpbWFnZVJlZmVyZW5jZXNNYXAgPSBuZXcgTWFwPHN0cmluZywgTWVzc2FnZUltYWdlUmVmZXJlbmNlPigpO1xuICBwYWdlUmVmZXJlbmNlc01hcCA9IG5ldyBNYXA8c3RyaW5nLCBNZXNzYWdlSW1hZ2VSZWZlcmVuY2U+KCk7XG4gIGNvbGxhcHNlUHJvZ3Jlc3M6IGJvb2xlYW47XG4gIGljb25TaXplID0gMjQ7XG5cbiAgaGlkZGVuVG9vbHRpcDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8vIHVzZWQgYnkgdGhlIHRlbXBsYXRlXG4gIEFycmF5ID0gQXJyYXk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHVpOiBVSVNlcnZpY2UsXG4gICAgcHVibGljIHByaW5jaXBhbFNlcnZpY2U6IFByaW5jaXBhbFNlcnZpY2UsXG4gICAgcHVibGljIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgcHVibGljIGVsOiBFbGVtZW50UmVmXG4gICkge31cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgaWYgKGNoYW5nZXMuc3RyZWFtaW5nKSB7XG4gICAgICB0aGlzLmNvbGxhcHNlUHJvZ3Jlc3MgPSAhdGhpcy5zdHJlYW1pbmc7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubWVzc2FnZT8ucm9sZSA9PT0gXCJhc3Npc3RhbnRcIikge1xuICAgICAgdGhpcy5yZWZlcmVuY2VNYXAuY2xlYXIoKTtcbiAgICAgIGZvciAobGV0IG0gb2YgdGhpcy5jb252ZXJzYXRpb24pIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIG0uYWRkaXRpb25hbFByb3BlcnRpZXMuJGF0dGFjaG1lbnQgJiZcbiAgICAgICAgICBtLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRhdHRhY2htZW50Lmxlbmd0aCA+IDBcbiAgICAgICAgKSB7XG4gICAgICAgICAgZm9yIChjb25zdCBhdHRhY2htZW50IG9mIG0uYWRkaXRpb25hbFByb3BlcnRpZXMuJGF0dGFjaG1lbnQpIHtcbiAgICAgICAgICAgIC8vIHNraXAgZW1wdHkgYXR0YWNobWVudFxuICAgICAgICAgICAgaWYgKCFhdHRhY2htZW50KSBjb250aW51ZTtcblxuICAgICAgICAgICAgdGhpcy5yZWZlcmVuY2VNYXAuc2V0KFwiXCIgKyBhdHRhY2htZW50LmNvbnRleHRJZCwge1xuICAgICAgICAgICAgICAuLi5hdHRhY2htZW50LFxuICAgICAgICAgICAgICAkcGFydElkOiBhdHRhY2htZW50LnBhcnRzPy5bMF0/LnBhcnRJZCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCEhYXR0YWNobWVudC5wYXJ0cyAmJiBhdHRhY2htZW50LnBhcnRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhdHRhY2htZW50LnBhcnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVmSWQgPSBgJHthdHRhY2htZW50LmNvbnRleHRJZH0uJHthdHRhY2htZW50LnBhcnRzW2ldLnBhcnRJZH1gO1xuICAgICAgICAgICAgICAgIHRoaXMucmVmZXJlbmNlTWFwLnNldChyZWZJZCwge1xuICAgICAgICAgICAgICAgICAgLi4uYXR0YWNobWVudCxcbiAgICAgICAgICAgICAgICAgICRwYXJ0SWQ6IGF0dGFjaG1lbnQucGFydHM/LltpXT8ucGFydElkLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5wcm9jZXNzTWVzc2FnZVR5cGUobSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZ2V0RW1iZWRkZWRJbWFnZVJlZmVyZW5jZShyZWY6IHN0cmluZyk6IE1lc3NhZ2VJbWFnZVJlZmVyZW5jZSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgW2RvYywgcGFydCwgaW1hZ2VdID0gcmVmLnNwbGl0KFwiLlwiKTtcbiAgICBjb25zdCBpbWFnZXMgPSB0aGlzLnJlZmVyZW5jZU1hcC5nZXQoZG9jKT8ucGFydHM/LlsrcGFydCAtIDFdPy5pbWFnZXM7XG5cbiAgICBpZiAoIWltYWdlcyB8fCBpbWFnZXMubGVuZ3RoID09PSAwIHx8IHR5cGVvZiBpbWFnZXNbMF0gIT09IFwib2JqZWN0XCIpXG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgY29uc3QgbWVzc2FnZUltYWdlUmVmZXJlbmNlOiBNZXNzYWdlSW1hZ2VSZWZlcmVuY2UgPSBPYmplY3QuYXNzaWduKFxuICAgICAge1xuICAgICAgICBhcnRpY2xlOiB0aGlzLnJlZmVyZW5jZU1hcC5nZXQoZG9jKT8ucmVjb3JkLFxuICAgICAgICBhcnRpY2xlSWQ6IHRoaXMucmVmZXJlbmNlTWFwLmdldChkb2MpPy5yZWNvcmRJZCxcbiAgICAgICAgcGFydHM6IFt0aGlzLnJlZmVyZW5jZU1hcC5nZXQoZG9jKT8ucGFydHM/LlsrcGFydCAtIDFdXSBhcyBEb2N1bWVudFBhcnRbXSwgLy8gc2luY2UgaXQgaXMgbm90IHBvc3NpYmxlIHRvIGxvY2F0ZSB0aGUgaW1hZ2UgYnkgaXRzZWxmLCB3ZSB1c2UgdGhlIHBhcnQgaW4gd2hpY2ggaXQgaXMgY29udGFpbmVkXG4gICAgICAgICRwYXJ0SWQ6IDEgLy8gQWx3YXlzIDEgZm9yIGltYWdlIHJlZmVyZW5jZXMgc2luY2UgcGFydHMgYXJyYXkgY29udGFpbnMgb25seSBvbmUgZWxlbWVudCByZWZlcmVuY2luZyB0aGUgcGFydCBjb250YWluaW5nIHRoZSBpbWFnZVxuICAgICAgfSxcbiAgICAgIGltYWdlc1sraW1hZ2UgLSAxXVxuICAgICk7XG5cbiAgICAvLyBzYXZlIHJlZmVyZW5jZSBpbiBtYXAgZm9yIHJlZmVyZW5jZSBsaXN0XG4gICAgaWYgKCF0aGlzLmltYWdlUmVmZXJlbmNlc01hcC5oYXMocmVmKSkgdGhpcy5pbWFnZVJlZmVyZW5jZXNNYXAuc2V0KHJlZiwgbWVzc2FnZUltYWdlUmVmZXJlbmNlKTtcblxuICAgIHJldHVybiBtZXNzYWdlSW1hZ2VSZWZlcmVuY2U7XG4gIH1cblxuICBnZXRFbWJlZGRlZFBhZ2VSZWZlcmVuY2UocmVmOiBzdHJpbmcpOiBNZXNzYWdlSW1hZ2VSZWZlcmVuY2UgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IFtkb2MsIHBhZ2VdID0gcmVmLnNwbGl0KFwiLlwiKTtcbiAgICBjb25zdCBwYWdlUmVmID0gdGhpcy5yZWZlcmVuY2VNYXAuZ2V0KGRvYyk/LnBhZ2VzPy5maW5kKHggPT4geC5wYWdlTnVtYmVyID09PSArcGFnZSk7XG5cbiAgICBpZiAoIXBhZ2VSZWYgfHwgdHlwZW9mIHBhZ2VSZWYgIT09IFwib2JqZWN0XCIpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICBjb25zdCBtZXNzYWdlUGFnZVJlZmVyZW5jZTogTWVzc2FnZUltYWdlUmVmZXJlbmNlID0gT2JqZWN0LmFzc2lnbihcbiAgICAgIHtcbiAgICAgICAgYXJ0aWNsZTogdGhpcy5yZWZlcmVuY2VNYXAuZ2V0KGRvYyk/LnJlY29yZCxcbiAgICAgICAgYXJ0aWNsZUlkOiB0aGlzLnJlZmVyZW5jZU1hcC5nZXQoZG9jKT8ucmVjb3JkSWQsXG4gICAgICAgIHBhcnRzOiBbe1xuICAgICAgICAgIG9mZnNldDogcGFnZVJlZi5vZmZTZXQhLFxuICAgICAgICAgIGxlbmd0aDogcGFnZVJlZi5sZW5ndGghXG4gICAgICAgIH1dLCAvLyBwYXJ0cyBoZXJlIGlzIGFuIGFycmF5IHdpdGggYSBzaW5nbGUgcGFydCByZXByZXNlbnRpbmcgdGhlIHBhZ2UgcmVmZXJlbmNlXG4gICAgICAgICRwYXJ0SWQ6IDEgLy8gQWx3YXlzIDEgZm9yIHBhZ2UgcmVmZXJlbmNlcyBzaW5jZSBwYXJ0cyBhcnJheSBjb250YWlucyBvbmx5IG9uZSBlbGVtZW50IHJlZmVyZW5jaW5nIHRoZSBwYWdlXG4gICAgICB9LFxuICAgICAgcGFnZVJlZlxuICAgICk7XG5cbiAgICAvLyBzYXZlIHJlZmVyZW5jZSBpbiBtYXAgZm9yIHJlZmVyZW5jZSBsaXN0XG4gICAgaWYgKCF0aGlzLnBhZ2VSZWZlcmVuY2VzTWFwLmhhcyhyZWYpKSB0aGlzLnBhZ2VSZWZlcmVuY2VzTWFwLnNldChyZWYsIG1lc3NhZ2VQYWdlUmVmZXJlbmNlKTtcblxuICAgIHJldHVybiBtZXNzYWdlUGFnZVJlZmVyZW5jZTtcbiAgfVxuXG4gIGdldCBuYW1lKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuICF0aGlzLnByaW5jaXBhbFNlcnZpY2UucHJpbmNpcGFsXG4gICAgICA/IFwiXCJcbiAgICAgIDogKHRoaXMucHJpbmNpcGFsU2VydmljZS5wcmluY2lwYWxbXCJmdWxsTmFtZVwiXSBhcyBzdHJpbmcpIHx8XG4gICAgICAgICAgdGhpcy5wcmluY2lwYWxTZXJ2aWNlLnByaW5jaXBhbC5uYW1lO1xuICB9XG5cbiAgZ2V0IGlzQWRtaW4oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMucHJpbmNpcGFsU2VydmljZS5wcmluY2lwYWw/LmlzQWRtaW5pc3RyYXRvciB8fCBmYWxzZTtcbiAgfVxuXG4gIHByb2Nlc3NNZXNzYWdlVHlwZShtZXNzYWdlOiBDaGF0TWVzc2FnZSkge1xuICAgIC8vIFByb2Nlc3MgbWVzc2FnZSB0eXBlIHdoZW4gc3BlYyBpcyBkb25lXG4gICAgLy8gbm9wIGZvciBuZXcgbWVzc2FnZSB0eXBlc1xuICAgIGlmICh0eXBlb2YgbWVzc2FnZS5jb250ZW50ICE9PSBcInN0cmluZ1wiKSByZXR1cm47XG5cbiAgICAvLyBMZWdhY3kgbWVzc2FnZSB0eXBlXG4gICAgaWYgKG1lc3NhZ2UuY29udGVudC5zdGFydHNXaXRoKFwiPGNoYXJ0anM+XCIpKSB7XG4gICAgICBtZXNzYWdlLm1lc3NhZ2VUeXBlID0gXCJDSEFSVFwiO1xuICAgIH0gZWxzZSB7XG4gICAgICBtZXNzYWdlLm1lc3NhZ2VUeXBlID0gXCJNQVJLRE9XTlwiO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9jZXNzZXMgYSByZWZlcmVuY2Ugc3RyaW5nIGJ5IHZhbGlkYXRpbmcgYW5kIGFkZGluZyBpdCB0byB0aGUgc2V0IG9mIHJlZmVyZW5jZXMgaWYgYXBwbGljYWJsZS5cbiAgICpcbiAgICogLSBJZ25vcmVzIGVtcHR5IG9yIGZhbHN5IHJlZmVyZW5jZXMuXG4gICAqIC0gSWdub3JlcyByZWZlcmVuY2VzIHRoYXQgYXJlIG5vdCBudW1lcmljLlxuICAgKiAtIElnbm9yZXMgcmVmZXJlbmNlcyB0aGF0IGFscmVhZHkgZXhpc3QgaW4gdGhlIHNldC5cbiAgICogLSBDb252ZXJ0cyB0aGUgcmVmZXJlbmNlIHRvIGEgbnVtYmVyIGFuZCBhZGRzIGl0IHRvIHRoZSBzZXQgb2YgcmVmZXJlbmNlcy5cbiAgICpcbiAgICogQHBhcmFtIHJlZiAtIFRoZSByZWZlcmVuY2Ugc3RyaW5nIHRvIHByb2Nlc3MuXG4gICAqL1xuICBwcm9jZXNzUmVmZXJlbmNlcyhyZWY6IHN0cmluZykge1xuICAgIGlmICghcmVmKSByZXR1cm47XG4gICAgaWYgKGlzTmFOKCtyZWYpKSByZXR1cm47XG4gICAgY29uc3QgcmVmTnVtID0gK3JlZjtcbiAgICBpZiAodGhpcy5yZWZzKCkuaW5jbHVkZXMocmVmTnVtKSkgcmV0dXJuO1xuICAgIHRoaXMucmVmcy51cGRhdGUoYXJyID0+IFsuLi5hcnIsIHJlZk51bV0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfY29weVRvQ2xpcGJvYXJkKGNvbnRlbnQ6IHN0cmluZykge1xuICAgIHRoaXMudWkuY29weVRvQ2xpcGJvYXJkKGNvbnRlbnQpO1xuICB9XG5cbiAgY29weU1lc3NhZ2UobWVzc2FnZTogQ2hhdE1lc3NhZ2UpIHtcbiAgICBsZXQgY29udGVudDogc3RyaW5nID0gXCJcIjtcblxuICAgIGlmICh0eXBlb2YgbWVzc2FnZS5jb250ZW50ID09PSBcInN0cmluZ1wiKVxuICAgICAgY29udGVudCA9IG1lc3NhZ2UuY29udGVudDtcbiAgICBlbHNlIGlmIChBcnJheS5pc0FycmF5KG1lc3NhZ2UuY29udGVudCkpXG4gICAgICBjb250ZW50ID0gKG1lc3NhZ2UuY29udGVudFswXSBhcyBUZXh0TWVzc2FnZUNvbnRlbnQpLnRleHQ7XG4gICAgZWxzZSB7XG4gICAgICBjb25zb2xlLmVycm9yKFwiVW5zdXBwb3J0ZWQgbWVzc2FnZSBjb250ZW50IHR5cGVcIiwgdHlwZW9mIG1lc3NhZ2UuY29udGVudCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29udGVudCA9IGNvbnRlbnQucmVwbGFjZUFsbCgvXFxzKlxcW1teXFxdXSpdXFxzKi9nLCBcIlwiKTtcblxuICAgIHRoaXMuX2NvcHlUb0NsaXBib2FyZChjb250ZW50KTtcbiAgICB0aGlzLmNvcHkuZW1pdChtZXNzYWdlKTtcbiAgfVxuXG4gIG9wZW5BdHRhY2htZW50UHJldmlldyhhdHRhY2htZW50OiBDaGF0Q29udGV4dEF0dGFjaG1lbnQpIHtcbiAgICB0aGlzLm9wZW5QcmV2aWV3LmVtaXQoeyByZWZlcmVuY2U6IGF0dGFjaG1lbnQgfSk7XG4gICAgdGhpcy5oaWRlVG9vbHRpcCgpO1xuICB9XG5cbiAgb3Blbk9yaWdpbmFsQXR0YWNobWVudChhdHRhY2htZW50OiBDaGF0Q29udGV4dEF0dGFjaG1lbnQpIHtcbiAgICB0aGlzLm9wZW5Eb2N1bWVudC5lbWl0KHsgcmVmZXJlbmNlOiBhdHRhY2htZW50IH0pO1xuICAgIHRoaXMuaGlkZVRvb2x0aXAoKTtcbiAgfVxuXG4gIGhpZGVUb29sdGlwKCk6IHZvaWQge1xuICAgIHRoaXMuaGlkZGVuVG9vbHRpcCA9IHRydWU7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLmhpZGRlblRvb2x0aXAgPSBmYWxzZTtcbiAgICB9KTtcbiAgfVxufVxuIiwiPCEtLSBNZXNzYWdlIGljb24gLS0+XG48c3BhbiBjbGFzcz1cIm1lc3NhZ2UtaWNvblwiIFt0aXRsZV09XCJtZXNzYWdlPy5yb2xlXCI+XG4gIDxpIGNsYXNzPVwiZC1ibG9ja1wiIFtzdHlsZS53aWR0aC5weF09XCJpY29uU2l6ZVwiICpuZ0lmPVwiIW1lc3NhZ2VcIj48L2k+XG4gIDxuZy1jb250YWluZXIgW25nU3dpdGNoXT1cIm1lc3NhZ2U/LnJvbGVcIj5cbiAgICA8IS0tIEZvciAnYXNzaXN0YW50JyAtLT5cbiAgICA8aSAqbmdTd2l0Y2hDYXNlPVwiJ2Fzc2lzdGFudCdcIiBbbmdDbGFzc109XCJhc3Npc3RhbnRNZXNzYWdlSWNvblwiIFtzdHlsZS4tLXNxLXNpemUucHhdPVwiaWNvblNpemVcIj48L2k+XG5cbiAgICA8IS0tIEZvciAndXNlcicgLS0+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ3VzZXInXCI+XG4gICAgICA8aSAqbmdJZj1cIiEhdXNlck1lc3NhZ2VJY29uOyBlbHNlIGluaXRpYWxzQXZhdGFyXCIgW25nQ2xhc3NdPVwidXNlck1lc3NhZ2VJY29uXCIgW3N0eWxlLi0tc3Etc2l6ZS5weF09XCJpY29uU2l6ZVwiPjwvaT5cbiAgICAgIDxuZy10ZW1wbGF0ZSAjaW5pdGlhbHNBdmF0YXI+XG4gICAgICAgIDxzcS1pbml0aWFscy1hdmF0YXIgW2Z1bGxOYW1lXT1cIm5hbWVcIj48L3NxLWluaXRpYWxzLWF2YXRhcj5cbiAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgPC9uZy1jb250YWluZXI+XG5cbiAgICA8IS0tIEZvciAnY29ubmVjdGlvbi1lcnJvcicgLS0+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ2Nvbm5lY3Rpb24tZXJyb3InXCI+XG4gICAgICA8aSAqbmdJZj1cIiEhY29ubmVjdGlvbkVycm9yTWVzc2FnZUljb247IGVsc2UgZGVmYXVsdEVycm9ySWNvblwiIFtuZ0NsYXNzXT1cImNvbm5lY3Rpb25FcnJvck1lc3NhZ2VJY29uXCIgW3N0eWxlLi0tc3Etc2l6ZS5weF09XCJpY29uU2l6ZVwiPjwvaT5cbiAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdEVycm9ySWNvbj5cbiAgICAgICAgPHN2ZyBbc3R5bGUuLS1zcS1zaXplLnB4XT1cImljb25TaXplXCIgY2xhc3M9XCJjb25uZWN0aW9uLWVycm9yXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgNTEyIDUxMlwiPlxuICAgICAgICAgIDxwYXRoIGZpbGw9XCJjdXJyZW50Q29sb3JcIiBkPVwiTTE3LjEgMjkyYy0xMi45LTIyLjMtMTIuOS00OS43IDAtNzJMMTA1LjQgNjcuMWMxMi45LTIyLjMgMzYuNi0zNiA2Mi40LTM2bDE3Ni42IDBjMjUuNyAwIDQ5LjUgMTMuNyA2Mi40IDM2TDQ5NC45IDIyMGMxMi45IDIyLjMgMTIuOSA0OS43IDAgNzJMNDA2LjYgNDQ0LjljLTEyLjkgMjIuMy0zNi42IDM2LTYyLjQgMzZsLTE3Ni42IDBjLTI1LjcgMC00OS41LTEzLjctNjIuNC0zNkwxNy4xIDI5MnpNMjU2IDEyOGMtMTMuMyAwLTI0IDEwLjctMjQgMjRsMCAxMTJjMCAxMy4zIDEwLjcgMjQgMjQgMjRzMjQtMTAuNyAyNC0yNGwwLTExMmMwLTEzLjMtMTAuNy0yNC0yNC0yNHptMzIgMjI0YTMyIDMyIDAgMSAwIC02NCAwIDMyIDMyIDAgMSAwIDY0IDB6XCIvPlxuICAgICAgICA8L3N2Zz5cbiAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgPC9uZy1jb250YWluZXI+XG5cbiAgICA8IS0tIEZvciAnc2VhcmNoLXdhcm5pbmcnIC0tPlxuICAgIDxuZy1jb250YWluZXIgKm5nU3dpdGNoQ2FzZT1cIidzZWFyY2gtd2FybmluZydcIj5cbiAgICAgIDxpICpuZ0lmPVwiISFzZWFyY2hXYXJuaW5nTWVzc2FnZUljb247IGVsc2UgZGVmYXVsdFdhcm5pbmdJY29uXCIgW25nQ2xhc3NdPVwic2VhcmNoV2FybmluZ01lc3NhZ2VJY29uXCIgW3N0eWxlLi0tc3Etc2l6ZS5weF09XCJpY29uU2l6ZVwiPjwvaT5cbiAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdFdhcm5pbmdJY29uPlxuICAgICAgICA8c3ZnIFtzdHlsZS4tLXNxLXNpemUucHhdPVwiaWNvblNpemVcIiBjbGFzcz1cInNlYXJjaC13YXJuaW5nXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgMzg0IDUxMlwiPlxuICAgICAgICAgIDxwYXRoIGZpbGw9XCJjdXJyZW50Q29sb3JcIiBkPVwiTTI3MiAzODRjOS42LTMxLjkgMjkuNS01OS4xIDQ5LjItODYuMmMwIDAgMCAwIDAgMGM1LjItNy4xIDEwLjQtMTQuMiAxNS40LTIxLjRjMTkuOC0yOC41IDMxLjQtNjMgMzEuNC0xMDAuM0MzNjggNzguOCAyODkuMiAwIDE5MiAwUzE2IDc4LjggMTYgMTc2YzAgMzcuMyAxMS42IDcxLjkgMzEuNCAxMDAuM2M1IDcuMiAxMC4yIDE0LjMgMTUuNCAyMS40YzAgMCAwIDAgMCAwYzE5LjggMjcuMSAzOS43IDU0LjQgNDkuMiA4Ni4ybDE2MCAwek0xOTIgNTEyYzQ0LjIgMCA4MC0zNS44IDgwLTgwbDAtMTYtMTYwIDAgMCAxNmMwIDQ0LjIgMzUuOCA4MCA4MCA4MHptMC00NDhjMTMuMyAwIDI0IDEwLjcgMjQgMjRsMCAxMTJjMCAxMy4zLTEwLjcgMjQtMjQgMjRzLTI0LTEwLjctMjQtMjRsMC0xMTJjMC0xMy4zIDEwLjctMjQgMjQtMjR6TTE2MCAyODhhMzIgMzIgMCAxIDEgNjQgMCAzMiAzMiAwIDEgMSAtNjQgMHpcIi8+XG4gICAgICAgIDwvc3ZnPlxuICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgPC9uZy1jb250YWluZXI+XG48L3NwYW4+XG5cbjwhLS0gTWVzc2FnZSBib2R5IC0tPlxuPGRpdiBjbGFzcz1cImZsZXgtZ3Jvdy0xIHBvc2l0aW9uLXJlbGF0aXZlIHJlbGF0aXZlXCIgc3R5bGU9XCJtaW4td2lkdGg6IDA7XCIgW25nQ2xhc3NdPVwiJ21lc3NhZ2UtJyttZXNzYWdlLnJvbGVcIj5cblxuICA8IS0tIFByb2dyZXNzIHN0ZXBzIC0tPlxuICA8ZGl2ICpuZ0lmPVwibWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcy4kcHJvZ3Jlc3MgYXMgcHJvZ3Jlc3NcIiBjbGFzcz1cInNtYWxsIG1zLTMgbWItMlwiPlxuICAgIDxkZXRhaWxzIHJvbGU9XCJidXR0b25cIiBjbGFzcz1cInNlbGVjdC1ub25lXCIgW29wZW5dPVwiIWNvbGxhcHNlUHJvZ3Jlc3NcIj5cbiAgICAgIDxzdW1tYXJ5IGNsYXNzPVwidGV4dC1tdXRlZFwiPlxuICAgICAgICB7eyAnY2hhdE1lc3NhZ2Uudmlld1Byb2dyZXNzJyB8IHRyYW5zbG9jbyB9fVxuICAgICAgPC9zdW1tYXJ5PlxuICAgICAgPHVsIGNsYXNzPVwibGlzdC11bnN0eWxlZFwiPlxuICAgICAgICA8bGkgKm5nRm9yPVwibGV0IHN0ZXAgb2YgcHJvZ3Jlc3NcIj5cbiAgICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1mdyBmYS1jaGVjayB0ZXh0LXN1Y2Nlc3NcIiAqbmdJZj1cInN0ZXAuZG9uZVwiPjwvaT5cbiAgICAgICAgICA8aSBjbGFzcz1cImZhcyBmYS1zcGlubmVyIGZhLXB1bHNlIHN0ZXAtb25nb2luZ1wiICpuZ0lmPVwiIXN0ZXAuZG9uZSAmJiBzdHJlYW1pbmdcIj48L2k+XG4gICAgICAgICAgPGkgY2xhc3M9XCJmYS1zb2xpZCBmYS1iYW4gc3RlcC1lcnJvclwiICpuZ0lmPVwiIXN0ZXAuZG9uZSAmJiAhc3RyZWFtaW5nXCI+PC9pPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwibXMtMiBmdy1ib2xkXCI+e3tzdGVwLnRpdGxlfX08L3NwYW4+XG4gICAgICAgICAgPHNwYW4gKm5nSWY9XCJzdGVwLmNvbnRlbnRcIiBbaW5uZXJIVE1MXT1cIic6ICcgKyBzdGVwLmNvbnRlbnRcIj48L3NwYW4+XG4gICAgICAgIDwvbGk+XG4gICAgICA8L3VsPlxuICAgIDwvZGV0YWlscz5cbiAgPC9kaXY+XG5cbiAgPCEtLSBNZXNzYWdlIGNvbnRlbnQgLS0+XG4gIDxkaXYgY2xhc3M9XCJtZXNzYWdlLWNvbnRlbnRcIiAqbmdJZj1cIm1lc3NhZ2UuY29udGVudFwiPlxuXG4gICAgPCEtLSBDdXN0b20gcmVuZGVyaW5nIGZvciBXUFMsIHRvIGJlIHJlbW92ZSB3aXRoIGh0dHBzOi8vc2luZXF1YS5hdGxhc3NpYW4ubmV0L2Jyb3dzZS9FUy0yMzcxMCAtLT5cbiAgICA8ZGl2ICpuZ0lmPVwibWVzc2FnZT8ucm9sZSA9PT0gJ2Fzc2lzdGFudCcgJiYgbWVzc2FnZS5tZXNzYWdlVHlwZSA9PT0gJ0NIQVJUJ1wiPlxuICAgICAgPHNxLWFzc2lzdGFudC1jaGFydCBbcmF3Q2hhcnREYXRhXT1cIm1lc3NhZ2UuY29udGVudFwiPjwvc3EtYXNzaXN0YW50LWNoYXJ0PlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBUaGlzIHNlY3Rpb24gaXMgcmVzcG9uc2libGUgZm9yIGN1c3RvbWl6aW5nIHRoZSB0ZW1wbGF0ZSBub2RlcyB1c2VkIGluIHRoZSBhcHBsaWNhdGlvbi5cbiAgICAgICAgVGVtcGxhdGUgbm9kZXMgYXJlIHByZWRlZmluZWQgc3RydWN0dXJlcyB0aGF0IHNlcnZlIGFzIGJsdWVwcmludHMgZm9yIGNyZWF0aW5nL2N1c3RvbWl6aW5nIGR5bmFtaWMgY29udGVudCAtLT5cblxuXG4gICAgQGlmKG1lc3NhZ2U/LnJvbGUgPT09ICdhc3Npc3RhbnQnICYmIG1lc3NhZ2UubWVzc2FnZVR5cGUgIT09ICdDSEFSVCcpIHtcbiAgICAgIDxTbWFydFJlbmRlcmVyXG4gICAgICAgIFttZXNzYWdlXT1cIm1lc3NhZ2UuY29udGVudCB8IG1lc3NhZ2VDb250ZW50XCJcbiAgICAgICAgW2NvbnRleHRdPVwie1xuICAgICAgICAgIGdldEVtYmVkZGVkUGFnZVJlZmVyZW5jZTogZ2V0RW1iZWRkZWRQYWdlUmVmZXJlbmNlLmJpbmQodGhpcyksXG4gICAgICAgICAgZ2V0RW1iZWRkZWRJbWFnZVJlZmVyZW5jZTogZ2V0RW1iZWRkZWRJbWFnZVJlZmVyZW5jZS5iaW5kKHRoaXMpLFxuICAgICAgICAgIHJlZmVyZW5jZXNNYXA6IHJlZmVyZW5jZU1hcCxcbiAgICAgICAgICByZWZlcmVuY2VzOiBwcm9jZXNzUmVmZXJlbmNlcy5iaW5kKHRoaXMpLFxuICAgICAgICAgIHJhbms6IGlkKClcbiAgICAgICAgfVwiPlxuICAgICAgPC9TbWFydFJlbmRlcmVyPlxuICAgIH1cblxuICAgIDxwICpuZ0lmPVwibWVzc2FnZT8ucm9sZSA9PT0gJ3VzZXInIHx8IG1lc3NhZ2U/LnJvbGUgPT09ICdzZWFyY2gtd2FybmluZycgfHwgbWVzc2FnZT8ucm9sZSA9PT0gJ2Nvbm5lY3Rpb24tZXJyb3InXCI+e3sgbWVzc2FnZS5jb250ZW50IHwgbWVzc2FnZUNvbnRlbnQgfX08L3A+XG5cbiAgICA8IS0tIExpc3Qgb2YgcmVmZXJlbmNlLCBpZiBhbnkgLS0+XG4gIEBsZXQgcmVmZXJlbmNlc0FycmF5ID0gcmVmZXJlbmNlcygpO1xuICAgIEBpZiAocmVmZXJlbmNlc0FycmF5Py5sZW5ndGggPiAwIHx8IGltYWdlUmVmZXJlbmNlc01hcD8uc2l6ZSA+IDAgfHwgcGFnZVJlZmVyZW5jZXNNYXA/LnNpemUgPiAwKSB7XG4gICAgICA8ZGl2IGNsYXNzPVwicmVmZXJlbmNlc1wiPlxuICAgICAgICA8ZGV0YWlscyByb2xlPVwiYnV0dG9uXCIgY2xhc3M9XCJzZWxlY3Qtbm9uZVwiIFtvcGVuXT1cIiFjb2xsYXBzZVJlZmVyZW5jZXNcIj5cbiAgICAgICAgICA8c3VtbWFyeSBjbGFzcz1cInJlZmVyZW5jZXMtdGl0bGVcIj57eyAnY2hhdE1lc3NhZ2UucmVmZXJlbmNlcycgfCB0cmFuc2xvY28gfX08L3N1bW1hcnk+XG4gICAgICAgICAgPHVsPlxuICAgICAgICAgICAgQGZvciAocmVmZXJlbmNlIG9mIHJlZmVyZW5jZXNBcnJheTsgdHJhY2sgJGluZGV4KSB7XG4gICAgICAgICAgICAgIEBsZXQgYXR0YWNobWVudCA9IHJlZmVyZW5jZU1hcC5nZXQocmVmZXJlbmNlKTtcbiAgICAgICAgICAgICAgPCEtLSBPbmx5IGRpc3BsYXkgdGhlIHJlZmVyZW5jZSB3aGVuIHRoZSBrZXkgaXMgYSBpbnRlZ2VyIG5vdCBhIGRlY2ltYWwgLS0+XG4gICAgICAgICAgICAgICBAaWYoYXR0YWNobWVudCkge1xuICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cInRleHQtdHJ1bmNhdGVcIj5cbiAgICAgICAgICAgICAgICAgIDxzcS1jaGF0LXJlZmVyZW5jZVxuICAgICAgICAgICAgICAgICAgICBbY2xhc3MuZXhwYW5kZWRdPVwiYXR0YWNobWVudD8uJGV4cGFuZGVkXCJcbiAgICAgICAgICAgICAgICAgICAgW2F0dGFjaG1lbnRdPVwiYXR0YWNobWVudFwiXG4gICAgICAgICAgICAgICAgICAgIFtyZWZlcmVuY2VdPVwicmVmZXJlbmNlXCJcbiAgICAgICAgICAgICAgICAgICAgW3JlZmVyZW5jZU1hcF09XCJyZWZlcmVuY2VNYXBcIlxuICAgICAgICAgICAgICAgICAgICBbaW1hZ2VzXT1cIkFycmF5LmZyb20oaW1hZ2VSZWZlcmVuY2VzTWFwLmtleXMoKSlcIlxuICAgICAgICAgICAgICAgICAgICBbcGFnZXNdPVwiQXJyYXkuZnJvbShwYWdlUmVmZXJlbmNlc01hcC5rZXlzKCkpXCJcbiAgICAgICAgICAgICAgICAgICAgKG9wZW5QcmV2aWV3KT1cIm9wZW5BdHRhY2htZW50UHJldmlldygkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgKG9wZW5Eb2N1bWVudCk9XCJvcGVuT3JpZ2luYWxBdHRhY2htZW50KCRldmVudClcIj5cbiAgICAgICAgICAgICAgICAgIDwvc3EtY2hhdC1yZWZlcmVuY2U+XG4gICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC91bD5cbiAgICAgICAgPC9kZXRhaWxzPlxuICAgICAgPC9kaXY+XG4gICAgfVxuICA8L2Rpdj5cblxuICAgIDwhLS0gRWRpdCAvIFJlZ2VuZXJhdGUgZmxvYXRpbmcgYWN0aW9ucyAtLT5cbiAgPGRpdiBjbGFzcz1cInNxLWNoYXQtbWVzc2FnZS1hY3Rpb25zXCIgKm5nSWY9XCJtZXNzYWdlXCI+XG4gICAgPCEtLSBDb21tb24gYWN0aW9uIGJ1dHRvbnMgZm9yIFwidXNlclwiICYgXCJhc3Npc3RhbnRcIiBtZXNzYWdlIC0tPlxuICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNtXCIgKm5nSWY9XCJjYW5Db3B5XCIgW3NxVG9vbHRpcF09XCInY2hhdE1lc3NhZ2UuY29weVRleHQnIHwgdHJhbnNsb2NvXCIgKGNsaWNrKT1cImNvcHlNZXNzYWdlKG1lc3NhZ2UpXCI+XG4gICAgICA8aSBjbGFzcz1cImZhciBmYS1jbGlwYm9hcmRcIj48L2k+XG4gICAgPC9idXR0b24+XG4gICAgPCEtLSBBY3Rpb24gYnV0dG9ucyBmb3IgXCJ1c2VyXCIgbWVzc2FnZSAtLT5cbiAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1zbVwiICpuZ0lmPVwiY2FuRWRpdFwiIFtzcVRvb2x0aXBdPVwiJ2NoYXRNZXNzYWdlLmVkaXRNZXNzYWdlJyB8IHRyYW5zbG9jb1wiIChjbGljayk9XCJlZGl0LmVtaXQobWVzc2FnZSlcIj5cbiAgICAgIDxpIGNsYXNzPVwiZmFzIGZhLWVkaXRcIj48L2k+XG4gICAgPC9idXR0b24+XG4gICAgPCEtLSBBY3Rpb24gYnV0dG9ucyBmb3IgXCJhc3Npc3RhbnRcIiBtZXNzYWdlIC0tPlxuICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNtXCIgW2NsYXNzLmJvdW5jZV09XCJtZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRsaWtlZFwiICpuZ0lmPVwiY2FuTGlrZVwiIFtzcVRvb2x0aXBdPVwiJ2NoYXRNZXNzYWdlLmxpa2VBbnN3ZXInIHwgdHJhbnNsb2NvXCIgKGNsaWNrKT1cImxpa2UuZW1pdCgpXCI+XG4gICAgICA8aSAqbmdJZj1cIiFtZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRsaWtlZFwiIGNsYXNzPVwiZmFyIGZhLXRodW1icy11cCBcIj48L2k+XG4gICAgICA8aSAqbmdJZj1cIm1lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMuJGxpa2VkXCIgY2xhc3M9XCJmYXMgZmEtdGh1bWJzLXVwXCI+PC9pPlxuICAgIDwvYnV0dG9uPlxuICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNtXCIgW2NsYXNzLmJvdW5jZV09XCJtZXNzYWdlLmFkZGl0aW9uYWxQcm9wZXJ0aWVzLiRkaXNsaWtlZFwiICpuZ0lmPVwiY2FuRGlzbGlrZVwiIFtzcVRvb2x0aXBdPVwiJ2NoYXRNZXNzYWdlLnJlcG9ydElzc3VlJyB8IHRyYW5zbG9jb1wiIChjbGljayk9XCJkaXNsaWtlLmVtaXQoKVwiPlxuICAgICAgPGkgKm5nSWY9XCIhbWVzc2FnZS5hZGRpdGlvbmFsUHJvcGVydGllcy4kZGlzbGlrZWRcIiBjbGFzcz1cImZhciBmYS10aHVtYnMtZG93biBcIj48L2k+XG4gICAgICA8aSAqbmdJZj1cIm1lc3NhZ2UuYWRkaXRpb25hbFByb3BlcnRpZXMuJGRpc2xpa2VkXCIgY2xhc3M9XCJmYXMgZmEtdGh1bWJzLWRvd25cIj48L2k+XG4gICAgPC9idXR0b24+XG4gICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc21cIiAqbmdJZj1cImNhblJlZ2VuZXJhdGVcIiBbc3FUb29sdGlwXT1cIidjaGF0TWVzc2FnZS5yZWdlbmVyYXRlUmVzcG9uc2UnIHwgdHJhbnNsb2NvXCIgKGNsaWNrKT1cInJlZ2VuZXJhdGUuZW1pdChtZXNzYWdlKVwiPlxuICAgICAgPGkgY2xhc3M9XCJmYXMgZmEtc3luYy1hbHRcIj48L2k+XG4gICAgPC9idXR0b24+XG4gICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc21cIiAqbmdJZj1cImNhbkRlYnVnXCIgW3NxVG9vbHRpcF09XCInY2hhdE1lc3NhZ2Uuc2hvd0xvZ0luZm9ybWF0aW9uJyB8IHRyYW5zbG9jb1wiIChjbGljayk9XCJkZWJ1Zy5lbWl0KG1lc3NhZ2UpO1wiPlxuICAgICAgPGkgY2xhc3M9XCJmYXIgZmEtbGlzdC1hbHRcIj48L2k+XG4gICAgPC9idXR0b24+XG4gIDwvZGl2PlxuXG4gIDwhLS0gTGlzdCBvZiBzdWdnZXN0ZWQgYWN0aW9ucywgaWYgYW55IC0tPlxuICA8ZGl2ICpuZ0lmPVwic3VnZ2VzdGVkQWN0aW9uc1wiIGNsYXNzPVwibXQtMiBtZXNzYWdlLXN1Z2dlc3Rpb25cIj5cbiAgICA8ZGl2IGNsYXNzPVwic3VnZ2VzdGVkLWFjdGlvblwiICpuZ0Zvcj1cImxldCBzdWdnZXN0ZWRBY3Rpb24gb2Ygc3VnZ2VzdGVkQWN0aW9uc1wiIChjbGljayk9XCJzdWdnZXN0QWN0aW9uLmVtaXQoc3VnZ2VzdGVkQWN0aW9uKVwiPlxuICAgICAgPGRpdiBjbGFzcz1cIm1lc3NhZ2UtaWNvblwiIFtzdHlsZS53aWR0aC5weF09XCJpY29uU2l6ZVwiPjwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cIm1lc3NhZ2UtY29udGVudFwiPlxuICAgICAgICA8cD48aSBjbGFzcz1cImZhcyB7e3N1Z2dlc3RlZEFjdGlvbi50eXBlID09PSAnU3VibWl0JyA/ICdmYS1wYXBlci1wbGFuZScgOiAnZmEtY29tbWVudC1tZWRpY2FsJ319IG1lLTFcIj48L2k+IHt7c3VnZ2VzdGVkQWN0aW9uLmNvbnRlbnR9fTwvcD5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cblxuPC9kaXY+XG4iXX0=