@acorex/components 17.0.21 → 17.0.22

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. package/conversation/index.d.ts +3 -2
  2. package/conversation/lib/classes/events.interface.d.ts +4 -1
  3. package/conversation/lib/conversation-input/conversation-input.component.d.ts +5 -5
  4. package/conversation/lib/conversation-messages/conversation-message-file/conversation-message-file.component.d.ts +18 -0
  5. package/conversation/lib/conversation-messages/{conversation-message-text.component.d.ts → conversation-message-text/conversation-message-text.component.d.ts} +1 -1
  6. package/conversation/lib/conversation-messages/{conversation-messages-voice → conversation-message-voice}/conversation-message-voice.component.d.ts +2 -0
  7. package/conversation/lib/conversation-view/conversation-view.component.d.ts +3 -1
  8. package/conversation/lib/conversation.module.d.ts +20 -18
  9. package/conversation/lib/conversation.types.d.ts +2 -0
  10. package/data-table/lib/columns/row-command-column.component.d.ts +2 -4
  11. package/esm2022/audio-wave/lib/audio-wave.component.mjs +2 -3
  12. package/esm2022/common/lib/services/hotkey.service.mjs +1 -2
  13. package/esm2022/conversation/index.mjs +4 -4
  14. package/esm2022/conversation/lib/classes/events.interface.mjs +4 -2
  15. package/esm2022/conversation/lib/conversation-input/conversation-input.component.mjs +10 -17
  16. package/esm2022/conversation/lib/conversation-message/conversation-message.component.mjs +2 -2
  17. package/esm2022/conversation/lib/conversation-messages/conversation-message-file/conversation-message-file.component.mjs +37 -0
  18. package/esm2022/conversation/lib/conversation-messages/conversation-message-text/conversation-message-text.component.mjs +19 -0
  19. package/esm2022/conversation/lib/conversation-messages/conversation-message-voice/conversation-message-voice.component.mjs +117 -0
  20. package/esm2022/conversation/lib/conversation-view/conversation-view.component.mjs +4 -4
  21. package/esm2022/conversation/lib/conversation.module.mjs +20 -8
  22. package/esm2022/conversation/lib/conversation.types.mjs +1 -1
  23. package/esm2022/data-table/lib/columns/row-command-column.component.mjs +1 -1
  24. package/esm2022/loading/lib/loading.component.mjs +2 -2
  25. package/esm2022/phone-box/lib/phone-box.component.mjs +31 -36
  26. package/esm2022/select-box/lib/select-box.component.mjs +3 -3
  27. package/esm2022/uploader/lib/uploader.service.mjs +6 -11
  28. package/fesm2022/acorex-components-audio-wave.mjs +1 -2
  29. package/fesm2022/acorex-components-audio-wave.mjs.map +1 -1
  30. package/fesm2022/acorex-components-common.mjs +0 -1
  31. package/fesm2022/acorex-components-common.mjs.map +1 -1
  32. package/fesm2022/acorex-components-conversation.mjs +73 -38
  33. package/fesm2022/acorex-components-conversation.mjs.map +1 -1
  34. package/fesm2022/acorex-components-data-table.mjs.map +1 -1
  35. package/fesm2022/acorex-components-loading.mjs +2 -2
  36. package/fesm2022/acorex-components-loading.mjs.map +1 -1
  37. package/fesm2022/acorex-components-phone-box.mjs +30 -35
  38. package/fesm2022/acorex-components-phone-box.mjs.map +1 -1
  39. package/fesm2022/acorex-components-select-box.mjs +2 -2
  40. package/fesm2022/acorex-components-select-box.mjs.map +1 -1
  41. package/fesm2022/acorex-components-uploader.mjs +4 -9
  42. package/fesm2022/acorex-components-uploader.mjs.map +1 -1
  43. package/package.json +1 -1
  44. package/phone-box/lib/phone-box.component.d.ts +9 -9
  45. package/esm2022/conversation/lib/conversation-messages/conversation-message-text.component.mjs +0 -23
  46. package/esm2022/conversation/lib/conversation-messages/conversation-messages-voice/conversation-message-voice.component.mjs +0 -112
@@ -1,23 +0,0 @@
1
- import { Component, ViewEncapsulation, signal } from '@angular/core';
2
- import { AXConversationMessageBaseComponent } from '../conversation.types';
3
- import * as i0 from "@angular/core";
4
- export class AXConversationTextMessageComponent extends AXConversationMessageBaseComponent {
5
- constructor() {
6
- super(...arguments);
7
- this._text = signal('');
8
- }
9
- ngOnInit() {
10
- this._text.set(this.message?.content);
11
- }
12
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: AXConversationTextMessageComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
13
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.2", type: AXConversationTextMessageComponent, selector: "ng-component", inputs: { message: "message" }, usesInheritance: true, ngImport: i0, template: `<div [innerHtml]="_text()"></div>`, isInline: true, encapsulation: i0.ViewEncapsulation.None }); }
14
- }
15
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: AXConversationTextMessageComponent, decorators: [{
16
- type: Component,
17
- args: [{
18
- template: `<div [innerHtml]="_text()"></div>`,
19
- encapsulation: ViewEncapsulation.None,
20
- inputs: ['message'],
21
- }]
22
- }] });
23
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udmVyc2F0aW9uLW1lc3NhZ2UtdGV4dC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL2NvbXBvbmVudHMvY29udmVyc2F0aW9uL3NyYy9saWIvY29udmVyc2F0aW9uLW1lc3NhZ2VzL2NvbnZlcnNhdGlvbi1tZXNzYWdlLXRleHQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQVUsaUJBQWlCLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzdFLE9BQU8sRUFBRSxrQ0FBa0MsRUFBRSxNQUFNLHVCQUF1QixDQUFDOztBQU8zRSxNQUFNLE9BQU8sa0NBQW1DLFNBQVEsa0NBQTBDO0lBTGxHOztRQU1ZLFVBQUssR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7S0FLOUI7SUFIQyxRQUFRO1FBQ04sSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztJQUN4QyxDQUFDOzhHQUxVLGtDQUFrQztrR0FBbEMsa0NBQWtDLDJHQUpuQyxtQ0FBbUM7OzJGQUlsQyxrQ0FBa0M7a0JBTDlDLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLG1DQUFtQztvQkFDN0MsYUFBYSxFQUFFLGlCQUFpQixDQUFDLElBQUk7b0JBQ3JDLE1BQU0sRUFBRSxDQUFDLFNBQVMsQ0FBQztpQkFDcEIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgVmlld0VuY2Fwc3VsYXRpb24sIHNpZ25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQVhDb252ZXJzYXRpb25NZXNzYWdlQmFzZUNvbXBvbmVudCB9IGZyb20gJy4uL2NvbnZlcnNhdGlvbi50eXBlcyc7XG5cbkBDb21wb25lbnQoe1xuICB0ZW1wbGF0ZTogYDxkaXYgW2lubmVySHRtbF09XCJfdGV4dCgpXCI+PC9kaXY+YCxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgaW5wdXRzOiBbJ21lc3NhZ2UnXSxcbn0pXG5leHBvcnQgY2xhc3MgQVhDb252ZXJzYXRpb25UZXh0TWVzc2FnZUNvbXBvbmVudCBleHRlbmRzIEFYQ29udmVyc2F0aW9uTWVzc2FnZUJhc2VDb21wb25lbnQ8c3RyaW5nPiBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIHByb3RlY3RlZCBfdGV4dCA9IHNpZ25hbCgnJyk7XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5fdGV4dC5zZXQodGhpcy5tZXNzYWdlPy5jb250ZW50KTtcbiAgfVxufVxuIl19
@@ -1,112 +0,0 @@
1
- import { AXAudioWaveComponent } from '@acorex/components/audio-wave';
2
- import { Component, HostBinding, ViewChild, ViewEncapsulation, afterNextRender, signal } from '@angular/core';
3
- import { AXConversationMessageBaseComponent } from '../../conversation.types';
4
- import * as i0 from "@angular/core";
5
- import * as i1 from "@acorex/components/decorators";
6
- import * as i2 from "@acorex/components/audio-wave";
7
- import * as i3 from "@acorex/components/loading";
8
- import * as i4 from "@angular/common";
9
- import * as i5 from "@acorex/core/format";
10
- export class AXConversationAudioMessageComponent extends AXConversationMessageBaseComponent {
11
- constructor() {
12
- super();
13
- this.config = { url: '' };
14
- this.audioState = signal('paused');
15
- this.selectedRate = signal(1);
16
- this.selectedRateIndex = signal(1);
17
- this.audioProgress = signal(0);
18
- this.timeLeft = signal(0);
19
- this.currentTime = signal(0);
20
- this.duration = signal(0);
21
- afterNextRender(() => {
22
- this.config.url = this.message?.content;
23
- this.config.audioRate = 0.25;
24
- this.setWaveColor();
25
- this.handleLoadingProgress();
26
- });
27
- }
28
- setWaveColor() {
29
- let waveColor = '';
30
- let progressColor = '';
31
- if (this.message.fromId) {
32
- waveColor = getComputedStyle(document.body).getPropertyValue('--ax-message-other-bar-color');
33
- progressColor = getComputedStyle(document.body).getPropertyValue('--ax-message-other-progress-color');
34
- }
35
- else {
36
- waveColor = getComputedStyle(document.body).getPropertyValue('--ax-message-own-bar-color');
37
- progressColor = getComputedStyle(document.body).getPropertyValue('--ax-message-own-progress-color');
38
- }
39
- this.config.waveColor = waveColor;
40
- this.config.progressColor = progressColor;
41
- }
42
- handlePauseClick() {
43
- this.audio?.pause();
44
- this.audioState.set('paused');
45
- }
46
- handlePlayClick() {
47
- this.audio?.play()?.then(() => {
48
- this.audioState.set('playing');
49
- });
50
- }
51
- handleOnStatusChanged(e) {
52
- if (e.status === 'load' || e.status === 'loading') {
53
- this.audioState.set('loading');
54
- }
55
- if (e.status === 'loading') {
56
- this.audioProgress.set(e.data.percent);
57
- this.duration.set(Math.ceil(e.data.duration * 1000));
58
- }
59
- if (e.status === 'ready') {
60
- this.audioState.set('ready');
61
- this.duration.set(Math.ceil(e.data.duration * 1000));
62
- }
63
- if (e.status === 'finish') {
64
- this.audioState.set('paused');
65
- }
66
- if (e.status === 'timeupdate') {
67
- this.timeLeft.set(this.duration() - e.data.currentTime * 1000);
68
- this.currentTime.set(e.data.currentTime * 1000);
69
- }
70
- if (e.status === 'error') {
71
- this.audioState.set('error');
72
- }
73
- }
74
- handleLoadingProgress() {
75
- // this.audioLoaderProgress?.nativeElement.style.cssText = `--ax-audio-progress: ${this.audioProgress()}`;
76
- }
77
- handleCancelLoading() {
78
- //
79
- }
80
- handleReloadClick() {
81
- //
82
- this.audioState.set('loading');
83
- this.audio.load();
84
- }
85
- handleRateClick() {
86
- const rates = [0.5, 1, 2, 4];
87
- if (this.selectedRateIndex() == rates.length - 1) {
88
- this.selectedRateIndex.set(0);
89
- }
90
- else {
91
- this.selectedRateIndex.set(this.selectedRateIndex() + 1);
92
- }
93
- this.selectedRate.set(rates[this.selectedRateIndex()]);
94
- this.audio.setRate(this.selectedRate());
95
- }
96
- get __hostClass() {
97
- return `${this.message.fromId ? 'ax-state-other' : 'ax-state-own'}`;
98
- }
99
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: AXConversationAudioMessageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
100
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.2", type: AXConversationAudioMessageComponent, selector: "ax-conversation-message-audio", inputs: { message: "message" }, host: { properties: { "class": "this.__hostClass" } }, viewQueries: [{ propertyName: "audio", first: true, predicate: ["a"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<ax-prefix>\n @switch (audioState()) {\n @case ('paused')\n {\n {{currentTime() | format:'time-duration' | async}}\n }\n @case ('playing')\n {\n {{currentTime() | format:'time-duration' | async}}\n }\n @default {\n {{duration() | format:'time-duration' | async}}\n }\n }\n <button class=\"ax-audio-speed\" (click)=\"handleRateClick()\"></button>\n\n</ax-prefix>\n<div class=\"ax-audio-controller\">\n\n @switch (audioState()) {\n @case ('playing') {\n <button (click)=\"handlePauseClick()\">\n <i class=\"ax-icon ax-icon-pause\"></i>\n </button>\n }\n\n @case ('ready') {\n <button (click)=\"handlePlayClick()\">\n <i class=\"ax-icon ax-icon-play\"></i>\n </button>\n }\n\n @case ('paused')\n {\n <button (click)=\"handlePlayClick()\">\n <i class=\"ax-icon ax-icon-play\"></i>\n </button>\n }\n\n @case ('error')\n {\n <button class=\"ax-state-error\" (click)=\"handleReloadClick()\">\n <i class=\"ax-icon ax-icon-reload\"></i>\n </button>\n }\n\n @default {\n <button (click)=\"handleCancelLoading()\">\n <ax-loading-spinner [size]=\"24\" [stroke]=\"2\"\n [color]=\"message.fromId?'var(--ax-other-color)':'var(--ax-own-color)'\"></ax-loading-spinner>\n </button>\n }\n }\n\n</div>\n<ax-audio-wave #a [config]=\"config\" (onStatusChanged)=\"handleOnStatusChanged($event)\"></ax-audio-wave>\n<ax-suffix>\n <div class=\"ax-audio-rate-button\" [class.ax-state-own]=\"!message?.fromId\" (click)=\"handleRateClick()\">\n {{selectedRate()}}X</div>\n</ax-suffix>", styles: ["ax-conversation-message-audio{display:flex;align-items:center;justify-content:space-between;gap:.5rem;min-width:18rem;max-width:100%}ax-conversation-message-audio.ax-state-own .ax-audio-controller button{background-color:var(--ax-message-own-color-fore);color:var(--ax-message-own-color)}ax-conversation-message-audio.ax-state-other .ax-audio-controller button{background-color:var(--ax-message-other-color-fore);color:var(--ax-message-other-color)}ax-conversation-message-audio .ax-audio-controller button{width:2.5rem;height:2.5rem;border-radius:999rem;display:flex;align-items:center;justify-content:center}ax-conversation-message-audio .ax-audio-controller button ax-loading-spinner{display:flex}ax-conversation-message-audio .ax-audio-controller button.ax-state-error{background-color:rgba(var(--ax-color-danger-500));color:rgba(var(--ax-color-danger-fore))}ax-conversation-message-audio .ax-audio-controller button>i{width:1.5rem;height:1.5rem;display:flex;align-items:center;justify-content:center;font-size:1.25rem;font-weight:700}ax-conversation-message-audio .ax-audio-wave{flex:1}.ax-audio-rate-button{background-color:var(--ax-message-other-color-fore);color:var(--ax-message-other-color);border-radius:.5rem;padding:0 .5rem;font-weight:700;margin-inline-end:.5rem;cursor:pointer;-webkit-user-select:none;user-select:none}.ax-audio-rate-button.ax-state-own{background-color:var(--ax-message-own-color-fore);color:var(--ax-message-own-color)}html[dir=rtl] ax-conversation-message-audio{flex-direction:row-reverse}\n"], dependencies: [{ kind: "component", type: i1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title , ax-sub-title, ax-placeholder, ax-overlay" }, { kind: "component", type: i2.AXAudioWaveComponent, selector: "ax-audio-wave", inputs: ["config"], outputs: ["onStatusChanged"] }, { kind: "component", type: i3.AXLoadingSpinnerComponent, selector: "ax-loading-spinner", inputs: ["color", "size", "stroke"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i5.AXFormatPipe, name: "format" }], encapsulation: i0.ViewEncapsulation.None }); }
101
- }
102
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: AXConversationAudioMessageComponent, decorators: [{
103
- type: Component,
104
- args: [{ selector: 'ax-conversation-message-audio', encapsulation: ViewEncapsulation.None, inputs: ['message'], template: "<ax-prefix>\n @switch (audioState()) {\n @case ('paused')\n {\n {{currentTime() | format:'time-duration' | async}}\n }\n @case ('playing')\n {\n {{currentTime() | format:'time-duration' | async}}\n }\n @default {\n {{duration() | format:'time-duration' | async}}\n }\n }\n <button class=\"ax-audio-speed\" (click)=\"handleRateClick()\"></button>\n\n</ax-prefix>\n<div class=\"ax-audio-controller\">\n\n @switch (audioState()) {\n @case ('playing') {\n <button (click)=\"handlePauseClick()\">\n <i class=\"ax-icon ax-icon-pause\"></i>\n </button>\n }\n\n @case ('ready') {\n <button (click)=\"handlePlayClick()\">\n <i class=\"ax-icon ax-icon-play\"></i>\n </button>\n }\n\n @case ('paused')\n {\n <button (click)=\"handlePlayClick()\">\n <i class=\"ax-icon ax-icon-play\"></i>\n </button>\n }\n\n @case ('error')\n {\n <button class=\"ax-state-error\" (click)=\"handleReloadClick()\">\n <i class=\"ax-icon ax-icon-reload\"></i>\n </button>\n }\n\n @default {\n <button (click)=\"handleCancelLoading()\">\n <ax-loading-spinner [size]=\"24\" [stroke]=\"2\"\n [color]=\"message.fromId?'var(--ax-other-color)':'var(--ax-own-color)'\"></ax-loading-spinner>\n </button>\n }\n }\n\n</div>\n<ax-audio-wave #a [config]=\"config\" (onStatusChanged)=\"handleOnStatusChanged($event)\"></ax-audio-wave>\n<ax-suffix>\n <div class=\"ax-audio-rate-button\" [class.ax-state-own]=\"!message?.fromId\" (click)=\"handleRateClick()\">\n {{selectedRate()}}X</div>\n</ax-suffix>", styles: ["ax-conversation-message-audio{display:flex;align-items:center;justify-content:space-between;gap:.5rem;min-width:18rem;max-width:100%}ax-conversation-message-audio.ax-state-own .ax-audio-controller button{background-color:var(--ax-message-own-color-fore);color:var(--ax-message-own-color)}ax-conversation-message-audio.ax-state-other .ax-audio-controller button{background-color:var(--ax-message-other-color-fore);color:var(--ax-message-other-color)}ax-conversation-message-audio .ax-audio-controller button{width:2.5rem;height:2.5rem;border-radius:999rem;display:flex;align-items:center;justify-content:center}ax-conversation-message-audio .ax-audio-controller button ax-loading-spinner{display:flex}ax-conversation-message-audio .ax-audio-controller button.ax-state-error{background-color:rgba(var(--ax-color-danger-500));color:rgba(var(--ax-color-danger-fore))}ax-conversation-message-audio .ax-audio-controller button>i{width:1.5rem;height:1.5rem;display:flex;align-items:center;justify-content:center;font-size:1.25rem;font-weight:700}ax-conversation-message-audio .ax-audio-wave{flex:1}.ax-audio-rate-button{background-color:var(--ax-message-other-color-fore);color:var(--ax-message-other-color);border-radius:.5rem;padding:0 .5rem;font-weight:700;margin-inline-end:.5rem;cursor:pointer;-webkit-user-select:none;user-select:none}.ax-audio-rate-button.ax-state-own{background-color:var(--ax-message-own-color-fore);color:var(--ax-message-own-color)}html[dir=rtl] ax-conversation-message-audio{flex-direction:row-reverse}\n"] }]
105
- }], ctorParameters: () => [], propDecorators: { audio: [{
106
- type: ViewChild,
107
- args: ['a']
108
- }], __hostClass: [{
109
- type: HostBinding,
110
- args: ['class']
111
- }] } });
112
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udmVyc2F0aW9uLW1lc3NhZ2Utdm9pY2UuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9jb21wb25lbnRzL2NvbnZlcnNhdGlvbi9zcmMvbGliL2NvbnZlcnNhdGlvbi1tZXNzYWdlcy9jb252ZXJzYXRpb24tbWVzc2FnZXMtdm9pY2UvY29udmVyc2F0aW9uLW1lc3NhZ2Utdm9pY2UuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9jb21wb25lbnRzL2NvbnZlcnNhdGlvbi9zcmMvbGliL2NvbnZlcnNhdGlvbi1tZXNzYWdlcy9jb252ZXJzYXRpb24tbWVzc2FnZXMtdm9pY2UvY29udmVyc2F0aW9uLW1lc3NhZ2Utdm9pY2UuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUEwQixvQkFBb0IsRUFBZ0IsTUFBTSwrQkFBK0IsQ0FBQztBQUMzRyxPQUFPLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsaUJBQWlCLEVBQWtCLGVBQWUsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDOUgsT0FBTyxFQUFFLGtDQUFrQyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7Ozs7Ozs7QUFTOUUsTUFBTSxPQUFPLG1DQUFvQyxTQUFRLGtDQUEwQztJQWNqRztRQUNFLEtBQUssRUFBRSxDQUFDO1FBWlYsV0FBTSxHQUFpQixFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsQ0FBQztRQUVuQyxlQUFVLEdBQXlFLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNwRyxpQkFBWSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN6QixzQkFBaUIsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFcEIsa0JBQWEsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDMUIsYUFBUSxH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QUFpQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUMzRCxDQUFDO1FBQ0QsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUN2RCxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRUQsSUFDSSxXQUFXO1FBQ2IsT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsY0FBYyxFQUFFLENBQUM7SUFDdEUsQ0FBQzs4R0F0R1UsbUNBQW1DO2tHQUFuQyxtQ0FBbUMsK1FDWGhELCsrQ0EyRFk7OzJGRGhEQyxtQ0FBbUM7a0JBUC9DLFNBQVM7K0JBQ0UsK0JBQStCLGlCQUcxQixpQkFBaUIsQ0FBQyxJQUFJLFVBQzdCLENBQUMsU0FBUyxDQUFDO3dEQUdILEtBQUs7c0JBQXBCLFNBQVM7dUJBQUMsR0FBRztnQkFtR1YsV0FBVztzQkFEZCxXQUFXO3VCQUFDLE9BQU8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBWEF1ZGlvV2F2ZUNoYW5nZUV2ZW50LCBBWEF1ZGlvV2F2ZUNvbXBvbmVudCwgQVhXYXZlQ29uZmlnIH0gZnJvbSAnQGFjb3JleC9jb21wb25lbnRzL2F1ZGlvLXdhdmUnO1xuaW1wb3J0IHsgQ29tcG9uZW50LCBIb3N0QmluZGluZywgVmlld0NoaWxkLCBWaWV3RW5jYXBzdWxhdGlvbiwgV3JpdGFibGVTaWduYWwsIGFmdGVyTmV4dFJlbmRlciwgc2lnbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBWENvbnZlcnNhdGlvbk1lc3NhZ2VCYXNlQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vY29udmVyc2F0aW9uLnR5cGVzJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXgtY29udmVyc2F0aW9uLW1lc3NhZ2UtYXVkaW8nLFxuICB0ZW1wbGF0ZVVybDogJy4vY29udmVyc2F0aW9uLW1lc3NhZ2Utdm9pY2UuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybDogYC4vY29udmVyc2F0aW9uLW1lc3NhZ2Utdm9pY2UuY29tcG9uZW50LnNjc3NgLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBpbnB1dHM6IFsnbWVzc2FnZSddLFxufSlcbmV4cG9ydCBjbGFzcyBBWENvbnZlcnNhdGlvbkF1ZGlvTWVzc2FnZUNvbXBvbmVudCBleHRlbmRzIEFYQ29udmVyc2F0aW9uTWVzc2FnZUJhc2VDb21wb25lbnQ8c3RyaW5nPiB7XG4gIEBWaWV3Q2hpbGQoJ2EnKSBhdWRpbzogQVhBdWRpb1dhdmVDb21wb25lbnQ7XG5cbiAgY29uZmlnOiBBWFdhdmVDb25maWcgPSB7IHVybDogJycgfTtcblxuICBhdWRpb1N0YXRlOiBXcml0YWJsZVNpZ25hbDwncGxheWluZycgfCAncGF1c2VkJyB8ICdsb2FkaW5nJyB8ICdyZWFkeScgfCAnZXJyb3InPiA9IHNpZ25hbCgncGF1c2VkJyk7XG4gIHNlbGVjdGVkUmF0ZSA9IHNpZ25hbCgxKTtcbiAgc2VsZWN0ZWRSYXRlSW5kZXggPSBzaWduYWwoMSk7XG5cbiAgcHJvdGVjdGVkIGF1ZGlvUHJvZ3Jlc3MgPSBzaWduYWwoMCk7XG4gIHByb3RlY3RlZCB0aW1lTGVmdCA9IHNpZ25hbCgwKTtcbiAgcHJvdGVjdGVkIGN1cnJlbnRUaW1lID0gc2lnbmFsKDApO1xuICBwcm90ZWN0ZWQgZHVyYXRpb24gPSBzaWduYWwoMCk7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcbiAgICBhZnRlck5leHRSZW5kZXIoKCkgPT4ge1xuICAgICAgdGhpcy5jb25maWcudXJsID0gdGhpcy5tZXNzYWdlPy5jb250ZW50O1xuICAgICAgdGhpcy5jb25maWcuYXVkaW9SYXRlID0gMC4yNTtcbiAgICAgIHRoaXMuc2V0V2F2ZUNvbG9yKCk7XG5cbiAgICAgIHRoaXMuaGFuZGxlTG9hZGluZ1Byb2dyZXNzKCk7XG4gICAgfSk7XG4gIH1cblxuICBzZXRXYXZlQ29sb3IoKSB7XG4gICAgbGV0IHdhdmVDb2xvciA9ICcnO1xuICAgIGxldCBwcm9ncmVzc0NvbG9yID0gJyc7XG4gICAgaWYgKHRoaXMubWVzc2FnZS5mcm9tSWQpIHtcbiAgICAgIHdhdmVDb2xvciA9IGdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuYm9keSkuZ2V0UHJvcGVydHlWYWx1ZSgnLS1heC1tZXNzYWdlLW90aGVyLWJhci1jb2xvcicpO1xuICAgICAgcHJvZ3Jlc3NDb2xvciA9IGdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuYm9keSkuZ2V0UHJvcGVydHlWYWx1ZSgnLS1heC1tZXNzYWdlLW90aGVyLXByb2dyZXNzLWNvbG9yJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHdhdmVDb2xvciA9IGdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuYm9keSkuZ2V0UHJvcGVydHlWYWx1ZSgnLS1heC1tZXNzYWdlLW93bi1iYXItY29sb3InKTtcbiAgICAgIHByb2dyZXNzQ29sb3IgPSBnZXRDb21wdXRlZFN0eWxlKGRvY3VtZW50LmJvZHkpLmdldFByb3BlcnR5VmFsdWUoJy0tYXgtbWVzc2FnZS1vd24tcHJvZ3Jlc3MtY29sb3InKTtcbiAgICB9XG4gICAgdGhpcy5jb25maWcud2F2ZUNvbG9yID0gd2F2ZUNvbG9yO1xuICAgIHRoaXMuY29uZmlnLnByb2dyZXNzQ29sb3IgPSBwcm9ncmVzc0NvbG9yO1xuICB9XG5cbiAgaGFuZGxlUGF1c2VDbGljaygpIHtcbiAgICB0aGlzLmF1ZGlvPy5wYXVzZSgpO1xuICAgIHRoaXMuYXVkaW9TdGF0ZS5zZXQoJ3BhdXNlZCcpO1xuICB9XG5cbiAgaGFuZGxlUGxheUNsaWNrKCkge1xuICAgIHRoaXMuYXVkaW8/LnBsYXkoKT8udGhlbigoKSA9PiB7XG4gICAgICB0aGlzLmF1ZGlvU3RhdGUuc2V0KCdwbGF5aW5nJyk7XG4gICAgfSk7XG4gIH1cblxuICBoYW5kbGVPblN0YXR1c0NoYW5nZWQoZTogQVhBdWRpb1dhdmVDaGFuZ2VFdmVudCkge1xuICAgIGlmIChlLnN0YXR1cyA9PT0gJ2xvYWQnIHx8IGUuc3RhdHVzID09PSAnbG9hZGluZycpIHtcbiAgICAgIHRoaXMuYXVkaW9TdGF0ZS5zZXQoJ2xvYWRpbmcnKTtcbiAgICB9XG4gICAgaWYgKGUuc3RhdHVzID09PSAnbG9hZGluZycpIHtcbiAgICAgIHRoaXMuYXVkaW9Qcm9ncmVzcy5zZXQoZS5kYXRhLnBlcmNlbnQpO1xuICAgICAgdGhpcy5kdXJhdGlvbi5zZXQoTWF0aC5jZWlsKGUuZGF0YS5kdXJhdGlvbiAqIDEwMDApKTtcbiAgICB9XG4gICAgaWYgKGUuc3RhdHVzID09PSAncmVhZHknKSB7XG4gICAgICB0aGlzLmF1ZGlvU3RhdGUuc2V0KCdyZWFkeScpO1xuICAgICAgdGhpcy5kdXJhdGlvbi5zZXQoTWF0aC5jZWlsKGUuZGF0YS5kdXJhdGlvbiAqIDEwMDApKTtcbiAgICB9XG4gICAgaWYgKGUuc3RhdHVzID09PSAnZmluaXNoJykge1xuICAgICAgdGhpcy5hdWRpb1N0YXRlLnNldCgncGF1c2VkJyk7XG4gICAgfVxuICAgIGlmIChlLnN0YXR1cyA9PT0gJ3RpbWV1cGRhdGUnKSB7XG4gICAgICB0aGlzLnRpbWVMZWZ0LnNldCh0aGlzLmR1cmF0aW9uKCkgLSBlLmRhdGEuY3VycmVudFRpbWUgKiAxMDAwKTtcbiAgICAgIHRoaXMuY3VycmVudFRpbWUuc2V0KGUuZGF0YS5jdXJyZW50VGltZSAqIDEwMDApO1xuICAgIH1cbiAgICBpZiAoZS5zdGF0dXMgPT09ICdlcnJvcicpIHtcbiAgICAgIHRoaXMuYXVkaW9TdGF0ZS5zZXQoJ2Vycm9yJyk7XG4gICAgfVxuICB9XG5cbiAgaGFuZGxlTG9hZGluZ1Byb2dyZXNzKCkge1xuICAgIC8vIHRoaXMuYXVkaW9Mb2FkZXJQcm9ncmVzcz8ubmF0aXZlRWxlbWVudC5zdHlsZS5jc3NUZXh0ID0gYC0tYXgtYXVkaW8tcHJvZ3Jlc3M6ICR7dGhpcy5hdWRpb1Byb2dyZXNzKCl9YDtcbiAgfVxuXG4gIGhhbmRsZUNhbmNlbExvYWRpbmcoKSB7XG4gICAgLy9cbiAgfVxuXG4gIGhhbmRsZVJlbG9hZENsaWNrKCkge1xuICAgIC8vXG4gICAgdGhpcy5hdWRpb1N0YXRlLnNldCgnbG9hZGluZycpO1xuICAgIHRoaXMuYXVkaW8ubG9hZCgpO1xuICB9XG5cbiAgaGFuZGxlUmF0ZUNsaWNrKCkge1xuICAgIGNvbnN0IHJhdGVzID0gWzAuNSwgMSwgMiwgNF07XG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRSYXRlSW5kZXgoKSA9PSByYXRlcy5sZW5ndGggLSAxKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkUmF0ZUluZGV4LnNldCgwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zZWxlY3RlZFJhdGVJbmRleC5zZXQodGhpcy5zZWxlY3RlZFJhdGVJbmRleCgpICsgMSk7XG4gICAgfVxuICAgIHRoaXMuc2VsZWN0ZWRSYXRlLnNldChyYXRlc1t0aGlzLnNlbGVjdGVkUmF0ZUluZGV4KCldKTtcbiAgICB0aGlzLmF1ZGlvLnNldFJhdGUodGhpcy5zZWxlY3RlZFJhdGUoKSk7XG4gIH1cblxuICBASG9zdEJpbmRpbmcoJ2NsYXNzJylcbiAgZ2V0IF9faG9zdENsYXNzKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGAke3RoaXMubWVzc2FnZS5mcm9tSWQgPyAnYXgtc3RhdGUtb3RoZXInIDogJ2F4LXN0YXRlLW93bid9YDtcbiAgfVxufVxuIiwiPGF4LXByZWZpeD5cbiAgQHN3aXRjaCAoYXVkaW9TdGF0ZSgpKSB7XG4gIEBjYXNlICgncGF1c2VkJylcbiAge1xuICB7e2N1cnJlbnRUaW1lKCkgfCBmb3JtYXQ6J3RpbWUtZHVyYXRpb24nIHwgYXN5bmN9fVxuICB9XG4gIEBjYXNlICgncGxheWluZycpXG4gIHtcbiAge3tjdXJyZW50VGltZSgpIHwgZm9ybWF0Oid0aW1lLWR1cmF0aW9uJyB8IGFzeW5jfX1cbiAgfVxuICBAZGVmYXVsdCB7XG4gIHt7ZHVyYXRpb24oKSB8IGZvcm1hdDondGltZS1kdXJhdGlvbicgfCBhc3luY319XG4gIH1cbiAgfVxuICA8YnV0dG9uIGNsYXNzPVwiYXgtYXVkaW8tc3BlZWRcIiAoY2xpY2spPVwiaGFuZGxlUmF0ZUNsaWNrKClcIj48L2J1dHRvbj5cblxuPC9heC1wcmVmaXg+XG48ZGl2IGNsYXNzPVwiYXgtYXVkaW8tY29udHJvbGxlclwiPlxuXG4gIEBzd2l0Y2ggKGF1ZGlvU3RhdGUoKSkge1xuICBAY2FzZSAoJ3BsYXlpbmcnKSB7XG4gIDxidXR0b24gKGNsaWNrKT1cImhhbmRsZVBhdXNlQ2xpY2soKVwiPlxuICAgIDxpIGNsYXNzPVwiYXgtaWNvbiBheC1pY29uLXBhdXNlXCI+PC9pPlxuICA8L2J1dHRvbj5cbiAgfVxuXG4gIEBjYXNlICgncmVhZHknKSB7XG4gIDxidXR0b24gKGNsaWNrKT1cImhhbmRsZVBsYXlDbGljaygpXCI+XG4gICAgPGkgY2xhc3M9XCJheC1pY29uIGF4LWljb24tcGxheVwiPjwvaT5cbiAgPC9idXR0b24+XG4gIH1cblxuICBAY2FzZSAoJ3BhdXNlZCcpXG4gIHtcbiAgPGJ1dHRvbiAoY2xpY2spPVwiaGFuZGxlUGxheUNsaWNrKClcIj5cbiAgICA8aSBjbGFzcz1cImF4LWljb24gYXgtaWNvbi1wbGF5XCI+PC9pPlxuICA8L2J1dHRvbj5cbiAgfVxuXG4gIEBjYXNlICgnZXJyb3InKVxuICB7XG4gIDxidXR0b24gY2xhc3M9XCJheC1zdGF0ZS1lcnJvclwiIChjbGljayk9XCJoYW5kbGVSZWxvYWRDbGljaygpXCI+XG4gICAgPGkgY2xhc3M9XCJheC1pY29uIGF4LWljb24tcmVsb2FkXCI+PC9pPlxuICA8L2J1dHRvbj5cbiAgfVxuXG4gIEBkZWZhdWx0IHtcbiAgPGJ1dHRvbiAoY2xpY2spPVwiaGFuZGxlQ2FuY2VsTG9hZGluZygpXCI+XG4gICAgPGF4LWxvYWRpbmctc3Bpbm5lciBbc2l6ZV09XCIyNFwiIFtzdHJva2VdPVwiMlwiXG4gICAgICBbY29sb3JdPVwibWVzc2FnZS5mcm9tSWQ/J3ZhcigtLWF4LW90aGVyLWNvbG9yKSc6J3ZhcigtLWF4LW93bi1jb2xvciknXCI+PC9heC1sb2FkaW5nLXNwaW5uZXI+XG4gIDwvYnV0dG9uPlxuICB9XG4gIH1cblxuPC9kaXY+XG48YXgtYXVkaW8td2F2ZSAjYSBbY29uZmlnXT1cImNvbmZpZ1wiIChvblN0YXR1c0NoYW5nZWQpPVwiaGFuZGxlT25TdGF0dXNDaGFuZ2VkKCRldmVudClcIj48L2F4LWF1ZGlvLXdhdmU+XG48YXgtc3VmZml4PlxuICA8ZGl2IGNsYXNzPVwiYXgtYXVkaW8tcmF0ZS1idXR0b25cIiBbY2xhc3MuYXgtc3RhdGUtb3duXT1cIiFtZXNzYWdlPy5mcm9tSWRcIiAoY2xpY2spPVwiaGFuZGxlUmF0ZUNsaWNrKClcIj5cbiAgICB7e3NlbGVjdGVkUmF0ZSgpfX1YPC9kaXY+XG48L2F4LXN1ZmZpeD4iXX0=