@banta/sdk 4.7.12 → 4.7.13

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.
@@ -2,8 +2,9 @@ import { Observable, Subject, BehaviorSubject, Subscription } from 'rxjs';
2
2
  import { publish, take } from 'rxjs/operators';
3
3
  import * as i0 from '@angular/core';
4
4
  import { Component, Input, ViewChild, Pipe, Inject, Optional, Output, HostBinding, NgModule, ViewChildren, Directive, TemplateRef, ContentChild, Injectable as Injectable$1 } from '@angular/core';
5
- import * as i1 from 'projects/sdk/src/lib/common/timer-pool.service';
6
- import { TimerPool as TimerPool$1 } from 'projects/sdk/src/lib/common/timer-pool.service';
5
+ import { __decorate } from 'tslib';
6
+ import * as i1$2 from '@banta/common';
7
+ import { Injectable, CommentsOrder, SocketRPC, RpcEvent, DurableSocket } from '@banta/common';
7
8
  import * as i2 from '@angular/common';
8
9
  import { CommonModule } from '@angular/common';
9
10
  import * as i2$1 from '@angular/material/icon';
@@ -11,22 +12,20 @@ import { MatIconModule } from '@angular/material/icon';
11
12
  import * as marked from 'marked';
12
13
  import createDOMPurify from 'dompurify';
13
14
  import twemoji$1 from 'twemoji';
14
- import * as i1$1 from '@angular/platform-browser';
15
+ import * as i1 from '@angular/platform-browser';
15
16
  import * as i3 from '@angular/cdk/bidi';
16
17
  import * as i4 from '@angular/material/progress-spinner';
17
18
  import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
18
19
  import * as i6 from '@angular/material/button';
19
20
  import { MatButtonModule } from '@angular/material/button';
20
- import { __decorate } from 'tslib';
21
- import * as i1$3 from '@banta/common';
22
- import { Injectable, CommentsOrder, SocketRPC, RpcEvent, DurableSocket } from '@banta/common';
21
+ import { TimerPool as TimerPool$1 } from 'projects/sdk/src/lib/common/timer-pool.service';
23
22
  import * as i4$1 from '@angular/forms';
24
23
  import { FormsModule } from '@angular/forms';
25
24
  import * as i6$1 from '@angular/material/form-field';
26
25
  import { MatFormFieldModule } from '@angular/material/form-field';
27
26
  import * as i7 from '@angular/material/input';
28
27
  import { MatInputModule } from '@angular/material/input';
29
- import * as i1$2 from '@angular/cdk/overlay';
28
+ import * as i1$1 from '@angular/cdk/overlay';
30
29
  import { OverlayModule } from '@angular/cdk/overlay';
31
30
  import * as i4$2 from '@angular/cdk/portal';
32
31
  import { PortalModule } from '@angular/cdk/portal';
@@ -58,6 +57,86 @@ function lazyConnection(options) {
58
57
  return obs.pipe(publish()).refCount();
59
58
  }
60
59
 
60
+ /**
61
+ * Provides a way to hook in to a shared set of timers, instead of creating a timer per instance.
62
+ * This is very useful for cases where the update is not extremely time-sensitive, but happens at scale.
63
+ * The principal use case is the TimestampComponent. When several hundred (or several thousand) comments are
64
+ * being displayed, we do not want to trigger thousands of independent relative timestamp updates, because over
65
+ * time the updates will saturate the CPU since they don't perfectly align.
66
+ */
67
+ let TimerPool = class TimerPool {
68
+ constructor() {
69
+ this.subscriptions = new Map();
70
+ this.newSubscriptions = new Map();
71
+ this.removedSubscriptions = new Map();
72
+ }
73
+ addTimer(interval, callback) {
74
+ if (interval <= 0) {
75
+ console.warn(`Refusing to set timer with interval of ${interval}!`);
76
+ return () => { };
77
+ }
78
+ let state;
79
+ let sizeWas = this.subscriptions.size;
80
+ if (!this.subscriptions.has(interval)) {
81
+ state = { subscribers: [] };
82
+ state.handle = setInterval(() => {
83
+ console.debug(`[Banta/TimerPool] Notifying ${state.subscribers.length} subs [${interval}ms]`);
84
+ state.subscribers.forEach(sub => sub());
85
+ }, interval);
86
+ this.subscriptions.set(interval, state);
87
+ }
88
+ else {
89
+ state = this.subscriptions.get(interval);
90
+ }
91
+ state.subscribers.push(callback);
92
+ // Debug information //////////////////////////
93
+ //
94
+ if (!this.newSubscriptions.has(interval))
95
+ this.newSubscriptions.set(interval, 0);
96
+ this.newSubscriptions.set(interval, (this.newSubscriptions.get(interval) ?? 0) + 1);
97
+ clearTimeout(this.newSubscriptionsNotice);
98
+ this.newSubscriptionsNotice = setTimeout(() => {
99
+ for (let [interval, count] of this.newSubscriptions) {
100
+ console.debug(`[Banta/TimerPool] ${count} new subscriptions to ${interval}ms [${state.subscribers.length} total]`);
101
+ }
102
+ this.newSubscriptions.clear();
103
+ });
104
+ //
105
+ ///////////////////////////////////////////////
106
+ if (sizeWas === 0) {
107
+ console.debug(`[Banta/TimerPool] No longer idle.`);
108
+ }
109
+ // Unsubscribe function
110
+ return () => {
111
+ let state = this.subscriptions.get(interval);
112
+ let index = state.subscribers.indexOf(callback);
113
+ if (index >= 0)
114
+ state.subscribers.splice(index, 1);
115
+ if (state.subscribers.length === 0) {
116
+ clearInterval(state.handle);
117
+ this.subscriptions.delete(interval);
118
+ }
119
+ if (!this.removedSubscriptions.has(interval))
120
+ this.removedSubscriptions.set(interval, 0);
121
+ this.removedSubscriptions.set(interval, (this.removedSubscriptions.get(interval) ?? 0) + 1);
122
+ // Debug information ////////////////////////////////////////////////////////////////////
123
+ clearTimeout(this.removedSubscriptionsNotice);
124
+ this.removedSubscriptionsNotice = setTimeout(() => {
125
+ for (let [interval, count] of this.removedSubscriptions) {
126
+ let state = this.subscriptions.get(interval);
127
+ console.debug(`[Banta/TimerPool] ${count} unsubscribed from ${interval}ms [${state?.subscribers?.length ?? 0} remain]`);
128
+ }
129
+ if (this.subscriptions.size === 0)
130
+ console.debug(`[Banta/TimerPool] All subscriptions have been removed. Now idle.`);
131
+ this.removedSubscriptions.clear();
132
+ });
133
+ };
134
+ }
135
+ };
136
+ TimerPool = __decorate([
137
+ Injectable()
138
+ ], TimerPool);
139
+
61
140
  class TimestampComponent {
62
141
  constructor(timerPool) {
63
142
  this.timerPool = timerPool;
@@ -154,7 +233,7 @@ class TimestampComponent {
154
233
  }
155
234
  }
156
235
  }
157
- TimestampComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: TimestampComponent, deps: [{ token: i1.TimerPool }], target: i0.ɵɵFactoryTarget.Component });
236
+ TimestampComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: TimestampComponent, deps: [{ token: TimerPool }], target: i0.ɵɵFactoryTarget.Component });
158
237
  TimestampComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: TimestampComponent, selector: "banta-timestamp", inputs: { value: "value" }, ngImport: i0, template: `
159
238
  <span *ngIf="showAbsolute" [title]="value | date : 'short'">
160
239
  {{value | date : 'shortDate'}}
@@ -173,7 +252,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
173
252
  {{relative}}
174
253
  </span>
175
254
  ` }]
176
- }], ctorParameters: function () { return [{ type: i1.TimerPool }]; }, propDecorators: { value: [{
255
+ }], ctorParameters: function () { return [{ type: TimerPool }]; }, propDecorators: { value: [{
177
256
  type: Input
178
257
  }] } });
179
258
 
@@ -275,14 +354,14 @@ class BantaMarkdownToHtmlPipe {
275
354
  }));
276
355
  }
277
356
  }
278
- BantaMarkdownToHtmlPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaMarkdownToHtmlPipe, deps: [{ token: i1$1.DomSanitizer }, { token: BANTA_SDK_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Pipe });
357
+ BantaMarkdownToHtmlPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaMarkdownToHtmlPipe, deps: [{ token: i1.DomSanitizer }, { token: BANTA_SDK_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Pipe });
279
358
  BantaMarkdownToHtmlPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "14.2.12", ngImport: i0, type: BantaMarkdownToHtmlPipe, name: "markdownToHtml" });
280
359
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaMarkdownToHtmlPipe, decorators: [{
281
360
  type: Pipe,
282
361
  args: [{
283
362
  name: 'markdownToHtml'
284
363
  }]
285
- }], ctorParameters: function () { return [{ type: i1$1.DomSanitizer }, { type: undefined, decorators: [{
364
+ }], ctorParameters: function () { return [{ type: i1.DomSanitizer }, { type: undefined, decorators: [{
286
365
  type: Inject,
287
366
  args: [BANTA_SDK_OPTIONS]
288
367
  }, {
@@ -299,14 +378,14 @@ class BantaTrustResourceUrlPipe {
299
378
  return this.sanitizer.bypassSecurityTrustResourceUrl(value);
300
379
  }
301
380
  }
302
- BantaTrustResourceUrlPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaTrustResourceUrlPipe, deps: [{ token: i1$1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe });
381
+ BantaTrustResourceUrlPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaTrustResourceUrlPipe, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe });
303
382
  BantaTrustResourceUrlPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "14.2.12", ngImport: i0, type: BantaTrustResourceUrlPipe, name: "trustResourceUrl" });
304
383
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaTrustResourceUrlPipe, decorators: [{
305
384
  type: Pipe,
306
385
  args: [{
307
386
  name: 'trustResourceUrl'
308
387
  }]
309
- }], ctorParameters: function () { return [{ type: i1$1.DomSanitizer }]; } });
388
+ }], ctorParameters: function () { return [{ type: i1.DomSanitizer }]; } });
310
389
 
311
390
  class BantaMentionLinkerPipe {
312
391
  transform(value, links) {
@@ -513,86 +592,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
513
592
  type: Output
514
593
  }] } });
515
594
 
516
- /**
517
- * Provides a way to hook in to a shared set of timers, instead of creating a timer per instance.
518
- * This is very useful for cases where the update is not extremely time-sensitive, but happens at scale.
519
- * The principal use case is the TimestampComponent. When several hundred (or several thousand) comments are
520
- * being displayed, we do not want to trigger thousands of independent relative timestamp updates, because over
521
- * time the updates will saturate the CPU since they don't perfectly align.
522
- */
523
- let TimerPool = class TimerPool {
524
- constructor() {
525
- this.subscriptions = new Map();
526
- this.newSubscriptions = new Map();
527
- this.removedSubscriptions = new Map();
528
- }
529
- addTimer(interval, callback) {
530
- if (interval <= 0) {
531
- console.warn(`Refusing to set timer with interval of ${interval}!`);
532
- return () => { };
533
- }
534
- let state;
535
- let sizeWas = this.subscriptions.size;
536
- if (!this.subscriptions.has(interval)) {
537
- state = { subscribers: [] };
538
- state.handle = setInterval(() => {
539
- console.debug(`[Banta/TimerPool] Notifying ${state.subscribers.length} subs [${interval}ms]`);
540
- state.subscribers.forEach(sub => sub());
541
- }, interval);
542
- this.subscriptions.set(interval, state);
543
- }
544
- else {
545
- state = this.subscriptions.get(interval);
546
- }
547
- state.subscribers.push(callback);
548
- // Debug information //////////////////////////
549
- //
550
- if (!this.newSubscriptions.has(interval))
551
- this.newSubscriptions.set(interval, 0);
552
- this.newSubscriptions.set(interval, (this.newSubscriptions.get(interval) ?? 0) + 1);
553
- clearTimeout(this.newSubscriptionsNotice);
554
- this.newSubscriptionsNotice = setTimeout(() => {
555
- for (let [interval, count] of this.newSubscriptions) {
556
- console.debug(`[Banta/TimerPool] ${count} new subscriptions to ${interval}ms [${state.subscribers.length} total]`);
557
- }
558
- this.newSubscriptions.clear();
559
- });
560
- //
561
- ///////////////////////////////////////////////
562
- if (sizeWas === 0) {
563
- console.debug(`[Banta/TimerPool] No longer idle.`);
564
- }
565
- // Unsubscribe function
566
- return () => {
567
- let state = this.subscriptions.get(interval);
568
- let index = state.subscribers.indexOf(callback);
569
- if (index >= 0)
570
- state.subscribers.splice(index, 1);
571
- if (state.subscribers.length === 0) {
572
- clearInterval(state.handle);
573
- this.subscriptions.delete(interval);
574
- }
575
- if (!this.removedSubscriptions.has(interval))
576
- this.removedSubscriptions.set(interval, 0);
577
- this.removedSubscriptions.set(interval, (this.removedSubscriptions.get(interval) ?? 0) + 1);
578
- // Debug information ////////////////////////////////////////////////////////////////////
579
- clearTimeout(this.removedSubscriptionsNotice);
580
- this.removedSubscriptionsNotice = setTimeout(() => {
581
- for (let [interval, count] of this.removedSubscriptions) {
582
- let state = this.subscriptions.get(interval);
583
- console.debug(`[Banta/TimerPool] ${count} unsubscribed from ${interval}ms [${state?.subscribers?.length ?? 0} remain]`);
584
- }
585
- if (this.subscriptions.size === 0)
586
- console.debug(`[Banta/TimerPool] All subscriptions have been removed. Now idle.`);
587
- this.removedSubscriptions.clear();
588
- });
589
- };
590
- }
591
- };
592
- TimerPool = __decorate([
593
- Injectable()
594
- ], TimerPool);
595
-
596
595
  const COMPONENTS$3 = [
597
596
  TimestampComponent,
598
597
  LightboxComponent,
@@ -7227,12 +7226,12 @@ class EmojiSelectorPanelComponent {
7227
7226
  this.categories = this.pairs(cats).map(pair => pair[1]);
7228
7227
  }
7229
7228
  }
7230
- EmojiSelectorPanelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: EmojiSelectorPanelComponent, deps: [{ token: i1$1.DomSanitizer }, { token: BANTA_SDK_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Component });
7229
+ EmojiSelectorPanelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: EmojiSelectorPanelComponent, deps: [{ token: i1.DomSanitizer }, { token: BANTA_SDK_OPTIONS, optional: true }], target: i0.ɵɵFactoryTarget.Component });
7231
7230
  EmojiSelectorPanelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: EmojiSelectorPanelComponent, selector: "emoji-selector-panel", outputs: { selected: "selected" }, ngImport: i0, template: "<div class=\"search-box\" *ngIf=\"searchVisible\">\r\n\t<a mat-icon-button href=\"javascript:;\" (click)=\"hideSearch()\">\r\n\t\t<mat-icon>arrow_back</mat-icon>\r\n\t</a>\r\n\t<mat-form-field appearance=\"outline\" floatLabel=\"always\">\r\n\t\t<mat-label>Search for emoji</mat-label>\r\n\t\t<input name=\"search\" type=\"text\" matInput placeholder=\"Start typing\" [(ngModel)]=\"searchQuery\" />\r\n\t</mat-form-field>\r\n</div>\r\n\r\n<div class=\"selector\">\r\n\t<ng-container *ngIf=\"searchVisible\">\r\n\t\t<div class=\"emoji-list\">\r\n\t\t\t<a href=\"javascript:;\" (click)=\"select(emoji.char)\" \r\n\t\t\t\t*ngFor=\"let emoji of searchResults\" [innerHtml]=\"emoji.html || ''\">\r\n\t\t\t</a>\r\n\t\t</div>\r\n\t</ng-container>\r\n\t<ng-container *ngIf=\"!searchVisible\">\r\n\t\t<div class=\"categories\">\r\n\t\t\t<ng-container *ngIf=\"!searchVisible\">\r\n\t\t\t\t<a [title]=\"humanize(category.name)\" [class.active]=\"activeCategory === category.name\" mat-icon-button *ngFor=\"let category of categories\" (click)=\"activeCategory = category.name\">\r\n\t\t\t\t\t<mat-icon>{{category.icon}}</mat-icon>\r\n\t\t\t\t</a>\r\n\r\n\t\t\t\t<a title=\"Search\" [class.active] mat-icon-button (click)=\"showSearch()\">\r\n\t\t\t\t\t<mat-icon>search</mat-icon>\r\n\t\t\t\t</a>\r\n\t\t\t</ng-container>\r\n\t\t</div>\r\n\t\t<ng-container *ngFor=\"let category of categories\">\r\n\t\t\t<div class=\"emoji-list\" *ngIf=\"activeCategory && activeCategory == category.name\">\r\n\t\t\t\t<a href=\"javascript:;\" (click)=\"select(emoji.char)\" \r\n\t\t\t\t\t*ngFor=\"let emoji of category.emojis\" [innerHtml]=\"emoji.html || ''\">\r\n\t\t\t\t</a>\r\n\t\t\t</div>\r\n\t\t</ng-container>\r\n\t</ng-container>\r\n</div>", styles: [":host{background:#111;color:#fff;border:1px solid #333;border-radius:5px;padding:.5em;width:calc(9*(32px + 1em));max-width:calc(100vw - 1.5em - 5px)}.selector{display:flex;flex-direction:column}.categories a{opacity:.25;transition:.4s opacity ease-in-out}.categories a:hover{opacity:.5}.categories a.active{opacity:1}.emoji-list{flex-grow:1;overflow-y:auto;height:20em}.emoji-list a{display:inline-block;padding:2px;margin:4px;background-color:#111}.emoji-list a ::ng-deep .emoji{width:32px;height:32px}.emoji-list a:hover{background-color:#333}.search-box{display:flex;align-items:baseline}.search-box mat-form-field{flex-grow:1}@media (max-width: 500px){.selector{flex-direction:row;height:27em}.emoji-list{height:auto}}:host-context(.banta-mobile) .selector{flex-direction:row;height:27em}:host-context(.banta-mobile) .emoji-list{height:auto}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6.MatAnchor, selector: "a[mat-button], a[mat-raised-button], a[mat-icon-button], a[mat-fab], a[mat-mini-fab], a[mat-stroked-button], a[mat-flat-button]", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i6$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }] });
7232
7231
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: EmojiSelectorPanelComponent, decorators: [{
7233
7232
  type: Component,
7234
7233
  args: [{ selector: 'emoji-selector-panel', template: "<div class=\"search-box\" *ngIf=\"searchVisible\">\r\n\t<a mat-icon-button href=\"javascript:;\" (click)=\"hideSearch()\">\r\n\t\t<mat-icon>arrow_back</mat-icon>\r\n\t</a>\r\n\t<mat-form-field appearance=\"outline\" floatLabel=\"always\">\r\n\t\t<mat-label>Search for emoji</mat-label>\r\n\t\t<input name=\"search\" type=\"text\" matInput placeholder=\"Start typing\" [(ngModel)]=\"searchQuery\" />\r\n\t</mat-form-field>\r\n</div>\r\n\r\n<div class=\"selector\">\r\n\t<ng-container *ngIf=\"searchVisible\">\r\n\t\t<div class=\"emoji-list\">\r\n\t\t\t<a href=\"javascript:;\" (click)=\"select(emoji.char)\" \r\n\t\t\t\t*ngFor=\"let emoji of searchResults\" [innerHtml]=\"emoji.html || ''\">\r\n\t\t\t</a>\r\n\t\t</div>\r\n\t</ng-container>\r\n\t<ng-container *ngIf=\"!searchVisible\">\r\n\t\t<div class=\"categories\">\r\n\t\t\t<ng-container *ngIf=\"!searchVisible\">\r\n\t\t\t\t<a [title]=\"humanize(category.name)\" [class.active]=\"activeCategory === category.name\" mat-icon-button *ngFor=\"let category of categories\" (click)=\"activeCategory = category.name\">\r\n\t\t\t\t\t<mat-icon>{{category.icon}}</mat-icon>\r\n\t\t\t\t</a>\r\n\r\n\t\t\t\t<a title=\"Search\" [class.active] mat-icon-button (click)=\"showSearch()\">\r\n\t\t\t\t\t<mat-icon>search</mat-icon>\r\n\t\t\t\t</a>\r\n\t\t\t</ng-container>\r\n\t\t</div>\r\n\t\t<ng-container *ngFor=\"let category of categories\">\r\n\t\t\t<div class=\"emoji-list\" *ngIf=\"activeCategory && activeCategory == category.name\">\r\n\t\t\t\t<a href=\"javascript:;\" (click)=\"select(emoji.char)\" \r\n\t\t\t\t\t*ngFor=\"let emoji of category.emojis\" [innerHtml]=\"emoji.html || ''\">\r\n\t\t\t\t</a>\r\n\t\t\t</div>\r\n\t\t</ng-container>\r\n\t</ng-container>\r\n</div>", styles: [":host{background:#111;color:#fff;border:1px solid #333;border-radius:5px;padding:.5em;width:calc(9*(32px + 1em));max-width:calc(100vw - 1.5em - 5px)}.selector{display:flex;flex-direction:column}.categories a{opacity:.25;transition:.4s opacity ease-in-out}.categories a:hover{opacity:.5}.categories a.active{opacity:1}.emoji-list{flex-grow:1;overflow-y:auto;height:20em}.emoji-list a{display:inline-block;padding:2px;margin:4px;background-color:#111}.emoji-list a ::ng-deep .emoji{width:32px;height:32px}.emoji-list a:hover{background-color:#333}.search-box{display:flex;align-items:baseline}.search-box mat-form-field{flex-grow:1}@media (max-width: 500px){.selector{flex-direction:row;height:27em}.emoji-list{height:auto}}:host-context(.banta-mobile) .selector{flex-direction:row;height:27em}:host-context(.banta-mobile) .emoji-list{height:auto}\n"] }]
7235
- }], ctorParameters: function () { return [{ type: i1$1.DomSanitizer }, { type: undefined, decorators: [{
7234
+ }], ctorParameters: function () { return [{ type: i1.DomSanitizer }, { type: undefined, decorators: [{
7236
7235
  type: Inject,
7237
7236
  args: [BANTA_SDK_OPTIONS]
7238
7237
  }, {
@@ -7306,7 +7305,7 @@ class EmojiSelectorButtonComponent {
7306
7305
  this.overlayRef.attach(this.selectorPanelTemplate);
7307
7306
  }
7308
7307
  }
7309
- EmojiSelectorButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: EmojiSelectorButtonComponent, deps: [{ token: i0.ElementRef }, { token: i1$2.Overlay }], target: i0.ɵɵFactoryTarget.Component });
7308
+ EmojiSelectorButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: EmojiSelectorButtonComponent, deps: [{ token: i0.ElementRef }, { token: i1$1.Overlay }], target: i0.ɵɵFactoryTarget.Component });
7310
7309
  EmojiSelectorButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: EmojiSelectorButtonComponent, selector: "emoji-selector-button", inputs: { overlayX: "overlayX", overlayY: "overlayY", originX: "originX", originY: "originY" }, outputs: { selected: "selected" }, viewQueries: [{ propertyName: "selectorPanelTemplate", first: true, predicate: ["selectorPanelTemplate"], descendants: true }], ngImport: i0, template: `
7311
7310
  <button #button type="button" mat-icon-button (click)="show()">
7312
7311
  <mat-icon>emoji_emotions</mat-icon>
@@ -7331,7 +7330,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImpo
7331
7330
  ></emoji-selector-panel>
7332
7331
  </ng-template>
7333
7332
  `, styles: [":host{display:block;position:relative}button{color:#666}\n"] }]
7334
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i1$2.Overlay }]; }, propDecorators: { selectorPanelTemplate: [{
7333
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i1$1.Overlay }]; }, propDecorators: { selectorPanelTemplate: [{
7335
7334
  type: ViewChild,
7336
7335
  args: ['selectorPanelTemplate']
7337
7336
  }], selected: [{
@@ -8046,12 +8045,12 @@ class AttachmentButtonComponent {
8046
8045
  }
8047
8046
  }
8048
8047
  }
8049
- AttachmentButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: AttachmentButtonComponent, deps: [{ token: i1$3.CDNProvider }], target: i0.ɵɵFactoryTarget.Component });
8048
+ AttachmentButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: AttachmentButtonComponent, deps: [{ token: i1$2.CDNProvider }], target: i0.ɵɵFactoryTarget.Component });
8050
8049
  AttachmentButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: AttachmentButtonComponent, selector: "banta-attachment-button", outputs: { addedAttachment: "addedAttachment", attachmentError: "attachmentError" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileUpload"], descendants: true }], ngImport: i0, template: "<button matTooltip=\"Add an image or gif\" #button type=\"button\" mat-icon-button (click)=\"show()\">\r\n\t<mat-icon>image</mat-icon>\r\n</button>\r\n<input style=\"display: none;\" #fileUpload [multiple]=\"false\" (change)=\"fileChange($event)\" type=\"file\" >", styles: ["button{color:#666}\n"], dependencies: [{ kind: "component", type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "directive", type: i11.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }] });
8051
8050
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: AttachmentButtonComponent, decorators: [{
8052
8051
  type: Component,
8053
8052
  args: [{ selector: 'banta-attachment-button', template: "<button matTooltip=\"Add an image or gif\" #button type=\"button\" mat-icon-button (click)=\"show()\">\r\n\t<mat-icon>image</mat-icon>\r\n</button>\r\n<input style=\"display: none;\" #fileUpload [multiple]=\"false\" (change)=\"fileChange($event)\" type=\"file\" >", styles: ["button{color:#666}\n"] }]
8054
- }], ctorParameters: function () { return [{ type: i1$3.CDNProvider }]; }, propDecorators: { fileInput: [{
8053
+ }], ctorParameters: function () { return [{ type: i1$2.CDNProvider }]; }, propDecorators: { fileInput: [{
8055
8054
  type: ViewChild,
8056
8055
  args: ['fileUpload', { static: false }]
8057
8056
  }], addedAttachment: [{