UNPKG

@angular/compiler

Version:

Angular - the compiler library

684 lines 123 kB
/** * @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 { identifierName, sanitizeIdentifier } from '../../compile_metadata'; import { BindingForm, convertPropertyBinding } from '../../compiler_util/expression_converter'; import * as core from '../../core'; import { DEFAULT_INTERPOLATION_CONFIG } from '../../ml_parser/interpolation_config'; import * as o from '../../output/output_ast'; import { CssSelector, SelectorMatcher } from '../../selector'; import { ShadowCss } from '../../shadow_css'; import { CONTENT_ATTR, HOST_ATTR } from '../../style_compiler'; import { error } from '../../util'; import { BoundEvent } from '../r3_ast'; import { compileFactoryFunction, R3FactoryTarget } from '../r3_factory'; import { Identifiers as R3 } from '../r3_identifiers'; import { prepareSyntheticListenerFunctionName, prepareSyntheticPropertyName, typeWithParameters } from '../util'; import { MIN_STYLING_BINDING_SLOTS_REQUIRED, StylingBuilder } from './styling_builder'; import { BindingScope, makeBindingParser, prepareEventListenerParameters, renderFlagCheckIfStmt, resolveSanitizationFn, TemplateDefinitionBuilder, ValueConverter } from './template'; import { asLiteral, chainedInstruction, conditionallyCreateMapObjectLiteral, CONTEXT_NAME, DefinitionMap, getQueryPredicate, RENDER_FLAGS, TEMPORARY_NAME, temporaryAllocator } from './util'; const EMPTY_ARRAY = []; // This regex matches any binding names that contain the "attr." prefix, e.g. "attr.required" // If there is a match, the first matching group will contain the attribute name to bind. const ATTR_REGEX = /attr\.([^\]]+)/; function baseDirectiveFields(meta, constantPool, bindingParser) { const definitionMap = new DefinitionMap(); const selectors = core.parseSelectorToR3Selector(meta.selector); // e.g. `type: MyDirective` definitionMap.set('type', meta.internalType); // e.g. `selectors: [['', 'someDir', '']]` if (selectors.length > 0) { definitionMap.set('selectors', asLiteral(selectors)); } if (meta.queries.length > 0) { // e.g. `contentQueries: (rf, ctx, dirIndex) => { ... } definitionMap.set('contentQueries', createContentQueriesFunction(meta.queries, constantPool, meta.name)); } if (meta.viewQueries.length) { definitionMap.set('viewQuery', createViewQueriesFunction(meta.viewQueries, constantPool, meta.name)); } // e.g. `hostBindings: (rf, ctx) => { ... } definitionMap.set('hostBindings', createHostBindingsFunction(meta.host, meta.typeSourceSpan, bindingParser, constantPool, meta.selector || '', meta.name, definitionMap)); // e.g 'inputs: {a: 'a'}` definitionMap.set('inputs', conditionallyCreateMapObjectLiteral(meta.inputs, true)); // e.g 'outputs: {a: 'a'}` definitionMap.set('outputs', conditionallyCreateMapObjectLiteral(meta.outputs)); if (meta.exportAs !== null) { definitionMap.set('exportAs', o.literalArr(meta.exportAs.map(e => o.literal(e)))); } return definitionMap; } /** * Add features to the definition map. */ function addFeatures(definitionMap, meta) { // e.g. `features: [NgOnChangesFeature]` const features = []; const providers = meta.providers; const viewProviders = meta.viewProviders; if (providers || viewProviders) { const args = [providers || new o.LiteralArrayExpr([])]; if (viewProviders) { args.push(viewProviders); } features.push(o.importExpr(R3.ProvidersFeature).callFn(args)); } if (meta.usesInheritance) { features.push(o.importExpr(R3.InheritDefinitionFeature)); } if (meta.fullInheritance) { features.push(o.importExpr(R3.CopyDefinitionFeature)); } if (meta.lifecycle.usesOnChanges) { features.push(o.importExpr(R3.NgOnChangesFeature)); } if (features.length) { definitionMap.set('features', o.literalArr(features)); } } /** * Compile a directive for the render3 runtime as defined by the `R3DirectiveMetadata`. */ export function compileDirectiveFromMetadata(meta, constantPool, bindingParser) { const definitionMap = baseDirectiveFields(meta, constantPool, bindingParser); addFeatures(definitionMap, meta); const expression = o.importExpr(R3.defineDirective).callFn([definitionMap.toLiteralMap()]); const typeParams = createDirectiveTypeParams(meta); const type = o.expressionType(o.importExpr(R3.DirectiveDefWithMeta, typeParams)); return { expression, type }; } /** * Compile a component for the render3 runtime as defined by the `R3ComponentMetadata`. */ export function compileComponentFromMetadata(meta, constantPool, bindingParser) { const definitionMap = baseDirectiveFields(meta, constantPool, bindingParser); addFeatures(definitionMap, meta); const selector = meta.selector && CssSelector.parse(meta.selector); const firstSelector = selector && selector[0]; // e.g. `attr: ["class", ".my.app"]` // This is optional an only included if the first selector of a component specifies attributes. if (firstSelector) { const selectorAttributes = firstSelector.getAttrs(); if (selectorAttributes.length) { definitionMap.set('attrs', constantPool.getConstLiteral(o.literalArr(selectorAttributes.map(value => value != null ? o.literal(value) : o.literal(undefined))), /* forceShared */ true)); } } // Generate the CSS matcher that recognize directive let directiveMatcher = null; if (meta.directives.length > 0) { const matcher = new SelectorMatcher(); for (const { selector, expression } of meta.directives) { matcher.addSelectables(CssSelector.parse(selector), expression); } directiveMatcher = matcher; } // e.g. `template: function MyComponent_Template(_ctx, _cm) {...}` const templateTypeName = meta.name; const templateName = templateTypeName ? `${templateTypeName}_Template` : null; const directivesUsed = new Set(); const pipesUsed = new Set(); const changeDetection = meta.changeDetection; const template = meta.template; const templateBuilder = new TemplateDefinitionBuilder(constantPool, BindingScope.createRootScope(), 0, templateTypeName, null, null, templateName, directiveMatcher, directivesUsed, meta.pipes, pipesUsed, R3.namespaceHTML, meta.relativeContextFilePath, meta.i18nUseExternalIds); const templateFunctionExpression = templateBuilder.buildTemplateFunction(template.nodes, []); // We need to provide this so that dynamically generated components know what // projected content blocks to pass through to the component when it is instantiated. const ngContentSelectors = templateBuilder.getNgContentSelectors(); if (ngContentSelectors) { definitionMap.set('ngContentSelectors', ngContentSelectors); } // e.g. `decls: 2` definitionMap.set('decls', o.literal(templateBuilder.getConstCount())); // e.g. `vars: 2` definitionMap.set('vars', o.literal(templateBuilder.getVarCount())); // Generate `consts` section of ComponentDef: // - either as an array: // `consts: [['one', 'two'], ['three', 'four']]` // - or as a factory function in case additional statements are present (to support i18n): // `consts: function() { var i18n_0; if (ngI18nClosureMode) {...} else {...} return [i18n_0]; }` const { constExpressions, prepareStatements } = templateBuilder.getConsts(); if (constExpressions.length > 0) { let constsExpr = o.literalArr(constExpressions); // Prepare statements are present - turn `consts` into a function. if (prepareStatements.length > 0) { constsExpr = o.fn([], [...prepareStatements, new o.ReturnStatement(constsExpr)]); } definitionMap.set('consts', constsExpr); } definitionMap.set('template', templateFunctionExpression); // e.g. `directives: [MyDirective]` if (directivesUsed.size) { let directivesExpr = o.literalArr(Array.from(directivesUsed)); if (meta.wrapDirectivesAndPipesInClosure) { directivesExpr = o.fn([], [new o.ReturnStatement(directivesExpr)]); } definitionMap.set('directives', directivesExpr); } // e.g. `pipes: [MyPipe]` if (pipesUsed.size) { let pipesExpr = o.literalArr(Array.from(pipesUsed)); if (meta.wrapDirectivesAndPipesInClosure) { pipesExpr = o.fn([], [new o.ReturnStatement(pipesExpr)]); } definitionMap.set('pipes', pipesExpr); } if (meta.encapsulation === null) { meta.encapsulation = core.ViewEncapsulation.Emulated; } // e.g. `styles: [str1, str2]` if (meta.styles && meta.styles.length) { const styleValues = meta.encapsulation == core.ViewEncapsulation.Emulated ? compileStyles(meta.styles, CONTENT_ATTR, HOST_ATTR) : meta.styles; const strings = styleValues.map(str => constantPool.getConstLiteral(o.literal(str))); definitionMap.set('styles', o.literalArr(strings)); } else if (meta.encapsulation === core.ViewEncapsulation.Emulated) { // If there is no style, don't generate css selectors on elements meta.encapsulation = core.ViewEncapsulation.None; } // Only set view encapsulation if it's not the default value if (meta.encapsulation !== core.ViewEncapsulation.Emulated) { definitionMap.set('encapsulation', o.literal(meta.encapsulation)); } // e.g. `animation: [trigger('123', [])]` if (meta.animations !== null) { definitionMap.set('data', o.literalMap([{ key: 'animation', value: meta.animations, quoted: false }])); } // Only set the change detection flag if it's defined and it's not the default. if (changeDetection != null && changeDetection !== core.ChangeDetectionStrategy.Default) { definitionMap.set('changeDetection', o.literal(changeDetection)); } const expression = o.importExpr(R3.defineComponent).callFn([definitionMap.toLiteralMap()]); const typeParams = createDirectiveTypeParams(meta); typeParams.push(stringArrayAsType(meta.template.ngContentSelectors)); const type = o.expressionType(o.importExpr(R3.ComponentDefWithMeta, typeParams)); return { expression, type }; } /** * A wrapper around `compileDirective` which depends on render2 global analysis data as its input * instead of the `R3DirectiveMetadata`. * * `R3DirectiveMetadata` is computed from `CompileDirectiveMetadata` and other statically reflected * information. */ export function compileDirectiveFromRender2(outputCtx, directive, reflector, bindingParser) { const name = identifierName(directive.type); name || error(`Cannot resolver the name of ${directive.type}`); const definitionField = outputCtx.constantPool.propertyNameOf(1 /* Directive */); const meta = directiveMetadataFromGlobalMetadata(directive, outputCtx, reflector); const res = compileDirectiveFromMetadata(meta, outputCtx.constantPool, bindingParser); const factoryRes = compileFactoryFunction(Object.assign(Object.assign({}, meta), { injectFn: R3.directiveInject, target: R3FactoryTarget.Directive })); const ngFactoryDefStatement = new o.ClassStmt(name, null, [new o.ClassField('ɵfac', o.INFERRED_TYPE, [o.StmtModifier.Static], factoryRes.factory)], [], new o.ClassMethod(null, [], []), []); const directiveDefStatement = new o.ClassStmt(name, null, [new o.ClassField(definitionField, o.INFERRED_TYPE, [o.StmtModifier.Static], res.expression)], [], new o.ClassMethod(null, [], []), []); // Create the partial class to be merged with the actual class. outputCtx.statements.push(ngFactoryDefStatement, directiveDefStatement); } /** * A wrapper around `compileComponent` which depends on render2 global analysis data as its input * instead of the `R3DirectiveMetadata`. * * `R3ComponentMetadata` is computed from `CompileDirectiveMetadata` and other statically reflected * information. */ export function compileComponentFromRender2(outputCtx, component, render3Ast, reflector, bindingParser, directiveTypeBySel, pipeTypeByName) { const name = identifierName(component.type); name || error(`Cannot resolver the name of ${component.type}`); const definitionField = outputCtx.constantPool.propertyNameOf(2 /* Component */); const summary = component.toSummary(); // Compute the R3ComponentMetadata from the CompileDirectiveMetadata const meta = Object.assign(Object.assign({}, directiveMetadataFromGlobalMetadata(component, outputCtx, reflector)), { selector: component.selector, template: { nodes: render3Ast.nodes, ngContentSelectors: render3Ast.ngContentSelectors }, directives: [], pipes: typeMapToExpressionMap(pipeTypeByName, outputCtx), viewQueries: queriesFromGlobalMetadata(component.viewQueries, outputCtx), wrapDirectivesAndPipesInClosure: false, styles: (summary.template && summary.template.styles) || EMPTY_ARRAY, encapsulation: (summary.template && summary.template.encapsulation) || core.ViewEncapsulation.Emulated, interpolation: DEFAULT_INTERPOLATION_CONFIG, animations: null, viewProviders: component.viewProviders.length > 0 ? new o.WrappedNodeExpr(component.viewProviders) : null, relativeContextFilePath: '', i18nUseExternalIds: true }); const res = compileComponentFromMetadata(meta, outputCtx.constantPool, bindingParser); const factoryRes = compileFactoryFunction(Object.assign(Object.assign({}, meta), { injectFn: R3.directiveInject, target: R3FactoryTarget.Directive })); const ngFactoryDefStatement = new o.ClassStmt(name, null, [new o.ClassField('ɵfac', o.INFERRED_TYPE, [o.StmtModifier.Static], factoryRes.factory)], [], new o.ClassMethod(null, [], []), []); const componentDefStatement = new o.ClassStmt(name, null, [new o.ClassField(definitionField, o.INFERRED_TYPE, [o.StmtModifier.Static], res.expression)], [], new o.ClassMethod(null, [], []), []); // Create the partial class to be merged with the actual class. outputCtx.statements.push(ngFactoryDefStatement, componentDefStatement); } /** * Compute `R3DirectiveMetadata` given `CompileDirectiveMetadata` and a `CompileReflector`. */ function directiveMetadataFromGlobalMetadata(directive, outputCtx, reflector) { // The global-analysis based Ivy mode in ngc is no longer utilized/supported. throw new Error('unsupported'); } /** * Convert `CompileQueryMetadata` into `R3QueryMetadata`. */ function queriesFromGlobalMetadata(queries, outputCtx) { return queries.map(query => { let read = null; if (query.read && query.read.identifier) { read = outputCtx.importExpr(query.read.identifier.reference); } return { propertyName: query.propertyName, first: query.first, predicate: selectorsFromGlobalMetadata(query.selectors, outputCtx), descendants: query.descendants, read, static: !!query.static }; }); } /** * Convert `CompileTokenMetadata` for query selectors into either an expression for a predicate * type, or a list of string predicates. */ function selectorsFromGlobalMetadata(selectors, outputCtx) { if (selectors.length > 1 || (selectors.length == 1 && selectors[0].value)) { const selectorStrings = selectors.map(value => value.value); selectorStrings.some(value => !value) && error('Found a type among the string selectors expected'); return outputCtx.constantPool.getConstLiteral(o.literalArr(selectorStrings.map(value => o.literal(value)))); } if (selectors.length == 1) { const first = selectors[0]; if (first.identifier) { return outputCtx.importExpr(first.identifier.reference); } } error('Unexpected query form'); return o.NULL_EXPR; } function prepareQueryParams(query, constantPool) { const parameters = [getQueryPredicate(query, constantPool), o.literal(query.descendants)]; if (query.read) { parameters.push(query.read); } return parameters; } function convertAttributesToExpressions(attributes) { const values = []; for (let key of Object.getOwnPropertyNames(attributes)) { const value = attributes[key]; values.push(o.literal(key), value); } return values; } // Define and update any content queries function createContentQueriesFunction(queries, constantPool, name) { const createStatements = []; const updateStatements = []; const tempAllocator = temporaryAllocator(updateStatements, TEMPORARY_NAME); for (const query of queries) { const queryInstruction = query.static ? R3.staticContentQuery : R3.contentQuery; // creation, e.g. r3.contentQuery(dirIndex, somePredicate, true, null); createStatements.push(o.importExpr(queryInstruction) .callFn([o.variable('dirIndex'), ...prepareQueryParams(query, constantPool)]) .toStmt()); // update, e.g. (r3.queryRefresh(tmp = r3.loadQuery()) && (ctx.someDir = tmp)); const temporary = tempAllocator(); const getQueryList = o.importExpr(R3.loadQuery).callFn([]); const refresh = o.importExpr(R3.queryRefresh).callFn([temporary.set(getQueryList)]); const updateDirective = o.variable(CONTEXT_NAME) .prop(query.propertyName) .set(query.first ? temporary.prop('first') : temporary); updateStatements.push(refresh.and(updateDirective).toStmt()); } const contentQueriesFnName = name ? `${name}_ContentQueries` : null; return o.fn([ new o.FnParam(RENDER_FLAGS, o.NUMBER_TYPE), new o.FnParam(CONTEXT_NAME, null), new o.FnParam('dirIndex', null) ], [ renderFlagCheckIfStmt(1 /* Create */, createStatements), renderFlagCheckIfStmt(2 /* Update */, updateStatements) ], o.INFERRED_TYPE, null, contentQueriesFnName); } function stringAsType(str) { return o.expressionType(o.literal(str)); } function stringMapAsType(map) { const mapValues = Object.keys(map).map(key => { const value = Array.isArray(map[key]) ? map[key][0] : map[key]; return { key, value: o.literal(value), quoted: true, }; }); return o.expressionType(o.literalMap(mapValues)); } function stringArrayAsType(arr) { return arr.length > 0 ? o.expressionType(o.literalArr(arr.map(value => o.literal(value)))) : o.NONE_TYPE; } function createDirectiveTypeParams(meta) { // On the type side, remove newlines from the selector as it will need to fit into a TypeScript // string literal, which must be on one line. const selectorForType = meta.selector !== null ? meta.selector.replace(/\n/g, '') : null; return [ typeWithParameters(meta.type.type, meta.typeArgumentCount), selectorForType !== null ? stringAsType(selectorForType) : o.NONE_TYPE, meta.exportAs !== null ? stringArrayAsType(meta.exportAs) : o.NONE_TYPE, stringMapAsType(meta.inputs), stringMapAsType(meta.outputs), stringArrayAsType(meta.queries.map(q => q.propertyName)), ]; } // Define and update any view queries function createViewQueriesFunction(viewQueries, constantPool, name) { const createStatements = []; const updateStatements = []; const tempAllocator = temporaryAllocator(updateStatements, TEMPORARY_NAME); viewQueries.forEach((query) => { const queryInstruction = query.static ? R3.staticViewQuery : R3.viewQuery; // creation, e.g. r3.viewQuery(somePredicate, true); const queryDefinition = o.importExpr(queryInstruction).callFn(prepareQueryParams(query, constantPool)); createStatements.push(queryDefinition.toStmt()); // update, e.g. (r3.queryRefresh(tmp = r3.loadQuery()) && (ctx.someDir = tmp)); const temporary = tempAllocator(); const getQueryList = o.importExpr(R3.loadQuery).callFn([]); const refresh = o.importExpr(R3.queryRefresh).callFn([temporary.set(getQueryList)]); const updateDirective = o.variable(CONTEXT_NAME) .prop(query.propertyName) .set(query.first ? temporary.prop('first') : temporary); updateStatements.push(refresh.and(updateDirective).toStmt()); }); const viewQueryFnName = name ? `${name}_Query` : null; return o.fn([new o.FnParam(RENDER_FLAGS, o.NUMBER_TYPE), new o.FnParam(CONTEXT_NAME, null)], [ renderFlagCheckIfStmt(1 /* Create */, createStatements), renderFlagCheckIfStmt(2 /* Update */, updateStatements) ], o.INFERRED_TYPE, null, viewQueryFnName); } // Return a host binding function or null if one is not necessary. function createHostBindingsFunction(hostBindingsMetadata, typeSourceSpan, bindingParser, constantPool, selector, name, definitionMap) { const bindingContext = o.variable(CONTEXT_NAME); const styleBuilder = new StylingBuilder(bindingContext); const { styleAttr, classAttr } = hostBindingsMetadata.specialAttributes; if (styleAttr !== undefined) { styleBuilder.registerStyleAttr(styleAttr); } if (classAttr !== undefined) { styleBuilder.registerClassAttr(classAttr); } const createStatements = []; const updateStatements = []; const hostBindingSourceSpan = typeSourceSpan; const directiveSummary = metadataAsSummary(hostBindingsMetadata); // Calculate host event bindings const eventBindings = bindingParser.createDirectiveHostEventAsts(directiveSummary, hostBindingSourceSpan); if (eventBindings && eventBindings.length) { const listeners = createHostListeners(eventBindings, name); createStatements.push(...listeners); } // Calculate the host property bindings const bindings = bindingParser.createBoundHostProperties(directiveSummary, hostBindingSourceSpan); const allOtherBindings = []; // We need to calculate the total amount of binding slots required by // all the instructions together before any value conversions happen. // Value conversions may require additional slots for interpolation and // bindings with pipes. These calculates happen after this block. let totalHostVarsCount = 0; bindings && bindings.forEach((binding) => { const stylingInputWasSet = styleBuilder.registerInputBasedOnName(binding.name, binding.expression, hostBindingSourceSpan); if (stylingInputWasSet) { totalHostVarsCount += MIN_STYLING_BINDING_SLOTS_REQUIRED; } else { allOtherBindings.push(binding); totalHostVarsCount++; } }); let valueConverter; const getValueConverter = () => { if (!valueConverter) { const hostVarsCountFn = (numSlots) => { const originalVarsCount = totalHostVarsCount; totalHostVarsCount += numSlots; return originalVarsCount; }; valueConverter = new ValueConverter(constantPool, () => error('Unexpected node'), // new nodes are illegal here hostVarsCountFn, () => error('Unexpected pipe')); // pipes are illegal here } return valueConverter; }; const propertyBindings = []; const attributeBindings = []; const syntheticHostBindings = []; allOtherBindings.forEach((binding) => { // resolve literal arrays and literal objects const value = binding.expression.visit(getValueConverter()); const bindingExpr = bindingFn(bindingContext, value); const { bindingName, instruction, isAttribute } = getBindingNameAndInstruction(binding); const securityContexts = bindingParser.calcPossibleSecurityContexts(selector, bindingName, isAttribute) .filter(context => context !== core.SecurityContext.NONE); let sanitizerFn = null; if (securityContexts.length) { if (securityContexts.length === 2 && securityContexts.indexOf(core.SecurityContext.URL) > -1 && securityContexts.indexOf(core.SecurityContext.RESOURCE_URL) > -1) { // Special case for some URL attributes (such as "src" and "href") that may be a part // of different security contexts. In this case we use special santitization function and // select the actual sanitizer at runtime based on a tag name that is provided while // invoking sanitization function. sanitizerFn = o.importExpr(R3.sanitizeUrlOrResourceUrl); } else { sanitizerFn = resolveSanitizationFn(securityContexts[0], isAttribute); } } const instructionParams = [o.literal(bindingName), bindingExpr.currValExpr]; if (sanitizerFn) { instructionParams.push(sanitizerFn); } updateStatements.push(...bindingExpr.stmts); if (instruction === R3.hostProperty) { propertyBindings.push(instructionParams); } else if (instruction === R3.attribute) { attributeBindings.push(instructionParams); } else if (instruction === R3.syntheticHostProperty) { syntheticHostBindings.push(instructionParams); } else { updateStatements.push(o.importExpr(instruction).callFn(instructionParams).toStmt()); } }); if (propertyBindings.length > 0) { updateStatements.push(chainedInstruction(R3.hostProperty, propertyBindings).toStmt()); } if (attributeBindings.length > 0) { updateStatements.push(chainedInstruction(R3.attribute, attributeBindings).toStmt()); } if (syntheticHostBindings.length > 0) { updateStatements.push(chainedInstruction(R3.syntheticHostProperty, syntheticHostBindings).toStmt()); } // since we're dealing with directives/components and both have hostBinding // functions, we need to generate a special hostAttrs instruction that deals // with both the assignment of styling as well as static attributes to the host // element. The instruction below will instruct all initial styling (styling // that is inside of a host binding within a directive/component) to be attached // to the host element alongside any of the provided host attributes that were // collected earlier. const hostAttrs = convertAttributesToExpressions(hostBindingsMetadata.attributes); styleBuilder.assignHostAttrs(hostAttrs, definitionMap); if (styleBuilder.hasBindings) { // finally each binding that was registered in the statement above will need to be added to // the update block of a component/directive templateFn/hostBindingsFn so that the bindings // are evaluated and updated for the element. styleBuilder.buildUpdateLevelInstructions(getValueConverter()).forEach(instruction => { if (instruction.calls.length > 0) { const calls = []; instruction.calls.forEach(call => { // we subtract a value of `1` here because the binding slot was already allocated // at the top of this method when all the input bindings were counted. totalHostVarsCount += Math.max(call.allocateBindingSlots - MIN_STYLING_BINDING_SLOTS_REQUIRED, 0); calls.push(convertStylingCall(call, bindingContext, bindingFn)); }); updateStatements.push(chainedInstruction(instruction.reference, calls).toStmt()); } }); } if (totalHostVarsCount) { definitionMap.set('hostVars', o.literal(totalHostVarsCount)); } if (createStatements.length > 0 || updateStatements.length > 0) { const hostBindingsFnName = name ? `${name}_HostBindings` : null; const statements = []; if (createStatements.length > 0) { statements.push(renderFlagCheckIfStmt(1 /* Create */, createStatements)); } if (updateStatements.length > 0) { statements.push(renderFlagCheckIfStmt(2 /* Update */, updateStatements)); } return o.fn([new o.FnParam(RENDER_FLAGS, o.NUMBER_TYPE), new o.FnParam(CONTEXT_NAME, null)], statements, o.INFERRED_TYPE, null, hostBindingsFnName); } return null; } function bindingFn(implicit, value) { return convertPropertyBinding(null, implicit, value, 'b', BindingForm.Expression, () => error('Unexpected interpolation')); } function convertStylingCall(call, bindingContext, bindingFn) { return call.params(value => bindingFn(bindingContext, value).currValExpr); } function getBindingNameAndInstruction(binding) { let bindingName = binding.name; let instruction; // Check to see if this is an attr binding or a property binding const attrMatches = bindingName.match(ATTR_REGEX); if (attrMatches) { bindingName = attrMatches[1]; instruction = R3.attribute; } else { if (binding.isAnimation) { bindingName = prepareSyntheticPropertyName(bindingName); // host bindings that have a synthetic property (e.g. @foo) should always be rendered // in the context of the component and not the parent. Therefore there is a special // compatibility instruction available for this purpose. instruction = R3.syntheticHostProperty; } else { instruction = R3.hostProperty; } } return { bindingName, instruction, isAttribute: !!attrMatches }; } function createHostListeners(eventBindings, name) { const listeners = []; const syntheticListeners = []; const instructions = []; eventBindings.forEach(binding => { let bindingName = binding.name && sanitizeIdentifier(binding.name); const bindingFnName = binding.type === 1 /* Animation */ ? prepareSyntheticListenerFunctionName(bindingName, binding.targetOrPhase) : bindingName; const handlerName = name && bindingName ? `${name}_${bindingFnName}_HostBindingHandler` : null; const params = prepareEventListenerParameters(BoundEvent.fromParsedEvent(binding), handlerName); if (binding.type == 1 /* Animation */) { syntheticListeners.push(params); } else { listeners.push(params); } }); if (syntheticListeners.length > 0) { instructions.push(chainedInstruction(R3.syntheticHostListener, syntheticListeners).toStmt()); } if (listeners.length > 0) { instructions.push(chainedInstruction(R3.listener, listeners).toStmt()); } return instructions; } function metadataAsSummary(meta) { // clang-format off return { // This is used by the BindingParser, which only deals with listeners and properties. There's no // need to pass attributes to it. hostAttributes: {}, hostListeners: meta.listeners, hostProperties: meta.properties, }; // clang-format on } function typeMapToExpressionMap(map, outputCtx) { // Convert each map entry into another entry where the value is an expression importing the type. const entries = Array.from(map).map(([key, type]) => [key, outputCtx.importExpr(type)]); return new Map(entries); } const HOST_REG_EXP = /^(?:\[([^\]]+)\])|(?:\(([^\)]+)\))$/; export function parseHostBindings(host) { const attributes = {}; const listeners = {}; const properties = {}; const specialAttributes = {}; for (const key of Object.keys(host)) { const value = host[key]; const matches = key.match(HOST_REG_EXP); if (matches === null) { switch (key) { case 'class': if (typeof value !== 'string') { // TODO(alxhub): make this a diagnostic. throw new Error(`Class binding must be string`); } specialAttributes.classAttr = value; break; case 'style': if (typeof value !== 'string') { // TODO(alxhub): make this a diagnostic. throw new Error(`Style binding must be string`); } specialAttributes.styleAttr = value; break; default: if (typeof value === 'string') { attributes[key] = o.literal(value); } else { attributes[key] = value; } } } else if (matches[1 /* Binding */] != null) { if (typeof value !== 'string') { // TODO(alxhub): make this a diagnostic. throw new Error(`Property binding must be string`); } // synthetic properties (the ones that have a `@` as a prefix) // are still treated the same as regular properties. Therefore // there is no point in storing them in a separate map. properties[matches[1 /* Binding */]] = value; } else if (matches[2 /* Event */] != null) { if (typeof value !== 'string') { // TODO(alxhub): make this a diagnostic. throw new Error(`Event binding must be string`); } listeners[matches[2 /* Event */]] = value; } } return { attributes, listeners, properties, specialAttributes }; } /** * Verifies host bindings and returns the list of errors (if any). Empty array indicates that a * given set of host bindings has no errors. * * @param bindings set of host bindings to verify. * @param sourceSpan source span where host bindings were defined. * @returns array of errors associated with a given set of host bindings. */ export function verifyHostBindings(bindings, sourceSpan) { const summary = metadataAsSummary(bindings); // TODO: abstract out host bindings verification logic and use it instead of // creating events and properties ASTs to detect errors (FW-996) const bindingParser = makeBindingParser(); bindingParser.createDirectiveHostEventAsts(summary, sourceSpan); bindingParser.createBoundHostProperties(summary, sourceSpan); return bindingParser.errors; } function compileStyles(styles, selector, hostSelector) { const shadowCss = new ShadowCss(); return styles.map(style => { return shadowCss.shimCssText(style, selector, hostSelector); }); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcGlsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb21waWxlci9zcmMvcmVuZGVyMy92aWV3L2NvbXBpbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUdILE9BQU8sRUFBZ0csY0FBYyxFQUFFLGtCQUFrQixFQUFDLE1BQU0sd0JBQXdCLENBQUM7QUFFekssT0FBTyxFQUFDLFdBQVcsRUFBRSxzQkFBc0IsRUFBQyxNQUFNLDBDQUEwQyxDQUFDO0FBRTdGLE9BQU8sS0FBSyxJQUFJLE1BQU0sWUFBWSxDQUFDO0FBRW5DLE9BQU8sRUFBQyw0QkFBNEIsRUFBQyxNQUFNLHNDQUFzQyxDQUFDO0FBQ2xGLE9BQU8sS0FBSyxDQUFDLE1BQU0seUJBQXlCLENBQUM7QUFFN0MsT0FBTyxFQUFDLFdBQVcsRUFBRSxlQUFlLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUM1RCxPQUFPLEVBQUMsU0FBUyxFQUFDLE1BQU0sa0JBQWtCLENBQUM7QUFDM0MsT0FBTyxFQUFDLFlBQVksRUFBRSxTQUFTLEVBQUMsTUFBTSxzQkFBc0IsQ0FBQztBQUU3RCxPQUFPLEVBQUMsS0FBSyxFQUFnQixNQUFNLFlBQVksQ0FBQztBQUNoRCxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sV0FBVyxDQUFDO0FBQ3JDLE9BQU8sRUFBQyxzQkFBc0IsRUFBd0IsZUFBZSxFQUEyQixNQUFNLGVBQWUsQ0FBQztBQUN0SCxPQUFPLEVBQUMsV0FBVyxJQUFJLEVBQUUsRUFBQyxNQUFNLG1CQUFtQixDQUFDO0FBRXBELE9BQU8sRUFBQyxvQ0FBb0MsRUFBRSw0QkFBNEIsRUFBRSxrQkFBa0IsRUFBQyxNQUFNLFNBQVMsQ0FBQztBQUcvRyxPQUFPLEVBQUMsa0NBQWtDLEVBQUUsY0FBYyxFQUF5QixNQUFNLG1CQUFtQixDQUFDO0FBQzdHLE9BQU8sRUFBQyxZQUFZLEVBQUUsaUJBQWlCLEVBQUUsOEJBQThCLEVBQUUscUJBQXFCLEVBQUUscUJBQXFCLEVBQUUseUJBQXlCLEVBQUUsY0FBYyxFQUFDLE1BQU0sWUFBWSxDQUFDO0FBQ3BMLE9BQU8sRUFBQyxTQUFTLEVBQUUsa0JBQWtCLEVBQUUsbUNBQW1DLEVBQUUsWUFBWSxFQUFFLGFBQWEsRUFBRSxpQkFBaUIsRUFBRSxZQUFZLEVBQUUsY0FBYyxFQUFFLGtCQUFrQixFQUFDLE1BQU0sUUFBUSxDQUFDO0FBRTVMLE1BQU0sV0FBVyxHQUFVLEVBQUUsQ0FBQztBQUU5Qiw2RkFBNkY7QUFDN0YseUZBQXlGO0FBQ3pGLE1BQU0sVUFBVSxHQUFHLGdCQUFnQixDQUFDO0FBRXBDLFNBQVMsbUJBQW1CLENBQ3hCLElBQXlCLEVBQUUsWUFBMEIsRUFDckQsYUFBNEI7SUFDOUIsTUFBTSxhQUFhLEdBQUcsSUFBSSxhQUFhLEVBQUUsQ0FBQztJQUMxQyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMseUJBQXlCLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBRWhFLDJCQUEyQjtJQUMzQixhQUFhLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7SUFFN0MsMENBQTBDO0lBQzFDLElBQUksU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7UUFDeEIsYUFBYSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7S0FDdEQ7SUFFRCxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtRQUMzQix1REFBdUQ7UUFDdkQsYUFBYSxDQUFDLEdBQUcsQ0FDYixnQkFBZ0IsRUFBRSw0QkFBNEIsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLFlBQVksRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztLQUM1RjtJQUVELElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUU7UUFDM0IsYUFBYSxDQUFDLEdBQUcsQ0FDYixXQUFXLEVBQUUseUJBQXlCLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxZQUFZLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7S0FDeEY7SUFFRCwyQ0FBMkM7SUFDM0MsYUFBYSxDQUFDLEdBQUcsQ0FDYixjQUFjLEVBQ2QsMEJBQTBCLENBQ3RCLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLGNBQWMsRUFBRSxhQUFhLEVBQUUsWUFBWSxFQUFFLElBQUksQ0FBQyxRQUFRLElBQUksRUFBRSxFQUNoRixJQUFJLENBQUMsSUFBSSxFQUFFLGFBQWEsQ0FBQyxDQUFDLENBQUM7SUFFbkMseUJBQXlCO0lBQ3pCLGFBQWEsQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLG1DQUFtQyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUVwRiwwQkFBMEI7SUFDMUIsYUFBYSxDQUFDLEdBQUcsQ0FBQyxTQUFTLEVBQUUsbUNBQW1DLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFFaEYsSUFBSSxJQUFJLENBQUMsUUFBUSxLQUFLLElBQUksRUFBRTtRQUMxQixhQUFhLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztLQUNuRjtJQUVELE9BQU8sYUFBYSxDQUFDO0FBQ3ZCLENBQUM7QUFFRDs7R0FFRztBQUNILFNBQVMsV0FBVyxDQUFDLGFBQTRCLEVBQUUsSUFBNkM7SUFDOUYsd0NBQXdDO0lBQ3hDLE1BQU0sUUFBUSxHQUFtQixFQUFFLENBQUM7SUFFcEMsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQztJQUNqQyxNQUFNLGFBQWEsR0FBSSxJQUE0QixDQUFDLGFBQWEsQ0FBQztJQUNsRSxJQUFJLFNBQVMsSUFBSSxhQUFhLEVBQUU7UUFDOUIsTUFBTSxJQUFJLEdBQUcsQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUN2RCxJQUFJLGFBQWEsRUFBRTtZQUNqQixJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1NBQzFCO1FBQ0QsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0tBQy9EO0lBRUQsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFO1FBQ3hCLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsd0JBQXdCLENBQUMsQ0FBQyxDQUFDO0tBQzFEO0lBQ0QsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFO1FBQ3hCLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDO0tBQ3ZEO0lBQ0QsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsRUFBRTtRQUNoQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQztLQUNwRDtJQUNELElBQUksUUFBUSxDQUFDLE1BQU0sRUFBRTtRQUNuQixhQUFhLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7S0FDdkQ7QUFDSCxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsNEJBQTRCLENBQ3hDLElBQXlCLEVBQUUsWUFBMEIsRUFDckQsYUFBNEI7SUFDOUIsTUFBTSxhQUFhLEdBQUcsbUJBQW1CLENBQUMsSUFBSSxFQUFFLFlBQVksRUFBRSxhQUFhLENBQUMsQ0FBQztJQUM3RSxXQUFXLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ2pDLE1BQU0sVUFBVSxHQUFHLENBQUMsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLGVBQWUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLGFBQWEsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFM0YsTUFBTSxVQUFVLEdBQUcseUJBQXlCLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDbkQsTUFBTSxJQUFJLEdBQUcsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxvQkFBb0IsRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDO0lBRWpGLE9BQU8sRUFBQyxVQUFVLEVBQUUsSUFBSSxFQUFDLENBQUM7QUFDNUIsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLDRCQUE0QixDQUN4QyxJQUF5QixFQUFFLFlBQTBCLEVBQ3JELGFBQTRCO0lBQzlCLE1BQU0sYUFBYSxHQUFHLG1CQUFtQixDQUFDLElBQUksRUFBRSxZQUFZLEVBQUUsYUFBYSxDQUFDLENBQUM7SUFDN0UsV0FBVyxDQUFDLGFBQWEsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUVqQyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxJQUFJLFdBQVcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ25FLE1BQU0sYUFBYSxHQUFHLFFBQVEsSUFBSSxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFOUMsb0NBQW9DO0lBQ3BDLCtGQUErRjtJQUMvRixJQUFJLGFBQWEsRUFBRTtRQUNqQixNQUFNLGtCQUFrQixHQUFHLGFBQWEsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNwRCxJQUFJLGtCQUFrQixDQUFDLE1BQU0sRUFBRTtZQUM3QixhQUFhLENBQUMsR0FBRyxDQUNiLE9BQU8sRUFDUCxZQUFZLENBQUMsZUFBZSxDQUN4QixDQUFDLENBQUMsVUFBVSxDQUFDLGtCQUFrQixDQUFDLEdBQUcsQ0FDL0IsS0FBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7WUFDdEUsaUJBQWlCLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztTQUNsQztLQUNGO0lBRUQsb0RBQW9EO0lBQ3BELElBQUksZ0JBQWdCLEdBQXlCLElBQUksQ0FBQztJQUVsRCxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtRQUM5QixNQUFNLE9BQU8sR0FBRyxJQUFJLGVBQWUsRUFBRSxDQUFDO1FBQ3RDLEtBQUssTUFBTSxFQUFDLFFBQVEsRUFBRSxVQUFVLEVBQUMsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFO1lBQ3BELE9BQU8sQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsRUFBRSxVQUFVLENBQUMsQ0FBQztTQUNqRTtRQUNELGdCQUFnQixHQUFHLE9BQU8sQ0FBQztLQUM1QjtJQUVELGtFQUFrRTtJQUNsRSxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDbkMsTUFBTSxZQUFZLEdBQUcsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLEdBQUcsZ0JBQWdCLFdBQVcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBRTlFLE1BQU0sY0FBYyxHQUFHLElBQUksR0FBRyxFQUFnQixDQUFDO0lBQy9DLE1BQU0sU0FBUyxHQUFHLElBQUksR0FBRyxFQUFnQixDQUFDO0lBQzFDLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUM7SUFFN0MsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztJQUMvQixNQUFNLGVBQWUsR0FBRyxJQUFJLHlCQUF5QixDQUNqRCxZQUFZLEVBQUUsWUFBWSxDQUFDLGVBQWUsRUFBRSxFQUFFLENBQUMsRUFBRSxnQkFBZ0IsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFDM0YsZ0JBQWdCLEVBQUUsY0FBYyxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFFLEVBQUUsQ0FBQyxhQUFhLEVBQ3pFLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQztJQUUzRCxNQUFNLDBCQUEwQixHQUFHLGVBQWUsQ0FBQyxxQkFBcUIsQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBRTdGLDZFQUE2RTtJQUM3RSxxRkFBcUY7SUFDckYsTUFBTSxrQkFBa0IsR0FBRyxlQUFlLENBQUMscUJBQXFCLEVBQUUsQ0FBQztJQUNuRSxJQUFJLGtCQUFrQixFQUFFO1FBQ3RCLGFBQWEsQ0FBQyxHQUFHLENBQUMsb0JBQW9CLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztLQUM3RDtJQUVELGtCQUFrQjtJQUNsQixhQUFhLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFdkUsaUJBQWlCO0lBQ2pCLGFBQWEsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsZUFBZSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUVwRSw2Q0FBNkM7SUFDN0Msd0JBQXdCO0lBQ3hCLGtEQUFrRDtJQUNsRCwwRkFBMEY7SUFDMUYsa0dBQWtHO0lBQ2xHLE1BQU0sRUFBQyxnQkFBZ0IsRUFBRSxpQkFBaUIsRUFBQyxHQUFHLGVBQWUsQ0FBQyxTQUFTLEVBQUUsQ0FBQztJQUMxRSxJQUFJLGdCQUFnQixDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7UUFDL0IsSUFBSSxVQUFVLEdBQXNDLENBQUMsQ0FBQyxVQUFVLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUNuRixrRUFBa0U7UUFDbEUsSUFBSSxpQkFBaUIsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1lBQ2hDLFVBQVUsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsaUJBQWlCLEVBQUUsSUFBSSxDQUFDLENBQUMsZUFBZSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUNsRjtRQUNELGFBQWEsQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0tBQ3pDO0lBRUQsYUFBYSxDQUFDLEdBQUcsQ0FBQyxVQUFVLEVBQUUsMEJBQTBCLENBQUMsQ0FBQztJQUUxRCxtQ0FBbUM7SUFDbkMsSUFBSSxjQUFjLENBQUMsSUFBSSxFQUFFO1FBQ3ZCLElBQUksY0FBYyxHQUFpQixDQUFDLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQztRQUM1RSxJQUFJLElBQUksQ0FBQywrQkFBK0IsRUFBRTtZQUN4QyxjQUFjLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxlQUFlLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDO1NBQ3BFO1FBQ0QsYUFBYSxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsY0FBYyxDQUFDLENBQUM7S0FDakQ7SUFFRCx5QkFBeUI7SUFDekIsSUFBSSxTQUFTLENBQUMsSUFBSSxFQUFFO1FBQ2xCLElBQUksU0FBUyxHQUFpQixDQUFDLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztRQUNsRSxJQUFJLElBQUksQ0FBQywrQkFBK0IsRUFBRTtZQUN4QyxTQUFTLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO1NBQzFEO1FBQ0QsYUFBYSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsU0FBUyxDQUFDLENBQUM7S0FDdkM7SUFFRCxJQUFJLElBQUksQ0FBQyxhQUFhLEtBQUssSUFBSSxFQUFFO1FBQy9CLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsQ0FBQztLQUN0RDtJQUVELDhCQUE4QjtJQUM5QixJQUFJLElBQUksQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUU7UUFDckMsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGFBQWEsSUFBSSxJQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDdkUsYUFBYSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsWUFBWSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUM7WUFDckQsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUNoQixNQUFNLE9BQU8sR0FBRyxXQUFXLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyRixhQUFhLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7S0FDcEQ7U0FBTSxJQUFJLElBQUksQ0FBQyxhQUFhLEtBQUssSUFBSSxDQUFDLGlCQUFpQixDQUFDLFFBQVEsRUFBRTtRQUNqRSxpRUFBaUU7UUFDakUsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDO0tBQ2xEO0lBRUQsNERBQTREO0lBQzVELElBQUksSUFBSSxDQUFDLGFBQWEsS0FBSyxJQUFJLENBQUMsaUJBQWlCLENBQUMsUUFBUSxFQUFFO1FBQzFELGFBQWEsQ0FBQyxHQUFHLENBQUMsZUFBZSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUM7S0FDbkU7SUFFRCx5Q0FBeUM7SUFDekMsSUFBSSxJQUFJLENBQUMsVUFBVSxLQUFLLElBQUksRUFBRTtRQUM1QixhQUFhLENBQUMsR0FBRyxDQUNiLE1BQU0sRUFBRSxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsRUFBQyxHQUFHLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztLQUN4RjtJQUVELCtFQUErRTtJQUMvRSxJQUFJLGVBQWUsSUFBSSxJQUFJLElBQUksZUFBZSxLQUFLLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxPQUFPLEVBQUU7UUFDdkYsYUFBYSxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUM7S0FDbEU7SUFFRCxNQUFNLFVBQVUsR0FBRyxDQUFDLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxlQUFlLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxhQUFhLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRzNGLE1BQU0sVUFBVSxHQUFHLHlCQUF5QixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ25ELFVBQVUsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUM7SUFDckUsTUFBTSxJQUFJLEdBQUcsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxvQkFBb0IsRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDO0lBRWpGLE9BQU8sRUFBQyxVQUFVLEVBQUUsSUFBSSxFQUFDLENBQUM7QUFDNUIsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSwyQkFBMkIsQ0FDdkMsU0FBd0IsRUFBRSxTQUFtQyxFQUFFLFNBQTJCLEVBQzFGLGFBQTRCO0lBQzlCLE1BQU0sSUFBSSxHQUFHLGNBQWMsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFFLENBQUM7SUFDN0MsSUFBSSxJQUFJLEtBQUssQ0FBQywrQkFBK0IsU0FBUyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7SUFFL0QsTUFBTSxlQUFlLEdBQUcsU0FBUyxDQUFDLFlBQVksQ0FBQyxjQUFjLG1CQUEwQixDQUFDO0lBRXhGLE1BQU0sSUFBSSxHQUFHLG1DQUFtQyxDQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUM7SUFDbEYsTUFBTSxHQUFHLEdBQUcsNEJBQTRCLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxZQUFZLEVBQUUsYUFBYSxDQUFDLENBQUM7SUFDdEYsTUFBTSxVQUFVLEdBQUcsc0JBQXNCLGlDQUNqQyxJQUFJLEtBQUUsUUFBUSxFQUFFLEVBQUUsQ0FBQyxlQUFlLEVBQUUsTUFBTSxFQUFFLGVBQWUsQ0FBQyxTQUFTLElBQUUsQ0FBQztJQUNoRixNQUFNLHFCQUFxQixHQUFHLElBQUksQ0FBQyxDQUFDLFNBQVMsQ0FDekMsSUFBSSxFQUFFLElBQUksRUFDVixDQUFDLElBQUksQ0FBQyxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLGFBQWEsRUFBRSxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLEVBQUUsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUM1RixJQUFJLENBQUMsQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUN6QyxNQUFNLHFCQUFxQixHQUFHLElBQUksQ0FBQyxDQUFDLFNBQVMsQ0FDekMsSUFBSSxFQUFFLElBQUksRUFDVixDQUFDLElBQUksQ0FBQyxDQUFDLFVBQVUsQ0FBQyxlQUFlLEVBQUUsQ0FBQyxDQUFDLGFBQWEsRUFBRSxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLEVBQUUsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLEVBQzdGLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUU3QywrREFBK0Q7SUFDL0QsU0FBUyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMscUJBQXFCLEVBQUUscUJBQXFCLENBQUMsQ0FBQztBQUMxRSxDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsTUFBTSxVQUFVLDJCQUEyQixDQUN2QyxTQUF3QixFQUFFLFNBQW1DLEVBQUUsVUFBOEIsRUFDN0YsU0FBMkIsRUFBRSxhQUE0QixFQUFFLGtCQUFvQyxFQUMvRixjQUFnQztJQUNsQyxNQUFNLElBQUksR0FBRyxjQUFjLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBRSxDQUFDO0lBQzdDLElBQUksSUFBSSxLQUFLLENBQUMsK0JBQStCLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBRS9ELE1BQU0sZUFBZSxHQUFHLFNBQVMsQ0FBQyxZQUFZLENBQUMsY0FBYyxtQkFBMEIsQ0FBQztJQUV4RixNQUFNLE9BQU8sR0FBRyxTQUFTLENBQUMsU0FBUyxFQUFFLENBQUM7SUFFdEMsb0VBQW9FO0lBQ3BFLE1BQU0sSUFBSSxtQ0FDTCxtQ0FBbUMsQ0FBQyxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsQ0FBQyxLQUN2RSxRQUFRLEVBQUUsU0FBUyxDQUFDLFFBQVEsRUFDNUIsUUFBUSxFQUFFLEVBQUMsS0FBSyxFQUFFLFVBQVUsQ0FBQyxLQUFLLEVBQUUsa0JBQWtCLEVBQUUsVUFBVSxDQUFDLGtCQUFrQixFQUFDLEVBQ3RGLFVBQVUsRUFBRSxFQUFFLEVBQ2QsS0FBSyxFQUFFLHNCQUFzQixDQUFDLGNBQWMsRUFBRSxTQUFTLENBQUMsRUFDeEQsV0FBVyxFQUFFLHlCQUF5QixDQUFDLFNBQVMsQ0FBQyxXQUFXLEVBQUUsU0FBUyxDQUFDLEVBQ3hFLCtCQUErQixFQUFFLEtBQUssRUFDdEMsTUFBTSxFQUFFLENBQUMsT0FBTyxDQUFDLFFBQVEsSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLFdBQVcsRUFDcEUsYUFBYSxFQUNULENBQUMsT0FBTyxDQUFDLFFBQVEsSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxJQUFJLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxRQUFRLEVBQzNGLGFBQWEsRUFBRSw0QkFBNEIsRUFDM0MsVUFBVSxFQUFFLElBQUksRUFDaEIsYUFBYSxFQUNULFNBQVMsQ0FBQyxhQUFhLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsZUFBZSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUM5Rix1QkFBdUIsRUFBRSxFQUFFLEVBQzNCLGtCQUFrQixFQUFFLElBQUksR0FDekIsQ0FBQztJQUNGLE1BQU0sR0FBRyxHQUFHLDRCQUE0QixDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsWUFBWSxFQUFFLGFBQWEsQ0FBQyxDQUFDO0lBQ3RGLE1BQU0sVUFBVSxHQUFHLHNCQUFzQixpQ0FDakMsSUFBSSxLQUFFLFFBQVEsRUFBRSxFQUFFLENBQUMsZUFBZSxFQUFFLE1BQU0sRUFBRSxlQUFlLENBQUMsU0FBUyxJQUFFLENBQUM7SUFDaEYsTUFBTSxxQkFBcUIsR0FBRyxJQUFJLENBQUMsQ0FBQyxTQUFTLENBQ3pDLElBQUksRUFBRSxJQUFJLEVBQ1YsQ0FBQyxJQUFJLENBQUMsQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxFQUFFLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLEVB