import { DOCUMENT } from '@angular/common'; import { HttpClient } from '@angular/common/http'; import { Inject, Injectable, InjectionToken, Optional, SecurityContext } from '@angular/core'; import { of, Observable, Subject } from 'rxjs'; import { catchError, filter, finalize, map, share, take, tap } from 'rxjs/operators'; import { cloneSVG, getIconDefinitionFromAbbr, getNameAndNamespace, getSecondaryColor, hasNamespace, isIconDefinition, replaceFillColor, warn, withSuffix, withSuffixAndColor } from '../utils'; import { DynamicLoadingTimeoutError, HttpModuleNotImport, IconNotFoundError, NameSpaceIsNotSpecifyError, SVGTagNotFoundError, UrlNotSafeError } from './icon.error'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common/http"; import * as i2 from "@angular/platform-browser"; const JSONP_HANDLER_NAME = '__ant_icon_load'; export const ANT_ICONS = new InjectionToken('ant_icons'); class IconService { set twoToneColor({ primaryColor, secondaryColor }) { this._twoToneColorPalette.primaryColor = primaryColor; this._twoToneColorPalette.secondaryColor = secondaryColor || getSecondaryColor(primaryColor); } get twoToneColor() { // Make a copy to avoid unexpected changes. return { ...this._twoToneColorPalette }; } /** * Disable dynamic loading (support static loading only). */ get _disableDynamicLoading() { return false; } constructor(_rendererFactory, _handler, _document, sanitizer, _antIcons) { this._rendererFactory = _rendererFactory; this._handler = _handler; this._document = _document; this.sanitizer = sanitizer; this._antIcons = _antIcons; this.defaultTheme = 'outline'; /** * All icon definitions would be registered here. */ this._svgDefinitions = new Map(); /** * Cache all rendered icons. Icons are identified by name, theme, * and for twotone icons, primary color and secondary color. */ this._svgRenderedDefinitions = new Map(); this._inProgressFetches = new Map(); /** * Url prefix for fetching inline SVG by dynamic importing. */ this._assetsUrlRoot = ''; this._twoToneColorPalette = { primaryColor: '#333333', secondaryColor: '#E6E6E6' }; /** A flag indicates whether jsonp loading is enabled. */ this._enableJsonpLoading = false; this._jsonpIconLoad$ = new Subject(); this._renderer = this._rendererFactory.createRenderer(null, null); if (this._handler) { this._http = new HttpClient(this._handler); } if (this._antIcons) { this.addIcon(...this._antIcons); } } /** * Call this method to switch to jsonp like loading. */ useJsonpLoading() { if (!this._enableJsonpLoading) { this._enableJsonpLoading = true; window[JSONP_HANDLER_NAME] = (icon) => { this._jsonpIconLoad$.next(icon); }; } else { warn('You are already using jsonp loading.'); } } /** * Change the prefix of the inline svg resources, so they could be deployed elsewhere, like CDN. * @param prefix */ changeAssetsSource(prefix) { this._assetsUrlRoot = prefix.endsWith('/') ? prefix : prefix + '/'; } /** * Add icons provided by ant design. * @param icons */ addIcon(...icons) { icons.forEach(icon => { this._svgDefinitions.set(withSuffix(icon.name, icon.theme), icon); }); } /** * Register an icon. Namespace is required. * @param type * @param literal */ addIconLiteral(type, literal) { const [_, namespace] = getNameAndNamespace(type); if (!namespace) { throw NameSpaceIsNotSpecifyError(); } this.addIcon({ name: type, icon: literal }); } /** * Remove all cache. */ clear() { this._svgDefinitions.clear(); this._svgRenderedDefinitions.clear(); } /** * Get a rendered `SVGElement`. * @param icon * @param twoToneColor */ getRenderedContent(icon, twoToneColor) { // If `icon` is a `IconDefinition`, go to the next step. If not, try to fetch it from cache. const definition = isIconDefinition(icon) ? icon : this._svgDefinitions.get(icon) || null; if (!definition && this._disableDynamicLoading) { throw IconNotFoundError(icon); } // If `icon` is a `IconDefinition` of successfully fetch, wrap it in an `Observable`. // Otherwise try to fetch it from remote. const $iconDefinition = definition ? of(definition) : this._loadIconDynamically(icon); // If finally get an `IconDefinition`, render and return it. Otherwise throw an error. return $iconDefinition.pipe(map(i => { if (!i) { throw IconNotFoundError(icon); } return this._loadSVGFromCacheOrCreateNew(i, twoToneColor); })); } getCachedIcons() { return this._svgDefinitions; } /** * Get raw svg and assemble a `IconDefinition` object. * @param type */ _loadIconDynamically(type) { // If developer doesn't provide HTTP module nor enable jsonp loading, just throw an error. if (!this._http && !this._enableJsonpLoading) { return of(HttpModuleNotImport()); } // If multi directive ask for the same icon at the same time, // request should only be fired once. let inProgress = this._inProgressFetches.get(type); if (!inProgress) { const [name, namespace] = getNameAndNamespace(type); // If the string has a namespace within, create a simple `IconDefinition`. const icon = namespace ? { name: type, icon: '' } : getIconDefinitionFromAbbr(name); const suffix = this._enableJsonpLoading ? '.js' : '.svg'; const url = (namespace ? `${this._assetsUrlRoot}assets/${namespace}/${name}` : `${this._assetsUrlRoot}assets/${icon.theme}/${icon.name}`) + suffix; const safeUrl = this.sanitizer.sanitize(SecurityContext.URL, url); if (!safeUrl) { throw UrlNotSafeError(url); } const source = !this._enableJsonpLoading ? this._http .get(safeUrl, { responseType: 'text' }) .pipe(map(literal => ({ ...icon, icon: literal }))) : this._loadIconDynamicallyWithJsonp(icon, safeUrl); inProgress = source.pipe(tap(definition => this.addIcon(definition)), finalize(() => this._inProgressFetches.delete(type)), catchError(() => of(null)), share()); this._inProgressFetches.set(type, inProgress); } return inProgress; } _loadIconDynamicallyWithJsonp(icon, url) { return new Observable(subscriber => { const loader = this._document.createElement('script'); const timer = setTimeout(() => { clean(); subscriber.error(DynamicLoadingTimeoutError()); }, 6000); loader.src = url; function clean() { loader.parentNode.removeChild(loader); clearTimeout(timer); } this._document.body.appendChild(loader); this._jsonpIconLoad$ .pipe(filter(i => i.name === icon.name && i.theme === icon.theme), take(1)) .subscribe(i => { subscriber.next(i); clean(); }); }); } /** * Render a new `SVGElement` for a given `IconDefinition`, or make a copy from cache. * @param icon * @param twoToneColor */ _loadSVGFromCacheOrCreateNew(icon, twoToneColor) { let svg; const pri = twoToneColor || this._twoToneColorPalette.primaryColor; const sec = getSecondaryColor(pri) || this._twoToneColorPalette.secondaryColor; const key = icon.theme === 'twotone' ? withSuffixAndColor(icon.name, icon.theme, pri, sec) : icon.theme === undefined ? icon.name : withSuffix(icon.name, icon.theme); // Try to make a copy from cache. const cached = this._svgRenderedDefinitions.get(key); if (cached) { svg = cached.icon; } else { svg = this._setSVGAttribute(this._colorizeSVGIcon( // Icons provided by ant design should be refined to remove preset colors. this._createSVGElementFromString(hasNamespace(icon.name) ? icon.icon : replaceFillColor(icon.icon)), icon.theme === 'twotone', pri, sec)); // Cache it. this._svgRenderedDefinitions.set(key, { ...icon, icon: svg }); } return cloneSVG(svg); } _createSVGElementFromString(str) { const div = this._document.createElement('div'); div.innerHTML = str; const svg = div.querySelector('svg'); if (!svg) { throw SVGTagNotFoundError; } return svg; } _setSVGAttribute(svg) { this._renderer.setAttribute(svg, 'width', '1em'); this._renderer.setAttribute(svg, 'height', '1em'); return svg; } _colorizeSVGIcon(svg, twotone, pri, sec) { if (twotone) { const children = svg.childNodes; const length = children.length; for (let i = 0; i < length; i++) { const child = children[i]; if (child.getAttribute('fill') === 'secondaryColor') { this._renderer.setAttribute(child, 'fill', sec); } else { this._renderer.setAttribute(child, 'fill', pri); } } } this._renderer.setAttribute(svg, 'fill', 'currentColor'); return svg; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.2", ngImport: i0, type: IconService, deps: [{ token: i0.RendererFactory2 }, { token: i1.HttpBackend, optional: true }, { token: DOCUMENT, optional: true }, { token: i2.DomSanitizer }, { token: ANT_ICONS, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.2", ngImport: i0, type: IconService }); } } export { IconService }; i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.2", ngImport: i0, type: IconService, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: i0.RendererFactory2 }, { type: i1.HttpBackend, decorators: [{ type: Optional }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [DOCUMENT] }] }, { type: i2.DomSanitizer }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [ANT_ICONS] }] }]; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaWNvbi5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudC9pY29uLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNDLE9BQU8sRUFBZSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUMvRCxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxjQUFjLEVBQUUsUUFBUSxFQUErQixlQUFlLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFM0gsT0FBTyxFQUFFLEVBQUUsRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9DLE9BQU8sRUFDTCxVQUFVLEVBQ1YsTUFBTSxFQUNOLFFBQVEsRUFDUixHQUFHLEVBQ0gsS0FBSyxFQUNMLElBQUksRUFDSixHQUFHLEVBQ0osTUFBTSxnQkFBZ0IsQ0FBQztBQVF4QixPQUFPLEVBQ0wsUUFBUSxFQUNSLHlCQUF5QixFQUN6QixtQkFBbUIsRUFDbkIsaUJBQWlCLEVBQ2pCLFlBQVksRUFDWixnQkFBZ0IsRUFDaEIsZ0JBQWdCLEVBQ2hCLElBQUksRUFDSixVQUFVLEVBQ1Ysa0JBQWtCLEVBQ25CLE1BQU0sVUFBVSxDQUFDO0FBQ2xCLE9BQU8sRUFDTCwwQkFBMEIsRUFDMUIsbUJBQW1CLEVBQ25CLGlCQUFpQixFQUNqQiwwQkFBMEIsRUFDMUIsbUJBQW1CLEVBQ25CLGVBQWUsRUFDaEIsTUFBTSxjQUFjLENBQUM7Ozs7QUFFdEIsTUFBTSxrQkFBa0IsR0FBRyxpQkFBaUIsQ0FBQztBQUU3QyxNQUFNLENBQUMsTUFBTSxTQUFTLEdBQUcsSUFBSSxjQUFjLENBQW1CLFdBQVcsQ0FBQyxDQUFDO0FBRTNFLE1BQ2EsV0FBVztJQUd0QixJQUFJLFlBQVksQ0FBQyxFQUNmLFlBQVksRUFDWixjQUFjLEVBQ1k7UUFDMUIsSUFBSSxDQUFDLG9C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SUFBSSxDQUFDLFNBQVMsQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQztpQkFDakQ7YUFDRjtTQUNGO1FBQ0QsSUFBSSxDQUFDLFNBQVMsQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxjQUFjLENBQUMsQ0FBQztRQUN6RCxPQUFPLEdBQUcsQ0FBQztJQUNiLENBQUM7OEdBaFZVLFdBQVcsNkZBNERBLFFBQVEseURBR1IsU0FBUztrSEEvRHBCLFdBQVc7O1NBQVgsV0FBVzsyRkFBWCxXQUFXO2tCQUR2QixVQUFVOzswQkE0RE4sUUFBUTs7MEJBQ1IsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyxRQUFROzswQkFHM0IsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyxTQUFTIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgSHR0cEJhY2tlbmQsIEh0dHBDbGllbnQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUsIEluamVjdGlvblRva2VuLCBPcHRpb25hbCwgUmVuZGVyZXIyLCBSZW5kZXJlckZhY3RvcnkyLCBTZWN1cml0eUNvbnRleHQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IERvbVNhbml0aXplciB9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXInO1xuaW1wb3J0IHsgb2YsIE9ic2VydmFibGUsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7XG4gIGNhdGNoRXJyb3IsXG4gIGZpbHRlcixcbiAgZmluYWxpemUsXG4gIG1hcCxcbiAgc2hhcmUsXG4gIHRha2UsXG4gIHRhcFxufSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQge1xuICBDYWNoZWRJY29uRGVmaW5pdGlvbixcbiAgSWNvbkRlZmluaXRpb24sXG4gIFRoZW1lVHlwZSxcbiAgVHdvVG9uZUNvbG9yUGFsZXR0ZSxcbiAgVHdvVG9uZUNvbG9yUGFsZXR0ZVNldHRlclxufSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQge1xuICBjbG9uZVNWRyxcbiAgZ2V0SWNvbkRlZmluaXRpb25Gcm9tQWJicixcbiAgZ2V0TmFtZUFuZE5hbWVzcGFjZSxcbiAgZ2V0U2Vjb25kYXJ5Q29sb3IsXG4gIGhhc05hbWVzcGFjZSxcbiAgaXNJY29uRGVmaW5pdGlvbixcbiAgcmVwbGFjZUZpbGxDb2xvcixcbiAgd2FybixcbiAgd2l0aFN1ZmZpeCxcbiAgd2l0aFN1ZmZpeEFuZENvbG9yXG59IGZyb20gJy4uL3V0aWxzJztcbmltcG9ydCB7XG4gIER5bmFtaWNMb2FkaW5nVGltZW91dEVycm9yLFxuICBIdHRwTW9kdWxlTm90SW1wb3J0LFxuICBJY29uTm90Rm91bmRFcnJvcixcbiAgTmFtZVNwYWNlSXNOb3RTcGVjaWZ5RXJyb3IsXG4gIFNWR1RhZ05vdEZvdW5kRXJyb3IsXG4gIFVybE5vdFNhZmVFcnJvclxufSBmcm9tICcuL2ljb24uZXJyb3InO1xuXG5jb25zdCBKU09OUF9IQU5ETEVSX05BTUUgPSAnX19hbnRfaWNvbl9sb2FkJztcblxuZXhwb3J0IGNvbnN0IEFOVF9JQ09OUyA9IG5ldyBJbmplY3Rpb25Ub2tlbjxJY29uRGVmaW5pdGlvbltdPignYW50X2ljb25zJyk7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBJY29uU2VydmljZSB7XG4gIGRlZmF1bHRUaGVtZTogVGhlbWVUeXBlID0gJ291dGxpbmUnO1xuXG4gIHNldCB0d29Ub25lQ29sb3Ioe1xuICAgIHByaW1hcnlDb2xvcixcbiAgICBzZWNvbmRhcnlDb2xvclxuICB9OiBUd29Ub25lQ29sb3JQYWxldHRlU2V0dGVyKSB7XG4gICAgdGhpcy5fdHdvVG9uZUNvbG9yUGFsZXR0ZS5wcmltYXJ5Q29sb3IgPSBwcmltYXJ5Q29sb3I7XG4gICAgdGhpcy5fdHdvVG9uZUNvbG9yUGFsZXR0ZS5zZWNvbmRhcnlDb2xvciA9XG4gICAgICBzZWNvbmRhcnlDb2xvciB8fCBnZXRTZWNvbmRhcnlDb2xvcihwcmltYXJ5Q29sb3IpO1xuICB9XG5cbiAgZ2V0IHR3b1RvbmVDb2xvcigpOiBUd29Ub25lQ29sb3JQYWxldHRlU2V0dGVyIHtcbiAgICAvLyBNYWtlIGEgY29weSB0byBhdm9pZCB1bmV4cGVjdGVkIGNoYW5nZXMuXG4gICAgcmV0dXJuIHsgLi4udGhpcy5fdHdvVG9uZUNvbG9yUGFsZXR0ZSB9IGFzIFR3b1RvbmVDb2xvclBhbGV0dGU7XG4gIH1cblxuICBwcm90ZWN0ZWQgX3JlbmRlcmVyOiBSZW5kZXJlcjI7XG4gIHByb3RlY3RlZCBfaHR0cDogSHR0cENsaWVudDtcblxuICAvKipcbiAgICogRGlzYWJsZSBkeW5hbWljIGxvYWRpbmcgKHN1cHBvcnQgc3RhdGljIGxvYWRpbmcgb25seSkuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0IF9kaXNhYmxlRHluYW1pY0xvYWRpbmcoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEFsbCBpY29uIGRlZmluaXRpb25zIHdvdWxkIGJlIHJlZ2lzdGVyZWQgaGVyZS5cbiAgICovXG4gIHByb3RlY3RlZCByZWFkb25seSBfc3ZnRGVmaW5pdGlvbnMgPSBuZXcgTWFwPHN0cmluZywgSWNvbkRlZmluaXRpb24+KCk7XG5cbiAgLyoqXG4gICAqIENhY2hlIGFsbCByZW5kZXJlZCBpY29ucy4gSWNvbnMgYXJlIGlkZW50aWZpZWQgYnkgbmFtZSwgdGhlbWUsXG4gICAqIGFuZCBmb3IgdHdvdG9uZSBpY29ucywgcHJpbWFyeSBjb2xvciBhbmQgc2Vjb25kYXJ5IGNvbG9yLlxuICAgKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IF9zdmdSZW5kZXJlZERlZmluaXRpb25zID0gbmV3IE1hcDxzdHJpbmcsIENhY2hlZEljb25EZWZpbml0aW9uPigpO1xuXG4gIHByb3RlY3RlZCBfaW5Qcm9ncmVzc0ZldGNoZXMgPSBuZXcgTWFwPFxuICAgIHN0cmluZyxcbiAgICBPYnNlcnZhYmxlPEljb25EZWZpbml0aW9uIHwgbnVsbD5cbiAgPigpO1xuXG4gIC8qKlxuICAgKiBVcmwgcHJlZml4IGZvciBmZXRjaGluZyBpbmxpbmUgU1ZHIGJ5IGR5bmFtaWMgaW1wb3J0aW5nLlxuICAgKi9cbiAgcHJvdGVjdGVkIF9hc3NldHNVcmxSb290ID0gJyc7XG5cbiAgcHJvdGVjdGVkIF90d29Ub25lQ29sb3JQYWxldHRlOiBUd29Ub25lQ29sb3JQYWxldHRlID0ge1xuICAgIHByaW1hcnlDb2xvcjogJyMzMzMzMzMnLFxuICAgIHNlY29uZGFyeUNvbG9yOiAnI0U2RTZFNidcbiAgfTtcblxuICAvKiogQSBmbGFnIGluZGljYXRlcyB3aGV0aGVyIGpzb25wIGxvYWRpbmcgaXMgZW5hYmxlZC4gKi9cbiAgcHJpdmF0ZSBfZW5hYmxlSnNvbnBMb2FkaW5nID0gZmFsc2U7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2pzb25wSWNvbkxvYWQkID0gbmV3IFN1YmplY3Q8SWNvbkRlZmluaXRpb24+KCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIF9yZW5kZXJlckZhY3Rvcnk6IFJlbmRlcmVyRmFjdG9yeTIsXG4gICAgQE9wdGlvbmFsKCkgcHJvdGVjdGVkIF9oYW5kbGVyOiBIdHRwQmFja2VuZCxcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KERPQ1VNRU5UKSBwcm90ZWN0ZWQgX2RvY3VtZW50OiBhbnksXG4gICAgcHJvdGVjdGVkIHNhbml0aXplcjogRG9tU2FuaXRpemVyLFxuXG4gICAgQE9wdGlvbmFsKCkgQEluamVjdChBTlRfSUNPTlMpIHByb3RlY3RlZCBfYW50SWNvbnM6IEljb25EZWZpbml0aW9uW11cbiAgKSB7XG4gICAgdGhpcy5fcmVuZGVyZXIgPSB0aGlzLl9yZW5kZXJlckZhY3RvcnkuY3JlYXRlUmVuZGVyZXIobnVsbCwgbnVsbCk7XG5cbiAgICBpZiAodGhpcy5faGFuZGxlcikge1xuICAgICAgdGhpcy5faHR0cCA9IG5ldyBIdHRwQ2xpZW50KHRoaXMuX2hhbmRsZXIpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9hbnRJY29ucykge1xuICAgICAgdGhpcy5hZGRJY29uKC4uLnRoaXMuX2FudEljb25zKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2FsbCB0aGlzIG1ldGhvZCB0byBzd2l0Y2ggdG8ganNvbnAgbGlrZSBsb2FkaW5nLlxuICAgKi9cbiAgdXNlSnNvbnBMb2FkaW5nKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5fZW5hYmxlSnNvbnBMb2FkaW5nKSB7XG4gICAgICB0aGlzLl9lbmFibGVKc29ucExvYWRpbmcgPSB0cnVlO1xuXG4gICAgICB3aW5kb3dbSlNPTlBfSEFORExFUl9OQU1FXSA9IChpY29uOiBJY29uRGVmaW5pdGlvbikgPT4ge1xuICAgICAgICB0aGlzLl9qc29ucEljb25Mb2FkJC5uZXh0KGljb24pO1xuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgd2FybignWW91IGFyZSBhbHJlYWR5IHVzaW5nIGpzb25wIGxvYWRpbmcuJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENoYW5nZSB0aGUgcHJlZml4IG9mIHRoZSBpbmxpbmUgc3ZnIHJlc291cmNlcywgc28gdGhleSBjb3VsZCBiZSBkZXBsb3llZCBlbHNld2hlcmUsIGxpa2UgQ0ROLlxuICAgKiBAcGFyYW0gcHJlZml4XG4gICAqL1xuICBjaGFuZ2VBc3NldHNTb3VyY2UocHJlZml4OiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLl9hc3NldHNVcmxSb290ID0gcHJlZml4LmVuZHNXaXRoKCcvJykgPyBwcmVmaXggOiBwcmVmaXggKyAnLyc7XG4gIH1cblxuICAvKipcbiAgICogQWRkIGljb25zIHByb3ZpZGVkIGJ5IGFudCBkZXNpZ24uXG4gICAqIEBwYXJhbSBpY29uc1xuICAgKi9cbiAgYWRkSWNvbiguLi5pY29uczogSWNvbkRlZmluaXRpb25bXSk6IHZvaWQge1xuICAgIGljb25zLmZvckVhY2goaWNvbiA9PiB7XG4gICAgICB0aGlzLl9zdmdEZWZpbml0aW9ucy5zZXQod2l0aFN1ZmZpeChpY29uLm5hbWUsIGljb24udGhlbWUpLCBpY29uKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlciBhbiBpY29uLiBOYW1lc3BhY2UgaXMgcmVxdWlyZWQuXG4gICAqIEBwYXJhbSB0eXBlXG4gICAqIEBwYXJhbSBsaXRlcmFsXG4gICAqL1xuICBhZGRJY29uTGl0ZXJhbCh0eXBlOiBzdHJpbmcsIGxpdGVyYWw6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IFtfLCBuYW1lc3BhY2VdID0gZ2V0TmFtZUFuZE5hbWVzcGFjZSh0eXBlKTtcbiAgICBpZiAoIW5hbWVzcGFjZSkge1xuICAgICAgdGhyb3cgTmFtZVNwYWNlSXNOb3RTcGVjaWZ5RXJyb3IoKTtcbiAgICB9XG4gICAgdGhpcy5hZGRJY29uKHsgbmFtZTogdHlwZSwgaWNvbjogbGl0ZXJhbCB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgYWxsIGNhY2hlLlxuICAgKi9cbiAgY2xlYXIoKTogdm9pZCB7XG4gICAgdGhpcy5fc3ZnRGVmaW5pdGlvbnMuY2xlYXIoKTtcbiAgICB0aGlzLl9zdmdSZW5kZXJlZERlZmluaXRpb25zLmNsZWFyKCk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGEgcmVuZGVyZWQgYFNWR0VsZW1lbnRgLlxuICAgKiBAcGFyYW0gaWNvblxuICAgKiBAcGFyYW0gdHdvVG9uZUNvbG9yXG4gICAqL1xuICBnZXRSZW5kZXJlZENvbnRlbnQoXG4gICAgaWNvbjogSWNvbkRlZmluaXRpb24gfCBzdHJpbmcsXG4gICAgdHdvVG9uZUNvbG9yPzogc3RyaW5nXG4gICk6IE9ic2VydmFibGU8U1ZHRWxlbWVudD4ge1xuICAgIC8vIElmIGBpY29uYCBpcyBhIGBJY29uRGVmaW5pdGlvbmAsIGdvIHRvIHRoZSBuZXh0IHN0ZXAuIElmIG5vdCwgdHJ5IHRvIGZldGNoIGl0IGZyb20gY2FjaGUuXG4gICAgY29uc3QgZGVmaW5pdGlvbjogSWNvbkRlZmluaXRpb24gfCBudWxsID0gaXNJY29uRGVmaW5pdGlvbihpY29uKVxuICAgICAgPyAoaWNvbiBhcyBJY29uRGVmaW5pdGlvbilcbiAgICAgIDogdGhpcy5fc3ZnRGVmaW5pdGlvbnMuZ2V0KGljb24pIHx8IG51bGw7XG4gICAgXG4gICAgaWYgKCFkZWZpbml0aW9uICYmIHRoaXMuX2Rpc2FibGVEeW5hbWljTG9hZGluZykge1xuICAgICAgdGhyb3cgSWNvbk5vdEZvdW5kRXJyb3IoaWNvbiBhcyBzdHJpbmcpO1xuICAgIH1cblxuICAgIC8vIElmIGBpY29uYCBpcyBhIGBJY29uRGVmaW5pdGlvbmAgb2Ygc3VjY2Vzc2Z1bGx5IGZldGNoLCB3cmFwIGl0IGluIGFuIGBPYnNlcnZhYmxlYC5cbiAgICAvLyBPdGhlcndpc2UgdHJ5IHRvIGZldGNoIGl0IGZyb20gcmVtb3RlLlxuICAgIGNvbnN0ICRpY29uRGVmaW5pdGlvbiA9IGRlZmluaXRpb25cbiAgICAgID8gb2YoZGVmaW5pdGlvbilcbiAgICAgIDogdGhpcy5fbG9hZEljb25EeW5hbWljYWxseShpY29uIGFzIHN0cmluZyk7XG5cbiAgICAvLyBJZiBmaW5hbGx5IGdldCBhbiBgSWNvbkRlZmluaXRpb25gLCByZW5kZXIgYW5kIHJldHVybiBpdC4gT3RoZXJ3aXNlIHRocm93IGFuIGVycm9yLlxuICAgIHJldHVybiAkaWNvbkRlZmluaXRpb24ucGlwZShcbiAgICAgIG1hcChpID0+IHtcbiAgICAgICAgaWYgKCFpKSB7XG4gICAgICAgICAgdGhyb3cgSWNvbk5vdEZvdW5kRXJyb3IoaWNvbiBhcyBzdHJpbmcpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9sb2FkU1ZHRnJvbUNhY2hlT3JDcmVhdGVOZXcoaSwgdHdvVG9uZUNvbG9yKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIGdldENhY2hlZEljb25zKCk6IE1hcDxzdHJpbmcsIEljb25EZWZpbml0aW9uPiB7XG4gICAgcmV0dXJuIHRoaXMuX3N2Z0RlZmluaXRpb25zO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCByYXcgc3ZnIGFuZCBhc3NlbWJsZSBhIGBJY29uRGVmaW5pdGlvbmAgb2JqZWN0LlxuICAgKiBAcGFyYW0gdHlwZVxuICAgKi9cbiAgcHJvdGVjdGVkIF9sb2FkSWNvbkR5bmFtaWNhbGx5KFxuICAgIHR5cGU6IHN0cmluZ1xuICApOiBPYnNlcnZhYmxlPEljb25EZWZpbml0aW9uIHwgbnVsbD4ge1xuICAgIC8vIElmIGRldmVsb3BlciBkb2Vzbid0IHByb3ZpZGUgSFRUUCBtb2R1bGUgbm9yIGVuYWJsZSBqc29ucCBsb2FkaW5nLCBqdXN0IHRocm93IGFuIGVycm9yLlxuICAgIGlmICghdGhpcy5faHR0cCAmJiAhdGhpcy5fZW5hYmxlSnNvbnBMb2FkaW5nKSB7XG4gICAgICByZXR1cm4gb2YoSHR0cE1vZHVsZU5vdEltcG9ydCgpKTtcbiAgICB9XG5cbiAgICAvLyBJZiBtdWx0aSBkaXJlY3RpdmUgYXNrIGZvciB0aGUgc2FtZSBpY29uIGF0IHRoZSBzYW1lIHRpbWUsXG4gICAgLy8gcmVxdWVzdCBzaG91bGQgb25seSBiZSBmaXJlZCBvbmNlLlxuICAgIGxldCBpblByb2dyZXNzID0gdGhpcy5faW5Qcm9ncmVzc0ZldGNoZXMuZ2V0KHR5cGUpO1xuXG4gICAgaWYgKCFpblByb2dyZXNzKSB7XG4gICAgICBjb25zdCBbbmFtZSwgbmFtZXNwYWNlXSA9IGdldE5hbWVBbmROYW1lc3BhY2UodHlwZSk7XG5cbiAgICAgIC8vIElmIHRoZSBzdHJpbmcgaGFzIGEgbmFtZXNwYWNlIHdpdGhpbiwgY3JlYXRlIGEgc2ltcGxlIGBJY29uRGVmaW5pdGlvbmAuXG4gICAgICBjb25zdCBpY29uOiBJY29uRGVmaW5pdGlvbiA9IG5hbWVzcGFjZVxuICAgICAgICA/IHsgbmFtZTogdHlwZSwgaWNvbjogJycgfVxuICAgICAgICA6IGdldEljb25EZWZpbml0aW9uRnJvbUFiYnIobmFtZSk7XG5cbiAgICAgIGNvbnN0IHN1ZmZpeCA9IHRoaXMuX2VuYWJsZUpzb25wTG9hZGluZyA/ICcuanMnIDogJy5zdmcnO1xuICAgICAgY29uc3QgdXJsID1cbiAgICAgICAgKG5hbWVzcGFjZVxuICAgICAgICAgID8gYCR7dGhpcy5fYXNzZXRzVXJsUm9vdH1hc3NldHMvJHtuYW1lc3BhY2V9LyR7bmFtZX1gXG4gICAgICAgICAgOiBgJHt0aGlzLl9hc3NldHNVcmxSb290fWFzc2V0cy8ke2ljb24udGhlbWV9LyR7aWNvbi5uYW1lfWApICsgc3VmZml4O1xuXG4gICAgICBjb25zdCBzYWZlVXJsID0gdGhpcy5zYW5pdGl6ZXIuc2FuaXRpemUoU2VjdXJpdHlDb250ZXh0LlVSTCwgdXJsKTtcblxuICAgICAgaWYgKCFzYWZlVXJsKSB7XG4gICAgICAgIHRocm93IFVybE5vdFNhZmVFcnJvcih1cmwpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzb3VyY2UgPSAhdGhpcy5fZW5hYmxlSnNvbnBMb2FkaW5nXG4gICAgICAgID8gdGhpcy5faHR0cFxuICAgICAgICAgICAgLmdldChzYWZlVXJsLCB7IHJlc3BvbnNlVHlwZTogJ3RleHQnIH0pXG4gICAgICAgICAgICAucGlwZShtYXAobGl0ZXJhbCA9PiAoeyAuLi5pY29uLCBpY29uOiBsaXRlcmFsIH0pKSlcbiAgICAgICAgOiB0aGlzLl9sb2FkSWNvbkR5bmFtaWNhbGx5V2l0aEpzb25wKGljb24sIHNhZmVVcmwpO1xuXG4gICAgICBpblByb2dyZXNzID0gc291cmNlLnBpcGUoXG4gICAgICAgIHRhcChkZWZpbml0aW9uID0+IHRoaXMuYWRkSWNvbihkZWZpbml0aW9uKSksXG4gICAgICAgIGZpbmFsaXplKCgpID0+IHRoaXMuX2luUHJvZ3Jlc3NGZXRjaGVzLmRlbGV0ZSh0eXBlKSksXG4gICAgICAgIGNhdGNoRXJyb3IoKCkgPT4gb2YobnVsbCkpLFxuICAgICAgICBzaGFyZSgpXG4gICAgICApO1xuXG4gICAgICB0aGlzLl9pblByb2dyZXNzRmV0Y2hlcy5zZXQodHlwZSwgaW5Qcm9ncmVzcyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGluUHJvZ3Jlc3M7XG4gIH1cblxuICBwcm90ZWN0ZWQgX2xvYWRJY29uRHluYW1pY2FsbHlXaXRoSnNvbnAoaWNvbjogSWNvbkRlZmluaXRpb24sIHVybDogc3RyaW5nKTogT2JzZXJ2YWJsZTxJY29uRGVmaW5pdGlvbj4ge1xuICAgIHJldHVybiBuZXcgT2JzZXJ2YWJsZTxJY29uRGVmaW5pdGlvbj4oc3Vic2NyaWJlciA9PiB7XG4gICAgICBjb25zdCBsb2FkZXIgPSB0aGlzLl9kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtcbiAgICAgIGNvbnN0IHRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGNsZWFuKCk7XG4gICAgICAgIHN1YnNjcmliZXIuZXJyb3IoRHluYW1pY0xvYWRpbmdUaW1lb3V0RXJyb3IoKSk7XG4gICAgICB9LCA2MDAwKTtcblxuICAgICAgbG9hZGVyLnNyYyA9IHVybDtcblxuICAgICAgZnVuY3Rpb24gY2xlYW4oKTogdm9pZCB7XG4gICAgICAgIGxvYWRlci5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGxvYWRlcik7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX2RvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQobG9hZGVyKTtcbiAgICAgIHRoaXMuX2pzb25wSWNvbkxvYWQkXG4gICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgIGZpbHRlcihpID0+IGkubmFtZSA9PT0gaWNvbi5uYW1lICYmIGkudGhlbWUgPT09IGljb24udGhlbWUpLFxuICAgICAgICAgICAgICB0YWtlKDEpXG4gICAgICAgICAgKVxuICAgICAgICAgIC5zdWJzY3JpYmUoaSA9PiB7XG4gICAgICAgICAgICBzdWJzY3JpYmVyLm5leHQoaSk7XG4gICAgICAgICAgICBjbGVhbigpO1xuICAgICAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbmRlciBhIG5ldyBgU1ZHRWxlbWVudGAgZm9yIGEgZ2l2ZW4gYEljb25EZWZpbml0aW9uYCwgb3IgbWFrZSBhIGNvcHkgZnJvbSBjYWNoZS5cbiAgICogQHBhcmFtIGljb25cbiAgICogQHBhcmFtIHR3b1RvbmVDb2xvclxuICAgKi9cbiAgcHJvdGVjdGVkIF9sb2FkU1ZHRnJvbUNhY2hlT3JDcmVhdGVOZXcoXG4gICAgaWNvbjogSWNvbkRlZmluaXRpb24sXG4gICAgdHdvVG9uZUNvbG9yPzogc3RyaW5nXG4gICk6IFNWR0VsZW1lbnQge1xuICAgIGxldCBzdmc6IFNWR0VsZW1lbnQ7XG5cbiAgICBjb25zdCBwcmkgPSB0d29Ub25lQ29sb3IgfHwgdGhpcy5fdHdvVG9uZUNvbG9yUGFsZXR0ZS5wcmltYXJ5Q29sb3I7XG4gICAgY29uc3Qgc2VjID1cbiAgICAgIGdldFNlY29uZGFyeUNvbG9yKHByaSkgfHwgdGhpcy5fdHdvVG9uZUNvbG9yUGFsZXR0ZS5zZWNvbmRhcnlDb2xvcjtcbiAgICBjb25zdCBrZXkgPVxuICAgICAgaWNvbi50aGVtZSA9PT0gJ3R3b3RvbmUnXG4gICAgICAgID8gd2l0aFN1ZmZpeEFuZENvbG9yKGljb24ubmFtZSwgaWNvbi50aGVtZSwgcHJpLCBzZWMpXG4gICAgICAgIDogaWNvbi50aGVtZSA9PT0gdW5kZWZpbmVkXG4gICAgICAgID8gaWNvbi5uYW1lXG4gICAgICAgIDogd2l0aFN1ZmZpeChpY29uLm5hbWUsIGljb24udGhlbWUpO1xuXG4gICAgLy8gVHJ5IHRvIG1ha2UgYSBjb3B5IGZyb20gY2FjaGUuXG4gICAgY29uc3QgY2FjaGVkID0gdGhpcy5fc3ZnUmVuZGVyZWREZWZpbml0aW9ucy5nZXQoa2V5KTtcblxuICAgIGlmIChjYWNoZWQpIHtcbiAgICAgIHN2ZyA9IGNhY2hlZC5pY29uO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdmcgPSB0aGlzLl9zZXRTVkdBdHRyaWJ1dGUoXG4gICAgICAgIHRoaXMuX2NvbG9yaXplU1ZHSWNvbihcbiAgICAgICAgICAvLyBJY29ucyBwcm92aWRlZCBieSBhbnQgZGVzaWduIHNob3VsZCBiZSByZWZpbmVkIHRvIHJlbW92ZSBwcmVzZXQgY29sb3JzLlxuICAgICAgICAgIHRoaXMuX2NyZWF0ZVNWR0VsZW1lbnRGcm9tU3RyaW5nKFxuICAgICAgICAgICAgaGFzTmFtZXNwYWNlKGljb24ubmFtZSkgPyBpY29uLmljb24gOiByZXBsYWNlRmlsbENvbG9yKGljb24uaWNvbilcbiAgICAgICAgICApLFxuICAgICAgICAgIGljb24udGhlbWUgPT09ICd0d290b25lJyxcbiAgICAgICAgICBwcmksXG4gICAgICAgICAgc2VjXG4gICAgICAgIClcbiAgICAgICk7XG4gICAgICAvLyBDYWNoZSBpdC5cbiAgICAgIHRoaXMuX3N2Z1JlbmRlcmVkRGVmaW5pdGlvbnMuc2V0KGtleSwge1xuICAgICAgICAuLi5pY29uLFxuICAgICAgICBpY29uOiBzdmdcbiAgICAgIH0gYXMgQ2FjaGVkSWNvbkRlZmluaXRpb24pO1xuICAgIH1cblxuICAgIHJldHVybiBjbG9uZVNWRyhzdmcpO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9jcmVhdGVTVkdFbGVtZW50RnJvbVN0cmluZyhzdHI6IHN0cmluZyk6IFNWR0VsZW1lbnQge1xuICAgIGNvbnN0IGRpdiA9IHRoaXMuX2RvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGRpdi5pbm5lckhUTUwgPSBzdHI7XG4gICAgY29uc3Qgc3ZnOiBTVkdFbGVtZW50ID0gZGl2LnF1ZXJ5U2VsZWN0b3IoJ3N2ZycpO1xuICAgIGlmICghc3ZnKSB7XG4gICAgICB0aHJvdyBTVkdUYWdOb3RGb3VuZEVycm9yO1xuICAgIH1cbiAgICByZXR1cm4gc3ZnO1xuICB9XG5cbiAgcHJvdGVjdGVkIF9zZXRTVkdBdHRyaWJ1dGUoc3ZnOiBTVkdFbGVtZW50KTogU1ZHRWxlbWVudCB7XG4gICAgdGhpcy5fcmVuZGVyZXIuc2V0QXR0cmlidXRlKHN2ZywgJ3dpZHRoJywgJzFlbScpO1xuICAgIHRoaXMuX3JlbmRlcmVyLnNldEF0dHJpYnV0ZShzdmcsICdoZWlnaHQnLCAnMWVtJyk7XG4gICAgcmV0dXJuIHN2ZztcbiAgfVxuXG4gIHByb3RlY3RlZCBfY29sb3JpemVTVkdJY29uKFxuICAgIHN2ZzogU1ZHRWxlbWVudCxcbiAgICB0d290b25lOiBib29sZWFuLFxuICAgIHByaTogc3RyaW5nLFxuICAgIHNlYzogc3RyaW5nXG4gICk6IFNWR0VsZW1lbnQge1xuICAgIGlmICh0d290b25lKSB7XG4gICAgICBjb25zdCBjaGlsZHJlbiA9IHN2Zy5jaGlsZE5vZGVzO1xuICAgICAgY29uc3QgbGVuZ3RoID0gY2hpbGRyZW4ubGVuZ3RoO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBjaGlsZDogSFRNTEVsZW1lbnQgPSBjaGlsZHJlbltpXSBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgaWYgKGNoaWxkLmdldEF0dHJpYnV0ZSgnZmlsbCcpID09PSAnc2Vjb25kYXJ5Q29sb3InKSB7XG4gICAgICAgICAgdGhpcy5fcmVuZGVyZXIuc2V0QXR0cmlidXRlKGNoaWxkLCAnZmlsbCcsIHNlYyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5fcmVuZGVyZXIuc2V0QXR0cmlidXRlKGNoaWxkLCAnZmlsbCcsIHByaSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5fcmVuZGVyZXIuc2V0QXR0cmlidXRlKHN2ZywgJ2ZpbGwnLCAnY3VycmVudENvbG9yJyk7XG4gICAgcmV0dXJuIHN2ZztcbiAgfVxufVxuIl19