@angular/compiler
Version:
Angular - the compiler library
520 lines • 88.6 kB
JavaScript
/**
* @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
*/
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define("@angular/compiler/src/template_parser/binding_parser", ["require", "exports", "tslib", "@angular/compiler/src/core", "@angular/compiler/src/expression_parser/ast", "@angular/compiler/src/ml_parser/tags", "@angular/compiler/src/parse_util", "@angular/compiler/src/selector", "@angular/compiler/src/util"], factory);
}
})(function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.calcPossibleSecurityContexts = exports.PipeCollector = exports.BindingParser = void 0;
var tslib_1 = require("tslib");
var core_1 = require("@angular/compiler/src/core");
var ast_1 = require("@angular/compiler/src/expression_parser/ast");
var tags_1 = require("@angular/compiler/src/ml_parser/tags");
var parse_util_1 = require("@angular/compiler/src/parse_util");
var selector_1 = require("@angular/compiler/src/selector");
var util_1 = require("@angular/compiler/src/util");
var PROPERTY_PARTS_SEPARATOR = '.';
var ATTRIBUTE_PREFIX = 'attr';
var CLASS_PREFIX = 'class';
var STYLE_PREFIX = 'style';
var TEMPLATE_ATTR_PREFIX = '*';
var ANIMATE_PROP_PREFIX = 'animate-';
/**
* Parses bindings in templates and in the directive host area.
*/
var BindingParser = /** @class */ (function () {
function BindingParser(_exprParser, _interpolationConfig, _schemaRegistry, pipes, errors) {
this._exprParser = _exprParser;
this._interpolationConfig = _interpolationConfig;
this._schemaRegistry = _schemaRegistry;
this.errors = errors;
this.pipesByName = null;
this._usedPipes = new Map();
// When the `pipes` parameter is `null`, do not check for used pipes
// This is used in IVY when we might not know the available pipes at compile time
if (pipes) {
var pipesByName_1 = new Map();
pipes.forEach(function (pipe) { return pipesByName_1.set(pipe.name, pipe); });
this.pipesByName = pipesByName_1;
}
}
Object.defineProperty(BindingParser.prototype, "interpolationConfig", {
get: function () {
return this._interpolationConfig;
},
enumerable: false,
configurable: true
});
BindingParser.prototype.getUsedPipes = function () {
return Array.from(this._usedPipes.values());
};
BindingParser.prototype.createBoundHostProperties = function (dirMeta, sourceSpan) {
var _this = this;
if (dirMeta.hostProperties) {
var boundProps_1 = [];
Object.keys(dirMeta.hostProperties).forEach(function (propName) {
var expression = dirMeta.hostProperties[propName];
if (typeof expression === 'string') {
_this.parsePropertyBinding(propName, expression, true, sourceSpan, sourceSpan.start.offset, undefined, [],
// Use the `sourceSpan` for `keySpan`. This isn't really accurate, but neither is the
// sourceSpan, as it represents the sourceSpan of the host itself rather than the
// source of the host binding (which doesn't exist in the template). Regardless,
// neither of these values are used in Ivy but are only here to satisfy the function
// signature. This should likely be refactored in the future so that `sourceSpan`
// isn't being used inaccurately.
boundProps_1, sourceSpan);
}
else {
_this._reportError("Value of the host property binding \"" + propName + "\" needs to be a string representing an expression but got \"" + expression + "\" (" + typeof expression + ")", sourceSpan);
}
});
return boundProps_1;
}
return null;
};
BindingParser.prototype.createDirectiveHostPropertyAsts = function (dirMeta, elementSelector, sourceSpan) {
var _this = this;
var boundProps = this.createBoundHostProperties(dirMeta, sourceSpan);
return boundProps &&
boundProps.map(function (prop) { return _this.createBoundElementProperty(elementSelector, prop); });
};
BindingParser.prototype.createDirectiveHostEventAsts = function (dirMeta, sourceSpan) {
var _this = this;
if (dirMeta.hostListeners) {
var targetEvents_1 = [];
Object.keys(dirMeta.hostListeners).forEach(function (propName) {
var expression = dirMeta.hostListeners[propName];
if (typeof expression === 'string') {
// TODO: pass a more accurate handlerSpan for this event.
_this.parseEvent(propName, expression, sourceSpan, sourceSpan, [], targetEvents_1);
}
else {
_this._reportError("Value of the host listener \"" + propName + "\" needs to be a string representing an expression but got \"" + expression + "\" (" + typeof expression + ")", sourceSpan);
}
});
return targetEvents_1;
}
return null;
};
BindingParser.prototype.parseInterpolation = function (value, sourceSpan) {
var sourceInfo = sourceSpan.start.toString();
try {
var ast = this._exprParser.parseInterpolation(value, sourceInfo, sourceSpan.start.offset, this._interpolationConfig);
if (ast)
this._reportExpressionParserErrors(ast.errors, sourceSpan);
this._checkPipes(ast, sourceSpan);
return ast;
}
catch (e) {
this._reportError("" + e, sourceSpan);
return this._exprParser.wrapLiteralPrimitive('ERROR', sourceInfo, sourceSpan.start.offset);
}
};
/**
* Similar to `parseInterpolation`, but treats the provided string as a single expression
* element that would normally appear within the interpolation prefix and suffix (`{{` and `}}`).
* This is used for parsing the switch expression in ICUs.
*/
BindingParser.prototype.parseInterpolationExpression = function (expression, sourceSpan) {
var sourceInfo = sourceSpan.start.toString();
try {
var ast = this._exprParser.parseInterpolationExpression(expression, sourceInfo, sourceSpan.start.offset);
if (ast)
this._reportExpressionParserErrors(ast.errors, sourceSpan);
this._checkPipes(ast, sourceSpan);
return ast;
}
catch (e) {
this._reportError("" + e, sourceSpan);
return this._exprParser.wrapLiteralPrimitive('ERROR', sourceInfo, sourceSpan.start.offset);
}
};
/**
* Parses the bindings in a microsyntax expression, and converts them to
* `ParsedProperty` or `ParsedVariable`.
*
* @param tplKey template binding name
* @param tplValue template binding value
* @param sourceSpan span of template binding relative to entire the template
* @param absoluteValueOffset start of the tplValue relative to the entire template
* @param targetMatchableAttrs potential attributes to match in the template
* @param targetProps target property bindings in the template
* @param targetVars target variables in the template
*/
BindingParser.prototype.parseInlineTemplateBinding = function (tplKey, tplValue, sourceSpan, absoluteValueOffset, targetMatchableAttrs, targetProps, targetVars, isIvyAst) {
var e_1, _a;
var absoluteKeyOffset = sourceSpan.start.offset + TEMPLATE_ATTR_PREFIX.length;
var bindings = this._parseTemplateBindings(tplKey, tplValue, sourceSpan, absoluteKeyOffset, absoluteValueOffset);
try {
for (var bindings_1 = tslib_1.__values(bindings), bindings_1_1 = bindings_1.next(); !bindings_1_1.done; bindings_1_1 = bindings_1.next()) {
var binding = bindings_1_1.value;
// sourceSpan is for the entire HTML attribute. bindingSpan is for a particular
// binding within the microsyntax expression so it's more narrow than sourceSpan.
var bindingSpan = moveParseSourceSpan(sourceSpan, binding.sourceSpan);
var key = binding.key.source;
var keySpan = moveParseSourceSpan(sourceSpan, binding.key.span);
if (binding instanceof ast_1.VariableBinding) {
var value = binding.value ? binding.value.source : '$implicit';
var valueSpan = binding.value ? moveParseSourceSpan(sourceSpan, binding.value.span) : undefined;
targetVars.push(new ast_1.ParsedVariable(key, value, bindingSpan, keySpan, valueSpan));
}
else if (binding.value) {
var srcSpan = isIvyAst ? bindingSpan : sourceSpan;
var valueSpan = moveParseSourceSpan(sourceSpan, binding.value.ast.sourceSpan);
this._parsePropertyAst(key, binding.value, srcSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps);
}
else {
targetMatchableAttrs.push([key, '' /* value */]);
// Since this is a literal attribute with no RHS, source span should be
// just the key span.
this.parseLiteralAttr(key, null /* value */, keySpan, absoluteValueOffset, undefined /* valueSpan */, targetMatchableAttrs, targetProps, keySpan);
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (bindings_1_1 && !bindings_1_1.done && (_a = bindings_1.return)) _a.call(bindings_1);
}
finally { if (e_1) throw e_1.error; }
}
};
/**
* Parses the bindings in a microsyntax expression, e.g.
* ```
* <tag *tplKey="let value1 = prop; let value2 = localVar">
* ```
*
* @param tplKey template binding name
* @param tplValue template binding value
* @param sourceSpan span of template binding relative to entire the template
* @param absoluteKeyOffset start of the `tplKey`
* @param absoluteValueOffset start of the `tplValue`
*/
BindingParser.prototype._parseTemplateBindings = function (tplKey, tplValue, sourceSpan, absoluteKeyOffset, absoluteValueOffset) {
var _this = this;
var sourceInfo = sourceSpan.start.toString();
try {
var bindingsResult = this._exprParser.parseTemplateBindings(tplKey, tplValue, sourceInfo, absoluteKeyOffset, absoluteValueOffset);
this._reportExpressionParserErrors(bindingsResult.errors, sourceSpan);
bindingsResult.templateBindings.forEach(function (binding) {
if (binding.value instanceof ast_1.ASTWithSource) {
_this._checkPipes(binding.value, sourceSpan);
}
});
bindingsResult.warnings.forEach(function (warning) {
_this._reportError(warning, sourceSpan, parse_util_1.ParseErrorLevel.WARNING);
});
return bindingsResult.templateBindings;
}
catch (e) {
this._reportError("" + e, sourceSpan);
return [];
}
};
BindingParser.prototype.parseLiteralAttr = function (name, value, sourceSpan, absoluteOffset, valueSpan, targetMatchableAttrs,
// TODO(atscott): keySpan is only optional here so VE template parser implementation does not
// have to change This should be required when VE is removed.
targetProps, keySpan) {
if (isAnimationLabel(name)) {
name = name.substring(1);
if (value) {
this._reportError("Assigning animation triggers via @prop=\"exp\" attributes with an expression is invalid." +
" Use property bindings (e.g. [@prop]=\"exp\") or use an attribute without a value (e.g. @prop) instead.", sourceSpan, parse_util_1.ParseErrorLevel.ERROR);
}
this._parseAnimation(name, value, sourceSpan, absoluteOffset, keySpan, valueSpan, targetMatchableAttrs, targetProps);
}
else {
targetProps.push(new ast_1.ParsedProperty(name, this._exprParser.wrapLiteralPrimitive(value, '', absoluteOffset), ast_1.ParsedPropertyType.LITERAL_ATTR, sourceSpan, keySpan, valueSpan));
}
};
BindingParser.prototype.parsePropertyBinding = function (name, expression, isHost, sourceSpan, absoluteOffset, valueSpan,
// TODO(atscott): keySpan is only optional here so VE template parser implementation does not
// have to change This should be required when VE is removed.
targetMatchableAttrs, targetProps, keySpan) {
if (name.length === 0) {
this._reportError("Property name is missing in binding", sourceSpan);
}
var isAnimationProp = false;
if (name.startsWith(ANIMATE_PROP_PREFIX)) {
isAnimationProp = true;
name = name.substring(ANIMATE_PROP_PREFIX.length);
}
else if (isAnimationLabel(name)) {
isAnimationProp = true;
name = name.substring(1);
}
if (isAnimationProp) {
this._parseAnimation(name, expression, sourceSpan, absoluteOffset, keySpan, valueSpan, targetMatchableAttrs, targetProps);
}
else {
this._parsePropertyAst(name, this._parseBinding(expression, isHost, valueSpan || sourceSpan, absoluteOffset), sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps);
}
};
BindingParser.prototype.parsePropertyInterpolation = function (name, value, sourceSpan, valueSpan, targetMatchableAttrs,
// TODO(atscott): keySpan is only optional here so VE template parser implementation does not
// have to change This should be required when VE is removed.
targetProps, keySpan) {
var expr = this.parseInterpolation(value, valueSpan || sourceSpan);
if (expr) {
this._parsePropertyAst(name, expr, sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps);
return true;
}
return false;
};
BindingParser.prototype._parsePropertyAst = function (name, ast, sourceSpan, keySpan, valueSpan, targetMatchableAttrs, targetProps) {
targetMatchableAttrs.push([name, ast.source]);
targetProps.push(new ast_1.ParsedProperty(name, ast, ast_1.ParsedPropertyType.DEFAULT, sourceSpan, keySpan, valueSpan));
};
BindingParser.prototype._parseAnimation = function (name, expression, sourceSpan, absoluteOffset, keySpan, valueSpan, targetMatchableAttrs, targetProps) {
if (name.length === 0) {
this._reportError('Animation trigger is missing', sourceSpan);
}
// This will occur when a @trigger is not paired with an expression.
// For animations it is valid to not have an expression since */void
// states will be applied by angular when the element is attached/detached
var ast = this._parseBinding(expression || 'undefined', false, valueSpan || sourceSpan, absoluteOffset);
targetMatchableAttrs.push([name, ast.source]);
targetProps.push(new ast_1.ParsedProperty(name, ast, ast_1.ParsedPropertyType.ANIMATION, sourceSpan, keySpan, valueSpan));
};
BindingParser.prototype._parseBinding = function (value, isHostBinding, sourceSpan, absoluteOffset) {
var sourceInfo = (sourceSpan && sourceSpan.start || '(unknown)').toString();
try {
var ast = isHostBinding ?
this._exprParser.parseSimpleBinding(value, sourceInfo, absoluteOffset, this._interpolationConfig) :
this._exprParser.parseBinding(value, sourceInfo, absoluteOffset, this._interpolationConfig);
if (ast)
this._reportExpressionParserErrors(ast.errors, sourceSpan);
this._checkPipes(ast, sourceSpan);
return ast;
}
catch (e) {
this._reportError("" + e, sourceSpan);
return this._exprParser.wrapLiteralPrimitive('ERROR', sourceInfo, absoluteOffset);
}
};
BindingParser.prototype.createBoundElementProperty = function (elementSelector, boundProp, skipValidation, mapPropertyName) {
if (skipValidation === void 0) { skipValidation = false; }
if (mapPropertyName === void 0) { mapPropertyName = true; }
if (boundProp.isAnimation) {
return new ast_1.BoundElementProperty(boundProp.name, 4 /* Animation */, core_1.SecurityContext.NONE, boundProp.expression, null, boundProp.sourceSpan, boundProp.keySpan, boundProp.valueSpan);
}
var unit = null;
var bindingType = undefined;
var boundPropertyName = null;
var parts = boundProp.name.split(PROPERTY_PARTS_SEPARATOR);
var securityContexts = undefined;
// Check for special cases (prefix style, attr, class)
if (parts.length > 1) {
if (parts[0] == ATTRIBUTE_PREFIX) {
boundPropertyName = parts.slice(1).join(PROPERTY_PARTS_SEPARATOR);
if (!skipValidation) {
this._validatePropertyOrAttributeName(boundPropertyName, boundProp.sourceSpan, true);
}
securityContexts = calcPossibleSecurityContexts(this._schemaRegistry, elementSelector, boundPropertyName, true);
var nsSeparatorIdx = boundPropertyName.indexOf(':');
if (nsSeparatorIdx > -1) {
var ns = boundPropertyName.substring(0, nsSeparatorIdx);
var name_1 = boundPropertyName.substring(nsSeparatorIdx + 1);
boundPropertyName = tags_1.mergeNsAndName(ns, name_1);
}
bindingType = 1 /* Attribute */;
}
else if (parts[0] == CLASS_PREFIX) {
boundPropertyName = parts[1];
bindingType = 2 /* Class */;
securityContexts = [core_1.SecurityContext.NONE];
}
else if (parts[0] == STYLE_PREFIX) {
unit = parts.length > 2 ? parts[2] : null;
boundPropertyName = parts[1];
bindingType = 3 /* Style */;
securityContexts = [core_1.SecurityContext.STYLE];
}
}
// If not a special case, use the full property name
if (boundPropertyName === null) {
var mappedPropName = this._schemaRegistry.getMappedPropName(boundProp.name);
boundPropertyName = mapPropertyName ? mappedPropName : boundProp.name;
securityContexts = calcPossibleSecurityContexts(this._schemaRegistry, elementSelector, mappedPropName, false);
bindingType = 0 /* Property */;
if (!skipValidation) {
this._validatePropertyOrAttributeName(mappedPropName, boundProp.sourceSpan, false);
}
}
return new ast_1.BoundElementProperty(boundPropertyName, bindingType, securityContexts[0], boundProp.expression, unit, boundProp.sourceSpan, boundProp.keySpan, boundProp.valueSpan);
};
BindingParser.prototype.parseEvent = function (name, expression, sourceSpan, handlerSpan, targetMatchableAttrs, targetEvents) {
if (name.length === 0) {
this._reportError("Event name is missing in binding", sourceSpan);
}
if (isAnimationLabel(name)) {
name = name.substr(1);
this._parseAnimationEvent(name, expression, sourceSpan, handlerSpan, targetEvents);
}
else {
this._parseRegularEvent(name, expression, sourceSpan, handlerSpan, targetMatchableAttrs, targetEvents);
}
};
BindingParser.prototype.calcPossibleSecurityContexts = function (selector, propName, isAttribute) {
var prop = this._schemaRegistry.getMappedPropName(propName);
return calcPossibleSecurityContexts(this._schemaRegistry, selector, prop, isAttribute);
};
BindingParser.prototype._parseAnimationEvent = function (name, expression, sourceSpan, handlerSpan, targetEvents) {
var matches = util_1.splitAtPeriod(name, [name, '']);
var eventName = matches[0];
var phase = matches[1].toLowerCase();
if (phase) {
switch (phase) {
case 'start':
case 'done':
var ast = this._parseAction(expression, handlerSpan);
targetEvents.push(new ast_1.ParsedEvent(eventName, phase, 1 /* Animation */, ast, sourceSpan, handlerSpan));
break;
default:
this._reportError("The provided animation output phase value \"" + phase + "\" for \"@" + eventName + "\" is not supported (use start or done)", sourceSpan);
break;
}
}
else {
this._reportError("The animation trigger output event (@" + eventName + ") is missing its phase value name (start or done are currently supported)", sourceSpan);
}
};
BindingParser.prototype._parseRegularEvent = function (name, expression, sourceSpan, handlerSpan, targetMatchableAttrs, targetEvents) {
// long format: 'target: eventName'
var _a = tslib_1.__read(util_1.splitAtColon(name, [null, name]), 2), target = _a[0], eventName = _a[1];
var ast = this._parseAction(expression, handlerSpan);
targetMatchableAttrs.push([name, ast.source]);
targetEvents.push(new ast_1.ParsedEvent(eventName, target, 0 /* Regular */, ast, sourceSpan, handlerSpan));
// Don't detect directives for event names for now,
// so don't add the event name to the matchableAttrs
};
BindingParser.prototype._parseAction = function (value, sourceSpan) {
var sourceInfo = (sourceSpan && sourceSpan.start || '(unknown').toString();
var absoluteOffset = (sourceSpan && sourceSpan.start) ? sourceSpan.start.offset : 0;
try {
var ast = this._exprParser.parseAction(value, sourceInfo, absoluteOffset, this._interpolationConfig);
if (ast) {
this._reportExpressionParserErrors(ast.errors, sourceSpan);
}
if (!ast || ast.ast instanceof ast_1.EmptyExpr) {
this._reportError("Empty expressions are not allowed", sourceSpan);
return this._exprParser.wrapLiteralPrimitive('ERROR', sourceInfo, absoluteOffset);
}
this._checkPipes(ast, sourceSpan);
return ast;
}
catch (e) {
this._reportError("" + e, sourceSpan);
return this._exprParser.wrapLiteralPrimitive('ERROR', sourceInfo, absoluteOffset);
}
};
BindingParser.prototype._reportError = function (message, sourceSpan, level) {
if (level === void 0) { level = parse_util_1.ParseErrorLevel.ERROR; }
this.errors.push(new parse_util_1.ParseError(sourceSpan, message, level));
};
BindingParser.prototype._reportExpressionParserErrors = function (errors, sourceSpan) {
var e_2, _a;
try {
for (var errors_1 = tslib_1.__values(errors), errors_1_1 = errors_1.next(); !errors_1_1.done; errors_1_1 = errors_1.next()) {
var error = errors_1_1.value;
this._reportError(error.message, sourceSpan);
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (errors_1_1 && !errors_1_1.done && (_a = errors_1.return)) _a.call(errors_1);
}
finally { if (e_2) throw e_2.error; }
}
};
// Make sure all the used pipes are known in `this.pipesByName`
BindingParser.prototype._checkPipes = function (ast, sourceSpan) {
var _this = this;
if (ast && this.pipesByName) {
var collector = new PipeCollector();
ast.visit(collector);
collector.pipes.forEach(function (ast, pipeName) {
var pipeMeta = _this.pipesByName.get(pipeName);
if (!pipeMeta) {
_this._reportError("The pipe '" + pipeName + "' could not be found", new parse_util_1.ParseSourceSpan(sourceSpan.start.moveBy(ast.span.start), sourceSpan.start.moveBy(ast.span.end)));
}
else {
_this._usedPipes.set(pipeName, pipeMeta);
}
});
}
};
/**
* @param propName the name of the property / attribute
* @param sourceSpan
* @param isAttr true when binding to an attribute
*/
BindingParser.prototype._validatePropertyOrAttributeName = function (propName, sourceSpan, isAttr) {
var report = isAttr ? this._schemaRegistry.validateAttribute(propName) :
this._schemaRegistry.validateProperty(propName);
if (report.error) {
this._reportError(report.msg, sourceSpan, parse_util_1.ParseErrorLevel.ERROR);
}
};
return BindingParser;
}());
exports.BindingParser = BindingParser;
var PipeCollector = /** @class */ (function (_super) {
tslib_1.__extends(PipeCollector, _super);
function PipeCollector() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.pipes = new Map();
return _this;
}
PipeCollector.prototype.visitPipe = function (ast, context) {
this.pipes.set(ast.name, ast);
ast.exp.visit(this);
this.visitAll(ast.args, context);
return null;
};
return PipeCollector;
}(ast_1.RecursiveAstVisitor));
exports.PipeCollector = PipeCollector;
function isAnimationLabel(name) {
return name[0] == '@';
}
function calcPossibleSecurityContexts(registry, selector, propName, isAttribute) {
var ctxs = [];
selector_1.CssSelector.parse(selector).forEach(function (selector) {
var elementNames = selector.element ? [selector.element] : registry.allKnownElementNames();
var notElementNames = new Set(selector.notSelectors.filter(function (selector) { return selector.isElementSelector(); })
.map(function (selector) { return selector.element; }));
var possibleElementNames = elementNames.filter(function (elementName) { return !notElementNames.has(elementName); });
ctxs.push.apply(ctxs, tslib_1.__spread(possibleElementNames.map(function (elementName) { return registry.securityContext(elementName, propName, isAttribute); })));
});
return ctxs.length === 0 ? [core_1.SecurityContext.NONE] : Array.from(new Set(ctxs)).sort();
}
exports.calcPossibleSecurityContexts = calcPossibleSecurityContexts;
/**
* Compute a new ParseSourceSpan based off an original `sourceSpan` by using
* absolute offsets from the specified `absoluteSpan`.
*
* @param sourceSpan original source span
* @param absoluteSpan absolute source span to move to
*/
function moveParseSourceSpan(sourceSpan, absoluteSpan) {
// The difference of two absolute offsets provide the relative offset
var startDiff = absoluteSpan.start - sourceSpan.start.offset;
var endDiff = absoluteSpan.end - sourceSpan.end.offset;
return new parse_util_1.ParseSourceSpan(sourceSpan.start.moveBy(startDiff), sourceSpan.end.moveBy(endDiff), sourceSpan.fullStart.moveBy(startDiff), sourceSpan.details);
}
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmluZGluZ19wYXJzZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb21waWxlci9zcmMvdGVtcGxhdGVfcGFyc2VyL2JpbmRpbmdfcGFyc2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRzs7Ozs7Ozs7Ozs7Ozs7SUFHSCxtREFBd0M7SUFDeEMsbUVBQTRSO0lBRzVSLDZEQUFpRDtJQUNqRCwrREFBMEY7SUFFMUYsMkRBQXdDO0lBQ3hDLG1EQUFvRDtJQUVwRCxJQUFNLHdCQUF3QixHQUFHLEdBQUcsQ0FBQztJQUNyQyxJQUFNLGdCQUFnQixHQUFHLE1BQU0sQ0FBQztJQUNoQyxJQUFNLFlBQVksR0FBRyxPQUFPLENBQUM7SUFDN0IsSUFBTSxZQUFZLEdBQUcsT0FBTyxDQUFDO0lBQzdCLElBQU0sb0JBQW9CLEdBQUcsR0FBRyxDQUFDO0lBQ2pDLElBQU0sbUJBQW1CLEdBQUcsVUFBVSxDQUFDO0lBRXZDOztPQUVHO0lBQ0g7UUFLRSx1QkFDWSxXQUFtQixFQUFVLG9CQUF5QyxFQUN0RSxlQUFzQyxFQUFFLEtBQWdDLEVBQ3pFLE1BQW9CO1lBRm5CLGdCQUFXLEdBQVgsV0FBVyxDQUFRO1lBQVUseUJBQW9CLEdBQXBCLG9CQUFvQixDQUFxQjtZQUN0RSxvQkFBZSxHQUFmLGVBQWUsQ0FBdUI7WUFDdkMsV0FBTSxHQUFOLE1BQU0sQ0FBYztZQVAvQixnQkFBVyxHQUF5QyxJQUFJLENBQUM7WUFFakQsZUFBVSxHQUFvQyxJQUFJLEdBQUcsRUFBRSxDQUFDO1lBTTlELG9FQUFvRTtZQUNwRSxpRkFBaUY7WUFDakYsSUFBSSxLQUFLLEVBQUU7Z0JBQ1QsSUFBTSxhQUFXLEdBQW9DLElBQUksR0FBRyxFQUFFLENBQUM7Z0JBQy9ELEtBQUssQ0FBQyxPQUFPLENBQUMsVUFBQSxJQUFJLElBQUksT0FBQSxhQUFXLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLEVB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