| 1 | 'use strict';var _minimatch = require('minimatch');var _minimatch2 = _interopRequireDefault(_minimatch);
|
|---|
| 2 |
|
|---|
| 3 | var _resolve = require('eslint-module-utils/resolve');var _resolve2 = _interopRequireDefault(_resolve);
|
|---|
| 4 | var _importType = require('../core/importType');var _importType2 = _interopRequireDefault(_importType);
|
|---|
| 5 | var _moduleVisitor = require('eslint-module-utils/moduleVisitor');var _moduleVisitor2 = _interopRequireDefault(_moduleVisitor);
|
|---|
| 6 | var _docsUrl = require('../docsUrl');var _docsUrl2 = _interopRequireDefault(_docsUrl);function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { 'default': obj };}
|
|---|
| 7 |
|
|---|
| 8 | module.exports = {
|
|---|
| 9 | meta: {
|
|---|
| 10 | type: 'suggestion',
|
|---|
| 11 | docs: {
|
|---|
| 12 | category: 'Static analysis',
|
|---|
| 13 | description: 'Forbid importing the submodules of other modules.',
|
|---|
| 14 | url: (0, _docsUrl2['default'])('no-internal-modules') },
|
|---|
| 15 |
|
|---|
| 16 |
|
|---|
| 17 | schema: [
|
|---|
| 18 | {
|
|---|
| 19 | anyOf: [
|
|---|
| 20 | {
|
|---|
| 21 | type: 'object',
|
|---|
| 22 | properties: {
|
|---|
| 23 | allow: {
|
|---|
| 24 | type: 'array',
|
|---|
| 25 | items: {
|
|---|
| 26 | type: 'string' } } },
|
|---|
| 27 |
|
|---|
| 28 |
|
|---|
| 29 |
|
|---|
| 30 | additionalProperties: false },
|
|---|
| 31 |
|
|---|
| 32 | {
|
|---|
| 33 | type: 'object',
|
|---|
| 34 | properties: {
|
|---|
| 35 | forbid: {
|
|---|
| 36 | type: 'array',
|
|---|
| 37 | items: {
|
|---|
| 38 | type: 'string' } } },
|
|---|
| 39 |
|
|---|
| 40 |
|
|---|
| 41 |
|
|---|
| 42 | additionalProperties: false }] }] },
|
|---|
| 43 |
|
|---|
| 44 |
|
|---|
| 45 |
|
|---|
| 46 |
|
|---|
| 47 |
|
|---|
| 48 |
|
|---|
| 49 | create: function () {function noReachingInside(context) {
|
|---|
| 50 | var options = context.options[0] || {};
|
|---|
| 51 | var allowRegexps = (options.allow || []).map(function (p) {return _minimatch2['default'].makeRe(p);});
|
|---|
| 52 | var forbidRegexps = (options.forbid || []).map(function (p) {return _minimatch2['default'].makeRe(p);});
|
|---|
| 53 |
|
|---|
| 54 | // minimatch patterns are expected to use / path separators, like import
|
|---|
| 55 | // statements, so normalize paths to use the same
|
|---|
| 56 | function normalizeSep(somePath) {
|
|---|
| 57 | return somePath.split('\\').join('/');
|
|---|
| 58 | }
|
|---|
| 59 |
|
|---|
| 60 | function toSteps(somePath) {
|
|---|
| 61 | return normalizeSep(somePath).
|
|---|
| 62 | split('/').
|
|---|
| 63 | filter(function (step) {return step && step !== '.';}).
|
|---|
| 64 | reduce(function (acc, step) {
|
|---|
| 65 | if (step === '..') {
|
|---|
| 66 | return acc.slice(0, -1);
|
|---|
| 67 | }
|
|---|
| 68 | return acc.concat(step);
|
|---|
| 69 | }, []);
|
|---|
| 70 | }
|
|---|
| 71 |
|
|---|
| 72 | // test if reaching to this destination is allowed
|
|---|
| 73 | function reachingAllowed(importPath) {
|
|---|
| 74 | return allowRegexps.some(function (re) {return re.test(importPath);});
|
|---|
| 75 | }
|
|---|
| 76 |
|
|---|
| 77 | // test if reaching to this destination is forbidden
|
|---|
| 78 | function reachingForbidden(importPath) {
|
|---|
| 79 | return forbidRegexps.some(function (re) {return re.test(importPath);});
|
|---|
| 80 | }
|
|---|
| 81 |
|
|---|
| 82 | function isAllowViolation(importPath) {
|
|---|
| 83 | var steps = toSteps(importPath);
|
|---|
| 84 |
|
|---|
| 85 | var nonScopeSteps = steps.filter(function (step) {return step.indexOf('@') !== 0;});
|
|---|
| 86 | if (nonScopeSteps.length <= 1) {return false;}
|
|---|
| 87 |
|
|---|
| 88 | // before trying to resolve, see if the raw import (with relative
|
|---|
| 89 | // segments resolved) matches an allowed pattern
|
|---|
| 90 | var justSteps = steps.join('/');
|
|---|
| 91 | if (reachingAllowed(justSteps) || reachingAllowed('/' + String(justSteps))) {return false;}
|
|---|
| 92 |
|
|---|
| 93 | // if the import statement doesn't match directly, try to match the
|
|---|
| 94 | // resolved path if the import is resolvable
|
|---|
| 95 | var resolved = (0, _resolve2['default'])(importPath, context);
|
|---|
| 96 | if (!resolved || reachingAllowed(normalizeSep(resolved))) {return false;}
|
|---|
| 97 |
|
|---|
| 98 | // this import was not allowed by the allowed paths, and reaches
|
|---|
| 99 | // so it is a violation
|
|---|
| 100 | return true;
|
|---|
| 101 | }
|
|---|
| 102 |
|
|---|
| 103 | function isForbidViolation(importPath) {
|
|---|
| 104 | var steps = toSteps(importPath);
|
|---|
| 105 |
|
|---|
| 106 | // before trying to resolve, see if the raw import (with relative
|
|---|
| 107 | // segments resolved) matches a forbidden pattern
|
|---|
| 108 | var justSteps = steps.join('/');
|
|---|
| 109 |
|
|---|
| 110 | if (reachingForbidden(justSteps) || reachingForbidden('/' + String(justSteps))) {return true;}
|
|---|
| 111 |
|
|---|
| 112 | // if the import statement doesn't match directly, try to match the
|
|---|
| 113 | // resolved path if the import is resolvable
|
|---|
| 114 | var resolved = (0, _resolve2['default'])(importPath, context);
|
|---|
| 115 | if (resolved && reachingForbidden(normalizeSep(resolved))) {return true;}
|
|---|
| 116 |
|
|---|
| 117 | // this import was not forbidden by the forbidden paths so it is not a violation
|
|---|
| 118 | return false;
|
|---|
| 119 | }
|
|---|
| 120 |
|
|---|
| 121 | // find a directory that is being reached into, but which shouldn't be
|
|---|
| 122 | var isReachViolation = options.forbid ? isForbidViolation : isAllowViolation;
|
|---|
| 123 |
|
|---|
| 124 | function checkImportForReaching(importPath, node) {
|
|---|
| 125 | var potentialViolationTypes = ['parent', 'index', 'sibling', 'external', 'internal'];
|
|---|
| 126 | if (
|
|---|
| 127 | potentialViolationTypes.indexOf((0, _importType2['default'])(importPath, context)) !== -1 &&
|
|---|
| 128 | isReachViolation(importPath))
|
|---|
| 129 | {
|
|---|
| 130 | context.report({
|
|---|
| 131 | node: node,
|
|---|
| 132 | message: 'Reaching to "' + String(importPath) + '" is not allowed.' });
|
|---|
| 133 |
|
|---|
| 134 | }
|
|---|
| 135 | }
|
|---|
| 136 |
|
|---|
| 137 | return (0, _moduleVisitor2['default'])(
|
|---|
| 138 | function (source) {
|
|---|
| 139 | checkImportForReaching(source.value, source);
|
|---|
| 140 | },
|
|---|
| 141 | { commonjs: true });
|
|---|
| 142 |
|
|---|
| 143 | }return noReachingInside;}() };
|
|---|
| 144 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydWxlcy9uby1pbnRlcm5hbC1tb2R1bGVzLmpzIl0sIm5hbWVzIjpbIm1vZHVsZSIsImV4cG9ydHMiLCJtZXRhIiwidHlwZSIsImRvY3MiLCJjYXRlZ29yeSIsImRlc2NyaXB0aW9uIiwidXJsIiwic2NoZW1hIiwiYW55T2YiLCJwcm9wZXJ0aWVzIiwiYWxsb3ciLCJpdGVtcyIsImFkZGl0aW9uYWxQcm9wZXJ0aWVzIiwiZm9yYmlkIiwiY3JlYXRlIiwibm9SZWFjaGluZ0luc2lkZSIsImNvbnRleHQiLCJvcHRpb25zIiwiYWxsb3dSZWdleHBzIiwibWFwIiwicCIsIm1pbmltYXRjaCIsIm1ha2VSZSIsImZvcmJpZFJlZ2V4cHMiLCJub3JtYWxpemVTZXAiLCJzb21lUGF0aCIsInNwbGl0Iiwiam9pbiIsInRvU3RlcHMiLCJmaWx0ZXIiLCJzdGVwIiwicmVkdWNlIiwiYWNjIiwic2xpY2UiLCJjb25jYXQiLCJyZWFjaGluZ0FsbG93ZWQiLCJpbXBvcnRQYXRoIiwic29tZSIsInJlIiwidGVzdCIsInJlYWNoaW5nRm9yYmlkZGVuIiwiaXNBbGxvd1Zpb2xhdGlvbiIsInN0ZXBzIiwibm9uU2NvcGVTdGVwcyIsImluZGV4T2YiLCJsZW5ndGgiLCJqdXN0U3RlcHMiLCJyZXNvbHZlZCIsImlzRm9yYmlkVmlvbGF0aW9uIiwiaXNSZWFjaFZpb2xhdGlvbiIsImNoZWNrSW1wb3J0Rm9yUmVhY2hpbmciLCJub2RlIiwicG90ZW50aWFsVmlvbGF0aW9uVHlwZXMiLCJyZXBvcnQiLCJtZXNzYWdlIiwic291cmNlIiwidmFsdWUiLCJjb21tb25qcyJdLCJtYXBwaW5ncyI6ImFBQUEsc0M7O0FBRUEsc0Q7QUFDQSxnRDtBQUNBLGtFO0FBQ0EscUM7O0FBRUFBLE9BQU9DLE9BQVAsR0FBaUI7QUFDZkMsUUFBTTtBQUNKQyxVQUFNLFlBREY7QUFFSkMsVUFBTTtBQUNKQyxnQkFBVSxpQkFETjtBQUVKQyxtQkFBYSxtREFGVDtBQUdKQyxXQUFLLDBCQUFR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QU87QUFDTCxnQkFBQ21CLE1BQUQsRUFBWTtBQUNWTCwrQkFBdUJLLE9BQU9DLEtBQTlCLEVBQXFDRCxNQUFyQztBQUNELE9BSEk7QUFJTCxRQUFFRSxVQUFVLElBQVosRUFKSyxDQUFQOztBQU1ELEtBOUZELE9BQWlCMUMsZ0JBQWpCLElBekNlLEVBQWpCIiwiZmlsZSI6Im5vLWludGVybmFsLW1vZHVsZXMuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgbWluaW1hdGNoIGZyb20gJ21pbmltYXRjaCc7XG5cbmltcG9ydCByZXNvbHZlIGZyb20gJ2VzbGludC1tb2R1bGUtdXRpbHMvcmVzb2x2ZSc7XG5pbXBvcnQgaW1wb3J0VHlwZSBmcm9tICcuLi9jb3JlL2ltcG9ydFR5cGUnO1xuaW1wb3J0IG1vZHVsZVZpc2l0b3IgZnJvbSAnZXNsaW50LW1vZHVsZS11dGlscy9tb2R1bGVWaXNpdG9yJztcbmltcG9ydCBkb2NzVXJsIGZyb20gJy4uL2RvY3NVcmwnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgbWV0YToge1xuICAgIHR5cGU6ICdzdWdnZXN0aW9uJyxcbiAgICBkb2NzOiB7XG4gICAgICBjYXRlZ29yeTogJ1N0YXRpYyBhbmFseXNpcycsXG4gICAgICBkZXNjcmlwdGlvbjogJ0ZvcmJpZCBpbXBvcnRpbmcgdGhlIHN1Ym1vZHVsZXMgb2Ygb3RoZXIgbW9kdWxlcy4nLFxuICAgICAgdXJsOiBkb2NzVXJsKCduby1pbnRlcm5hbC1tb2R1bGVzJyksXG4gICAgfSxcblxuICAgIHNjaGVtYTogW1xuICAgICAge1xuICAgICAgICBhbnlPZjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgICAgICBhbGxvdzoge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdhcnJheScsXG4gICAgICAgICAgICAgICAgaXRlbXM6IHtcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlLFxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICAgIGZvcmJpZDoge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdhcnJheScsXG4gICAgICAgICAgICAgICAgaXRlbXM6IHtcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9LFxuICAgIF0sXG4gIH0sXG5cbiAgY3JlYXRlOiBmdW5jdGlvbiBub1JlYWNoaW5nSW5zaWRlKGNvbnRleHQpIHtcbiAgICBjb25zdCBvcHRpb25zID0gY29udGV4dC5vcHRpb25zWzBdIHx8IHt9O1xuICAgIGNvbnN0IGFsbG93UmVnZXhwcyA9IChvcHRpb25zLmFsbG93IHx8IFtdKS5tYXAoKHApID0+IG1pbmltYXRjaC5tYWtlUmUocCkpO1xuICAgIGNvbnN0IGZvcmJpZFJlZ2V4cHMgPSAob3B0aW9ucy5mb3JiaWQgfHwgW10pLm1hcCgocCkgPT4gbWluaW1hdGNoLm1ha2VSZShwKSk7XG5cbiAgICAvLyBtaW5pbWF0Y2ggcGF0dGVybnMgYXJlIGV4cGVjdGVkIHRvIHVzZSAvIHBhdGggc2VwYXJhdG9ycywgbGlrZSBpbXBvcnRcbiAgICAvLyBzdGF0ZW1lbnRzLCBzbyBub3JtYWxpemUgcGF0aHMgdG8gdXNlIHRoZSBzYW1lXG4gICAgZnVuY3Rpb24gbm9ybWFsaXplU2VwKHNvbWVQYXRoKSB7XG4gICAgICByZXR1cm4gc29tZVBhdGguc3BsaXQoJ1xcXFwnKS5qb2luKCcvJyk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdG9TdGVwcyhzb21lUGF0aCkge1xuICAgICAgcmV0dXJuIG5vcm1hbGl6ZVNlcChzb21lUGF0aClcbiAgICAgICAgLnNwbGl0KCcvJylcbiAgICAgICAgLmZpbHRlcigoc3RlcCkgPT4gc3RlcCAmJiBzdGVwICE9PSAnLicpXG4gICAgICAgIC5yZWR1Y2UoKGFjYywgc3RlcCkgPT4ge1xuICAgICAgICAgIGlmIChzdGVwID09PSAnLi4nKSB7XG4gICAgICAgICAgICByZXR1cm4gYWNjLnNsaWNlKDAsIC0xKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGFjYy5jb25jYXQoc3RlcCk7XG4gICAgICAgIH0sIFtdKTtcbiAgICB9XG5cbiAgICAvLyB0ZXN0IGlmIHJlYWNoaW5nIHRvIHRoaXMgZGVzdGluYXRpb24gaXMgYWxsb3dlZFxuICAgIGZ1bmN0aW9uIHJlYWNoaW5nQWxsb3dlZChpbXBvcnRQYXRoKSB7XG4gICAgICByZXR1cm4gYWxsb3dSZWdleHBzLnNvbWUoKHJlKSA9PiByZS50ZXN0KGltcG9ydFBhdGgpKTtcbiAgICB9XG5cbiAgICAvLyB0ZXN0IGlmIHJlYWNoaW5nIHRvIHRoaXMgZGVzdGluYXRpb24gaXMgZm9yYmlkZGVuXG4gICAgZnVuY3Rpb24gcmVhY2hpbmdGb3JiaWRkZW4oaW1wb3J0UGF0aCkge1xuICAgICAgcmV0dXJuIGZvcmJpZFJlZ2V4cHMuc29tZSgocmUpID0+IHJlLnRlc3QoaW1wb3J0UGF0aCkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGlzQWxsb3dWaW9sYXRpb24oaW1wb3J0UGF0aCkge1xuICAgICAgY29uc3Qgc3RlcHMgPSB0b1N0ZXBzKGltcG9ydFBhdGgpO1xuXG4gICAgICBjb25zdCBub25TY29wZVN0ZXBzID0gc3RlcHMuZmlsdGVyKChzdGVwKSA9PiBzdGVwLmluZGV4T2YoJ0AnKSAhPT0gMCk7XG4gICAgICBpZiAobm9uU2NvcGVTdGVwcy5sZW5ndGggPD0gMSkgeyByZXR1cm4gZmFsc2U7IH1cblxuICAgICAgLy8gYmVmb3JlIHRyeWluZyB0byByZXNvbHZlLCBzZWUgaWYgdGhlIHJhdyBpbXBvcnQgKHdpdGggcmVsYXRpdmVcbiAgICAgIC8vIHNlZ21lbnRzIHJlc29sdmVkKSBtYXRjaGVzIGFuIGFsbG93ZWQgcGF0dGVyblxuICAgICAgY29uc3QganVzdFN0ZXBzID0gc3RlcHMuam9pbignLycpO1xuICAgICAgaWYgKHJlYWNoaW5nQWxsb3dlZChqdXN0U3RlcHMpIHx8IHJlYWNoaW5nQWxsb3dlZChgLyR7anVzdFN0ZXBzfWApKSB7IHJldHVybiBmYWxzZTsgfVxuXG4gICAgICAvLyBpZiB0aGUgaW1wb3J0IHN0YXRlbWVudCBkb2Vzbid0IG1hdGNoIGRpcmVjdGx5LCB0cnkgdG8gbWF0Y2ggdGhlXG4gICAgICAvLyByZXNvbHZlZCBwYXRoIGlmIHRoZSBpbXBvcnQgaXMgcmVzb2x2YWJsZVxuICAgICAgY29uc3QgcmVzb2x2ZWQgPSByZXNvbHZlKGltcG9ydFBhdGgsIGNvbnRleHQpO1xuICAgICAgaWYgKCFyZXNvbHZlZCB8fCByZWFjaGluZ0FsbG93ZWQobm9ybWFsaXplU2VwKHJlc29sdmVkKSkpIHsgcmV0dXJuIGZhbHNlOyB9XG5cbiAgICAgIC8vIHRoaXMgaW1wb3J0IHdhcyBub3QgYWxsb3dlZCBieSB0aGUgYWxsb3dlZCBwYXRocywgYW5kIHJlYWNoZXNcbiAgICAgIC8vIHNvIGl0IGlzIGEgdmlvbGF0aW9uXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc0ZvcmJpZFZpb2xhdGlvbihpbXBvcnRQYXRoKSB7XG4gICAgICBjb25zdCBzdGVwcyA9IHRvU3RlcHMoaW1wb3J0UGF0aCk7XG5cbiAgICAgIC8vIGJlZm9yZSB0cnlpbmcgdG8gcmVzb2x2ZSwgc2VlIGlmIHRoZSByYXcgaW1wb3J0ICh3aXRoIHJlbGF0aXZlXG4gICAgICAvLyBzZWdtZW50cyByZXNvbHZlZCkgbWF0Y2hlcyBhIGZvcmJpZGRlbiBwYXR0ZXJuXG4gICAgICBjb25zdCBqdXN0U3RlcHMgPSBzdGVwcy5qb2luKCcvJyk7XG5cbiAgICAgIGlmIChyZWFjaGluZ0ZvcmJpZGRlbihqdXN0U3RlcHMpIHx8IHJlYWNoaW5nRm9yYmlkZGVuKGAvJHtqdXN0U3RlcHN9YCkpIHsgcmV0dXJuIHRydWU7IH1cblxuICAgICAgLy8gaWYgdGhlIGltcG9ydCBzdGF0ZW1lbnQgZG9lc24ndCBtYXRjaCBkaXJlY3RseSwgdHJ5IHRvIG1hdGNoIHRoZVxuICAgICAgLy8gcmVzb2x2ZWQgcGF0aCBpZiB0aGUgaW1wb3J0IGlzIHJlc29sdmFibGVcbiAgICAgIGNvbnN0IHJlc29sdmVkID0gcmVzb2x2ZShpbXBvcnRQYXRoLCBjb250ZXh0KTtcbiAgICAgIGlmIChyZXNvbHZlZCAmJiByZWFjaGluZ0ZvcmJpZGRlbihub3JtYWxpemVTZXAocmVzb2x2ZWQpKSkgeyByZXR1cm4gdHJ1ZTsgfVxuXG4gICAgICAvLyB0aGlzIGltcG9ydCB3YXMgbm90IGZvcmJpZGRlbiBieSB0aGUgZm9yYmlkZGVuIHBhdGhzIHNvIGl0IGlzIG5vdCBhIHZpb2xhdGlvblxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIGZpbmQgYSBkaXJlY3RvcnkgdGhhdCBpcyBiZWluZyByZWFjaGVkIGludG8sIGJ1dCB3aGljaCBzaG91bGRuJ3QgYmVcbiAgICBjb25zdCBpc1JlYWNoVmlvbGF0aW9uID0gb3B0aW9ucy5mb3JiaWQgPyBpc0ZvcmJpZFZpb2xhdGlvbiA6IGlzQWxsb3dWaW9sYXRpb247XG5cbiAgICBmdW5jdGlvbiBjaGVja0ltcG9ydEZvclJlYWNoaW5nKGltcG9ydFBhdGgsIG5vZGUpIHtcbiAgICAgIGNvbnN0IHBvdGVudGlhbFZpb2xhdGlvblR5cGVzID0gWydwYXJlbnQnLCAnaW5kZXgnLCAnc2libGluZycsICdleHRlcm5hbCcsICdpbnRlcm5hbCddO1xuICAgICAgaWYgKFxuICAgICAgICBwb3RlbnRpYWxWaW9sYXRpb25UeXBlcy5pbmRleE9mKGltcG9ydFR5cGUoaW1wb3J0UGF0aCwgY29udGV4dCkpICE9PSAtMVxuICAgICAgICAmJiBpc1JlYWNoVmlvbGF0aW9uKGltcG9ydFBhdGgpXG4gICAgICApIHtcbiAgICAgICAgY29udGV4dC5yZXBvcnQoe1xuICAgICAgICAgIG5vZGUsXG4gICAgICAgICAgbWVzc2FnZTogYFJlYWNoaW5nIHRvIFwiJHtpbXBvcnRQYXRofVwiIGlzIG5vdCBhbGxvd2VkLmAsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBtb2R1bGVWaXNpdG9yKFxuICAgICAgKHNvdXJjZSkgPT4ge1xuICAgICAgICBjaGVja0ltcG9ydEZvclJlYWNoaW5nKHNvdXJjZS52YWx1ZSwgc291cmNlKTtcbiAgICAgIH0sXG4gICAgICB7IGNvbW1vbmpzOiB0cnVlIH0sXG4gICAgKTtcbiAgfSxcbn07XG4iXX0= |
|---|