UNPKG

@alauda-fe/common

Version:

Alauda frontend team common codes.

290 lines 41 kB
import { __decorate, __metadata } from "tslib"; /** * @packageDocumentation * @module translate */ import { HttpClient } from '@angular/common/http'; import { Inject, Injectable, Optional, isDevMode, } from '@angular/core'; import { get, head, isPlainObject, template } from 'lodash-es'; import { EMPTY, Observable, Subject, forkJoin, throwError, catchError, filter, finalize, map, takeUntil, } from 'rxjs'; import { ajax } from 'rxjs/ajax'; import { API_GATEWAY, TEMPLATE_OPTIONS } from '../core/constants/constants'; import { TOKEN_BASE_HREF } from '../core/public-api'; import { isAbsoluteUrl } from '../core/utils/common'; import { ObservableInput } from '../core/utils/decorators'; import { parse } from '../core/utils/yaml'; import { FALLBACK_LANGUAGE, LOCALE_PLACEHOLDER_REGEX, LOCALE_STORAGE, } from './constants'; import { TRANSLATE_OPTIONS, TRANSLATIONS } from './tokens'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common/http"; export class TranslateService { get locales() { return this.options.locales; } get fallbackLocale() { return this.options.fallbackLocale; } constructor(http, baseHref, options, translationList) { this.http = http; this.baseHref = baseHref; this.translationsAdded$ = new Subject(); this.destroy$$ = new Subject(); this.translationsList = []; this.remoteTranslationsList = []; this.locale = options?.locale || navigator.language; this.options = { locales: [this.locale], fallbackLocale: FALLBACK_LANGUAGE, ...options, }; this.translationsList = [ options?.translations, ...(translationList || []), ].filter(Boolean); if (options?.remoteUrl) { if (Array.isArray(options.remoteUrl)) { options.remoteUrl.forEach(url => this.addRemoteTranslations(url)); } else { this.addRemoteTranslations(options.remoteUrl); } } } ngOnDestroy() { this.destroy$$.next(); this.destroy$$.complete(); } /** * @param key - 翻译key * @param data - 根据翻译上下文数据获取翻译内容,翻译项不存在直接返回 key 文本 * @param ignoreNonExist - 开发环境是否忽视不存在的翻译项 */ get(key, data) { const translation = this.getRaw(key); if (data != null && typeof data !== 'object') { data = [data]; } try { return template(translation, TEMPLATE_OPTIONS)(data); } catch { // eslint-disable-next-line no-console console[isDevMode() ? 'error' : 'warn'](`The translation key '${key}' is missing the necessary parameters.`); } } /** * 直接返回翻译文本模板 * @param key - 翻译key * @param ignoreNonExist - 开发环境是否忽视不存在的翻译项 */ getRaw(key) { return typeof key === 'string' ? this._get(key) : this._getValue(key); } /** * 根据 `locales` 循环切换当前区域设置 */ toggleLocale() { const index = this.options.locales.indexOf(this.locale); if (index === -1) { if (isDevMode()) { throw new TypeError('`locales` has not been initialized correctly'); } return; } const nextLocale = this.options.locales[index === this.options.locales.length - 1 ? 0 : index + 1]; if (!nextLocale || this.locale === nextLocale) { return; } this.setLocale(nextLocale); } setLocale(locale) { localStorage.setItem(LOCALE_STORAGE, locale); this.locale = locale; } /** * 手动添加语言包 */ addTranslations(translations) { this.translationsList.unshift(Object.freeze(translations)); this.translationsAdded$.next(); } /** * 手动添加语言包 */ addRemoteTranslations(remoteUrl) { if (!remoteUrl) { return; } remoteUrl = head(remoteUrl.split(/#/)); const isAbsolute = isAbsoluteUrl(remoteUrl); const isApiGateWayRequest = remoteUrl.startsWith(API_GATEWAY); if (isDevMode()) { let errorMessage; if (!isAbsolute && (!this.baseHref || !isAbsoluteUrl(this.baseHref))) { errorMessage = 'absolute base href is required for relative remote url'; } else if (remoteUrl.split('?')[0].includes('./')) { errorMessage = 'do not use any dot with slash for relative url which should always base from base href'; } if (errorMessage) { throw new TypeError(errorMessage); } } if (!isAbsolute && !isApiGateWayRequest) { remoteUrl = (this.baseHref.endsWith('/') ? this.baseHref : this.baseHref + '/') + remoteUrl; } (LOCALE_PLACEHOLDER_REGEX.test(remoteUrl) ? forkJoin(this.options.locales.map(locale => this.fetchTranslation(remoteUrl, locale).pipe(catchError(error => { if (this.options.loose) { const looseLocale = this._getLooseLocale(locale); if (locale !== looseLocale && !this.options.locales.includes(looseLocale)) { return this.fetchTranslation(remoteUrl, looseLocale); } } return isDevMode() ? throwError(() => error) : EMPTY; }), filter(isPlainObject), map((translation) => ({ [locale]: translation, }))))).pipe(map(_ => _.reduce(Object.assign))) : this.fetchTranslation(remoteUrl).pipe(catchError(error => (isDevMode() ? throwError(() => error) : EMPTY)))) .pipe(takeUntil(this.destroy$$), finalize(() => { this.translationsAdded$.next(); })) .subscribe(remoteTranslations => { if (!remoteTranslations) { return; } this.remoteTranslationsList.unshift(Object.freeze(remoteTranslations)); }); } fetchTranslation(remoteUrl, locale) { if (isDevMode() && LOCALE_PLACEHOLDER_REGEX.test(remoteUrl) && !locale) { throw new TypeError('`locale` is required sine the provided remote url contains locale placeholder'); } const isJSON = remoteUrl.endsWith('.json'); const isApiGateWayRequest = remoteUrl.startsWith(API_GATEWAY); const url = locale ? remoteUrl.replace(LOCALE_PLACEHOLDER_REGEX, locale) : remoteUrl; const responseType = isJSON ? 'json' : 'text'; if (isApiGateWayRequest) { return this.http .request('GET', url, { responseType }) .pipe(map(body => (isJSON ? body : parse(body)))); } return ajax({ url, responseType, }).pipe(map(({ response }) => (isJSON ? response : parse(response)))); } _getLooseLocale(locale) { return head(locale.split(/[_-]/)); } _getValue(source, locale = this.locale) { if (!source) { return; } let value = source[locale]; if (value == null && this.options.loose) { const looseLocale = this._getLooseLocale(locale); value = locale === looseLocale ? Object.entries(source).find(([key]) => locale === this._getLooseLocale(key))?.[1] : source[looseLocale]; } if (value == null && locale !== this.options.fallbackLocale) { return this._getValue(source, this.options.fallbackLocale); } return value; } _getWithFallback(key, locale = this.locale, translations) { const value = get(this._getValue(translations, locale), key); if (value != null) { if (typeof value === 'object' && isDevMode() && typeof get(value, Symbol.toPrimitive) !== 'function') { console.warn(`The translation for locale: \`${locale}\` and key:\`${key}\` is an object, which could be unexpected`); } return String(value); } if (locale !== this.options.fallbackLocale) { return this._getWithFallback(key, this.options.fallbackLocale, translations); } } _getBase(key, locale = this.locale, translationsList) { if (!translationsList || translationsList.length === 0) { return; } for (let i = translationsList.length; i > 0; i--) { const value = this._getWithFallback(key, locale, translationsList[i - 1]); if (value != null) { return value; } } } _get(key, locale = this.locale) { let value = this._getBase(key, locale, this.remoteTranslationsList); if (value == null) { value = this._getBase(key, locale, this.translationsList); } if (value != null) { return value; } return key; } _compareKeys(locale, translation, prevTranslation, path = []) { if (translation == null || prevTranslation == null) { return; } Object.entries(translation).forEach(([key, value]) => { if (!Object.prototype.hasOwnProperty.call(prevTranslation, key)) { return; } const prevValue = prevTranslation[key]; const valueIsPlainObject = isPlainObject(value); const prevValueIsPlainObject = isPlainObject(prevValue); if (valueIsPlainObject && prevValueIsPlainObject) { this._compareKeys(locale, value, prevValue, [...path, key]); return; } if (!valueIsPlainObject && !prevValueIsPlainObject) { const outputPath = [...path, key].join(' -> '); if (value === prevValue) { console.warn(`The customized translation for locale: \`${locale}\` and path: \`${outputPath}\` is duplicated with the other translation, please remove it in your translation file.`); } else { console.warn(`Two keys that the locale is \`${locale}\` and the path is \`${outputPath}\` are same, but their values are not equal , please remove one of them or change one of the keys.`); } } }); } static { this.ɵfac = function TranslateService_Factory(t) { return new (t || TranslateService)(i0.ɵɵinject(i1.HttpClient), i0.ɵɵinject(TOKEN_BASE_HREF), i0.ɵɵinject(TRANSLATE_OPTIONS, 8), i0.ɵɵinject(TRANSLATIONS, 8)); }; } static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: TranslateService, factory: TranslateService.ɵfac, providedIn: 'root' }); } } __decorate([ ObservableInput(), __metadata("design:type", Observable) ], TranslateService.prototype, "locale$", void 0); (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TranslateService, [{ type: Injectable, args: [{ providedIn: 'root' }] }], () => [{ type: i1.HttpClient }, { type: undefined, decorators: [{ type: Inject, args: [TOKEN_BASE_HREF] }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [TRANSLATE_OPTIONS] }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [TRANSLATIONS] }] }], { locale$: [] }); })(); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsYXRlLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzL2NvbW1vbi9zcmMvdHJhbnNsYXRlL3RyYW5zbGF0ZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7O0dBR0c7QUFFSCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDbEQsT0FBTyxFQUNMLE1BQU0sRUFDTixVQUFVLEVBRVYsUUFBUSxFQUNSLFNBQVMsR0FDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxhQUFhLEVBQUUsUUFBUSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQy9ELE9BQU8sRUFDTCxLQUFLLEVBQ0wsVUFBVSxFQUNWLE9BQU8sRUFDUCxRQUFRLEVBQ1IsVUFBVSxFQUNWLFVBQVUsRUFDVixNQUFNLEVBQ04sUUFBUSxFQUNSLEdBQUcsRUFDSCxTQUFTLEdBQ1YsTUFBTSxNQUFNLENBQUM7QUFDZCxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRWpDLE9BQU8sRUFBRSxXQUFXLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUM1RSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDckQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFM0MsT0FBTyxFQUNMLGlCQUFpQixFQUNqQix3QkFBd0IsRUFDeEIsY0FBYyxHQUNmLE1BQU0sYUFBYSxDQUFDO0FBQ3JCLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxZQUFZLEVBQUUsTUFBTSxVQUFVLENBQUM7OztBQVUzRCxNQUFNLE9BQU8sZ0JBQWdCO0lB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Z0IsbUJBREgsTUFBTTs7QUFhckI7SUFEUixlQUFlLEVBQUU7OEJBQ0EsVUFBVTtpREFBUztpRkFaMUIsZ0JBQWdCO2NBRDVCLFVBQVU7ZUFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUU7O3NCQXlCN0IsTUFBTTt1QkFBQyxlQUFlOztzQkFFdEIsUUFBUTs7c0JBQ1IsTUFBTTt1QkFBQyxpQkFBaUI7O3NCQUV4QixRQUFROztzQkFBSSxNQUFNO3VCQUFDLFlBQVk7cUJBakJ6QixPQUFPIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAcGFja2FnZURvY3VtZW50YXRpb25cbiAqIEBtb2R1bGUgdHJhbnNsYXRlXG4gKi9cblxuaW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7XG4gIEluamVjdCxcbiAgSW5qZWN0YWJsZSxcbiAgT25EZXN0cm95LFxuICBPcHRpb25hbCxcbiAgaXNEZXZNb2RlLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGdldCwgaGVhZCwgaXNQbGFpbk9iamVjdCwgdGVtcGxhdGUgfSBmcm9tICdsb2Rhc2gtZXMnO1xuaW1wb3J0IHtcbiAgRU1QVFksXG4gIE9ic2VydmFibGUsXG4gIFN1YmplY3QsXG4gIGZvcmtKb2luLFxuICB0aHJvd0Vycm9yLFxuICBjYXRjaEVycm9yLFxuICBmaWx0ZXIsXG4gIGZpbmFsaXplLFxuICBtYXAsXG4gIHRha2VVbnRpbCxcbn0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBhamF4IH0gZnJvbSAncnhqcy9hamF4JztcblxuaW1wb3J0IHsgQVBJX0dBVEVXQVksIFRFTVBMQVRFX09QVElPTlMgfSBmcm9tICcuLi9jb3JlL2NvbnN0YW50cy9jb25zdGFudHMnO1xuaW1wb3J0IHsgVE9LRU5fQkFTRV9IUkVGIH0gZnJvbSAnLi4vY29yZS9wdWJsaWMtYXBpJztcbmltcG9ydCB7IGlzQWJzb2x1dGVVcmwgfSBmcm9tICcuLi9jb3JlL3V0aWxzL2NvbW1vbic7XG5pbXBvcnQgeyBPYnNlcnZhYmxlSW5wdXQgfSBmcm9tICcuLi9jb3JlL3V0aWxzL2RlY29yYXRvcnMnO1xuaW1wb3J0IHsgcGFyc2UgfSBmcm9tICcuLi9jb3JlL3V0aWxzL3lhbWwnO1xuXG5pbXBvcnQge1xuICBGQUxMQkFDS19MQU5HVUFHRSxcbiAgTE9DQUxFX1BMQUNFSE9MREVSX1JFR0VYLFxuICBMT0NBTEVfU1RPUkFHRSxcbn0gZnJvbSAnLi9jb25zdGFudHMnO1xuaW1wb3J0IHsgVFJBTlNMQVRFX09QVElPTlMsIFRSQU5TTEFUSU9OUyB9IGZyb20gJy4vdG9rZW5zJztcbmltcG9ydCB7XG4gIFRyYW5zbGF0ZUtleSxcbiAgVHJhbnNsYXRlT3B0aW9ucyxcbiAgVHJhbnNsYXRpb24sXG4gIFRyYW5zbGF0aW9uVmFsdWUsXG4gIFRyYW5zbGF0aW9ucyxcbn0gZnJvbSAnLi90eXBlcyc7XG5cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgVHJhbnNsYXRlU2VydmljZSBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG4gIHJlYWRvbmx5IHRyYW5zbGF0aW9uc0FkZGVkJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBkZXN0cm95JCQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIHJlYWRvbmx5IHRyYW5zbGF0aW9uc0xpc3Q6IEFycmF5PFJlYWRvbmx5PFRyYW5zbGF0aW9ucz4+ID0gW107XG4gIHJlYWRvbmx5IHJlbW90ZVRyYW5zbGF0aW9uc0xpc3Q6IEFycmF5PFJlYWRvbmx5PFRyYW5zbGF0aW9ucz4+ID0gW107XG4gIHJlYWRvbmx5IG9wdGlvbnM6IFRyYW5zbGF0ZU9wdGlvbnM7XG5cbiAgbG9jYWxlOiBzdHJpbmc7XG5cbiAgQE9ic2VydmFibGVJbnB1dCgpXG4gIHJlYWRvbmx5IGxvY2FsZSQ6IE9ic2VydmFibGU8c3RyaW5nPjtcblxuICBnZXQgbG9jYWxlcygpIHtcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zLmxvY2FsZXM7XG4gIH1cblxuICBnZXQgZmFsbGJhY2tMb2NhbGUoKSB7XG4gICAgcmV0dXJuIHRoaXMub3B0aW9ucy5mYWxsYmFja0xvY2FsZTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgaHR0cDogSHR0cENsaWVudCxcbiAgICBASW5qZWN0KFRPS0VOX0JBU0VfSFJFRilcbiAgICBwcml2YXRlIHJlYWRvbmx5IGJhc2VIcmVmOiBzdHJpbmcsXG4gICAgQE9wdGlvbmFsKClcbiAgICBASW5qZWN0KFRSQU5TTEFURV9PUFRJT05TKVxuICAgIG9wdGlvbnM6IFRyYW5zbGF0ZU9wdGlvbnMsXG4gICAgQE9wdGlvbmFsKCkgQEluamVjdChUUkFOU0xBVElPTlMpIHRyYW5zbGF0aW9uTGlzdDogVHJhbnNsYXRpb25zW10sXG4gICkge1xuICAgIHRoaXMubG9jYWxlID0gb3B0aW9ucz8ubG9jYWxlIHx8IG5hdmlnYXRvci5sYW5ndWFnZTtcbiAgICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgICBsb2NhbGVzOiBbdGhpcy5sb2NhbGVdLFxuICAgICAgZmFsbGJhY2tMb2NhbGU6IEZBTExCQUNLX0xBTkdVQUdFLFxuICAgICAgLi4ub3B0aW9ucyxcbiAgICB9O1xuXG4gICAgdGhpcy50cmFuc2xhdGlvbnNMaXN0ID0gW1xuICAgICAgb3B0aW9ucz8udHJhbnNsYXRpb25zLFxuICAgICAgLi4uKHRyYW5zbGF0aW9uTGlzdCB8fCBbXSksXG4gICAgXS5maWx0ZXIoQm9vbGVhbik7XG5cbiAgICBpZiAob3B0aW9ucz8ucmVtb3RlVXJsKSB7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShvcHRpb25zLnJlbW90ZVVybCkpIHtcbiAgICAgICAgb3B0aW9ucy5yZW1vdGVVcmwuZm9yRWFjaCh1cmwgPT4gdGhpcy5hZGRSZW1vdGVUcmFuc2xhdGlvbnModXJsKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmFkZFJlbW90ZVRyYW5zbGF0aW9ucyhvcHRpb25zLnJlbW90ZVVybCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5kZXN0cm95JCQubmV4dCgpO1xuICAgIHRoaXMuZGVzdHJveSQkLmNvbXBsZXRlKCk7XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIGtleSAtIOe/u+ivkWtleVxuICAgKiBAcGFyYW0gZGF0YSAtIOagueaNrue/u+ivkeS4iuS4i+aWh+aVsOaNruiOt+WPlue/u+ivkeWGheWuue+8jOe/u+ivkemhueS4jeWtmOWcqOebtOaOpei/lOWbniBrZXkg5paH5pysXG4gICAqIEBwYXJhbSBpZ25vcmVOb25FeGlzdCAtIOW8gOWPkeeOr+Wig+aYr+WQpuW/veinhuS4jeWtmOWcqOeahOe/u+ivkemhuVxuICAgKi9cbiAgZ2V0KGtleTogVHJhbnNsYXRlS2V5LCBkYXRhPzogdW5rbm93bikge1xuICAgIGNvbnN0IHRyYW5zbGF0aW9uID0gdGhpcy5nZXRSYXcoa2V5KTtcbiAgICBpZiAoZGF0YSAhPSBudWxsICYmIHR5cGVvZiBkYXRhICE9PSAnb2JqZWN0Jykge1xuICAgICAgZGF0YSA9IFtkYXRhXTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiB0ZW1wbGF0ZSh0cmFuc2xhdGlvbiwgVEVNUExBVEVfT1BUSU9OUykoZGF0YSBhcyBvYmplY3QpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgIGNvbnNvbGVbaXNEZXZNb2RlKCkgPyAnZXJyb3InIDogJ3dhcm4nXShcbiAgICAgICAgYFRoZSB0cmFuc2xhdGlvbiBrZXkgJyR7a2V5fScgaXMgbWlzc2luZyB0aGUgbmVjZXNzYXJ5IHBhcmFtZXRlcnMuYCxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOebtOaOpei/lOWbnue/u+ivkeaWh+acrOaooeadv1xuICAgKiBAcGFyYW0ga2V5IC0g57+76K+Ra2V5XG4gICAqIEBwYXJhbSBpZ25vcmVOb25FeGlzdCAtIOW8gOWPkeeOr+Wig+aYr+WQpuW/veinhuS4jeWtmOWcqOeahOe/u+ivkemhuVxuICAgKi9cbiAgZ2V0UmF3KGtleTogVHJhbnNsYXRlS2V5KSB7XG4gICAgcmV0dXJuIHR5cGVvZiBrZXkgPT09ICdzdHJpbmcnXG4gICAgICA/IHRoaXMuX2dldChrZXkpXG4gICAgICA6ICh0aGlzLl9nZXRWYWx1ZShrZXkpIGFzIHN0cmluZyk7XG4gIH1cblxuICAvKipcbiAgICog5qC55o2uIGBsb2NhbGVzYCDlvqrnjq/liIfmjaLlvZPliY3ljLrln5/orr7nva5cbiAgICovXG4gIHRvZ2dsZUxvY2FsZSgpIHtcbiAgICBjb25zdCBpbmRleCA9IHRoaXMub3B0aW9ucy5sb2NhbGVzLmluZGV4T2YodGhpcy5sb2NhbGUpO1xuICAgIGlmIChpbmRleCA9PT0gLTEpIHtcbiAgICAgIGlmIChpc0Rldk1vZGUoKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdgbG9jYWxlc2AgaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkIGNvcnJlY3RseScpO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBuZXh0TG9jYWxlID1cbiAgICAgIHRoaXMub3B0aW9ucy5sb2NhbGVzW1xuICAgICAgICBpbmRleCA9PT0gdGhpcy5vcHRpb25zLmxvY2FsZXMubGVuZ3RoIC0gMSA/IDAgOiBpbmRleCArIDFcbiAgICAgIF07XG5cbiAgICBpZiAoIW5leHRMb2NhbGUgfHwgdGhpcy5sb2NhbGUgPT09IG5leHRMb2NhbGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnNldExvY2FsZShuZXh0TG9jYWxlKTtcbiAgfVxuXG4gIHNldExvY2FsZShsb2NhbGU6IHN0cmluZykge1xuICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKExPQ0FMRV9TVE9SQUdFLCBsb2NhbGUpO1xuICAgIHRoaXMubG9jYWxlID0gbG9jYWxlO1xuICB9XG5cbiAgLyoqXG4gICAqIOaJi+WKqOa3u+WKoOivreiogOWMhVxuICAgKi9cbiAgYWRkVHJhbnNsYXRpb25zKHRyYW5zbGF0aW9uczogVHJhbnNsYXRpb25zKSB7XG4gICAgdGhpcy50cmFuc2xhdGlvbnNMaXN0LnVuc2hpZnQoT2JqZWN0LmZyZWV6ZSh0cmFuc2xhdGlvbnMpKTtcbiAgICB0aGlzLnRyYW5zbGF0aW9uc0FkZGVkJC5uZXh0KCk7XG4gIH1cblxuICAvKipcbiAgICog5omL5Yqo5re75Yqg6K+t6KiA5YyFXG4gICAqL1xuICBhZGRSZW1vdGVUcmFuc2xhdGlvbnMocmVtb3RlVXJsOiBzdHJpbmcpIHtcbiAgICBpZiAoIXJlbW90ZVVybCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICByZW1vdGVVcmwgPSBoZWFkKHJlbW90ZVVybC5zcGxpdCgvIy8pKTtcbiAgICBjb25zdCBpc0Fic29sdXRlID0gaXNBYnNvbHV0ZVVybChyZW1vdGVVcmwpO1xuICAgIGNvbnN0IGlzQXBpR2F0ZVdheVJlcXVlc3QgPSByZW1vdGVVcmwuc3RhcnRzV2l0aChBUElfR0FURVdBWSk7XG4gICAgaWYgKGlzRGV2TW9kZSgpKSB7XG4gICAgICBsZXQgZXJyb3JNZXNzYWdlOiBzdHJpbmc7XG4gICAgICBpZiAoIWlzQWJzb2x1dGUgJiYgKCF0aGlzLmJhc2VIcmVmIHx8ICFpc0Fic29sdXRlVXJsKHRoaXMuYmFzZUhyZWYpKSkge1xuICAgICAgICBlcnJvck1lc3NhZ2UgPSAnYWJzb2x1dGUgYmFzZSBocmVmIGlzIHJlcXVpcmVkIGZvciByZWxhdGl2ZSByZW1vdGUgdXJsJztcbiAgICAgIH0gZWxzZSBpZiAocmVtb3RlVXJsLnNwbGl0KCc/JylbMF0uaW5jbHVkZXMoJy4vJykpIHtcbiAgICAgICAgZXJyb3JNZXNzYWdlID1cbiAgICAgICAgICAnZG8gbm90IHVzZSBhbnkgZG90IHdpdGggc2xhc2ggZm9yIHJlbGF0aXZlIHVybCB3aGljaCBzaG91bGQgYWx3YXlzIGJhc2UgZnJvbSBiYXNlIGhyZWYnO1xuICAgICAgfVxuICAgICAgaWYgKGVycm9yTWVzc2FnZSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGVycm9yTWVzc2FnZSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICghaXNBYnNvbHV0ZSAmJiAhaXNBcGlHYXRlV2F5UmVxdWVzdCkge1xuICAgICAgcmVtb3RlVXJsID1cbiAgICAgICAgKHRoaXMuYmFzZUhyZWYuZW5kc1dpdGgoJy8nKSA/IHRoaXMuYmFzZUhyZWYgOiB0aGlzLmJhc2VIcmVmICsgJy8nKSArXG4gICAgICAgIHJlbW90ZVVybDtcbiAgICB9XG4gICAgKExPQ0FMRV9QTEFDRUhPTERFUl9SRUdFWC50ZXN0KHJlbW90ZVVybClcbiAgICAgID8gZm9ya0pvaW4oXG4gICAgICAgICAgdGhpcy5vcHRpb25zLmxvY2FsZXMubWFwKGxvY2FsZSA9PlxuICAgICAgICAgICAgdGhpcy5mZXRjaFRyYW5zbGF0aW9uKHJlbW90ZVVybCwgbG9jYWxlKS5waXBlKFxuICAgICAgICAgICAgICBjYXRjaEVycm9yKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5vcHRpb25zLmxvb3NlKSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCBsb29zZUxvY2FsZSA9IHRoaXMuX2dldExvb3NlTG9jYWxlKGxvY2FsZSk7XG4gICAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgIGxvY2FsZSAhPT0gbG9vc2VMb2NhbGUgJiZcbiAgICAgICAgICAgICAgICAgICAgIXRoaXMub3B0aW9ucy5sb2NhbGVzLmluY2x1ZGVzKGxvb3NlTG9jYWxlKVxuICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmZldGNoVHJhbnNsYXRpb24ocmVtb3RlVXJsLCBsb29zZUxvY2FsZSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBpc0Rldk1vZGUoKSA/IHRocm93RXJyb3IoKCkgPT4gZXJyb3IpIDogRU1QVFk7XG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICBmaWx0ZXIoaXNQbGFpbk9iamVjdCksXG4gICAgICAgICAgICAgIG1hcChcbiAgICAgICAgICAgICAgICAodHJhbnNsYXRpb246IFRyYW5zbGF0aW9uKSA9PlxuICAgICAgICAgICAgICAgICAgKHtcbiAgICAgICAgICAgICAgICAgICAgW2xvY2FsZV06IHRyYW5zbGF0aW9uLFxuICAgICAgICAgICAgICAgICAgfSkgYXMgVHJhbnNsYXRpb25zLFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICApLFxuICAgICAgICApLnBpcGUobWFwKF8gPT4gXy5yZWR1Y2UoT2JqZWN0LmFzc2lnbikpKVxuICAgICAgOiB0aGlzLmZldGNoVHJhbnNsYXRpb24ocmVtb3RlVXJsKS5waXBlKFxuICAgICAgICAgIGNhdGNoRXJyb3IoZXJyb3IgPT4gKGlzRGV2TW9kZSgpID8gdGhyb3dFcnJvcigoKSA9PiBlcnJvcikgOiBFTVBUWSkpLFxuICAgICAgICApXG4gICAgKVxuICAgICAgLnBpcGUoXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkJCksXG4gICAgICAgIGZpbmFsaXplKCgpID0+IHtcbiAgICAgICAgICB0aGlzLnRyYW5zbGF0aW9uc0FkZGVkJC5uZXh0KCk7XG4gICAgICAgIH0pLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZShyZW1vdGVUcmFuc2xhdGlvbnMgPT4ge1xuICAgICAgICBpZiAoIXJlbW90ZVRyYW5zbGF0aW9ucykge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJlbW90ZVRyYW5zbGF0aW9uc0xpc3QudW5zaGlmdChPYmplY3QuZnJlZXplKHJlbW90ZVRyYW5zbGF0aW9ucykpO1xuICAgICAgfSk7XG4gIH1cblxuICAvKipcbiAgICog5LuO6L+c56iLIHVybCDmqKHmnb/lkozljLrln5/ojrflj5bnv7vor5HljIVcbiAgICovXG4gIGZldGNoVHJhbnNsYXRpb24ocmVtb3RlVXJsOiBzdHJpbmcpOiBPYnNlcnZhYmxlPFRyYW5zbGF0aW9ucz47XG4gIGZldGNoVHJhbnNsYXRpb24ocmVtb3RlVXJsOiBzdHJpbmcsIGxvY2FsZTogc3RyaW5nKTogT2JzZXJ2YWJsZTxUcmFuc2xhdGlvbj47XG4gIGZldGNoVHJhbnNsYXRpb24ocmVtb3RlVXJsOiBzdHJpbmcsIGxvY2FsZT86IHN0cmluZykge1xuICAgIGlmIChpc0Rldk1vZGUoKSAmJiBMT0NBTEVfUExBQ0VIT0xERVJfUkVHRVgudGVzdChyZW1vdGVVcmwpICYmICFsb2NhbGUpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICdgbG9jYWxlYCBpcyByZXF1aXJlZCBzaW5lIHRoZSBwcm92aWRlZCByZW1vdGUgdXJsIGNvbnRhaW5zIGxvY2FsZSBwbGFjZWhvbGRlcicsXG4gICAgICApO1xuICAgIH1cbiAgICBjb25zdCBpc0pTT04gPSByZW1vdGVVcmwuZW5kc1dpdGgoJy5qc29uJyk7XG4gICAgY29uc3QgaXNBcGlHYXRlV2F5UmVxdWVzdCA9IHJlbW90ZVVybC5zdGFydHNXaXRoKEFQSV9HQVRFV0FZKTtcbiAgICBjb25zdCB1cmwgPSBsb2NhbGVcbiAgICAgID8gcmVtb3RlVXJsLnJlcGxhY2UoTE9DQUxFX1BMQUNFSE9MREVSX1JFR0VYLCBsb2NhbGUpXG4gICAgICA6IHJlbW90ZVVybDtcbiAgICBjb25zdCByZXNwb25zZVR5cGUgPSBpc0pTT04gPyAnanNvbicgOiAndGV4dCc7XG4gICAgaWYgKGlzQXBpR2F0ZVdheVJlcXVlc3QpIHtcbiAgICAgIHJldHVybiB0aGlzLmh0dHBcbiAgICAgICAgLnJlcXVlc3QoJ0dFVCcsIHVybCwgeyByZXNwb25zZVR5cGUgfSlcbiAgICAgICAgLnBpcGUobWFwKGJvZHkgPT4gKGlzSlNPTiA/IGJvZHkgOiBwYXJzZShib2R5KSkpKTtcbiAgICB9XG4gICAgcmV0dXJuIGFqYXgoe1xuICAgICAgdXJsLFxuICAgICAgcmVzcG9uc2VUeXBlLFxuICAgIH0pLnBpcGUoXG4gICAgICBtYXAoKHsgcmVzcG9uc2UgfSkgPT4gKGlzSlNPTiA/IHJlc3BvbnNlIDogcGFyc2UocmVzcG9uc2UgYXMgc3RyaW5nKSkpLFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIF9nZXRMb29zZUxvY2FsZShsb2NhbGU6IHN0cmluZykge1xuICAgIHJldHVybiBoZWFkKGxvY2FsZS5zcGxpdCgvW18tXS8pKTtcbiAgfVxuXG4gIHByaXZhdGUgX2dldFZhbHVlKFxuICAgIHNvdXJjZTogVHJhbnNsYXRpb24sXG4gICAgbG9jYWxlID0gdGhpcy5sb2NhbGUsXG4gICk6IFRyYW5zbGF0aW9uVmFsdWUge1xuICAgIGlmICghc291cmNlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGxldCB2YWx1ZSA9IHNvdXJjZVtsb2NhbGVdO1xuICAgIGlmICh2YWx1ZSA9PSBudWxsICYmIHRoaXMub3B0aW9ucy5sb29zZSkge1xuICAgICAgY29uc3QgbG9vc2VMb2NhbGUgPSB0aGlzLl9nZXRMb29zZUxvY2FsZShsb2NhbGUpO1xuICAgICAgdmFsdWUgPVxuICAgICAgICBsb2NhbGUgPT09IGxvb3NlTG9jYWxlXG4gICAgICAgICAgPyBPYmplY3QuZW50cmllcyhzb3VyY2UpLmZpbmQoXG4gICAgICAgICAgICAgIChba2V5XSkgPT4gbG9jYWxlID09PSB0aGlzLl9nZXRMb29zZUxvY2FsZShrZXkpLFxuICAgICAgICAgICAgKT8uWzFdXG4gICAgICAgICAgOiBzb3VyY2VbbG9vc2VMb2NhbGVdO1xuICAgIH1cbiAgICBpZiAodmFsdWUgPT0gbnVsbCAmJiBsb2NhbGUgIT09IHRoaXMub3B0aW9ucy5mYWxsYmFja0xvY2FsZSkge1xuICAgICAgcmV0dXJuIHRoaXMuX2dldFZhbHVlKHNvdXJjZSwgdGhpcy5vcHRpb25zLmZhbGxiYWNrTG9jYWxlKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cbiAgcHJpdmF0ZSBfZ2V0V2l0aEZhbGxiYWNrKFxuICAgIGtleTogc3RyaW5nLFxuICAgIGxvY2FsZSA9IHRoaXMubG9jYWxlLFxuICAgIHRyYW5zbGF0aW9uczogVHJhbnNsYXRpb25zLFxuICApOiBzdHJpbmcge1xuICAgIGNvbnN0IHZhbHVlID0gZ2V0KHRoaXMuX2dldFZhbHVlKHRyYW5zbGF0aW9ucywgbG9jYWxlKSwga2V5KTtcbiAgICBpZiAodmFsdWUgIT0gbnVsbCkge1xuICAgICAgaWYgKFxuICAgICAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXG4gICAgICAgIGlzRGV2TW9kZSgpICYmXG4gICAgICAgIHR5cGVvZiBnZXQodmFsdWUsIFN5bWJvbC50b1ByaW1pdGl2ZSkgIT09ICdmdW5jdGlvbidcbiAgICAgICkge1xuICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgYFRoZSB0cmFuc2xhdGlvbiBmb3IgbG9jYWxlOiBcXGAke2xvY2FsZX1cXGAgYW5kIGtleTpcXGAke2tleX1cXGAgaXMgYW4gb2JqZWN0LCB3aGljaCBjb3VsZCBiZSB1bmV4cGVjdGVkYCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBTdHJpbmcodmFsdWUpO1xuICAgIH1cbiAgICBpZiAobG9jYWxlICE9PSB0aGlzLm9wdGlvbnMuZmFsbGJhY2tMb2NhbGUpIHtcbiAgICAgIHJldHVybiB0aGlzLl9nZXRXaXRoRmFsbGJhY2soXG4gICAgICAgIGtleSxcbiAgICAgICAgdGhpcy5vcHRpb25zLmZhbGxiYWNrTG9jYWxlLFxuICAgICAgICB0cmFuc2xhdGlvbnMsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2dldEJhc2UoXG4gICAga2V5OiBzdHJpbmcsXG4gICAgbG9jYWxlID0gdGhpcy5sb2NhbGUsXG4gICAgdHJhbnNsYXRpb25zTGlzdDogVHJhbnNsYXRpb25zW10sXG4gICkge1xuICAgIGlmICghdHJhbnNsYXRpb25zTGlzdCB8fCB0cmFuc2xhdGlvbnNMaXN0Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBmb3IgKGxldCBpID0gdHJhbnNsYXRpb25zTGlzdC5sZW5ndGg7IGkgPiAwOyBpLS0pIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5fZ2V0V2l0aEZhbGxiYWNrKGtleSwgbG9jYWxlLCB0cmFuc2xhdGlvbnNMaXN0W2kgLSAxXSk7XG4gICAgICBpZiAodmFsdWUgIT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIF9nZXQoa2V5OiBzdHJpbmcsIGxvY2FsZSA9IHRoaXMubG9jYWxlKSB7XG4gICAgbGV0IHZhbHVlID0gdGhpcy5fZ2V0QmFzZShrZXksIGxvY2FsZSwgdGhpcy5yZW1vdGVUcmFuc2xhdGlvbnNMaXN0KTtcbiAgICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgICAgdmFsdWUgPSB0aGlzLl9nZXRCYXNlKGtleSwgbG9jYWxlLCB0aGlzLnRyYW5zbGF0aW9uc0xpc3QpO1xuICAgIH1cbiAgICBpZiAodmFsdWUgIT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICByZXR1cm4ga2V5O1xuICB9XG5cbiAgcHJpdmF0ZSBfY29tcGFyZUtleXMoXG4gICAgbG9jYWxlOiBzdHJpbmcsXG4gICAgdHJhbnNsYXRpb246IFRyYW5zbGF0aW9uLFxuICAgIHByZXZUcmFuc2xhdGlvbjogVHJhbnNsYXRpb24sXG4gICAgcGF0aDogc3RyaW5nW10gPSBbXSxcbiAgKSB7XG4gICAgaWYgKHRyYW5zbGF0aW9uID09IG51bGwgfHwgcHJldlRyYW5zbGF0aW9uID09IG51bGwpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBPYmplY3QuZW50cmllcyh0cmFuc2xhdGlvbikuZm9yRWFjaCgoW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChwcmV2VHJhbnNsYXRpb24sIGtleSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwcmV2VmFsdWUgPSBwcmV2VHJhbnNsYXRpb25ba2V5XTtcbiAgICAgIGNvbnN0IHZhbHVlSXNQbGFpbk9iamVjdCA9IGlzUGxhaW5PYmplY3QodmFsdWUpO1xuICAgICAgY29uc3QgcHJldlZhbHVlSXNQbGFpbk9iamVjdCA9IGlzUGxhaW5PYmplY3QocHJldlZhbHVlKTtcblxuICAgICAgaWYgKHZhbHVlSXNQbGFpbk9iamVjdCAmJiBwcmV2VmFsdWVJc1BsYWluT2JqZWN0KSB7XG4gICAgICAgIHRoaXMuX2NvbXBhcmVLZXlzKFxuICAgICAgICAgIGxvY2FsZSxcbiAgICAgICAgICB2YWx1ZSBhcyBUcmFuc2xhdGlvbixcbiAgICAgICAgICBwcmV2VmFsdWUgYXMgVHJhbnNsYXRpb24sXG4gICAgICAgICAgWy4uLnBhdGgsIGtleV0sXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKCF2YWx1ZUlzUGxhaW5PYmplY3QgJiYgIXByZXZWYWx1ZUlzUGxhaW5PYmplY3QpIHtcbiAgICAgICAgY29uc3Qgb3V0cHV0UGF0aCA9IFsuLi5wYXRoLCBrZXldLmpvaW4oJyAtPiAnKTtcbiAgICAgICAgaWYgKHZhbHVlID09PSBwcmV2VmFsdWUpIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICBgVGhlIGN1c3RvbWl6ZWQgdHJhbnNsYXRpb24gZm9yIGxvY2FsZTogXFxgJHtsb2NhbGV9XFxgIGFuZCBwYXRoOiBcXGAke291dHB1dFBhdGh9XFxgIGlzIGR1cGxpY2F0ZWQgd2l0aCB0aGUgb3RoZXIgdHJhbnNsYXRpb24sIHBsZWFzZSByZW1vdmUgaXQgaW4geW91ciB0cmFuc2xhdGlvbiBmaWxlLmAsXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICBgVHdvIGtleXMgdGhhdCB0aGUgbG9jYWxlIGlzIFxcYCR7bG9jYWxlfVxcYCBhbmQgdGhlIHBhdGggaXMgXFxgJHtvdXRwdXRQYXRofVxcYCBhcmUgc2FtZSwgIGJ1dCB0aGVpciB2YWx1ZXMgYXJlIG5vdCBlcXVhbCAsIHBsZWFzZSByZW1vdmUgb25lIG9mIHRoZW0gb3IgY2hhbmdlIG9uZSBvZiB0aGUga2V5cy5gLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuIl19