mirror of
https://github.com/github/codeql-action.git
synced 2025-12-31 19:50:32 +08:00
246 lines
30 KiB
JavaScript
246 lines
30 KiB
JavaScript
'use strict';var _path = require('path');var _path2 = _interopRequireDefault(_path);
|
|
|
|
var _resolve = require('eslint-module-utils/resolve');var _resolve2 = _interopRequireDefault(_resolve);
|
|
var _moduleVisitor = require('eslint-module-utils/moduleVisitor');var _moduleVisitor2 = _interopRequireDefault(_moduleVisitor);
|
|
var _isGlob = require('is-glob');var _isGlob2 = _interopRequireDefault(_isGlob);
|
|
var _minimatch = require('minimatch');
|
|
var _docsUrl = require('../docsUrl');var _docsUrl2 = _interopRequireDefault(_docsUrl);
|
|
var _importType = require('../core/importType');var _importType2 = _interopRequireDefault(_importType);function _interopRequireDefault(obj) {return obj && obj.__esModule ? obj : { 'default': obj };}
|
|
|
|
var containsPath = function containsPath(filepath, target) {
|
|
var relative = _path2['default'].relative(target, filepath);
|
|
return relative === '' || !relative.startsWith('..');
|
|
};
|
|
|
|
module.exports = {
|
|
meta: {
|
|
type: 'problem',
|
|
docs: {
|
|
category: 'Static analysis',
|
|
description: 'Enforce which files can be imported in a given folder.',
|
|
url: (0, _docsUrl2['default'])('no-restricted-paths') },
|
|
|
|
|
|
schema: [
|
|
{
|
|
type: 'object',
|
|
properties: {
|
|
zones: {
|
|
type: 'array',
|
|
minItems: 1,
|
|
items: {
|
|
type: 'object',
|
|
properties: {
|
|
target: {
|
|
anyOf: [
|
|
{ type: 'string' },
|
|
{
|
|
type: 'array',
|
|
items: { type: 'string' },
|
|
uniqueItems: true,
|
|
minLength: 1 }] },
|
|
|
|
|
|
|
|
from: {
|
|
anyOf: [
|
|
{ type: 'string' },
|
|
{
|
|
type: 'array',
|
|
items: { type: 'string' },
|
|
uniqueItems: true,
|
|
minLength: 1 }] },
|
|
|
|
|
|
|
|
except: {
|
|
type: 'array',
|
|
items: {
|
|
type: 'string' },
|
|
|
|
uniqueItems: true },
|
|
|
|
message: { type: 'string' } },
|
|
|
|
additionalProperties: false } },
|
|
|
|
|
|
basePath: { type: 'string' } },
|
|
|
|
additionalProperties: false }] },
|
|
|
|
|
|
|
|
|
|
create: function () {function noRestrictedPaths(context) {
|
|
var options = context.options[0] || {};
|
|
var restrictedPaths = options.zones || [];
|
|
var basePath = options.basePath || process.cwd();
|
|
var currentFilename = context.getPhysicalFilename ? context.getPhysicalFilename() : context.getFilename();
|
|
var matchingZones = restrictedPaths.filter(function (zone) {
|
|
return [].concat(zone.target).
|
|
map(function (target) {return _path2['default'].resolve(basePath, target);}).
|
|
some(function (targetPath) {return isMatchingTargetPath(currentFilename, targetPath);});
|
|
});
|
|
|
|
function isMatchingTargetPath(filename, targetPath) {
|
|
if ((0, _isGlob2['default'])(targetPath)) {
|
|
var mm = new _minimatch.Minimatch(targetPath);
|
|
return mm.match(filename);
|
|
}
|
|
|
|
return containsPath(filename, targetPath);
|
|
}
|
|
|
|
function isValidExceptionPath(absoluteFromPath, absoluteExceptionPath) {
|
|
var relativeExceptionPath = _path2['default'].relative(absoluteFromPath, absoluteExceptionPath);
|
|
|
|
return (0, _importType2['default'])(relativeExceptionPath, context) !== 'parent';
|
|
}
|
|
|
|
function areBothGlobPatternAndAbsolutePath(areGlobPatterns) {
|
|
return areGlobPatterns.some(function (isGlob) {return isGlob;}) && areGlobPatterns.some(function (isGlob) {return !isGlob;});
|
|
}
|
|
|
|
function reportInvalidExceptionPath(node) {
|
|
context.report({
|
|
node: node,
|
|
message: 'Restricted path exceptions must be descendants of the configured `from` path for that zone.' });
|
|
|
|
}
|
|
|
|
function reportInvalidExceptionMixedGlobAndNonGlob(node) {
|
|
context.report({
|
|
node: node,
|
|
message: 'Restricted path `from` must contain either only glob patterns or none' });
|
|
|
|
}
|
|
|
|
function reportInvalidExceptionGlob(node) {
|
|
context.report({
|
|
node: node,
|
|
message: 'Restricted path exceptions must be glob patterns when `from` contains glob patterns' });
|
|
|
|
}
|
|
|
|
function computeMixedGlobAndAbsolutePathValidator() {
|
|
return {
|
|
isPathRestricted: function () {function isPathRestricted() {return true;}return isPathRestricted;}(),
|
|
hasValidExceptions: false,
|
|
reportInvalidException: reportInvalidExceptionMixedGlobAndNonGlob };
|
|
|
|
}
|
|
|
|
function computeGlobPatternPathValidator(absoluteFrom, zoneExcept) {
|
|
var isPathException = void 0;
|
|
|
|
var mm = new _minimatch.Minimatch(absoluteFrom);
|
|
var isPathRestricted = function () {function isPathRestricted(absoluteImportPath) {return mm.match(absoluteImportPath);}return isPathRestricted;}();
|
|
var hasValidExceptions = zoneExcept.every(_isGlob2['default']);
|
|
|
|
if (hasValidExceptions) {
|
|
var exceptionsMm = zoneExcept.map(function (except) {return new _minimatch.Minimatch(except);});
|
|
isPathException = function () {function isPathException(absoluteImportPath) {return exceptionsMm.some(function (mm) {return mm.match(absoluteImportPath);});}return isPathException;}();
|
|
}
|
|
|
|
var reportInvalidException = reportInvalidExceptionGlob;
|
|
|
|
return {
|
|
isPathRestricted: isPathRestricted,
|
|
hasValidExceptions: hasValidExceptions,
|
|
isPathException: isPathException,
|
|
reportInvalidException: reportInvalidException };
|
|
|
|
}
|
|
|
|
function computeAbsolutePathValidator(absoluteFrom, zoneExcept) {
|
|
var isPathException = void 0;
|
|
|
|
var isPathRestricted = function () {function isPathRestricted(absoluteImportPath) {return containsPath(absoluteImportPath, absoluteFrom);}return isPathRestricted;}();
|
|
|
|
var absoluteExceptionPaths = zoneExcept.
|
|
map(function (exceptionPath) {return _path2['default'].resolve(absoluteFrom, exceptionPath);});
|
|
var hasValidExceptions = absoluteExceptionPaths.
|
|
every(function (absoluteExceptionPath) {return isValidExceptionPath(absoluteFrom, absoluteExceptionPath);});
|
|
|
|
if (hasValidExceptions) {
|
|
isPathException = function () {function isPathException(absoluteImportPath) {return absoluteExceptionPaths.some(
|
|
function (absoluteExceptionPath) {return containsPath(absoluteImportPath, absoluteExceptionPath);});}return isPathException;}();
|
|
|
|
}
|
|
|
|
var reportInvalidException = reportInvalidExceptionPath;
|
|
|
|
return {
|
|
isPathRestricted: isPathRestricted,
|
|
hasValidExceptions: hasValidExceptions,
|
|
isPathException: isPathException,
|
|
reportInvalidException: reportInvalidException };
|
|
|
|
}
|
|
|
|
function reportInvalidExceptions(validators, node) {
|
|
validators.forEach(function (validator) {return validator.reportInvalidException(node);});
|
|
}
|
|
|
|
function reportImportsInRestrictedZone(validators, node, importPath, customMessage) {
|
|
validators.forEach(function () {
|
|
context.report({
|
|
node: node,
|
|
message: 'Unexpected path "{{importPath}}" imported in restricted zone.' + (customMessage ? ' ' + String(customMessage) : ''),
|
|
data: { importPath: importPath } });
|
|
|
|
});
|
|
}
|
|
|
|
var makePathValidators = function () {function makePathValidators(zoneFrom) {var zoneExcept = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
var allZoneFrom = [].concat(zoneFrom);
|
|
var areGlobPatterns = allZoneFrom.map(_isGlob2['default']);
|
|
|
|
if (areBothGlobPatternAndAbsolutePath(areGlobPatterns)) {
|
|
return [computeMixedGlobAndAbsolutePathValidator()];
|
|
}
|
|
|
|
var isGlobPattern = areGlobPatterns.every(function (isGlob) {return isGlob;});
|
|
|
|
return allZoneFrom.map(function (singleZoneFrom) {
|
|
var absoluteFrom = _path2['default'].resolve(basePath, singleZoneFrom);
|
|
|
|
if (isGlobPattern) {
|
|
return computeGlobPatternPathValidator(absoluteFrom, zoneExcept);
|
|
}
|
|
return computeAbsolutePathValidator(absoluteFrom, zoneExcept);
|
|
});
|
|
}return makePathValidators;}();
|
|
|
|
var validators = [];
|
|
|
|
function checkForRestrictedImportPath(importPath, node) {
|
|
var absoluteImportPath = (0, _resolve2['default'])(importPath, context);
|
|
|
|
if (!absoluteImportPath) {
|
|
return;
|
|
}
|
|
|
|
matchingZones.forEach(function (zone, index) {
|
|
if (!validators[index]) {
|
|
validators[index] = makePathValidators(zone.from, zone.except);
|
|
}
|
|
|
|
var applicableValidatorsForImportPath = validators[index].filter(function (validator) {return validator.isPathRestricted(absoluteImportPath);});
|
|
|
|
var validatorsWithInvalidExceptions = applicableValidatorsForImportPath.filter(function (validator) {return !validator.hasValidExceptions;});
|
|
reportInvalidExceptions(validatorsWithInvalidExceptions, node);
|
|
|
|
var applicableValidatorsForImportPathExcludingExceptions = applicableValidatorsForImportPath.
|
|
filter(function (validator) {return validator.hasValidExceptions;}).
|
|
filter(function (validator) {return !validator.isPathException(absoluteImportPath);});
|
|
reportImportsInRestrictedZone(applicableValidatorsForImportPathExcludingExceptions, node, importPath, zone.message);
|
|
});
|
|
}
|
|
|
|
return (0, _moduleVisitor2['default'])(function (source) {
|
|
checkForRestrictedImportPath(source.value, source);
|
|
}, { commonjs: true });
|
|
}return noRestrictedPaths;}() };
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydWxlcy9uby1yZXN0cmljdGVkLXBhdGhzLmpzIl0sIm5hbWVzIjpbImNvbnRhaW5zUGF0aCIsImZpbGVwYXRoIiwidGFyZ2V0IiwicmVsYXRpdmUiLCJwYXRoIiwic3RhcnRzV2l0aCIsIm1vZHVsZSIsImV4cG9ydHMiLCJtZXRhIiwidHlwZSIsImRvY3MiLCJjYXRlZ29yeSIsImRlc2NyaXB0aW9uIiwidXJsIiwic2NoZW1hIiwicHJvcGVydGllcyIsInpvbmVzIiwibWluSXRlbXMiLCJpdGVtcyIsImFueU9mIiwidW5pcXVlSXRlbXMiLCJtaW5MZW5ndGgiLCJmcm9tIiwiZXhjZXB0IiwibWVzc2FnZSIsImFkZGl0aW9uYWxQcm9wZXJ0aWVzIiwiYmFzZVBhdGgiLCJjcmVhdGUiLCJub1Jlc3RyaWN0ZWRQYXRocyIsImNvbnRleHQiLCJvcHRpb25zIiwicmVzdHJpY3RlZFBhdGhzIiwicHJvY2VzcyIsImN3ZCIsImN1cnJlbnRGaWxlbmFtZSIsImdldFBoeXNpY2FsRmlsZW5hbWUiLCJnZXRGaWxlbmFtZSIsIm1hdGNoaW5nWm9uZXMiLCJmaWx0ZXIiLCJ6b25lIiwiY29uY2F0IiwibWFwIiwicmVzb2x2ZSIsInNvbWUiLCJpc01hdGNoaW5nVGFyZ2V0UGF0aCIsInRhcmdldFBhdGgiLCJmaWxlbmFtZSIsIm1tIiwiTWluaW1hdGNoIiwibWF0Y2giLCJpc1ZhbGlkRXhjZXB0aW9uUGF0aCIsImFic29sdXRlRnJvbVBhdGgiLCJhYnNvbHV0ZUV4Y2VwdGlvblBhdGgiLCJyZWxhdGl2ZUV4Y2VwdGlvblBhdGgiLCJhcmVCb3RoR2xvYlBhdHRlcm5BbmRBYnNvbHV0ZVBhdGgiLCJhcmVHbG9iUGF0dGVybnMiLCJpc0dsb2IiLCJyZXBvcnRJbnZhbGlkRXhjZXB0aW9uUGF0aCIsIm5vZGUiLCJyZXBvcnQiLCJyZXBvcnRJbnZhbGlkRXhjZXB0aW9uTWl4ZWRHbG9iQW5kTm9uR2xvYiIsInJlcG9ydEludmFsaWRFeGNlcHRpb25HbG9iIiwiY29tcHV0ZU1peGVkR2xvYkFuZEFic29sdXRlUGF0aFZhbGlkYXRvciIsImlzUGF0aFJlc3RyaWN0ZWQiLCJoYXNWYWxpZEV4Y2VwdGlvbnMiLCJyZXBvcnRJbnZhbGlkRXhjZXB0aW9uIiwiY29tcHV0ZUdsb2JQYXR0ZXJuUGF0aFZhbGlkYXRvciIsImFic29sdXRlRnJvbSIsInpvbmVFeGNlcHQiLCJpc1BhdGhFeGNlcHRpb24iLCJhYnNvbHV0ZUltcG9ydFBhdGgiLCJldmVyeSIsImV4Y2VwdGlvbnNNbSIsImNvbXB1dGVBYnNvbHV0ZVBhdGhWYWxpZGF0b3IiLCJhYnNvbHV0ZUV4Y2VwdGlvblBhdGhzIiwiZXhjZXB0aW9uUGF0aCIsInJlcG9ydEludmFsaWRFeGNlcHRpb25zIiwidmFsaWRhdG9ycyIsImZvckVhY2giLCJ2YWxpZGF0b3IiLCJyZXBvcnRJbXBvcnRzSW5SZXN0cmljdGVkWm9uZSIsImltcG9ydFBhdGgiLCJjdXN0b21NZXNzYWdlIiwiZGF0YSIsIm1ha2VQYXRoVmFsaWRhdG9ycyIsInpvbmVGcm9tIiwiYWxsWm9uZUZyb20iLCJpc0dsb2JQYXR0ZXJuIiwic2luZ2xlWm9uZUZyb20iLCJjaGVja0ZvclJlc3RyaWN0ZWRJbXBvcnRQYXRoIiwiaW5kZXgiLCJhcHBsaWNhYmxlVmFsaWRhdG9yc0ZvckltcG9ydFBhdGgiLCJ2YWxpZGF0b3JzV2l0aEludmFsaWRFeGNlcHRpb25zIiwiYXBwbGljYWJsZVZhbGlkYXRvcnNGb3JJbXBvcnRQYXRoRXhjbHVkaW5nRXhjZXB0aW9ucyIsInNvdXJjZSIsInZhbHVlIiwiY29tbW9uanMiXSwibWFwcGluZ3MiOiJhQUFBLDRCOztBQUVBLHNEO0FBQ0Esa0U7QUFDQSxpQztBQUNBO0FBQ0EscUM7QUFDQSxnRDs7QUFFQSxJQUFNQSxlQUFlLFNBQWZBLFlBQWUsQ0FBQ0MsUUFBRCxFQUFXQyxNQUFYLEVBQXNCO0FBQ3pDLE1BQU1DLFdBQVdDLGtCQUFLRCxRQUFMLENBQWNELE1BQWQsRUFBc0JELFFBQXRCLENBQWpCO0FBQ0EsU0FBT0UsYUFB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QWMsVUFBQ3NFLE1BQUQsRUFBWTtBQUMvQkwscUNBQTZCSyxPQUFPQyxLQUFwQyxFQUEyQ0QsTUFBM0M7QUFDRCxPQUZNLEVBRUosRUFBRUUsVUFBVSxJQUFaLEVBRkksQ0FBUDtBQUdELEtBMUtELE9BQWlCcEUsaUJBQWpCLElBNURlLEVBQWpCIiwiZmlsZSI6Im5vLXJlc3RyaWN0ZWQtcGF0aHMuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcblxuaW1wb3J0IHJlc29sdmUgZnJvbSAnZXNsaW50LW1vZHVsZS11dGlscy9yZXNvbHZlJztcbmltcG9ydCBtb2R1bGVWaXNpdG9yIGZyb20gJ2VzbGludC1tb2R1bGUtdXRpbHMvbW9kdWxlVmlzaXRvcic7XG5pbXBvcnQgaXNHbG9iIGZyb20gJ2lzLWdsb2InO1xuaW1wb3J0IHsgTWluaW1hdGNoIH0gZnJvbSAnbWluaW1hdGNoJztcbmltcG9ydCBkb2NzVXJsIGZyb20gJy4uL2RvY3NVcmwnO1xuaW1wb3J0IGltcG9ydFR5cGUgZnJvbSAnLi4vY29yZS9pbXBvcnRUeXBlJztcblxuY29uc3QgY29udGFpbnNQYXRoID0gKGZpbGVwYXRoLCB0YXJnZXQpID0+IHtcbiAgY29uc3QgcmVsYXRpdmUgPSBwYXRoLnJlbGF0aXZlKHRhcmdldCwgZmlsZXBhdGgpO1xuICByZXR1cm4gcmVsYXRpdmUgPT09ICcnIHx8ICFyZWxhdGl2ZS5zdGFydHNXaXRoKCcuLicpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIG1ldGE6IHtcbiAgICB0eXBlOiAncHJvYmxlbScsXG4gICAgZG9jczoge1xuICAgICAgY2F0ZWdvcnk6ICdTdGF0aWMgYW5hbHlzaXMnLFxuICAgICAgZGVzY3JpcHRpb246ICdFbmZvcmNlIHdoaWNoIGZpbGVzIGNhbiBiZSBpbXBvcnRlZCBpbiBhIGdpdmVuIGZvbGRlci4nLFxuICAgICAgdXJsOiBkb2NzVXJsKCduby1yZXN0cmljdGVkLXBhdGhzJyksXG4gICAgfSxcblxuICAgIHNjaGVtYTogW1xuICAgICAge1xuICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgIHpvbmVzOiB7XG4gICAgICAgICAgICB0eXBlOiAnYXJyYXknLFxuICAgICAgICAgICAgbWluSXRlbXM6IDEsXG4gICAgICAgICAgICBpdGVtczoge1xuICAgICAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgICAgICAgIHRhcmdldDoge1xuICAgICAgICAgICAgICAgICAgYW55T2Y6IFtcbiAgICAgICAgICAgICAgICAgICAgeyB0eXBlOiAnc3RyaW5nJyB9LFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2FycmF5JyxcbiAgICAgICAgICAgICAgICAgICAgICBpdGVtczogeyB0eXBlOiAnc3RyaW5nJyB9LFxuICAgICAgICAgICAgICAgICAgICAgIHVuaXF1ZUl0ZW1zOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgIG1pbkxlbmd0aDogMSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBmcm9tOiB7XG4gICAgICAgICAgICAgICAgICBhbnlPZjogW1xuICAgICAgICAgICAgICAgICAgICB7IHR5cGU6ICdzdHJpbmcnIH0sXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnYXJyYXknLFxuICAgICAgICAgICAgICAgICAgICAgIGl0ZW1zOiB7IHR5cGU6ICdzdHJpbmcnIH0sXG4gICAgICAgICAgICAgICAgICAgICAgdW5pcXVlSXRlbXM6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgbWluTGVuZ3RoOiAxLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGV4Y2VwdDoge1xuICAgICAgICAgICAgICAgICAgdHlwZTogJ2FycmF5JyxcbiAgICAgICAgICAgICAgICAgIGl0ZW1zOiB7XG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIHVuaXF1ZUl0ZW1zOiB0cnVlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogeyB0eXBlOiAnc3RyaW5nJyB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBhZGRpdGlvbmFsUHJvcGVydGllczogZmFsc2UsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgYmFzZVBhdGg6IHsgdHlwZTogJ3N0cmluZycgfSxcbiAgICAgICAgfSxcbiAgICAgICAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlLFxuICAgICAgfSxcbiAgICBdLFxuICB9LFxuXG4gIGNyZWF0ZTogZnVuY3Rpb24gbm9SZXN0cmljdGVkUGF0aHMoY29udGV4dCkge1xuICAgIGNvbnN0IG9wdGlvbnMgPSBjb250ZXh0Lm9wdGlvbnNbMF0gfHwge307XG4gICAgY29uc3QgcmVzdHJpY3RlZFBhdGhzID0gb3B0aW9ucy56b25lcyB8fCBbXTtcbiAgICBjb25zdCBiYXNlUGF0aCA9IG9wdGlvbnMuYmFzZVBhdGggfHwgcHJvY2Vzcy5jd2QoKTtcbiAgICBjb25zdCBjdXJyZW50RmlsZW5hbWUgPSBjb250ZXh0LmdldFBoeXNpY2FsRmlsZW5hbWUgPyBjb250ZXh0LmdldFBoeXNpY2FsRmlsZW5hbWUoKSA6IGNvbnRleHQuZ2V0RmlsZW5hbWUoKTtcbiAgICBjb25zdCBtYXRjaGluZ1pvbmVzID0gcmVzdHJpY3RlZFBhdGhzLmZpbHRlcigoem9uZSkgPT4ge1xuICAgICAgcmV0dXJuIFtdLmNvbmNhdCh6b25lLnRhcmdldClcbiAgICAgICAgLm1hcCh0YXJnZXQgPT4gcGF0aC5yZXNvbHZlKGJhc2VQYXRoLCB0YXJnZXQpKVxuICAgICAgICAuc29tZSh0YXJnZXRQYXRoID0+IGlzTWF0Y2hpbmdUYXJnZXRQYXRoKGN1cnJlbnRGaWxlbmFtZSwgdGFyZ2V0UGF0aCkpO1xuICAgIH0pO1xuXG4gICAgZnVuY3Rpb24gaXNNYXRjaGluZ1RhcmdldFBhdGgoZmlsZW5hbWUsIHRhcmdldFBhdGgpIHtcbiAgICAgIGlmIChpc0dsb2IodGFyZ2V0UGF0aCkpIHtcbiAgICAgICAgY29uc3QgbW0gPSBuZXcgTWluaW1hdGNoKHRhcmdldFBhdGgpO1xuICAgICAgICByZXR1cm4gbW0ubWF0Y2goZmlsZW5hbWUpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gY29udGFpbnNQYXRoKGZpbGVuYW1lLCB0YXJnZXRQYXRoKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpc1ZhbGlkRXhjZXB0aW9uUGF0aChhYnNvbHV0ZUZyb21QYXRoLCBhYnNvbHV0ZUV4Y2VwdGlvblBhdGgpIHtcbiAgICAgIGNvbnN0IHJlbGF0aXZlRXhjZXB0aW9uUGF0aCA9IHBhdGgucmVsYXRpdmUoYWJzb2x1dGVGcm9tUGF0aCwgYWJzb2x1dGVFeGNlcHRpb25QYXRoKTtcblxuICAgICAgcmV0dXJuIGltcG9ydFR5cGUocmVsYXRpdmVFeGNlcHRpb25QYXRoLCBjb250ZXh0KSAhPT0gJ3BhcmVudCc7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gYXJlQm90aEdsb2JQYXR0ZXJuQW5kQWJzb2x1dGVQYXRoKGFyZUdsb2JQYXR0ZXJucykge1xuICAgICAgcmV0dXJuIGFyZUdsb2JQYXR0ZXJucy5zb21lKChpc0dsb2IpID0+IGlzR2xvYikgJiYgYXJlR2xvYlBhdHRlcm5zLnNvbWUoKGlzR2xvYikgPT4gIWlzR2xvYik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmVwb3J0SW52YWxpZEV4Y2VwdGlvblBhdGgobm9kZSkge1xuICAgICAgY29udGV4dC5yZXBvcnQoe1xuICAgICAgICBub2RlLFxuICAgICAgICBtZXNzYWdlOiAnUmVzdHJpY3RlZCBwYXRoIGV4Y2VwdGlvbnMgbXVzdCBiZSBkZXNjZW5kYW50cyBvZiB0aGUgY29uZmlndXJlZCBgZnJvbWAgcGF0aCBmb3IgdGhhdCB6b25lLicsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiByZXBvcnRJbnZhbGlkRXhjZXB0aW9uTWl4ZWRHbG9iQW5kTm9uR2xvYihub2RlKSB7XG4gICAgICBjb250ZXh0LnJlcG9ydCh7XG4gICAgICAgIG5vZGUsXG4gICAgICAgIG1lc3NhZ2U6ICdSZXN0cmljdGVkIHBhdGggYGZyb21gIG11c3QgY29udGFpbiBlaXRoZXIgb25seSBnbG9iIHBhdHRlcm5zIG9yIG5vbmUnLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmVwb3J0SW52YWxpZEV4Y2VwdGlvbkdsb2Iobm9kZSkge1xuICAgICAgY29udGV4dC5yZXBvcnQoe1xuICAgICAgICBub2RlLFxuICAgICAgICBtZXNzYWdlOiAnUmVzdHJpY3RlZCBwYXRoIGV4Y2VwdGlvbnMgbXVzdCBiZSBnbG9iIHBhdHRlcm5zIHdoZW4gYGZyb21gIGNvbnRhaW5zIGdsb2IgcGF0dGVybnMnLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY29tcHV0ZU1peGVkR2xvYkFuZEFic29sdXRlUGF0aFZhbGlkYXRvcigpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGlzUGF0aFJlc3RyaWN0ZWQ6ICgpID0+IHRydWUsXG4gICAgICAgIGhhc1ZhbGlkRXhjZXB0aW9uczogZmFsc2UsXG4gICAgICAgIHJlcG9ydEludmFsaWRFeGNlcHRpb246IHJlcG9ydEludmFsaWRFeGNlcHRpb25NaXhlZEdsb2JBbmROb25HbG9iLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjb21wdXRlR2xvYlBhdHRlcm5QYXRoVmFsaWRhdG9yKGFic29sdXRlRnJvbSwgem9uZUV4Y2VwdCkge1xuICAgICAgbGV0IGlzUGF0aEV4Y2VwdGlvbjtcblxuICAgICAgY29uc3QgbW0gPSBuZXcgTWluaW1hdGNoKGFic29sdXRlRnJvbSk7XG4gICAgICBjb25zdCBpc1BhdGhSZXN0cmljdGVkID0gKGFic29sdXRlSW1wb3J0UGF0aCkgPT4gbW0ubWF0Y2goYWJzb2x1dGVJbXBvcnRQYXRoKTtcbiAgICAgIGNvbnN0IGhhc1ZhbGlkRXhjZXB0aW9ucyA9IHpvbmVFeGNlcHQuZXZlcnkoaXNHbG9iKTtcblxuICAgICAgaWYgKGhhc1ZhbGlkRXhjZXB0aW9ucykge1xuICAgICAgICBjb25zdCBleGNlcHRpb25zTW0gPSB6b25lRXhjZXB0Lm1hcCgoZXhjZXB0KSA9PiBuZXcgTWluaW1hdGNoKGV4Y2VwdCkpO1xuICAgICAgICBpc1BhdGhFeGNlcHRpb24gPSAoYWJzb2x1dGVJbXBvcnRQYXRoKSA9PiBleGNlcHRpb25zTW0uc29tZSgobW0pID0+IG1tLm1hdGNoKGFic29sdXRlSW1wb3J0UGF0aCkpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCByZXBvcnRJbnZhbGlkRXhjZXB0aW9uID0gcmVwb3J0SW52YWxpZEV4Y2VwdGlvbkdsb2I7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGlzUGF0aFJlc3RyaWN0ZWQsXG4gICAgICAgIGhhc1ZhbGlkRXhjZXB0aW9ucyxcbiAgICAgICAgaXNQYXRoRXhjZXB0aW9uLFxuICAgICAgICByZXBvcnRJbnZhbGlkRXhjZXB0aW9uLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjb21wdXRlQWJzb2x1dGVQYXRoVmFsaWRhdG9yKGFic29sdXRlRnJvbSwgem9uZUV4Y2VwdCkge1xuICAgICAgbGV0IGlzUGF0aEV4Y2VwdGlvbjtcblxuICAgICAgY29uc3QgaXNQYXRoUmVzdHJpY3RlZCA9IChhYnNvbHV0ZUltcG9ydFBhdGgpID0+IGNvbnRhaW5zUGF0aChhYnNvbHV0ZUltcG9ydFBhdGgsIGFic29sdXRlRnJvbSk7XG5cbiAgICAgIGNvbnN0IGFic29sdXRlRXhjZXB0aW9uUGF0aHMgPSB6b25lRXhjZXB0XG4gICAgICAgIC5tYXAoKGV4Y2VwdGlvblBhdGgpID0+IHBhdGgucmVzb2x2ZShhYnNvbHV0ZUZyb20sIGV4Y2VwdGlvblBhdGgpKTtcbiAgICAgIGNvbnN0IGhhc1ZhbGlkRXhjZXB0aW9ucyA9IGFic29sdXRlRXhjZXB0aW9uUGF0aHNcbiAgICAgICAgLmV2ZXJ5KChhYnNvbHV0ZUV4Y2VwdGlvblBhdGgpID0+IGlzVmFsaWRFeGNlcHRpb25QYXRoKGFic29sdXRlRnJvbSwgYWJzb2x1dGVFeGNlcHRpb25QYXRoKSk7XG5cbiAgICAgIGlmIChoYXNWYWxpZEV4Y2VwdGlvbnMpIHtcbiAgICAgICAgaXNQYXRoRXhjZXB0aW9uID0gKGFic29sdXRlSW1wb3J0UGF0aCkgPT4gYWJzb2x1dGVFeGNlcHRpb25QYXRocy5zb21lKFxuICAgICAgICAgIChhYnNvbHV0ZUV4Y2VwdGlvblBhdGgpID0+IGNvbnRhaW5zUGF0aChhYnNvbHV0ZUltcG9ydFBhdGgsIGFic29sdXRlRXhjZXB0aW9uUGF0aCksXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlcG9ydEludmFsaWRFeGNlcHRpb24gPSByZXBvcnRJbnZhbGlkRXhjZXB0aW9uUGF0aDtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgaXNQYXRoUmVzdHJpY3RlZCxcbiAgICAgICAgaGFzVmFsaWRFeGNlcHRpb25zLFxuICAgICAgICBpc1BhdGhFeGNlcHRpb24sXG4gICAgICAgIHJlcG9ydEludmFsaWRFeGNlcHRpb24sXG4gICAgICB9O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJlcG9ydEludmFsaWRFeGNlcHRpb25zKHZhbGlkYXRvcnMsIG5vZGUpIHtcbiAgICAgIHZhbGlkYXRvcnMuZm9yRWFjaCh2YWxpZGF0b3IgPT4gdmFsaWRhdG9yLnJlcG9ydEludmFsaWRFeGNlcHRpb24obm9kZSkpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJlcG9ydEltcG9ydHNJblJlc3RyaWN0ZWRab25lKHZhbGlkYXRvcnMsIG5vZGUsIGltcG9ydFBhdGgsIGN1c3RvbU1lc3NhZ2UpIHtcbiAgICAgIHZhbGlkYXRvcnMuZm9yRWFjaCgoKSA9PiB7XG4gICAgICAgIGNvbnRleHQucmVwb3J0KHtcbiAgICAgICAgICBub2RlLFxuICAgICAgICAgIG1lc3NhZ2U6IGBVbmV4cGVjdGVkIHBhdGggXCJ7e2ltcG9ydFBhdGh9fVwiIGltcG9ydGVkIGluIHJlc3RyaWN0ZWQgem9uZS4ke2N1c3RvbU1lc3NhZ2UgPyBgICR7Y3VzdG9tTWVzc2FnZX1gIDogJyd9YCxcbiAgICAgICAgICBkYXRhOiB7IGltcG9ydFBhdGggfSxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBtYWtlUGF0aFZhbGlkYXRvcnMgPSAoem9uZUZyb20sIHpvbmVFeGNlcHQgPSBbXSkgPT4ge1xuICAgICAgY29uc3QgYWxsWm9uZUZyb20gPSBbXS5jb25jYXQoem9uZUZyb20pO1xuICAgICAgY29uc3QgYXJlR2xvYlBhdHRlcm5zID0gYWxsWm9uZUZyb20ubWFwKGlzR2xvYik7XG5cbiAgICAgIGlmIChhcmVCb3RoR2xvYlBhdHRlcm5BbmRBYnNvbHV0ZVBhdGgoYXJlR2xvYlBhdHRlcm5zKSkge1xuICAgICAgICByZXR1cm4gW2NvbXB1dGVNaXhlZEdsb2JBbmRBYnNvbHV0ZVBhdGhWYWxpZGF0b3IoKV07XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGlzR2xvYlBhdHRlcm4gPSBhcmVHbG9iUGF0dGVybnMuZXZlcnkoKGlzR2xvYikgPT4gaXNHbG9iKTtcblxuICAgICAgcmV0dXJuIGFsbFpvbmVGcm9tLm1hcChzaW5nbGVab25lRnJvbSA9PiB7XG4gICAgICAgIGNvbnN0IGFic29sdXRlRnJvbSA9IHBhdGgucmVzb2x2ZShiYXNlUGF0aCwgc2luZ2xlWm9uZUZyb20pO1xuXG4gICAgICAgIGlmIChpc0dsb2JQYXR0ZXJuKSB7XG4gICAgICAgICAgcmV0dXJuIGNvbXB1dGVHbG9iUGF0dGVyblBhdGhWYWxpZGF0b3IoYWJzb2x1dGVGcm9tLCB6b25lRXhjZXB0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY29tcHV0ZUFic29sdXRlUGF0aFZhbGlkYXRvcihhYnNvbHV0ZUZyb20sIHpvbmVFeGNlcHQpO1xuICAgICAgfSk7XG4gICAgfTtcblxuICAgIGNvbnN0IHZhbGlkYXRvcnMgPSBbXTtcblxuICAgIGZ1bmN0aW9uIGNoZWNrRm9yUmVzdHJpY3RlZEltcG9ydFBhdGgoaW1wb3J0UGF0aCwgbm9kZSkge1xuICAgICAgY29uc3QgYWJzb2x1dGVJbXBvcnRQYXRoID0gcmVzb2x2ZShpbXBvcnRQYXRoLCBjb250ZXh0KTtcblxuICAgICAgaWYgKCFhYnNvbHV0ZUltcG9ydFBhdGgpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBtYXRjaGluZ1pvbmVzLmZvckVhY2goKHpvbmUsIGluZGV4KSA9PiB7XG4gICAgICAgIGlmICghdmFsaWRhdG9yc1tpbmRleF0pIHtcbiAgICAgICAgICB2YWxpZGF0b3JzW2luZGV4XSA9IG1ha2VQYXRoVmFsaWRhdG9ycyh6b25lLmZyb20sIHpvbmUuZXhjZXB0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGFwcGxpY2FibGVWYWxpZGF0b3JzRm9ySW1wb3J0UGF0aCA9IHZhbGlkYXRvcnNbaW5kZXhdLmZpbHRlcih2YWxpZGF0b3IgPT4gdmFsaWRhdG9yLmlzUGF0aFJlc3RyaWN0ZWQoYWJzb2x1dGVJbXBvcnRQYXRoKSk7XG5cbiAgICAgICAgY29uc3QgdmFsaWRhdG9yc1dpdGhJbnZhbGlkRXhjZXB0aW9ucyA9IGFwcGxpY2FibGVWYWxpZGF0b3JzRm9ySW1wb3J0UGF0aC5maWx0ZXIodmFsaWRhdG9yID0+ICF2YWxpZGF0b3IuaGFzVmFsaWRFeGNlcHRpb25zKTtcbiAgICAgICAgcmVwb3J0SW52YWxpZEV4Y2VwdGlvbnModmFsaWRhdG9yc1dpdGhJbnZhbGlkRXhjZXB0aW9ucywgbm9kZSk7XG5cbiAgICAgICAgY29uc3QgYXBwbGljYWJsZVZhbGlkYXRvcnNGb3JJbXBvcnRQYXRoRXhjbHVkaW5nRXhjZXB0aW9ucyA9IGFwcGxpY2FibGVWYWxpZGF0b3JzRm9ySW1wb3J0UGF0aFxuICAgICAgICAgIC5maWx0ZXIodmFsaWRhdG9yID0+IHZhbGlkYXRvci5oYXNWYWxpZEV4Y2VwdGlvbnMpXG4gICAgICAgICAgLmZpbHRlcih2YWxpZGF0b3IgPT4gIXZhbGlkYXRvci5pc1BhdGhFeGNlcHRpb24oYWJzb2x1dGVJbXBvcnRQYXRoKSk7XG4gICAgICAgIHJlcG9ydEltcG9ydHNJblJlc3RyaWN0ZWRab25lKGFwcGxpY2FibGVWYWxpZGF0b3JzRm9ySW1wb3J0UGF0aEV4Y2x1ZGluZ0V4Y2VwdGlvbnMsIG5vZGUsIGltcG9ydFBhdGgsIHpvbmUubWVzc2FnZSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gbW9kdWxlVmlzaXRvcigoc291cmNlKSA9PiB7XG4gICAgICBjaGVja0ZvclJlc3RyaWN0ZWRJbXBvcnRQYXRoKHNvdXJjZS52YWx1ZSwgc291cmNlKTtcbiAgICB9LCB7IGNvbW1vbmpzOiB0cnVlIH0pO1xuICB9LFxufTtcbiJdfQ==
|