You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
390 lines
52 KiB
390 lines
52 KiB
/**
|
|
* @license
|
|
* Copyright Google LLC All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.io/license
|
|
*/
|
|
import { coerceBooleanProperty } from '@angular/cdk/coercion';
|
|
import { DOCUMENT } from '@angular/common';
|
|
import { Attribute, ChangeDetectionStrategy, Component, ElementRef, ErrorHandler, inject, Inject, InjectionToken, Input, ViewEncapsulation, } from '@angular/core';
|
|
import { mixinColor } from '@angular/material/core';
|
|
import { Subscription } from 'rxjs';
|
|
import { take } from 'rxjs/operators';
|
|
import { MatIconRegistry } from './icon-registry';
|
|
// Boilerplate for applying mixins to MatIcon.
|
|
/** @docs-private */
|
|
import * as ɵngcc0 from '@angular/core';
|
|
import * as ɵngcc1 from './icon-registry';
|
|
|
|
const _c0 = ["*"];
|
|
const _MatIconBase = mixinColor(class {
|
|
constructor(_elementRef) {
|
|
this._elementRef = _elementRef;
|
|
}
|
|
});
|
|
/**
|
|
* Injection token used to provide the current location to `MatIcon`.
|
|
* Used to handle server-side rendering and to stub out during unit tests.
|
|
* @docs-private
|
|
*/
|
|
export const MAT_ICON_LOCATION = new InjectionToken('mat-icon-location', {
|
|
providedIn: 'root',
|
|
factory: MAT_ICON_LOCATION_FACTORY
|
|
});
|
|
/** @docs-private */
|
|
export function MAT_ICON_LOCATION_FACTORY() {
|
|
const _document = inject(DOCUMENT);
|
|
const _location = _document ? _document.location : null;
|
|
return {
|
|
// Note that this needs to be a function, rather than a property, because Angular
|
|
// will only resolve it once, but we want the current path on each call.
|
|
getPathname: () => _location ? (_location.pathname + _location.search) : ''
|
|
};
|
|
}
|
|
/** SVG attributes that accept a FuncIRI (e.g. `url(<something>)`). */
|
|
const funcIriAttributes = [
|
|
'clip-path',
|
|
'color-profile',
|
|
'src',
|
|
'cursor',
|
|
'fill',
|
|
'filter',
|
|
'marker',
|
|
'marker-start',
|
|
'marker-mid',
|
|
'marker-end',
|
|
'mask',
|
|
'stroke'
|
|
];
|
|
const ɵ0 = attr => `[${attr}]`;
|
|
/** Selector that can be used to find all elements that are using a `FuncIRI`. */
|
|
const funcIriAttributeSelector = funcIriAttributes.map(ɵ0).join(', ');
|
|
/** Regex that can be used to extract the id out of a FuncIRI. */
|
|
const funcIriPattern = /^url\(['"]?#(.*?)['"]?\)$/;
|
|
/**
|
|
* Component to display an icon. It can be used in the following ways:
|
|
*
|
|
* - Specify the svgIcon input to load an SVG icon from a URL previously registered with the
|
|
* addSvgIcon, addSvgIconInNamespace, addSvgIconSet, or addSvgIconSetInNamespace methods of
|
|
* MatIconRegistry. If the svgIcon value contains a colon it is assumed to be in the format
|
|
* "[namespace]:[name]", if not the value will be the name of an icon in the default namespace.
|
|
* Examples:
|
|
* `<mat-icon svgIcon="left-arrow"></mat-icon>
|
|
* <mat-icon svgIcon="animals:cat"></mat-icon>`
|
|
*
|
|
* - Use a font ligature as an icon by putting the ligature text in the content of the `<mat-icon>`
|
|
* component. By default the Material icons font is used as described at
|
|
* http://google.github.io/material-design-icons/#icon-font-for-the-web. You can specify an
|
|
* alternate font by setting the fontSet input to either the CSS class to apply to use the
|
|
* desired font, or to an alias previously registered with MatIconRegistry.registerFontClassAlias.
|
|
* Examples:
|
|
* `<mat-icon>home</mat-icon>
|
|
* <mat-icon fontSet="myfont">sun</mat-icon>`
|
|
*
|
|
* - Specify a font glyph to be included via CSS rules by setting the fontSet input to specify the
|
|
* font, and the fontIcon input to specify the icon. Typically the fontIcon will specify a
|
|
* CSS class which causes the glyph to be displayed via a :before selector, as in
|
|
* https://fortawesome.github.io/Font-Awesome/examples/
|
|
* Example:
|
|
* `<mat-icon fontSet="fa" fontIcon="alarm"></mat-icon>`
|
|
*/
|
|
export class MatIcon extends _MatIconBase {
|
|
constructor(elementRef, _iconRegistry, ariaHidden, _location, _errorHandler) {
|
|
super(elementRef);
|
|
this._iconRegistry = _iconRegistry;
|
|
this._location = _location;
|
|
this._errorHandler = _errorHandler;
|
|
this._inline = false;
|
|
/** Subscription to the current in-progress SVG icon request. */
|
|
this._currentIconFetch = Subscription.EMPTY;
|
|
// If the user has not explicitly set aria-hidden, mark the icon as hidden, as this is
|
|
// the right thing to do for the majority of icon use-cases.
|
|
if (!ariaHidden) {
|
|
elementRef.nativeElement.setAttribute('aria-hidden', 'true');
|
|
}
|
|
}
|
|
/**
|
|
* Whether the icon should be inlined, automatically sizing the icon to match the font size of
|
|
* the element the icon is contained in.
|
|
*/
|
|
get inline() {
|
|
return this._inline;
|
|
}
|
|
set inline(inline) {
|
|
this._inline = coerceBooleanProperty(inline);
|
|
}
|
|
/** Name of the icon in the SVG icon set. */
|
|
get svgIcon() { return this._svgIcon; }
|
|
set svgIcon(value) {
|
|
if (value !== this._svgIcon) {
|
|
if (value) {
|
|
this._updateSvgIcon(value);
|
|
}
|
|
else if (this._svgIcon) {
|
|
this._clearSvgElement();
|
|
}
|
|
this._svgIcon = value;
|
|
}
|
|
}
|
|
/** Font set that the icon is a part of. */
|
|
get fontSet() { return this._fontSet; }
|
|
set fontSet(value) {
|
|
const newValue = this._cleanupFontValue(value);
|
|
if (newValue !== this._fontSet) {
|
|
this._fontSet = newValue;
|
|
this._updateFontIconClasses();
|
|
}
|
|
}
|
|
/** Name of an icon within a font set. */
|
|
get fontIcon() { return this._fontIcon; }
|
|
set fontIcon(value) {
|
|
const newValue = this._cleanupFontValue(value);
|
|
if (newValue !== this._fontIcon) {
|
|
this._fontIcon = newValue;
|
|
this._updateFontIconClasses();
|
|
}
|
|
}
|
|
/**
|
|
* Splits an svgIcon binding value into its icon set and icon name components.
|
|
* Returns a 2-element array of [(icon set), (icon name)].
|
|
* The separator for the two fields is ':'. If there is no separator, an empty
|
|
* string is returned for the icon set and the entire value is returned for
|
|
* the icon name. If the argument is falsy, returns an array of two empty strings.
|
|
* Throws an error if the name contains two or more ':' separators.
|
|
* Examples:
|
|
* `'social:cake' -> ['social', 'cake']
|
|
* 'penguin' -> ['', 'penguin']
|
|
* null -> ['', '']
|
|
* 'a:b:c' -> (throws Error)`
|
|
*/
|
|
_splitIconName(iconName) {
|
|
if (!iconName) {
|
|
return ['', ''];
|
|
}
|
|
const parts = iconName.split(':');
|
|
switch (parts.length) {
|
|
case 1: return ['', parts[0]]; // Use default namespace.
|
|
case 2: return parts;
|
|
default: throw Error(`Invalid icon name: "${iconName}"`); // TODO: add an ngDevMode check
|
|
}
|
|
}
|
|
ngOnInit() {
|
|
// Update font classes because ngOnChanges won't be called if none of the inputs are present,
|
|
// e.g. <mat-icon>arrow</mat-icon> In this case we need to add a CSS class for the default font.
|
|
this._updateFontIconClasses();
|
|
}
|
|
ngAfterViewChecked() {
|
|
const cachedElements = this._elementsWithExternalReferences;
|
|
if (cachedElements && cachedElements.size) {
|
|
const newPath = this._location.getPathname();
|
|
// We need to check whether the URL has changed on each change detection since
|
|
// the browser doesn't have an API that will let us react on link clicks and
|
|
// we can't depend on the Angular router. The references need to be updated,
|
|
// because while most browsers don't care whether the URL is correct after
|
|
// the first render, Safari will break if the user navigates to a different
|
|
// page and the SVG isn't re-rendered.
|
|
if (newPath !== this._previousPath) {
|
|
this._previousPath = newPath;
|
|
this._prependPathToReferences(newPath);
|
|
}
|
|
}
|
|
}
|
|
ngOnDestroy() {
|
|
this._currentIconFetch.unsubscribe();
|
|
if (this._elementsWithExternalReferences) {
|
|
this._elementsWithExternalReferences.clear();
|
|
}
|
|
}
|
|
_usingFontIcon() {
|
|
return !this.svgIcon;
|
|
}
|
|
_setSvgElement(svg) {
|
|
this._clearSvgElement();
|
|
// Workaround for IE11 and Edge ignoring `style` tags inside dynamically-created SVGs.
|
|
// See: https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/10898469/
|
|
// Do this before inserting the element into the DOM, in order to avoid a style recalculation.
|
|
const styleTags = svg.querySelectorAll('style');
|
|
for (let i = 0; i < styleTags.length; i++) {
|
|
styleTags[i].textContent += ' ';
|
|
}
|
|
// Note: we do this fix here, rather than the icon registry, because the
|
|
// references have to point to the URL at the time that the icon was created.
|
|
const path = this._location.getPathname();
|
|
this._previousPath = path;
|
|
this._cacheChildrenWithExternalReferences(svg);
|
|
this._prependPathToReferences(path);
|
|
this._elementRef.nativeElement.appendChild(svg);
|
|
}
|
|
_clearSvgElement() {
|
|
const layoutElement = this._elementRef.nativeElement;
|
|
let childCount = layoutElement.childNodes.length;
|
|
if (this._elementsWithExternalReferences) {
|
|
this._elementsWithExternalReferences.clear();
|
|
}
|
|
// Remove existing non-element child nodes and SVGs, and add the new SVG element. Note that
|
|
// we can't use innerHTML, because IE will throw if the element has a data binding.
|
|
while (childCount--) {
|
|
const child = layoutElement.childNodes[childCount];
|
|
// 1 corresponds to Node.ELEMENT_NODE. We remove all non-element nodes in order to get rid
|
|
// of any loose text nodes, as well as any SVG elements in order to remove any old icons.
|
|
if (child.nodeType !== 1 || child.nodeName.toLowerCase() === 'svg') {
|
|
layoutElement.removeChild(child);
|
|
}
|
|
}
|
|
}
|
|
_updateFontIconClasses() {
|
|
if (!this._usingFontIcon()) {
|
|
return;
|
|
}
|
|
const elem = this._elementRef.nativeElement;
|
|
const fontSetClass = this.fontSet ?
|
|
this._iconRegistry.classNameForFontAlias(this.fontSet) :
|
|
this._iconRegistry.getDefaultFontSetClass();
|
|
if (fontSetClass != this._previousFontSetClass) {
|
|
if (this._previousFontSetClass) {
|
|
elem.classList.remove(this._previousFontSetClass);
|
|
}
|
|
if (fontSetClass) {
|
|
elem.classList.add(fontSetClass);
|
|
}
|
|
this._previousFontSetClass = fontSetClass;
|
|
}
|
|
if (this.fontIcon != this._previousFontIconClass) {
|
|
if (this._previousFontIconClass) {
|
|
elem.classList.remove(this._previousFontIconClass);
|
|
}
|
|
if (this.fontIcon) {
|
|
elem.classList.add(this.fontIcon);
|
|
}
|
|
this._previousFontIconClass = this.fontIcon;
|
|
}
|
|
}
|
|
/**
|
|
* Cleans up a value to be used as a fontIcon or fontSet.
|
|
* Since the value ends up being assigned as a CSS class, we
|
|
* have to trim the value and omit space-separated values.
|
|
*/
|
|
_cleanupFontValue(value) {
|
|
return typeof value === 'string' ? value.trim().split(' ')[0] : value;
|
|
}
|
|
/**
|
|
* Prepends the current path to all elements that have an attribute pointing to a `FuncIRI`
|
|
* reference. This is required because WebKit browsers require references to be prefixed with
|
|
* the current path, if the page has a `base` tag.
|
|
*/
|
|
_prependPathToReferences(path) {
|
|
const elements = this._elementsWithExternalReferences;
|
|
if (elements) {
|
|
elements.forEach((attrs, element) => {
|
|
attrs.forEach(attr => {
|
|
element.setAttribute(attr.name, `url('${path}#${attr.value}')`);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
/**
|
|
* Caches the children of an SVG element that have `url()`
|
|
* references that we need to prefix with the current path.
|
|
*/
|
|
_cacheChildrenWithExternalReferences(element) {
|
|
const elementsWithFuncIri = element.querySelectorAll(funcIriAttributeSelector);
|
|
const elements = this._elementsWithExternalReferences =
|
|
this._elementsWithExternalReferences || new Map();
|
|
for (let i = 0; i < elementsWithFuncIri.length; i++) {
|
|
funcIriAttributes.forEach(attr => {
|
|
const elementWithReference = elementsWithFuncIri[i];
|
|
const value = elementWithReference.getAttribute(attr);
|
|
const match = value ? value.match(funcIriPattern) : null;
|
|
if (match) {
|
|
let attributes = elements.get(elementWithReference);
|
|
if (!attributes) {
|
|
attributes = [];
|
|
elements.set(elementWithReference, attributes);
|
|
}
|
|
attributes.push({ name: attr, value: match[1] });
|
|
}
|
|
});
|
|
}
|
|
}
|
|
/** Sets a new SVG icon with a particular name. */
|
|
_updateSvgIcon(rawName) {
|
|
this._svgNamespace = null;
|
|
this._svgName = null;
|
|
this._currentIconFetch.unsubscribe();
|
|
if (rawName) {
|
|
const [namespace, iconName] = this._splitIconName(rawName);
|
|
if (namespace) {
|
|
this._svgNamespace = namespace;
|
|
}
|
|
if (iconName) {
|
|
this._svgName = iconName;
|
|
}
|
|
this._currentIconFetch = this._iconRegistry.getNamedSvgIcon(iconName, namespace)
|
|
.pipe(take(1))
|
|
.subscribe(svg => this._setSvgElement(svg), (err) => {
|
|
const errorMessage = `Error retrieving icon ${namespace}:${iconName}! ${err.message}`;
|
|
this._errorHandler.handleError(new Error(errorMessage));
|
|
});
|
|
}
|
|
}
|
|
}
|
|
MatIcon.ɵfac = function MatIcon_Factory(t) { return new (t || MatIcon)(ɵngcc0.ɵɵdirectiveInject(ɵngcc0.ElementRef), ɵngcc0.ɵɵdirectiveInject(ɵngcc1.MatIconRegistry), ɵngcc0.ɵɵinjectAttribute('aria-hidden'), ɵngcc0.ɵɵdirectiveInject(MAT_ICON_LOCATION), ɵngcc0.ɵɵdirectiveInject(ɵngcc0.ErrorHandler)); };
|
|
MatIcon.ɵcmp = /*@__PURE__*/ ɵngcc0.ɵɵdefineComponent({ type: MatIcon, selectors: [["mat-icon"]], hostAttrs: ["role", "img", 1, "mat-icon", "notranslate"], hostVars: 7, hostBindings: function MatIcon_HostBindings(rf, ctx) { if (rf & 2) {
|
|
ɵngcc0.ɵɵattribute("data-mat-icon-type", ctx._usingFontIcon() ? "font" : "svg")("data-mat-icon-name", ctx._svgName || ctx.fontIcon)("data-mat-icon-namespace", ctx._svgNamespace || ctx.fontSet);
|
|
ɵngcc0.ɵɵclassProp("mat-icon-inline", ctx.inline)("mat-icon-no-color", ctx.color !== "primary" && ctx.color !== "accent" && ctx.color !== "warn");
|
|
} }, inputs: { color: "color", inline: "inline", svgIcon: "svgIcon", fontSet: "fontSet", fontIcon: "fontIcon" }, exportAs: ["matIcon"], features: [ɵngcc0.ɵɵInheritDefinitionFeature], ngContentSelectors: _c0, decls: 1, vars: 0, template: function MatIcon_Template(rf, ctx) { if (rf & 1) {
|
|
ɵngcc0.ɵɵprojectionDef();
|
|
ɵngcc0.ɵɵprojection(0);
|
|
} }, styles: [".mat-icon{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-repeat:no-repeat;display:inline-block;fill:currentColor;height:24px;width:24px}.mat-icon.mat-icon-inline{font-size:inherit;height:inherit;line-height:inherit;width:inherit}[dir=rtl] .mat-icon-rtl-mirror{transform:scale(-1, 1)}.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-prefix .mat-icon,.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-suffix .mat-icon{display:block}.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-prefix .mat-icon-button .mat-icon,.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-suffix .mat-icon-button .mat-icon{margin:auto}\n"], encapsulation: 2, changeDetection: 0 });
|
|
MatIcon.ctorParameters = () => [
|
|
{ type: ElementRef },
|
|
{ type: MatIconRegistry },
|
|
{ type: String, decorators: [{ type: Attribute, args: ['aria-hidden',] }] },
|
|
{ type: undefined, decorators: [{ type: Inject, args: [MAT_ICON_LOCATION,] }] },
|
|
{ type: ErrorHandler }
|
|
];
|
|
MatIcon.propDecorators = {
|
|
inline: [{ type: Input }],
|
|
svgIcon: [{ type: Input }],
|
|
fontSet: [{ type: Input }],
|
|
fontIcon: [{ type: Input }]
|
|
};
|
|
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && ɵngcc0.ɵsetClassMetadata(MatIcon, [{
|
|
type: Component,
|
|
args: [{
|
|
template: '<ng-content></ng-content>',
|
|
selector: 'mat-icon',
|
|
exportAs: 'matIcon',
|
|
inputs: ['color'],
|
|
host: {
|
|
'role': 'img',
|
|
'class': 'mat-icon notranslate',
|
|
'[attr.data-mat-icon-type]': '_usingFontIcon() ? "font" : "svg"',
|
|
'[attr.data-mat-icon-name]': '_svgName || fontIcon',
|
|
'[attr.data-mat-icon-namespace]': '_svgNamespace || fontSet',
|
|
'[class.mat-icon-inline]': 'inline',
|
|
'[class.mat-icon-no-color]': 'color !== "primary" && color !== "accent" && color !== "warn"'
|
|
},
|
|
encapsulation: ViewEncapsulation.None,
|
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
styles: [".mat-icon{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-repeat:no-repeat;display:inline-block;fill:currentColor;height:24px;width:24px}.mat-icon.mat-icon-inline{font-size:inherit;height:inherit;line-height:inherit;width:inherit}[dir=rtl] .mat-icon-rtl-mirror{transform:scale(-1, 1)}.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-prefix .mat-icon,.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-suffix .mat-icon{display:block}.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-prefix .mat-icon-button .mat-icon,.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-suffix .mat-icon-button .mat-icon{margin:auto}\n"]
|
|
}]
|
|
}], function () { return [{ type: ɵngcc0.ElementRef }, { type: ɵngcc1.MatIconRegistry }, { type: String, decorators: [{
|
|
type: Attribute,
|
|
args: ['aria-hidden']
|
|
}] }, { type: undefined, decorators: [{
|
|
type: Inject,
|
|
args: [MAT_ICON_LOCATION]
|
|
}] }, { type: ɵngcc0.ErrorHandler }]; }, { inline: [{
|
|
type: Input
|
|
}], svgIcon: [{
|
|
type: Input
|
|
}], fontSet: [{
|
|
type: Input
|
|
}], fontIcon: [{
|
|
type: Input
|
|
}] }); })();
|
|
export { ɵ0 };
|
|
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaWNvbi5qcyIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL21hdGVyaWFsL2ljb24vaWNvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBRUgsT0FBTyxFQUFlLHFCQUFxQixFQUFDLE1BQU0sdUJBQXVCLENBQUM7QUFDMUUsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQ3pDLE9BQU8sRUFFTCxTQUFTLEVBQ1QsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLE1BQU0sRUFDTixNQUFNLEVBQ04sY0FBYyxFQUNkLEtBQUssRUFHTCxpQkFBaUIsR0FDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFXLFVBQVUsRUFBQyxNQUFNLHdCQUF3QixDQUFDO0FBQzVELE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFDbEMsT0FBTyxFQUFDLElBQUksRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBRXBDLE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUdoRCw4Q0FBOEM7QUFDOUMsb0JBQW9COzs7OztBQUNwQixNQUFNLFlBQVksR0FBRyxVQUFVLENBQUM7QUFDaEMsSUFBRSxZQUFtQixXQUF1QjtBQUFJLFFBQTNCLGdCQUFXLEdBQVgsV0FBVyxDQUFZO0FBQUMsSUFBRSxDQUFDO0FBQ2hELENBQUMsQ0FBQyxDQUFDO0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxjQUFjLENBQWtCLG1CQUFtQixFQUFFO0FBQzFGLElBQUUsVUFBVSxFQUFFLE1BQU07QUFDcEIsSUFBRSxPQUFPLEVBQUUseUJBQXlCO0FBQ3BDLENBQUMsQ0FBQyxDQUFDO0FBVUgsb0JBQW9CO0FBQ3BCLE1BQU0sVUFBVSx5QkFBeUI7QUFB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QXVCLENBQUMsTUFBTTs7OzsrWkFDaEQsMFlBQ0k7QUFBQztBQUFpQyxZQXpIckMsVUFBVTtBQUNWLFlBYU0sZUFBZTtBQUFJLHlDQW1McEIsU0FBUyxTQUFDLGFBQWE7QUFBUyw0Q0FDaEMsTUFBTSxTQUFDLGlCQUFpQjtBQUFTLFlBak10QyxZQUFZO0FBQ2I7QUFBRztBQUVPLHFCQTBIUixLQUFLO0FBQ04sc0JBU0MsS0FBSztBQUNOLHNCQWNDLEtBQUs7QUFDTix1QkFZQyxLQUFLO0FBQ1A7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O29CQUFFO0FBQUM7QUFBZSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQge0Jvb2xlYW5JbnB1dCwgY29lcmNlQm9vbGVhblByb3BlcnR5fSBmcm9tICdAYW5ndWxhci9jZGsvY29lcmNpb24nO1xuaW1wb3J0IHtET0NVTUVOVH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gIEFmdGVyVmlld0NoZWNrZWQsXG4gIEF0dHJpYnV0ZSxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgRXJyb3JIYW5kbGVyLFxuICBpbmplY3QsXG4gIEluamVjdCxcbiAgSW5qZWN0aW9uVG9rZW4sXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgVmlld0VuY2Fwc3VsYXRpb24sXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtDYW5Db2xvciwgbWl4aW5Db2xvcn0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvY29yZSc7XG5pbXBvcnQge1N1YnNjcmlwdGlvbn0gZnJvbSAncnhqcyc7XG5pbXBvcnQge3Rha2V9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHtNYXRJY29uUmVnaXN0cnl9IGZyb20gJy4vaWNvbi1yZWdpc3RyeSc7XG5cblxuLy8gQm9pbGVycGxhdGUgZm9yIGFwcGx5aW5nIG1peGlucyB0byBNYXRJY29uLlxuLyoqIEBkb2NzLXByaXZhdGUgKi9cbmNvbnN0IF9NYXRJY29uQmFzZSA9IG1peGluQ29sb3IoY2xhc3Mge1xuICBjb25zdHJ1Y3RvcihwdWJsaWMgX2VsZW1lbnRSZWY6IEVsZW1lbnRSZWYpIHt9XG59KTtcblxuLyoqXG4gKiBJbmplY3Rpb24gdG9rZW4gdXNlZCB0byBwcm92aWRlIHRoZSBjdXJyZW50IGxvY2F0aW9uIHRvIGBNYXRJY29uYC5cbiAqIFVzZWQgdG8gaGFuZGxlIHNlcnZlci1zaWRlIHJlbmRlcmluZyBhbmQgdG8gc3R1YiBvdXQgZHVyaW5nIHVuaXQgdGVzdHMuXG4gKiBAZG9jcy1wcml2YXRlXG4gKi9cbmV4cG9ydCBjb25zdCBNQVRfSUNPTl9MT0NBVElPTiA9IG5ldyBJbmplY3Rpb25Ub2tlbjxNYXRJY29uTG9jYXRpb24+KCdtYXQtaWNvbi1sb2NhdGlvbicsIHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxuICBmYWN0b3J5OiBNQVRfSUNPTl9MT0NBVElPTl9GQUNUT1JZXG59KTtcblxuLyoqXG4gKiBTdHViYmVkIG91dCBsb2NhdGlvbiBmb3IgYE1hdEljb25gLlxuICogQGRvY3MtcHJpdmF0ZVxuICovXG5leHBvcnQgaW50ZXJmYWNlIE1hdEljb25Mb2NhdGlvbiB7XG4gIGdldFBhdGhuYW1lOiAoKSA9PiBzdHJpbmc7XG59XG5cbi8qKiBAZG9jcy1wcml2YXRlICovXG5leHBvcnQgZnVuY3Rpb24gTUFUX0lDT05fTE9DQVRJT05fRkFDVE9SWSgpOiBNYXRJY29uTG9jYXRpb24ge1xuICBjb25zdCBfZG9jdW1lbnQgPSBpbmplY3QoRE9DVU1FTlQpO1xuICBjb25zdCBfbG9jYXRpb24gPSBfZG9jdW1lbnQgPyBfZG9jdW1lbnQubG9jYXRpb24gOiBudWxsO1xuXG4gIHJldHVybiB7XG4gICAgLy8gTm90ZSB0aGF0IHRoaXMgbmVlZHMgdG8gYmUgYSBmdW5jdGlvbiwgcmF0aGVyIHRoYW4gYSBwcm9wZXJ0eSwgYmVjYXVzZSBBbmd1bGFyXG4gICAgLy8gd2lsbCBvbmx5IHJlc29sdmUgaXQgb25jZSwgYnV0IHdlIHdhbnQgdGhlIGN1cnJlbnQgcGF0aCBvbiBlYWNoIGNhbGwuXG4gICAgZ2V0UGF0aG5hbWU6ICgpID0+IF9sb2NhdGlvbiA/IChfbG9jYXRpb24ucGF0aG5hbWUgKyBfbG9jYXRpb24uc2VhcmNoKSA6ICcnXG4gIH07XG59XG5cblxuLyoqIFNWRyBhdHRyaWJ1dGVzIHRoYXQgYWNjZXB0IGEgRnVuY0lSSSAoZS5nLiBgdXJsKDxzb21ldGhpbmc+KWApLiAqL1xuY29uc3QgZnVuY0lyaUF0dHJpYnV0ZXMgPSBbXG4gICdjbGlwLXBhdGgnLFxuICAnY29sb3ItcHJvZmlsZScsXG4gICdzcmMnLFxuICAnY3Vyc29yJyxcbiAgJ2ZpbGwnLFxuICAnZmlsdGVyJyxcbiAgJ21hcmtlcicsXG4gICdtYXJrZXItc3RhcnQnLFxuICAnbWFya2VyLW1pZCcsXG4gICdtYXJrZXItZW5kJyxcbiAgJ21hc2snLFxuICAnc3Ryb2tlJ1xuXTtcblxuLyoqIFNlbGVjdG9yIHRoYXQgY2FuIGJlIHVzZWQgdG8gZmluZCBhbGwgZWxlbWVudHMgdGhhdCBhcmUgdXNpbmcgYSBgRnVuY0lSSWAuICovXG5jb25zdCBmdW5jSXJpQXR0cmlidXRlU2VsZWN0b3IgPSBmdW5jSXJpQXR0cmlidXRlcy5tYXAoYXR0ciA9PiBgWyR7YXR0cn1dYCkuam9pbignLCAnKTtcblxuLyoqIFJlZ2V4IHRoYXQgY2FuIGJlIHVzZWQgdG8gZXh0cmFjdCB0aGUgaWQgb3V0IG9mIGEgRnVuY0lSSS4gKi9cbmNvbnN0IGZ1bmNJcmlQYXR0ZXJuID0gL151cmxcXChbJ1wiXT8jKC4qPylbJ1wiXT9cXCkkLztcblxuLyoqXG4gKiBDb21wb25lbnQgdG8gZGlzcGxheSBhbiBpY29uLiBJdCBjYW4gYmUgdXNlZCBpbiB0aGUgZm9sbG93aW5nIHdheXM6XG4gKlxuICogLSBTcGVjaWZ5IHRoZSBzdmdJY29uIGlucHV0IHRvIGxvYWQgYW4gU1ZHIGljb24gZnJvbSBhIFVSTCBwcmV2aW91c2x5IHJlZ2lzdGVyZWQgd2l0aCB0aGVcbiAqICAgYWRkU3ZnSWNvbiwgYWRkU3ZnSWNvbkluTmFtZXNwYWNlLCBhZGRTdmdJY29uU2V0LCBvciBhZGRTdmdJY29uU2V0SW5OYW1lc3BhY2UgbWV0aG9kcyBvZlxuICogICBNYXRJY29uUmVnaXN0cnkuIElmIHRoZSBzdmdJY29uIHZhbHVlIGNvbnRhaW5zIGEgY29sb24gaXQgaXMgYXNzdW1lZCB0byBiZSBpbiB0aGUgZm9ybWF0XG4gKiAgIFwiW25hbWVzcGFjZV06W25hbWVdXCIsIGlmIG5vdCB0aGUgdmFsdWUgd2lsbCBiZSB0aGUgbmFtZSBvZiBhbiBpY29uIGluIHRoZSBkZWZhdWx0IG5hbWVzcGFjZS5cbiAqICAgRXhhbXBsZXM6XG4gKiAgICAgYDxtYXQtaWNvbiBzdmdJY29uPVwibGVmdC1hcnJvd1wiPjwvbWF0LWljb24+XG4gKiAgICAgPG1hdC1pY29uIHN2Z0ljb249XCJhbmltYWxzOmNhdFwiPjwvbWF0LWljb24+YFxuICpcbiAqIC0gVXNlIGEgZm9udCBsaWdhdHVyZSBhcyBhbiBpY29uIGJ5IHB1dHRpbmcgdGhlIGxpZ2F0dXJlIHRleHQgaW4gdGhlIGNvbnRlbnQgb2YgdGhlIGA8bWF0LWljb24+YFxuICogICBjb21wb25lbnQuIEJ5IGRlZmF1bHQgdGhlIE1hdGVyaWFsIGljb25zIGZvbnQgaXMgdXNlZCBhcyBkZXNjcmliZWQgYXRcbiAqICAgaHR0cDovL2dvb2dsZS5naXRodWIuaW8vbWF0ZXJpYWwtZGVzaWduLWljb25zLyNpY29uLWZvbnQtZm9yLXRoZS13ZWIuIFlvdSBjYW4gc3BlY2lmeSBhblxuICogICBhbHRlcm5hdGUgZm9udCBieSBzZXR0aW5nIHRoZSBmb250U2V0IGlucHV0IHRvIGVpdGhlciB0aGUgQ1NTIGNsYXNzIHRvIGFwcGx5IHRvIHVzZSB0aGVcbiAqICAgZGVzaXJlZCBmb250LCBvciB0byBhbiBhbGlhcyBwcmV2aW91c2x5IHJlZ2lzdGVyZWQgd2l0aCBNYXRJY29uUmVnaXN0cnkucmVnaXN0ZXJGb250Q2xhc3NBbGlhcy5cbiAqICAgRXhhbXBsZXM6XG4gKiAgICAgYDxtYXQtaWNvbj5ob21lPC9tYXQtaWNvbj5cbiAqICAgICA8bWF0LWljb24gZm9udFNldD1cIm15Zm9udFwiPnN1bjwvbWF0LWljb24+YFxuICpcbiAqIC0gU3BlY2lmeSBhIGZvbnQgZ2x5cGggdG8gYmUgaW5jbHVkZWQgdmlhIENTUyBydWxlcyBieSBzZXR0aW5nIHRoZSBmb250U2V0IGlucHV0IHRvIHNwZWNpZnkgdGhlXG4gKiAgIGZvbnQsIGFuZCB0aGUgZm9udEljb24gaW5wdXQgdG8gc3BlY2lmeSB0aGUgaWNvbi4gVHlwaWNhbGx5IHRoZSBmb250SWNvbiB3aWxsIHNwZWNpZnkgYVxuICogICBDU1MgY2xhc3Mgd2hpY2ggY2F1c2VzIHRoZSBnbHlwaCB0byBiZSBkaXNwbGF5ZWQgdmlhIGEgOmJlZm9yZSBzZWxlY3RvciwgYXMgaW5cbiAqICAgaHR0cHM6Ly9mb3J0YXdlc29tZS5naXRodWIuaW8vRm9udC1Bd2Vzb21lL2V4YW1wbGVzL1xuICogICBFeGFtcGxlOlxuICogICAgIGA8bWF0LWljb24gZm9udFNldD1cImZhXCIgZm9udEljb249XCJhbGFybVwiPjwvbWF0LWljb24+YFxuICovXG5AQ29tcG9uZW50KHtcbiAgdGVtcGxhdGU6ICc8bmctY29udGVudD48L25nLWNvbnRlbnQ+JyxcbiAgc2VsZWN0b3I6ICdtYXQtaWNvbicsXG4gIGV4cG9ydEFzOiAnbWF0SWNvbicsXG4gIHN0eWxlVXJsczogWydpY29uLmNzcyddLFxuICBpbnB1dHM6IFsnY29sb3InXSxcbiAgaG9zdDoge1xuICAgICdyb2xlJzogJ2ltZycsXG4gICAgJ2NsYXNzJzogJ21hdC1pY29uIG5vdHJhbnNsYXRlJyxcbiAgICAnW2F0dHIuZGF0YS1tYXQtaWNvbi10eXBlXSc6ICdfdXNpbmdGb250SWNvbigpID8gXCJmb250XCIgOiBcInN2Z1wiJyxcbiAgICAnW2F0dHIuZGF0YS1tYXQtaWNvbi1uYW1lXSc6ICdfc3ZnTmFtZSB8fCBmb250SWNvbicsXG4gICAgJ1thdHRyLmRhdGEtbWF0LWljb24tbmFtZXNwYWNlXSc6ICdfc3ZnTmFtZXNwYWNlIHx8IGZvbnRTZXQnLFxuICAgICdbY2xhc3MubWF0LWljb24taW5saW5lXSc6ICdpbmxpbmUnLFxuICAgICdbY2xhc3MubWF0LWljb24tbm8tY29sb3JdJzogJ2NvbG9yICE9PSBcInByaW1hcnlcIiAmJiBjb2xvciAhPT0gXCJhY2NlbnRcIiAmJiBjb2xvciAhPT0gXCJ3YXJuXCInLFxuICB9LFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgTWF0SWNvbiBleHRlbmRzIF9NYXRJY29uQmFzZSBpbXBsZW1lbnRzIE9uSW5pdCwgQWZ0ZXJWaWV3Q2hlY2tlZCwgQ2FuQ29sb3IsIE9uRGVzdHJveSB7XG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBpY29uIHNob3VsZCBiZSBpbmxpbmVkLCBhdXRvbWF0aWNhbGx5IHNpemluZyB0aGUgaWNvbiB0byBtYXRjaCB0aGUgZm9udCBzaXplIG9mXG4gICAqIHRoZSBlbGVtZW50IHRoZSBpY29uIGlzIGNvbnRhaW5lZCBpbi5cbiAgICovXG4gIEBJbnB1dCgpXG4gIGdldCBpbmxpbmUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX2lubGluZTtcbiAgfVxuICBzZXQgaW5saW5lKGlubGluZTogYm9vbGVhbikge1xuICAgIHRoaXMuX2lubGluZSA9IGNvZXJjZUJvb2xlYW5Qcm9wZXJ0eShpbmxpbmUpO1xuICB9XG4gIHByaXZhdGUgX2lubGluZTogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8qKiBOYW1lIG9mIHRoZSBpY29uIGluIHRoZSBTVkcgaWNvbiBzZXQuICovXG4gIEBJbnB1dCgpXG4gIGdldCBzdmdJY29uKCk6IHN0cmluZyB7IHJldHVybiB0aGlzLl9zdmdJY29uOyB9XG4gIHNldCBzdmdJY29uKHZhbHVlOiBzdHJpbmcpIHtcbiAgICBpZiAodmFsdWUgIT09IHRoaXMuX3N2Z0ljb24pIHtcbiAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICB0aGlzLl91cGRhdGVTdmdJY29uKHZhbHVlKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5fc3ZnSWNvbikge1xuICAgICAgICB0aGlzLl9jbGVhclN2Z0VsZW1lbnQoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX3N2Z0ljb24gPSB2YWx1ZTtcbiAgICB9XG4gIH1cbiAgcHJpdmF0ZSBfc3ZnSWNvbjogc3RyaW5nO1xuXG4gIC8qKiBGb250IHNldCB0aGF0IHRoZSBpY29uIGlzIGEgcGFydCBvZi4gKi9cbiAgQElucHV0KClcbiAgZ2V0IGZvbnRTZXQoKTogc3RyaW5nIHsgcmV0dXJuIHRoaXMuX2ZvbnRTZXQ7IH1cbiAgc2V0IGZvbnRTZXQodmFsdWU6IHN0cmluZykge1xuICAgIGNvbnN0IG5ld1ZhbHVlID0gdGhpcy5fY2xlYW51cEZvbnRWYWx1ZSh2YWx1ZSk7XG5cbiAgICBpZiAobmV3VmFsdWUgIT09IHRoaXMuX2ZvbnRTZXQpIHtcbiAgICAgIHRoaXMuX2ZvbnRTZXQgPSBuZXdWYWx1ZTtcbiAgICAgIHRoaXMuX3VwZGF0ZUZvbnRJY29uQ2xhc3NlcygpO1xuICAgIH1cbiAgfVxuICBwcml2YXRlIF9mb250U2V0OiBzdHJpbmc7XG5cbiAgLyoqIE5hbWUgb2YgYW4gaWNvbiB3aXRoaW4gYSBmb250IHNldC4gKi9cbiAgQElucHV0KClcbiAgZ2V0IGZvbnRJY29uKCk6IHN0cmluZyB7IHJldHVybiB0aGlzLl9mb250SWNvbjsgfVxuICBzZXQgZm9udEljb24odmFsdWU6IHN0cmluZykge1xuICAgIGNvbnN0IG5ld1ZhbHVlID0gdGhpcy5fY2xlYW51cEZvbnRWYWx1ZSh2YWx1ZSk7XG5cbiAgICBpZiAobmV3VmFsdWUgIT09IHRoaXMuX2ZvbnRJY29uKSB7XG4gICAgICB0aGlzLl9mb250SWNvbiA9IG5ld1ZhbHVlO1xuICAgICAgdGhpcy5fdXBkYXRlRm9udEljb25DbGFzc2VzKCk7XG4gICAgfVxuICB9XG4gIHByaXZhdGUgX2ZvbnRJY29uOiBzdHJpbmc7XG5cbiAgcHJpdmF0ZSBfcHJldmlvdXNGb250U2V0Q2xhc3M6IHN0cmluZztcbiAgcHJpdmF0ZSBfcHJldmlvdXNGb250SWNvbkNsYXNzOiBzdHJpbmc7XG5cbiAgX3N2Z05hbWU6IHN0cmluZyB8IG51bGw7XG4gIF9zdmdOYW1lc3BhY2U6IHN0cmluZyB8IG51bGw7XG5cbiAgLyoqIEtlZXBzIHRyYWNrIG9mIHRoZSBjdXJyZW50IHBhZ2UgcGF0aC4gKi9cbiAgcHJpdmF0ZSBfcHJldmlvdXNQYXRoPzogc3RyaW5nO1xuXG4gIC8qKiBLZWVwcyB0cmFjayBvZiB0aGUgZWxlbWVudHMgYW5kIGF0dHJpYnV0ZXMgdGhhdCB3ZSd2ZSBwcmVmaXhlZCB3aXRoIHRoZSBjdXJyZW50IHBhdGguICovXG4gIHByaXZhdGUgX2VsZW1lbnRzV2l0aEV4dGVybmFsUmVmZXJlbmNlcz86IE1hcDxFbGVtZW50LCB7bmFtZTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nfVtdPjtcblxuICAvKiogU3Vic2NyaXB0aW9uIHRvIHRoZSBjdXJyZW50IGluLXByb2dyZXNzIFNWRyBpY29uIHJlcXVlc3QuICovXG4gIHByaXZhdGUgX2N1cnJlbnRJY29uRmV0Y2ggPSBTdWJzY3JpcHRpb24uRU1QVFk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgICBlbGVtZW50UmVmOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PiwgcHJpdmF0ZSBfaWNvblJlZ2lzdHJ5OiBNYXRJY29uUmVnaXN0cnksXG4gICAgICBAQXR0cmlidXRlKCdhcmlhLWhpZGRlbicpIGFyaWFIaWRkZW46IHN0cmluZyxcbiAgICAgIEBJbmplY3QoTUFUX0lDT05fTE9DQVRJT04pIHByaXZhdGUgX2xvY2F0aW9uOiBNYXRJY29uTG9jYXRpb24sXG4gICAgICBwcml2YXRlIHJlYWRvbmx5IF9lcnJvckhhbmRsZXI6IEVycm9ySGFuZGxlcikge1xuICAgIHN1cGVyKGVsZW1lbnRSZWYpO1xuXG4gICAgLy8gSWYgdGhlIHVzZXIgaGFzIG5vdCBleHBsaWNpdGx5IHNldCBhcmlhLWhpZGRlbiwgbWFyayB0aGUgaWNvbiBhcyBoaWRkZW4sIGFzIHRoaXMgaXNcbiAgICAvLyB0aGUgcmlnaHQgdGhpbmcgdG8gZG8gZm9yIHRoZSBtYWpvcml0eSBvZiBpY29uIHVzZS1jYXNlcy5cbiAgICBpZiAoIWFyaWFIaWRkZW4pIHtcbiAgICAgIGVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2FyaWEtaGlkZGVuJywgJ3RydWUnKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU3BsaXRzIGFuIHN2Z0ljb24gYmluZGluZyB2YWx1ZSBpbnRvIGl0cyBpY29uIHNldCBhbmQgaWNvbiBuYW1lIGNvbXBvbmVudHMuXG4gICAqIFJldHVybnMgYSAyLWVsZW1lbnQgYXJyYXkgb2YgWyhpY29uIHNldCksIChpY29uIG5hbWUpXS5cbiAgICogVGhlIHNlcGFyYXRvciBmb3IgdGhlIHR3byBmaWVsZHMgaXMgJzonLiBJZiB0aGVyZSBpcyBubyBzZXBhcmF0b3IsIGFuIGVtcHR5XG4gICAqIHN0cmluZyBpcyByZXR1cm5lZCBmb3IgdGhlIGljb24gc2V0IGFuZCB0aGUgZW50aXJlIHZhbHVlIGlzIHJldHVybmVkIGZvclxuICAgKiB0aGUgaWNvbiBuYW1lLiBJZiB0aGUgYXJndW1lbnQgaXMgZmFsc3ksIHJldHVybnMgYW4gYXJyYXkgb2YgdHdvIGVtcHR5IHN0cmluZ3MuXG4gICAqIFRocm93cyBhbiBlcnJvciBpZiB0aGUgbmFtZSBjb250YWlucyB0d28gb3IgbW9yZSAnOicgc2VwYXJhdG9ycy5cbiAgICogRXhhbXBsZXM6XG4gICAqICAgYCdzb2NpYWw6Y2FrZScgLT4gWydzb2NpYWwnLCAnY2FrZSddXG4gICAqICAgJ3Blbmd1aW4nIC0+IFsnJywgJ3Blbmd1aW4nXVxuICAgKiAgIG51bGwgLT4gWycnLCAnJ11cbiAgICogICAnYTpiOmMnIC0+ICh0aHJvd3MgRXJyb3IpYFxuICAgKi9cbiAgcHJpdmF0ZSBfc3BsaXRJY29uTmFtZShpY29uTmFtZTogc3RyaW5nKTogW3N0cmluZywgc3RyaW5nXSB7XG4gICAgaWYgKCFpY29uTmFtZSkge1xuICAgICAgcmV0dXJuIFsnJywgJyddO1xuICAgIH1cbiAgICBjb25zdCBwYXJ0cyA9IGljb25OYW1lLnNwbGl0KCc6Jyk7XG4gICAgc3dpdGNoIChwYXJ0cy5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMTogcmV0dXJuIFsnJywgcGFydHNbMF1dOyAvLyBVc2UgZGVmYXVsdCBuYW1lc3BhY2UuXG4gICAgICBjYXNlIDI6IHJldHVybiA8W3N0cmluZywgc3RyaW5nXT5wYXJ0cztcbiAgICAgIGRlZmF1bHQ6IHRocm93IEVycm9yKGBJbnZhbGlkIGljb24gbmFtZTogXCIke2ljb25OYW1lfVwiYCk7IC8vIFRPRE86IGFkZCBhbiBuZ0Rldk1vZGUgY2hlY2tcbiAgICB9XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICAvLyBVcGRhdGUgZm9udCBjbGFzc2VzIGJlY2F1c2UgbmdPbkNoYW5nZXMgd29uJ3QgYmUgY2FsbGVkIGlmIG5vbmUgb2YgdGhlIGlucHV0cyBhcmUgcHJlc2VudCxcbiAgICAvLyBlLmcuIDxtYXQtaWNvbj5hcnJvdzwvbWF0LWljb24+IEluIHRoaXMgY2FzZSB3ZSBuZWVkIHRvIGFkZCBhIENTUyBjbGFzcyBmb3IgdGhlIGRlZmF1bHQgZm9udC5cbiAgICB0aGlzLl91cGRhdGVGb250SWNvbkNsYXNzZXMoKTtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3Q2hlY2tlZCgpIHtcbiAgICBjb25zdCBjYWNoZWRFbGVtZW50cyA9IHRoaXMuX2VsZW1lbnRzV2l0aEV4dGVybmFsUmVmZXJlbmNlcztcblxuICAgIGlmIChjYWNoZWRFbGVtZW50cyAmJiBjYWNoZWRFbGVtZW50cy5zaXplKSB7XG4gICAgICBjb25zdCBuZXdQYXRoID0gdGhpcy5fbG9jYXRpb24uZ2V0UGF0aG5hbWUoKTtcblxuICAgICAgLy8gV2UgbmVlZCB0byBjaGVjayB3aGV0aGVyIHRoZSBVUkwgaGFzIGNoYW5nZWQgb24gZWFjaCBjaGFuZ2UgZGV0ZWN0aW9uIHNpbmNlXG4gICAgICAvLyB0aGUgYnJvd3NlciBkb2Vzbid0IGhhdmUgYW4gQVBJIHRoYXQgd2lsbCBsZXQgdXMgcmVhY3Qgb24gbGluayBjbGlja3MgYW5kXG4gICAgICAvLyB3ZSBjYW4ndCBkZXBlbmQgb24gdGhlIEFuZ3VsYXIgcm91dGVyLiBUaGUgcmVmZXJlbmNlcyBuZWVkIHRvIGJlIHVwZGF0ZWQsXG4gICAgICAvLyBiZWNhdXNlIHdoaWxlIG1vc3QgYnJvd3NlcnMgZG9uJ3QgY2FyZSB3aGV0aGVyIHRoZSBVUkwgaXMgY29ycmVjdCBhZnRlclxuICAgICAgLy8gdGhlIGZpcnN0IHJlbmRlciwgU2FmYXJpIHdpbGwgYnJlYWsgaWYgdGhlIHVzZXIgbmF2aWdhdGVzIHRvIGEgZGlmZmVyZW50XG4gICAgICAvLyBwYWdlIGFuZCB0aGUgU1ZHIGlzbid0IHJlLXJlbmRlcmVkLlxuICAgICAgaWYgKG5ld1BhdGggIT09IHRoaXMuX3ByZXZpb3VzUGF0aCkge1xuICAgICAgICB0aGlzLl9wcmV2aW91c1BhdGggPSBuZXdQYXRoO1xuICAgICAgICB0aGlzLl9wcmVwZW5kUGF0aFRvUmVmZXJlbmNlcyhuZXdQYXRoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLl9jdXJyZW50SWNvbkZldGNoLnVuc3Vic2NyaWJlKCk7XG5cbiAgICBpZiAodGhpcy5fZWxlbWVudHNXaXRoRXh0ZXJuYWxSZWZlcmVuY2VzKSB7XG4gICAgICB0aGlzLl9lbGVtZW50c1dpdGhFeHRlcm5hbFJlZmVyZW5jZXMuY2xlYXIoKTtcbiAgICB9XG4gIH1cblxuICBfdXNpbmdGb250SWNvbigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gIXRoaXMuc3ZnSWNvbjtcbiAgfVxuXG4gIHByaXZhdGUgX3NldFN2Z0VsZW1lbnQoc3ZnOiBTVkdFbGVtZW50KSB7XG4gICAgdGhpcy5fY2xlYXJTdmdFbGVtZW50KCk7XG5cbiAgICAvLyBXb3JrYXJvdW5kIGZvciBJRTExIGFuZCBFZGdlIGlnbm9yaW5nIGBzdHlsZWAgdGFncyBpbnNpZGUgZHluYW1pY2FsbHktY3JlYXRlZCBTVkdzLlxuICAgIC8vIFNlZTogaHR0cHM6Ly9kZXZlbG9wZXIubWljcm9zb2Z0LmNvbS9lbi11cy9taWNyb3NvZnQtZWRnZS9wbGF0Zm9ybS9pc3N1ZXMvMTA4OTg0NjkvXG4gICAgLy8gRG8gdGhpcyBiZWZvcmUgaW5zZXJ0aW5nIHRoZSBlbGVtZW50IGludG8gdGhlIERPTSwgaW4gb3JkZXIgdG8gYXZvaWQgYSBzdHlsZSByZWNhbGN1bGF0aW9uLlxuICAgIGNvbnN0IHN0eWxlVGFncyA9IHN2Zy5xdWVyeVNlbGVjdG9yQWxsKCdzdHlsZScpIGFzIE5vZGVMaXN0T2Y8SFRNTFN0eWxlRWxlbWVudD47XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHN0eWxlVGFncy5sZW5ndGg7IGkrKykge1xuICAgICAgc3R5bGVUYWdzW2ldLnRleHRDb250ZW50ICs9ICcgJztcbiAgICB9XG5cbiAgICAvLyBOb3RlOiB3ZSBkbyB0aGlzIGZpeCBoZXJlLCByYXRoZXIgdGhhbiB0aGUgaWNvbiByZWdpc3RyeSwgYmVjYXVzZSB0aGVcbiAgICAvLyByZWZlcmVuY2VzIGhhdmUgdG8gcG9pbnQgdG8gdGhlIFVSTCBhdCB0aGUgdGltZSB0aGF0IHRoZSBpY29uIHdhcyBjcmVhdGVkLlxuICAgIGNvbnN0IHBhdGggPSB0aGlzLl9sb2NhdGlvbi5nZXRQYXRobmFtZSgpO1xuICAgIHRoaXMuX3ByZXZpb3VzUGF0aCA9IHBhdGg7XG4gICAgdGhpcy5fY2FjaGVDaGlsZHJlbldpdGhFeHRlcm5hbFJlZmVyZW5jZXMoc3ZnKTtcbiAgICB0aGlzLl9wcmVwZW5kUGF0aFRvUmVmZXJlbmNlcyhwYXRoKTtcbiAgICB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuYXBwZW5kQ2hpbGQoc3ZnKTtcbiAgfVxuXG4gIHByaXZhdGUgX2NsZWFyU3ZnRWxlbWVudCgpIHtcbiAgICBjb25zdCBsYXlvdXRFbGVtZW50OiBIVE1MRWxlbWVudCA9IHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcbiAgICBsZXQgY2hpbGRDb3VudCA9IGxheW91dEVsZW1lbnQuY2hpbGROb2Rlcy5sZW5ndGg7XG5cbiAgICBpZiAodGhpcy5fZWxlbWVudHNXaXRoRXh0ZXJuYWxSZWZlcmVuY2VzKSB7XG4gICAgICB0aGlzLl9lbGVtZW50c1dpdGhFeHRlcm5hbFJlZmVyZW5jZXMuY2xlYXIoKTtcbiAgICB9XG5cbiAgICAvLyBSZW1vdmUgZXhpc3Rpbmcgbm9uLWVsZW1lbnQgY2hpbGQgbm9kZXMgYW5kIFNWR3MsIGFuZCBhZGQgdGhlIG5ldyBTVkcgZWxlbWVudC4gTm90ZSB0aGF0XG4gICAgLy8gd2UgY2FuJ3QgdXNlIGlubmVySFRNTCwgYmVjYXVzZSBJRSB3aWxsIHRocm93IGlmIHRoZSBlbGVtZW50IGhhcyBhIGRhdGEgYmluZGluZy5cbiAgICB3aGlsZSAoY2hpbGRDb3VudC0tKSB7XG4gICAgICBjb25zdCBjaGlsZCA9IGxheW91dEVsZW1lbnQuY2hpbGROb2Rlc1tjaGlsZENvdW50XTtcblxuICAgICAgLy8gMSBjb3JyZXNwb25kcyB0byBOb2RlLkVMRU1FTlRfTk9ERS4gV2UgcmVtb3ZlIGFsbCBub24tZWxlbWVudCBub2RlcyBpbiBvcmRlciB0byBnZXQgcmlkXG4gICAgICAvLyBvZiBhbnkgbG9vc2UgdGV4dCBub2RlcywgYXMgd2VsbCBhcyBhbnkgU1ZHIGVsZW1lbnRzIGluIG9yZGVyIHRvIHJlbW92ZSBhbnkgb2xkIGljb25zLlxuICAgICAgaWYgKGNoaWxkLm5vZGVUeXBlICE9PSAxIHx8IGNoaWxkLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09ICdzdmcnKSB7XG4gICAgICAgIGxheW91dEVsZW1lbnQucmVtb3ZlQ2hpbGQoY2hpbGQpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX3VwZGF0ZUZvbnRJY29uQ2xhc3NlcygpIHtcbiAgICBpZiAoIXRoaXMuX3VzaW5nRm9udEljb24oKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGVsZW06IEhUTUxFbGVtZW50ID0gdGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50O1xuICAgIGNvbnN0IGZvbnRTZXRDbGFzcyA9IHRoaXMuZm9udFNldCA/XG4gICAgICAgIHRoaXMuX2ljb25SZWdpc3RyeS5jbGFzc05hbWVGb3JGb250QWxpYXModGhpcy5mb250U2V0KSA6XG4gICAgICAgIHRoaXMuX2ljb25SZWdpc3RyeS5nZXREZWZhdWx0Rm9udFNldENsYXNzKCk7XG5cbiAgICBpZiAoZm9udFNldENsYXNzICE9IHRoaXMuX3ByZXZpb3VzRm9udFNldENsYXNzKSB7XG4gICAgICBpZiAodGhpcy5fcHJldmlvdXNGb250U2V0Q2xhc3MpIHtcbiAgICAgICAgZWxlbS5jbGFzc0xpc3QucmVtb3ZlKHRoaXMuX3ByZXZpb3VzRm9udFNldENsYXNzKTtcbiAgICAgIH1cbiAgICAgIGlmIChmb250U2V0Q2xhc3MpIHtcbiAgICAgICAgZWxlbS5jbGFzc0xpc3QuYWRkKGZvbnRTZXRDbGFzcyk7XG4gICAgICB9XG4gICAgICB0aGlzLl9wcmV2aW91c0ZvbnRTZXRDbGFzcyA9IGZvbnRTZXRDbGFzcztcbiAgICB9XG5cbiAgICBpZiAodGhpcy5mb250SWNvbiAhPSB0aGlzLl9wcmV2aW91c0ZvbnRJY29uQ2xhc3MpIHtcbiAgICAgIGlmICh0aGlzLl9wcmV2aW91c0ZvbnRJY29uQ2xhc3MpIHtcbiAgICAgICAgZWxlbS5jbGFzc0xpc3QucmVtb3ZlKHRoaXMuX3ByZXZpb3VzRm9udEljb25DbGFzcyk7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5mb250SWNvbikge1xuICAgICAgICBlbGVtLmNsYXNzTGlzdC5hZGQodGhpcy5mb250SWNvbik7XG4gICAgICB9XG4gICAgICB0aGlzLl9wcmV2aW91c0ZvbnRJY29uQ2xhc3MgPSB0aGlzLmZvbnRJY29uO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhbnMgdXAgYSB2YWx1ZSB0byBiZSB1c2VkIGFzIGEgZm9udEljb24gb3IgZm9udFNldC5cbiAgICogU2luY2UgdGhlIHZhbHVlIGVuZHMgdXAgYmVpbmcgYXNzaWduZWQgYXMgYSBDU1MgY2xhc3MsIHdlXG4gICAqIGhhdmUgdG8gdHJpbSB0aGUgdmFsdWUgYW5kIG9taXQgc3BhY2Utc2VwYXJhdGVkIHZhbHVlcy5cbiAgICovXG4gIHByaXZhdGUgX2NsZWFudXBGb250VmFsdWUodmFsdWU6IHN0cmluZykge1xuICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnID8gdmFsdWUudHJpbSgpLnNwbGl0KCcgJylbMF0gOiB2YWx1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcmVwZW5kcyB0aGUgY3VycmVudCBwYXRoIHRvIGFsbCBlbGVtZW50cyB0aGF0IGhhdmUgYW4gYXR0cmlidXRlIHBvaW50aW5nIHRvIGEgYEZ1bmNJUklgXG4gICAqIHJlZmVyZW5jZS4gVGhpcyBpcyByZXF1aXJlZCBiZWNhdXNlIFdlYktpdCBicm93c2VycyByZXF1aXJlIHJlZmVyZW5jZXMgdG8gYmUgcHJlZml4ZWQgd2l0aFxuICAgKiB0aGUgY3VycmVudCBwYXRoLCBpZiB0aGUgcGFnZSBoYXMgYSBgYmFzZWAgdGFnLlxuICAgKi9cbiAgcHJpdmF0ZSBfcHJlcGVuZFBhdGhUb1JlZmVyZW5jZXMocGF0aDogc3RyaW5nKSB7XG4gICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLl9lbGVtZW50c1dpdGhFeHRlcm5hbFJlZmVyZW5jZXM7XG5cbiAgICBpZiAoZWxlbWVudHMpIHtcbiAgICAgIGVsZW1lbnRzLmZvckVhY2goKGF0dHJzLCBlbGVtZW50KSA9PiB7XG4gICAgICAgIGF0dHJzLmZvckVhY2goYXR0ciA9PiB7XG4gICAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoYXR0ci5uYW1lLCBgdXJsKCcke3BhdGh9IyR7YXR0ci52YWx1ZX0nKWApO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDYWNoZXMgdGhlIGNoaWxkcmVuIG9mIGFuIFNWRyBlbGVtZW50IHRoYXQgaGF2ZSBgdXJsKClgXG4gICAqIHJlZmVyZW5jZXMgdGhhdCB3ZSBuZWVkIHRvIHByZWZpeCB3aXRoIHRoZSBjdXJyZW50IHBhdGguXG4gICAqL1xuICBwcml2YXRlIF9jYWNoZUNoaWxkcmVuV2l0aEV4dGVybmFsUmVmZXJlbmNlcyhlbGVtZW50OiBTVkdFbGVtZW50KSB7XG4gICAgY29uc3QgZWxlbWVudHNXaXRoRnVuY0lyaSA9IGVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChmdW5jSXJpQXR0cmlidXRlU2VsZWN0b3IpO1xuICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy5fZWxlbWVudHNXaXRoRXh0ZXJuYWxSZWZlcmVuY2VzID1cbiAgICAgICAgdGhpcy5fZWxlbWVudHNXaXRoRXh0ZXJuYWxSZWZlcmVuY2VzIHx8IG5ldyBNYXAoKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZWxlbWVudHNXaXRoRnVuY0lyaS5sZW5ndGg7IGkrKykge1xuICAgICAgZnVuY0lyaUF0dHJpYnV0ZXMuZm9yRWFjaChhdHRyID0+IHtcbiAgICAgICAgY29uc3QgZWxlbWVudFdpdGhSZWZlcmVuY2UgPSBlbGVtZW50c1dpdGhGdW5jSXJpW2ldO1xuICAgICAgICBjb25zdCB2YWx1ZSA9IGVsZW1lbnRXaXRoUmVmZXJlbmNlLmdldEF0dHJpYnV0ZShhdHRyKTtcbiAgICAgICAgY29uc3QgbWF0Y2ggPSB2YWx1ZSA/IHZhbHVlLm1hdGNoKGZ1bmNJcmlQYXR0ZXJuKSA6IG51bGw7XG5cbiAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgbGV0IGF0dHJpYnV0ZXMgPSBlbGVtZW50cy5nZXQoZWxlbWVudFdpdGhSZWZlcmVuY2UpO1xuXG4gICAgICAgICAgaWYgKCFhdHRyaWJ1dGVzKSB7XG4gICAgICAgICAgICBhdHRyaWJ1dGVzID0gW107XG4gICAgICAgICAgICBlbGVtZW50cy5zZXQoZWxlbWVudFdpdGhSZWZlcmVuY2UsIGF0dHJpYnV0ZXMpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGF0dHJpYnV0ZXMhLnB1c2goe25hbWU6IGF0dHIsIHZhbHVlOiBtYXRjaFsxXX0pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvKiogU2V0cyBhIG5ldyBTVkcgaWNvbiB3aXRoIGEgcGFydGljdWxhciBuYW1lLiAqL1xuICBwcml2YXRlIF91cGRhdGVTdmdJY29uKHJhd05hbWU6IHN0cmluZ3x1bmRlZmluZWQpIHtcbiAgICB0aGlzLl9zdmdOYW1lc3BhY2UgPSBudWxsO1xuICAgIHRoaXMuX3N2Z05hbWUgPSBudWxsO1xuICAgIHRoaXMuX2N1cnJlbnRJY29uRmV0Y2gudW5zdWJzY3JpYmUoKTtcblxuICAgIGlmIChyYXdOYW1lKSB7XG4gICAgICBjb25zdCBbbmFtZXNwYWNlLCBpY29uTmFtZV0gPSB0aGlzLl9zcGxpdEljb25OYW1lKHJhd05hbWUpO1xuXG4gICAgICBpZiAobmFtZXNwYWNlKSB7XG4gICAgICAgIHRoaXMuX3N2Z05hbWVzcGFjZSA9IG5hbWVzcGFjZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGljb25OYW1lKSB7XG4gICAgICAgIHRoaXMuX3N2Z05hbWUgPSBpY29uTmFtZTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fY3VycmVudEljb25GZXRjaCA9IHRoaXMuX2ljb25SZWdpc3RyeS5nZXROYW1lZFN2Z0ljb24oaWNvbk5hbWUsIG5hbWVzcGFjZSlcbiAgICAgICAgICAucGlwZSh0YWtlKDEpKVxuICAgICAgICAgIC5zdWJzY3JpYmUoc3ZnID0+IHRoaXMuX3NldFN2Z0VsZW1lbnQoc3ZnKSwgKGVycjogRXJyb3IpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGBFcnJvciByZXRyaWV2aW5nIGljb24gJHtuYW1lc3BhY2V9OiR7aWNvbk5hbWV9ISAke2Vyci5tZXNzYWdlfWA7XG4gICAgICAgICAgICB0aGlzLl9lcnJvckhhbmRsZXIuaGFuZGxlRXJyb3IobmV3IEVycm9yKGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyBuZ0FjY2VwdElucHV0VHlwZV9pbmxpbmU6IEJvb2xlYW5JbnB1dDtcbn1cbiJdfQ==
|