UNPKG

34.8 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const tslib_1 = require("tslib");
4const uniqBy_1 = tslib_1.__importDefault(require("lodash/uniqBy"));
5// tslint:disable ban-types
6const ts_utils_1 = require("@neo-one/ts-utils");
7const typescript_1 = tslib_1.__importStar(require("typescript"));
8const util_1 = require("util");
9const analysis_1 = require("./analysis");
10const builtins_1 = require("./compile/builtins");
11const CompilerDiagnostic_1 = require("./CompilerDiagnostic");
12const DiagnosticCode_1 = require("./DiagnosticCode");
13const DiagnosticMessage_1 = require("./DiagnosticMessage");
14const utils_1 = require("./utils");
15exports.DEFAULT_DIAGNOSTIC_OPTIONS = {
16 error: false,
17 warning: true
18};
19const getErrorKey = (diagnostic) => `${diagnostic.file}:${diagnostic.start}:${diagnostic.length}:${diagnostic.code}`;
20const getFullKey = (diagnostic) => `${diagnostic.file}:${diagnostic.start}:${diagnostic.length}:${diagnostic.category}:${diagnostic.code}:${diagnostic.messageText}`;
21class Context {
22 constructor(program, typeChecker, languageService, smartContractDir, mutableDiagnostics = typescript_1.default.getPreEmitDiagnostics(program)) {
23 this.program = program;
24 this.typeChecker = typeChecker;
25 this.languageService = languageService;
26 this.smartContractDir = smartContractDir;
27 this.mutableDiagnostics = mutableDiagnostics;
28 this.memoized = utils_1.createMemoized();
29 this.builtins = builtins_1.createBuiltins(this);
30 this.analysis = new analysis_1.AnalysisService(this);
31 }
32 get diagnostics() {
33 const errorDiagnostics = new Set(); // tslint:disable-next-line no-loop-statement
34 for (const diagnostic of this.mutableDiagnostics) {
35 if (diagnostic.category === typescript_1.DiagnosticCategory.Error) {
36 errorDiagnostics.add(getErrorKey(diagnostic));
37 }
38 }
39 const diagnostics = this.mutableDiagnostics.filter(diagnostic => diagnostic.category === typescript_1.DiagnosticCategory.Error || !errorDiagnostics.has(getErrorKey(diagnostic)));
40 return uniqBy_1.default(diagnostics, getFullKey);
41 }
42 update(program, typeChecker, languageService, smartContractDir) {
43 return new Context(program, typeChecker, languageService, smartContractDir, [...this.mutableDiagnostics]);
44 }
45 reportError(node, code, message, // tslint:disable-next-line no-any readonly-array
46 ...args) {
47 this.mutableDiagnostics.push(new CompilerDiagnostic_1.CompilerDiagnostic(node, this.getDiagnosticMessage(message, ...args), code, typescript_1.default.DiagnosticCategory.Error));
48 } // tslint:disable-next-line no-any readonly-array
49 reportWarning(node, code, message, ...args) {
50 this.mutableDiagnostics.push(new CompilerDiagnostic_1.CompilerDiagnostic(node, this.getDiagnosticMessage(message, ...args), code, typescript_1.default.DiagnosticCategory.Warning));
51 }
52 reportUnsupported(node) {
53 this.reportError(node, DiagnosticCode_1.DiagnosticCode.GenericUnsupportedSyntax, DiagnosticMessage_1.DiagnosticMessage.GenericUnsupportedSyntax);
54 }
55 reportUnsupportedEfficiency(node) {
56 this.reportError(node, DiagnosticCode_1.DiagnosticCode.GenericUnsupportedSyntax, DiagnosticMessage_1.DiagnosticMessage.EfficiencyUnsupportedSyntax);
57 }
58 reportTypeError(node) {
59 this.reportError(node, DiagnosticCode_1.DiagnosticCode.UnknownType, DiagnosticMessage_1.DiagnosticMessage.CouldNotInferType);
60 }
61 reportTypeWarning(node) {
62 this.reportWarning(node, DiagnosticCode_1.DiagnosticCode.UnknownType, DiagnosticMessage_1.DiagnosticMessage.CouldNotInferTypeDeopt);
63 }
64 getType(node, { warning = exports.DEFAULT_DIAGNOSTIC_OPTIONS.warning, error = exports.DEFAULT_DIAGNOSTIC_OPTIONS.error } = exports.DEFAULT_DIAGNOSTIC_OPTIONS) {
65 return this.memoized('type', utils_1.nodeKey(node), () => {
66 const type = this.getNotAnyTypeBase(ts_utils_1.tsUtils.type_.getType(this.typeChecker, node));
67 if (type === undefined) {
68 if (error) {
69 this.reportTypeError(node);
70 }
71 else if (warning) {
72 this.reportTypeWarning(node);
73 }
74 }
75 if (type !== undefined) {
76 const constraintType = ts_utils_1.tsUtils.type_.getConstraint(type);
77 if (constraintType !== undefined) {
78 return constraintType;
79 }
80 }
81 return type;
82 });
83 }
84 getTypeOfSymbol(symbol, node, { warning = exports.DEFAULT_DIAGNOSTIC_OPTIONS.warning, error = exports.DEFAULT_DIAGNOSTIC_OPTIONS.error } = exports.DEFAULT_DIAGNOSTIC_OPTIONS) {
85 if (symbol === undefined) {
86 return undefined;
87 }
88 return this.memoized('type-of-symbol', `${utils_1.symbolKey(symbol)}:${utils_1.nodeKey(node)}`, () => {
89 const type = this.getNotAnyTypeBase(ts_utils_1.tsUtils.type_.getTypeAtLocation(this.typeChecker, symbol, node));
90 if (type === undefined) {
91 if (error) {
92 this.reportTypeError(node);
93 }
94 else if (warning) {
95 this.reportTypeWarning(node);
96 }
97 }
98 if (type !== undefined) {
99 const constraintType = ts_utils_1.tsUtils.type_.getConstraint(type);
100 if (constraintType !== undefined) {
101 return constraintType;
102 }
103 }
104 return type;
105 });
106 }
107 getSymbol(node, { warning = exports.DEFAULT_DIAGNOSTIC_OPTIONS.warning, error = exports.DEFAULT_DIAGNOSTIC_OPTIONS.error } = exports.DEFAULT_DIAGNOSTIC_OPTIONS) {
108 return this.memoized('symbol', utils_1.nodeKey(node), () => {
109 const symbol = ts_utils_1.tsUtils.node.getSymbol(this.typeChecker, node);
110 if (symbol === undefined) {
111 if (error) {
112 this.reportSymbolError(node);
113 }
114 else if (warning) {
115 this.reportSymbolWarning(node);
116 }
117 return undefined;
118 }
119 const aliased = ts_utils_1.tsUtils.symbol.getAliasedSymbol(this.typeChecker, symbol);
120 if (aliased !== undefined) {
121 return aliased;
122 }
123 return symbol;
124 });
125 }
126 getTypeSymbol(node, { warning = exports.DEFAULT_DIAGNOSTIC_OPTIONS.warning, error = exports.DEFAULT_DIAGNOSTIC_OPTIONS.error } = exports.DEFAULT_DIAGNOSTIC_OPTIONS) {
127 return this.memoized('type-symbol', utils_1.nodeKey(node), () => {
128 const noWarnOrError = {
129 warning: false,
130 error: false
131 };
132 const type = this.getType(node, noWarnOrError);
133 const symbol = this.getSymbolForType(node, type, noWarnOrError);
134 if (symbol === undefined) {
135 if (error) {
136 this.reportSymbolError(node);
137 }
138 else if (warning) {
139 this.reportSymbolWarning(node);
140 }
141 return undefined;
142 }
143 return symbol;
144 });
145 }
146 getSymbolForType(_node, type, _options = exports.DEFAULT_DIAGNOSTIC_OPTIONS) {
147 if (type === undefined) {
148 return undefined;
149 }
150 return this.memoized('symbol-for-type', utils_1.typeKey(type), () => {
151 let symbol = ts_utils_1.tsUtils.type_.getSymbol(type);
152 if (symbol === undefined) {
153 symbol = ts_utils_1.tsUtils.type_.getAliasSymbol(type);
154 }
155 if (symbol === undefined) {
156 return undefined;
157 }
158 const aliased = ts_utils_1.tsUtils.symbol.getAliasedSymbol(this.typeChecker, symbol);
159 if (aliased !== undefined) {
160 return aliased;
161 }
162 return symbol;
163 });
164 }
165 getNotAnyType(node, typeIn, { warning = exports.DEFAULT_DIAGNOSTIC_OPTIONS.warning, error = exports.DEFAULT_DIAGNOSTIC_OPTIONS.error } = exports.DEFAULT_DIAGNOSTIC_OPTIONS) {
166 const type = this.getNotAnyTypeBase(typeIn);
167 if (type === undefined) {
168 if (error) {
169 this.reportTypeError(node);
170 }
171 else if (warning) {
172 this.reportTypeWarning(node);
173 }
174 }
175 return type;
176 }
177 getNotAnyTypeBase(type) {
178 // tslint:disable-next-line no-bitwise
179 if (type === undefined || ts_utils_1.tsUtils.type_.isAny(type)) {
180 return undefined;
181 }
182 return type;
183 }
184 reportSymbolError(node) {
185 this.reportError(node, DiagnosticCode_1.DiagnosticCode.UnknownSymbol, DiagnosticMessage_1.DiagnosticMessage.CouldNotInferSymbol);
186 }
187 reportSymbolWarning(node) {
188 this.reportError(node, DiagnosticCode_1.DiagnosticCode.UnknownSymbol, DiagnosticMessage_1.DiagnosticMessage.CouldNotInferSymbolDeopt);
189 } // tslint:disable-next-line no-any readonly-array
190 getDiagnosticMessage(message, ...args) {
191 const match = message.match(/%[dfijoOs]/g);
192 const expectedLength = (match === null ? [] : match).length;
193 if (expectedLength !== args.length) {
194 throw new Error(`The provided arguments length (${args.length}) does not match the required arguments length (${expectedLength})`);
195 }
196 return util_1.format(message, ...args);
197 }
198}
199exports.Context = Context;
200
201//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkNvbnRleHQudHMiXSwibmFtZXMiOlsiREVGQVVMVF9ESUFHTk9TVElDX09QVElPTlMiLCJlcnJvciIsIndhcm5pbmciLCJnZXRFcnJvcktleSIsImRpYWdub3N0aWMiLCJmaWxlIiwic3RhcnQiLCJsZW5ndGgiLCJjb2RlIiwiZ2V0RnVsbEtleSIsImNhdGVnb3J5IiwibWVzc2FnZVRleHQiLCJDb250ZXh0IiwicHJvZ3JhbSIsInR5cGVDaGVja2VyIiwibGFuZ3VhZ2VTZXJ2aWNlIiwic21hcnRDb250cmFjdERpciIsIm11dGFibGVEaWFnbm9zdGljcyIsInRzIiwiZ2V0UHJlRW1pdERpYWdub3N0aWNzIiwibWVtb2l6ZWQiLCJjcmVhdGVNZW1vaXplZCIsImJ1aWx0aW5zIiwiY3JlYXRlQnVpbHRpbnMiLCJhbmFseXNpcyIsIkFuYWx5c2lzU2VydmljZSIsImRpYWdub3N0aWNzIiwiZXJyb3JEaWFnbm9zdGljcyIsIlNldCIsIkRpYWdub3N0aWNDYXRlZ29yeSIsIkVycm9yIiwiYWRkIiwiZmlsdGVyIiwiaGFzIiwidXBkYXRlIiwicmVwb3J0RXJyb3IiLCJub2RlIiwibWVzc2FnZSIsImFyZ3MiLCJwdXNoIiwiQ29tcGlsZXJEaWFnbm9zdGljIiwiZ2V0RGlhZ25vc3RpY01lc3NhZ2UiLCJyZXBvcnRXYXJuaW5nIiwiV2FybmluZyIsInJlcG9ydFVuc3VwcG9ydGVkIiwiRGlhZ25vc3RpY0NvZGUiLCJHZW5lcmljVW5zdXBwb3J0ZWRTeW50YXgiLCJEaWFnbm9zdGljTWVzc2FnZSIsInJlcG9ydFVuc3VwcG9ydGVkRWZmaWNpZW5jeSIsIkVmZmljaWVuY3lVbnN1cHBvcnRlZFN5bnRheCIsInJlcG9ydFR5cGVFcnJvciIsIlVua25vd25UeXBlIiwiQ291bGROb3RJbmZlclR5cGUiLCJyZXBvcnRUeXBlV2FybmluZyIsIkNvdWxkTm90SW5mZXJUeXBlRGVvcHQiLCJnZXRUeXBlIiwibm9kZUtleSIsInR5cGUiLCJnZXROb3RBbnlUeXBlQmFzZSIsInRzVXRpbHMiLCJ0eXBlXyIsInVuZGVmaW5lZCIsImNvbnN0cmFpbnRUeXBlIiwiZ2V0Q29uc3RyYWludCIsImdldFR5cGVPZlN5bWJvbCIsInN5bWJvbCIsInN5bWJvbEtleSIsImdldFR5cGVBdExvY2F0aW9uIiwiZ2V0U3ltYm9sIiwicmVwb3J0U3ltYm9sRXJyb3IiLCJyZXBvcnRTeW1ib2xXYXJuaW5nIiwiYWxpYXNlZCIsImdldEFsaWFzZWRTeW1ib2wiLCJnZXRUeXBlU3ltYm9sIiwibm9XYXJuT3JFcnJvciIsImdldFN5bWJvbEZvclR5cGUiLCJfbm9kZSIsIl9vcHRpb25zIiwidHlwZUtleSIsImdldEFsaWFzU3ltYm9sIiwiZ2V0Tm90QW55VHlwZSIsInR5cGVJbiIsImlzQW55IiwiVW5rbm93blN5bWJvbCIsIkNvdWxkTm90SW5mZXJTeW1ib2wiLCJDb3VsZE5vdEluZmVyU3ltYm9sRGVvcHQiLCJtYXRjaCIsImV4cGVjdGVkTGVuZ3RoIiwiZm9ybWF0Il0sIm1hcHBpbmdzIjoiOzs7QUFBQSxtRUFBb0M7QUFBcEMsMkJBQUE7QUFDQSxnREFBQTtBQUVBLGlFQUFBO0FBQ0EsK0JBQUE7QUFDQSx5Q0FBQTtBQUNBLGlEQUFBO0FBQ0EsNkRBQUE7QUFDQSxxREFBQTtBQUNBLDJEQUFBO0FBQ0EsbUNBQUE7QUFPYUEsUUFBQUEsMEJBQTBCLEdBQUc7SUFDeENDLEtBQUssRUFBRSxLQURpQztJQUV4Q0MsT0FBTyxFQUFFLElBQUE7Q0FGSixDQUFBO0FBS1AsTUFBTUMsV0FBVyxHQUFHLENBQUNDLFVBQUQsRUFBQSxFQUFBLENBQ2pCLEdBQUVBLFVBQVUsQ0FBQ0MsSUFBSyxJQUFHRCxVQUFVLENBQUNFLEtBQU0sSUFBR0YsVUFBVSxDQUFDRyxNQUFPLElBQUdILFVBQVUsQ0FBQ0ksSUFBSyxFQURqRixDQUFBO0FBRUEsTUFBTUMsVUFBVSxHQUFHLENBQUNMLFVBQUQsRUFBQSxFQUFBLENBQ2hCLEdBQUVBLFVBQVUsQ0FBQ0MsSUFBSyxJQUFHRCxVQUFVLENBQUNFLEtBQU0sSUFBR0YsVUFBVSxD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SUFBSSxDQUFDL0IsTUFBNUIsRUFBb0M7WUFDbEMsTUFBTSxJQUFJdUIsS0FBSixDQUNILGtDQUNDUSxJQUFJLENBQUMvQixNQUNOLG1EQUFrRGdGLGNBQWUsR0FIOUQsQ0FBTixDQUFBO1NBS0Q7UUFFRCxPQUFPQyxhQUFNLENBQUNuRCxPQUFELEVBQVUsR0FBR0MsSUFBYixDQUFiLENBQUE7SUFDRCxDQUFBO0NBOVFrQjtBQUFyQiwwQkFBcUIiLCJmaWxlIjoibmVvLW9uZS1zbWFydC1jb250cmFjdC1jb21waWxlci9zcmMvQ29udGV4dC5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8vIHRzbGludDpkaXNhYmxlIGJhbi10eXBlc1xuaW1wb3J0IHsgdHNVdGlscyB9IGZyb20gJ0BuZW8tb25lL3RzLXV0aWxzJztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgdHMsIHsgRGlhZ25vc3RpY0NhdGVnb3J5IH0gZnJvbSAndHlwZXNjcmlwdCc7XG5pbXBvcnQgeyBmb3JtYXQgfSBmcm9tICd1dGlsJztcbmltcG9ydCB7IEFuYWx5c2lzU2VydmljZSB9IGZyb20gJy4vYW5hbHlzaXMnO1xuaW1wb3J0IHsgQnVpbHRpbnMsIGNyZWF0ZUJ1aWx0aW5zIH0gZnJvbSAnLi9jb21waWxlL2J1aWx0aW5zJztcbmltcG9ydCB7IENvbXBpbGVyRGlhZ25vc3RpYyB9IGZyb20gJy4vQ29tcGlsZXJEaWFnbm9zdGljJztcbmltcG9ydCB7IERpYWdub3N0aWNDb2RlIH0gZnJvbSAnLi9EaWFnbm9zdGljQ29kZSc7XG5pbXBvcnQgeyBEaWFnbm9zdGljTWVzc2FnZSB9IGZyb20gJy4vRGlhZ25vc3RpY01lc3NhZ2UnO1xuaW1wb3J0IHsgY3JlYXRlTWVtb2l6ZWQsIG5vZGVLZXksIHN5bWJvbEtleSwgdHlwZUtleSB9IGZyb20gJy4vdXRpbHMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIERpYWdub3N0aWNPcHRpb25zIHtcbiAgcmVhZG9ubHkgZXJyb3I/OiBib29sZWFuO1xuICByZWFkb25seSB3YXJuaW5nPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGNvbnN0IERFRkFVTFRfRElBR05PU1RJQ19PUFRJT05TID0ge1xuICBlcnJvcjogZmFsc2UsXG4gIHdhcm5pbmc6IHRydWUsXG59O1xuXG5jb25zdCBnZXRFcnJvcktleSA9IChkaWFnbm9zdGljOiB0cy5EaWFnbm9zdGljKSA9PlxuICBgJHtkaWFnbm9zdGljLmZpbGV9OiR7ZGlhZ25vc3RpYy5zdGFydH06JHtkaWFnbm9zdGljLmxlbmd0aH06JHtkaWFnbm9zdGljLmNvZGV9YDtcbmNvbnN0IGdldEZ1bGxLZXkgPSAoZGlhZ25vc3RpYzogdHMuRGlhZ25vc3RpYykgPT5cbiAgYCR7ZGlhZ25vc3RpYy5maWxlfToke2RpYWdub3N0aWMuc3RhcnR9OiR7ZGlhZ25vc3RpYy5sZW5ndGh9OiR7ZGlhZ25vc3RpYy5jYXRlZ29yeX06JHtkaWFnbm9zdGljLmNvZGV9OiR7XG4gICAgZGlhZ25vc3RpYy5tZXNzYWdlVGV4dFxuICB9YDtcblxuZXhwb3J0IGNsYXNzIENvbnRleHQge1xuICBwdWJsaWMgcmVhZG9ubHkgYnVpbHRpbnM6IEJ1aWx0aW5zO1xuICBwdWJsaWMgcmVhZG9ubHkgYW5hbHlzaXM6IEFuYWx5c2lzU2VydmljZTtcbiAgcHJpdmF0ZSByZWFkb25seSBtZW1vaXplZCA9IGNyZWF0ZU1lbW9pemVkKCk7XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyByZWFkb25seSBwcm9ncmFtOiB0cy5Qcm9ncmFtLFxuICAgIHB1YmxpYyByZWFkb25seSB0eXBlQ2hlY2tlcjogdHMuVHlwZUNoZWNrZXIsXG4gICAgcHVibGljIHJlYWRvbmx5IGxhbmd1YWdlU2VydmljZTogdHMuTGFuZ3VhZ2VTZXJ2aWNlLFxuICAgIHB1YmxpYyByZWFkb25seSBzbWFydENvbnRyYWN0RGlyOiBzdHJpbmcsXG4gICAgcHJpdmF0ZSByZWFkb25seSBtdXRhYmxlRGlhZ25vc3RpY3M6IHRzLkRpYWdub3N0aWNbXSA9IHRzLmdldFByZUVtaXREaWFnbm9zdGljcyhwcm9ncmFtKSxcbiAgKSB7XG4gICAgdGhpcy5idWlsdGlucyA9IGNyZWF0ZUJ1aWx0aW5zKHRoaXMpO1xuICAgIHRoaXMuYW5hbHlzaXMgPSBuZXcgQW5hbHlzaXNTZXJ2aWNlKHRoaXMpO1xuICB9XG5cbiAgcHVibGljIGdldCBkaWFnbm9zdGljcygpOiBSZWFkb25seUFycmF5PHRzLkRpYWdub3N0aWM+IHtcbiAgICBjb25zdCBlcnJvckRpYWdub3N0aWNzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIG5vLWxvb3Atc3RhdGVtZW50XG4gICAgZm9yIChjb25zdCBkaWFnbm9zdGljIG9mIHRoaXMubXV0YWJsZURpYWdub3N0aWNzKSB7XG4gICAgICBpZiAoZGlhZ25vc3RpYy5jYXRlZ29yeSA9PT0gRGlhZ25vc3RpY0NhdGVnb3J5LkVycm9yKSB7XG4gICAgICAgIGVycm9yRGlhZ25vc3RpY3MuYWRkKGdldEVycm9yS2V5KGRpYWdub3N0aWMpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBkaWFnbm9zdGljcyA9IHRoaXMubXV0YWJsZURpYWdub3N0aWNzLmZpbHRlcihcbiAgICAgIChkaWFnbm9zdGljKSA9PlxuICAgICAgICBkaWFnbm9zdGljLmNhdGVnb3J5ID09PSBEaWFnbm9zdGljQ2F0ZWdvcnkuRXJyb3IgfHwgIWVycm9yRGlhZ25vc3RpY3MuaGFzKGdldEVycm9yS2V5KGRpYWdub3N0aWMpKSxcbiAgICApO1xuXG4gICAgcmV0dXJuIF8udW5pcUJ5KGRpYWdub3N0aWNzLCBnZXRGdWxsS2V5KTtcbiAgfVxuXG4gIHB1YmxpYyB1cGRhdGUoXG4gICAgcHJvZ3JhbTogdHMuUHJvZ3JhbSxcbiAgICB0eXBlQ2hlY2tlcjogdHMuVHlwZUNoZWNrZXIsXG4gICAgbGFuZ3VhZ2VTZXJ2aWNlOiB0cy5MYW5ndWFnZVNlcnZpY2UsXG4gICAgc21hcnRDb250cmFjdERpcjogc3RyaW5nLFxuICApOiBDb250ZXh0IHtcbiAgICByZXR1cm4gbmV3IENvbnRleHQocHJvZ3JhbSwgdHlwZUNoZWNrZXIsIGxhbmd1YWdlU2VydmljZSwgc21hcnRDb250cmFjdERpciwgWy4uLnRoaXMubXV0YWJsZURpYWdub3N0aWNzXSk7XG4gIH1cblxuICBwdWJsaWMgcmVwb3J0RXJyb3IoXG4gICAgbm9kZTogdHMuTm9kZSxcbiAgICBjb2RlOiBEaWFnbm9zdGljQ29kZSxcbiAgICBtZXNzYWdlOiBEaWFnbm9zdGljTWVzc2FnZSxcbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmUgbm8tYW55IHJlYWRvbmx5LWFycmF5XG4gICAgLi4uYXJnczogYW55W11cbiAgKTogdm9pZCB7XG4gICAgdGhpcy5tdXRhYmxlRGlhZ25vc3RpY3MucHVzaChcbiAgICAgIG5ldyBDb21waWxlckRpYWdub3N0aWMobm9kZSwgdGhpcy5nZXREaWFnbm9zdGljTWVzc2FnZShtZXNzYWdlLCAuLi5hcmdzKSwgY29kZSwgdHMuRGlhZ25vc3RpY0NhdGVnb3J5LkVycm9yKSxcbiAgICApO1xuICB9XG5cbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIG5vLWFueSByZWFkb25seS1hcnJheVxuICBwdWJsaWMgcmVwb3J0V2FybmluZyhub2RlOiB0cy5Ob2RlLCBjb2RlOiBEaWFnbm9zdGljQ29kZSwgbWVzc2FnZTogRGlhZ25vc3RpY01lc3NhZ2UsIC4uLmFyZ3M6IGFueVtdKTogdm9pZCB7XG4gICAgdGhpcy5tdXRhYmxlRGlhZ25vc3RpY3MucHVzaChcbiAgICAgIG5ldyBDb21waWxlckRpYWdub3N0aWMobm9kZSwgdGhpcy5nZXREaWFnbm9zdGljTWVzc2FnZShtZXNzYWdlLCAuLi5hcmdzKSwgY29kZSwgdHMuRGlhZ25vc3RpY0NhdGVnb3J5Lldhcm5pbmcpLFxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgcmVwb3J0VW5zdXBwb3J0ZWQobm9kZTogdHMuTm9kZSk6IHZvaWQge1xuICAgIHRoaXMucmVwb3J0RXJyb3Iobm9kZSwgRGlhZ25vc3RpY0NvZGUuR2VuZXJpY1Vuc3VwcG9ydGVkU3ludGF4LCBEaWFnbm9zdGljTWVzc2FnZS5HZW5lcmljVW5zdXBwb3J0ZWRTeW50YXgpO1xuICB9XG5cbiAgcHVibGljIHJlcG9ydFVuc3VwcG9ydGVkRWZmaWNpZW5jeShub2RlOiB0cy5Ob2RlKTogdm9pZCB7XG4gICAgdGhpcy5yZXBvcnRFcnJvcihub2RlLCBEaWFnbm9zdGljQ29kZS5HZW5lcmljVW5zdXBwb3J0ZWRTeW50YXgsIERpYWdub3N0aWNNZXNzYWdlLkVmZmljaWVuY3lVbnN1cHBvcnRlZFN5bnRheCk7XG4gIH1cblxuICBwdWJsaWMgcmVwb3J0VHlwZUVycm9yKG5vZGU6IHRzLk5vZGUpOiB2b2lkIHtcbiAgICB0aGlzLnJlcG9ydEVycm9yKG5vZGUsIERpYWdub3N0aWNDb2RlLlVua25vd25UeXBlLCBEaWFnbm9zdGljTWVzc2FnZS5Db3VsZE5vdEluZmVyVHlwZSk7XG4gIH1cblxuICBwdWJsaWMgcmVwb3J0VHlwZVdhcm5pbmcobm9kZTogdHMuTm9kZSk6IHZvaWQge1xuICAgIHRoaXMucmVwb3J0V2FybmluZyhub2RlLCBEaWFnbm9zdGljQ29kZS5Vbmtub3duVHlwZSwgRGlhZ25vc3RpY01lc3NhZ2UuQ291bGROb3RJbmZlclR5cGVEZW9wdCk7XG4gIH1cblxuICBwdWJsaWMgZ2V0VHlwZShcbiAgICBub2RlOiB0cy5Ob2RlLFxuICAgIHtcbiAgICAgIHdhcm5pbmcgPSBERUZBVUxUX0RJQUdOT1NUSUNfT1BUSU9OUy53YXJuaW5nLFxuICAgICAgZXJyb3IgPSBERUZBVUxUX0RJQUdOT1NUSUNfT1BUSU9OUy5lcnJvcixcbiAgICB9OiBEaWFnbm9zdGljT3B0aW9ucyA9IERFRkFVTFRfRElBR05PU1RJQ19PUFRJT05TLFxuICApOiB0cy5UeXBlIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5tZW1vaXplZCgndHlwZScsIG5vZGVLZXkobm9kZSksICgpID0+IHtcbiAgICAgIGNvbnN0IHR5cGUgPSB0aGlzLmdldE5vdEFueVR5cGVCYXNlKHRzVXRpbHMudHlwZV8uZ2V0VHlwZSh0aGlzLnR5cGVDaGVja2VyLCBub2RlKSk7XG5cbiAgICAgIGlmICh0eXBlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgdGhpcy5yZXBvcnRUeXBlRXJyb3Iobm9kZSk7XG4gICAgICAgIH0gZWxzZSBpZiAod2FybmluZykge1xuICAgICAgICAgIHRoaXMucmVwb3J0VHlwZVdhcm5pbmcobm9kZSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb25zdCBjb25zdHJhaW50VHlwZSA9IHRzVXRpbHMudHlwZV8uZ2V0Q29uc3RyYWludCh0eXBlKTtcbiAgICAgICAgaWYgKGNvbnN0cmFpbnRUeXBlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICByZXR1cm4gY29uc3RyYWludFR5cGU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHR5cGU7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0VHlwZU9mU3ltYm9sKFxuICAgIHN5bWJvbDogdHMuU3ltYm9sIHwgdW5kZWZpbmVkLFxuICAgIG5vZGU6IHRzLk5vZGUsXG4gICAge1xuICAgICAgd2FybmluZyA9IERFRkFVTFRfRElBR05PU1RJQ19PUFRJT05TLndhcm5pbmcsXG4gICAgICBlcnJvciA9IERFRkFVTFRfRElBR05PU1RJQ19PUFRJT05TLmVycm9yLFxuICAgIH06IERpYWdub3N0aWNPcHRpb25zID0gREVGQVVMVF9ESUFHTk9TVElDX09QVElPTlMsXG4gICk6IHRzLlR5cGUgfCB1bmRlZmluZWQge1xuICAgIGlmIChzeW1ib2wgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5tZW1vaXplZCgndHlwZS1vZi1zeW1ib2wnLCBgJHtzeW1ib2xLZXkoc3ltYm9sKX06JHtub2RlS2V5KG5vZGUpfWAsICgpID0+IHtcbiAgICAgIGNvbnN0IHR5cGUgPSB0aGlzLmdldE5vdEFueVR5cGVCYXNlKHRzVXRpbHMudHlwZV8uZ2V0VHlwZUF0TG9jYXRpb24odGhpcy50eXBlQ2hlY2tlciwgc3ltYm9sLCBub2RlKSk7XG4gICAgICBpZiAodHlwZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgIHRoaXMucmVwb3J0VHlwZUVycm9yKG5vZGUpO1xuICAgICAgICB9IGVsc2UgaWYgKHdhcm5pbmcpIHtcbiAgICAgICAgICB0aGlzLnJlcG9ydFR5cGVXYXJuaW5nKG5vZGUpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29uc3QgY29uc3RyYWludFR5cGUgPSB0c1V0aWxzLnR5cGVfLmdldENvbnN0cmFpbnQodHlwZSk7XG4gICAgICAgIGlmIChjb25zdHJhaW50VHlwZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcmV0dXJuIGNvbnN0cmFpbnRUeXBlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0eXBlO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGdldFN5bWJvbChcbiAgICBub2RlOiB0cy5Ob2RlLFxuICAgIHtcbiAgICAgIHdhcm5pbmcgPSBERUZBVUxUX0RJQUdOT1NUSUNfT1BUSU9OUy53YXJuaW5nLFxuICAgICAgZXJyb3IgPSBERUZBVUxUX0RJQUdOT1NUSUNfT1BUSU9OUy5lcnJvcixcbiAgICB9OiBEaWFnbm9zdGljT3B0aW9ucyA9IERFRkFVTFRfRElBR05PU1RJQ19PUFRJT05TLFxuICApOiB0cy5TeW1ib2wgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLm1lbW9pemVkKCdzeW1ib2wnLCBub2RlS2V5KG5vZGUpLCAoKSA9PiB7XG4gICAgICBjb25zdCBzeW1ib2wgPSB0c1V0aWxzLm5vZGUuZ2V0U3ltYm9sKHRoaXMudHlwZUNoZWNrZXIsIG5vZGUpO1xuICAgICAgaWYgKHN5bWJvbCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgIHRoaXMucmVwb3J0U3ltYm9sRXJyb3Iobm9kZSk7XG4gICAgICAgIH0gZWxzZSBpZiAod2FybmluZykge1xuICAgICAgICAgIHRoaXMucmVwb3J0U3ltYm9sV2FybmluZyhub2RlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGFsaWFzZWQgPSB0c1V0aWxzLnN5bWJvbC5nZXRBbGlhc2VkU3ltYm9sKHRoaXMudHlwZUNoZWNrZXIsIHN5bWJvbCk7XG4gICAgICBpZiAoYWxpYXNlZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBhbGlhc2VkO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gc3ltYm9sO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGdldFR5cGVTeW1ib2woXG4gICAgbm9kZTogdHMuTm9kZSxcbiAgICB7XG4gICAgICB3YXJuaW5nID0gREVGQVVMVF9ESUFHTk9TVElDX09QVElPTlMud2FybmluZyxcbiAgICAgIGVycm9yID0gREVGQVVMVF9ESUFHTk9TVElDX09QVElPTlMuZXJyb3IsXG4gICAgfTogRGlhZ25vc3RpY09wdGlvbnMgPSBERUZBVUxUX0RJQUdOT1NUSUNfT1BUSU9OUyxcbiAgKTogdHMuU3ltYm9sIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5tZW1vaXplZCgndHlwZS1zeW1ib2wnLCBub2RlS2V5KG5vZGUpLCAoKSA9PiB7XG4gICAgICBjb25zdCBub1dhcm5PckVycm9yID0geyB3YXJuaW5nOiBmYWxzZSwgZXJyb3I6IGZhbHNlIH07XG4gICAgICBjb25zdCB0eXBlID0gdGhpcy5nZXRUeXBlKG5vZGUsIG5vV2Fybk9yRXJyb3IpO1xuICAgICAgY29uc3Qgc3ltYm9sID0gdGhpcy5nZXRTeW1ib2xGb3JUeXBlKG5vZGUsIHR5cGUsIG5vV2Fybk9yRXJyb3IpO1xuICAgICAgaWYgKHN5bWJvbCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgIHRoaXMucmVwb3J0U3ltYm9sRXJyb3Iobm9kZSk7XG4gICAgICAgIH0gZWxzZSBpZiAod2FybmluZykge1xuICAgICAgICAgIHRoaXMucmVwb3J0U3ltYm9sV2FybmluZyhub2RlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBzeW1ib2w7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0U3ltYm9sRm9yVHlwZShcbiAgICBfbm9kZTogdHMuTm9kZSxcbiAgICB0eXBlOiB0cy5UeXBlIHwgdW5kZWZpbmVkLFxuICAgIF9vcHRpb25zOiBEaWFnbm9zdGljT3B0aW9ucyA9IERFRkFVTFRfRElBR05PU1RJQ19PUFRJT05TLFxuICApOiB0cy5TeW1ib2wgfCB1bmRlZmluZWQge1xuICAgIGlmICh0eXBlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMubWVtb2l6ZWQoJ3N5bWJvbC1mb3ItdHlwZScsIHR5cGVLZXkodHlwZSksICgpID0+IHtcbiAgICAgIGxldCBzeW1ib2wgPSB0c1V0aWxzLnR5cGVfLmdldFN5bWJvbCh0eXBlKTtcbiAgICAgIGlmIChzeW1ib2wgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBzeW1ib2wgPSB0c1V0aWxzLnR5cGVfLmdldEFsaWFzU3ltYm9sKHR5cGUpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc3ltYm9sID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgICAgY29uc3QgYWxpYXNlZCA9IHRzVXRpbHMuc3ltYm9sLmdldEFsaWFzZWRTeW1ib2wodGhpcy50eXBlQ2hlY2tlciwgc3ltYm9sKTtcbiAgICAgIGlmIChhbGlhc2VkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGFsaWFzZWQ7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBzeW1ib2w7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0Tm90QW55VHlwZShcbiAgICBub2RlOiB0cy5Ob2RlLFxuICAgIHR5cGVJbjogdHMuVHlwZSB8IHVuZGVmaW5lZCxcbiAgICB7XG4gICAgICB3YXJuaW5nID0gREVGQVVMVF9ESUFHTk9TVElDX09QVElPTlMud2FybmluZyxcbiAgICAgIGVycm9yID0gREVGQVVMVF9ESUFHTk9TVElDX09QVElPTlMuZXJyb3IsXG4gICAgfTogRGlhZ25vc3RpY09wdGlvbnMgPSBERUZBVUxUX0RJQUdOT1NUSUNfT1BUSU9OUyxcbiAgKTogdHMuVHlwZSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgdHlwZSA9IHRoaXMuZ2V0Tm90QW55VHlwZUJhc2UodHlwZUluKTtcbiAgICBpZiAodHlwZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgdGhpcy5yZXBvcnRUeXBlRXJyb3Iobm9kZSk7XG4gICAgICB9IGVsc2UgaWYgKHdhcm5pbmcpIHtcbiAgICAgICAgdGhpcy5yZXBvcnRUeXBlV2FybmluZyhub2RlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHlwZTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Tm90QW55VHlwZUJhc2UodHlwZTogdHMuVHlwZSB8IHVuZGVmaW5lZCk6IHRzLlR5cGUgfCB1bmRlZmluZWQge1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSBuby1iaXR3aXNlXG4gICAgaWYgKHR5cGUgPT09IHVuZGVmaW5lZCB8fCB0c1V0aWxzLnR5cGVfLmlzQW55KHR5cGUpKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHJldHVybiB0eXBlO1xuICB9XG5cbiAgcHJpdmF0ZSByZXBvcnRTeW1ib2xFcnJvcihub2RlOiB0cy5Ob2RlKTogdm9pZCB7XG4gICAgdGhpcy5yZXBvcnRFcnJvcihub2RlLCBEaWFnbm9zdGljQ29kZS5Vbmtub3duU3ltYm9sLCBEaWFnbm9zdGljTWVzc2FnZS5Db3VsZE5vdEluZmVyU3ltYm9sKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVwb3J0U3ltYm9sV2FybmluZyhub2RlOiB0cy5Ob2RlKTogdm9pZCB7XG4gICAgdGhpcy5yZXBvcnRFcnJvcihub2RlLCBEaWFnbm9zdGljQ29kZS5Vbmtub3duU3ltYm9sLCBEaWFnbm9zdGljTWVzc2FnZS5Db3VsZE5vdEluZmVyU3ltYm9sRGVvcHQpO1xuICB9XG5cbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIG5vLWFueSByZWFkb25seS1hcnJheVxuICBwcml2YXRlIGdldERpYWdub3N0aWNNZXNzYWdlKG1lc3NhZ2U6IERpYWdub3N0aWNNZXNzYWdlLCAuLi5hcmdzOiBhbnlbXSk6IHN0cmluZyB7XG4gICAgY29uc3QgbWF0Y2ggPSBtZXNzYWdlLm1hdGNoKC8lW2RmaWpvT3NdL2cpO1xuICAgIGNvbnN0IGV4cGVjdGVkTGVuZ3RoID0gKG1hdGNoID09PSBudWxsID8gW10gOiBtYXRjaCkubGVuZ3RoO1xuICAgIGlmIChleHBlY3RlZExlbmd0aCAhPT0gYXJncy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYFRoZSBwcm92aWRlZCBhcmd1bWVudHMgbGVuZ3RoICgke1xuICAgICAgICAgIGFyZ3MubGVuZ3RoXG4gICAgICAgIH0pIGRvZXMgbm90IG1hdGNoIHRoZSByZXF1aXJlZCBhcmd1bWVudHMgbGVuZ3RoICgke2V4cGVjdGVkTGVuZ3RofSlgLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZm9ybWF0KG1lc3NhZ2UsIC4uLmFyZ3MpO1xuICB9XG59XG4iXX0=