@hxui/angular
Version:
An Angular library based on the [HXUI design system](https://hxui.io).
258 lines (252 loc) • 28.1 kB
JavaScript
import { ChangeDetectorRef, Component, ElementRef, HostListener, ViewEncapsulation } from '@angular/core';
import { Subject } from 'rxjs';
import { latinize } from './typeahead-utils';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
export class TypeaheadContainerComponent {
constructor(element, _changeDetectionRef) {
this.element = element;
this._changeDetectionRef = _changeDetectionRef;
this.isFocused = false;
this._matches = [];
/** Subject for notifying that the tooltip has been hidden from the view */
this._onHide = new Subject();
}
get active() {
return this._active;
}
get matches() {
return this._matches;
}
set matches(value) {
this._matches = value;
if (this._matches.length > 0) {
this._active = this._matches[0];
if (this._active.isHeader()) {
this.nextActiveMatch();
}
}
}
get optionsListTemplate() {
return this.parent ? this.parent.optionsListTemplate : undefined;
}
get itemTemplate() {
return this.parent ? this.parent.typeaheadItemTemplate : undefined;
}
selectActiveMatch() {
this.selectMatch(this._active);
}
prevActiveMatch() {
let index = this.matches.indexOf(this._active);
this._active =
this.matches[index - 1 < 0 ? this.matches.length - 1 : index - 1];
if (this._active.isHeader()) {
this.prevActiveMatch();
}
}
nextActiveMatch() {
let index = this.matches.indexOf(this._active);
this._active =
this.matches[index + 1 > this.matches.length - 1 ? 0 : index + 1];
if (this._active.isHeader()) {
this.nextActiveMatch();
}
}
selectActive(value) {
this.isFocused = true;
this._active = value;
}
hightlight(match, query) {
let itemStr = match.value;
let itemStrHelper = (this.parent && this.parent.typeaheadLatinize ? latinize(itemStr) : itemStr).toLowerCase();
let startIdx;
let tokenLen;
// Replaces the capture string with the same string inside of a "strong" tag
if (typeof query === 'object') {
let queryLen = query.length;
for (let i = 0; i < queryLen; i += 1) {
// query[i] is already latinized and lower case
startIdx = itemStrHelper.indexOf(query[i]);
tokenLen = query[i].length;
if (startIdx >= 0 && tokenLen > 0) {
itemStr =
itemStr.substring(0, startIdx) +
'<strong class="is-matched">' +
itemStr.substring(startIdx, startIdx + tokenLen) +
'</strong>' +
itemStr.substring(startIdx + tokenLen);
itemStrHelper =
itemStrHelper.substring(0, startIdx) +
' ' +
' '.repeat(tokenLen) +
' ' +
itemStrHelper.substring(startIdx + tokenLen);
}
}
}
else if (query) {
// query is already latinized and lower case
startIdx = itemStrHelper.indexOf(query);
tokenLen = query.length;
if (startIdx >= 0 && tokenLen > 0) {
itemStr =
itemStr.substring(0, startIdx) +
'<strong class="is-matched">' +
itemStr.substring(startIdx, startIdx + tokenLen) +
'</strong>' +
itemStr.substring(startIdx + tokenLen);
}
}
return itemStr;
}
focusLost() {
this.isFocused = false;
}
isActive(value) {
return this._active === value;
}
selectMatch(value, e = void 0) {
if (e) {
e.stopPropagation();
e.preventDefault();
}
this.parent.changeModel(value);
setTimeout(() => this.parent.typeaheadOnSelect.emit(value), 0);
return false;
}
show(delay) {
// Cancel the delayed hide if it is scheduled
if (this._hideTimeoutId) {
clearTimeout(this._hideTimeoutId);
}
this._showTimeoutId = window.setTimeout(() => {
// Schedule for change detection incase the tooltip is used within a
// component with OnPush change detection
this._changeDetectionRef.markForCheck();
//this.visibility = Visibility.Visible;
}, delay);
}
/**
* Hide the tooltip after the provided delay in ms.
* @param delay Amount of milliseconds to delay hiding the tooltip.
*/
hide(delay) {
// Cancel the delayed show if it is scheduled
if (this._showTimeoutId) {
clearTimeout(this._showTimeoutId);
}
this._hideTimeoutId = window.setTimeout(() => {
// this.visibility = Visibility.Hidden;
this._onHide.next(true);
}, delay);
}
/** Returns an observable that notifies when the dropdown has been hidden from view. */
afterHidden() {
return this._onHide.asObservable();
}
}
TypeaheadContainerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: TypeaheadContainerComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
TypeaheadContainerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: TypeaheadContainerComponent, selector: "hx-typeahead-container", host: { listeners: { "mouseleave": "focusLost()", "blur": "focusLost()" }, classAttribute: "hx-dropdown-menu" }, ngImport: i0, template: `
<!-- inject options list template -->
<ng-template
[ngTemplateOutlet]="optionsListTemplate || optionListTemplate"
[ngTemplateOutletContext]="{
matches: matches,
itemTemplate: itemTemplate,
query: query
}"
></ng-template>
<!-- default options item template -->
<ng-template #hxItemTemplate let-match="match" let-query="query"
><span [innerHtml]="hightlight(match, query)"></span
></ng-template>
<!-- options list template -->
<ng-template #optionListTemplate>
<ng-template ngFor let-match let-i="index" [ngForOf]="matches">
<h6 *ngIf="match.isHeader()" class="hx-dropdown-header">{{ match }}</h6>
<ng-template [ngIf]="!match.isHeader()">
<a
href="#"
class="hx-dropdown-item"
(click)="selectMatch(match, $event)"
(mouseenter)="selectActive(match)"
[class.active]="isActive(match)"
>
<ng-template
[ngTemplateOutlet]="itemTemplate || hxItemTemplate"
[ngTemplateOutletContext]="{
item: match.item,
index: i,
match: match,
query: query
}"
></ng-template>
</a>
</ng-template>
</ng-template>
</ng-template>
`, isInline: true, styles: ["strong.is-matched{background-color:#23312b3b}\n", ".hx-dropdown-item{font-weight:300}\n"], directives: [{ type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], encapsulation: i0.ViewEncapsulation.None });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: TypeaheadContainerComponent, decorators: [{
type: Component,
args: [{
selector: 'hx-typeahead-container',
// eslint-disable-next-line
template: `
<!-- inject options list template -->
<ng-template
[ngTemplateOutlet]="optionsListTemplate || optionListTemplate"
[ngTemplateOutletContext]="{
matches: matches,
itemTemplate: itemTemplate,
query: query
}"
></ng-template>
<!-- default options item template -->
<ng-template #hxItemTemplate let-match="match" let-query="query"
><span [innerHtml]="hightlight(match, query)"></span
></ng-template>
<!-- options list template -->
<ng-template #optionListTemplate>
<ng-template ngFor let-match let-i="index" [ngForOf]="matches">
<h6 *ngIf="match.isHeader()" class="hx-dropdown-header">{{ match }}</h6>
<ng-template [ngIf]="!match.isHeader()">
<a
href="#"
class="hx-dropdown-item"
(click)="selectMatch(match, $event)"
(mouseenter)="selectActive(match)"
[class.active]="isActive(match)"
>
<ng-template
[ngTemplateOutlet]="itemTemplate || hxItemTemplate"
[ngTemplateOutletContext]="{
item: match.item,
index: i,
match: match,
query: query
}"
></ng-template>
</a>
</ng-template>
</ng-template>
</ng-template>
`,
/* eslint-disable */
host: {
class: 'hx-dropdown-menu'
},
// tslint: enable
encapsulation: ViewEncapsulation.None,
styles: [
'strong.is-matched { background-color: rgba(35, 49, 43, .23) }',
'.hx-dropdown-item { font-weight: 300 }'
]
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { focusLost: [{
type: HostListener,
args: ['mouseleave']
}, {
type: HostListener,
args: ['blur']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZWFoZWFkLWNvbnRhaW5lci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9oeC11aS9zcmMvbGliL3R5cGVhaGVhZC90eXBlYWhlYWQtY29udGFpbmVyLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUVaLGlCQUFpQixFQUNsQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQWMsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRTNDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQzs7O0FBNEQ3QyxNQUFNLE9BQU8sMkJBQTJCO0lBcUJ0QyxZQUNVLE9BQW1CLEVBQ25CLG1CQUFzQztRQUR0QyxZQUFPLEdBQVAsT0FBTyxDQUFZO1FBQ25CLHdCQUFtQixHQUFuQixtQkFBbUIsQ0FBbUI7UUFwQnpDLGNBQVMsR0FBWSxLQUFLLENBQUM7UUFPeEIsYUFBUSxHQUFxQixFQUFFLENBQUM7UUFFMUMsMkVBQTJFO1FBQzFELFlBQU8sR0FBaUIsSUFBSSxPQUFPLEVBQUUsQ0FBQztJQVdwRCxDQUFDO0lBRUosSUFBVyxNQUFNO1FBQ2YsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDO0lBQ3RCLENBQUM7SUFFRCxJQUFXLE9BQU87UUFDaEIsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDO0lBQ3ZCLENBQUM7SUFFRCxJQUFXLE9BQU8sQ0FBQyxLQUF1QjtRQUN4QyxJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQztRQUV0QixJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtZQUM1QixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDaEMsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxFQUFFO2dCQUMzQixJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7YUFDeEI7U0FDRjtJQUNILENBQUM7SUFFRCxJQUFXLG1CQUFtQjtRQUM1QixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztJQUNuRSxDQUFDO0lBRUQsSUFBVyxZQUFZO1FBQ3JCLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0lBQ3JFLENBQUM7SUFFTSxpQkFBaUI7UUFDdEIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDakMsQ0FBQztJQUVNLGVBQWU7UUFDcEIsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQy9DLElBQUksQ0FBQyxPQUFPO1lBQ1YsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDcEUsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxFQUFFO1lBQzNCLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztTQUN4QjtJQUNILENBQUM7SUFFTSxlQUFlO1FBQ3BCLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMvQyxJQUFJLENBQUMsT0FBTztZQUNWLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ3BFLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsRUFBRTtZQUMzQixJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7U0FDeEI7SUFDSCxDQUFDO0lBRU0sWUFBWSxDQUFDLEtBQXFCO1FBQ3ZDLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO0lBQ3ZCLENBQUM7SUFFTSxVQUFVLENBQUMsS0FBcUIsRUFBRSxLQUFVO1FBQ2pELElBQUksT0FBTyxHQUFXLEtBQUssQ0FBQyxLQUFLLENBQUM7UUFDbEMsSUFBSSxhQUFhLEdBQVcsQ0FDMUIsSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FDM0UsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNoQixJQUFJLFFBQWdCLENBQUM7UUFDckIsSUFBSSxRQUFnQixDQUFDO1FBQ3JCLDRFQUE0RTtRQUM1RSxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsRUFBRTtZQUM3QixJQUFJLFFBQVEsR0FBVyxLQUFLLENBQUMsTUFBTSxDQUFDO1lBQ3BDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxRQUFRLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRTtnQkFDcEMsK0NBQStDO2dCQUMvQyxRQUFRLEdBQUcsYUFBYSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDM0MsUUFBUSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7Z0JBQzNCLElBQUksUUFBUSxJQUFJLENBQUMsSUFBSSxRQUFRLEdBQUcsQ0FBQyxFQUFFO29CQUNqQyxPQUFPO3dCQUNMLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQzs0QkFDOUIsNkJBQTZCOzRCQUM3QixPQUFPLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxRQUFRLEdBQUcsUUFBUSxDQUFDOzRCQUNoRCxXQUFXOzRCQUNYLE9BQU8sQ0FBQyxTQUFTLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQyxDQUFDO29CQUN6QyxhQUFhO3dCQUNYLGFBQWEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQzs0QkFDcEMsVUFBVTs0QkFDVixHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQzs0QkFDcEIsV0FBVzs0QkFDWCxhQUFhLENBQUMsU0FBUyxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUMsQ0FBQztpQkFDaEQ7YUFDRjtTQUNGO2FBQU0sSUFBSSxLQUFLLEVBQUU7WUFDaEIsNENBQTRDO1lBQzVDLFFBQVEsR0FBRyxhQUFhLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3hDLFFBQVEsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDO1lBQ3hCLElBQUksUUFBUSxJQUFJLENBQUMsSUFBSSxRQUFRLEdBQUcsQ0FBQyxFQUFFO2dCQUNqQyxPQUFPO29CQUNMLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQzt3QkFDOUIsOEJBQThCO3dCQUM5QixPQUFPLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxRQUFRLEdBQUcsUUFBUSxDQUFDO3dCQUNoRCxXQUFXO3dCQUNYLE9BQU8sQ0FBQyxTQUFTLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQyxDQUFDO2FBQzFDO1NBQ0Y7UUFDRCxPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDO0lBSU0sU0FBUztRQUNkLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO0lBQ3pCLENBQUM7SUFFTSxRQUFRLENBQUMsS0FBcUI7UUFDbkMsT0FBTyxJQUFJLENBQUMsT0FBTyxLQUFLLEtBQUssQ0FBQztJQUNoQyxDQUFDO0lBRU0sV0FBVyxDQUFDLEtBQXFCLEVBQUUsSUFBVyxLQUFLLENBQUM7UUFDekQsSUFBSSxDQUFDLEVBQUU7WUFDTCxDQUFDLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDcEIsQ0FBQyxDQUFDLGNBQWMsRUFBRSxDQUFDO1NBQ3BCO1FBQ0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDL0IsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQy9ELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVELElBQUksQ0FBQyxLQUFhO1FBQ2hCLDZDQUE2QztRQUM3QyxJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUU7WUFDdkIsWUFBWSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztTQUNuQztRQUNELElBQUksQ0FBQyxjQUFjLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDM0Msb0VBQW9FO1lBQ3BFLHlDQUF5QztZQUN6QyxJQUFJLENBQUMsbUJBQW1CLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDeEMsdUNBQXVDO1FBQ3pDLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUNaLENBQUM7SUFFRDs7O09BR0c7SUFDSCxJQUFJLENBQUMsS0FBYTtRQUNoQiw2Q0FBNkM7UUFDN0MsSUFBSSxJQUFJLENBQUMsY0FBYyxFQUFFO1lBQ3ZCLFlBQVksQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7U0FDbkM7UUFFRCxJQUFJLENBQUMsY0FBYyxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFO1lBQzNDLHVDQUF1QztZQUN2QyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMxQixDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDWixDQUFDO0lBRUQsdUZBQXVGO0lBQ3ZGLFdBQVc7UUFDVCxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDckMsQ0FBQzs7eUhBakxVLDJCQUEyQjs2R0FBM0IsMkJBQTJCLCtLQXRENUI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTBDVDs0RkFZVSwyQkFBMkI7a0JBekR2QyxTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSx3QkFBd0I7b0JBQ2xDLDJCQUEyQjtvQkFDM0IsUUFBUSxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0EwQ1Q7b0JBQ0Qsb0JBQW9CO29CQUNwQixJQUFJLEVBQUU7d0JBQ0osS0FBSyxFQUFFLGtCQUFrQjtxQkFDMUI7b0JBQ0QsaUJBQWlCO29CQUNqQixhQUFhLEVBQUUsaUJBQWlCLENBQUMsSUFBSTtvQkFDckMsTUFBTSxFQUFFO3dCQUNOLCtEQUErRDt3QkFDL0Qsd0NBQXdDO3FCQUN6QztpQkFDRjtpSUFnSVEsU0FBUztzQkFGZixZQUFZO3VCQUFDLFlBQVk7O3NCQUN6QixZQUFZO3VCQUFDLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIENoYW5nZURldGVjdG9yUmVmLFxyXG4gIENvbXBvbmVudCxcclxuICBFbGVtZW50UmVmLFxyXG4gIEhvc3RMaXN0ZW5lcixcclxuICBUZW1wbGF0ZVJlZixcclxuICBWaWV3RW5jYXBzdWxhdGlvblxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IFR5cGVhaGVhZE1hdGNoIH0gZnJvbSAnLi90eXBlYWhlYWQtbWF0Y2guY2xhc3MnO1xyXG5pbXBvcnQgeyBsYXRpbml6ZSB9IGZyb20gJy4vdHlwZWFoZWFkLXV0aWxzJztcclxuaW1wb3J0IHsgVHlwZWFoZWFkRGlyZWN0aXZlIH0gZnJvbSAnLi90eXBlYWhlYWQuZGlyZWN0aXZlJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnaHgtdHlwZWFoZWFkLWNvbnRhaW5lcicsXHJcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lXHJcbiAgdGVtcGxhdGU6IGBcclxuICAgIDwhLS0gaW5qZWN0IG9wdGlvbnMgbGlzdCB0ZW1wbGF0ZSAtLT5cclxuICAgIDxuZy10ZW1wbGF0ZVxyXG4gICAgICBbbmdUZW1wbGF0ZU91dGxldF09XCJvcHRpb25zTGlzdFRlbXBsYXRlIHx8IG9wdGlvbkxpc3RUZW1wbGF0ZVwiXHJcbiAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7XHJcbiAgICAgICAgbWF0Y2hlczogbWF0Y2hlcyxcclxuICAgICAgICBpdGVtVGVtcGxhdGU6IGl0ZW1UZW1wbGF0ZSxcclxuICAgICAgICBxdWVyeTogcXVlcnlcclxuICAgICAgfVwiXHJcbiAgICA+PC9uZy10ZW1wbGF0ZT5cclxuXHJcbiAgICA8IS0tIGRlZmF1bHQgb3B0aW9ucyBpdGVtIHRlbXBsYXRlIC0tPlxyXG4gICAgPG5nLXRlbXBsYXRlICNoeEl0ZW1UZW1wbGF0ZSBsZXQtbWF0Y2g9XCJtYXRjaFwiIGxldC1xdWVyeT1cInF1ZXJ5XCJcclxuICAgICAgPjxzcGFuIFtpbm5lckh0bWxdPVwiaGlnaHRsaWdodChtYXRjaCwgcXVlcnkpXCI+PC9zcGFuXHJcbiAgICA+PC9uZy10ZW1wbGF0ZT5cclxuXHJcbiAgICA8IS0tIG9wdGlvbnMgbGlzdCB0ZW1wbGF0ZSAtLT5cclxuICAgIDxuZy10ZW1wbGF0ZSAjb3B0aW9uTGlzdFRlbXBsYXRlPlxyXG4gICAgICA8bmctdGVtcGxhdGUgbmdGb3IgbGV0LW1hdGNoIGxldC1pPVwiaW5kZXhcIiBbbmdGb3JPZl09XCJtYXRjaGVzXCI+XHJcbiAgICAgICAgPGg2ICpuZ0lmPVwibWF0Y2guaXNIZWFkZXIoKVwiIGNsYXNzPVwiaHgtZHJvcGRvd24taGVhZGVyXCI+e3sgbWF0Y2ggfX08L2g2PlxyXG5cclxuICAgICAgICA8bmctdGVtcGxhdGUgW25nSWZdPVwiIW1hdGNoLmlzSGVhZGVyKClcIj5cclxuICAgICAgICAgIDxhXHJcbiAgICAgICAgICAgIGhyZWY9XCIjXCJcclxuICAgICAgICAgICAgY2xhc3M9XCJoeC1kcm9wZG93bi1pdGVtXCJcclxuICAgICAgICAgICAgKGNsaWNrKT1cInNlbGVjdE1hdGNoKG1hdGNoLCAkZXZlbnQpXCJcclxuICAgICAgICAgICAgKG1vdXNlZW50ZXIpPVwic2VsZWN0QWN0aXZlKG1hdGNoKVwiXHJcbiAgICAgICAgICAgIFtjbGFzcy5hY3RpdmVdPVwiaXNBY3RpdmUobWF0Y2gpXCJcclxuICAgICAgICAgID5cclxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlXHJcbiAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwiaXRlbVRlbXBsYXRlIHx8IGh4SXRlbVRlbXBsYXRlXCJcclxuICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwie1xyXG4gICAgICAgICAgICAgICAgaXRlbTogbWF0Y2guaXRlbSxcclxuICAgICAgICAgICAgICAgIGluZGV4OiBpLFxyXG4gICAgICAgICAgICAgICAgbWF0Y2g6IG1hdGNoLFxyXG4gICAgICAgICAgICAgICAgcXVlcnk6IHF1ZXJ5XHJcbiAgICAgICAgICAgICAgfVwiXHJcbiAgICAgICAgICAgID48L25nLXRlbXBsYXRlPlxyXG4gICAgICAgICAgPC9hPlxyXG4gICAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICAgIDwvbmctdGVtcGxhdGU+XHJcbiAgICA8L25nLXRlbXBsYXRlPlxyXG4gIGAsXHJcbiAgLyogZXNsaW50LWRpc2FibGUgKi9cclxuICBob3N0OiB7XHJcbiAgICBjbGFzczogJ2h4LWRyb3Bkb3duLW1lbnUnXHJcbiAgfSxcclxuICAvLyB0c2xpbnQ6IGVuYWJsZVxyXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXHJcbiAgc3R5bGVzOiBbXHJcbiAgICAnc3Ryb25nLmlzLW1hdGNoZWQgeyBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDM1LCA0OSwgNDMsIC4yMykgfScsXHJcbiAgICAnLmh4LWRyb3Bkb3duLWl0ZW0geyBmb250LXdlaWdodDogMzAwIH0nXHJcbiAgXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgVHlwZWFoZWFkQ29udGFpbmVyQ29tcG9uZW50IHtcclxuICBwdWJsaWMgcGFyZW50OiBUeXBlYWhlYWREaXJlY3RpdmU7XHJcbiAgcHVibGljIHF1ZXJ5OiBhbnk7XHJcbiAgcHVibGljIGlzRm9jdXNlZDogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIHB1YmxpYyB0b3A6IHN0cmluZztcclxuICBwdWJsaWMgbGVmdDogc3RyaW5nO1xyXG4gIHB1YmxpYyBkaXNwbGF5OiBzdHJpbmc7XHJcbiAgcHVibGljIHBsYWNlbWVudDogc3RyaW5nO1xyXG5cclxuICBwcm90ZWN0ZWQgX2FjdGl2ZTogVHlwZWFoZWFkTWF0Y2g7XHJcbiAgcHJvdGVjdGVkIF9tYXRjaGVzOiBUeXBlYWhlYWRNYXRjaFtdID0gW107XHJcblxyXG4gIC8qKiBTdWJqZWN0IGZvciBub3RpZnlpbmcgdGhhdCB0aGUgdG9vbHRpcCBoYXMgYmVlbiBoaWRkZW4gZnJvbSB0aGUgdmlldyAqL1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgX29uSGlkZTogU3ViamVjdDxhbnk+ID0gbmV3IFN1YmplY3QoKTtcclxuXHJcbiAgLyoqIFRoZSB0aW1lb3V0IElEIG9mIGFueSBjdXJyZW50IHRpbWVyIHNldCB0byBzaG93IHRoZSB0b29sdGlwICovXHJcbiAgcHJpdmF0ZSBfc2hvd1RpbWVvdXRJZDogbnVtYmVyO1xyXG5cclxuICAvKiogVGhlIHRpbWVvdXQgSUQgb2YgYW55IGN1cnJlbnQgdGltZXIgc2V0IHRvIGhpZGUgdGhlIHRvb2x0aXAgKi9cclxuICBwcml2YXRlIF9oaWRlVGltZW91dElkOiBudW1iZXI7XHJcblxyXG4gIHB1YmxpYyBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgZWxlbWVudDogRWxlbWVudFJlZixcclxuICAgIHByaXZhdGUgX2NoYW5nZURldGVjdGlvblJlZjogQ2hhbmdlRGV0ZWN0b3JSZWZcclxuICApIHt9XHJcblxyXG4gIHB1YmxpYyBnZXQgYWN0aXZlKCk6IFR5cGVhaGVhZE1hdGNoIHtcclxuICAgIHJldHVybiB0aGlzLl9hY3RpdmU7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZ2V0IG1hdGNoZXMoKTogVHlwZWFoZWFkTWF0Y2hbXSB7XHJcbiAgICByZXR1cm4gdGhpcy5fbWF0Y2hlcztcclxuICB9XHJcblxyXG4gIHB1YmxpYyBzZXQgbWF0Y2hlcyh2YWx1ZTogVHlwZWFoZWFkTWF0Y2hbXSkge1xyXG4gICAgdGhpcy5fbWF0Y2hlcyA9IHZhbHVlO1xyXG5cclxuICAgIGlmICh0aGlzLl9tYXRjaGVzLmxlbmd0aCA+IDApIHtcclxuICAgICAgdGhpcy5fYWN0aXZlID0gdGhpcy5fbWF0Y2hlc1swXTtcclxuICAgICAgaWYgKHRoaXMuX2FjdGl2ZS5pc0hlYWRlcigpKSB7XHJcbiAgICAgICAgdGhpcy5uZXh0QWN0aXZlTWF0Y2goKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHVibGljIGdldCBvcHRpb25zTGlzdFRlbXBsYXRlKCk6IFRlbXBsYXRlUmVmPGFueT4ge1xyXG4gICAgcmV0dXJuIHRoaXMucGFyZW50ID8gdGhpcy5wYXJlbnQub3B0aW9uc0xpc3RUZW1wbGF0ZSA6IHVuZGVmaW5lZDtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBnZXQgaXRlbVRlbXBsYXRlKCk6IFRlbXBsYXRlUmVmPGFueT4ge1xyXG4gICAgcmV0dXJuIHRoaXMucGFyZW50ID8gdGhpcy5wYXJlbnQudHlwZWFoZWFkSXRlbVRlbXBsYXRlIDogdW5kZWZpbmVkO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHNlbGVjdEFjdGl2ZU1hdGNoKCk6IHZvaWQge1xyXG4gICAgdGhpcy5zZWxlY3RNYXRjaCh0aGlzLl9hY3RpdmUpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHByZXZBY3RpdmVNYXRjaCgpOiB2b2lkIHtcclxuICAgIGxldCBpbmRleCA9IHRoaXMubWF0Y2hlcy5pbmRleE9mKHRoaXMuX2FjdGl2ZSk7XHJcbiAgICB0aGlzLl9hY3RpdmUgPVxyXG4gICAgICB0aGlzLm1hdGNoZXNbaW5kZXggLSAxIDwgMCA/IHRoaXMubWF0Y2hlcy5sZW5ndGggLSAxIDogaW5kZXggLSAxXTtcclxuICAgIGlmICh0aGlzLl9hY3RpdmUuaXNIZWFkZXIoKSkge1xyXG4gICAgICB0aGlzLnByZXZBY3RpdmVNYXRjaCgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHVibGljIG5leHRBY3RpdmVNYXRjaCgpOiB2b2lkIHtcclxuICAgIGxldCBpbmRleCA9IHRoaXMubWF0Y2hlcy5pbmRleE9mKHRoaXMuX2FjdGl2ZSk7XHJcbiAgICB0aGlzLl9hY3RpdmUgPVxyXG4gICAgICB0aGlzLm1hdGNoZXNbaW5kZXggKyAxID4gdGhpcy5tYXRjaGVzLmxlbmd0aCAtIDEgPyAwIDogaW5kZXggKyAxXTtcclxuICAgIGlmICh0aGlzLl9hY3RpdmUuaXNIZWFkZXIoKSkge1xyXG4gICAgICB0aGlzLm5leHRBY3RpdmVNYXRjaCgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHVibGljIHNlbGVjdEFjdGl2ZSh2YWx1ZTogVHlwZWFoZWFkTWF0Y2gpOiB2b2lkIHtcclxuICAgIHRoaXMuaXNGb2N1c2VkID0gdHJ1ZTtcclxuICAgIHRoaXMuX2FjdGl2ZSA9IHZhbHVlO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGhpZ2h0bGlnaHQobWF0Y2g6IFR5cGVhaGVhZE1hdGNoLCBxdWVyeTogYW55KTogc3RyaW5nIHtcclxuICAgIGxldCBpdGVtU3RyOiBzdHJpbmcgPSBtYXRjaC52YWx1ZTtcclxuICAgIGxldCBpdGVtU3RySGVscGVyOiBzdHJpbmcgPSAoXHJcbiAgICAgIHRoaXMucGFyZW50ICYmIHRoaXMucGFyZW50LnR5cGVhaGVhZExhdGluaXplID8gbGF0aW5pemUoaXRlbVN0cikgOiBpdGVtU3RyXHJcbiAgICApLnRvTG93ZXJDYXNlKCk7XHJcbiAgICBsZXQgc3RhcnRJZHg6IG51bWJlcjtcclxuICAgIGxldCB0b2tlbkxlbjogbnVtYmVyO1xyXG4gICAgLy8gUmVwbGFjZXMgdGhlIGNhcHR1cmUgc3RyaW5nIHdpdGggdGhlIHNhbWUgc3RyaW5nIGluc2lkZSBvZiBhIFwic3Ryb25nXCIgdGFnXHJcbiAgICBpZiAodHlwZW9mIHF1ZXJ5ID09PSAnb2JqZWN0Jykge1xyXG4gICAgICBsZXQgcXVlcnlMZW46IG51bWJlciA9IHF1ZXJ5Lmxlbmd0aDtcclxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBxdWVyeUxlbjsgaSArPSAxKSB7XHJcbiAgICAgICAgLy8gcXVlcnlbaV0gaXMgYWxyZWFkeSBsYXRpbml6ZWQgYW5kIGxvd2VyIGNhc2VcclxuICAgICAgICBzdGFydElkeCA9IGl0ZW1TdHJIZWxwZXIuaW5kZXhPZihxdWVyeVtpXSk7XHJcbiAgICAgICAgdG9rZW5MZW4gPSBxdWVyeVtpXS5sZW5ndGg7XHJcbiAgICAgICAgaWYgKHN0YXJ0SWR4ID49IDAgJiYgdG9rZW5MZW4gPiAwKSB7XHJcbiAgICAgICAgICBpdGVtU3RyID1cclxuICAgICAgICAgICAgaXRlbVN0ci5zdWJzdHJpbmcoMCwgc3RhcnRJZHgpICtcclxuICAgICAgICAgICAgJzxzdHJvbmcgY2xhc3M9XCJpcy1tYXRjaGVkXCI+JyArXHJcbiAgICAgICAgICAgIGl0ZW1TdHIuc3Vic3RyaW5nKHN0YXJ0SWR4LCBzdGFydElkeCArIHRva2VuTGVuKSArXHJcbiAgICAgICAgICAgICc8L3N0cm9uZz4nICtcclxuICAgICAgICAgICAgaXRlbVN0ci5zdWJzdHJpbmcoc3RhcnRJZHggKyB0b2tlbkxlbik7XHJcbiAgICAgICAgICBpdGVtU3RySGVscGVyID1cclxuICAgICAgICAgICAgaXRlbVN0ckhlbHBlci5zdWJzdHJpbmcoMCwgc3RhcnRJZHgpICtcclxuICAgICAgICAgICAgJyAgICAgICAgJyArXHJcbiAgICAgICAgICAgICcgJy5yZXBlYXQodG9rZW5MZW4pICtcclxuICAgICAgICAgICAgJyAgICAgICAgICcgK1xyXG4gICAgICAgICAgICBpdGVtU3RySGVscGVyLnN1YnN0cmluZyhzdGFydElkeCArIHRva2VuTGVuKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSBpZiAocXVlcnkpIHtcclxuICAgICAgLy8gcXVlcnkgaXMgYWxyZWFkeSBsYXRpbml6ZWQgYW5kIGxvd2VyIGNhc2VcclxuICAgICAgc3RhcnRJZHggPSBpdGVtU3RySGVscGVyLmluZGV4T2YocXVlcnkpO1xyXG4gICAgICB0b2tlbkxlbiA9IHF1ZXJ5Lmxlbmd0aDtcclxuICAgICAgaWYgKHN0YXJ0SWR4ID49IDAgJiYgdG9rZW5MZW4gPiAwKSB7XHJcbiAgICAgICAgaXRlbVN0ciA9XHJcbiAgICAgICAgICBpdGVtU3RyLnN1YnN0cmluZygwLCBzdGFydElkeCkgK1xyXG4gICAgICAgICAgJzxzdHJvbmcgIGNsYXNzPVwiaXMtbWF0Y2hlZFwiPicgK1xyXG4gICAgICAgICAgaXRlbVN0ci5zdWJzdHJpbmcoc3RhcnRJZHgsIHN0YXJ0SWR4ICsgdG9rZW5MZW4pICtcclxuICAgICAgICAgICc8L3N0cm9uZz4nICtcclxuICAgICAgICAgIGl0ZW1TdHIuc3Vic3RyaW5nKHN0YXJ0SWR4ICsgdG9rZW5MZW4pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gaXRlbVN0cjtcclxuICB9XHJcblxyXG4gIEBIb3N0TGlzdGVuZXIoJ21vdXNlbGVhdmUnKVxyXG4gIEBIb3N0TGlzdGVuZXIoJ2JsdXInKVxyXG4gIHB1YmxpYyBmb2N1c0xvc3QoKTogdm9pZCB7XHJcbiAgICB0aGlzLmlzRm9jdXNlZCA9IGZhbHNlO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGlzQWN0aXZlKHZhbHVlOiBUeXBlYWhlYWRNYXRjaCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuX2FjdGl2ZSA9PT0gdmFsdWU7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgc2VsZWN0TWF0Y2godmFsdWU6IFR5cGVhaGVhZE1hdGNoLCBlOiBFdmVudCA9IHZvaWQgMCk6IGJvb2xlYW4ge1xyXG4gICAgaWYgKGUpIHtcclxuICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgfVxyXG4gICAgdGhpcy5wYXJlbnQuY2hhbmdlTW9kZWwodmFsdWUpO1xyXG4gICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLnBhcmVudC50eXBlYWhlYWRPblNlbGVjdC5lbWl0KHZhbHVlKSwgMCk7XHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbiAgfVxyXG5cclxuICBzaG93KGRlbGF5OiBudW1iZXIpOiB2b2lkIHtcclxuICAgIC8vIENhbmNlbCB0aGUgZGVsYXllZCBoaWRlIGlmIGl0IGlzIHNjaGVkdWxlZFxyXG4gICAgaWYgKHRoaXMuX2hpZGVUaW1lb3V0SWQpIHtcclxuICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuX2hpZGVUaW1lb3V0SWQpO1xyXG4gICAgfVxyXG4gICAgdGhpcy5fc2hvd1RpbWVvdXRJZCA9IHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgLy8gU2NoZWR1bGUgZm9yIGNoYW5nZSBkZXRlY3Rpb24gaW5jYXNlIHRoZSB0b29sdGlwIGlzIHVzZWQgd2l0aGluIGFcclxuICAgICAgLy8gY29tcG9uZW50IHdpdGggT25QdXNoIGNoYW5nZSBkZXRlY3Rpb25cclxuICAgICAgdGhpcy5fY2hhbmdlRGV0ZWN0aW9uUmVmLm1hcmtGb3JDaGVjaygpO1xyXG4gICAgICAvL3RoaXMudmlzaWJpbGl0eSA9IFZpc2liaWxpdHkuVmlzaWJsZTtcclxuICAgIH0sIGRlbGF5KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEhpZGUgdGhlIHRvb2x0aXAgYWZ0ZXIgdGhlIHByb3ZpZGVkIGRlbGF5IGluIG1zLlxyXG4gICAqIEBwYXJhbSBkZWxheSBBbW91bnQgb2YgbWlsbGlzZWNvbmRzIHRvIGRlbGF5IGhpZGluZyB0aGUgdG9vbHRpcC5cclxuICAgKi9cclxuICBoaWRlKGRlbGF5OiBudW1iZXIpOiB2b2lkIHtcclxuICAgIC8vIENhbmNlbCB0aGUgZGVsYXllZCBzaG93IGlmIGl0IGlzIHNjaGVkdWxlZFxyXG4gICAgaWYgKHRoaXMuX3Nob3dUaW1lb3V0SWQpIHtcclxuICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuX3Nob3dUaW1lb3V0SWQpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuX2hpZGVUaW1lb3V0SWQgPSB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgIC8vIHRoaXMudmlzaWJpbGl0eSA9IFZpc2liaWxpdHkuSGlkZGVuO1xyXG4gICAgICB0aGlzLl9vbkhpZGUubmV4dCh0cnVlKTtcclxuICAgIH0sIGRlbGF5KTtcclxuICB9XHJcblxyXG4gIC8qKiBSZXR1cm5zIGFuIG9ic2VydmFibGUgdGhhdCBub3RpZmllcyB3aGVuIHRoZSBkcm9wZG93biBoYXMgYmVlbiBoaWRkZW4gZnJvbSB2aWV3LiAqL1xyXG4gIGFmdGVySGlkZGVuKCk6IE9ic2VydmFibGU8dm9pZD4ge1xyXG4gICAgcmV0dXJuIHRoaXMuX29uSGlkZS5hc09ic2VydmFibGUoKTtcclxuICB9XHJcbn1cclxuIl19