@jsverse/transloco-locale
Version:
The localization (l10n) library plugin for Transloco
149 lines • 21.1 kB
JavaScript
import { DestroyRef, inject, Injectable } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { getBrowserCultureLang, TranslocoService } from '@jsverse/transloco';
import { BehaviorSubject } from 'rxjs';
import { distinctUntilChanged, filter, map } from 'rxjs/operators';
import { isLocaleFormat, toDate } from './helpers';
import { getDefaultOptions } from './shared';
import { TRANSLOCO_LOCALE_CONFIG, TRANSLOCO_LOCALE_CURRENCY_MAPPING, TRANSLOCO_LOCALE_DEFAULT_CURRENCY, TRANSLOCO_LOCALE_DEFAULT_LOCALE, TRANSLOCO_LOCALE_LANG_MAPPING, } from './transloco-locale.config';
import { TRANSLOCO_DATE_TRANSFORMER, TRANSLOCO_NUMBER_TRANSFORMER, } from './transloco-locale.transformers';
import * as i0 from "@angular/core";
export class TranslocoLocaleService {
translocoService = inject(TranslocoService);
langLocaleMapping = inject(TRANSLOCO_LOCALE_LANG_MAPPING);
defaultLocale = inject(TRANSLOCO_LOCALE_DEFAULT_LOCALE);
defaultCurrency = inject(TRANSLOCO_LOCALE_DEFAULT_CURRENCY);
localeCurrencyMapping = inject(TRANSLOCO_LOCALE_CURRENCY_MAPPING);
numberTransformer = inject(TRANSLOCO_NUMBER_TRANSFORMER);
dateTransformer = inject(TRANSLOCO_DATE_TRANSFORMER);
localeConfig = inject(TRANSLOCO_LOCALE_CONFIG);
browserLocale = getBrowserCultureLang() || this.defaultLocale;
_locale = '';
locale = new BehaviorSubject(this._locale);
localeChanges$ = this.locale.pipe(distinctUntilChanged());
constructor() {
inject(DestroyRef).onDestroy(() => {
// Complete subjects to release observers if users forget to unsubscribe manually.
// This is important in server-side rendering.
this.locale.complete();
this.locale.unsubscribe();
});
// Initialize locale with fallback chain
this.setLocale(this.initializeLocale());
// Subscribe to language changes
this.translocoService.langChanges$
.pipe(map((lang) => this.toLocale(lang)), filter(Boolean), takeUntilDestroyed())
.subscribe((locale) => this.setLocale(locale));
}
getDefaultLocale() {
return this.defaultLocale;
}
getLocale() {
return this._locale;
}
setLocale(locale) {
if (!isLocaleFormat(locale)) {
console.error(`${locale} isn't a valid locale format`);
return;
}
this.locale.next(locale);
this._locale = locale;
}
/**
* Get the currency symbol for the currently set locale.
*/
getCurrencySymbol(locale = this.getLocale()) {
const currency = this.localeCurrencyMapping[locale];
const numberFormat = new Intl.NumberFormat(locale, {
style: 'currency',
currencyDisplay: 'symbol',
currency,
minimumFractionDigits: 0,
maximumFractionDigits: 0,
});
const pivot = 0;
return numberFormat
.format(pivot)
.split(pivot.toString())
.map((element) => element.trim())
.find((element) => !!element);
}
/**
* Transform a date into the locale's date format.
*
* The date expression: a `Date` object, a number
* (milliseconds since UTC epoch), or an ISO string (https://www.w3.org/TR/NOTE-datetime).
*
* @example
*
* localizeDate(new Date(2019, 9, 7, 12, 0, 0)) // 10/7/2019
* localizeDate(date, 'en-US', { dateStyle: 'medium', timeStyle: 'medium' }) // Sep 10, 2019, 10:46:12 PM
* localizeDate(date) 'en-US', { timeZone: 'UTC', timeStyle: 'full' } // 7:40:32 PM Coordinated Universal Time
* localizeDate(1, 'en-US', { dateStyle: 'medium' }) // Jan 1, 1970
* localizeDate('2019-02-08', 'en-US', { dateStyle: 'medium' }) // Feb 8, 2019
*/
localizeDate(date, locale = this.getLocale(), options = {}) {
const resolved = options ?? getDefaultOptions(locale, 'date', this.localeConfig);
return this.dateTransformer.transform(toDate(date), locale, resolved);
}
/**
* Transform a number into the locale's number format according to the number type.
*
* localizeNumber(1234567890, 'decimal') // 1,234,567,890
* localizeNumber(0.5, 'percent') // 50%
* localizeNumber(1000, 'currency') // $1,000.00
*/
localizeNumber(value, style, locale = this.getLocale(), options) {
let resolved = options ?? getDefaultOptions(locale, style, this.localeConfig);
if (style === 'currency') {
resolved = {
...resolved,
currency: resolved.currency || this._resolveCurrencyCode(locale),
};
}
return this.numberTransformer.transform(value, style, locale, resolved);
}
/**
* @internal
*/
_resolveCurrencyCode(locale = this.getLocale()) {
return this.localeCurrencyMapping[locale] || this.defaultCurrency;
}
toLocale(val) {
if (this.langLocaleMapping[val]) {
return this.langLocaleMapping[val];
}
if (isLocaleFormat(val)) {
return val;
}
return '';
}
/*
* Get the browser's language and validate.
* If the browser's language is not set, it will fall back to the active language from TranslocoService.
* If active language from TranslocoService is not valid, it will fall back to the default locale.
* If the default locale is not valid, it will return the default locale as a string
*/
initializeLocale() {
const browserLocale = this.toLocale(this.browserLocale);
if (browserLocale)
return browserLocale;
const activeLang = this.translocoService.getActiveLang();
if (activeLang) {
const locale = this.toLocale(activeLang);
if (locale)
return locale;
}
const defaultLocaleResolved = this.toLocale(this.defaultLocale);
if (defaultLocaleResolved)
return defaultLocaleResolved;
return this.defaultLocale; // Fallback to a default locale
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: TranslocoLocaleService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: TranslocoLocaleService, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: TranslocoLocaleService, decorators: [{
type: Injectable,
args: [{ providedIn: 'root' }]
}], ctorParameters: () => [] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsb2NvLWxvY2FsZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGlicy90cmFuc2xvY28tbG9jYWxlL3NyYy9saWIvdHJhbnNsb2NvLWxvY2FsZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMvRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUM3RSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFbkUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDbkQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQzdDLE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsaUNBQWlDLEVBQ2pDLGlDQUFpQyxFQUNqQywrQkFBK0IsRUFDL0IsNkJBQTZCLEdBQzlCLE1BQU0sMkJBQTJCLENBQUM7QUFDbkMsT0FBTyxFQUNMLDBCQUEwQixFQUMxQiw0QkFBNEIsR0FDN0IsTUFBTSxpQ0FBaUMsQ0FBQzs7QUFVekMsTUFBTSxPQUFPLHNCQUFzQjtJQUN6QixnQkFBZ0IsR0FBRyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUM1QyxpQkFBaUIsR0FBRyxNQUFNLENBQUMsNkJBQTZCLENBQUMsQ0FBQztJQUMxRCxhQUFhLEdBQUcsTUFBTSxDQUFDLCtCQUErQixDQUFDLENBQUM7SUFDeEQsZUFBZSxHQUFHLE1BQU0sQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO0lBQzVELHFCQUFxQixHQUFHLE1BQU0sQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO0lBQ2xFLGlCQUFpQixHQUFHLE1BQU0sQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDO0lBQ3pELGVBQWUsR0FBRyxNQUFNLENBQUMsMEJBQTBCLENBQUMsQ0FBQztJQUNyRCxZQUFZLEdBQWlCLE1BQU0sQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO0lBQzdELGFBQWEsR0FBRyxxQkFBcUIsRUFBRSxJQUFJLElBQUksQ0FBQyxhQUFhLENBQUM7SUFFOUQsT0FBTyxHQUFHLEVBQUUsQ0FBQztJQUNiLE1BQU0sR0FBRyxJQUFJLGVBQWUsQ0FBUyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFFbEQsY0FBYyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUMsQ0FBQztJQUVuRTtRQUNFLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFO1lBQ2hDLGtGQUFrRjtZQUNsRiw4Q0FBOEM7WUFDOUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQzVCLENBQUMsQ0FBQyxDQUFDO1FBRUgsd0NBQXdDO1FBQ3hDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUMsQ0FBQztRQUV4QyxnQ0FBZ0M7UUFDaEMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFlBQVk7YUFDL0IsSUFBSSxDQUNILEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUNsQyxNQUFNLENBQUMsT0FBTyxDQUFDLEVBQ2Ysa0JBQWtCLEVBQUUsQ0FDckI7YUFDQSxTQUFTLENBQUMsQ0FBQyxNQUFjLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUMzRCxDQUFDO0lBRUQsZ0JBQWdCO1FBQ2QsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDO0lBQzVCLENBQUM7SUFFRCxTQUFTO1FBQ1AsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDO0lBQ3RCLENBQUM7SUFFRCxTQUFTLENBQUMsTUFBYztRQUN0QixJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFDNUIsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLE1BQU0sOEJBQThCLENBQUMsQ0FBQztZQUN2RCxPQUFPO1FBQ1QsQ0FBQztRQUVELElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3pCLElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDO0lBQ3hCLENBQUM7SUFFRDs7T0FFRztJQUNILGlCQUFpQixDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFO1FBQ3pDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNwRCxNQUFNLFlBQVksR0FBRyxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFO1lBQ2pELEtBQUssRUFBRSxVQUFVO1lBQ2pCLGVBQWUsRUFBRSxRQUFRO1lBQ3pCLFFBQVE7WUFDUixxQkFBcUIsRUFBRSxDQUFDO1lBQ3hCLHFCQUFxQixFQUFFLENBQUM7U0FDekIsQ0FBQyxDQUFDO1FBRUgsTUFBTSxLQUFLLEdBQUcsQ0FBQyxDQUFDO1FBRWhCLE9BQU8sWUFBWTthQUNoQixNQUFNLENBQUMsS0FBSyxDQUFDO2FBQ2IsS0FBSyxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQzthQUN2QixHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQzthQUNoQyxJQUFJLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7T0FhRztJQUNILFlBQVksQ0FDVixJQUFlLEVBQ2YsU0FBaUIsSUFBSSxDQUFDLFNBQVMsRUFBRSxFQUNqQyxVQUE2QixFQUFFO1FBRS9CLE1BQU0sUUFBUSxHQUNaLE9BQU8sSUFBSSxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUVsRSxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDeEUsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILGNBQWMsQ0FDWixLQUFzQixFQUN0QixLQUFtQixFQUNuQixTQUFpQixJQUFJLENBQUMsU0FBUyxFQUFFLEVBQ2pDLE9BQWtDO1FBRWxDLElBQUksUUFBUSxHQUNWLE9BQU8sSUFBSSxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUVqRSxJQUFJLEtBQUssS0FBSyxVQUFVLEVBQUUsQ0FBQztZQUN6QixRQUFRLEdBQUc7Z0JBQ1QsR0FBRyxRQUFRO2dCQUNYLFFBQVEsRUFBRSxRQUFRLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLENBQUM7YUFDakUsQ0FBQztRQUNKLENBQUM7UUFFRCxPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDMUUsQ0FBQztJQUVEOztPQUVHO0lBQ0gsb0JBQW9CLENBQUMsU0FBaUIsSUFBSSxDQUFDLFNBQVMsRUFBRTtRQUNwRCxPQUFPLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxNQUFNLENBQUMsSUFBSSxJQUFJLENBQUMsZUFBZSxDQUFDO0lBQ3BFLENBQUM7SUFFTyxRQUFRLENBQUMsR0FBb0I7UUFDbkMsSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNoQyxPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNyQyxDQUFDO1FBRUQsSUFBSSxjQUFjLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN4QixPQUFPLEdBQUcsQ0FBQztRQUNiLENBQUM7UUFFRCxPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7SUFFRDs7Ozs7T0FLRztJQUVLLGdCQUFnQjtRQUN0QixNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUN4RCxJQUFJLGFBQWE7WUFBRSxPQUFPLGFBQWEsQ0FBQztRQUV4QyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDekQsSUFBSSxVQUFVLEVBQUUsQ0FBQztZQUNmLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDekMsSUFBSSxNQUFNO2dCQUFFLE9BQU8sTUFBTSxDQUFDO1FBQzVCLENBQUM7UUFFRCxNQUFNLHFCQUFxQixHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ2hFLElBQUkscUJBQXFCO1lBQUUsT0FBTyxxQkFBcUIsQ0FBQztRQUV4RCxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQywrQkFBK0I7SUFDNUQsQ0FBQzt1R0F4S1Usc0JBQXNCOzJHQUF0QixzQkFBc0IsY0FEVCxNQUFNOzsyRkFDbkIsc0JBQXNCO2tCQURsQyxVQUFVO21CQUFDLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERlc3Ryb3lSZWYsIGluamVjdCwgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHsgZ2V0QnJvd3NlckN1bHR1cmVMYW5nLCBUcmFuc2xvY29TZXJ2aWNlIH0gZnJvbSAnQGpzdmVyc2UvdHJhbnNsb2NvJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGlzdGluY3RVbnRpbENoYW5nZWQsIGZpbHRlciwgbWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBpc0xvY2FsZUZvcm1hdCwgdG9EYXRlIH0gZnJvbSAnLi9oZWxwZXJzJztcbmltcG9ydCB7IGdldERlZmF1bHRPcHRpb25zIH0gZnJvbSAnLi9zaGFyZWQnO1xuaW1wb3J0IHtcbiAgVFJBTlNMT0NPX0xPQ0FMRV9DT05GSUcsXG4gIFRSQU5TTE9DT19MT0NBTEVfQ1VSUkVOQ1lfTUFQUElORyxcbiAgVFJBTlNMT0NPX0xPQ0FMRV9ERUZBVUxUX0NVUlJFTkNZLFxuICBUUkFOU0xPQ09fTE9DQUxFX0RFRkFVTFRfTE9DQUxFLFxuICBUUkFOU0xPQ09fTE9DQUxFX0xBTkdfTUFQUElORyxcbn0gZnJvbSAnLi90cmFuc2xvY28tbG9jYWxlLmNvbmZpZyc7XG5pbXBvcnQge1xuICBUUkFOU0xPQ09fREFURV9UUkFOU0ZPUk1FUixcbiAgVFJBTlNMT0NPX05VTUJFUl9UUkFOU0ZPUk1FUixcbn0gZnJvbSAnLi90cmFuc2xvY28tbG9jYWxlLnRyYW5zZm9ybWVycyc7XG5pbXBvcnQge1xuICBEYXRlRm9ybWF0T3B0aW9ucyxcbiAgTG9jYWxlLFxuICBMb2NhbGVDb25maWcsXG4gIE51bWJlclN0eWxlcyxcbiAgVmFsaWREYXRlLFxufSBmcm9tICcuL3RyYW5zbG9jby1sb2NhbGUudHlwZXMnO1xuXG5ASW5qZWN0YWJsZSh7IHByb3ZpZGVkSW46ICdyb290JyB9KVxuZXhwb3J0IGNsYXNzIFRyYW5zbG9jb0xvY2FsZVNlcnZpY2Uge1xuICBwcml2YXRlIHRyYW5zbG9jb1NlcnZpY2UgPSBpbmplY3QoVHJhbnNsb2NvU2VydmljZSk7XG4gIHByaXZhdGUgbGFuZ0xvY2FsZU1hcHBpbmcgPSBpbmplY3QoVFJBTlNMT0NPX0xPQ0FMRV9MQU5HX01BUFBJTkcpO1xuICBwcml2YXRlIGRlZmF1bHRMb2NhbGUgPSBpbmplY3QoVFJBTlNMT0NPX0xPQ0FMRV9ERUZBVUxUX0xPQ0FMRSk7XG4gIHByaXZhdGUgZGVmYXVsdEN1cnJlbmN5ID0gaW5qZWN0KFRSQU5TTE9DT19MT0NBTEVfREVGQVVMVF9DVVJSRU5DWSk7XG4gIHByaXZhdGUgbG9jYWxlQ3VycmVuY3lNYXBwaW5nID0gaW5qZWN0KFRSQU5TTE9DT19MT0NBTEVfQ1VSUkVOQ1lfTUFQUElORyk7XG4gIHByaXZhdGUgbnVtYmVyVHJhbnNmb3JtZXIgPSBpbmplY3QoVFJBTlNMT0NPX05VTUJFUl9UUkFOU0ZPUk1FUik7XG4gIHByaXZhdGUgZGF0ZVRyYW5zZm9ybWVyID0gaW5qZWN0KFRSQU5TTE9DT19EQVRFX1RSQU5TRk9STUVSKTtcbiAgcHJpdmF0ZSBsb2NhbGVDb25maWc6IExvY2FsZUNvbmZpZyA9IGluamVjdChUUkFOU0xPQ09fTE9DQUxFX0NPTkZJRyk7XG4gIHByaXZhdGUgYnJvd3NlckxvY2FsZSA9IGdldEJyb3dzZXJDdWx0dXJlTGFuZygpIHx8IHRoaXMuZGVmYXVsdExvY2FsZTtcblxuICBwcml2YXRlIF9sb2NhbGUgPSAnJztcbiAgcHJpdmF0ZSBsb2NhbGUgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PExvY2FsZT4odGhpcy5fbG9jYWxlKTtcblxuICByZWFkb25seSBsb2NhbGVDaGFuZ2VzJCA9IHRoaXMubG9jYWxlLnBpcGUoZGlzdGluY3RVbnRpbENoYW5nZWQoKSk7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgaW5qZWN0KERlc3Ryb3lSZWYpLm9uRGVzdHJveSgoKSA9PiB7XG4gICAgICAvLyBDb21wbGV0ZSBzdWJqZWN0cyB0byByZWxlYXNlIG9ic2VydmVycyBpZiB1c2VycyBmb3JnZXQgdG8gdW5zdWJzY3JpYmUgbWFudWFsbHkuXG4gICAgICAvLyBUaGlzIGlzIGltcG9ydGFudCBpbiBzZXJ2ZXItc2lkZSByZW5kZXJpbmcuXG4gICAgICB0aGlzLmxvY2FsZS5jb21wbGV0ZSgpO1xuICAgICAgdGhpcy5sb2NhbGUudW5zdWJzY3JpYmUoKTtcbiAgICB9KTtcblxuICAgIC8vIEluaXRpYWxpemUgbG9jYWxlIHdpdGggZmFsbGJhY2sgY2hhaW5cbiAgICB0aGlzLnNldExvY2FsZSh0aGlzLmluaXRpYWxpemVMb2NhbGUoKSk7XG5cbiAgICAvLyBTdWJzY3JpYmUgdG8gbGFuZ3VhZ2UgY2hhbmdlc1xuICAgIHRoaXMudHJhbnNsb2NvU2VydmljZS5sYW5nQ2hhbmdlcyRcbiAgICAgIC5waXBlKFxuICAgICAgICBtYXAoKGxhbmcpID0+IHRoaXMudG9Mb2NhbGUobGFuZykpLFxuICAgICAgICBmaWx0ZXIoQm9vbGVhbiksXG4gICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCgpLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgobG9jYWxlOiBMb2NhbGUpID0+IHRoaXMuc2V0TG9jYWxlKGxvY2FsZSkpO1xuICB9XG5cbiAgZ2V0RGVmYXVsdExvY2FsZSgpIHtcbiAgICByZXR1cm4gdGhpcy5kZWZhdWx0TG9jYWxlO1xuICB9XG5cbiAgZ2V0TG9jYWxlKCkge1xuICAgIHJldHVybiB0aGlzLl9sb2NhbGU7XG4gIH1cblxuICBzZXRMb2NhbGUobG9jYWxlOiBMb2NhbGUpIHtcbiAgICBpZiAoIWlzTG9jYWxlRm9ybWF0KGxvY2FsZSkpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoYCR7bG9jYWxlfSBpc24ndCBhIHZhbGlkIGxvY2FsZSBmb3JtYXRgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmxvY2FsZS5uZXh0KGxvY2FsZSk7XG4gICAgdGhpcy5fbG9jYWxlID0gbG9jYWxlO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgY3VycmVuY3kgc3ltYm9sIGZvciB0aGUgY3VycmVudGx5IHNldCBsb2NhbGUuXG4gICAqL1xuICBnZXRDdXJyZW5jeVN5bWJvbChsb2NhbGUgPSB0aGlzLmdldExvY2FsZSgpKSB7XG4gICAgY29uc3QgY3VycmVuY3kgPSB0aGlzLmxvY2FsZUN1cnJlbmN5TWFwcGluZ1tsb2NhbGVdO1xuICAgIGNvbnN0IG51bWJlckZvcm1hdCA9IG5ldyBJbnRsLk51bWJlckZvcm1hdChsb2NhbGUsIHtcbiAgICAgIHN0eWxlOiAnY3VycmVuY3knLFxuICAgICAgY3VycmVuY3lEaXNwbGF5OiAnc3ltYm9sJyxcbiAgICAgIGN1cnJlbmN5LFxuICAgICAgbWluaW11bUZyYWN0aW9uRGlnaXRzOiAwLFxuICAgICAgbWF4aW11bUZyYWN0aW9uRGlnaXRzOiAwLFxuICAgIH0pO1xuXG4gICAgY29uc3QgcGl2b3QgPSAwO1xuXG4gICAgcmV0dXJuIG51bWJlckZvcm1hdFxuICAgICAgLmZvcm1hdChwaXZvdClcbiAgICAgIC5zcGxpdChwaXZvdC50b1N0cmluZygpKVxuICAgICAgLm1hcCgoZWxlbWVudCkgPT4gZWxlbWVudC50cmltKCkpXG4gICAgICAuZmluZCgoZWxlbWVudCkgPT4gISFlbGVtZW50KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmFuc2Zvcm0gYSBkYXRlIGludG8gdGhlIGxvY2FsZSdzIGRhdGUgZm9ybWF0LlxuICAgKlxuICAgKiBUaGUgZGF0ZSBleHByZXNzaW9uOiBhIGBEYXRlYCBvYmplY3QsIGEgbnVtYmVyXG4gICAqIChtaWxsaXNlY29uZHMgc2luY2UgVVRDIGVwb2NoKSwgb3IgYW4gSVNPIHN0cmluZyAoaHR0cHM6Ly93d3cudzMub3JnL1RSL05PVEUtZGF0ZXRpbWUpLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKlxuICAgKiBsb2NhbGl6ZURhdGUobmV3IERhdGUoMjAxOSwgOSwgNywgMTIsIDAsIDApKSAvLyAxMC83LzIwMTlcbiAgICogbG9jYWxpemVEYXRlKGRhdGUsICdlbi1VUycsIHsgZGF0ZVN0eWxlOiAnbWVkaXVtJywgdGltZVN0eWxlOiAnbWVkaXVtJyB9KSAvLyBTZXAgMTAsIDIwMTksIDEwOjQ2OjEyIFBNXG4gICAqIGxvY2FsaXplRGF0ZShkYXRlKSAnZW4tVVMnLCB7IHRpbWVab25lOiAnVVRDJywgdGltZVN0eWxlOiAnZnVsbCcgfSAvLyA3OjQwOjMyIFBNIENvb3JkaW5hdGVkIFVuaXZlcnNhbCBUaW1lXG4gICAqIGxvY2FsaXplRGF0ZSgxLCAnZW4tVVMnLCB7IGRhdGVTdHlsZTogJ21lZGl1bScgfSkgLy8gSmFuIDEsIDE5NzBcbiAgICogbG9jYWxpemVEYXRlKCcyMDE5LTAyLTA4JywgJ2VuLVVTJywgeyBkYXRlU3R5bGU6ICdtZWRpdW0nIH0pIC8vIEZlYiA4LCAyMDE5XG4gICAqL1xuICBsb2NhbGl6ZURhdGUoXG4gICAgZGF0ZTogVmFsaWREYXRlLFxuICAgIGxvY2FsZTogTG9jYWxlID0gdGhpcy5nZXRMb2NhbGUoKSxcbiAgICBvcHRpb25zOiBEYXRlRm9ybWF0T3B0aW9ucyA9IHt9LFxuICApOiBzdHJpbmcge1xuICAgIGNvbnN0IHJlc29sdmVkID1cbiAgICAgIG9wdGlvbnMgPz8gZ2V0RGVmYXVsdE9wdGlvbnMobG9jYWxlLCAnZGF0ZScsIHRoaXMubG9jYWxlQ29uZmlnKTtcblxuICAgIHJldHVybiB0aGlzLmRhdGVUcmFuc2Zvcm1lci50cmFuc2Zvcm0odG9EYXRlKGRhdGUpLCBsb2NhbGUsIHJlc29sdmVkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmFuc2Zvcm0gYSBudW1iZXIgaW50byB0aGUgbG9jYWxlJ3MgbnVtYmVyIGZvcm1hdCBhY2NvcmRpbmcgdG8gdGhlIG51bWJlciB0eXBlLlxuICAgKlxuICAgKiBsb2NhbGl6ZU51bWJlcigxMjM0NTY3ODkwLCAnZGVjaW1hbCcpIC8vIDEsMjM0LDU2Nyw4OTBcbiAgICogbG9jYWxpemVOdW1iZXIoMC41LCAncGVyY2VudCcpIC8vIDUwJVxuICAgKiBsb2NhbGl6ZU51bWJlcigxMDAwLCAnY3VycmVuY3knKSAvLyAkMSwwMDAuMDBcbiAgICovXG4gIGxvY2FsaXplTnVtYmVyKFxuICAgIHZhbHVlOiBudW1iZXIgfCBzdHJpbmcsXG4gICAgc3R5bGU6IE51bWJlclN0eWxlcyxcbiAgICBsb2NhbGU6IExvY2FsZSA9IHRoaXMuZ2V0TG9jYWxlKCksXG4gICAgb3B0aW9ucz86IEludGwuTnVtYmVyRm9ybWF0T3B0aW9ucyxcbiAgKTogc3RyaW5nIHtcbiAgICBsZXQgcmVzb2x2ZWQgPVxuICAgICAgb3B0aW9ucyA/PyBnZXREZWZhdWx0T3B0aW9ucyhsb2NhbGUsIHN0eWxlLCB0aGlzLmxvY2FsZUNvbmZpZyk7XG5cbiAgICBpZiAoc3R5bGUgPT09ICdjdXJyZW5jeScpIHtcbiAgICAgIHJlc29sdmVkID0ge1xuICAgICAgICAuLi5yZXNvbHZlZCxcbiAgICAgICAgY3VycmVuY3k6IHJlc29sdmVkLmN1cnJlbmN5IHx8IHRoaXMuX3Jlc29sdmVDdXJyZW5jeUNvZGUobG9jYWxlKSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMubnVtYmVyVHJhbnNmb3JtZXIudHJhbnNmb3JtKHZhbHVlLCBzdHlsZSwgbG9jYWxlLCByZXNvbHZlZCk7XG4gIH1cblxuICAvKipcbiAgICogQGludGVybmFsXG4gICAqL1xuICBfcmVzb2x2ZUN1cnJlbmN5Q29kZShsb2NhbGU6IExvY2FsZSA9IHRoaXMuZ2V0TG9jYWxlKCkpIHtcbiAgICByZXR1cm4gdGhpcy5sb2NhbGVDdXJyZW5jeU1hcHBpbmdbbG9jYWxlXSB8fCB0aGlzLmRlZmF1bHRDdXJyZW5jeTtcbiAgfVxuXG4gIHByaXZhdGUgdG9Mb2NhbGUodmFsOiBzdHJpbmcgfCBMb2NhbGUpOiBMb2NhbGUge1xuICAgIGlmICh0aGlzLmxhbmdMb2NhbGVNYXBwaW5nW3ZhbF0pIHtcbiAgICAgIHJldHVybiB0aGlzLmxhbmdMb2NhbGVNYXBwaW5nW3ZhbF07XG4gICAgfVxuXG4gICAgaWYgKGlzTG9jYWxlRm9ybWF0KHZhbCkpIHtcbiAgICAgIHJldHVybiB2YWw7XG4gICAgfVxuXG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgLypcbiAgICogR2V0IHRoZSBicm93c2VyJ3MgbGFuZ3VhZ2UgYW5kIHZhbGlkYXRlLlxuICAgKiBJZiB0aGUgYnJvd3NlcidzIGxhbmd1YWdlIGlzIG5vdCBzZXQsIGl0IHdpbGwgZmFsbCBiYWNrIHRvIHRoZSBhY3RpdmUgbGFuZ3VhZ2UgZnJvbSBUcmFuc2xvY29TZXJ2aWNlLlxuICAgKiBJZiBhY3RpdmUgbGFuZ3VhZ2UgZnJvbSBUcmFuc2xvY29TZXJ2aWNlIGlzIG5vdCB2YWxpZCwgaXQgd2lsbCBmYWxsIGJhY2sgdG8gdGhlIGRlZmF1bHQgbG9jYWxlLlxuICAgKiBJZiB0aGUgZGVmYXVsdCBsb2NhbGUgaXMgbm90IHZhbGlkLCBpdCB3aWxsIHJldHVybiB0aGUgZGVmYXVsdCBsb2NhbGUgYXMgYSBzdHJpbmdcbiAgICovXG5cbiAgcHJpdmF0ZSBpbml0aWFsaXplTG9jYWxlKCk6IExvY2FsZSB7XG4gICAgY29uc3QgYnJvd3NlckxvY2FsZSA9IHRoaXMudG9Mb2NhbGUodGhpcy5icm93c2VyTG9jYWxlKTtcbiAgICBpZiAoYnJvd3NlckxvY2FsZSkgcmV0dXJuIGJyb3dzZXJMb2NhbGU7XG5cbiAgICBjb25zdCBhY3RpdmVMYW5nID0gdGhpcy50cmFuc2xvY29TZXJ2aWNlLmdldEFjdGl2ZUxhbmcoKTtcbiAgICBpZiAoYWN0aXZlTGFuZykge1xuICAgICAgY29uc3QgbG9jYWxlID0gdGhpcy50b0xvY2FsZShhY3RpdmVMYW5nKTtcbiAgICAgIGlmIChsb2NhbGUpIHJldHVybiBsb2NhbGU7XG4gICAgfVxuXG4gICAgY29uc3QgZGVmYXVsdExvY2FsZVJlc29sdmVkID0gdGhpcy50b0xvY2FsZSh0aGlzLmRlZmF1bHRMb2NhbGUpO1xuICAgIGlmIChkZWZhdWx0TG9jYWxlUmVzb2x2ZWQpIHJldHVybiBkZWZhdWx0TG9jYWxlUmVzb2x2ZWQ7XG5cbiAgICByZXR1cm4gdGhpcy5kZWZhdWx0TG9jYWxlOyAvLyBGYWxsYmFjayB0byBhIGRlZmF1bHQgbG9jYWxlXG4gIH1cbn1cbiJdfQ==