UNPKG

@cucumber/gherkin

Version:
290 lines 37.5 kB
import AstNode from './AstNode.js'; import { AstBuilderException } from './Errors.js'; import { RuleType, TokenType } from './Parser.js'; export default class AstBuilder { stack; comments; newId; constructor(newId) { this.newId = newId; if (!newId) { throw new Error('No newId'); } this.reset(); } reset() { this.stack = [new AstNode(RuleType.None)]; this.comments = []; } startRule(ruleType) { this.stack.push(new AstNode(ruleType)); } endRule() { const node = this.stack.pop(); const transformedNode = this.transformNode(node); this.currentNode().add(node.ruleType, transformedNode); } build(token) { if (token.matchedType === TokenType.Comment) { this.comments.push({ location: this.getLocation(token), text: token.matchedText, }); } else { this.currentNode().add(token.matchedType, token); } } getResult() { return this.currentNode().getSingle(RuleType.GherkinDocument); } currentNode() { return this.stack[this.stack.length - 1]; } getLocation(token, column) { return !column ? token.location : { line: token.location.line, column }; } getTags(node) { const tags = []; const tagsNode = node.getSingle(RuleType.Tags); if (!tagsNode) { return tags; } const tokens = tagsNode.getTokens(TokenType.TagLine); for (const token of tokens) { for (const tagItem of token.matchedItems) { tags.push({ location: this.getLocation(token, tagItem.column), name: tagItem.text, id: this.newId(), }); } } return tags; } getCells(tableRowToken) { return tableRowToken.matchedItems.map((cellItem) => ({ location: this.getLocation(tableRowToken, cellItem.column), value: cellItem.text, })); } getDescription(node) { return node.getSingle(RuleType.Description) || ''; } getSteps(node) { return node.getItems(RuleType.Step); } getTableRows(node) { const rows = node.getTokens(TokenType.TableRow).map((token) => ({ id: this.newId(), location: this.getLocation(token), cells: this.getCells(token), })); this.ensureCellCount(rows); return rows.length === 0 ? [] : rows; } ensureCellCount(rows) { if (rows.length === 0) { return; } const cellCount = rows[0].cells.length; rows.forEach((row) => { if (row.cells.length !== cellCount) { throw AstBuilderException.create('inconsistent cell count within the table', row.location); } }); } transformNode(node) { switch (node.ruleType) { case RuleType.Step: { const stepLine = node.getToken(TokenType.StepLine); const dataTable = node.getSingle(RuleType.DataTable); const docString = node.getSingle(RuleType.DocString); const location = this.getLocation(stepLine); const step = { id: this.newId(), location, keyword: stepLine.matchedKeyword, keywordType: stepLine.matchedKeywordType, text: stepLine.matchedText, dataTable: dataTable, docString: docString, }; return step; } case RuleType.DocString: { const separatorToken = node.getTokens(TokenType.DocStringSeparator)[0]; const mediaType = separatorToken.matchedText.length > 0 ? separatorToken.matchedText : undefined; const lineTokens = node.getTokens(TokenType.Other); const content = lineTokens.map((t) => t.matchedText).join('\n'); const result = { location: this.getLocation(separatorToken), content, delimiter: separatorToken.matchedKeyword, }; // conditionally add this like this (needed to make tests pass on node 0.10 as well as 4.0) if (mediaType) { result.mediaType = mediaType; } return result; } case RuleType.DataTable: { const rows = this.getTableRows(node); const dataTable = { location: rows[0].location, rows, }; return dataTable; } case RuleType.Background: { const backgroundLine = node.getToken(TokenType.BackgroundLine); const description = this.getDescription(node); const steps = this.getSteps(node); const background = { id: this.newId(), location: this.getLocation(backgroundLine), keyword: backgroundLine.matchedKeyword, name: backgroundLine.matchedText, description, steps, }; return background; } case RuleType.ScenarioDefinition: { const tags = this.getTags(node); const scenarioNode = node.getSingle(RuleType.Scenario); const scenarioLine = scenarioNode.getToken(TokenType.ScenarioLine); const description = this.getDescription(scenarioNode); const steps = this.getSteps(scenarioNode); const examples = scenarioNode.getItems(RuleType.ExamplesDefinition); const scenario = { id: this.newId(), tags, location: this.getLocation(scenarioLine), keyword: scenarioLine.matchedKeyword, name: scenarioLine.matchedText, description, steps, examples, }; return scenario; } case RuleType.ExamplesDefinition: { const tags = this.getTags(node); const examplesNode = node.getSingle(RuleType.Examples); const examplesLine = examplesNode.getToken(TokenType.ExamplesLine); const description = this.getDescription(examplesNode); const examplesTable = examplesNode.getSingle(RuleType.ExamplesTable); const examples = { id: this.newId(), tags, location: this.getLocation(examplesLine), keyword: examplesLine.matchedKeyword, name: examplesLine.matchedText, description, tableHeader: examplesTable ? examplesTable[0] : undefined, tableBody: examplesTable ? examplesTable.slice(1) : [], }; return examples; } case RuleType.ExamplesTable: { return this.getTableRows(node); } case RuleType.Description: { let lineTokens = node.getTokens(TokenType.Other); // Trim trailing empty lines let end = lineTokens.length; while (end > 0 && lineTokens[end - 1].line.trimmedLineText === '') { end--; } lineTokens = lineTokens.slice(0, end); return lineTokens.map((token) => token.matchedText).join('\n'); } case RuleType.Feature: { const header = node.getSingle(RuleType.FeatureHeader); if (!header) { return null; } const tags = this.getTags(header); const featureLine = header.getToken(TokenType.FeatureLine); if (!featureLine) { return null; } const children = []; const background = node.getSingle(RuleType.Background); if (background) { children.push({ background, }); } for (const scenario of node.getItems(RuleType.ScenarioDefinition)) { children.push({ scenario, }); } for (const rule of node.getItems(RuleType.Rule)) { children.push({ rule, }); } const description = this.getDescription(header); const language = featureLine.matchedGherkinDialect; const feature = { tags, location: this.getLocation(featureLine), language, keyword: featureLine.matchedKeyword, name: featureLine.matchedText, description, children, }; return feature; } case RuleType.Rule: { const header = node.getSingle(RuleType.RuleHeader); if (!header) { return null; } const ruleLine = header.getToken(TokenType.RuleLine); if (!ruleLine) { return null; } const tags = this.getTags(header); const children = []; const background = node.getSingle(RuleType.Background); if (background) { children.push({ background, }); } for (const scenario of node.getItems(RuleType.ScenarioDefinition)) { children.push({ scenario, }); } const description = this.getDescription(header); const rule = { id: this.newId(), location: this.getLocation(ruleLine), keyword: ruleLine.matchedKeyword, name: ruleLine.matchedText, description, children, tags, }; return rule; } case RuleType.GherkinDocument: { const feature = node.getSingle(RuleType.Feature); const gherkinDocument = { feature, comments: this.comments, }; return gherkinDocument; } default: return node; } } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQXN0QnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9Bc3RCdWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQWtCQSxPQUFPLE9BQU8sTUFBTSxjQUFjLENBQUE7QUFDbEMsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sYUFBYSxDQUFBO0FBR2pELE9BQU8sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLE1BQU0sYUFBYSxDQUFBO0FBRWpELE1BQU0sQ0FBQyxPQUFPLE9BQU8sVUFBVTtJQUM3QixLQUFLLENBQVc7SUFDaEIsUUFBUSxDQUFXO0lBQ1YsS0FBSyxDQUFtQjtJQUVqQyxZQUFZLEtBQXdCO1FBQ2xDLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFBO1FBQ2xCLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNYLE1BQU0sSUFBSSxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUE7UUFDN0IsQ0FBQztRQUNELElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQTtJQUNkLENBQUM7SUFFRCxLQUFLO1FBQ0gsSUFBSSxDQUFDLEtBQUssR0FBRyxDQUFDLElBQUksT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFBO1FBQ3pDLElBQUksQ0FBQyxRQUFRLEdBQUcsRUFBRSxDQUFBO0lBQ3BCLENBQUM7SUFFRCxTQUFTLENBQUMsUUFBa0I7UUFDMUIsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQTtJQUN4QyxDQUFDO0lBRUQsT0FBTztRQUNMLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUE7UUFDN0IsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUNoRCxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFR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QVEsQ0FBQyxRQUFRLENBQUMsa0JBQWtCLENBQUMsRUFBRSxDQUFDO29CQUNsRSxRQUFRLENBQUMsSUFBSSxDQUFDO3dCQUNaLFFBQVE7cUJBQ1QsQ0FBQyxDQUFBO2dCQUNKLENBQUM7Z0JBQ0QsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQTtnQkFFL0MsTUFBTSxJQUFJLEdBQVM7b0JBQ2pCLEVBQUUsRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFO29CQUNoQixRQUFRLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUM7b0JBQ3BDLE9BQU8sRUFBRSxRQUFRLENBQUMsY0FBYztvQkFDaEMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxXQUFXO29CQUMxQixXQUFXO29CQUNYLFFBQVE7b0JBQ1IsSUFBSTtpQkFDTCxDQUFBO2dCQUNELE9BQU8sSUFBSSxDQUFBO1lBQ2IsQ0FBQztZQUNELEtBQUssUUFBUSxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUM5QixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQTtnQkFFaEQsTUFBTSxlQUFlLEdBQW9CO29CQUN2QyxPQUFPO29CQUNQLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTtpQkFDeEIsQ0FBQTtnQkFDRCxPQUFPLGVBQWUsQ0FBQTtZQUN4QixDQUFDO1lBQ0Q7Z0JBQ0UsT0FBTyxJQUFJLENBQUE7UUFDZixDQUFDO0lBQ0gsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUge1xuICBCYWNrZ3JvdW5kLFxuICBDb21tZW50LFxuICBEYXRhVGFibGUsXG4gIERvY1N0cmluZyxcbiAgRXhhbXBsZXMsXG4gIEZlYXR1cmUsXG4gIEZlYXR1cmVDaGlsZCxcbiAgR2hlcmtpbkRvY3VtZW50LFxuICBJZEdlbmVyYXRvcixcbiAgTG9jYXRpb24sXG4gIFJ1bGUsXG4gIFJ1bGVDaGlsZCxcbiAgU2NlbmFyaW8sXG4gIFN0ZXAsXG4gIFRhYmxlUm93LFxuICBUYWcsXG59IGZyb20gJ0BjdWN1bWJlci9tZXNzYWdlcydcbmltcG9ydCBBc3ROb2RlIGZyb20gJy4vQXN0Tm9kZS5qcydcbmltcG9ydCB7IEFzdEJ1aWxkZXJFeGNlcHRpb24gfSBmcm9tICcuL0Vycm9ycy5qcydcbmltcG9ydCB0eXBlIHsgSUFzdEJ1aWxkZXIgfSBmcm9tICcuL0lBc3RCdWlsZGVyLmpzJ1xuaW1wb3J0IHR5cGUgSVRva2VuIGZyb20gJy4vSVRva2VuLmpzJ1xuaW1wb3J0IHsgUnVsZVR5cGUsIFRva2VuVHlwZSB9IGZyb20gJy4vUGFyc2VyLmpzJ1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBBc3RCdWlsZGVyIGltcGxlbWVudHMgSUFzdEJ1aWxkZXI8QXN0Tm9kZSwgVG9rZW5UeXBlLCBSdWxlVHlwZT4ge1xuICBzdGFjazogQXN0Tm9kZVtdXG4gIGNvbW1lbnRzOiBDb21tZW50W11cbiAgcmVhZG9ubHkgbmV3SWQ6IElkR2VuZXJhdG9yLk5ld0lkXG5cbiAgY29uc3RydWN0b3IobmV3SWQ6IElkR2VuZXJhdG9yLk5ld0lkKSB7XG4gICAgdGhpcy5uZXdJZCA9IG5ld0lkXG4gICAgaWYgKCFuZXdJZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBuZXdJZCcpXG4gICAgfVxuICAgIHRoaXMucmVzZXQoKVxuICB9XG5cbiAgcmVzZXQoKSB7XG4gICAgdGhpcy5zdGFjayA9IFtuZXcgQXN0Tm9kZShSdWxlVHlwZS5Ob25lKV1cbiAgICB0aGlzLmNvbW1lbnRzID0gW11cbiAgfVxuXG4gIHN0YXJ0UnVsZShydWxlVHlwZTogUnVsZVR5cGUpIHtcbiAgICB0aGlzLnN0YWNrLnB1c2gobmV3IEFzdE5vZGUocnVsZVR5cGUpKVxuICB9XG5cbiAgZW5kUnVsZSgpIHtcbiAgICBjb25zdCBub2RlID0gdGhpcy5zdGFjay5wb3AoKVxuICAgIGNvbnN0IHRyYW5zZm9ybWVkTm9kZSA9IHRoaXMudHJhbnNmb3JtTm9kZShub2RlKVxuICAgIHRoaXMuY3VycmVudE5vZGUoKS5hZGQobm9kZS5ydWxlVHlwZSwgdHJhbnNmb3JtZWROb2RlKVxuICB9XG5cbiAgYnVpbGQodG9rZW46IElUb2tlbjxUb2tlblR5cGU+KSB7XG4gICAgaWYgKHRva2VuLm1hdGNoZWRUeXBlID09PSBUb2tlblR5cGUuQ29tbWVudCkge1xuICAgICAgdGhpcy5jb21tZW50cy5wdXNoKHtcbiAgICAgICAgbG9jYXRpb246IHRoaXMuZ2V0TG9jYXRpb24odG9rZW4pLFxuICAgICAgICB0ZXh0OiB0b2tlbi5tYXRjaGVkVGV4dCxcbiAgICAgIH0pXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY3VycmVudE5vZGUoKS5hZGQodG9rZW4ubWF0Y2hlZFR5cGUsIHRva2VuKVxuICAgIH1cbiAgfVxuXG4gIGdldFJlc3VsdCgpIHtcbiAgICByZXR1cm4gdGhpcy5jdXJyZW50Tm9kZSgpLmdldFNpbmdsZShSdWxlVHlwZS5HaGVya2luRG9jdW1lbnQpXG4gIH1cblxuICBjdXJyZW50Tm9kZSgpIHtcbiAgICByZXR1cm4gdGhpcy5zdGFja1t0aGlzLnN0YWNrLmxlbmd0aCAtIDFdXG4gIH1cblxuICBnZXRMb2NhdGlvbih0b2tlbjogSVRva2VuPFRva2VuVHlwZT4sIGNvbHVtbj86IG51bWJlcik6IExvY2F0aW9uIHtcbiAgICByZXR1cm4gIWNvbHVtbiA/IHRva2VuLmxvY2F0aW9uIDogeyBsaW5lOiB0b2tlbi5sb2NhdGlvbi5saW5lLCBjb2x1bW4gfVxuICB9XG5cbiAgZ2V0VGFncyhub2RlOiBBc3ROb2RlKSB7XG4gICAgY29uc3QgdGFnczogVGFnW10gPSBbXVxuICAgIGNvbnN0IHRhZ3NOb2RlID0gbm9kZS5nZXRTaW5nbGUoUnVsZVR5cGUuVGFncylcbiAgICBpZiAoIXRhZ3NOb2RlKSB7XG4gICAgICByZXR1cm4gdGFnc1xuICAgIH1cbiAgICBjb25zdCB0b2tlbnMgPSB0YWdzTm9kZS5nZXRUb2tlbnMoVG9rZW5UeXBlLlRhZ0xpbmUpXG4gICAgZm9yIChjb25zdCB0b2tlbiBvZiB0b2tlbnMpIHtcbiAgICAgIGZvciAoY29uc3QgdGFnSXRlbSBvZiB0b2tlbi5tYXRjaGVkSXRlbXMpIHtcbiAgICAgICAgdGFncy5wdXNoKHtcbiAgICAgICAgICBsb2NhdGlvbjogdGhpcy5nZXRMb2NhdGlvbih0b2tlbiwgdGFnSXRlbS5jb2x1bW4pLFxuICAgICAgICAgIG5hbWU6IHRhZ0l0ZW0udGV4dCxcbiAgICAgICAgICBpZDogdGhpcy5uZXdJZCgpLFxuICAgICAgICB9KVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGFnc1xuICB9XG5cbiAgZ2V0Q2VsbHModGFibGVSb3dUb2tlbjogSVRva2VuPFRva2VuVHlwZT4pIHtcbiAgICByZXR1cm4gdGFibGVSb3dUb2tlbi5tYXRjaGVkSXRlbXMubWFwKChjZWxsSXRlbSkgPT4gKHtcbiAgICAgIGxvY2F0aW9uOiB0aGlzLmdldExvY2F0aW9uKHRhYmxlUm93VG9rZW4sIGNlbGxJdGVtLmNvbHVtbiksXG4gICAgICB2YWx1ZTogY2VsbEl0ZW0udGV4dCxcbiAgICB9KSlcbiAgfVxuXG4gIGdldERlc2NyaXB0aW9uKG5vZGU6IEFzdE5vZGUpIHtcbiAgICByZXR1cm4gbm9kZS5nZXRTaW5nbGUoUnVsZVR5cGUuRGVzY3JpcHRpb24pIHx8ICcnXG4gIH1cblxuICBnZXRTdGVwcyhub2RlOiBBc3ROb2RlKSB7XG4gICAgcmV0dXJuIG5vZGUuZ2V0SXRlbXMoUnVsZVR5cGUuU3RlcClcbiAgfVxuXG4gIGdldFRhYmxlUm93cyhub2RlOiBBc3ROb2RlKSB7XG4gICAgY29uc3Qgcm93cyA9IG5vZGUuZ2V0VG9rZW5zKFRva2VuVHlwZS5UYWJsZVJvdykubWFwKCh0b2tlbikgPT4gKHtcbiAgICAgIGlkOiB0aGlzLm5ld0lkKCksXG4gICAgICBsb2NhdGlvbjogdGhpcy5nZXRMb2NhdGlvbih0b2tlbiksXG4gICAgICBjZWxsczogdGhpcy5nZXRDZWxscyh0b2tlbiksXG4gICAgfSkpXG4gICAgdGhpcy5lbnN1cmVDZWxsQ291bnQocm93cylcbiAgICByZXR1cm4gcm93cy5sZW5ndGggPT09IDAgPyBbXSA6IHJvd3NcbiAgfVxuXG4gIGVuc3VyZUNlbGxDb3VudChyb3dzOiBUYWJsZVJvd1tdKSB7XG4gICAgaWYgKHJvd3MubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgY29uc3QgY2VsbENvdW50ID0gcm93c1swXS5jZWxscy5sZW5ndGhcblxuICAgIHJvd3MuZm9yRWFjaCgocm93KSA9PiB7XG4gICAgICBpZiAocm93LmNlbGxzLmxlbmd0aCAhPT0gY2VsbENvdW50KSB7XG4gICAgICAgIHRocm93IEFzdEJ1aWxkZXJFeGNlcHRpb24uY3JlYXRlKCdpbmNvbnNpc3RlbnQgY2VsbCBjb3VudCB3aXRoaW4gdGhlIHRhYmxlJywgcm93LmxvY2F0aW9uKVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICB0cmFuc2Zvcm1Ob2RlKG5vZGU6IEFzdE5vZGUpIHtcbiAgICBzd2l0Y2ggKG5vZGUucnVsZVR5cGUpIHtcbiAgICAgIGNhc2UgUnVsZVR5cGUuU3RlcDoge1xuICAgICAgICBjb25zdCBzdGVwTGluZSA9IG5vZGUuZ2V0VG9rZW4oVG9rZW5UeXBlLlN0ZXBMaW5lKVxuICAgICAgICBjb25zdCBkYXRhVGFibGUgPSBub2RlLmdldFNpbmdsZShSdWxlVHlwZS5EYXRhVGFibGUpXG4gICAgICAgIGNvbnN0IGRvY1N0cmluZyA9IG5vZGUuZ2V0U2luZ2xlKFJ1bGVUeXBlLkRvY1N0cmluZylcblxuICAgICAgICBjb25zdCBsb2NhdGlvbiA9IHRoaXMuZ2V0TG9jYXRpb24oc3RlcExpbmUpXG4gICAgICAgIGNvbnN0IHN0ZXA6IFN0ZXAgPSB7XG4gICAgICAgICAgaWQ6IHRoaXMubmV3SWQoKSxcbiAgICAgICAgICBsb2NhdGlvbixcbiAgICAgICAgICBrZXl3b3JkOiBzdGVwTGluZS5tYXRjaGVkS2V5d29yZCxcbiAgICAgICAgICBrZXl3b3JkVHlwZTogc3RlcExpbmUubWF0Y2hlZEtleXdvcmRUeXBlLFxuICAgICAgICAgIHRleHQ6IHN0ZXBMaW5lLm1hdGNoZWRUZXh0LFxuICAgICAgICAgIGRhdGFUYWJsZTogZGF0YVRhYmxlLFxuICAgICAgICAgIGRvY1N0cmluZzogZG9jU3RyaW5nLFxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdGVwXG4gICAgICB9XG4gICAgICBjYXNlIFJ1bGVUeXBlLkRvY1N0cmluZzoge1xuICAgICAgICBjb25zdCBzZXBhcmF0b3JUb2tlbiA9IG5vZGUuZ2V0VG9rZW5zKFRva2VuVHlwZS5Eb2NTdHJpbmdTZXBhcmF0b3IpWzBdXG4gICAgICAgIGNvbnN0IG1lZGlhVHlwZSA9XG4gICAgICAgICAgc2VwYXJhdG9yVG9rZW4ubWF0Y2hlZFRleHQubGVuZ3RoID4gMCA/IHNlcGFyYXRvclRva2VuLm1hdGNoZWRUZXh0IDogdW5kZWZpbmVkXG4gICAgICAgIGNvbnN0IGxpbmVUb2tlbnMgPSBub2RlLmdldFRva2VucyhUb2tlblR5cGUuT3RoZXIpXG4gICAgICAgIGNvbnN0IGNvbnRlbnQgPSBsaW5lVG9rZW5zLm1hcCgodCkgPT4gdC5tYXRjaGVkVGV4dCkuam9pbignXFxuJylcblxuICAgICAgICBjb25zdCByZXN1bHQ6IERvY1N0cmluZyA9IHtcbiAgICAgICAgICBsb2NhdGlvbjogdGhpcy5nZXRMb2NhdGlvbihzZXBhcmF0b3JUb2tlbiksXG4gICAgICAgICAgY29udGVudCxcbiAgICAgICAgICBkZWxpbWl0ZXI6IHNlcGFyYXRvclRva2VuLm1hdGNoZWRLZXl3b3JkLFxuICAgICAgICB9XG4gICAgICAgIC8vIGNvbmRpdGlvbmFsbHkgYWRkIHRoaXMgbGlrZSB0aGlzIChuZWVkZWQgdG8gbWFrZSB0ZXN0cyBwYXNzIG9uIG5vZGUgMC4xMCBhcyB3ZWxsIGFzIDQuMClcbiAgICAgICAgaWYgKG1lZGlhVHlwZSkge1xuICAgICAgICAgIHJlc3VsdC5tZWRpYVR5cGUgPSBtZWRpYVR5cGVcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0XG4gICAgICB9XG4gICAgICBjYXNlIFJ1bGVUeXBlLkRhdGFUYWJsZToge1xuICAgICAgICBjb25zdCByb3dzID0gdGhpcy5nZXRUYWJsZVJvd3Mobm9kZSlcbiAgICAgICAgY29uc3QgZGF0YVRhYmxlOiBEYXRhVGFibGUgPSB7XG4gICAgICAgICAgbG9jYXRpb246IHJvd3NbMF0ubG9jYXRpb24sXG4gICAgICAgICAgcm93cyxcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGF0YVRhYmxlXG4gICAgICB9XG4gICAgICBjYXNlIFJ1bGVUeXBlLkJhY2tncm91bmQ6IHtcbiAgICAgICAgY29uc3QgYmFja2dyb3VuZExpbmUgPSBub2RlLmdldFRva2VuKFRva2VuVHlwZS5CYWNrZ3JvdW5kTGluZSlcbiAgICAgICAgY29uc3QgZGVzY3JpcHRpb24gPSB0aGlzLmdldERlc2NyaXB0aW9uKG5vZGUpXG4gICAgICAgIGNvbnN0IHN0ZXBzID0gdGhpcy5nZXRTdGVwcyhub2RlKVxuXG4gICAgICAgIGNvbnN0IGJhY2tncm91bmQ6IEJhY2tncm91bmQgPSB7XG4gICAgICAgICAgaWQ6IHRoaXMubmV3SWQoKSxcbiAgICAgICAgICBsb2NhdGlvbjogdGhpcy5nZXRMb2NhdGlvbihiYWNrZ3JvdW5kTGluZSksXG4gICAgICAgICAga2V5d29yZDogYmFja2dyb3VuZExpbmUubWF0Y2hlZEtleXdvcmQsXG4gICAgICAgICAgbmFtZTogYmFja2dyb3VuZExpbmUubWF0Y2hlZFRleHQsXG4gICAgICAgICAgZGVzY3JpcHRpb24sXG4gICAgICAgICAgc3RlcHMsXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGJhY2tncm91bmRcbiAgICAgIH1cbiAgICAgIGNhc2UgUnVsZVR5cGUuU2NlbmFyaW9EZWZpbml0aW9uOiB7XG4gICAgICAgIGNvbnN0IHRhZ3MgPSB0aGlzLmdldFRhZ3Mobm9kZSlcbiAgICAgICAgY29uc3Qgc2NlbmFyaW9Ob2RlID0gbm9kZS5nZXRTaW5nbGUoUnVsZVR5cGUuU2NlbmFyaW8pXG4gICAgICAgIGNvbnN0IHNjZW5hcmlvTGluZSA9IHNjZW5hcmlvTm9kZS5nZXRUb2tlbihUb2tlblR5cGUuU2NlbmFyaW9MaW5lKVxuICAgICAgICBjb25zdCBkZXNjcmlwdGlvbiA9IHRoaXMuZ2V0RGVzY3JpcHRpb24oc2NlbmFyaW9Ob2RlKVxuICAgICAgICBjb25zdCBzdGVwcyA9IHRoaXMuZ2V0U3RlcHMoc2NlbmFyaW9Ob2RlKVxuICAgICAgICBjb25zdCBleGFtcGxlcyA9IHNjZW5hcmlvTm9kZS5nZXRJdGVtcyhSdWxlVHlwZS5FeGFtcGxlc0RlZmluaXRpb24pXG4gICAgICAgIGNvbnN0IHNjZW5hcmlvOiBTY2VuYXJpbyA9IHtcbiAgICAgICAgICBpZDogdGhpcy5uZXdJZCgpLFxuICAgICAgICAgIHRhZ3MsXG4gICAgICAgICAgbG9jYXRpb246IHRoaXMuZ2V0TG9jYXRpb24oc2NlbmFyaW9MaW5lKSxcbiAgICAgICAgICBrZXl3b3JkOiBzY2VuYXJpb0xpbmUubWF0Y2hlZEtleXdvcmQsXG4gICAgICAgICAgbmFtZTogc2NlbmFyaW9MaW5lLm1hdGNoZWRUZXh0LFxuICAgICAgICAgIGRlc2NyaXB0aW9uLFxuICAgICAgICAgIHN0ZXBzLFxuICAgICAgICAgIGV4YW1wbGVzLFxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzY2VuYXJpb1xuICAgICAgfVxuICAgICAgY2FzZSBSdWxlVHlwZS5FeGFtcGxlc0RlZmluaXRpb246IHtcbiAgICAgICAgY29uc3QgdGFncyA9IHRoaXMuZ2V0VGFncyhub2RlKVxuICAgICAgICBjb25zdCBleGFtcGxlc05vZGUgPSBub2RlLmdldFNpbmdsZShSdWxlVHlwZS5FeGFtcGxlcylcbiAgICAgICAgY29uc3QgZXhhbXBsZXNMaW5lID0gZXhhbXBsZXNOb2RlLmdldFRva2VuKFRva2VuVHlwZS5FeGFtcGxlc0xpbmUpXG4gICAgICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gdGhpcy5nZXREZXNjcmlwdGlvbihleGFtcGxlc05vZGUpXG4gICAgICAgIGNvbnN0IGV4YW1wbGVzVGFibGU6IFRhYmxlUm93W10gPSBleGFtcGxlc05vZGUuZ2V0U2luZ2xlKFJ1bGVUeXBlLkV4YW1wbGVzVGFibGUpXG5cbiAgICAgICAgY29uc3QgZXhhbXBsZXM6IEV4YW1wbGVzID0ge1xuICAgICAgICAgIGlkOiB0aGlzLm5ld0lkKCksXG4gICAgICAgICAgdGFncyxcbiAgICAgICAgICBsb2NhdGlvbjogdGhpcy5nZXRMb2NhdGlvbihleGFtcGxlc0xpbmUpLFxuICAgICAgICAgIGtleXdvcmQ6IGV4YW1wbGVzTGluZS5tYXRjaGVkS2V5d29yZCxcbiAgICAgICAgICBuYW1lOiBleGFtcGxlc0xpbmUubWF0Y2hlZFRleHQsXG4gICAgICAgICAgZGVzY3JpcHRpb24sXG4gICAgICAgICAgdGFibGVIZWFkZXI6IGV4YW1wbGVzVGFibGUgPyBleGFtcGxlc1RhYmxlWzBdIDogdW5kZWZpbmVkLFxuICAgICAgICAgIHRhYmxlQm9keTogZXhhbXBsZXNUYWJsZSA/IGV4YW1wbGVzVGFibGUuc2xpY2UoMSkgOiBbXSxcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZXhhbXBsZXNcbiAgICAgIH1cbiAgICAgIGNhc2UgUnVsZVR5cGUuRXhhbXBsZXNUYWJsZToge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRUYWJsZVJvd3Mobm9kZSlcbiAgICAgIH1cbiAgICAgIGNhc2UgUnVsZVR5cGUuRGVzY3JpcHRpb246IHtcbiAgICAgICAgbGV0IGxpbmVUb2tlbnMgPSBub2RlLmdldFRva2VucyhUb2tlblR5cGUuT3RoZXIpXG4gICAgICAgIC8vIFRyaW0gdHJhaWxpbmcgZW1wdHkgbGluZXNcbiAgICAgICAgbGV0IGVuZCA9IGxpbmVUb2tlbnMubGVuZ3RoXG4gICAgICAgIHdoaWxlIChlbmQgPiAwICYmIGxpbmVUb2tlbnNbZW5kIC0gMV0ubGluZS50cmltbWVkTGluZVRleHQgPT09ICcnKSB7XG4gICAgICAgICAgZW5kLS1cbiAgICAgICAgfVxuICAgICAgICBsaW5lVG9rZW5zID0gbGluZVRva2Vucy5zbGljZSgwLCBlbmQpXG5cbiAgICAgICAgcmV0dXJuIGxpbmVUb2tlbnMubWFwKCh0b2tlbikgPT4gdG9rZW4ubWF0Y2hlZFRleHQpLmpvaW4oJ1xcbicpXG4gICAgICB9XG5cbiAgICAgIGNhc2UgUnVsZVR5cGUuRmVhdHVyZToge1xuICAgICAgICBjb25zdCBoZWFkZXIgPSBub2RlLmdldFNpbmdsZShSdWxlVHlwZS5GZWF0dXJlSGVhZGVyKVxuICAgICAgICBpZiAoIWhlYWRlcikge1xuICAgICAgICAgIHJldHVybiBudWxsXG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdGFncyA9IHRoaXMuZ2V0VGFncyhoZWFkZXIpXG4gICAgICAgIGNvbnN0IGZlYXR1cmVMaW5lID0gaGVhZGVyLmdldFRva2VuKFRva2VuVHlwZS5GZWF0dXJlTGluZSlcbiAgICAgICAgaWYgKCFmZWF0dXJlTGluZSkge1xuICAgICAgICAgIHJldHVybiBudWxsXG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY2hpbGRyZW46IEZlYXR1cmVDaGlsZFtdID0gW11cbiAgICAgICAgY29uc3QgYmFja2dyb3VuZCA9IG5vZGUuZ2V0U2luZ2xlKFJ1bGVUeXBlLkJhY2tncm91bmQpXG4gICAgICAgIGlmIChiYWNrZ3JvdW5kKSB7XG4gICAgICAgICAgY2hpbGRyZW4ucHVzaCh7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kLFxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgICAgZm9yIChjb25zdCBzY2VuYXJpbyBvZiBub2RlLmdldEl0ZW1zKFJ1bGVUeXBlLlNjZW5hcmlvRGVmaW5pdGlvbikpIHtcbiAgICAgICAgICBjaGlsZHJlbi5wdXNoKHtcbiAgICAgICAgICAgIHNjZW5hcmlvLFxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgICAgZm9yIChjb25zdCBydWxlIG9mIG5vZGUuZ2V0SXRlbXMoUnVsZVR5cGUuUnVsZSkpIHtcbiAgICAgICAgICBjaGlsZHJlbi5wdXNoKHtcbiAgICAgICAgICAgIHJ1bGUsXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gdGhpcy5nZXREZXNjcmlwdGlvbihoZWFkZXIpXG4gICAgICAgIGNvbnN0IGxhbmd1YWdlID0gZmVhdHVyZUxpbmUubWF0Y2hlZEdoZXJraW5EaWFsZWN0XG5cbiAgICAgICAgY29uc3QgZmVhdHVyZTogRmVhdHVyZSA9IHtcbiAgICAgICAgICB0YWdzLFxuICAgICAgICAgIGxvY2F0aW9uOiB0aGlzLmdldExvY2F0aW9uKGZlYXR1cmVMaW5lKSxcbiAgICAgICAgICBsYW5ndWFnZSxcbiAgICAgICAgICBrZXl3b3JkOiBmZWF0dXJlTGluZS5tYXRjaGVkS2V5d29yZCxcbiAgICAgICAgICBuYW1lOiBmZWF0dXJlTGluZS5tYXRjaGVkVGV4dCxcbiAgICAgICAgICBkZXNjcmlwdGlvbixcbiAgICAgICAgICBjaGlsZHJlbixcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmVhdHVyZVxuICAgICAgfVxuXG4gICAgICBjYXNlIFJ1bGVUeXBlLlJ1bGU6IHtcbiAgICAgICAgY29uc3QgaGVhZGVyID0gbm9kZS5nZXRTaW5nbGUoUnVsZVR5cGUuUnVsZUhlYWRlcilcbiAgICAgICAgaWYgKCFoZWFkZXIpIHtcbiAgICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJ1bGVMaW5lID0gaGVhZGVyLmdldFRva2VuKFRva2VuVHlwZS5SdWxlTGluZSlcbiAgICAgICAgaWYgKCFydWxlTGluZSkge1xuICAgICAgICAgIHJldHVybiBudWxsXG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdGFncyA9IHRoaXMuZ2V0VGFncyhoZWFkZXIpXG4gICAgICAgIGNvbnN0IGNoaWxkcmVuOiBSdWxlQ2hpbGRbXSA9IFtdXG4gICAgICAgIGNvbnN0IGJhY2tncm91bmQgPSBub2RlLmdldFNpbmdsZShSdWxlVHlwZS5CYWNrZ3JvdW5kKVxuICAgICAgICBpZiAoYmFja2dyb3VuZCkge1xuICAgICAgICAgIGNoaWxkcmVuLnB1c2goe1xuICAgICAgICAgICAgYmFja2dyb3VuZCxcbiAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3Qgc2NlbmFyaW8gb2Ygbm9kZS5nZXRJdGVtcyhSdWxlVHlwZS5TY2VuYXJpb0RlZmluaXRpb24pKSB7XG4gICAgICAgICAgY2hpbGRyZW4ucHVzaCh7XG4gICAgICAgICAgICBzY2VuYXJpbyxcbiAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gdGhpcy5nZXREZXNjcmlwdGlvbihoZWFkZXIpXG5cbiAgICAgICAgY29uc3QgcnVsZTogUnVsZSA9IHtcbiAgICAgICAgICBpZDogdGhpcy5uZXdJZCgpLFxuICAgICAgICAgIGxvY2F0aW9uOiB0aGlzLmdldExvY2F0aW9uKHJ1bGVMaW5lKSxcbiAgICAgICAgICBrZXl3b3JkOiBydWxlTGluZS5tYXRjaGVkS2V5d29yZCxcbiAgICAgICAgICBuYW1lOiBydWxlTGluZS5tYXRjaGVkVGV4dCxcbiAgICAgICAgICBkZXNjcmlwdGlvbixcbiAgICAgICAgICBjaGlsZHJlbixcbiAgICAgICAgICB0YWdzLFxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBydWxlXG4gICAgICB9XG4gICAgICBjYXNlIFJ1bGVUeXBlLkdoZXJraW5Eb2N1bWVudDoge1xuICAgICAgICBjb25zdCBmZWF0dXJlID0gbm9kZS5nZXRTaW5nbGUoUnVsZVR5cGUuRmVhdHVyZSlcblxuICAgICAgICBjb25zdCBnaGVya2luRG9jdW1lbnQ6IEdoZXJraW5Eb2N1bWVudCA9IHtcbiAgICAgICAgICBmZWF0dXJlLFxuICAgICAgICAgIGNvbW1lbnRzOiB0aGlzLmNvbW1lbnRzLFxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBnaGVya2luRG9jdW1lbnRcbiAgICAgIH1cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBub2RlXG4gICAgfVxuICB9XG59XG4iXX0=