@pobuca/email-builder 1.0.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 (150) hide show
  1. package/README.md +1 -0
  2. package/assets/icons/dribbble.png +0 -0
  3. package/assets/icons/facebook.png +0 -0
  4. package/assets/icons/github.png +0 -0
  5. package/assets/icons/instagram.png +0 -0
  6. package/assets/icons/linkedin.png +0 -0
  7. package/assets/icons/medium.png +0 -0
  8. package/assets/icons/pinterest.png +0 -0
  9. package/assets/icons/snapchat.png +0 -0
  10. package/assets/icons/soundcloud.png +0 -0
  11. package/assets/icons/tumblr.png +0 -0
  12. package/assets/icons/twitter.png +0 -0
  13. package/assets/icons/vimeo.png +0 -0
  14. package/assets/icons/web.png +0 -0
  15. package/assets/icons/xing.png +0 -0
  16. package/assets/icons/youtube.png +0 -0
  17. package/bundles/pobuca-email-builder.umd.js +4664 -0
  18. package/bundles/pobuca-email-builder.umd.js.map +1 -0
  19. package/bundles/pobuca-email-builder.umd.min.js +2 -0
  20. package/bundles/pobuca-email-builder.umd.min.js.map +1 -0
  21. package/esm2015/lib/classes/DefaultEmail.js +53 -0
  22. package/esm2015/lib/classes/Elements.js +229 -0
  23. package/esm2015/lib/classes/Structure.js +89 -0
  24. package/esm2015/lib/components/block/block.component.js +89 -0
  25. package/esm2015/lib/components/block-settings/block-settings.component.js +53 -0
  26. package/esm2015/lib/components/builder-container/builder-container.component.js +114 -0
  27. package/esm2015/lib/components/dialog.component.js +30 -0
  28. package/esm2015/lib/components/general-settings/general-settings.component.js +25 -0
  29. package/esm2015/lib/components/import-dialog/import-dialog.component.js +62 -0
  30. package/esm2015/lib/components/preview.component.js +89 -0
  31. package/esm2015/lib/components/structure/structure.component.js +163 -0
  32. package/esm2015/lib/components/structure-settings/structure-settings.component.js +31 -0
  33. package/esm2015/lib/components/template-list-dialog/template-list-dialog.component.js +45 -0
  34. package/esm2015/lib/directives/dynamic-component.directive.js +46 -0
  35. package/esm2015/lib/elements/abstract-block.js +23 -0
  36. package/esm2015/lib/elements/button/button.component.js +29 -0
  37. package/esm2015/lib/elements/divider/divider.component.js +30 -0
  38. package/esm2015/lib/elements/image/image.component.js +54 -0
  39. package/esm2015/lib/elements/social/social.component.js +42 -0
  40. package/esm2015/lib/elements/spacer/spacer.component.js +30 -0
  41. package/esm2015/lib/elements/text-element/text-element.component.js +80 -0
  42. package/esm2015/lib/groups/align.js +79 -0
  43. package/esm2015/lib/groups/back-repeat.js +55 -0
  44. package/esm2015/lib/groups/border.js +102 -0
  45. package/esm2015/lib/groups/color.js +139 -0
  46. package/esm2015/lib/groups/direction.js +63 -0
  47. package/esm2015/lib/groups/font-styles.js +112 -0
  48. package/esm2015/lib/groups/gaps.js +45 -0
  49. package/esm2015/lib/groups/line-height.js +68 -0
  50. package/esm2015/lib/groups/link.js +67 -0
  51. package/esm2015/lib/groups/margin.js +45 -0
  52. package/esm2015/lib/groups/padding.js +53 -0
  53. package/esm2015/lib/groups/upload-image.js +112 -0
  54. package/esm2015/lib/groups/width-height.js +94 -0
  55. package/esm2015/lib/interceptors/pb-interceptor.interceptor.js +51 -0
  56. package/esm2015/lib/interfaces/interfaces.js +13 -0
  57. package/esm2015/lib/pb-email-builder.component.js +246 -0
  58. package/esm2015/lib/pb-email-builder.module.js +291 -0
  59. package/esm2015/lib/pb-email-builder.service.js +134 -0
  60. package/esm2015/lib/pipes/slugify.pipe.js +39 -0
  61. package/esm2015/lib/services/internals/pb-email-object-store/pb-email-object-store.service.js +165 -0
  62. package/esm2015/lib/services/internals/user-interfaces/user-interface.service.js +122 -0
  63. package/esm2015/lib/services/pb-storage/FreeUsersStorage.class.js +11 -0
  64. package/esm2015/lib/services/pb-storage/index.js +7 -0
  65. package/esm2015/lib/services/pb-storage/pb-storage.service.js +79 -0
  66. package/esm2015/lib/services/user-image-uploader-service/free-users-image-uploader.service.js +26 -0
  67. package/esm2015/lib/services/user-image-uploader-service/index.js +8 -0
  68. package/esm2015/lib/services/user-image-uploader-service/paid-users-image-uploader.service.js +30 -0
  69. package/esm2015/lib/services/user-image-uploader-service/upload-bottom-sheet-dialog/upload-bottom-sheet-dialog.component.js +112 -0
  70. package/esm2015/lib/services/user-image-uploader-service/upload-image-gallery/upload-image-gallery.component.js +91 -0
  71. package/esm2015/lib/services/user-image-uploader-service/user-image-uploader.service.js +26 -0
  72. package/esm2015/lib/services/user-middleware-service/FreeUsersMiddleware.js +31 -0
  73. package/esm2015/lib/services/user-middleware-service/PaidUsersMiddleware.js +12 -0
  74. package/esm2015/lib/services/user-middleware-service/index.js +8 -0
  75. package/esm2015/lib/services/user-middleware-service/pb-middlewares.service.js +195 -0
  76. package/esm2015/lib/services/user-rest-api-service/free-users-rest-api.service.js +16 -0
  77. package/esm2015/lib/services/user-rest-api-service/index.js +7 -0
  78. package/esm2015/lib/services/user-rest-api-service/user-rest-api.service.js +116 -0
  79. package/esm2015/lib/tokens/private-tokens.js +17 -0
  80. package/esm2015/lib/tokens/tokens.js +159 -0
  81. package/esm2015/lib/utils.js +147 -0
  82. package/esm2015/pobuca-email-builder.js +43 -0
  83. package/esm2015/public_api.js +26 -0
  84. package/fesm2015/pobuca-email-builder.js +4335 -0
  85. package/fesm2015/pobuca-email-builder.js.map +1 -0
  86. package/lib/classes/DefaultEmail.d.ts +9 -0
  87. package/lib/classes/Elements.d.ts +62 -0
  88. package/lib/classes/Structure.d.ts +11 -0
  89. package/lib/components/block/block.component.d.ts +25 -0
  90. package/lib/components/block-settings/block-settings.component.d.ts +18 -0
  91. package/lib/components/builder-container/builder-container.component.d.ts +36 -0
  92. package/lib/components/dialog.component.d.ts +10 -0
  93. package/lib/components/general-settings/general-settings.component.d.ts +6 -0
  94. package/lib/components/import-dialog/import-dialog.component.d.ts +16 -0
  95. package/lib/components/preview.component.d.ts +18 -0
  96. package/lib/components/structure/structure.component.d.ts +43 -0
  97. package/lib/components/structure-settings/structure-settings.component.d.ts +9 -0
  98. package/lib/components/template-list-dialog/template-list-dialog.component.d.ts +15 -0
  99. package/lib/directives/dynamic-component.directive.d.ts +13 -0
  100. package/lib/elements/abstract-block.d.ts +8 -0
  101. package/lib/elements/button/button.component.d.ts +18 -0
  102. package/lib/elements/divider/divider.component.d.ts +10 -0
  103. package/lib/elements/image/image.component.d.ts +19 -0
  104. package/lib/elements/social/social.component.d.ts +21 -0
  105. package/lib/elements/spacer/spacer.component.d.ts +5 -0
  106. package/lib/elements/text-element/text-element.component.d.ts +52 -0
  107. package/lib/groups/align.d.ts +17 -0
  108. package/lib/groups/back-repeat.d.ts +8 -0
  109. package/lib/groups/border.d.ts +13 -0
  110. package/lib/groups/color.d.ts +26 -0
  111. package/lib/groups/direction.d.ts +13 -0
  112. package/lib/groups/font-styles.d.ts +17 -0
  113. package/lib/groups/gaps.d.ts +7 -0
  114. package/lib/groups/line-height.d.ts +12 -0
  115. package/lib/groups/link.d.ts +11 -0
  116. package/lib/groups/margin.d.ts +8 -0
  117. package/lib/groups/padding.d.ts +8 -0
  118. package/lib/groups/upload-image.d.ts +19 -0
  119. package/lib/groups/width-height.d.ts +19 -0
  120. package/lib/interceptors/pb-interceptor.interceptor.d.ts +10 -0
  121. package/lib/interfaces/interfaces.d.ts +422 -0
  122. package/lib/pb-email-builder.component.d.ts +67 -0
  123. package/lib/pb-email-builder.module.d.ts +51 -0
  124. package/lib/pb-email-builder.service.d.ts +83 -0
  125. package/lib/pipes/slugify.pipe.d.ts +9 -0
  126. package/lib/services/internals/pb-email-object-store/pb-email-object-store.service.d.ts +50 -0
  127. package/lib/services/internals/user-interfaces/user-interface.service.d.ts +46 -0
  128. package/lib/services/pb-storage/FreeUsersStorage.class.d.ts +6 -0
  129. package/lib/services/pb-storage/index.d.ts +2 -0
  130. package/lib/services/pb-storage/pb-storage.service.d.ts +54 -0
  131. package/lib/services/user-image-uploader-service/free-users-image-uploader.service.d.ts +12 -0
  132. package/lib/services/user-image-uploader-service/index.d.ts +3 -0
  133. package/lib/services/user-image-uploader-service/paid-users-image-uploader.service.d.ts +14 -0
  134. package/lib/services/user-image-uploader-service/upload-bottom-sheet-dialog/upload-bottom-sheet-dialog.component.d.ts +28 -0
  135. package/lib/services/user-image-uploader-service/upload-image-gallery/upload-image-gallery.component.d.ts +27 -0
  136. package/lib/services/user-image-uploader-service/user-image-uploader.service.d.ts +26 -0
  137. package/lib/services/user-middleware-service/FreeUsersMiddleware.d.ts +15 -0
  138. package/lib/services/user-middleware-service/PaidUsersMiddleware.d.ts +7 -0
  139. package/lib/services/user-middleware-service/index.d.ts +3 -0
  140. package/lib/services/user-middleware-service/pb-middlewares.service.d.ts +190 -0
  141. package/lib/services/user-rest-api-service/free-users-rest-api.service.d.ts +10 -0
  142. package/lib/services/user-rest-api-service/index.d.ts +2 -0
  143. package/lib/services/user-rest-api-service/user-rest-api.service.d.ts +82 -0
  144. package/lib/tokens/private-tokens.d.ts +5 -0
  145. package/lib/tokens/tokens.d.ts +70 -0
  146. package/lib/utils.d.ts +88 -0
  147. package/package.json +37 -0
  148. package/pobuca-email-builder.d.ts +42 -0
  149. package/pobuca-email-builder.metadata.json +1 -0
  150. package/public_api.d.ts +16 -0
@@ -0,0 +1,246 @@
1
+ /*
2
+ * Copyright (c) 2024 Pobuca.
3
+ * All rights reserved.
4
+ */
5
+ import { Component, ChangeDetectionStrategy, Input, Renderer2, Inject, ChangeDetectorRef, Output, EventEmitter, forwardRef } from '@angular/core';
6
+ import { DOCUMENT } from '@angular/common';
7
+ import { fromEvent, Subject, iif, EMPTY } from 'rxjs';
8
+ import { switchMap, take, takeUntil, filter, catchError, withLatestFrom, exhaustMap, map } from 'rxjs/operators';
9
+ import { NG_VALUE_ACCESSOR } from '@angular/forms';
10
+ import { PbEmailBuilderService } from './pb-email-builder.service';
11
+ import { PBEmail } from './classes/DefaultEmail';
12
+ import { SlugifyPipe } from './pipes/slugify.pipe';
13
+ import { PbUserMiddlewaresService } from './services/user-middleware-service/pb-middlewares.service';
14
+ import { PbUserInterfaceService } from './services/internals/user-interfaces/user-interface.service';
15
+ import { PbEmailObjectStoreService } from './services/internals/pb-email-object-store/pb-email-object-store.service';
16
+ import { PB_STRUCTURES, PB_BLOCKS, PB_GOOGLE_FONTS } from './tokens/tokens';
17
+ import { PbUserRestApiService } from './services/user-rest-api-service/user-rest-api.service';
18
+ import { deferOf } from './utils';
19
+ export class PbEmailBuilderComponent {
20
+ constructor(ngb, userRestApiService, userInterfaceService, emailObjectStore, renderer2, slugifyPipe, middlewares, changeDetectorRef, structures, blocks, googleFonts, doc) {
21
+ this.ngb = ngb;
22
+ this.userRestApiService = userRestApiService;
23
+ this.userInterfaceService = userInterfaceService;
24
+ this.emailObjectStore = emailObjectStore;
25
+ this.renderer2 = renderer2;
26
+ this.slugifyPipe = slugifyPipe;
27
+ this.middlewares = middlewares;
28
+ this.changeDetectorRef = changeDetectorRef;
29
+ this.structures = structures;
30
+ this.blocks = blocks;
31
+ this.doc = doc;
32
+ this.emailChange = new EventEmitter();
33
+ this.previewTemplate = false;
34
+ this.showGeneralSettings$ = this.userInterfaceService.editGeneralSettings$;
35
+ this.currentTabIndex$ = this.userInterfaceService.currentTabIndex$;
36
+ this.cdkDropListConnectedTo$ = this.userInterfaceService.cdkDropListConnectedTo$;
37
+ this.getBuilderContainerStyles$ = this.emailObjectStore.builderContainerStyles$;
38
+ this.currentHTMLTemplate$ = this.emailObjectStore.templateAsObservable$;
39
+ this.activeMatProgress$ = this.userInterfaceService.activeMatProgress$.asObservable();
40
+ this.customModuleList$ = this.userRestApiService.getAllUserModules$;
41
+ this._onDestroy$ = new Subject();
42
+ this.includedFonts = new Set();
43
+ if (this.doc) {
44
+ for (const font of googleFonts) {
45
+ const link = this.doc.createElement('link');
46
+ link.href = `https://fonts.googleapis.com/css?family=${font}`;
47
+ link.rel = 'stylesheet';
48
+ this.includedFonts.add(link);
49
+ this.doc.head.appendChild(link);
50
+ }
51
+ }
52
+ }
53
+ writeValue(email) {
54
+ try {
55
+ this.emailObjectStore.setEmail(email);
56
+ this.previewTemplate = false;
57
+ this.changeDetectorRef.markForCheck();
58
+ }
59
+ catch (error) {
60
+ this.userInterfaceService.notify(error.message);
61
+ }
62
+ }
63
+ registerOnChange(fn) {
64
+ this.onChange = fn;
65
+ }
66
+ registerOnTouched(fn) {
67
+ this.onTouched = fn;
68
+ }
69
+ /**
70
+ * Not implemented yet
71
+ * @param isDisabled The state of builder
72
+ */
73
+ setDisabledState(isDisabled) {
74
+ // tslint:disable-next-line: no-console
75
+ console.info('[IpEmailBuilderComponent] Method [setDisabledState] is not implemented.');
76
+ }
77
+ saveEmail() {
78
+ return this.emailObjectStore.currentEmailHasChanges$
79
+ .pipe(exhaustMap(hasChanges => {
80
+ return iif(() => hasChanges, this.ngb.createHTMLTemplate$(), this.userInterfaceService.notify('No changes were detected to be save!').afterDismissed());
81
+ }), take(1))
82
+ .subscribe();
83
+ }
84
+ disableBlocksList$(block) {
85
+ return iif(() => { var _a; return !((_a = block.state) === null || _a === void 0 ? void 0 : _a.disabled); }, this.emailObjectStore.emailStructuresAsObservable$.pipe(map(({ length }) => length > 0), exhaustMap(hasStructures => (hasStructures ? this.middlewares.disableBlockDragFromList(block) : deferOf(true))))).pipe(take(1));
86
+ }
87
+ disableStructureList$(structure) {
88
+ return this.middlewares.disableStructureDragFromList(structure).pipe(take(1));
89
+ }
90
+ trackByFn(block) {
91
+ return block.type;
92
+ }
93
+ changeTabIndex(index) {
94
+ this.userInterfaceService.changeTabIndex(index);
95
+ }
96
+ download(source) {
97
+ return this.middlewares
98
+ .exportFile(source)
99
+ .pipe(exhaustMap(() => this.ngb.createHTMLTemplate$().pipe(map(serverResponse => (Object.assign(Object.assign({}, serverResponse), { type: source }))))), catchError(error => this.middlewares.catchError(error).pipe(switchMap(() => {
100
+ this.userInterfaceService.notify(error.message);
101
+ return EMPTY;
102
+ }))), take(1))
103
+ .subscribe(({ type, html, mjml }) => {
104
+ const anchor = this.renderer2.createElement('a');
105
+ let download = html;
106
+ if (type === 'mjml') {
107
+ download = mjml;
108
+ }
109
+ else if (type === 'json') {
110
+ download = JSON.stringify(this.ngb.Email, null, 1);
111
+ }
112
+ const href = URL.createObjectURL(new Blob([download], {
113
+ type: type === 'json' ? 'text/json' : 'text/html'
114
+ }));
115
+ const fileName = this.slugifyPipe.transform(this.ngb.Email.general.name || 'ngb-template');
116
+ anchor.href = href;
117
+ anchor.target = '_blank';
118
+ anchor.download = `${fileName}.${type}`;
119
+ anchor.click();
120
+ URL.revokeObjectURL(href);
121
+ });
122
+ }
123
+ importFile() {
124
+ this.userInterfaceService
125
+ .importDialog$()
126
+ .pipe(switchMap(emailOrError => {
127
+ if (emailOrError instanceof Error) {
128
+ throw emailOrError;
129
+ }
130
+ return deferOf(emailOrError);
131
+ }), catchError(error => this.middlewares.catchError(error).pipe(switchMap(() => {
132
+ this.userInterfaceService.notify(error.message);
133
+ return EMPTY;
134
+ }))), take(1), filter(email => !!email))
135
+ .subscribe(email => {
136
+ this.writeValue(email);
137
+ this.userInterfaceService.notify('Email has been imported successfully.');
138
+ });
139
+ }
140
+ // getBackgroundImage(): SafeStyle {
141
+ // const {
142
+ // background: { url }
143
+ // } = this.email.general;
144
+ // return this.sanitizer.bypassSecurityTrustStyle(url && `url(${url})`);
145
+ // }
146
+ // getBuilderContainerStyles() {
147
+ // const { background, padding, direction } = this.emailObjectStore.Email.general;
148
+ // return {
149
+ // direction,
150
+ // backgroundRepeat: background.repeat,
151
+ // backgroundColor: background.color,
152
+ // backgroundSize: createWidthHeight(background.size),
153
+ // backgroundPosition: 'top center',
154
+ // ...createPadding(padding)
155
+ // };
156
+ // }
157
+ createArrayFromStructureColumns({ columns }) {
158
+ return new Array(columns).fill('');
159
+ }
160
+ togglePreview() {
161
+ return this.emailObjectStore
162
+ .createHTMLTemplate$()
163
+ .pipe(exhaustMap(() => this.middlewares.togglePreview(!this.previewTemplate)), catchError(error => this.middlewares.catchError(error).pipe(switchMap(() => {
164
+ this.userInterfaceService.notify(error.message);
165
+ return EMPTY;
166
+ }))), take(1))
167
+ .subscribe(nextState => {
168
+ this.previewTemplate = nextState;
169
+ this.changeDetectorRef.markForCheck();
170
+ });
171
+ }
172
+ ngOnInit() {
173
+ fromEvent(window, 'beforeunload')
174
+ .pipe(withLatestFrom(this.emailObjectStore.currentEmailHasChanges$), filter(([_, emailIsDirty]) => emailIsDirty), switchMap(([event]) => this.middlewares.preventWindowExit(event)), takeUntil(this._onDestroy$))
175
+ .subscribe(ev => {
176
+ ev.preventDefault();
177
+ ev.returnValue = '';
178
+ });
179
+ this.emailObjectStore.emailAsObservable$.pipe(takeUntil(this._onDestroy$)).subscribe(email => {
180
+ var _a, _b;
181
+ (_a = this.onTouched) === null || _a === void 0 ? void 0 : _a.call(this);
182
+ (_b = this.onChange) === null || _b === void 0 ? void 0 : _b.call(this, email);
183
+ this.emailChange.next(email);
184
+ });
185
+ }
186
+ ngOnChanges(changes) {
187
+ if (changes.email) {
188
+ this.writeValue(changes.email.currentValue);
189
+ }
190
+ }
191
+ // private setEmail(email: PBEmail) {
192
+ // try {
193
+ // this.emailObjectStore.setEmail(email);
194
+ // this.previewTemplate = false;
195
+ // this.changeDetectorRef.markForCheck();
196
+ // } catch (error) {
197
+ // this.userInterfaceService.notify(error.message);
198
+ // }
199
+ // }
200
+ ngOnDestroy() {
201
+ this._onDestroy$.next();
202
+ this._onDestroy$.complete();
203
+ // Reset the builder state
204
+ this.userInterfaceService.reset();
205
+ if (this.doc) {
206
+ this.includedFonts.forEach(font => font.remove());
207
+ }
208
+ this.includedFonts.clear();
209
+ }
210
+ }
211
+ PbEmailBuilderComponent.decorators = [
212
+ { type: Component, args: [{
213
+ selector: 'pb-email-builder',
214
+ template: "<!--\n ~ Copyright (c) 2024 Pobuca.\n ~ All rights reserved.\n -->\n\n<mat-sidenav-container>\n <div class=\"pb-builder-container\" fxLayout=\"column\" fxFlex>\n <mat-progress-bar *ngIf=\"activeMatProgress$ | async\" mode=\"buffer\"></mat-progress-bar>\n <mat-toolbar fxLayoutGap=\"1rem\" fxLayoutAlign=\"space-between center\">\n <ng-content fxLayout fxLayoutGap=\"0.5rem\" select=\".top-actions\"></ng-content>\n\n <div fxFlexlayout fxLayoutGap=\"0.5rem\">\n <button *ngIf=\"ngb.config.useSaveButton\" type=\"button\" (click)=\"saveEmail()\" mat-stroked-button color=\"primary\"\n i18n=\"actions|Save Email\">\n Save Email\n </button>\n <button *ngIf=\"ngb.config.usePreviewButton\" type=\"button\" (click)=\"togglePreview()\" mat-stroked-button>\n <ng-container [ngSwitch]=\"previewTemplate\">\n <span *ngSwitchDefault i18n=\"actions|Preview\">Preview</span>\n <span *ngSwitchCase=\"true\" i18n=\"actions|Close Preview\">Close Preview</span>\n </ng-container>\n </button>\n\n <button mat-button mat-stroked-button i18n=\"actions|Import\" (click)=\"importFile()\">\n Import\n </button>\n\n <ng-container *ngIf=\"ngb.config.useDownloadButton\">\n <button mat-button [matMenuTriggerFor]=\"downloadMenu\" mat-stroked-button i18n=\"actions|Export\">\n Export\n </button>\n <mat-menu #downloadMenu=\"matMenu\">\n <button mat-menu-item (click)=\"download('html')\" i18n=\"actions|Export HTML\">\n Export HTML\n </button>\n <button mat-menu-item (click)=\"download('mjml')\" i18n=\"actions|Export MJML\">\n Export MJML\n </button>\n <button mat-menu-item (click)=\"download('json')\" i18n=\"actions|Export JSON\">\n Export JSON\n </button>\n </mat-menu>\n </ng-container>\n\n </div>\n <!-- <div class=\"history-actions\" style=\"margin-inline-start: auto;\">\n <span>Last saved Now</span>\n <button type=\"button\" mat-icon-button>\n <mat-icon>undo</mat-icon>\n </button>\n <button type=\"button\" mat-icon-button>\n <mat-icon>redo</mat-icon>\n </button>\n </div> -->\n </mat-toolbar>\n <ng-container [ngSwitch]=\"previewTemplate\">\n <pb-builder-container *ngSwitchDefault [ngStyle]=\"getBuilderContainerStyles$ | async\">\n <ng-content select=\".rewrited-empty-email\"></ng-content>\n </pb-builder-container>\n\n <pb-preview-template fxLayout fxFlex=\"auto\" fxLayoutAlign=\"center\" [template]=\"currentHTMLTemplate$ | async\"\n *ngSwitchCase=\"true\">\n </pb-preview-template>\n </ng-container>\n </div>\n <mat-sidenav mode=\"side\" fxFlex=\"0 0 310px\" [opened]=\"!previewTemplate\" position=\"end\" class=\"pb-builder-content\">\n <mat-tab-group [selectedIndex]=\"currentTabIndex$ | async\" (selectedIndexChange)=\"changeTabIndex($event)\">\n <mat-tab i18n-label=\"Content\" label=\"Content\">\n <div class=\"main-padding\">\n <cdk-drop-list class=\"elements\" [cdkDropListConnectedTo]=\"cdkDropListConnectedTo$ | async\"\n [cdkDropListData]=\"blocks\" [cdkDropListSortingDisabled]=\"true\" id=\"block-elements\">\n <div cdkDrag *ngFor=\"let block of blocks; trackBy: trackByFn\" [cdkDragData]=\"block\"\n [cdkDragDisabled]=\"disableBlocksList$(block) | async\" class=\"drag-element\"\n [matTooltip]=\"block.state.message\">\n <mat-icon>{{ block.icon }}</mat-icon>\n <div class=\"drag-element-title\">{{ block.title }}</div>\n </div>\n </cdk-drop-list>\n\n <mat-divider style=\"margin: 1em 0;\"></mat-divider>\n <!-- <h3 class=\"divider\"><span>Structures</span></h3> -->\n <cdk-drop-list class=\"elements structure-elements\" cdkDropListConnectedTo=\"structures-drop-list\"\n [cdkDropListSortingDisabled]=\"true\" [cdkDropListData]=\"structures\">\n <div cdkDrag *ngFor=\"let structure of structures; trackBy: trackByFn\" [cdkDragData]=\"structure\"\n [cdkDragDisabled]=\"disableStructureList$(structure) | async\" class=\"drag-element structure-element\"\n [ngClass]=\"structure.type\">\n <div *ngFor=\"let column of createArrayFromStructureColumns(structure)\"></div>\n </div>\n </cdk-drop-list>\n <ng-content fxLayout fxLayoutGap=\"0.5rem\" select=\".after-structure-blocks\"></ng-content>\n </div>\n </mat-tab>\n <mat-tab i18n-label=\"Modules\" label=\"Modules\" class=\"modules-tab\">\n <cdk-virtual-scroll-viewport itemSize=\"54\" [minBufferPx]=\"54 * 10\" [maxBufferPx]=\"54 * 20\"\n style=\"height: inherit;\"\n *ngIf=\"customModuleList$ | async as modules; else emptyModuleList\">\n <div class=\"main-padding\">\n <div class=\"custom-modules\" cdkDropList cdkDropListConnectedTo=\"structures-drop-list\"\n [cdkDropListData]=\"modules\" [cdkDropListSortingDisabled]=\"true\">\n <div fxLayout=\"column\" fxLayoutGap=\"1rem\">\n <ng-container *cdkVirtualFor=\"let module of modules\">\n <div cdkDrag [cdkDragData]=\"module.module\"\n [cdkDragDisabled]=\"disableStructureList$(module.module) | async\" class=\"drag-element\"\n style=\"padding: 1em;text-transform: uppercase;height: 54px;\">\n <span *ngIf=\"module.name\">{{module.name}}</span>\n <!-- <img *ngIf=\"module.thumb\" [src]=\"module.thumb\" /> -->\n </div>\n </ng-container>\n </div>\n </div>\n <ng-content fxLayout fxLayoutGap=\"0.5rem\" select=\".after-content-blocks\"></ng-content>\n </div>\n </cdk-virtual-scroll-viewport>\n <ng-template #emptyModuleList>\n <h4 class=\"main-padding\" style=\"text-align: center;\" i18n=\"modules|empty list message\">\n Module list is empty\n </h4>\n </ng-template>\n </mat-tab>\n <mat-tab i18n-label=\"Settings\" label=\"Settings\">\n <div class=\"pb-builder-options\" [ngSwitch]=\"showGeneralSettings$ | async\">\n <pb-general-settings *ngSwitchDefault></pb-general-settings>\n <pb-block-settings *ngSwitchCase=\"'block'\"></pb-block-settings>\n <pb-structure-settings *ngSwitchCase=\"'structure'\" fxLayout=\"column\"></pb-structure-settings>\n </div>\n </mat-tab>\n </mat-tab-group>\n </mat-sidenav>\n</mat-sidenav-container>\n",
215
+ exportAs: 'pbEmailBuilder',
216
+ changeDetection: ChangeDetectionStrategy.OnPush,
217
+ providers: [
218
+ {
219
+ provide: NG_VALUE_ACCESSOR,
220
+ useExisting: forwardRef(() => PbEmailBuilderComponent),
221
+ multi: true
222
+ },
223
+ SlugifyPipe
224
+ ],
225
+ styles: ["/*!\n * Copyright (c) 2024 Pobuca.\n * All rights reserved.\n */:host{display:block;height:100vh}.hide{display:none}::ng-deep mat-sidenav-container{height:100%}::ng-deep mat-sidenav-container mat-sidenav-content{width:100%;z-index:unset!important;overflow:unset!important}::ng-deep h3.divider{text-align:center;display:block;overflow:hidden;margin:0 0 1rem}::ng-deep h3.divider span{font-weight:100;position:relative;display:inline-block}::ng-deep h3.divider span:after,::ng-deep h3.divider span:before{content:\"\";position:absolute;top:50%;height:1px;background:#ccc;width:99999px}::ng-deep h3.divider span:before{left:100%;margin-left:10px}::ng-deep h3.divider span:after{right:100%;margin-right:10px}::ng-deep .pb-builder-content{border-right:1px solid rgba(0,0,0,.12)}::ng-deep .pb-builder-content .overflow{position:absolute;top:0;bottom:0;left:0;right:0;background-color:#fff;opacity:.5;display:none;z-index:3}::ng-deep .pb-builder-content.disabled .overflow{display:block}::ng-deep .pb-builder-content .mat-tab-label{width:50%;min-width:auto;height:64px;font-size:medium;text-transform:uppercase;padding:0 12px}::ng-deep .pb-builder-content .mat-tab-body-wrapper,::ng-deep .pb-builder-content .mat-tab-group{height:100%}::ng-deep .pb-builder-content .mat-tab-body-wrapper .mat-tab-body{padding:0}::ng-deep .pb-builder-content .mat-tab-body-wrapper .mat-tab-body .elements{display:grid;grid-gap:.5rem;margin-bottom:1rem;grid-template:repeat(2,1fr)/repeat(3,1fr)}::ng-deep .pb-builder-content .mat-tab-body-wrapper .mat-tab-body .elements.structure-elements{grid-template:repeat(4,1fr)/1fr}::ng-deep .pb-builder-content .mat-tab-body-wrapper .mat-tab-body .elements.cdk-drop-list-dragging .cdk-drag{transform:none!important}::ng-deep .pb-builder-content .mat-tab-body-wrapper .mat-tab-body input{height:auto;border:none}::ng-deep .pb-builder-content .mat-tab-body-wrapper .mat-tab-body .custom-modules .drag-element img{max-width:100%}::ng-deep .pb-builder-container{position:relative;height:100%}::ng-deep .pb-builder-container mat-progress-bar{position:absolute}::ng-deep .pb-builder-container mat-toolbar{background-color:#fff}::ng-deep .pb-builder-options .mat-expansion-panel{box-shadow:none!important}::ng-deep .pb-builder-options .mat-expansion-panel.mat-expanded{overflow:visible}::ng-deep .pb-builder-options mat-expansion-panel-header:not(.mat-expanded){background:rgba(0,0,0,.04)}::ng-deep .pb-builder-options ::ng-deep .group{display:grid;grid-template:auto/repeat(2,1fr);grid-gap:1rem}::ng-deep .pb-builder-options ::ng-deep .group>*{align-self:center}::ng-deep .pb-builder-options ::ng-deep .group+.group{margin-top:1em}::ng-deep .pb-builder-options ::ng-deep .group.four{grid-template-columns:repeat(4,1fr)}::ng-deep .pb-builder-options ::ng-deep .group.f-large{grid-template-columns:2fr 1fr}::ng-deep .pb-builder-options ::ng-deep .group.l-large{grid-template-columns:1fr 2fr}::ng-deep .pb-builder-options ::ng-deep .group.three{grid-template-columns:repeat(3,1fr)}::ng-deep .pb-builder-options ::ng-deep .group.three.f-small{grid-template-columns:1fr repeat(2,2fr)}::ng-deep .pb-builder-options ::ng-deep .group.three.f-large{grid-template-columns:2fr repeat(2,1fr)}::ng-deep .pb-builder-options ::ng-deep .group.three.l-large{grid-template-columns:repeat(2,1fr) 2fr}::ng-deep .pb-builder-options ::ng-deep .group .mat-form-field-infix{width:auto!important}::ng-deep .drag-element{text-align:center;border:1px solid #ccc;box-sizing:border-box;background:#fff;color:#7b7b7b;cursor:move;transition:box-shadow .3s ease-in-out;will-change:box-shadow;border-radius:3px}::ng-deep .drag-element.cdk-drag-disabled,::ng-deep .drag-element.cdk-drag-placeholder{cursor:not-allowed;opacity:.6}::ng-deep .drag-element:hover{box-shadow:0 3px 1px -2px rgba(0,0,0,.2),0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12)}::ng-deep .drag-element .mat-icon{font-size:40px!important;padding:.5rem;width:auto;height:auto}::ng-deep .drag-element img{max-width:100%}::ng-deep .drag-element-title{font-size:.9em;text-transform:uppercase;margin-bottom:.5rem}::ng-deep .drag-element.structure-element{height:60px;position:relative;padding:4px;display:grid;grid-template:1fr/1fr}::ng-deep .drag-element.structure-element>div{background:#ccc;border:4px solid #bbb}::ng-deep .drag-element.structure-element.cols_2{grid-template-columns:repeat(2,5fr)}::ng-deep .drag-element.structure-element.cols_3{grid-template-columns:repeat(3,3.33fr)}::ng-deep .drag-element.structure-element.cols_4{grid-template-columns:repeat(4,2.5fr)}::ng-deep .drag-element.structure-element.cols_12{grid-template-columns:6fr 4fr}::ng-deep .drag-element.structure-element.cols_21{grid-template-columns:4fr 6fr}::ng-deep .main-padding{padding:1rem}::ng-deep .cdk-drop-list-receiving>:not(.cdk-drag){opacity:.6}::ng-deep .cdk-drop-list-dragging>*{pointer-events:none}@keyframes drag-animation{0%{opacity:0;height:0}to{opacity:1}}::ng-deep .cdk-drag-animating{animation:drag-animation 1s cubic-bezier(0,0,.2,1) infinite}::ng-deep .cdk-drag-preview{border-radius:4px;box-shadow:0 0 0 2px rgba(63,81,181,.5);min-height:60px;min-width:100px;background-color:#fff}::ng-deep .cdk-drag.structure-element.cdk-drag-placeholder{box-shadow:0 0 1px 2px #ff4081;width:100%;pointer-events:none}"]
226
+ },] }
227
+ ];
228
+ PbEmailBuilderComponent.ctorParameters = () => [
229
+ { type: PbEmailBuilderService },
230
+ { type: PbUserRestApiService },
231
+ { type: PbUserInterfaceService },
232
+ { type: PbEmailObjectStoreService },
233
+ { type: Renderer2 },
234
+ { type: SlugifyPipe },
235
+ { type: PbUserMiddlewaresService },
236
+ { type: ChangeDetectorRef },
237
+ { type: Array, decorators: [{ type: Inject, args: [PB_STRUCTURES,] }] },
238
+ { type: Array, decorators: [{ type: Inject, args: [PB_BLOCKS,] }] },
239
+ { type: Array, decorators: [{ type: Inject, args: [PB_GOOGLE_FONTS,] }] },
240
+ { type: Document, decorators: [{ type: Inject, args: [DOCUMENT,] }] }
241
+ ];
242
+ PbEmailBuilderComponent.propDecorators = {
243
+ email: [{ type: Input }],
244
+ emailChange: [{ type: Output }]
245
+ };
246
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGItZW1haWwtYnVpbGRlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9wYi1lbWFpbC1idWlsZGVyL3NyYy9saWIvcGItZW1haWwtYnVpbGRlci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztHQUdHO0FBRUgsT0FBTyxFQUNMLFNBQVMsRUFDVCx1QkFBdUIsRUFDdkIsS0FBSyxFQUNMLFNBQVMsRUFLVCxNQUFNLEVBQ04saUJBQWlCLEVBQ2pCLE1BQU0sRUFDTixZQUFZLEVBQ1osVUFBVSxFQUNYLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzQyxPQUFPLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3RELE9BQU8sRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLGNBQWMsRUFBRSxVQUFVLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDakgsT0FBTyxFQUF3QixpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXpFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRW5FLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNqRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDbkQsT0FBTyxFQUFFLHdCQUF3QixFQUFlLE1BQU0sMkRBQTJELENBQUM7QUFFbEgsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sNkRBQTZELENBQUM7QUFDckcsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sMEVBQTBFLENBQUM7QUFDckgsT0FBTyxFQUFFLGFBQWEsRUFBRSxTQUFTLEVBQUUsZUFBZSxF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O2dCQUNULFFBQVEsRUFBRSxrQkFBa0I7Z0JBQzVCLHF2TkFBZ0Q7Z0JBRWhELFFBQVEsRUFBRSxnQkFBZ0I7Z0JBQzFCLGVBQWUsRUFBRSx1QkFBdUIsQ0FBQyxNQUFNO2dCQUMvQyxTQUFTLEVBQUU7b0JBQ1Q7d0JBQ0UsT0FBTyxFQUFFLGlCQUFpQjt3QkFDMUIsV0FBVyxFQUFFLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyx1QkFBdUIsQ0FBQzt3QkFDdEQsS0FBSyxFQUFFLElBQUk7cUJBQ1o7b0JBQ0QsV0FBVztpQkFDWjs7YUFDRjs7O1lBMUJRLHFCQUFxQjtZQVNyQixvQkFBb0I7WUFIcEIsc0JBQXNCO1lBQ3RCLHlCQUF5QjtZQXZCaEMsU0FBUztZQW1CRixXQUFXO1lBQ1gsd0JBQXdCO1lBZC9CLGlCQUFpQjt3Q0E4RGQsTUFBTSxTQUFDLGFBQWE7d0NBQ3BCLE1BQU0sU0FBQyxTQUFTO3dDQUNoQixNQUFNLFNBQUMsZUFBZTtZQUNRLFFBQVEsdUJBQXRDLE1BQU0sU0FBQyxRQUFROzs7b0JBM0JqQixLQUFLOzBCQUNMLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IChjKSAyMDI0IFBvYnVjYS5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKi9cblxuaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgSW5wdXQsXG4gIFJlbmRlcmVyMixcbiAgT25DaGFuZ2VzLFxuICBTaW1wbGVDaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgSW5qZWN0LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgT3V0cHV0LFxuICBFdmVudEVtaXR0ZXIsXG4gIGZvcndhcmRSZWZcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBET0NVTUVOVCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBmcm9tRXZlbnQsIFN1YmplY3QsIGlpZiwgRU1QVFkgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHN3aXRjaE1hcCwgdGFrZSwgdGFrZVVudGlsLCBmaWx0ZXIsIGNhdGNoRXJyb3IsIHdpdGhMYXRlc3RGcm9tLCBleGhhdXN0TWFwLCBtYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5cbmltcG9ydCB7IFBiRW1haWxCdWlsZGVyU2VydmljZSB9IGZyb20gJy4vcGItZW1haWwtYnVpbGRlci5zZXJ2aWNlJztcbmltcG9ydCB7IElTdHJ1Y3R1cmUgfSBmcm9tICcuL2ludGVyZmFjZXMvaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBQQkVtYWlsIH0gZnJvbSAnLi9jbGFzc2VzL0RlZmF1bHRFbWFpbCc7XG5pbXBvcnQgeyBTbHVnaWZ5UGlwZSB9IGZyb20gJy4vcGlwZXMvc2x1Z2lmeS5waXBlJztcbmltcG9ydCB7IFBiVXNlck1pZGRsZXdhcmVzU2VydmljZSwgVEV4cG9ydFR5cGUgfSBmcm9tICcuL3NlcnZpY2VzL3VzZXItbWlkZGxld2FyZS1zZXJ2aWNlL3BiLW1pZGRsZXdhcmVzLnNlcnZpY2UnO1xuaW1wb3J0IHsgVEJsb2NrcyB9IGZyb20gJy4vY2xhc3Nlcy9FbGVtZW50cyc7XG5pbXBvcnQgeyBQYlVzZXJJbnRlcmZhY2VTZXJ2aWNlIH0gZnJvbSAnLi9zZXJ2aWNlcy9pbnRlcm5hbHMvdXNlci1pbnRlcmZhY2VzL3VzZXItaW50ZXJmYWNlLnNlcnZpY2UnO1xuaW1wb3J0IHsgUGJFbWFpbE9iamVjdFN0b3JlU2VydmljZSB9IGZyb20gJy4vc2VydmljZXMvaW50ZXJuYWxzL3BiLWVtYWlsLW9iamVjdC1zdG9yZS9wYi1lbWFpbC1vYmplY3Qtc3RvcmUuc2VydmljZSc7XG5pbXBvcnQgeyBQQl9TVFJVQ1RVUkVTLCBQQl9CTE9DS1MsIFBCX0dPT0dMRV9GT05UUyB9IGZyb20gJy4vdG9rZW5zL3Rva2Vucyc7XG5pbXBvcnQgeyBQYlVzZXJSZXN0QXBpU2VydmljZSB9IGZyb20gJy4vc2VydmljZXMvdXNlci1yZXN0LWFwaS1zZXJ2aWNlL3VzZXItcmVzdC1hcGkuc2VydmljZSc7XG5pbXBvcnQgeyBkZWZlck9mIH0gZnJvbSAnLi91dGlscyc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3BiLWVtYWlsLWJ1aWxkZXInLFxuICB0ZW1wbGF0ZVVybDogJy4vcGItZW1haWwtYnVpbGRlci5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3BiLWVtYWlsLWJ1aWxkZXIuY29tcG9uZW50LnNjc3MnXSxcbiAgZXhwb3J0QXM6ICdwYkVtYWlsQnVpbGRlcicsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBwcm92aWRlcnM6IFtcbiAgICB7XG4gICAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IFBiRW1haWxCdWlsZGVyQ29tcG9uZW50KSxcbiAgICAgIG11bHRpOiB0cnVlXG4gICAgfSxcbiAgICBTbHVnaWZ5UGlwZVxuICBdXG59KVxuZXhwb3J0IGNsYXNzIFBiRW1haWxCdWlsZGVyQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzLCBPbkRlc3Ryb3ksIE9uSW5pdCwgQ29udHJvbFZhbHVlQWNjZXNzb3Ige1xuICBASW5wdXQoKSBlbWFpbD86IFBCRW1haWw7XG4gIEBPdXRwdXQoKSBlbWFpbENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8UEJFbWFpbD4oKTtcblxuICBwcmV2aWV3VGVtcGxhdGUgPSBmYWxzZTtcbiAgc2hvd0dlbmVyYWxTZXR0aW5ncyQgPSB0aGlzLnVzZXJJbnRlcmZhY2VTZXJ2aWNlLmVkaXRHZW5lcmFsU2V0dGluZ3MkO1xuICBjdXJyZW50VGFiSW5kZXgkID0gdGhpcy51c2VySW50ZXJmYWNlU2VydmljZS5jdXJyZW50VGFiSW5kZXgkO1xuICBjZGtEcm9wTGlzdENvbm5lY3RlZFRvJCA9IHRoaXMudXNlckludGVyZmFjZVNlcnZpY2UuY2RrRHJvcExpc3RDb25uZWN0ZWRUbyQ7XG4gIGdldEJ1aWxkZXJDb250YWluZXJTdHlsZXMkID0gdGhpcy5lbWFpbE9iamVjdFN0b3JlLmJ1aWxkZXJDb250YWluZXJTdHlsZXMkO1xuICBjdXJyZW50SFRNTFRlbXBsYXRlJCA9IHRoaXMuZW1haWxPYmplY3RTdG9yZS50ZW1wbGF0ZUFzT2JzZXJ2YWJsZSQ7XG4gIGFjdGl2ZU1hdFByb2dyZXNzJCA9IHRoaXMudXNlckludGVyZmFjZVNlcnZpY2UuYWN0aXZlTWF0UHJvZ3Jlc3MkLmFzT2JzZXJ2YWJsZSgpO1xuICBjdXN0b21Nb2R1bGVMaXN0JCA9IHRoaXMudXNlclJlc3RBcGlTZXJ2aWNlLmdldEFsbFVzZXJNb2R1bGVzJDtcblxuICBwcml2YXRlIHJlYWRvbmx5IF9vbkRlc3Ryb3kkID0gbmV3IFN1YmplY3QoKTtcbiAgcHJpdmF0ZSBpbmNsdWRlZEZvbnRzID0gbmV3IFNldDxIVE1MTGlua0VsZW1lbnQ+KCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIG5nYjogUGJFbWFpbEJ1aWxkZXJTZXJ2aWNlLFxuICAgIHByaXZhdGUgdXNlclJlc3RBcGlTZXJ2aWNlOiBQYlVzZXJSZXN0QXBpU2VydmljZSxcbiAgICBwcml2YXRlIHVzZXJJbnRlcmZhY2VTZXJ2aWNlOiBQYlVzZXJJbnRlcmZhY2VTZXJ2aWNlLFxuICAgIHByaXZhdGUgZW1haWxPYmplY3RTdG9yZTogUGJFbWFpbE9iamVjdFN0b3JlU2VydmljZSxcbiAgICBwcml2YXRlIHJlbmRlcmVyMjogUmVuZGVyZXIyLFxuICAgIHByaXZhdGUgc2x1Z2lmeVBpcGU6IFNsdWdpZnlQaXBlLFxuICAgIHByaXZhdGUgbWlkZGxld2FyZXM6IFBiVXNlck1pZGRsZXdhcmVzU2VydmljZSxcbiAgICBwcml2YXRlIGNoYW5nZURldGVjdG9yUmVmOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBASW5qZWN0KFBCX1NUUlVDVFVSRVMpIHB1YmxpYyBzdHJ1Y3R1cmVzOiBJU3RydWN0dXJlW10sXG4gICAgQEluamVjdChQQl9CTE9DS1MpIHB1YmxpYyBibG9ja3M6IFRCbG9ja3NbXSxcbiAgICBASW5qZWN0KFBCX0dPT0dMRV9GT05UUykgZ29vZ2xlRm9udHM6IFRCbG9ja3NbXSxcbiAgICBASW5qZWN0KERPQ1VNRU5UKSBwcml2YXRlIGRvYzogRG9jdW1lbnRcbiAgKSB7XG4gICAgaWYgKHRoaXMuZG9jKSB7XG4gICAgICBmb3IgKGNvbnN0IGZvbnQgb2YgZ29vZ2xlRm9udHMpIHtcbiAgICAgICAgY29uc3QgbGluayA9IHRoaXMuZG9jLmNyZWF0ZUVsZW1lbnQoJ2xpbmsnKTtcbiAgICAgICAgbGluay5ocmVmID0gYGh0dHBzOi8vZm9udHMuZ29vZ2xlYXBpcy5jb20vY3NzP2ZhbWlseT0ke2ZvbnR9YDtcbiAgICAgICAgbGluay5yZWwgPSAnc3R5bGVzaGVldCc7XG4gICAgICAgIHRoaXMuaW5jbHVkZWRGb250cy5hZGQobGluayk7XG4gICAgICAgIHRoaXMuZG9jLmhlYWQuYXBwZW5kQ2hpbGQobGluayk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gRm9ybSBDb250cm9sIGltcGxlbWVudGF0aW9uXG4gIHByaXZhdGUgb25DaGFuZ2U6IChfPzogYW55KSA9PiB2b2lkO1xuICBwcml2YXRlIG9uVG91Y2hlZDogKCkgPT4gdm9pZDtcblxuICB3cml0ZVZhbHVlKGVtYWlsOiBQQkVtYWlsKTogdm9pZCB7XG4gICAgdHJ5IHtcbiAgICAgIHRoaXMuZW1haWxPYmplY3RTdG9yZS5zZXRFbWFpbChlbWFpbCk7XG4gICAgICB0aGlzLnByZXZpZXdUZW1wbGF0ZSA9IGZhbHNlO1xuICAgICAgdGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhpcy51c2VySW50ZXJmYWNlU2VydmljZS5ub3RpZnkoZXJyb3IubWVzc2FnZSk7XG4gICAgfVxuICB9XG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm46IGFueSk6IHZvaWQge1xuICAgIHRoaXMub25DaGFuZ2UgPSBmbjtcbiAgfVxuICByZWdpc3Rlck9uVG91Y2hlZChmbjogYW55KTogdm9pZCB7XG4gICAgdGhpcy5vblRvdWNoZWQgPSBmbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBOb3QgaW1wbGVtZW50ZWQgeWV0XG4gICAqIEBwYXJhbSBpc0Rpc2FibGVkIFRoZSBzdGF0ZSBvZiBidWlsZGVyXG4gICAqL1xuICBzZXREaXNhYmxlZFN0YXRlPyhpc0Rpc2FibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOiBuby1jb25zb2xlXG4gICAgY29uc29sZS5pbmZvKCdbSXBFbWFpbEJ1aWxkZXJDb21wb25lbnRdIE1ldGhvZCBbc2V0RGlzYWJsZWRTdGF0ZV0gaXMgbm90IGltcGxlbWVudGVkLicpO1xuICB9XG5cbiAgc2F2ZUVtYWlsKCkge1xuICAgIHJldHVybiB0aGlzLmVtYWlsT2JqZWN0U3RvcmUuY3VycmVudEVtYWlsSGFzQ2hhbmdlcyRcbiAgICAgIC5waXBlKFxuICAgICAgICBleGhhdXN0TWFwKGhhc0NoYW5nZXMgPT4ge1xuICAgICAgICAgIHJldHVybiBpaWYoXG4gICAgICAgICAgICAoKSA9PiBoYXNDaGFuZ2VzLFxuICAgICAgICAgICAgdGhpcy5uZ2IuY3JlYXRlSFRNTFRlbXBsYXRlJCgpLFxuICAgICAgICAgICAgdGhpcy51c2VySW50ZXJmYWNlU2VydmljZS5ub3RpZnkoJ05vIGNoYW5nZXMgd2VyZSBkZXRlY3RlZCB0byBiZSBzYXZlIScpLmFmdGVyRGlzbWlzc2VkKClcbiAgICAgICAgICApO1xuICAgICAgICB9KSxcbiAgICAgICAgdGFrZSgxKVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgpO1xuICB9XG5cbiAgZGlzYWJsZUJsb2Nrc0xpc3QkKGJsb2NrOiBUQmxvY2tzKSB7XG4gICAgcmV0dXJuIGlpZihcbiAgICAgICgpID0+ICFibG9jay5zdGF0ZT8uZGlzYWJsZWQsXG4gICAgICB0aGlzLmVtYWlsT2JqZWN0U3RvcmUuZW1haWxTdHJ1Y3R1cmVzQXNPYnNlcnZhYmxlJC5waXBlKFxuICAgICAgICBtYXAoKHsgbGVuZ3RoIH0pID0+IGxlbmd0aCA+IDApLFxuICAgICAgICBleGhhdXN0TWFwKGhhc1N0cnVjdHVyZXMgPT4gKGhhc1N0cnVjdHVyZXMgPyB0aGlzLm1pZGRsZXdhcmVzLmRpc2FibGVCbG9ja0RyYWdGcm9tTGlzdChibG9jaykgOiBkZWZlck9mKHRydWUpKSlcbiAgICAgIClcbiAgICApLnBpcGUodGFrZSgxKSk7XG4gIH1cblxuICBkaXNhYmxlU3RydWN0dXJlTGlzdCQoc3RydWN0dXJlOiBJU3RydWN0dXJlKSB7XG4gICAgcmV0dXJuIHRoaXMubWlkZGxld2FyZXMuZGlzYWJsZVN0cnVjdHVyZURyYWdGcm9tTGlzdChzdHJ1Y3R1cmUpLnBpcGUodGFrZSgxKSk7XG4gIH1cblxuICB0cmFja0J5Rm4oYmxvY2s6IFRCbG9ja3MgfCBJU3RydWN0dXJlKSB7XG4gICAgcmV0dXJuIGJsb2NrLnR5cGU7XG4gIH1cblxuICBjaGFuZ2VUYWJJbmRleChpbmRleDogbnVtYmVyKSB7XG4gICAgdGhpcy51c2VySW50ZXJmYWNlU2VydmljZS5jaGFuZ2VUYWJJbmRleChpbmRleCk7XG4gIH1cblxuICBkb3dubG9hZChzb3VyY2U6IFRFeHBvcnRUeXBlKSB7XG4gICAgcmV0dXJuIHRoaXMubWlkZGxld2FyZXNcbiAgICAgIC5leHBvcnRGaWxlKHNvdXJjZSlcbiAgICAgIC5waXBlKFxuICAgICAgICBleGhhdXN0TWFwKCgpID0+IHRoaXMubmdiLmNyZWF0ZUhUTUxUZW1wbGF0ZSQoKS5waXBlKG1hcChzZXJ2ZXJSZXNwb25zZSA9PiAoeyAuLi5zZXJ2ZXJSZXNwb25zZSwgdHlwZTogc291cmNlIH0pKSkpLFxuICAgICAgICBjYXRjaEVycm9yKGVycm9yID0+XG4gICAgICAgICAgdGhpcy5taWRkbGV3YXJlcy5jYXRjaEVycm9yKGVycm9yKS5waXBlKFxuICAgICAgICAgICAgc3dpdGNoTWFwKCgpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy51c2VySW50ZXJmYWNlU2VydmljZS5ub3RpZnkoZXJyb3IubWVzc2FnZSk7XG4gICAgICAgICAgICAgIHJldHVybiBFTVBUWTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgKVxuICAgICAgICApLFxuICAgICAgICB0YWtlKDEpXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKCh7IHR5cGUsIGh0bWwsIG1qbWwgfSkgPT4ge1xuICAgICAgICBjb25zdCBhbmNob3IgPSB0aGlzLnJlbmRlcmVyMi5jcmVhdGVFbGVtZW50KCdhJyk7XG4gICAgICAgIGxldCBkb3dubG9hZCA9IGh0bWw7XG4gICAgICAgIGlmICh0eXBlID09PSAnbWptbCcpIHtcbiAgICAgICAgICBkb3dubG9hZCA9IG1qbWw7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2pzb24nKSB7XG4gICAgICAgICAgZG93bmxvYWQgPSBKU09OLnN0cmluZ2lmeSh0aGlzLm5nYi5FbWFpbCwgbnVsbCwgMSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaHJlZiA9IFVSTC5jcmVhdGVPYmplY3RVUkwoXG4gICAgICAgICAgbmV3IEJsb2IoW2Rvd25sb2FkXSwge1xuICAgICAgICAgICAgdHlwZTogdHlwZSA9PT0gJ2pzb24nID8gJ3RleHQvanNvbicgOiAndGV4dC9odG1sJ1xuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IGZpbGVOYW1lID0gdGhpcy5zbHVnaWZ5UGlwZS50cmFuc2Zvcm0odGhpcy5uZ2IuRW1haWwuZ2VuZXJhbC5uYW1lIHx8ICduZ2ItdGVtcGxhdGUnKTtcbiAgICAgICAgYW5jaG9yLmhyZWYgPSBocmVmO1xuICAgICAgICBhbmNob3IudGFyZ2V0ID0gJ19ibGFuayc7XG4gICAgICAgIGFuY2hvci5kb3dubG9hZCA9IGAke2ZpbGVOYW1lfS4ke3R5cGV9YDtcbiAgICAgICAgYW5jaG9yLmNsaWNrKCk7XG4gICAgICAgIFVSTC5yZXZva2VPYmplY3RVUkwoaHJlZik7XG4gICAgICB9KTtcbiAgfVxuXG4gIGltcG9ydEZpbGUoKSB7XG4gICAgdGhpcy51c2VySW50ZXJmYWNlU2VydmljZVxuICAgICAgLmltcG9ydERpYWxvZyQoKVxuICAgICAgLnBpcGUoXG4gICAgICAgIHN3aXRjaE1hcChlbWFpbE9yRXJyb3IgPT4ge1xuICAgICAgICAgIGlmIChlbWFpbE9yRXJyb3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgICAgdGhyb3cgZW1haWxPckVycm9yO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gZGVmZXJPZihlbWFpbE9yRXJyb3IpO1xuICAgICAgICB9KSxcbiAgICAgICAgY2F0Y2hFcnJvcihlcnJvciA9PlxuICAgICAgICAgIHRoaXMubWlkZGxld2FyZXMuY2F0Y2hFcnJvcihlcnJvcikucGlwZShcbiAgICAgICAgICAgIHN3aXRjaE1hcCgoKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMudXNlckludGVyZmFjZVNlcnZpY2Uubm90aWZ5KGVycm9yLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICByZXR1cm4gRU1QVFk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgIClcbiAgICAgICAgKSxcbiAgICAgICAgdGFrZSgxKSxcbiAgICAgICAgZmlsdGVyKGVtYWlsID0+ICEhZW1haWwpXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKGVtYWlsID0+IHtcbiAgICAgICAgdGhpcy53cml0ZVZhbHVlKGVtYWlsKTtcbiAgICAgICAgdGhpcy51c2VySW50ZXJmYWNlU2VydmljZS5ub3RpZnkoJ0VtYWlsIGhhcyBiZWVuIGltcG9ydGVkIHN1Y2Nlc3NmdWxseS4nKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLy8gZ2V0QmFja2dyb3VuZEltYWdlKCk6IFNhZmVTdHlsZSB7XG4gIC8vICAgY29uc3Qge1xuICAvLyAgICAgYmFja2dyb3VuZDogeyB1cmwgfVxuICAvLyAgIH0gPSB0aGlzLmVtYWlsLmdlbmVyYWw7XG4gIC8vICAgcmV0dXJuIHRoaXMuc2FuaXRpemVyLmJ5cGFzc1NlY3VyaXR5VHJ1c3RTdHlsZSh1cmwgJiYgYHVybCgke3VybH0pYCk7XG4gIC8vIH1cblxuICAvLyBnZXRCdWlsZGVyQ29udGFpbmVyU3R5bGVzKCkge1xuICAvLyAgIGNvbnN0IHsgYmFja2dyb3VuZCwgcGFkZGluZywgZGlyZWN0aW9uIH0gPSB0aGlzLmVtYWlsT2JqZWN0U3RvcmUuRW1haWwuZ2VuZXJhbDtcblxuICAvLyAgIHJldHVybiB7XG4gIC8vICAgICBkaXJlY3Rpb24sXG4gIC8vICAgICBiYWNrZ3JvdW5kUmVwZWF0OiBiYWNrZ3JvdW5kLnJlcGVhdCxcbiAgLy8gICAgIGJhY2tncm91bmRDb2xvcjogYmFja2dyb3VuZC5jb2xvcixcbiAgLy8gICAgIGJhY2tncm91bmRTaXplOiBjcmVhdGVXaWR0aEhlaWdodChiYWNrZ3JvdW5kLnNpemUpLFxuICAvLyAgICAgYmFja2dyb3VuZFBvc2l0aW9uOiAndG9wIGNlbnRlcicsXG4gIC8vICAgICAuLi5jcmVhdGVQYWRkaW5nKHBhZGRpbmcpXG4gIC8vICAgfTtcbiAgLy8gfVxuXG4gIGNyZWF0ZUFycmF5RnJvbVN0cnVjdHVyZUNvbHVtbnMoeyBjb2x1bW5zIH0pOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIG5ldyBBcnJheShjb2x1bW5zKS5maWxsKCcnKTtcbiAgfVxuXG4gIHRvZ2dsZVByZXZpZXcoKSB7XG4gICAgcmV0dXJuIHRoaXMuZW1haWxPYmplY3RTdG9yZVxuICAgICAgLmNyZWF0ZUhUTUxUZW1wbGF0ZSQoKVxuICAgICAgLnBpcGUoXG4gICAgICAgIGV4aGF1c3RNYXAoKCkgPT4gdGhpcy5taWRkbGV3YXJlcy50b2dnbGVQcmV2aWV3KCF0aGlzLnByZXZpZXdUZW1wbGF0ZSkpLFxuICAgICAgICBjYXRjaEVycm9yKGVycm9yID0+XG4gICAgICAgICAgdGhpcy5taWRkbGV3YXJlcy5jYXRjaEVycm9yKGVycm9yKS5waXBlKFxuICAgICAgICAgICAgc3dpdGNoTWFwKCgpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy51c2VySW50ZXJmYWNlU2VydmljZS5ub3RpZnkoZXJyb3IubWVzc2FnZSk7XG4gICAgICAgICAgICAgIHJldHVybiBFTVBUWTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgKVxuICAgICAgICApLFxuICAgICAgICB0YWtlKDEpXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKG5leHRTdGF0ZSA9PiB7XG4gICAgICAgIHRoaXMucHJldmlld1RlbXBsYXRlID0gbmV4dFN0YXRlO1xuICAgICAgICB0aGlzLmNoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSk7XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICBmcm9tRXZlbnQ8QmVmb3JlVW5sb2FkRXZlbnQ+KHdpbmRvdywgJ2JlZm9yZXVubG9hZCcpXG4gICAgICAucGlwZShcbiAgICAgICAgd2l0aExhdGVzdEZyb20odGhpcy5lbWFpbE9iamVjdFN0b3JlLmN1cnJlbnRFbWFpbEhhc0NoYW5nZXMkKSxcbiAgICAgICAgZmlsdGVyKChbXywgZW1haWxJc0RpcnR5XSkgPT4gZW1haWxJc0RpcnR5KSxcbiAgICAgICAgc3dpdGNoTWFwKChbZXZlbnRdKSA9PiB0aGlzLm1pZGRsZXdhcmVzLnByZXZlbnRXaW5kb3dFeGl0KGV2ZW50KSksXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLl9vbkRlc3Ryb3kkKVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZShldiA9PiB7XG4gICAgICAgIGV2LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGV2LnJldHVyblZhbHVlID0gJyc7XG4gICAgICB9KTtcblxuICAgIHRoaXMuZW1haWxPYmplY3RTdG9yZS5lbWFpbEFzT2JzZXJ2YWJsZSQucGlwZSh0YWtlVW50aWwodGhpcy5fb25EZXN0cm95JCkpLnN1YnNjcmliZShlbWFpbCA9PiB7XG4gICAgICB0aGlzLm9uVG91Y2hlZD8uKCk7XG4gICAgICB0aGlzLm9uQ2hhbmdlPy4oZW1haWwpO1xuICAgICAgdGhpcy5lbWFpbENoYW5nZS5uZXh0KGVtYWlsKTtcbiAgICB9KTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcbiAgICBpZiAoY2hhbmdlcy5lbWFpbCkge1xuICAgICAgdGhpcy53cml0ZVZhbHVlKGNoYW5nZXMuZW1haWwuY3VycmVudFZhbHVlKTtcbiAgICB9XG4gIH1cblxuICAvLyBwcml2YXRlIHNldEVtYWlsKGVtYWlsOiBQQkVtYWlsKSB7XG4gIC8vICAgdHJ5IHtcbiAgLy8gICAgIHRoaXMuZW1haWxPYmplY3RTdG9yZS5zZXRFbWFpbChlbWFpbCk7XG4gIC8vICAgICB0aGlzLnByZXZpZXdUZW1wbGF0ZSA9IGZhbHNlO1xuICAvLyAgICAgdGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgLy8gICB9IGNhdGNoIChlcnJvcikge1xuICAvLyAgICAgdGhpcy51c2VySW50ZXJmYWNlU2VydmljZS5ub3RpZnkoZXJyb3IubWVzc2FnZSk7XG4gIC8vICAgfVxuICAvLyB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5fb25EZXN0cm95JC5uZXh0KCk7XG4gICAgdGhpcy5fb25EZXN0cm95JC5jb21wbGV0ZSgpO1xuXG4gICAgLy8gUmVzZXQgdGhlIGJ1aWxkZXIgc3RhdGVcbiAgICB0aGlzLnVzZXJJbnRlcmZhY2VTZXJ2aWNlLnJlc2V0KCk7XG5cbiAgICBpZiAodGhpcy5kb2MpIHtcbiAgICAgIHRoaXMuaW5jbHVkZWRGb250cy5mb3JFYWNoKGZvbnQgPT4gZm9udC5yZW1vdmUoKSk7XG4gICAgfVxuICAgIHRoaXMuaW5jbHVkZWRGb250cy5jbGVhcigpO1xuICB9XG59XG4iXX0=