UNPKG

ngx-teximate

Version:
255 lines 19.8 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ import { Component, Input, Output, NgZone, ElementRef, EventEmitter, ChangeDetectionStrategy } from '@angular/core'; import { style, query, stagger, useAnimation, AnimationBuilder } from '@angular/animations'; import { BehaviorSubject } from 'rxjs'; import { map } from 'rxjs/operators'; export class Teximate { /** * @param {?} animationBuilder * @param {?} zone * @param {?} el */ constructor(animationBuilder, zone, el) { this.animationBuilder = animationBuilder; this.zone = zone; this.el = el; /** * Stream that emits when animation is started */ this.playEmitter = new EventEmitter(); /** * Stream that emits when animation is done */ this.finishEmitter = new EventEmitter(); /** * Teximate animations */ this.players = new Map(); /** * Teximate state */ this._state = new BehaviorSubject(''); this.state = this._state.pipe(map((text) => teximateFactory(text))); } /** * Set animated text * @param {?} text * @return {?} */ set setText(text) { this._state.next(text); } /** * @return {?} */ get isPlaying() { return this._isPlaying; } /** * @return {?} */ get enterPlayer() { return this.players.get('enter'); } /** * @return {?} */ get leavePlayer() { return this.players.get('leave'); } /** * @return {?} */ get defaultPlayer() { return this.players.get('default'); } /** * @return {?} */ ngAfterViewInit() { this._isViewInit = true; this.updateAnimations(true); } /** * @return {?} */ ngOnChanges() { if (this._isViewInit) { this.updateAnimations(); } } /** * @return {?} */ ngOnDestroy() { // TODO: Use players.forEach to destroy players if (this.players.has('enter')) { this.players.get('enter').destroy(); } if (this.players.has('leave')) { this.players.get('leave').destroy(); } if (this.players.has('default')) { this.players.get('default').destroy(); } } /** * Register a new animation * @param {?} config * @return {?} */ registerAnimation(config) { /** @type {?} */ const player = this.buildAnimation(config).create(this.el.nativeElement); /** TODO: Investigate why onStart and onDone fire only once */ player.onStart(() => { this._isPlaying = true; this.playEmitter.emit(config.id); }); player.onDone(() => { this._isPlaying = false; this.finishEmitter.emit(config.id); }); return this.players.set(config.id, player).get(config.id); } /** * @param {?=} autoPlayEnter * @return {?} */ updateAnimations(autoPlayEnter) { this.zone.runOutsideAngular(() => { if (this.enter) { /** @type {?} */ const enterPlayer = this.registerAnimation(Object.assign({}, this.enter, { id: 'enter', isEnter: true })); if (autoPlayEnter) { enterPlayer.play(); } } if (this.leave) { this.registerAnimation(Object.assign({}, this.leave, { id: 'leave' })); } if (this.animation) { this.registerAnimation(Object.assign({ id: 'default' }, this.animation)); } }); } /** * Build animation * @param {?} config * @return {?} */ buildAnimation(config) { /** TODO: Use ':enter' and ':leave' for enter and leave animations */ return this.animationBuilder.build([ query(`.teximate-${config.type}`, [ // This is a workaround for enter animation to work style({ opacity: config.isEnter ? 0 : 1 }), stagger(config.delay, [useAnimation(config.animation)]) ]) ]); } } Teximate.decorators = [ { type: Component, args: [{ selector: 'teximate', host: { 'aria-label': 'text' }, template: "<p *ngFor=\"let paragraph of state | async; index as i\"\r\n class=\"teximate-paragraph teximate-paragraph-{{i}}\">\r\n\r\n <span *ngFor=\"let word of paragraph; index as j\"\r\n class=\"teximate-word teximate-word-{{j}}\">\r\n\r\n <span *ngFor=\"let letter of word; index as k\"\r\n class=\"teximate-letter teximate-letter-{{k}}\">\r\n {{letter}}\r\n </span>\r\n </span>\r\n</p>\r\n", changeDetection: ChangeDetectionStrategy.OnPush, styles: [".teximate-letter,.teximate-word{display:inline-block}.teximate-word{margin-right:8px}"] }] } ]; /** @nocollapse */ Teximate.ctorParameters = () => [ { type: AnimationBuilder }, { type: NgZone }, { type: ElementRef } ]; Teximate.propDecorators = { setText: [{ type: Input, args: ['text',] }], enter: [{ type: Input }], leave: [{ type: Input }], animation: [{ type: Input }], playEmitter: [{ type: Output, args: ['play',] }], finishEmitter: [{ type: Output, args: ['finish',] }] }; if (false) { /** * Animation that triggers on init * @type {?} */ Teximate.prototype.enter; /** * Animation that triggers on destroy * @type {?} */ Teximate.prototype.leave; /** * Animation that triggers with the play() function * @type {?} */ Teximate.prototype.animation; /** * Stream that emits when animation is started * @type {?} */ Teximate.prototype.playEmitter; /** * Stream that emits when animation is done * @type {?} */ Teximate.prototype.finishEmitter; /** * Teximate animations * @type {?} */ Teximate.prototype.players; /** * Teximate state * @type {?} */ Teximate.prototype._state; /** @type {?} */ Teximate.prototype.state; /** * Teximate playing state * @type {?} */ Teximate.prototype._isPlaying; /** @type {?} */ Teximate.prototype._isViewInit; /** @type {?} */ Teximate.prototype.animationBuilder; /** @type {?} */ Teximate.prototype.zone; /** @type {?} */ Teximate.prototype.el; } /** * Convert text string into a workable text * @param {?} text * @return {?} */ export function teximateFactory(text) { /** @type {?} */ const paragraphs = []; // Split text into paragraphs text.split('\n').map((paragraph) => { /** @type {?} */ const words = []; // Split paragraph into words paragraph .split(' ') .filter(word => word !== '') .map((word) => // Split word into letters words.push(word.split(/(?!$)/u))); paragraphs.push(words); }); return paragraphs; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGV4aW1hdGUuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtdGV4aW1hdGUvIiwic291cmNlcyI6WyJsaWIvdGV4aW1hdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsS0FBSyxFQUNMLE1BQU0sRUFJTixNQUFNLEVBQ04sVUFBVSxFQUNWLFlBQVksRUFDWix1QkFBdUIsRUFDeEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUNMLEtBQUssRUFDTCxLQUFLLEVBQ0wsT0FBTyxFQUNQLFlBQVksRUFFWixnQkFBZ0IsRUFFakIsTUFBTSxxQkFBcUIsQ0FBQztBQUM3QixPQUFPLEVBQUUsZUFBZSxFQUFjLE1BQU0sTUFBTSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQVlyQyxNQUFNLE9BQU8sUUFBUTs7Ozs7O0lBaURuQixZQUFvQixnQkFBa0MsRUFBVSxJQUFZLEVBQVUsRUFBYztRQUFoRixxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO1FBQVUsU0FBSSxHQUFKLElBQUksQ0FBUTtRQUFVLE9BQUUsR0FBRixFQUFFLENBQVk7Ozs7UUFoQ3BGLGdCQUFXLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQzs7OztRQUcvQixrQkFBYSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7Ozs7UUFHckQsWUFBTyxHQUFHLElBQUksR0FBRyxFQUEyQixDQUFDOzs7O1FBR3JDLFdBQU0sR0FBRyxJQUFJLGVBQWUsQ0FBUyxFQUFFLENBQUMsQ0FBQztRQXdCL0MsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFZLEVBQUUsRUFBRSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDOUUsQ0FBQzs7Ozs7O0lBaERELElBQW1CLE9BQU8sQ0FBQyxJQUFZO1FBQ3JDLElBQUksQ0FB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QThCOzs7OztJQUc5Qix5QkFBOEI7Ozs7O0lBRzlCLDZCQUFrQzs7Ozs7SUFHbEMsK0JBQWlEOzs7OztJQUdqRCxpQ0FBcUQ7Ozs7O0lBR3JELDJCQUE2Qzs7Ozs7SUFHN0MsMEJBQWlEOztJQUNqRCx5QkFBZ0M7Ozs7O0lBR2hDLDhCQUE0Qjs7SUFDNUIsK0JBQTZCOztJQWtCakIsb0NBQTBDOztJQUFFLHdCQUFvQjs7SUFBRSxzQkFBc0I7Ozs7Ozs7QUFpRnRHLE1BQU0sVUFBVSxlQUFlLENBQUMsSUFBWTs7VUFDcEMsVUFBVSxHQUFpQixFQUFFO0lBQ25DLDZCQUE2QjtJQUM3QixJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFNBQWlCLEVBQUUsRUFBRTs7Y0FDbkMsS0FBSyxHQUFlLEVBQUU7UUFDNUIsNkJBQTZCO1FBQzdCLFNBQVM7YUFDTixLQUFLLENBQUMsR0FBRyxDQUFDO2FBQ1YsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxLQUFLLEVBQUUsQ0FBQzthQUMzQixHQUFHLENBQUMsQ0FBQyxJQUFZLEVBQUUsRUFBRTtRQUNwQiwwQkFBMEI7UUFDMUIsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQ2pDLENBQUM7UUFDSixVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3pCLENBQUMsQ0FBQyxDQUFDO0lBQ0gsT0FBTyxVQUFVLENBQUM7QUFDcEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgSW5wdXQsXG4gIE91dHB1dCxcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE5nWm9uZSxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneVxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIHN0eWxlLFxuICBxdWVyeSxcbiAgc3RhZ2dlcixcbiAgdXNlQW5pbWF0aW9uLFxuICBBbmltYXRpb25QbGF5ZXIsXG4gIEFuaW1hdGlvbkJ1aWxkZXIsXG4gIEFuaW1hdGlvbkZhY3Rvcnlcbn0gZnJvbSAnQGFuZ3VsYXIvYW5pbWF0aW9ucyc7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IFRleHRBbmltYXRpb24gfSBmcm9tICcuL3RleGltYXRlLm1vZGVsJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndGV4aW1hdGUnLFxuICBob3N0OiB7XG4gICAgJ2FyaWEtbGFiZWwnOiAndGV4dCdcbiAgfSxcbiAgdGVtcGxhdGVVcmw6ICcuL3RleGltYXRlLmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi90ZXhpbWF0ZS5zY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuZXhwb3J0IGNsYXNzIFRleGltYXRlIGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3kge1xuXG4gIC8qKiBTZXQgYW5pbWF0ZWQgdGV4dCAqL1xuICBASW5wdXQoJ3RleHQnKSBzZXQgc2V0VGV4dCh0ZXh0OiBzdHJpbmcpIHtcbiAgICB0aGlzLl9zdGF0ZS5uZXh0KHRleHQpO1xuICB9XG5cbiAgLyoqIEFuaW1hdGlvbiB0aGF0IHRyaWdnZXJzIG9uIGluaXQgKi9cbiAgQElucHV0KCkgZW50ZXI6IFRleHRBbmltYXRpb247XG5cbiAgLyoqIEFuaW1hdGlvbiB0aGF0IHRyaWdnZXJzIG9uIGRlc3Ryb3kgKi9cbiAgQElucHV0KCkgbGVhdmU6IFRleHRBbmltYXRpb247XG5cbiAgLyoqIEFuaW1hdGlvbiB0aGF0IHRyaWdnZXJzIHdpdGggdGhlIHBsYXkoKSBmdW5jdGlvbiAqL1xuICBASW5wdXQoKSBhbmltYXRpb246IFRleHRBbmltYXRpb247XG5cbiAgLyoqIFN0cmVhbSB0aGF0IGVtaXRzIHdoZW4gYW5pbWF0aW9uIGlzIHN0YXJ0ZWQgKi9cbiAgQE91dHB1dCgncGxheScpIHBsYXlFbWl0dGVyID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIC8qKiBTdHJlYW0gdGhhdCBlbWl0cyB3aGVuIGFuaW1hdGlvbiBpcyBkb25lICovXG4gIEBPdXRwdXQoJ2ZpbmlzaCcpIGZpbmlzaEVtaXR0ZXIgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgLyoqIFRleGltYXRlIGFuaW1hdGlvbnMgKi9cbiAgcGxheWVycyA9IG5ldyBNYXA8c3RyaW5nLCBBbmltYXRpb25QbGF5ZXI+KCk7XG5cbiAgLyoqIFRleGltYXRlIHN0YXRlICovXG4gIHByaXZhdGUgX3N0YXRlID0gbmV3IEJlaGF2aW9yU3ViamVjdDxzdHJpbmc+KCcnKTtcbiAgc3RhdGU6IE9ic2VydmFibGU8c3RyaW5nW11bXVtdPjtcblxuICAvKiogVGV4aW1hdGUgcGxheWluZyBzdGF0ZSAqL1xuICBwcml2YXRlIF9pc1BsYXlpbmc6IGJvb2xlYW47XG4gIHByaXZhdGUgX2lzVmlld0luaXQ6IGJvb2xlYW47XG5cbiAgZ2V0IGlzUGxheWluZygpIHtcbiAgICByZXR1cm4gdGhpcy5faXNQbGF5aW5nO1xuICB9XG5cbiAgZ2V0IGVudGVyUGxheWVyKCk6IEFuaW1hdGlvblBsYXllciB7XG4gICAgcmV0dXJuIHRoaXMucGxheWVycy5nZXQoJ2VudGVyJyk7XG4gIH1cblxuICBnZXQgbGVhdmVQbGF5ZXIoKTogQW5pbWF0aW9uUGxheWVyIHtcbiAgICByZXR1cm4gdGhpcy5wbGF5ZXJzLmdldCgnbGVhdmUnKTtcbiAgfVxuXG4gIGdldCBkZWZhdWx0UGxheWVyKCk6IEFuaW1hdGlvblBsYXllciB7XG4gICAgcmV0dXJuIHRoaXMucGxheWVycy5nZXQoJ2RlZmF1bHQnKTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgYW5pbWF0aW9uQnVpbGRlcjogQW5pbWF0aW9uQnVpbGRlciwgcHJpdmF0ZSB6b25lOiBOZ1pvbmUsIHByaXZhdGUgZWw6IEVsZW1lbnRSZWYpIHtcbiAgICB0aGlzLnN0YXRlID0gdGhpcy5fc3RhdGUucGlwZShtYXAoKHRleHQ6IHN0cmluZykgPT4gdGV4aW1hdGVGYWN0b3J5KHRleHQpKSk7XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgdGhpcy5faXNWaWV3SW5pdCA9IHRydWU7XG4gICAgdGhpcy51cGRhdGVBbmltYXRpb25zKHRydWUpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoKSB7XG4gICAgaWYgKHRoaXMuX2lzVmlld0luaXQpIHtcbiAgICAgIHRoaXMudXBkYXRlQW5pbWF0aW9ucygpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIC8vIFRPRE86IFVzZSBwbGF5ZXJzLmZvckVhY2ggdG8gZGVzdHJveSBwbGF5ZXJzXG4gICAgaWYgKHRoaXMucGxheWVycy5oYXMoJ2VudGVyJykpIHtcbiAgICAgIHRoaXMucGxheWVycy5nZXQoJ2VudGVyJykuZGVzdHJveSgpO1xuICAgIH1cbiAgICBpZiAodGhpcy5wbGF5ZXJzLmhhcygnbGVhdmUnKSkge1xuICAgICAgdGhpcy5wbGF5ZXJzLmdldCgnbGVhdmUnKS5kZXN0cm95KCk7XG4gICAgfVxuICAgIGlmICh0aGlzLnBsYXllcnMuaGFzKCdkZWZhdWx0JykpIHtcbiAgICAgIHRoaXMucGxheWVycy5nZXQoJ2RlZmF1bHQnKS5kZXN0cm95KCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVyIGEgbmV3IGFuaW1hdGlvblxuICAgKi9cbiAgcmVnaXN0ZXJBbmltYXRpb24oY29uZmlnOiBUZXh0QW5pbWF0aW9uKTogQW5pbWF0aW9uUGxheWVyIHtcbiAgICBjb25zdCBwbGF5ZXIgPSB0aGlzLmJ1aWxkQW5pbWF0aW9uKGNvbmZpZykuY3JlYXRlKHRoaXMuZWwubmF0aXZlRWxlbWVudCk7XG4gICAgLyoqIFRPRE86IEludmVzdGlnYXRlIHdoeSBvblN0YXJ0IGFuZCBvbkRvbmUgZmlyZSBvbmx5IG9uY2UgKi9cbiAgICBwbGF5ZXIub25TdGFydCgoKSA9PiB7XG4gICAgICB0aGlzLl9pc1BsYXlpbmcgPSB0cnVlO1xuICAgICAgdGhpcy5wbGF5RW1pdHRlci5lbWl0KGNvbmZpZy5pZCk7XG4gICAgfSk7XG4gICAgcGxheWVyLm9uRG9uZSgoKSA9PiB7XG4gICAgICB0aGlzLl9pc1BsYXlpbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMuZmluaXNoRW1pdHRlci5lbWl0KGNvbmZpZy5pZCk7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMucGxheWVycy5zZXQoY29uZmlnLmlkLCBwbGF5ZXIpLmdldChjb25maWcuaWQpO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVBbmltYXRpb25zKGF1dG9QbGF5RW50ZXI/OiBib29sZWFuKSB7XG4gICAgdGhpcy56b25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgIGlmICh0aGlzLmVudGVyKSB7XG4gICAgICAgIGNvbnN0IGVudGVyUGxheWVyID0gdGhpcy5yZWdpc3RlckFuaW1hdGlvbih7Li4udGhpcy5lbnRlciwgaWQ6ICdlbnRlcicsIGlzRW50ZXI6IHRydWV9KTtcbiAgICAgICAgaWYgKGF1dG9QbGF5RW50ZXIpIHtcbiAgICAgICAgICBlbnRlclBsYXllci5wbGF5KCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLmxlYXZlKSB7XG4gICAgICAgIHRoaXMucmVnaXN0ZXJBbmltYXRpb24oey4uLnRoaXMubGVhdmUsIGlkOiAnbGVhdmUnfSk7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5hbmltYXRpb24pIHtcbiAgICAgICAgdGhpcy5yZWdpc3RlckFuaW1hdGlvbih7aWQ6ICdkZWZhdWx0JywgLi4udGhpcy5hbmltYXRpb259KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZCBhbmltYXRpb25cbiAgICovXG4gIHByaXZhdGUgYnVpbGRBbmltYXRpb24oY29uZmlnOiBUZXh0QW5pbWF0aW9uKTogQW5pbWF0aW9uRmFjdG9yeSB7XG4gICAgLyoqIFRPRE86IFVzZSAnOmVudGVyJyBhbmQgJzpsZWF2ZScgZm9yIGVudGVyIGFuZCBsZWF2ZSBhbmltYXRpb25zICovXG4gICAgcmV0dXJuIHRoaXMuYW5pbWF0aW9uQnVpbGRlci5idWlsZChbXG4gICAgICBxdWVyeShcbiAgICAgICAgYC50ZXhpbWF0ZS0ke2NvbmZpZy50eXBlfWAsXG4gICAgICAgIFtcbiAgICAgICAgICAvLyBUaGlzIGlzIGEgd29ya2Fyb3VuZCBmb3IgZW50ZXIgYW5pbWF0aW9uIHRvIHdvcmtcbiAgICAgICAgICBzdHlsZSh7b3BhY2l0eTogY29uZmlnLmlzRW50ZXIgPyAwIDogMX0pLFxuICAgICAgICAgIHN0YWdnZXIoY29uZmlnLmRlbGF5LCBbdXNlQW5pbWF0aW9uKGNvbmZpZy5hbmltYXRpb24pXSlcbiAgICAgICAgXVxuICAgICAgKVxuICAgIF0pO1xuICB9XG59XG5cbi8qKiBDb252ZXJ0IHRleHQgc3RyaW5nIGludG8gYSB3b3JrYWJsZSB0ZXh0ICovXG5leHBvcnQgZnVuY3Rpb24gdGV4aW1hdGVGYWN0b3J5KHRleHQ6IHN0cmluZyk6IHN0cmluZ1tdW11bXSB7XG4gIGNvbnN0IHBhcmFncmFwaHM6IHN0cmluZ1tdW11bXSA9IFtdO1xuICAvLyBTcGxpdCB0ZXh0IGludG8gcGFyYWdyYXBoc1xuICB0ZXh0LnNwbGl0KCdcXG4nKS5tYXAoKHBhcmFncmFwaDogc3RyaW5nKSA9PiB7XG4gICAgY29uc3Qgd29yZHM6IHN0cmluZ1tdW10gPSBbXTtcbiAgICAvLyBTcGxpdCBwYXJhZ3JhcGggaW50byB3b3Jkc1xuICAgIHBhcmFncmFwaFxuICAgICAgLnNwbGl0KCcgJylcbiAgICAgIC5maWx0ZXIod29yZCA9PiB3b3JkICE9PSAnJylcbiAgICAgIC5tYXAoKHdvcmQ6IHN0cmluZykgPT5cbiAgICAgICAgLy8gU3BsaXQgd29yZCBpbnRvIGxldHRlcnNcbiAgICAgICAgd29yZHMucHVzaCh3b3JkLnNwbGl0KC8oPyEkKS91KSlcbiAgICAgICk7XG4gICAgcGFyYWdyYXBocy5wdXNoKHdvcmRzKTtcbiAgfSk7XG4gIHJldHVybiBwYXJhZ3JhcGhzO1xufVxuIl19