@banta/sdk 4.7.14 → 4.7.16

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.
@@ -182,7 +182,7 @@ export class BantaComponent {
182
182
  }
183
183
  }
184
184
  BantaComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaComponent, deps: [{ token: i1.ChatBackendBase }, { token: i2.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
185
- BantaComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: BantaComponent, selector: "banta", inputs: { topicID: "topicID", chatLabel: "chatLabel", commentsLabel: "commentsLabel" }, outputs: { signInSelected: "signInSelected" }, host: { properties: { "class.point-focus": "this.hasPoint" } }, viewQueries: [{ propertyName: "firehose", first: true, predicate: ["firehose"], descendants: true, static: true }], ngImport: i0, template: "\r\n<mat-menu #userMenu=\"matMenu\">\r\n <ng-container *ngIf=\"currentUser\">\r\n <button [disabled]=\"true\" mat-menu-item>{{currentUser.displayName}} (@{{currentUser.username}})</button>\r\n <button mat-menu-item (click)=\"signOut()\">Sign Out</button>\r\n </ng-container>\r\n <ng-container *ngIf=\"!currentUser\">\r\n <button mat-menu-item>Sign In</button>\r\n </ng-container>\r\n <button mat-menu-item>Help</button>\r\n</mat-menu>\r\n\r\n<div class=\"tabs\">\r\n <div>\r\n <a mat-button (click)=\"mobileFocus = 'chat'\">{{chatLabel}}</a>\r\n <a mat-button (click)=\"mobileFocus = 'comments'\">{{commentsLabel}}</a>\r\n </div>\r\n <div class=\"spacer\"></div>\r\n <div>\r\n <ng-container *ngIf=\"currentUser\">\r\n <button mat-button [matMenuTriggerFor]=\"userMenu\">\r\n @{{currentUser.username}}\r\n </button>\r\n <button mat-icon-button (click)=\"showNotifications()\">\r\n <mat-icon>notification_important</mat-icon>\r\n </button>\r\n </ng-container>\r\n \r\n <button mat-button *ngIf=\"!currentUser\" (click)=\"showSignIn()\">\r\n Sign In\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<div class=\"firehose\" [class.focus]=\"mobileFocus === 'chat'\">\r\n <header>\r\n <div>\r\n <label (click)=\"mobileFocus = 'chat'\">{{chatLabel}}</label>\r\n <div class=\"spacer\"></div>\r\n\r\n <ng-container *ngIf=\"currentUser\">\r\n <button mat-button [matMenuTriggerFor]=\"userMenu\">\r\n @{{currentUser.username}}\r\n </button>\r\n <button mat-icon-button (click)=\"showNotifications()\">\r\n <mat-icon>notification_important</mat-icon>\r\n </button>\r\n </ng-container>\r\n \r\n <button mat-button *ngIf=\"!currentUser\" (click)=\"showSignIn()\">\r\n Sign In\r\n </button>\r\n </div>\r\n </header>\r\n <banta-chat \r\n #firehose\r\n [source]=\"firehoseSource\"\r\n (signInSelected)=\"showSignIn()\"\r\n (upvoted)=\"upvoteMessage($event)\"\r\n (userSelected)=\"showProfile($event.user)\"\r\n (reported)=\"reportMessage($event)\"\r\n ></banta-chat>\r\n</div>\r\n\r\n<div class=\"aux\" [class.focus]=\"mobileFocus === 'aux'\" [class.open]=\"auxOpen\">\r\n <header>\r\n <div>\r\n <label>{{auxTitle}}</label>\r\n <div class=\"spacer\"></div>\r\n <button mat-icon-button (click)=\"auxOpen = false\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n </div>\r\n </header>\r\n <div class=\"aux-contents\">\r\n <ng-container *ngIf=\"auxMode === 'profile'\">\r\n <ng-container *ngIf=\"profileUser\">\r\n\r\n <div>\r\n <strong style=\"font-size: 125%;\">\r\n {{profileUser.displayName}}\r\n </strong>\r\n @{{profileUser.username}}\r\n </div>\r\n\r\n <br/>\r\n <strong>Top Messages</strong>\r\n\r\n <div>\r\n <em>Not yet available</em>\r\n </div>\r\n\r\n <br/>\r\n <strong>Recent Messages</strong>\r\n\r\n <div>\r\n <em>Not yet available</em>\r\n </div>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"auxMode === 'report'\">\r\n <p>Are you sure you want to report this message?</p>\r\n\r\n <banta-live-message [message]=\"reportedMessage\"></banta-live-message>\r\n\r\n <div style=\"text-align: center;\">\r\n <button mat-raised-button color=\"primary\" (click)=\"sendReport(reportedMessage)\">Yes, Report</button>\r\n &nbsp;\r\n <button mat-raised-button color=\"secondary\" (click)=\"auxOpen = false\">No, Cancel</button>\r\n </div>\r\n\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"auxMode === 'notifications'\">\r\n\r\n <div *ngIf=\"!notifications || notifications.length === 0\">\r\n <em>You do not have any notifications yet</em>\r\n </div>\r\n \r\n <div class=\"notifications\">\r\n <div class=\"notification\" *ngFor=\"let notif of notifications\">\r\n <div>\r\n <ng-container *ngIf=\"notif.type === 'upvote'\">\r\n @{{notif.message?.user?.username}} upvoted your post\r\n \r\n <banta-live-message\r\n [message]=\"notif.message\"\r\n (upvoted)=\"upvoteMessage(notif.message)\"\r\n (reported)=\"reportMessage(notif.message)\"\r\n (selected)=\"goToMessage(notif.message)\">\r\n </banta-live-message>\r\n\r\n </ng-container>\r\n <ng-container *ngIf=\"notif.type === 'notice'\">\r\n <div>\r\n {{notif.message}}\r\n </div>\r\n <a mat-button target=\"_blank\" href=\"{{notif.actionUrl}}\">\r\n {{notif.actionLabel}}\r\n </a>\r\n </ng-container>\r\n <ng-container *ngIf=\"notif.type === 'mention'\">\r\n You were mentioned by @{{notif.message?.user?.username}}\r\n\r\n <banta-live-message\r\n [message]=\"notif.message\"\r\n (upvoted)=\"upvoteMessage(notif.message)\"\r\n (reported)=\"reportMessage(notif.message)\"\r\n (selected)=\"goToMessage(notif.message)\">\r\n </banta-live-message>\r\n\r\n </ng-container>\r\n <ng-container *ngIf=\"notif.type === 'reply'\">\r\n @{{notif.replyMessage?.user?.username}} replied to your post\r\n \r\n <banta-live-message\r\n [message]=\"notif.replyMessage\"\r\n (upvoted)=\"upvoteMessage(notif.replyMessage)\"\r\n (reported)=\"reportMessage(notif.replyMessage)\"\r\n (selected)=\"goToMessage(notif.replyMessage)\">\r\n </banta-live-message>\r\n </ng-container>\r\n </div>\r\n\r\n <banta-timestamp [value]=\"notif.sentAt\"></banta-timestamp>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n</div>\r\n<div class=\"points\" [class.focus]=\"mobileFocus === 'points'\">\r\n <header>\r\n <div>\r\n <label>{{commentsLabel}}</label>\r\n </div>\r\n </header>\r\n <div class=\"point-focus\">\r\n <div class=\"actions\">\r\n <button mat-button (click)=\"pointUnfocus()\">\r\n <mat-icon>arrow_back</mat-icon>\r\n Back\r\n </button>\r\n\r\n <div class=\"spacer\"></div>\r\n \r\n <ng-container *ngIf=\"pointOpen\">\r\n <div class=\"counted-action\">\r\n <div class=\"count-indicator\"> \r\n {{pointOpen.likes}}\r\n </div>\r\n <button mat-icon-button>\r\n <mat-icon>thumb_up</mat-icon>\r\n </button>\r\n </div>\r\n\r\n </ng-container>\r\n </div>\r\n\r\n <div *ngIf=\"!pointSubChat\">\r\n Error: No subchat\r\n </div>\r\n \r\n <banta-comment-view\r\n class=\"subcomments\"\r\n *ngIf=\"pointSubChat\"\r\n [newestLast]=\"true\"\r\n [allowReplies]=\"false\"\r\n [source]=\"pointSubChat\"\r\n (upvoted)=\"upvoteMessage($event)\"\r\n (reported)=\"reportMessage($event)\"\r\n (userSelected)=\"showProfile($event.user)\"\r\n >\r\n \r\n <banta-comment\r\n class=\"focused-comment\"\r\n data-before\r\n *ngIf=\"pointOpen\"\r\n (upvoted)=\"upvoteMessage(pointOpen)\"\r\n (userSelected)=\"showProfile(pointOpen.user)\"\r\n (reported)=\"reportMessage(pointOpen)\"\r\n [showReplyAction]=\"false\"\r\n [message]=\"pointOpen\"\r\n ></banta-comment>\r\n \r\n <div class=\"message reply\">\r\n Reply:\r\n <form class=\"new-message\" (submit)=\"sendPointSubMessage()\">\r\n <textarea \r\n name=\"message\" \r\n (keydown)=\"newPointSubMessageKeyDown($event)\"\r\n [(ngModel)]=\"newPointSubMessage.message\"></textarea>\r\n \r\n <div class=\"actions\">\r\n <button [disabled]=\"!newPointSubMessage.message\" \r\n mat-raised-button color=\"primary\">Send</button>\r\n </div>\r\n </form>\r\n </div>\r\n </banta-comment-view>\r\n </div>\r\n <div class=\"points-section\">\r\n <banta-comments\r\n [source]=\"pointSource\"\r\n (signInSelected)=\"showSignIn()\"\r\n (upvoted)=\"upvoteMessage($event)\"\r\n (reported)=\"reportMessage($event)\"\r\n (selected)=\"goToMessage($event)\"\r\n (userSelected)=\"showProfile($event.user)\"\r\n ></banta-comments>\r\n </div>\r\n</div>", styles: [":host{display:flex;flex-direction:row;padding:.5em;height:40em;position:relative}.counted-action{display:flex;align-items:center}.count-indicator{font-size:9pt;padding:0 3px;border-radius:3px;border:1px solid #333}header{position:relative;margin-bottom:1em}header div{display:flex;align-items:center;height:30px}header button{color:#666}header label{text-transform:uppercase;z-index:1;font-size:12pt;letter-spacing:2px;font-weight:100;color:#333;margin:0 auto 0 0;display:block;width:-moz-fit-content;width:fit-content;position:relative;white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis}header:after{content:\"\";border:1px solid;border-color:#ccc;height:0px;width:100%;display:block;position:relative;z-index:0}.points{width:33%;max-width:50em;display:flex;flex-direction:column}:host.point-focus .points{width:66%;max-width:50em}:host.point-focus .points .points-section{opacity:0;pointer-events:none}:host.point-focus .points .point-focus{opacity:1;pointer-events:initial}:host.point-focus .points .point-focus .actions{display:flex}banta-comments{flex-grow:1}.points{width:33%;margin-left:.5em;font-size:12pt;flex-shrink:0;max-width:30em;transition:.2s width ease-in,.2s max-width ease-in;position:relative}.points .points-section{flex-grow:1;display:flex;flex-direction:column;opacity:1;transition:.2s opacity ease-in;z-index:2}.points .point-focus{position:absolute;width:100%;inset:1.75em 0 0;padding:.5em;opacity:0;transition:.2s opacity ease-in;flex-grow:1;display:flex;flex-direction:column}.firehose{flex-grow:1;font-size:10pt;display:flex;flex-direction:column}form{display:flex;padding:.5em 0;align-items:center}form textarea{font-size:14pt;background:black;color:#fff;border:1px solid #333;min-height:6em;width:100%}form input[type=text]{background:black;color:#fff;border:1px solid #333;width:100%;height:1em}form .actions{margin-left:1em}form button{display:block;margin:0 0 0 auto}.subcomments ::ng-deep banta-comment{font-size:10pt}.subcomments ::ng-deep banta-comment.focused-comment{background:#001321;color:#fff;font-size:12pt}.aux{width:0px;min-width:0px;overflow-x:hidden;transition:.4s width ease-out,.4s min-width ease-out;display:flex;flex-direction:column}.aux.open{width:30em;min-width:18em}.aux .aux-contents{width:30em;min-width:10em;max-width:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;flex-grow:1}.notifications .notification{border-bottom:1px solid #333;padding:1em}.notifications .notification banta-timestamp{display:block;text-align:right;font-size:9pt;color:#999}.message.reply{padding:1em}.tabs{display:none}@media (max-width: 1015px){:host{flex-direction:column}.tabs{display:flex;position:absolute;top:0;left:0;right:0;width:100%;z-index:10;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);background:rgba(0,0,0,.5)}.points{width:100%;max-width:100%;margin-left:0}header{display:none}:host.point-focus .points{width:100%;max-width:100%}.aux{width:100%;min-width:0;min-width:initial;max-width:100%}.points,.firehose,.aux{position:absolute;inset:2em 0 0;z-index:0;background:black}.points.focus,.firehose.focus,.aux.focus{z-index:2}}:host-context(.mat-dark-theme) :host{background:#090909;color:#fff}:host-context(.mat-dark-theme) form textarea{background:#ccc;color:#333}:host-context(.mat-dark-theme) header:after{border-color:#222}:host-context(.mat-dark-theme) header label{color:#aaa}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i4.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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i4.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i5.TimestampComponent, selector: "banta-timestamp", inputs: ["value"] }, { kind: "component", type: i6.CommentComponent, selector: "banta-comment", inputs: ["maxLength", "message", "customMenuItems", "showReplyAction", "permissions", "mine", "editing", "genericAvatarUrl"], outputs: ["loaded", "userSelected", "usernameSelected", "avatarSelected", "reported", "liked", "unliked", "selected", "edited", "deleted", "editStarted", "editEnded", "shared"] }, { kind: "component", type: i7.CommentViewComponent, selector: "banta-comment-view", inputs: ["showEmptyState", "allowReplies", "customMenuItems", "fixedHeight", "selectedMessage", "source", "genericAvatarUrl", "maxMessages", "maxVisibleMessages", "newestLast"], outputs: ["selected", "messageEdited", "userSelected", "reported", "liked", "unliked", "usernameSelected", "avatarSelected", "shared", "deleted", "sortOrderChanged"] }, { kind: "component", type: i8.BantaCommentsComponent, selector: "banta-comments", inputs: ["customMenuItems", "maxCommentLength", "loadingMessages", "useInlineReplies", "signInLabel", "sendLabel", "replyLabel", "sendingLabel", "permissionDeniedLabel", "postCommentLabel", "postReplyLabel", "allowAttachments", "fixedHeight", "maxMessages", "maxVisibleMessages", "genericAvatarUrl", "shouldInterceptMessageSend", "participants", "source", "hashtags", "topicID"], outputs: ["signInSelected", "editAvatarSelected", "permissionDeniedError", "upvoted", "reported", "selected", "userSelected", "usernameSelected", "avatarSelected", "shared"] }, { kind: "component", type: i9.BantaChatComponent, selector: "banta-chat", inputs: ["shouldInterceptMessageSend", "source", "topicID", "signInLabel", "sendLabel", "permissionDeniedLabel", "messageFieldPlaceholder", "emptyLabel"], outputs: ["selected", "reported", "upvoted", "userSelected", "permissionDeniedError", "signInSelected", "received"] }, { kind: "component", type: i10.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i11.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: "component", type: i11.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: i12.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "component", type: i12.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i12.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "component", type: i13.LiveMessageComponent, selector: "banta-live-message", inputs: ["message"], outputs: ["upvoted", "reported", "selected"] }] });
185
+ BantaComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: BantaComponent, selector: "banta", inputs: { topicID: "topicID", chatLabel: "chatLabel", commentsLabel: "commentsLabel" }, outputs: { signInSelected: "signInSelected" }, host: { properties: { "class.point-focus": "this.hasPoint" } }, viewQueries: [{ propertyName: "firehose", first: true, predicate: ["firehose"], descendants: true, static: true }], ngImport: i0, template: "\r\n<mat-menu #userMenu=\"matMenu\">\r\n <ng-container *ngIf=\"currentUser\">\r\n <button [disabled]=\"true\" mat-menu-item>{{currentUser.displayName}} (@{{currentUser.username}})</button>\r\n <button mat-menu-item (click)=\"signOut()\">Sign Out</button>\r\n </ng-container>\r\n <ng-container *ngIf=\"!currentUser\">\r\n <button mat-menu-item>Sign In</button>\r\n </ng-container>\r\n <button mat-menu-item>Help</button>\r\n</mat-menu>\r\n\r\n<div class=\"tabs\">\r\n <div>\r\n <a mat-button (click)=\"mobileFocus = 'chat'\">{{chatLabel}}</a>\r\n <a mat-button (click)=\"mobileFocus = 'comments'\">{{commentsLabel}}</a>\r\n </div>\r\n <div class=\"spacer\"></div>\r\n <div>\r\n <ng-container *ngIf=\"currentUser\">\r\n <button mat-button [matMenuTriggerFor]=\"userMenu\">\r\n @{{currentUser.username}}\r\n </button>\r\n <button mat-icon-button (click)=\"showNotifications()\">\r\n <mat-icon>notification_important</mat-icon>\r\n </button>\r\n </ng-container>\r\n \r\n <button mat-button *ngIf=\"!currentUser\" (click)=\"showSignIn()\">\r\n Sign In\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<div class=\"firehose\" [class.focus]=\"mobileFocus === 'chat'\">\r\n <header>\r\n <div>\r\n <label (click)=\"mobileFocus = 'chat'\">{{chatLabel}}</label>\r\n <div class=\"spacer\"></div>\r\n\r\n <ng-container *ngIf=\"currentUser\">\r\n <button mat-button [matMenuTriggerFor]=\"userMenu\">\r\n @{{currentUser.username}}\r\n </button>\r\n <button mat-icon-button (click)=\"showNotifications()\">\r\n <mat-icon>notification_important</mat-icon>\r\n </button>\r\n </ng-container>\r\n \r\n <button mat-button *ngIf=\"!currentUser\" (click)=\"showSignIn()\">\r\n Sign In\r\n </button>\r\n </div>\r\n </header>\r\n <banta-chat \r\n #firehose\r\n [source]=\"firehoseSource\"\r\n (signInSelected)=\"showSignIn()\"\r\n (upvoted)=\"upvoteMessage($event)\"\r\n (userSelected)=\"showProfile($event.user)\"\r\n (reported)=\"reportMessage($event)\"\r\n ></banta-chat>\r\n</div>\r\n\r\n<div class=\"aux\" [class.focus]=\"mobileFocus === 'aux'\" [class.open]=\"auxOpen\">\r\n <header>\r\n <div>\r\n <label>{{auxTitle}}</label>\r\n <div class=\"spacer\"></div>\r\n <button mat-icon-button (click)=\"auxOpen = false\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n </div>\r\n </header>\r\n <div class=\"aux-contents\">\r\n <ng-container *ngIf=\"auxMode === 'profile'\">\r\n <ng-container *ngIf=\"profileUser\">\r\n\r\n <div>\r\n <strong style=\"font-size: 125%;\">\r\n {{profileUser.displayName}}\r\n </strong>\r\n @{{profileUser.username}}\r\n </div>\r\n\r\n <br/>\r\n <strong>Top Messages</strong>\r\n\r\n <div>\r\n <em>Not yet available</em>\r\n </div>\r\n\r\n <br/>\r\n <strong>Recent Messages</strong>\r\n\r\n <div>\r\n <em>Not yet available</em>\r\n </div>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"auxMode === 'report'\">\r\n <p>Are you sure you want to report this message?</p>\r\n\r\n <banta-live-message [message]=\"reportedMessage\"></banta-live-message>\r\n\r\n <div style=\"text-align: center;\">\r\n <button mat-raised-button color=\"primary\" (click)=\"sendReport(reportedMessage)\">Yes, Report</button>\r\n &nbsp;\r\n <button mat-raised-button color=\"secondary\" (click)=\"auxOpen = false\">No, Cancel</button>\r\n </div>\r\n\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"auxMode === 'notifications'\">\r\n\r\n <div *ngIf=\"!notifications || notifications.length === 0\">\r\n <em>You do not have any notifications yet</em>\r\n </div>\r\n \r\n <div class=\"notifications\">\r\n <div class=\"notification\" *ngFor=\"let notif of notifications\">\r\n <div>\r\n <ng-container *ngIf=\"notif.type === 'upvote'\">\r\n @{{notif.message?.user?.username}} upvoted your post\r\n \r\n <banta-live-message\r\n [message]=\"notif.message\"\r\n (upvoted)=\"upvoteMessage(notif.message)\"\r\n (reported)=\"reportMessage(notif.message)\"\r\n (selected)=\"goToMessage(notif.message)\">\r\n </banta-live-message>\r\n\r\n </ng-container>\r\n <ng-container *ngIf=\"notif.type === 'notice'\">\r\n <div>\r\n {{notif.message}}\r\n </div>\r\n <a mat-button target=\"_blank\" href=\"{{notif.actionUrl}}\">\r\n {{notif.actionLabel}}\r\n </a>\r\n </ng-container>\r\n <ng-container *ngIf=\"notif.type === 'mention'\">\r\n You were mentioned by @{{notif.message?.user?.username}}\r\n\r\n <banta-live-message\r\n [message]=\"notif.message\"\r\n (upvoted)=\"upvoteMessage(notif.message)\"\r\n (reported)=\"reportMessage(notif.message)\"\r\n (selected)=\"goToMessage(notif.message)\">\r\n </banta-live-message>\r\n\r\n </ng-container>\r\n <ng-container *ngIf=\"notif.type === 'reply'\">\r\n @{{notif.replyMessage?.user?.username}} replied to your post\r\n \r\n <banta-live-message\r\n [message]=\"notif.replyMessage\"\r\n (upvoted)=\"upvoteMessage(notif.replyMessage)\"\r\n (reported)=\"reportMessage(notif.replyMessage)\"\r\n (selected)=\"goToMessage(notif.replyMessage)\">\r\n </banta-live-message>\r\n </ng-container>\r\n </div>\r\n\r\n <banta-timestamp [value]=\"notif.sentAt\"></banta-timestamp>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n</div>\r\n<div class=\"points\" [class.focus]=\"mobileFocus === 'points'\">\r\n <header>\r\n <div>\r\n <label>{{commentsLabel}}</label>\r\n </div>\r\n </header>\r\n <div class=\"point-focus\">\r\n <div class=\"actions\">\r\n <button mat-button (click)=\"pointUnfocus()\">\r\n <mat-icon>arrow_back</mat-icon>\r\n Back\r\n </button>\r\n\r\n <div class=\"spacer\"></div>\r\n \r\n <ng-container *ngIf=\"pointOpen\">\r\n <div class=\"counted-action\">\r\n <div class=\"count-indicator\"> \r\n {{pointOpen.likes}}\r\n </div>\r\n <button mat-icon-button>\r\n <mat-icon>thumb_up</mat-icon>\r\n </button>\r\n </div>\r\n\r\n </ng-container>\r\n </div>\r\n\r\n <div *ngIf=\"!pointSubChat\">\r\n Error: No subchat\r\n </div>\r\n \r\n <banta-comment-view\r\n class=\"subcomments\"\r\n *ngIf=\"pointSubChat\"\r\n [newestLast]=\"true\"\r\n [allowReplies]=\"false\"\r\n [source]=\"pointSubChat\"\r\n (upvoted)=\"upvoteMessage($event)\"\r\n (reported)=\"reportMessage($event)\"\r\n (userSelected)=\"showProfile($event.user)\"\r\n >\r\n \r\n <banta-comment\r\n class=\"focused-comment\"\r\n data-before\r\n *ngIf=\"pointOpen\"\r\n (upvoted)=\"upvoteMessage(pointOpen)\"\r\n (userSelected)=\"showProfile(pointOpen.user)\"\r\n (reported)=\"reportMessage(pointOpen)\"\r\n [showReplyAction]=\"false\"\r\n [message]=\"pointOpen\"\r\n ></banta-comment>\r\n \r\n <div class=\"message reply\">\r\n Reply:\r\n <form class=\"new-message\" (submit)=\"sendPointSubMessage()\">\r\n <textarea \r\n name=\"message\" \r\n (keydown)=\"newPointSubMessageKeyDown($event)\"\r\n [(ngModel)]=\"newPointSubMessage.message\"></textarea>\r\n \r\n <div class=\"actions\">\r\n <button [disabled]=\"!newPointSubMessage.message\" \r\n mat-raised-button color=\"primary\">Send</button>\r\n </div>\r\n </form>\r\n </div>\r\n </banta-comment-view>\r\n </div>\r\n <div class=\"points-section\">\r\n <banta-comments\r\n [source]=\"pointSource\"\r\n (signInSelected)=\"showSignIn()\"\r\n (upvoted)=\"upvoteMessage($event)\"\r\n (reported)=\"reportMessage($event)\"\r\n (selected)=\"goToMessage($event)\"\r\n (userSelected)=\"showProfile($event.user)\"\r\n ></banta-comments>\r\n </div>\r\n</div>", styles: [":host{display:flex;flex-direction:row;padding:.5em;height:40em;position:relative}.counted-action{display:flex;align-items:center}.count-indicator{font-size:9pt;padding:0 3px;border-radius:3px;border:1px solid #333}header{position:relative;margin-bottom:1em}header div{display:flex;align-items:center;height:30px}header button{color:#666}header label{text-transform:uppercase;z-index:1;font-size:12pt;letter-spacing:2px;font-weight:100;color:#333;margin:0 auto 0 0;display:block;width:-moz-fit-content;width:fit-content;position:relative;white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis}header:after{content:\"\";border:1px solid;border-color:#ccc;height:0px;width:100%;display:block;position:relative;z-index:0}.points{width:33%;max-width:50em;display:flex;flex-direction:column}:host.point-focus .points{width:66%;max-width:50em}:host.point-focus .points .points-section{opacity:0;pointer-events:none}:host.point-focus .points .point-focus{opacity:1;pointer-events:initial}:host.point-focus .points .point-focus .actions{display:flex}banta-comments{flex-grow:1}.points{width:33%;margin-left:.5em;font-size:12pt;flex-shrink:0;max-width:30em;transition:.2s width ease-in,.2s max-width ease-in;position:relative}.points .points-section{flex-grow:1;display:flex;flex-direction:column;opacity:1;transition:.2s opacity ease-in;z-index:2}.points .point-focus{position:absolute;width:100%;inset:1.75em 0 0;padding:.5em;opacity:0;transition:.2s opacity ease-in;flex-grow:1;display:flex;flex-direction:column}.firehose{flex-grow:1;font-size:10pt;display:flex;flex-direction:column}form{display:flex;padding:.5em 0;align-items:center}form textarea{font-size:14pt;background:black;color:#fff;border:1px solid #333;min-height:6em;width:100%}form input[type=text]{background:black;color:#fff;border:1px solid #333;width:100%;height:1em}form .actions{margin-left:1em}form button{display:block;margin:0 0 0 auto}.subcomments ::ng-deep banta-comment{font-size:10pt}.subcomments ::ng-deep banta-comment.focused-comment{background:#001321;color:#fff;font-size:12pt}.aux{width:0px;min-width:0px;overflow-x:hidden;transition:.4s width ease-out,.4s min-width ease-out;display:flex;flex-direction:column}.aux.open{width:30em;min-width:18em}.aux .aux-contents{width:30em;min-width:10em;max-width:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;flex-grow:1}.notifications .notification{border-bottom:1px solid #333;padding:1em}.notifications .notification banta-timestamp{display:block;text-align:right;font-size:9pt;color:#999}.message.reply{padding:1em}.tabs{display:none}@media (max-width: 1015px){:host{flex-direction:column}.tabs{display:flex;position:absolute;top:0;left:0;right:0;width:100%;z-index:10;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);background:rgba(0,0,0,.5)}.points{width:100%;max-width:100%;margin-left:0}header{display:none}:host.point-focus .points{width:100%;max-width:100%}.aux{width:100%;min-width:0;min-width:initial;max-width:100%}.points,.firehose,.aux{position:absolute;inset:2em 0 0;z-index:0;background:black}.points.focus,.firehose.focus,.aux.focus{z-index:2}}:host-context(.mat-dark-theme) :host{background:#090909;color:#fff}:host-context(.mat-dark-theme) form textarea{background:#ccc;color:#333}:host-context(.mat-dark-theme) header:after{border-color:#222}:host-context(.mat-dark-theme) header label{color:#aaa}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i4.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.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i4.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i5.TimestampComponent, selector: "banta-timestamp", inputs: ["value"] }, { kind: "component", type: i6.CommentComponent, selector: "banta-comment", inputs: ["maxLength", "message", "customMenuItems", "showReplyAction", "permissions", "mine", "editing", "genericAvatarUrl"], outputs: ["loaded", "userSelected", "usernameSelected", "avatarSelected", "reported", "liked", "unliked", "selected", "edited", "deleted", "editStarted", "editEnded", "shared"] }, { kind: "component", type: i7.CommentViewComponent, selector: "banta-comment-view", inputs: ["showEmptyState", "allowReplies", "customMenuItems", "fixedHeight", "selectedMessage", "source", "genericAvatarUrl", "maxMessages", "maxVisibleMessages", "newestLast"], outputs: ["selected", "messageEdited", "userSelected", "reported", "liked", "unliked", "usernameSelected", "avatarSelected", "shared", "deleted", "sortOrderChanged"] }, { kind: "component", type: i8.BantaCommentsComponent, selector: "banta-comments", inputs: ["customMenuItems", "maxCommentLength", "loadingMessages", "useInlineReplies", "signInLabel", "sendLabel", "signingInLabel", "replyLabel", "sendingLabel", "permissionDeniedLabel", "postCommentLabel", "postReplyLabel", "allowAttachments", "fixedHeight", "maxMessages", "maxVisibleMessages", "genericAvatarUrl", "shouldInterceptMessageSend", "participants", "source", "hashtags", "topicID"], outputs: ["signInSelected", "editAvatarSelected", "permissionDeniedError", "upvoted", "reported", "selected", "userSelected", "usernameSelected", "avatarSelected", "shared"] }, { kind: "component", type: i9.BantaChatComponent, selector: "banta-chat", inputs: ["shouldInterceptMessageSend", "source", "topicID", "signInLabel", "sendLabel", "permissionDeniedLabel", "messageFieldPlaceholder", "emptyLabel"], outputs: ["selected", "reported", "upvoted", "userSelected", "permissionDeniedError", "signInSelected", "received"] }, { kind: "component", type: i10.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i11.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: "component", type: i11.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: i12.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { kind: "component", type: i12.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i12.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { kind: "component", type: i13.LiveMessageComponent, selector: "banta-live-message", inputs: ["message"], outputs: ["upvoted", "reported", "selected"] }] });
186
186
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: BantaComponent, decorators: [{
187
187
  type: Component,
188
188
  args: [{ selector: `banta`, template: "\r\n<mat-menu #userMenu=\"matMenu\">\r\n <ng-container *ngIf=\"currentUser\">\r\n <button [disabled]=\"true\" mat-menu-item>{{currentUser.displayName}} (@{{currentUser.username}})</button>\r\n <button mat-menu-item (click)=\"signOut()\">Sign Out</button>\r\n </ng-container>\r\n <ng-container *ngIf=\"!currentUser\">\r\n <button mat-menu-item>Sign In</button>\r\n </ng-container>\r\n <button mat-menu-item>Help</button>\r\n</mat-menu>\r\n\r\n<div class=\"tabs\">\r\n <div>\r\n <a mat-button (click)=\"mobileFocus = 'chat'\">{{chatLabel}}</a>\r\n <a mat-button (click)=\"mobileFocus = 'comments'\">{{commentsLabel}}</a>\r\n </div>\r\n <div class=\"spacer\"></div>\r\n <div>\r\n <ng-container *ngIf=\"currentUser\">\r\n <button mat-button [matMenuTriggerFor]=\"userMenu\">\r\n @{{currentUser.username}}\r\n </button>\r\n <button mat-icon-button (click)=\"showNotifications()\">\r\n <mat-icon>notification_important</mat-icon>\r\n </button>\r\n </ng-container>\r\n \r\n <button mat-button *ngIf=\"!currentUser\" (click)=\"showSignIn()\">\r\n Sign In\r\n </button>\r\n </div>\r\n</div>\r\n\r\n<div class=\"firehose\" [class.focus]=\"mobileFocus === 'chat'\">\r\n <header>\r\n <div>\r\n <label (click)=\"mobileFocus = 'chat'\">{{chatLabel}}</label>\r\n <div class=\"spacer\"></div>\r\n\r\n <ng-container *ngIf=\"currentUser\">\r\n <button mat-button [matMenuTriggerFor]=\"userMenu\">\r\n @{{currentUser.username}}\r\n </button>\r\n <button mat-icon-button (click)=\"showNotifications()\">\r\n <mat-icon>notification_important</mat-icon>\r\n </button>\r\n </ng-container>\r\n \r\n <button mat-button *ngIf=\"!currentUser\" (click)=\"showSignIn()\">\r\n Sign In\r\n </button>\r\n </div>\r\n </header>\r\n <banta-chat \r\n #firehose\r\n [source]=\"firehoseSource\"\r\n (signInSelected)=\"showSignIn()\"\r\n (upvoted)=\"upvoteMessage($event)\"\r\n (userSelected)=\"showProfile($event.user)\"\r\n (reported)=\"reportMessage($event)\"\r\n ></banta-chat>\r\n</div>\r\n\r\n<div class=\"aux\" [class.focus]=\"mobileFocus === 'aux'\" [class.open]=\"auxOpen\">\r\n <header>\r\n <div>\r\n <label>{{auxTitle}}</label>\r\n <div class=\"spacer\"></div>\r\n <button mat-icon-button (click)=\"auxOpen = false\">\r\n <mat-icon>close</mat-icon>\r\n </button>\r\n </div>\r\n </header>\r\n <div class=\"aux-contents\">\r\n <ng-container *ngIf=\"auxMode === 'profile'\">\r\n <ng-container *ngIf=\"profileUser\">\r\n\r\n <div>\r\n <strong style=\"font-size: 125%;\">\r\n {{profileUser.displayName}}\r\n </strong>\r\n @{{profileUser.username}}\r\n </div>\r\n\r\n <br/>\r\n <strong>Top Messages</strong>\r\n\r\n <div>\r\n <em>Not yet available</em>\r\n </div>\r\n\r\n <br/>\r\n <strong>Recent Messages</strong>\r\n\r\n <div>\r\n <em>Not yet available</em>\r\n </div>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"auxMode === 'report'\">\r\n <p>Are you sure you want to report this message?</p>\r\n\r\n <banta-live-message [message]=\"reportedMessage\"></banta-live-message>\r\n\r\n <div style=\"text-align: center;\">\r\n <button mat-raised-button color=\"primary\" (click)=\"sendReport(reportedMessage)\">Yes, Report</button>\r\n &nbsp;\r\n <button mat-raised-button color=\"secondary\" (click)=\"auxOpen = false\">No, Cancel</button>\r\n </div>\r\n\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"auxMode === 'notifications'\">\r\n\r\n <div *ngIf=\"!notifications || notifications.length === 0\">\r\n <em>You do not have any notifications yet</em>\r\n </div>\r\n \r\n <div class=\"notifications\">\r\n <div class=\"notification\" *ngFor=\"let notif of notifications\">\r\n <div>\r\n <ng-container *ngIf=\"notif.type === 'upvote'\">\r\n @{{notif.message?.user?.username}} upvoted your post\r\n \r\n <banta-live-message\r\n [message]=\"notif.message\"\r\n (upvoted)=\"upvoteMessage(notif.message)\"\r\n (reported)=\"reportMessage(notif.message)\"\r\n (selected)=\"goToMessage(notif.message)\">\r\n </banta-live-message>\r\n\r\n </ng-container>\r\n <ng-container *ngIf=\"notif.type === 'notice'\">\r\n <div>\r\n {{notif.message}}\r\n </div>\r\n <a mat-button target=\"_blank\" href=\"{{notif.actionUrl}}\">\r\n {{notif.actionLabel}}\r\n </a>\r\n </ng-container>\r\n <ng-container *ngIf=\"notif.type === 'mention'\">\r\n You were mentioned by @{{notif.message?.user?.username}}\r\n\r\n <banta-live-message\r\n [message]=\"notif.message\"\r\n (upvoted)=\"upvoteMessage(notif.message)\"\r\n (reported)=\"reportMessage(notif.message)\"\r\n (selected)=\"goToMessage(notif.message)\">\r\n </banta-live-message>\r\n\r\n </ng-container>\r\n <ng-container *ngIf=\"notif.type === 'reply'\">\r\n @{{notif.replyMessage?.user?.username}} replied to your post\r\n \r\n <banta-live-message\r\n [message]=\"notif.replyMessage\"\r\n (upvoted)=\"upvoteMessage(notif.replyMessage)\"\r\n (reported)=\"reportMessage(notif.replyMessage)\"\r\n (selected)=\"goToMessage(notif.replyMessage)\">\r\n </banta-live-message>\r\n </ng-container>\r\n </div>\r\n\r\n <banta-timestamp [value]=\"notif.sentAt\"></banta-timestamp>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </div>\r\n</div>\r\n<div class=\"points\" [class.focus]=\"mobileFocus === 'points'\">\r\n <header>\r\n <div>\r\n <label>{{commentsLabel}}</label>\r\n </div>\r\n </header>\r\n <div class=\"point-focus\">\r\n <div class=\"actions\">\r\n <button mat-button (click)=\"pointUnfocus()\">\r\n <mat-icon>arrow_back</mat-icon>\r\n Back\r\n </button>\r\n\r\n <div class=\"spacer\"></div>\r\n \r\n <ng-container *ngIf=\"pointOpen\">\r\n <div class=\"counted-action\">\r\n <div class=\"count-indicator\"> \r\n {{pointOpen.likes}}\r\n </div>\r\n <button mat-icon-button>\r\n <mat-icon>thumb_up</mat-icon>\r\n </button>\r\n </div>\r\n\r\n </ng-container>\r\n </div>\r\n\r\n <div *ngIf=\"!pointSubChat\">\r\n Error: No subchat\r\n </div>\r\n \r\n <banta-comment-view\r\n class=\"subcomments\"\r\n *ngIf=\"pointSubChat\"\r\n [newestLast]=\"true\"\r\n [allowReplies]=\"false\"\r\n [source]=\"pointSubChat\"\r\n (upvoted)=\"upvoteMessage($event)\"\r\n (reported)=\"reportMessage($event)\"\r\n (userSelected)=\"showProfile($event.user)\"\r\n >\r\n \r\n <banta-comment\r\n class=\"focused-comment\"\r\n data-before\r\n *ngIf=\"pointOpen\"\r\n (upvoted)=\"upvoteMessage(pointOpen)\"\r\n (userSelected)=\"showProfile(pointOpen.user)\"\r\n (reported)=\"reportMessage(pointOpen)\"\r\n [showReplyAction]=\"false\"\r\n [message]=\"pointOpen\"\r\n ></banta-comment>\r\n \r\n <div class=\"message reply\">\r\n Reply:\r\n <form class=\"new-message\" (submit)=\"sendPointSubMessage()\">\r\n <textarea \r\n name=\"message\" \r\n (keydown)=\"newPointSubMessageKeyDown($event)\"\r\n [(ngModel)]=\"newPointSubMessage.message\"></textarea>\r\n \r\n <div class=\"actions\">\r\n <button [disabled]=\"!newPointSubMessage.message\" \r\n mat-raised-button color=\"primary\">Send</button>\r\n </div>\r\n </form>\r\n </div>\r\n </banta-comment-view>\r\n </div>\r\n <div class=\"points-section\">\r\n <banta-comments\r\n [source]=\"pointSource\"\r\n (signInSelected)=\"showSignIn()\"\r\n (upvoted)=\"upvoteMessage($event)\"\r\n (reported)=\"reportMessage($event)\"\r\n (selected)=\"goToMessage($event)\"\r\n (userSelected)=\"showProfile($event.user)\"\r\n ></banta-comments>\r\n </div>\r\n</div>", styles: [":host{display:flex;flex-direction:row;padding:.5em;height:40em;position:relative}.counted-action{display:flex;align-items:center}.count-indicator{font-size:9pt;padding:0 3px;border-radius:3px;border:1px solid #333}header{position:relative;margin-bottom:1em}header div{display:flex;align-items:center;height:30px}header button{color:#666}header label{text-transform:uppercase;z-index:1;font-size:12pt;letter-spacing:2px;font-weight:100;color:#333;margin:0 auto 0 0;display:block;width:-moz-fit-content;width:fit-content;position:relative;white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis}header:after{content:\"\";border:1px solid;border-color:#ccc;height:0px;width:100%;display:block;position:relative;z-index:0}.points{width:33%;max-width:50em;display:flex;flex-direction:column}:host.point-focus .points{width:66%;max-width:50em}:host.point-focus .points .points-section{opacity:0;pointer-events:none}:host.point-focus .points .point-focus{opacity:1;pointer-events:initial}:host.point-focus .points .point-focus .actions{display:flex}banta-comments{flex-grow:1}.points{width:33%;margin-left:.5em;font-size:12pt;flex-shrink:0;max-width:30em;transition:.2s width ease-in,.2s max-width ease-in;position:relative}.points .points-section{flex-grow:1;display:flex;flex-direction:column;opacity:1;transition:.2s opacity ease-in;z-index:2}.points .point-focus{position:absolute;width:100%;inset:1.75em 0 0;padding:.5em;opacity:0;transition:.2s opacity ease-in;flex-grow:1;display:flex;flex-direction:column}.firehose{flex-grow:1;font-size:10pt;display:flex;flex-direction:column}form{display:flex;padding:.5em 0;align-items:center}form textarea{font-size:14pt;background:black;color:#fff;border:1px solid #333;min-height:6em;width:100%}form input[type=text]{background:black;color:#fff;border:1px solid #333;width:100%;height:1em}form .actions{margin-left:1em}form button{display:block;margin:0 0 0 auto}.subcomments ::ng-deep banta-comment{font-size:10pt}.subcomments ::ng-deep banta-comment.focused-comment{background:#001321;color:#fff;font-size:12pt}.aux{width:0px;min-width:0px;overflow-x:hidden;transition:.4s width ease-out,.4s min-width ease-out;display:flex;flex-direction:column}.aux.open{width:30em;min-width:18em}.aux .aux-contents{width:30em;min-width:10em;max-width:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;flex-grow:1}.notifications .notification{border-bottom:1px solid #333;padding:1em}.notifications .notification banta-timestamp{display:block;text-align:right;font-size:9pt;color:#999}.message.reply{padding:1em}.tabs{display:none}@media (max-width: 1015px){:host{flex-direction:column}.tabs{display:flex;position:absolute;top:0;left:0;right:0;width:100%;z-index:10;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);background:rgba(0,0,0,.5)}.points{width:100%;max-width:100%;margin-left:0}header{display:none}:host.point-focus .points{width:100%;max-width:100%}.aux{width:100%;min-width:0;min-width:initial;max-width:100%}.points,.firehose,.aux{position:absolute;inset:2em 0 0;z-index:0;background:black}.points.focus,.firehose.focus,.aux.focus{z-index:2}}:host-context(.mat-dark-theme) :host{background:#090909;color:#fff}:host-context(.mat-dark-theme) form textarea{background:#ccc;color:#333}:host-context(.mat-dark-theme) header:after{border-color:#222}:host-context(.mat-dark-theme) header label{color:#aaa}\n"] }]
@@ -1,6 +1,7 @@
1
1
  import { __decorate } from "tslib";
2
- import { Subject, Subscription } from "rxjs";
2
+ import { BehaviorSubject, Subject, Subscription } from "rxjs";
3
3
  import { RpcEvent, SocketRPC } from "@banta/common";
4
+ import { v4 as uuid } from "uuid";
4
5
  export class ChatSource extends SocketRPC {
5
6
  constructor(backend, identifier, parentIdentifier, sortOrder) {
6
7
  super();
@@ -11,8 +12,12 @@ export class ChatSource extends SocketRPC {
11
12
  this.subscription = new Subscription();
12
13
  this._state = 'connecting';
13
14
  this._connectionStateChanged = new Subject();
15
+ this._connectionStateChanged$ = this._connectionStateChanged.asObservable();
14
16
  this.wasRestored = false;
15
17
  this.subscribeAttempt = 0;
18
+ this._signInState = 'signed-out';
19
+ this._signInStateChanged = new BehaviorSubject(this._signInState);
20
+ this._signInStateChanged$ = this._signInStateChanged.asObservable();
16
21
  this.messageMap = new Map();
17
22
  this._messageReceived = new Subject();
18
23
  this._messageUpdated = new Subject();
@@ -28,9 +33,7 @@ export class ChatSource extends SocketRPC {
28
33
  this._state = value;
29
34
  setTimeout(() => this._connectionStateChanged.next(this._state));
30
35
  }
31
- get connectionStateChanged() {
32
- return this._connectionStateChanged.asObservable();
33
- }
36
+ get connectionStateChanged() { return this._connectionStateChanged$; }
34
37
  async bind(socket) {
35
38
  super.bind(socket);
36
39
  this.subscription.add(this.backend.userChanged.subscribe(() => this.authenticate()));
@@ -45,7 +48,12 @@ export class ChatSource extends SocketRPC {
45
48
  await this.authenticate();
46
49
  await this.subscribeToTopic();
47
50
  });
48
- await this.subscribeToTopic();
51
+ try {
52
+ await this.subscribeToTopic();
53
+ }
54
+ catch (e) {
55
+ console.error(`[Banta/ChatSource] Error during initial subscribeToTopic: ${e.message}`);
56
+ }
49
57
  return this;
50
58
  }
51
59
  mapOrUpdateMessages(messages) {
@@ -64,7 +72,7 @@ export class ChatSource extends SocketRPC {
64
72
  }
65
73
  async getExistingMessages() {
66
74
  try {
67
- let messages = await this.peer.getExistingMessages();
75
+ let messages = await this.idempotentPeer.getExistingMessages();
68
76
  messages = this.mapOrUpdateMessages(messages);
69
77
  return messages;
70
78
  }
@@ -75,13 +83,13 @@ export class ChatSource extends SocketRPC {
75
83
  }
76
84
  }
77
85
  async ensureConnection(errorMessage) {
78
- let reason = `Connection to chat services is not currently available.`;
79
- if (this.state !== 'connected' && this.state !== 'restored') {
80
- if (errorMessage)
81
- throw new Error(`${errorMessage}: ${reason}`);
82
- else
83
- throw new Error(`${reason}`);
84
- }
86
+ // let reason = `Connection to chat services is not currently available.`;
87
+ // if (this.state !== 'connected' && this.state !== 'restored') {
88
+ // if (errorMessage)
89
+ // throw new Error(`${errorMessage}: ${reason}`);
90
+ // else
91
+ // throw new Error(`${reason}`);
92
+ // }
85
93
  }
86
94
  async editMessage(messageId, text) {
87
95
  await this.ensureConnection();
@@ -92,7 +100,7 @@ export class ChatSource extends SocketRPC {
92
100
  }
93
101
  async subscribeToTopic() {
94
102
  try {
95
- await this.peer.subscribe(this.identifier, this.parentIdentifier, this.sortOrder);
103
+ await this.immediatePeer.subscribe(this.identifier, this.parentIdentifier, this.sortOrder);
96
104
  this.subscribeAttempt = 0;
97
105
  this._errorState = undefined;
98
106
  this.state = this.wasRestored ? 'restored' : 'connected';
@@ -107,19 +115,34 @@ export class ChatSource extends SocketRPC {
107
115
  let delay = Math.min(30 * 1000, (3 * 1000 * this.subscribeAttempt) * (1 + Math.random()));
108
116
  console.error(`[Banta/${this.identifier}] Waiting ${delay}ms before attempting to reconnect...`);
109
117
  setTimeout(() => {
110
- console.info(`Attempting reconnection after error in subscribeToTopic...`);
111
- this.reconnect();
118
+ if (this.state === 'lost') {
119
+ console.info(`Attempting reconnection after error in subscribeToTopic...`);
120
+ this.reconnect();
121
+ }
112
122
  }, delay);
123
+ throw e;
113
124
  }
114
125
  }
126
+ get signInState() { return this._signInState; }
127
+ get signInStateChanged() { return this._signInStateChanged$; }
128
+ setSignInState(state) {
129
+ this._signInState = state;
130
+ this._signInStateChanged.next(state);
131
+ }
115
132
  async authenticate() {
133
+ this.setSignInState('signing-in');
116
134
  if (this.backend.user) {
117
135
  try {
118
- await this.peer.authenticate(this.backend.user?.token);
136
+ // console.log(`Artificial delay...`);
137
+ // await new Promise(r => setTimeout(r, 30_000));
138
+ // console.log(`Artificial delay complete...`);
139
+ await this.immediatePeer.authenticate(this.backend.user?.token);
140
+ this.setSignInState('signed-in');
119
141
  }
120
142
  catch (e) {
121
- console.error(`Could not authenticate with Banta server:`);
143
+ console.error(`[Banta] Could not authenticate:`);
122
144
  console.error(e);
145
+ this.setSignInState('signed-out');
123
146
  }
124
147
  }
125
148
  }
@@ -149,20 +172,21 @@ export class ChatSource extends SocketRPC {
149
172
  get messageObserved() { return this._messageObserved.asObservable(); }
150
173
  async send(message) {
151
174
  await this.ensureConnection();
152
- return await this.peer.sendMessage(message);
175
+ message.id ?? (message.id = uuid());
176
+ return await this.idempotentPeer.sendMessage(message);
153
177
  }
154
178
  async loadAfter(message, count) {
155
179
  if (!message)
156
180
  return;
157
181
  if (!message.pagingCursor)
158
182
  return [];
159
- return this.mapOrUpdateMessages(await this.peer.loadAfter(Number(message.pagingCursor), count));
183
+ return this.mapOrUpdateMessages(await this.idempotentPeer.loadAfter(Number(message.pagingCursor), count));
160
184
  }
161
185
  async get(id) {
162
186
  if (this.messageMap.has(id))
163
187
  return this.messageMap.get(id);
164
188
  await this.ensureConnection(`Could not get message`);
165
- let message = await this.peer.getMessage(id);
189
+ let message = await this.idempotentPeer.getMessage(id);
166
190
  if (this.messageMap.has(id)) {
167
191
  let existingMessage = this.messageMap.get(id);
168
192
  Object.assign(existingMessage, message);
@@ -174,19 +198,19 @@ export class ChatSource extends SocketRPC {
174
198
  return message;
175
199
  }
176
200
  async getCount() {
177
- return await this.peer.getCount();
201
+ return await this.idempotentPeer.getCount();
178
202
  }
179
203
  async likeMessage(messageId) {
180
204
  await this.ensureConnection();
181
- return await this.peer.likeMessage(messageId);
205
+ return await this.idempotentPeer.likeMessage(messageId);
182
206
  }
183
207
  async unlikeMessage(messageId) {
184
208
  await this.ensureConnection();
185
- return await this.peer.unlikeMessage(messageId);
209
+ return await this.idempotentPeer.unlikeMessage(messageId);
186
210
  }
187
211
  async deleteMessage(messageId) {
188
212
  await this.ensureConnection();
189
- return await this.peer.deleteMessage(messageId);
213
+ return await this.idempotentPeer.deleteMessage(messageId);
190
214
  }
191
215
  }
192
216
  __decorate([
@@ -195,4 +219,4 @@ __decorate([
195
219
  __decorate([
196
220
  RpcEvent()
197
221
  ], ChatSource.prototype, "onChatMessage", null);
198
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhdC1zb3VyY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9zZGsvc3JjL2xpYi9jaGF0LXNvdXJjZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQ0EsT0FBTyxFQUFjLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDekQsT0FBTyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFJcEQsTUFBTSxPQUFPLFVBQVcsU0FBUSxTQUFTO0lBQ3JDLFlBQ2EsT0FBb0IsRUFDcEIsVUFBa0IsRUFDbEIsZ0JBQXdCLEVBQ3hCLFNBQXdCO1FBRWpDLEtBQUssRUFBRSxDQUFDO1FBTEMsWUFBTyxHQUFQLE9BQU8sQ0FBYTtRQUNwQixlQUFVLEdBQVYsVUFBVSxDQUFRO1FBQ2xCLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBUTtRQUN4QixjQUFTLEdBQVQsU0FBUyxDQUFlO1FBTTdCLGlCQUFZLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQU1sQyxXQUFNLEdBQXFELFlBQVksQ0FBQztRQVd4RSw0QkFBdUIsR0FBRyxJQUFJLE9BQU8sRUFBb0QsQ0FBQztRQUsxRixnQkFBVyxHQUFHLEtBQUssQ0FBQztRQXFFcEIscUJBQWdCLEdBQUcsQ0FBQyxDQUFDO1FBb0VyQixlQUFVLEdBQUcsSUFBSSxHQUFHLEVBQXVCLENBQUM7UUFDNUMscUJBQWdCLEdBQUcsSUFBSSxPQUFPLEVBQWUsQ0FBQztRQUM5QyxvQkFBZSxHQUFHLElBQUksT0FBTyxFQUFlLENBQUM7UUFDN0MsaUJBQVksR0FBRyxJQUFJLE9BQU8sRUFBZSxDQUFDO1FBQzFDLHFCQUFnQixHQUFHLElBQUksT0FBTyxFQUFlLENBQUM7UUFPdEQsYUFBUSxHQUFrQixFQUFFLENBQUM7UUE3S3pCLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxPQUFPLENBQU8sT0FBTyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMs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O1FBQ1YsT0FBTyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDdEMsQ0FBQztJQUVELEtBQUssQ0FBQyxXQUFXLENBQUMsU0FBaUI7UUFDL0IsTUFBTSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUM5QixPQUFPLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDbEQsQ0FBQztJQUVELEtBQUssQ0FBQyxhQUFhLENBQUMsU0FBaUI7UUFDakMsTUFBTSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUM5QixPQUFPLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDcEQsQ0FBQztJQUVELEtBQUssQ0FBQyxhQUFhLENBQUMsU0FBaUI7UUFDakMsTUFBTSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUM5QixPQUFPLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDcEQsQ0FBQztDQUVKO0FBckZHO0lBREMsUUFBUSxFQUFFOytDQUlWO0FBR0Q7SUFEQyxRQUFRLEVBQUU7K0NBV1YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGF0TWVzc2FnZSwgQ2hhdFBlcm1pc3Npb25zLCBDb21tZW50c09yZGVyLCBEdXJhYmxlU29ja2V0LCBVc2VyIH0gZnJvbSBcIkBiYW50YS9jb21tb25cIjtcclxuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgU3ViamVjdCwgU3Vic2NyaXB0aW9uIH0gZnJvbSBcInJ4anNcIjtcclxuaW1wb3J0IHsgUnBjRXZlbnQsIFNvY2tldFJQQyB9IGZyb20gXCJAYmFudGEvY29tbW9uXCI7XHJcbmltcG9ydCB7IENoYXRTb3VyY2VCYXNlIH0gZnJvbSBcIi4vY2hhdC1zb3VyY2UtYmFzZVwiO1xyXG5pbXBvcnQgeyBDaGF0QmFja2VuZCB9IGZyb20gXCIuL2NoYXQtYmFja2VuZFwiO1xyXG5cclxuZXhwb3J0IGNsYXNzIENoYXRTb3VyY2UgZXh0ZW5kcyBTb2NrZXRSUEMgaW1wbGVtZW50cyBDaGF0U291cmNlQmFzZSB7XHJcbiAgICBjb25zdHJ1Y3RvcihcclxuICAgICAgICByZWFkb25seSBiYWNrZW5kOiBDaGF0QmFja2VuZCxcclxuICAgICAgICByZWFkb25seSBpZGVudGlmaWVyOiBzdHJpbmcsXHJcbiAgICAgICAgcmVhZG9ubHkgcGFyZW50SWRlbnRpZmllcjogc3RyaW5nLFxyXG4gICAgICAgIHJlYWRvbmx5IHNvcnRPcmRlcjogQ29tbWVudHNPcmRlclxyXG4gICAgKSB7XHJcbiAgICAgICAgc3VwZXIoKTtcclxuICAgICAgICB0aGlzLnJlYWR5ID0gbmV3IFByb21pc2U8dm9pZD4ocmVzb2x2ZSA9PiB0aGlzLm1hcmtSZWFkeSA9IHJlc29sdmUpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbigpO1xyXG4gICAgcHJpdmF0ZSBtYXJrUmVhZHk6ICgpID0+IHZvaWQ7XHJcblxyXG4gICAgcmVhZHk6IFByb21pc2U8dm9pZD47XHJcblxyXG4gICAgcGVybWlzc2lvbnM6IENoYXRQZXJtaXNzaW9ucztcclxuICAgIHByaXZhdGUgX3N0YXRlOiAnY29ubmVjdGVkJyB8ICdjb25uZWN0aW5nJyB8ICdsb3N0JyB8ICdyZXN0b3JlZCcgPSAnY29ubmVjdGluZyc7XHJcblxyXG4gICAgZ2V0IHN0YXRlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zdGF0ZTtcclxuICAgIH1cclxuXHJcbiAgICBzZXQgc3RhdGUodmFsdWUpIHtcclxuICAgICAgICB0aGlzLl9zdGF0ZSA9IHZhbHVlO1xyXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5fY29ubmVjdGlvblN0YXRlQ2hhbmdlZC5uZXh0KHRoaXMuX3N0YXRlKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfY29ubmVjdGlvblN0YXRlQ2hhbmdlZCA9IG5ldyBTdWJqZWN0PCdjb25uZWN0ZWQnIHwgJ2Nvbm5lY3RpbmcnIHwgJ2xvc3QnIHwgJ3Jlc3RvcmVkJz4oKTtcclxuICAgIGdldCBjb25uZWN0aW9uU3RhdGVDaGFuZ2VkKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9jb25uZWN0aW9uU3RhdGVDaGFuZ2VkLmFzT2JzZXJ2YWJsZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgd2FzUmVzdG9yZWQgPSBmYWxzZTtcclxuXHJcbiAgICBhc3luYyBiaW5kKHNvY2tldDogRHVyYWJsZVNvY2tldCk6IFByb21pc2U8dGhpcz4ge1xyXG4gICAgICAgIHN1cGVyLmJpbmQoc29ja2V0KTtcclxuXHJcbiAgICAgICAgdGhpcy5zdWJzY3JpcHRpb24uYWRkKHRoaXMuYmFja2VuZC51c2VyQ2hhbmdlZC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5hdXRoZW50aWNhdGUoKSkpO1xyXG5cclxuICAgICAgICBzb2NrZXQuYWRkRXZlbnRMaXN0ZW5lcignb3BlbicsIGFzeW5jICgpID0+IHtcclxuICAgICAgICAgICAgY29uc29sZS5sb2coYFtCYW50YS8ke3RoaXMuaWRlbnRpZmllcn1dIFNvY2tldCBpcyBvcGVuYCk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHNvY2tldC5hZGRFdmVudExpc3RlbmVyKCdsb3N0JywgYXN5bmMgKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gJ2xvc3QnO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBzb2NrZXQuYWRkRXZlbnRMaXN0ZW5lcigncmVzdG9yZScsIGFzeW5jICgpID0+IHtcclxuICAgICAgICAgICAgdGhpcy53YXNSZXN0b3JlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuYXV0aGVudGljYXRlKCk7XHJcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuc3Vic2NyaWJlVG9Ub3BpYygpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBhd2FpdCB0aGlzLnN1YnNjcmliZVRvVG9waWMoKTtcclxuICAgICAgICBcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIG1hcE9yVXBkYXRlTWVzc2FnZXMobWVzc2FnZXM6IENoYXRNZXNzYWdlW10pOiBDaGF0TWVzc2FnZVtdIHtcclxuICAgICAgICByZXR1cm4gbWVzc2FnZXMubWFwKG1lc3NhZ2UgPT4gdGhpcy5tYXBPclVwZGF0ZU1lc3NhZ2UobWVzc2FnZSkpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgbWFwT3JVcGRhdGVNZXNzYWdlKG1lc3NhZ2U6IENoYXRNZXNzYWdlKTogQ2hhdE1lc3NhZ2Uge1xyXG4gICAgICAgIGxldCBleGlzdGluZ01lc3NhZ2UgPSB0aGlzLm1lc3NhZ2VNYXAuZ2V0KG1lc3NhZ2UuaWQpO1xyXG4gICAgICAgIGlmIChleGlzdGluZ01lc3NhZ2UpIHtcclxuICAgICAgICAgICAgbWVzc2FnZSA9IE9iamVjdC5hc3NpZ24oZXhpc3RpbmdNZXNzYWdlLCBtZXNzYWdlKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2VNYXAuc2V0KG1lc3NhZ2UuaWQsIG1lc3NhZ2UpO1xyXG4gICAgICAgICAgICB0aGlzLl9tZXNzYWdlT2JzZXJ2ZWQubmV4dChtZXNzYWdlKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBtZXNzYWdlO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGdldEV4aXN0aW5nTWVzc2FnZXMoKTogUHJvbWlzZTxDaGF0TWVzc2FnZVtdPiB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgbGV0IG1lc3NhZ2VzID0gYXdhaXQgdGhpcy5wZWVyLmdldEV4aXN0aW5nTWVzc2FnZXMoKTtcclxuICAgICAgICAgICAgbWVzc2FnZXMgPSB0aGlzLm1hcE9yVXBkYXRlTWVzc2FnZXMobWVzc2FnZXMpO1xyXG4gICAgICAgICAgICByZXR1cm4gbWVzc2FnZXM7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGBbQmFudGEvJHt0aGlzLmlkZW50aWZpZXJ9XSBFcnJvciBvY2N1cnJlZCB3aGlsZSB0cnlpbmcgdG8gZ2V0IGV4aXN0aW5nIG1lc3NhZ2VzOmApO1xyXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGUpO1xyXG4gICAgICAgICAgICByZXR1cm4gW107XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgYXN5bmMgZW5zdXJlQ29ubmVjdGlvbihlcnJvck1lc3NhZ2U/OiBzdHJpbmcpIHtcclxuICAgICAgICBsZXQgcmVhc29uID0gYENvbm5lY3Rpb24gdG8gY2hhdCBzZXJ2aWNlcyBpcyBub3QgY3VycmVudGx5IGF2YWlsYWJsZS5gO1xyXG4gICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSAnY29ubmVjdGVkJyAmJiB0aGlzLnN0YXRlICE9PSAncmVzdG9yZWQnKSB7XHJcbiAgICAgICAgICAgIGlmIChlcnJvck1lc3NhZ2UpXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7ZXJyb3JNZXNzYWdlfTogJHtyZWFzb259YCk7XHJcbiAgICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtyZWFzb259YCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGVkaXRNZXNzYWdlKG1lc3NhZ2VJZDogc3RyaW5nLCB0ZXh0OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBhd2FpdCB0aGlzLmVuc3VyZUNvbm5lY3Rpb24oKTtcclxuICAgICAgICBhd2FpdCB0aGlzLnBlZXIuZWRpdE1lc3NhZ2UobWVzc2FnZUlkLCB0ZXh0KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHN1YnNjcmliZUF0dGVtcHQgPSAwO1xyXG4gICAgcHJpdmF0ZSBfZXJyb3JTdGF0ZTogc3RyaW5nO1xyXG5cclxuICAgIGdldCBlcnJvclN0YXRlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9lcnJvclN0YXRlO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIHN1YnNjcmliZVRvVG9waWMoKSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5wZWVyLnN1YnNjcmliZSh0aGlzLmlkZW50aWZpZXIsIHRoaXMucGFyZW50SWRlbnRpZmllciwgdGhpcy5zb3J0T3JkZXIpO1xyXG4gICAgICAgICAgICB0aGlzLnN1YnNjcmliZUF0dGVtcHQgPSAwO1xyXG4gICAgICAgICAgICB0aGlzLl9lcnJvclN0YXRlID0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gdGhpcy53YXNSZXN0b3JlZCA/ICdyZXN0b3JlZCcgOiAnY29ubmVjdGVkJztcclxuICAgICAgICAgICAgdGhpcy5tYXJrUmVhZHkoKTtcclxuXHJcbiAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGBbQmFudGEvJHt0aGlzLmlkZW50aWZpZXJ9XSBFcnJvciB3aGlsZSBzdWJzY3JpYmluZyB0byB0b3BpY2ApO1xyXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGUpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9ICdsb3N0JztcclxuICAgICAgICAgICAgdGhpcy5fZXJyb3JTdGF0ZSA9ICdzZXJ2ZXItaXNzdWUnO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5zdWJzY3JpYmVBdHRlbXB0ICs9IDE7XHJcbiAgICAgICAgICAgIGxldCBkZWxheSA9IE1hdGgubWluKDMwKjEwMDAsICgzKjEwMDAgKiB0aGlzLnN1YnNjcmliZUF0dGVtcHQpICogKDEgKyBNYXRoLnJhbmRvbSgpKSk7XHJcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYFtCYW50YS8ke3RoaXMuaWRlbnRpZmllcn1dIFdhaXRpbmcgJHtkZWxheX1tcyBiZWZvcmUgYXR0ZW1wdGluZyB0byByZWNvbm5lY3QuLi5gKTtcclxuXHJcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKGBBdHRlbXB0aW5nIHJlY29ubmVjdGlvbiBhZnRlciBlcnJvciBpbiBzdWJzY3JpYmVUb1RvcGljLi4uYCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnJlY29ubmVjdCgpO1xyXG4gICAgICAgICAgICB9LCBkZWxheSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGF1dGhlbnRpY2F0ZSgpIHtcclxuICAgICAgICBpZiAodGhpcy5iYWNrZW5kLnVzZXIpIHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucGVlci5hdXRoZW50aWNhdGUodGhpcy5iYWNrZW5kLnVzZXI/LnRva2VuKTtcclxuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihgQ291bGQgbm90IGF1dGhlbnRpY2F0ZSB3aXRoIEJhbnRhIHNlcnZlcjpgKTtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgY2xvc2UoKTogdm9pZCB7XHJcbiAgICAgICAgc3VwZXIuY2xvc2UoKTtcclxuICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIEBScGNFdmVudCgpXHJcbiAgICBvblBlcm1pc3Npb25zKHBlcm1pc3Npb25zOiBDaGF0UGVybWlzc2lvbnMpIHtcclxuICAgICAgICAod2luZG93IGFzIGFueSkuYmFudGFQZXJtaXNzaW9uc0RlYnVnID0gcGVybWlzc2lvbnM7XHJcbiAgICAgICAgdGhpcy5wZXJtaXNzaW9ucyA9IHBlcm1pc3Npb25zO1xyXG4gICAgfVxyXG5cclxuICAgIEBScGNFdmVudCgpXHJcbiAgICBvbkNoYXRNZXNzYWdlKG1lc3NhZ2U6IENoYXRNZXNzYWdlKSB7XHJcbiAgICAgICAgaWYgKHRoaXMubWVzc2FnZU1hcC5oYXMobWVzc2FnZS5pZCkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubWFwT3JVcGRhdGVNZXNzYWdlKG1lc3NhZ2UpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoIW1lc3NhZ2UuaGlkZGVuKSB7XHJcbiAgICAgICAgICAgIC8vIE9ubHkgcHJvY2VzcyBub24taGlkZGVuIG1lc3NhZ2VzIHRocm91Z2ggaGVyZS4gXHJcbiAgICAgICAgICAgIC8vIEhpZGRlbiBtZXNzYWdlcyBtYXkgYmUgc2VudCB0byB1cyB3aGVuIHRoZXkgYmVjb21lIGhpZGRlbiAoaWUgbW9kZXJhdGlvbiBpcyBvY2N1cnJpbmcpLlxyXG4gICAgICAgICAgICAvLyBCdXQgaWYgd2UgbmV2ZXIgaGFkIHRoZSBtZXNzYWdlIHRvIGJlZ2luIHdpdGgsIHdlIHNob3VsZCBkaXNjYXJkIGl0LlxyXG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2VNYXAuc2V0KG1lc3NhZ2UuaWQsIG1lc3NhZ2UpO1xyXG4gICAgICAgICAgICB0aGlzLl9tZXNzYWdlUmVjZWl2ZWQubmV4dChtZXNzYWdlKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBtZXNzYWdlTWFwID0gbmV3IE1hcDxzdHJpbmcsIENoYXRNZXNzYWdlPigpO1xyXG4gICAgcHJpdmF0ZSBfbWVzc2FnZVJlY2VpdmVkID0gbmV3IFN1YmplY3Q8Q2hhdE1lc3NhZ2U+KCk7XHJcbiAgICBwcml2YXRlIF9tZXNzYWdlVXBkYXRlZCA9IG5ldyBTdWJqZWN0PENoYXRNZXNzYWdlPigpO1xyXG4gICAgcHJpdmF0ZSBfbWVzc2FnZVNlbnQgPSBuZXcgU3ViamVjdDxDaGF0TWVzc2FnZT4oKTtcclxuICAgIHByaXZhdGUgX21lc3NhZ2VPYnNlcnZlZCA9IG5ldyBTdWJqZWN0PENoYXRNZXNzYWdlPigpO1xyXG5cclxuICAgIGdldCBtZXNzYWdlUmVjZWl2ZWQoKSB7IHJldHVybiB0aGlzLl9tZXNzYWdlUmVjZWl2ZWQuYXNPYnNlcnZhYmxlKCk7IH1cclxuICAgIGdldCBtZXNzYWdlVXBkYXRlZCgpIHsgcmV0dXJuIHRoaXMuX21lc3NhZ2VVcGRhdGVkLmFzT2JzZXJ2YWJsZSgpOyB9XHJcbiAgICBnZXQgbWVzc2FnZVNlbnQoKSB7IHJldHVybiB0aGlzLl9tZXNzYWdlU2VudC5hc09ic2VydmFibGUoKTsgfVxyXG4gICAgZ2V0IG1lc3NhZ2VPYnNlcnZlZCgpIHsgcmV0dXJuIHRoaXMuX21lc3NhZ2VPYnNlcnZlZC5hc09ic2VydmFibGUoKTsgfVxyXG5cclxuICAgIG1lc3NhZ2VzOiBDaGF0TWVzc2FnZVtdID0gW107XHJcblxyXG4gICAgYXN5bmMgc2VuZChtZXNzYWdlOiBDaGF0TWVzc2FnZSk6IFByb21pc2U8Q2hhdE1lc3NhZ2U+IHtcclxuICAgICAgICBhd2FpdCB0aGlzLmVuc3VyZUNvbm5lY3Rpb24oKTtcclxuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5wZWVyLnNlbmRNZXNzYWdlKG1lc3NhZ2UpO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGxvYWRBZnRlcihtZXNzYWdlOiBDaGF0TWVzc2FnZSwgY291bnQ6IG51bWJlcik6IFByb21pc2U8Q2hhdE1lc3NhZ2VbXT4ge1xyXG4gICAgICAgIGlmICghbWVzc2FnZSlcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICBpZiAoIW1lc3NhZ2UucGFnaW5nQ3Vyc29yKVxyXG4gICAgICAgICAgICByZXR1cm4gW107XHJcbiAgICAgICAgXHJcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwT3JVcGRhdGVNZXNzYWdlcyhcclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5wZWVyLmxvYWRBZnRlcihOdW1iZXIobWVzc2FnZS5wYWdpbmdDdXJzb3IpLCBjb3VudClcclxuICAgICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGdldChpZDogc3RyaW5nKTogUHJvbWlzZTxDaGF0TWVzc2FnZT4ge1xyXG4gICAgICAgIGlmICh0aGlzLm1lc3NhZ2VNYXAuaGFzKGlkKSlcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubWVzc2FnZU1hcC5nZXQoaWQpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIGF3YWl0IHRoaXMuZW5zdXJlQ29ubmVjdGlvbihgQ291bGQgbm90IGdldCBtZXNzYWdlYCk7XHJcbiAgICAgICAgbGV0IG1lc3NhZ2UgPSBhd2FpdCB0aGlzLnBlZXIuZ2V0TWVzc2FnZShpZCk7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLm1lc3NhZ2VNYXAuaGFzKGlkKSkge1xyXG4gICAgICAgICAgICBsZXQgZXhpc3RpbmdNZXNzYWdlID0gdGhpcy5tZXNzYWdlTWFwLmdldChpZCk7XHJcbiAgICAgICAgICAgIE9iamVjdC5hc3NpZ24oZXhpc3RpbmdNZXNzYWdlLCBtZXNzYWdlKTtcclxuICAgICAgICAgICAgbWVzc2FnZSA9IGV4aXN0aW5nTWVzc2FnZTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2VNYXAuc2V0KGlkLCBtZXNzYWdlKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBtZXNzYWdlO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGdldENvdW50KCk6IFByb21pc2U8bnVtYmVyPiB7XHJcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucGVlci5nZXRDb3VudCgpO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGxpa2VNZXNzYWdlKG1lc3NhZ2VJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgYXdhaXQgdGhpcy5lbnN1cmVDb25uZWN0aW9uKCk7XHJcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucGVlci5saWtlTWVzc2FnZShtZXNzYWdlSWQpO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIHVubGlrZU1lc3NhZ2UobWVzc2FnZUlkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBhd2FpdCB0aGlzLmVuc3VyZUNvbm5lY3Rpb24oKTtcclxuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5wZWVyLnVubGlrZU1lc3NhZ2UobWVzc2FnZUlkKTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBkZWxldGVNZXNzYWdlKG1lc3NhZ2VJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgYXdhaXQgdGhpcy5lbnN1cmVDb25uZWN0aW9uKCk7XHJcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucGVlci5kZWxldGVNZXNzYWdlKG1lc3NhZ2VJZCk7XHJcbiAgICB9XHJcblxyXG59Il19
222
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhdC1zb3VyY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9zZGsvc3JjL2xpYi9jaGF0LXNvdXJjZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQ0EsT0FBTyxFQUFFLGVBQWUsRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzlELE9BQU8sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBR3BELE9BQU8sRUFBRSxFQUFFLElBQUksSUFBSSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBSWxDLE1BQU0sT0FBTyxVQUFXLFNBQVEsU0FBUztJQUNyQyxZQUNhLE9BQW9CLEVBQ3BCLFVBQWtCLEVBQ2xCLGdCQUF3QixFQUN4QixTQUF3QjtRQUVqQyxLQUFLLEVBQUUsQ0FBQztRQUxDLFlBQU8sR0FBUCxPQUFPLENBQWE7UUFDcEIsZUFBVSxHQUFWLFVBQVUsQ0FBUTtRQUNsQixxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQVE7UUFDeEIsY0FBUyxHQUFULFNBQVMsQ0FBZTtRQU03QixpQkFBWSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFNbEMsV0FBTSxHQUFxRCxZQUFZLENBQUM7UUFXeEUsNEJBQXVCLEdBQUcsSUFBSSxPQUFPLEVBQW9ELENBQUM7UUFDMUYsNkJBQXdCLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLFlBQVksRUFBRSxDQUFDO1FBR3ZFLGdCQUFXLEdBQUcsS0FBSyxDQUFDO1FBeUVwQixxQkFBZ0IsR0FBRyxDQUFDLENBQUM7UUFxQ3JCLGlCQUFZLEdBQWdCLFlBQVksQ0FBQztRQUN6Qyx3QkFBbUIsR0FBRyxJQUFJLGVBQWUsQ0FBYyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDMUUseUJBQW9CLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFlBQVksRUFBRSxDQUFDO1FBa0QvRCxlQUFVLEdBQUcsSUFBSSxHQUFHLEVB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LFNBQVMsQ0FBQyxDQUFDO0lBQzVELENBQUM7SUFFRCxLQUFLLENBQUMsYUFBYSxDQUFDLFNBQWlCO1FBQ2pDLE1BQU0sSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDOUIsT0FBTyxNQUFNLElBQUksQ0FBQyxjQUFjLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzlELENBQUM7SUFFRCxLQUFLLENBQUMsYUFBYSxDQUFDLFNBQWlCO1FBQ2pDLE1BQU0sSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDOUIsT0FBTyxNQUFNLElBQUksQ0FBQyxjQUFjLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzlELENBQUM7Q0FFSjtBQXRGRztJQURDLFFBQVEsRUFBRTsrQ0FJVjtBQUdEO0lBREMsUUFBUSxFQUFFOytDQVdWIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhdE1lc3NhZ2UsIENoYXRQZXJtaXNzaW9ucywgQ29tbWVudHNPcmRlciwgRHVyYWJsZVNvY2tldCwgVXNlciB9IGZyb20gXCJAYmFudGEvY29tbW9uXCI7XHJcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgU3ViamVjdCwgU3Vic2NyaXB0aW9uIH0gZnJvbSBcInJ4anNcIjtcclxuaW1wb3J0IHsgUnBjRXZlbnQsIFNvY2tldFJQQyB9IGZyb20gXCJAYmFudGEvY29tbW9uXCI7XHJcbmltcG9ydCB7IENoYXRTb3VyY2VCYXNlIH0gZnJvbSBcIi4vY2hhdC1zb3VyY2UtYmFzZVwiO1xyXG5pbXBvcnQgeyBDaGF0QmFja2VuZCB9IGZyb20gXCIuL2NoYXQtYmFja2VuZFwiO1xyXG5pbXBvcnQgeyB2NCBhcyB1dWlkIH0gZnJvbSBcInV1aWRcIjtcclxuXHJcbmV4cG9ydCB0eXBlIFNpZ25JblN0YXRlID0gJ3NpZ25lZC1vdXQnIHwgJ3NpZ25lZC1pbicgfCAnc2lnbmluZy1pbic7XHJcblxyXG5leHBvcnQgY2xhc3MgQ2hhdFNvdXJjZSBleHRlbmRzIFNvY2tldFJQQyBpbXBsZW1lbnRzIENoYXRTb3VyY2VCYXNlIHtcclxuICAgIGNvbnN0cnVjdG9yKFxyXG4gICAgICAgIHJlYWRvbmx5IGJhY2tlbmQ6IENoYXRCYWNrZW5kLFxyXG4gICAgICAgIHJlYWRvbmx5IGlkZW50aWZpZXI6IHN0cmluZyxcclxuICAgICAgICByZWFkb25seSBwYXJlbnRJZGVudGlmaWVyOiBzdHJpbmcsXHJcbiAgICAgICAgcmVhZG9ubHkgc29ydE9yZGVyOiBDb21tZW50c09yZGVyXHJcbiAgICApIHtcclxuICAgICAgICBzdXBlcigpO1xyXG4gICAgICAgIHRoaXMucmVhZHkgPSBuZXcgUHJvbWlzZTx2b2lkPihyZXNvbHZlID0+IHRoaXMubWFya1JlYWR5ID0gcmVzb2x2ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBzdWJzY3JpcHRpb24gPSBuZXcgU3Vic2NyaXB0aW9uKCk7XHJcbiAgICBwcml2YXRlIG1hcmtSZWFkeTogKCkgPT4gdm9pZDtcclxuXHJcbiAgICByZWFkeTogUHJvbWlzZTx2b2lkPjtcclxuXHJcbiAgICBwZXJtaXNzaW9uczogQ2hhdFBlcm1pc3Npb25zO1xyXG4gICAgcHJpdmF0ZSBfc3RhdGU6ICdjb25uZWN0ZWQnIHwgJ2Nvbm5lY3RpbmcnIHwgJ2xvc3QnIHwgJ3Jlc3RvcmVkJyA9ICdjb25uZWN0aW5nJztcclxuXHJcbiAgICBnZXQgc3RhdGUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0YXRlO1xyXG4gICAgfVxyXG5cclxuICAgIHNldCBzdGF0ZSh2YWx1ZSkge1xyXG4gICAgICAgIHRoaXMuX3N0YXRlID0gdmFsdWU7XHJcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLl9jb25uZWN0aW9uU3RhdGVDaGFuZ2VkLm5leHQodGhpcy5fc3RhdGUpKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9jb25uZWN0aW9uU3RhdGVDaGFuZ2VkID0gbmV3IFN1YmplY3Q8J2Nvbm5lY3RlZCcgfCAnY29ubmVjdGluZycgfCAnbG9zdCcgfCAncmVzdG9yZWQnPigpO1xyXG4gICAgcHJpdmF0ZSBfY29ubmVjdGlvblN0YXRlQ2hhbmdlZCQgPSB0aGlzLl9jb25uZWN0aW9uU3RhdGVDaGFuZ2VkLmFzT2JzZXJ2YWJsZSgpO1xyXG4gICAgZ2V0IGNvbm5lY3Rpb25TdGF0ZUNoYW5nZWQoKSB7IHJldHVybiB0aGlzLl9jb25uZWN0aW9uU3RhdGVDaGFuZ2VkJDsgfVxyXG5cclxuICAgIHByaXZhdGUgd2FzUmVzdG9yZWQgPSBmYWxzZTtcclxuXHJcbiAgICBhc3luYyBiaW5kKHNvY2tldDogRHVyYWJsZVNvY2tldCk6IFByb21pc2U8dGhpcz4ge1xyXG4gICAgICAgIHN1cGVyLmJpbmQoc29ja2V0KTtcclxuXHJcbiAgICAgICAgdGhpcy5zdWJzY3JpcHRpb24uYWRkKHRoaXMuYmFja2VuZC51c2VyQ2hhbmdlZC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5hdXRoZW50aWNhdGUoKSkpO1xyXG5cclxuICAgICAgICBzb2NrZXQuYWRkRXZlbnRMaXN0ZW5lcignb3BlbicsIGFzeW5jICgpID0+IHtcclxuICAgICAgICAgICAgY29uc29sZS5sb2coYFtCYW50YS8ke3RoaXMuaWRlbnRpZmllcn1dIFNvY2tldCBpcyBvcGVuYCk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHNvY2tldC5hZGRFdmVudExpc3RlbmVyKCdsb3N0JywgYXN5bmMgKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gJ2xvc3QnO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBzb2NrZXQuYWRkRXZlbnRMaXN0ZW5lcigncmVzdG9yZScsIGFzeW5jICgpID0+IHtcclxuICAgICAgICAgICAgdGhpcy53YXNSZXN0b3JlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuYXV0aGVudGljYXRlKCk7XHJcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuc3Vic2NyaWJlVG9Ub3BpYygpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLnN1YnNjcmliZVRvVG9waWMoKTtcclxuICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYFtCYW50YS9DaGF0U291cmNlXSBFcnJvciBkdXJpbmcgaW5pdGlhbCBzdWJzY3JpYmVUb1RvcGljOiAke2UubWVzc2FnZX1gKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBtYXBPclVwZGF0ZU1lc3NhZ2VzKG1lc3NhZ2VzOiBDaGF0TWVzc2FnZVtdKTogQ2hhdE1lc3NhZ2VbXSB7XHJcbiAgICAgICAgcmV0dXJuIG1lc3NhZ2VzLm1hcChtZXNzYWdlID0+IHRoaXMubWFwT3JVcGRhdGVNZXNzYWdlKG1lc3NhZ2UpKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIG1hcE9yVXBkYXRlTWVzc2FnZShtZXNzYWdlOiBDaGF0TWVzc2FnZSk6IENoYXRNZXNzYWdlIHtcclxuICAgICAgICBsZXQgZXhpc3RpbmdNZXNzYWdlID0gdGhpcy5tZXNzYWdlTWFwLmdldChtZXNzYWdlLmlkKTtcclxuICAgICAgICBpZiAoZXhpc3RpbmdNZXNzYWdlKSB7XHJcbiAgICAgICAgICAgIG1lc3NhZ2UgPSBPYmplY3QuYXNzaWduKGV4aXN0aW5nTWVzc2FnZSwgbWVzc2FnZSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5tZXNzYWdlTWFwLnNldChtZXNzYWdlLmlkLCBtZXNzYWdlKTtcclxuICAgICAgICAgICAgdGhpcy5fbWVzc2FnZU9ic2VydmVkLm5leHQobWVzc2FnZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gbWVzc2FnZTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBnZXRFeGlzdGluZ01lc3NhZ2VzKCk6IFByb21pc2U8Q2hhdE1lc3NhZ2VbXT4ge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGxldCBtZXNzYWdlcyA9IGF3YWl0IHRoaXMuaWRlbXBvdGVudFBlZXIuZ2V0RXhpc3RpbmdNZXNzYWdlcygpO1xyXG4gICAgICAgICAgICBtZXNzYWdlcyA9IHRoaXMubWFwT3JVcGRhdGVNZXNzYWdlcyhtZXNzYWdlcyk7XHJcbiAgICAgICAgICAgIHJldHVybiBtZXNzYWdlcztcclxuICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYFtCYW50YS8ke3RoaXMuaWRlbnRpZmllcn1dIEVycm9yIG9jY3VycmVkIHdoaWxlIHRyeWluZyB0byBnZXQgZXhpc3RpbmcgbWVzc2FnZXM6YCk7XHJcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XHJcbiAgICAgICAgICAgIHJldHVybiBbXTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBhc3luYyBlbnN1cmVDb25uZWN0aW9uKGVycm9yTWVzc2FnZT86IHN0cmluZykge1xyXG4gICAgICAgIC8vIGxldCByZWFzb24gPSBgQ29ubmVjdGlvbiB0byBjaGF0IHNlcnZpY2VzIGlzIG5vdCBjdXJyZW50bHkgYXZhaWxhYmxlLmA7XHJcbiAgICAgICAgLy8gaWYgKHRoaXMuc3RhdGUgIT09ICdjb25uZWN0ZWQnICYmIHRoaXMuc3RhdGUgIT09ICdyZXN0b3JlZCcpIHtcclxuICAgICAgICAvLyAgICAgaWYgKGVycm9yTWVzc2FnZSlcclxuICAgICAgICAvLyAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtlcnJvck1lc3NhZ2V9OiAke3JlYXNvbn1gKTtcclxuICAgICAgICAvLyAgICAgZWxzZVxyXG4gICAgICAgIC8vICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3JlYXNvbn1gKTtcclxuICAgICAgICAvLyB9XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgZWRpdE1lc3NhZ2UobWVzc2FnZUlkOiBzdHJpbmcsIHRleHQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGF3YWl0IHRoaXMuZW5zdXJlQ29ubmVjdGlvbigpO1xyXG4gICAgICAgIGF3YWl0IHRoaXMucGVlci5lZGl0TWVzc2FnZShtZXNzYWdlSWQsIHRleHQpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgc3Vic2NyaWJlQXR0ZW1wdCA9IDA7XHJcbiAgICBwcml2YXRlIF9lcnJvclN0YXRlOiBzdHJpbmc7XHJcblxyXG4gICAgZ2V0IGVycm9yU3RhdGUoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Vycm9yU3RhdGU7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgc3Vic2NyaWJlVG9Ub3BpYygpIHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLmltbWVkaWF0ZVBlZXIuc3Vic2NyaWJlKHRoaXMuaWRlbnRpZmllciwgdGhpcy5wYXJlbnRJZGVudGlmaWVyLCB0aGlzLnNvcnRPcmRlcik7XHJcbiAgICAgICAgICAgIHRoaXMuc3Vic2NyaWJlQXR0ZW1wdCA9IDA7XHJcbiAgICAgICAgICAgIHRoaXMuX2Vycm9yU3RhdGUgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgIHRoaXMuc3RhdGUgPSB0aGlzLndhc1Jlc3RvcmVkID8gJ3Jlc3RvcmVkJyA6ICdjb25uZWN0ZWQnO1xyXG4gICAgICAgICAgICB0aGlzLm1hcmtSZWFkeSgpO1xyXG5cclxuICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYFtCYW50YS8ke3RoaXMuaWRlbnRpZmllcn1dIEVycm9yIHdoaWxlIHN1YnNjcmliaW5nIHRvIHRvcGljYCk7XHJcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gJ2xvc3QnO1xyXG4gICAgICAgICAgICB0aGlzLl9lcnJvclN0YXRlID0gJ3NlcnZlci1pc3N1ZSc7XHJcblxyXG4gICAgICAgICAgICB0aGlzLnN1YnNjcmliZUF0dGVtcHQgKz0gMTtcclxuICAgICAgICAgICAgbGV0IGRlbGF5ID0gTWF0aC5taW4oMzAqMTAwMCwgKDMqMTAwMCAqIHRoaXMuc3Vic2NyaWJlQXR0ZW1wdCkgKiAoMSArIE1hdGgucmFuZG9tKCkpKTtcclxuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgW0JhbnRhLyR7dGhpcy5pZGVudGlmaWVyfV0gV2FpdGluZyAke2RlbGF5fW1zIGJlZm9yZSBhdHRlbXB0aW5nIHRvIHJlY29ubmVjdC4uLmApO1xyXG5cclxuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSA9PT0gJ2xvc3QnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5pbmZvKGBBdHRlbXB0aW5nIHJlY29ubmVjdGlvbiBhZnRlciBlcnJvciBpbiBzdWJzY3JpYmVUb1RvcGljLi4uYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZWNvbm5lY3QoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSwgZGVsYXkpO1xyXG5cclxuICAgICAgICAgICAgdGhyb3cgZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfc2lnbkluU3RhdGU6IFNpZ25JblN0YXRlID0gJ3NpZ25lZC1vdXQnO1xyXG4gICAgcHJpdmF0ZSBfc2lnbkluU3RhdGVDaGFuZ2VkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxTaWduSW5TdGF0ZT4odGhpcy5fc2lnbkluU3RhdGUpO1xyXG4gICAgcHJpdmF0ZSBfc2lnbkluU3RhdGVDaGFuZ2VkJCA9IHRoaXMuX3NpZ25JblN0YXRlQ2hhbmdlZC5hc09ic2VydmFibGUoKTtcclxuXHJcbiAgICBnZXQgc2lnbkluU3RhdGUoKSB7IHJldHVybiB0aGlzLl9zaWduSW5TdGF0ZTsgfVxyXG4gICAgZ2V0IHNpZ25JblN0YXRlQ2hhbmdlZCgpIHsgcmV0dXJuIHRoaXMuX3NpZ25JblN0YXRlQ2hhbmdlZCQ7IH1cclxuXHJcbiAgICBwcml2YXRlIHNldFNpZ25JblN0YXRlKHN0YXRlOiBTaWduSW5TdGF0ZSkge1xyXG4gICAgICAgIHRoaXMuX3NpZ25JblN0YXRlID0gc3RhdGU7XHJcbiAgICAgICAgdGhpcy5fc2lnbkluU3RhdGVDaGFuZ2VkLm5leHQoc3RhdGUpO1xyXG4gICAgfVxyXG4gICAgYXN5bmMgYXV0aGVudGljYXRlKCkge1xyXG4gICAgICAgIHRoaXMuc2V0U2lnbkluU3RhdGUoJ3NpZ25pbmctaW4nKTtcclxuICAgICAgICBpZiAodGhpcy5iYWNrZW5kLnVzZXIpIHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGBBcnRpZmljaWFsIGRlbGF5Li4uYCk7XHJcbiAgICAgICAgICAgICAgICAvLyBhd2FpdCBuZXcgUHJvbWlzZShyID0+IHNldFRpbWVvdXQociwgMzBfMDAwKSk7XHJcbiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhgQXJ0aWZpY2lhbCBkZWxheSBjb21wbGV0ZS4uLmApO1xyXG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5pbW1lZGlhdGVQZWVyLmF1dGhlbnRpY2F0ZSh0aGlzLmJhY2tlbmQudXNlcj8udG9rZW4pO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTaWduSW5TdGF0ZSgnc2lnbmVkLWluJyk7XHJcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYFtCYW50YV0gQ291bGQgbm90IGF1dGhlbnRpY2F0ZTpgKTtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNldFNpZ25JblN0YXRlKCdzaWduZWQtb3V0Jyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgY2xvc2UoKTogdm9pZCB7XHJcbiAgICAgICAgc3VwZXIuY2xvc2UoKTtcclxuICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIEBScGNFdmVudCgpXHJcbiAgICBvblBlcm1pc3Npb25zKHBlcm1pc3Npb25zOiBDaGF0UGVybWlzc2lvbnMpIHtcclxuICAgICAgICAod2luZG93IGFzIGFueSkuYmFudGFQZXJtaXNzaW9uc0RlYnVnID0gcGVybWlzc2lvbnM7XHJcbiAgICAgICAgdGhpcy5wZXJtaXNzaW9ucyA9IHBlcm1pc3Npb25zO1xyXG4gICAgfVxyXG5cclxuICAgIEBScGNFdmVudCgpXHJcbiAgICBvbkNoYXRNZXNzYWdlKG1lc3NhZ2U6IENoYXRNZXNzYWdlKSB7XHJcbiAgICAgICAgaWYgKHRoaXMubWVzc2FnZU1hcC5oYXMobWVzc2FnZS5pZCkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubWFwT3JVcGRhdGVNZXNzYWdlKG1lc3NhZ2UpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoIW1lc3NhZ2UuaGlkZGVuKSB7XHJcbiAgICAgICAgICAgIC8vIE9ubHkgcHJvY2VzcyBub24taGlkZGVuIG1lc3NhZ2VzIHRocm91Z2ggaGVyZS4gXHJcbiAgICAgICAgICAgIC8vIEhpZGRlbiBtZXNzYWdlcyBtYXkgYmUgc2VudCB0byB1cyB3aGVuIHRoZXkgYmVjb21lIGhpZGRlbiAoaWUgbW9kZXJhdGlvbiBpcyBvY2N1cnJpbmcpLlxyXG4gICAgICAgICAgICAvLyBCdXQgaWYgd2UgbmV2ZXIgaGFkIHRoZSBtZXNzYWdlIHRvIGJlZ2luIHdpdGgsIHdlIHNob3VsZCBkaXNjYXJkIGl0LlxyXG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2VNYXAuc2V0KG1lc3NhZ2UuaWQsIG1lc3NhZ2UpO1xyXG4gICAgICAgICAgICB0aGlzLl9tZXNzYWdlUmVjZWl2ZWQubmV4dChtZXNzYWdlKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBtZXNzYWdlTWFwID0gbmV3IE1hcDxzdHJpbmcsIENoYXRNZXNzYWdlPigpO1xyXG4gICAgcHJpdmF0ZSBfbWVzc2FnZVJlY2VpdmVkID0gbmV3IFN1YmplY3Q8Q2hhdE1lc3NhZ2U+KCk7XHJcbiAgICBwcml2YXRlIF9tZXNzYWdlVXBkYXRlZCA9IG5ldyBTdWJqZWN0PENoYXRNZXNzYWdlPigpO1xyXG4gICAgcHJpdmF0ZSBfbWVzc2FnZVNlbnQgPSBuZXcgU3ViamVjdDxDaGF0TWVzc2FnZT4oKTtcclxuICAgIHByaXZhdGUgX21lc3NhZ2VPYnNlcnZlZCA9IG5ldyBTdWJqZWN0PENoYXRNZXNzYWdlPigpO1xyXG5cclxuICAgIGdldCBtZXNzYWdlUmVjZWl2ZWQoKSB7IHJldHVybiB0aGlzLl9tZXNzYWdlUmVjZWl2ZWQuYXNPYnNlcnZhYmxlKCk7IH1cclxuICAgIGdldCBtZXNzYWdlVXBkYXRlZCgpIHsgcmV0dXJuIHRoaXMuX21lc3NhZ2VVcGRhdGVkLmFzT2JzZXJ2YWJsZSgpOyB9XHJcbiAgICBnZXQgbWVzc2FnZVNlbnQoKSB7IHJldHVybiB0aGlzLl9tZXNzYWdlU2VudC5hc09ic2VydmFibGUoKTsgfVxyXG4gICAgZ2V0IG1lc3NhZ2VPYnNlcnZlZCgpIHsgcmV0dXJuIHRoaXMuX21lc3NhZ2VPYnNlcnZlZC5hc09ic2VydmFibGUoKTsgfVxyXG5cclxuICAgIG1lc3NhZ2VzOiBDaGF0TWVzc2FnZVtdID0gW107XHJcblxyXG4gICAgYXN5bmMgc2VuZChtZXNzYWdlOiBDaGF0TWVzc2FnZSk6IFByb21pc2U8Q2hhdE1lc3NhZ2U+IHtcclxuICAgICAgICBhd2FpdCB0aGlzLmVuc3VyZUNvbm5lY3Rpb24oKTtcclxuICAgICAgICBtZXNzYWdlLmlkID8/PSB1dWlkKCk7XHJcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuaWRlbXBvdGVudFBlZXIuc2VuZE1lc3NhZ2UobWVzc2FnZSk7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgbG9hZEFmdGVyKG1lc3NhZ2U6IENoYXRNZXNzYWdlLCBjb3VudDogbnVtYmVyKTogUHJvbWlzZTxDaGF0TWVzc2FnZVtdPiB7XHJcbiAgICAgICAgaWYgKCFtZXNzYWdlKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIGlmICghbWVzc2FnZS5wYWdpbmdDdXJzb3IpXHJcbiAgICAgICAgICAgIHJldHVybiBbXTtcclxuICAgICAgICBcclxuICAgICAgICByZXR1cm4gdGhpcy5tYXBPclVwZGF0ZU1lc3NhZ2VzKFxyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLmlkZW1wb3RlbnRQZWVyLmxvYWRBZnRlcihOdW1iZXIobWVzc2FnZS5wYWdpbmdDdXJzb3IpLCBjb3VudClcclxuICAgICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGdldChpZDogc3RyaW5nKTogUHJvbWlzZTxDaGF0TWVzc2FnZT4ge1xyXG4gICAgICAgIGlmICh0aGlzLm1lc3NhZ2VNYXAuaGFzKGlkKSlcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubWVzc2FnZU1hcC5nZXQoaWQpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIGF3YWl0IHRoaXMuZW5zdXJlQ29ubmVjdGlvbihgQ291bGQgbm90IGdldCBtZXNzYWdlYCk7XHJcbiAgICAgICAgbGV0IG1lc3NhZ2UgPSBhd2FpdCB0aGlzLmlkZW1wb3RlbnRQZWVyLmdldE1lc3NhZ2UoaWQpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5tZXNzYWdlTWFwLmhhcyhpZCkpIHtcclxuICAgICAgICAgICAgbGV0IGV4aXN0aW5nTWVzc2FnZSA9IHRoaXMubWVzc2FnZU1hcC5nZXQoaWQpO1xyXG4gICAgICAgICAgICBPYmplY3QuYXNzaWduKGV4aXN0aW5nTWVzc2FnZSwgbWVzc2FnZSk7XHJcbiAgICAgICAgICAgIG1lc3NhZ2UgPSBleGlzdGluZ01lc3NhZ2U7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5tZXNzYWdlTWFwLnNldChpZCwgbWVzc2FnZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gbWVzc2FnZTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBnZXRDb3VudCgpOiBQcm9taXNlPG51bWJlcj4ge1xyXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmlkZW1wb3RlbnRQZWVyLmdldENvdW50KCk7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgbGlrZU1lc3NhZ2UobWVzc2FnZUlkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBhd2FpdCB0aGlzLmVuc3VyZUNvbm5lY3Rpb24oKTtcclxuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5pZGVtcG90ZW50UGVlci5saWtlTWVzc2FnZShtZXNzYWdlSWQpO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIHVubGlrZU1lc3NhZ2UobWVzc2FnZUlkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBhd2FpdCB0aGlzLmVuc3VyZUNvbm5lY3Rpb24oKTtcclxuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5pZGVtcG90ZW50UGVlci51bmxpa2VNZXNzYWdlKG1lc3NhZ2VJZCk7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgZGVsZXRlTWVzc2FnZShtZXNzYWdlSWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGF3YWl0IHRoaXMuZW5zdXJlQ29ubmVjdGlvbigpO1xyXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmlkZW1wb3RlbnRQZWVyLmRlbGV0ZU1lc3NhZ2UobWVzc2FnZUlkKTtcclxuICAgIH1cclxuXHJcbn0iXX0=