namespace.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. 'use strict';
  2. var _declaredScope = require('eslint-module-utils/declaredScope');
  3. var _declaredScope2 = _interopRequireDefault(_declaredScope);
  4. var _ExportMap = require('../ExportMap');
  5. var _ExportMap2 = _interopRequireDefault(_ExportMap);
  6. var _importDeclaration = require('../importDeclaration');
  7. var _importDeclaration2 = _interopRequireDefault(_importDeclaration);
  8. var _docsUrl = require('../docsUrl');
  9. var _docsUrl2 = _interopRequireDefault(_docsUrl);
  10. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  11. module.exports = {
  12. meta: {
  13. docs: {
  14. url: (0, _docsUrl2.default)('namespace')
  15. },
  16. schema: [{
  17. 'type': 'object',
  18. 'properties': {
  19. 'allowComputed': {
  20. 'description': 'If `false`, will report computed (and thus, un-lintable) references ' + 'to namespace members.',
  21. 'type': 'boolean',
  22. 'default': false
  23. }
  24. },
  25. 'additionalProperties': false
  26. }]
  27. },
  28. create: function namespaceRule(context) {
  29. // read options
  30. var _ref = context.options[0] || {},
  31. _ref$allowComputed = _ref.allowComputed;
  32. const allowComputed = _ref$allowComputed === undefined ? false : _ref$allowComputed;
  33. const namespaces = new Map();
  34. function makeMessage(last, namepath) {
  35. return `'${last.name}' not found in` + (namepath.length > 1 ? ' deeply ' : ' ') + `imported namespace '${namepath.join('.')}'.`;
  36. }
  37. return {
  38. // pick up all imports at body entry time, to properly respect hoisting
  39. Program: function (_ref2) {
  40. let body = _ref2.body;
  41. function processBodyStatement(declaration) {
  42. if (declaration.type !== 'ImportDeclaration') return;
  43. if (declaration.specifiers.length === 0) return;
  44. const imports = _ExportMap2.default.get(declaration.source.value, context);
  45. if (imports == null) return null;
  46. if (imports.errors.length) {
  47. imports.reportErrors(context, declaration);
  48. return;
  49. }
  50. for (const specifier of declaration.specifiers) {
  51. switch (specifier.type) {
  52. case 'ImportNamespaceSpecifier':
  53. if (!imports.size) {
  54. context.report(specifier, `No exported names found in module '${declaration.source.value}'.`);
  55. }
  56. namespaces.set(specifier.local.name, imports);
  57. break;
  58. case 'ImportDefaultSpecifier':
  59. case 'ImportSpecifier':
  60. {
  61. const meta = imports.get(
  62. // default to 'default' for default http://i.imgur.com/nj6qAWy.jpg
  63. specifier.imported ? specifier.imported.name : 'default');
  64. if (!meta || !meta.namespace) break;
  65. namespaces.set(specifier.local.name, meta.namespace);
  66. break;
  67. }
  68. }
  69. }
  70. }
  71. body.forEach(processBodyStatement);
  72. },
  73. // same as above, but does not add names to local map
  74. ExportNamespaceSpecifier: function (namespace) {
  75. var declaration = (0, _importDeclaration2.default)(context);
  76. var imports = _ExportMap2.default.get(declaration.source.value, context);
  77. if (imports == null) return null;
  78. if (imports.errors.length) {
  79. imports.reportErrors(context, declaration);
  80. return;
  81. }
  82. if (!imports.size) {
  83. context.report(namespace, `No exported names found in module '${declaration.source.value}'.`);
  84. }
  85. },
  86. // todo: check for possible redefinition
  87. MemberExpression: function (dereference) {
  88. if (dereference.object.type !== 'Identifier') return;
  89. if (!namespaces.has(dereference.object.name)) return;
  90. if (dereference.parent.type === 'AssignmentExpression' && dereference.parent.left === dereference) {
  91. context.report(dereference.parent, `Assignment to member of namespace '${dereference.object.name}'.`);
  92. }
  93. // go deep
  94. var namespace = namespaces.get(dereference.object.name);
  95. var namepath = [dereference.object.name];
  96. // while property is namespace and parent is member expression, keep validating
  97. while (namespace instanceof _ExportMap2.default && dereference.type === 'MemberExpression') {
  98. if (dereference.computed) {
  99. if (!allowComputed) {
  100. context.report(dereference.property, 'Unable to validate computed reference to imported namespace \'' + dereference.object.name + '\'.');
  101. }
  102. return;
  103. }
  104. if (!namespace.has(dereference.property.name)) {
  105. context.report(dereference.property, makeMessage(dereference.property, namepath));
  106. break;
  107. }
  108. const exported = namespace.get(dereference.property.name);
  109. if (exported == null) return;
  110. // stash and pop
  111. namepath.push(dereference.property.name);
  112. namespace = exported.namespace;
  113. dereference = dereference.parent;
  114. }
  115. },
  116. VariableDeclarator: function (_ref3) {
  117. let id = _ref3.id,
  118. init = _ref3.init;
  119. if (init == null) return;
  120. if (init.type !== 'Identifier') return;
  121. if (!namespaces.has(init.name)) return;
  122. // check for redefinition in intermediate scopes
  123. if ((0, _declaredScope2.default)(context, init.name) !== 'module') return;
  124. // DFS traverse child namespaces
  125. function testKey(pattern, namespace) {
  126. let path = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [init.name];
  127. if (!(namespace instanceof _ExportMap2.default)) return;
  128. if (pattern.type !== 'ObjectPattern') return;
  129. for (const property of pattern.properties) {
  130. if (property.type === 'ExperimentalRestProperty' || property.type === 'RestElement' || !property.key) {
  131. continue;
  132. }
  133. if (property.key.type !== 'Identifier') {
  134. context.report({
  135. node: property,
  136. message: 'Only destructure top-level names.'
  137. });
  138. continue;
  139. }
  140. if (!namespace.has(property.key.name)) {
  141. context.report({
  142. node: property,
  143. message: makeMessage(property.key, path)
  144. });
  145. continue;
  146. }
  147. path.push(property.key.name);
  148. testKey(property.value, namespace.get(property.key.name).namespace, path);
  149. path.pop();
  150. }
  151. }
  152. testKey(id, namespaces.get(init.name));
  153. },
  154. JSXMemberExpression: function (_ref4) {
  155. let object = _ref4.object,
  156. property = _ref4.property;
  157. if (!namespaces.has(object.name)) return;
  158. var namespace = namespaces.get(object.name);
  159. if (!namespace.has(property.name)) {
  160. context.report({
  161. node: property,
  162. message: makeMessage(property, [object.name])
  163. });
  164. }
  165. }
  166. };
  167. }
  168. };
  169. //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInJ1bGVzL25hbWVzcGFjZS5qcyJdLCJuYW1lcyI6WyJtb2R1bGUiLCJleHBvcnRzIiwibWV0YSIsImRvY3MiLCJ1cmwiLCJzY2hlbWEiLCJjcmVhdGUiLCJuYW1lc3BhY2VSdWxlIiwiY29udGV4dCIsIm9wdGlvbnMiLCJhbGxvd0NvbXB1dGVkIiwibmFtZXNwYWNlcyIsIk1hcCIsIm1ha2VNZXNzYWdlIiwibGFzdCIsIm5hbWVwYXRoIiwibmFtZSIsImxlbmd0aCIsImpvaW4iLCJQcm9ncmFtIiwiYm9keSIsInByb2Nlc3NCb2R5U3RhdGVtZW50IiwiZGVjbGFyYXRpb24iLCJ0eXBlIiwic3BlY2lmaWVycyIsImltcG9ydHMiLCJFeHBvcnRzIiwiZ2V0Iiwic291cmNlIiwidmFsdWUiLCJlcnJvcnMiLCJyZXBvcnRFcnJvcnMiLCJzcGVjaWZpZXIiLCJzaXplIiwicmVwb3J0Iiwic2V0IiwibG9jYWwiLCJpbXBvcnRlZCIsIm5hbWVzcGFjZSIsImZvckVhY2giLCJFeHBvcnROYW1lc3BhY2VTcGVjaWZpZXIiLCJNZW1iZXJFeHByZXNzaW9uIiwiZGVyZWZlcmVuY2UiLCJvYmplY3QiLCJoYXMiLCJwYXJlbnQiLCJsZWZ0IiwiY29tcHV0ZWQiLCJwcm9wZXJ0eSIsImV4cG9ydGVkIiwicHVzaCIsIlZhcmlhYmxlRGVjbGFyYXRvciIsImlkIiwiaW5pdCIsInRlc3RLZXkiLCJwYXR0ZXJuIiwicGF0aCIsInByb3BlcnRpZXMiLCJrZXkiLCJub2RlIiwibWVzc2FnZSIsInBvcCIsIkpTWE1lbWJlckV4cHJlc3Npb24iXSwibWFwcGluZ3MiOiI7O0FBQUE7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7OztBQUVBQSxPQUFPQyxPQUFQLEdBQWlCO0FBQ2ZDLFFBQU07QUFDSkMsVUFBTTtBQUNKQyxXQUFLLHVCQUFRLFdBQVI7QUFERCxLQURGOztBQUtKQyxZQUFRLENBQ047QUFDRSxjQUFRLFFBRFY7QUFFRSxvQkFBYztBQUNaLHlCQUFpQjtBQUNmLHlCQUNFLHlFQUNBLHVCQUhhO0FBSWYsa0JBQVEsU0FKTztBQUtmLHFCQUFXO0FBTEk7QUFETCxPQUZoQjtBQVdFLDhCQUF3QjtBQVgxQixLQURNO0FBTEosR0FEUzs7QUF1QmZDLFVBQVEsU0FBU0MsYUFBVCxDQUF1QkMsT0FBdkIsRUFBZ0M7O0FBRXRDO0FBRnNDLGVBS2xDQSxRQUFRQyxPQUFSLENBQWdCLENBQWhCLEtBQXNCLEVBTFk7QUFBQSxrQ0FJcENDLGFBSm9DOztBQUFBLFVBSXBDQSxhQUpvQyxzQ0FJcEIsS0FKb0I7OztBQU90QyxVQUFNQyxhQUFhLElBQUlDLEdBQUosRUFBbkI7O0FBRUEsYUFBU0MsV0FBVCxDQUFxQkMsSUFBckIsRUFBMkJDLFFBQTNCLEVBQXFDO0FBQ2xDLGFBQVEsSUFBR0QsS0FBS0UsSUFBSyxnQkFBZCxJQUNDRCxTQUFTRSxNQUFULEdBQWtCLENBQWxCLEdBQXNCLFVBQXRCLEdBQW1DLEdBRHBDLElBRUMsdUJBQXNCRixTQUFTRyxJQUFULENBQWMsR0FBZCxDQUFtQixJQUZqRDtBQUdGOztBQUVELFdBQU87O0FBRUw7QUFDQUMsZUFBUyxpQkFBb0I7QUFBQSxZQUFSQyxJQUFRLFNBQVJBLElBQVE7O0FBQzNCLGlCQUFTQyxvQkFBVCxDQUE4QkMsV0FBOUIsRUFBMkM7QUFDekMsY0FBSUEsWUFBWUMsSUFBWixLQUFxQixtQkFBekIsRUFBOEM7O0FBRTlDLGNBQUlELFlBQVlFLFVBQVosQ0FBdUJQLE1BQXZCLEtBQWtDLENBQXRDLEVBQXlDOztBQUV6QyxnQkFBTVEsVUFBVUMsb0JBQVFDLEdBQVIsQ0FBWUwsWUFBWU0sTUFBWixDQUFtQkMsS0FBL0IsRUFBc0NyQixPQUF0QyxDQUFoQjtBQUNBLGNBQUlpQixXQUFXLElBQWYsRUFBcUIsT0FBTyxJQUFQOztBQUVyQixjQUFJQSxRQUFRSyxNQUFSLENBQWViLE1BQW5CLEVBQTJCO0FBQ3pCUSxvQkFBUU0sWUFBUixDQUFxQnZCLE9BQXJCLEVBQThCYyxXQUE5QjtBQUNBO0FBQ0Q7O0FBRUQsZUFBSyxNQUFNVSxTQUFYLElBQXdCVixZQUFZRSxVQUFwQyxFQUFnRDtBQUM5QyxvQkFBUVEsVUFBVVQsSUFBbEI7QUFDRSxtQkFBSywwQkFBTDtBQUNFLG9CQUFJLENBQUNFLFFBQVFRLElBQWIsRUFBbUI7QUFDakJ6QiwwQkFBUTBCLE1BQVIsQ0FBZUYsU0FBZixFQUNHLHNDQUFxQ1YsWUFBWU0sTUFBWixDQUFtQkMsS0FBTSxJQURqRTtBQUVEO0FBQ0RsQiwyQkFBV3dCLEdBQVgsQ0FBZUgsVUFBVUksS0FBVixDQUFnQnBCLElBQS9CLEVBQXFDUyxPQUFyQztBQUNBO0FBQ0YsbUJBQUssd0JBQUw7QUFDQSxtQkFBSyxpQkFBTDtBQUF3QjtBQUN0Qix3QkFBTXZCLE9BQU91QixRQUFRRSxHQUFSO0FBQ1g7QUFDQUssNEJBQVVLLFFBQVYsR0FBcUJMLFVBQVVLLFFBQVYsQ0FBbUJyQixJQUF4QyxHQUErQyxTQUZwQyxDQUFiO0FBR0Esc0JBQUksQ0FBQ2QsSUFBRCxJQUFTLENBQUNBLEtBQUtvQyxTQUFuQixFQUE4QjtBQUM5QjNCLDZCQUFXd0IsR0FBWCxDQUFlSCxVQUFVSSxLQUFWLENBQWdCcEIsSUFBL0IsRUFBcUNkLEtBQUtvQyxTQUExQztBQUNBO0FBQ0Q7QUFoQkg7QUFrQkQ7QUFDRjtBQUNEbEIsYUFBS21CLE9BQUwsQ0FBYWxCLG9CQUFiO0FBQ0QsT0F2Q0k7O0FBeUNMO0FBQ0FtQixnQ0FBMEIsVUFBVUYsU0FBVixFQUFxQjtBQUM3QyxZQUFJaEIsY0FBYyxpQ0FBa0JkLE9BQWxCLENBQWxCOztBQUVBLFlBQUlpQixVQUFVQyxvQkFBUUMsR0FBUixDQUFZTCxZQUFZTSxNQUFaLENBQW1CQyxLQUEvQixFQUFzQ3JCLE9BQXRDLENBQWQ7QUFDQSxZQUFJaUIsV0FBVyxJQUFmLEVBQXFCLE9BQU8sSUFBUDs7QUFFckIsWUFBSUEsUUFBUUssTUFBUixDQUFlYixNQUFuQixFQUEyQjtBQUN6QlEsa0JBQVFNLFlBQVIsQ0FBcUJ2QixPQUFyQixFQUE4QmMsV0FBOUI7QUFDQTtBQUNEOztBQUVELFlBQUksQ0FBQ0csUUFBUVEsSUFBYixFQUFtQjtBQUNqQnpCLGtCQUFRMEIsTUFBUixDQUFlSSxTQUFmLEVBQ0csc0NBQXFDaEIsWUFBWU0sTUFBWixDQUFtQkMsS0FBTSxJQURqRTtBQUVEO0FBQ0YsT0F6REk7O0FBMkRMOztBQUVBWSx3QkFBa0IsVUFBVUMsV0FBVixFQUF1QjtBQUN2QyxZQUFJQSxZQUFZQyxNQUFaLENBQW1CcEIsSUFBbkIsS0FBNEIsWUFBaEMsRUFBOEM7QUFDOUMsWUFBSSxDQUFDWixXQUFXaUMsR0FBWCxDQUFlRixZQUFZQyxNQUFaLENBQW1CM0IsSUFBbEMsQ0FBTCxFQUE4Qzs7QUFFOUMsWUFBSTBCLFlBQVlHLE1BQVosQ0FBbUJ0QixJQUFuQixLQUE0QixzQkFBNUIsSUFDQW1CLFlBQVlHLE1BQVosQ0FBbUJDLElBQW5CLEtBQTRCSixXQURoQyxFQUM2QztBQUN6Q2xDLGtCQUFRMEIsTUFBUixDQUFlUSxZQUFZRyxNQUEzQixFQUNLLHNDQUFxQ0gsWUFBWUMsTUFBWixDQUFtQjNCLElBQUssSUFEbEU7QUFFSDs7QUFFRDtBQUNBLFlBQUlzQixZQUFZM0IsV0FBV2dCLEdBQVgsQ0FBZWUsWUFBWUMsTUFBWixDQUFtQjNCLElBQWxDLENBQWhCO0FBQ0EsWUFBSUQsV0FBVyxDQUFDMkIsWUFBWUMsTUFBWixDQUFtQjNCLElBQXBCLENBQWY7QUFDQTtBQUNBLGVBQU9zQixxQkFBcUJaLG1CQUFyQixJQUNBZ0IsWUFBWW5CLElBQVosS0FBcUIsa0JBRDVCLEVBQ2dEOztBQUU5QyxjQUFJbUIsWUFBWUssUUFBaEIsRUFBMEI7QUFDeEIsZ0JBQUksQ0FBQ3JDLGFBQUwsRUFBb0I7QUFDbEJGLHNCQUFRMEIsTUFBUixDQUFlUSxZQUFZTSxRQUEzQixFQUNFLG1FQUNBTixZQUFZQyxNQUFaLENBQW1CM0IsSUFEbkIsR0FDMEIsS0FGNUI7QUFHRDtBQUNEO0FBQ0Q7O0FBRUQsY0FBSSxDQUFDc0IsVUFBVU0sR0FBVixDQUFjRixZQUFZTSxRQUFaLENBQXFCaEMsSUFBbkMsQ0FBTCxFQUErQztBQUM3Q1Isb0JBQVEwQixNQUFSLENBQ0VRLFlBQVlNLFFBRGQsRUFFRW5DLFlBQVk2QixZQUFZTSxRQUF4QixFQUFrQ2pDLFFBQWxDLENBRkY7QUFHQTtBQUNEOztBQUVELGdCQUFNa0MsV0FBV1gsVUFBVVgsR0FBVixDQUFjZSxZQUFZTSxRQUFaLENBQXFCaEMsSUFBbkMsQ0FBakI7QUFDQSxjQUFJaUMsWUFBWSxJQUFoQixFQUFzQjs7QUFFdEI7QUFDQWxDLG1CQUFTbUMsSUFBVCxDQUFjUixZQUFZTSxRQUFaLENBQXFCaEMsSUFBbkM7QUFDQXNCLHNCQUFZVyxTQUFTWCxTQUFyQjtBQUNBSSx3QkFBY0EsWUFBWUcsTUFBMUI7QUFDRDtBQUVGLE9BdkdJOztBQXlHTE0sMEJBQW9CLGlCQUF3QjtBQUFBLFlBQVpDLEVBQVksU0FBWkEsRUFBWTtBQUFBLFlBQVJDLElBQVEsU0FBUkEsSUFBUTs7QUFDMUMsWUFBSUEsUUFBUSxJQUFaLEVBQWtCO0FBQ2xCLFlBQUlBLEtBQUs5QixJQUFMLEtBQWMsWUFBbEIsRUFBZ0M7QUFDaEMsWUFBSSxDQUFDWixXQUFXaUMsR0FBWCxDQUFlUyxLQUFLckMsSUFBcEIsQ0FBTCxFQUFnQzs7QUFFaEM7QUFDQSxZQUFJLDZCQUFjUixPQUFkLEVBQXVCNkMsS0FBS3JDLElBQTVCLE1BQXNDLFFBQTFDLEVBQW9EOztBQUVwRDtBQUNBLGlCQUFTc0MsT0FBVCxDQUFpQkMsT0FBakIsRUFBMEJqQixTQUExQixFQUF5RDtBQUFBLGNBQXBCa0IsSUFBb0IsdUVBQWIsQ0FBQ0gsS0FBS3JDLElBQU4sQ0FBYTs7QUFDdkQsY0FBSSxFQUFFc0IscUJBQXFCWixtQkFBdkIsQ0FBSixFQUFxQzs7QUFFckMsY0FBSTZCLFFBQVFoQyxJQUFSLEtBQWlCLGVBQXJCLEVBQXNDOztBQUV0QyxlQUFLLE1BQU15QixRQUFYLElBQXVCTyxRQUFRRSxVQUEvQixFQUEyQztBQUN6QyxnQkFDRVQsU0FBU3pCLElBQVQsS0FBa0IsMEJBQWxCLElBQ0d5QixTQUFTekIsSUFBVCxLQUFrQixhQURyQixJQUVHLENBQUN5QixTQUFTVSxHQUhmLEVBSUU7QUFDQTtBQUNEOztBQUVELGdCQUFJVixTQUFTVSxHQUFULENBQWFuQyxJQUFiLEtBQXNCLFlBQTFCLEVBQXdDO0FBQ3RDZixzQkFBUTBCLE1BQVIsQ0FBZTtBQUNieUIsc0JBQU1YLFFBRE87QUFFYlkseUJBQVM7QUFGSSxlQUFmO0FBSUE7QUFDRDs7QUFFRCxnQkFBSSxDQUFDdEIsVUFBVU0sR0FBVixDQUFjSSxTQUFTVSxHQUFULENBQWExQyxJQUEzQixDQUFMLEVBQXVDO0FBQ3JDUixzQkFBUTBCLE1BQVIsQ0FBZTtBQUNieUIsc0JBQU1YLFFBRE87QUFFYlkseUJBQVMvQyxZQUFZbUMsU0FBU1UsR0FBckIsRUFBMEJGLElBQTFCO0FBRkksZUFBZjtBQUlBO0FBQ0Q7O0FBRURBLGlCQUFLTixJQUFMLENBQVVGLFNBQVNVLEdBQVQsQ0FBYTFDLElBQXZCO0FBQ0FzQyxvQkFBUU4sU0FBU25CLEtBQWpCLEVBQXdCUyxVQUFVWCxHQUFWLENBQWNxQixTQUFTVSxHQUFULENBQWExQyxJQUEzQixFQUFpQ3NCLFNBQXpELEVBQW9Fa0IsSUFBcEU7QUFDQUEsaUJBQUtLLEdBQUw7QUFDRDtBQUNGOztBQUVEUCxnQkFBUUYsRUFBUixFQUFZekMsV0FBV2dCLEdBQVgsQ0FBZTBCLEtBQUtyQyxJQUFwQixDQUFaO0FBQ0QsT0F2Skk7O0FBeUpMOEMsMkJBQXFCLGlCQUE2QjtBQUFBLFlBQW5CbkIsTUFBbUIsU0FBbkJBLE1BQW1CO0FBQUEsWUFBWEssUUFBVyxTQUFYQSxRQUFXOztBQUMvQyxZQUFJLENBQUNyQyxXQUFXaUMsR0FBWCxDQUFlRCxPQUFPM0IsSUFBdEIsQ0FBTCxFQUFrQztBQUNsQyxZQUFJc0IsWUFBWTNCLFdBQVdnQixHQUFYLENBQWVnQixPQUFPM0IsSUFBdEIsQ0FBaEI7QUFDQSxZQUFJLENBQUNzQixVQUFVTSxHQUFWLENBQWNJLFNBQVNoQyxJQUF2QixDQUFMLEVBQW1DO0FBQ2pDUixrQkFBUTBCLE1BQVIsQ0FBZTtBQUNieUIsa0JBQU1YLFFBRE87QUFFYlkscUJBQVMvQyxZQUFZbUMsUUFBWixFQUFzQixDQUFDTCxPQUFPM0IsSUFBUixDQUF0QjtBQUZJLFdBQWY7QUFJRDtBQUNIO0FBbEtJLEtBQVA7QUFvS0Q7QUExTWMsQ0FBakIiLCJmaWxlIjoicnVsZXMvbmFtZXNwYWNlLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGRlY2xhcmVkU2NvcGUgZnJvbSAnZXNsaW50LW1vZHVsZS11dGlscy9kZWNsYXJlZFNjb3BlJ1xuaW1wb3J0IEV4cG9ydHMgZnJvbSAnLi4vRXhwb3J0TWFwJ1xuaW1wb3J0IGltcG9ydERlY2xhcmF0aW9uIGZyb20gJy4uL2ltcG9ydERlY2xhcmF0aW9uJ1xuaW1wb3J0IGRvY3NVcmwgZnJvbSAnLi4vZG9jc1VybCdcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIG1ldGE6IHtcbiAgICBkb2NzOiB7XG4gICAgICB1cmw6IGRvY3NVcmwoJ25hbWVzcGFjZScpLFxuICAgIH0sXG5cbiAgICBzY2hlbWE6IFtcbiAgICAgIHtcbiAgICAgICAgJ3R5cGUnOiAnb2JqZWN0JyxcbiAgICAgICAgJ3Byb3BlcnRpZXMnOiB7XG4gICAgICAgICAgJ2FsbG93Q29tcHV0ZWQnOiB7XG4gICAgICAgICAgICAnZGVzY3JpcHRpb24nOlxuICAgICAgICAgICAgICAnSWYgYGZhbHNlYCwgd2lsbCByZXBvcnQgY29tcHV0ZWQgKGFuZCB0aHVzLCB1bi1saW50YWJsZSkgcmVmZXJlbmNlcyAnICtcbiAgICAgICAgICAgICAgJ3RvIG5hbWVzcGFjZSBtZW1iZXJzLicsXG4gICAgICAgICAgICAndHlwZSc6ICdib29sZWFuJyxcbiAgICAgICAgICAgICdkZWZhdWx0JzogZmFsc2UsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgJ2FkZGl0aW9uYWxQcm9wZXJ0aWVzJzogZmFsc2UsXG4gICAgICB9LFxuICAgIF0sXG4gIH0sXG5cbiAgY3JlYXRlOiBmdW5jdGlvbiBuYW1lc3BhY2VSdWxlKGNvbnRleHQpIHtcblxuICAgIC8vIHJlYWQgb3B0aW9uc1xuICAgIGNvbnN0IHtcbiAgICAgIGFsbG93Q29tcHV0ZWQgPSBmYWxzZSxcbiAgICB9ID0gY29udGV4dC5vcHRpb25zWzBdIHx8IHt9XG5cbiAgICBjb25zdCBuYW1lc3BhY2VzID0gbmV3IE1hcCgpXG5cbiAgICBmdW5jdGlvbiBtYWtlTWVzc2FnZShsYXN0LCBuYW1lcGF0aCkge1xuICAgICAgIHJldHVybiBgJyR7bGFzdC5uYW1lfScgbm90IGZvdW5kIGluYCArXG4gICAgICAgICAgICAgIChuYW1lcGF0aC5sZW5ndGggPiAxID8gJyBkZWVwbHkgJyA6ICcgJykgK1xuICAgICAgICAgICAgICBgaW1wb3J0ZWQgbmFtZXNwYWNlICcke25hbWVwYXRoLmpvaW4oJy4nKX0nLmBcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuXG4gICAgICAvLyBwaWNrIHVwIGFsbCBpbXBvcnRzIGF0IGJvZHkgZW50cnkgdGltZSwgdG8gcHJvcGVybHkgcmVzcGVjdCBob2lzdGluZ1xuICAgICAgUHJvZ3JhbTogZnVuY3Rpb24gKHsgYm9keSB9KSB7XG4gICAgICAgIGZ1bmN0aW9uIHByb2Nlc3NCb2R5U3RhdGVtZW50KGRlY2xhcmF0aW9uKSB7XG4gICAgICAgICAgaWYgKGRlY2xhcmF0aW9uLnR5cGUgIT09ICdJbXBvcnREZWNsYXJhdGlvbicpIHJldHVyblxuXG4gICAgICAgICAgaWYgKGRlY2xhcmF0aW9uLnNwZWNpZmllcnMubGVuZ3RoID09PSAwKSByZXR1cm5cblxuICAgICAgICAgIGNvbnN0IGltcG9ydHMgPSBFeHBvcnRzLmdldChkZWNsYXJhdGlvbi5zb3VyY2UudmFsdWUsIGNvbnRleHQpXG4gICAgICAgICAgaWYgKGltcG9ydHMgPT0gbnVsbCkgcmV0dXJuIG51bGxcblxuICAgICAgICAgIGlmIChpbXBvcnRzLmVycm9ycy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGltcG9ydHMucmVwb3J0RXJyb3JzKGNvbnRleHQsIGRlY2xhcmF0aW9uKVxuICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZm9yIChjb25zdCBzcGVjaWZpZXIgb2YgZGVjbGFyYXRpb24uc3BlY2lmaWVycykge1xuICAgICAgICAgICAgc3dpdGNoIChzcGVjaWZpZXIudHlwZSkge1xuICAgICAgICAgICAgICBjYXNlICdJbXBvcnROYW1lc3BhY2VTcGVjaWZpZXInOlxuICAgICAgICAgICAgICAgIGlmICghaW1wb3J0cy5zaXplKSB7XG4gICAgICAgICAgICAgICAgICBjb250ZXh0LnJlcG9ydChzcGVjaWZpZXIsXG4gICAgICAgICAgICAgICAgICAgIGBObyBleHBvcnRlZCBuYW1lcyBmb3VuZCBpbiBtb2R1bGUgJyR7ZGVjbGFyYXRpb24uc291cmNlLnZhbHVlfScuYClcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbmFtZXNwYWNlcy5zZXQoc3BlY2lmaWVyLmxvY2FsLm5hbWUsIGltcG9ydHMpXG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgICAgICAgY2FzZSAnSW1wb3J0RGVmYXVsdFNwZWNpZmllcic6XG4gICAgICAgICAgICAgIGNhc2UgJ0ltcG9ydFNwZWNpZmllcic6IHtcbiAgICAgICAgICAgICAgICBjb25zdCBtZXRhID0gaW1wb3J0cy5nZXQoXG4gICAgICAgICAgICAgICAgICAvLyBkZWZhdWx0IHRvICdkZWZhdWx0JyBmb3IgZGVmYXVsdCBodHRwOi8vaS5pbWd1ci5jb20vbmo2cUFXeS5qcGdcbiAgICAgICAgICAgICAgICAgIHNwZWNpZmllci5pbXBvcnRlZCA/IHNwZWNpZmllci5pbXBvcnRlZC5uYW1lIDogJ2RlZmF1bHQnKVxuICAgICAgICAgICAgICAgIGlmICghbWV0YSB8fCAhbWV0YS5uYW1lc3BhY2UpIGJyZWFrXG4gICAgICAgICAgICAgICAgbmFtZXNwYWNlcy5zZXQoc3BlY2lmaWVyLmxvY2FsLm5hbWUsIG1ldGEubmFtZXNwYWNlKVxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYm9keS5mb3JFYWNoKHByb2Nlc3NCb2R5U3RhdGVtZW50KVxuICAgICAgfSxcblxuICAgICAgLy8gc2FtZSBhcyBhYm92ZSwgYnV0IGRvZXMgbm90IGFkZCBuYW1lcyB0byBsb2NhbCBtYXBcbiAgICAgIEV4cG9ydE5hbWVzcGFjZVNwZWNpZmllcjogZnVuY3Rpb24gKG5hbWVzcGFjZSkge1xuICAgICAgICB2YXIgZGVjbGFyYXRpb24gPSBpbXBvcnREZWNsYXJhdGlvbihjb250ZXh0KVxuXG4gICAgICAgIHZhciBpbXBvcnRzID0gRXhwb3J0cy5nZXQoZGVjbGFyYXRpb24uc291cmNlLnZhbHVlLCBjb250ZXh0KVxuICAgICAgICBpZiAoaW1wb3J0cyA9PSBudWxsKSByZXR1cm4gbnVsbFxuXG4gICAgICAgIGlmIChpbXBvcnRzLmVycm9ycy5sZW5ndGgpIHtcbiAgICAgICAgICBpbXBvcnRzLnJlcG9ydEVycm9ycyhjb250ZXh0LCBkZWNsYXJhdGlvbilcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghaW1wb3J0cy5zaXplKSB7XG4gICAgICAgICAgY29udGV4dC5yZXBvcnQobmFtZXNwYWNlLFxuICAgICAgICAgICAgYE5vIGV4cG9ydGVkIG5hbWVzIGZvdW5kIGluIG1vZHVsZSAnJHtkZWNsYXJhdGlvbi5zb3VyY2UudmFsdWV9Jy5gKVxuICAgICAgICB9XG4gICAgICB9LFxuXG4gICAgICAvLyB0b2RvOiBjaGVjayBmb3IgcG9zc2libGUgcmVkZWZpbml0aW9uXG5cbiAgICAgIE1lbWJlckV4cHJlc3Npb246IGZ1bmN0aW9uIChkZXJlZmVyZW5jZSkge1xuICAgICAgICBpZiAoZGVyZWZlcmVuY2Uub2JqZWN0LnR5cGUgIT09ICdJZGVudGlmaWVyJykgcmV0dXJuXG4gICAgICAgIGlmICghbmFtZXNwYWNlcy5oYXMoZGVyZWZlcmVuY2Uub2JqZWN0Lm5hbWUpKSByZXR1cm5cblxuICAgICAgICBpZiAoZGVyZWZlcmVuY2UucGFyZW50LnR5cGUgPT09ICdBc3NpZ25tZW50RXhwcmVzc2lvbicgJiZcbiAgICAgICAgICAgIGRlcmVmZXJlbmNlLnBhcmVudC5sZWZ0ID09PSBkZXJlZmVyZW5jZSkge1xuICAgICAgICAgICAgY29udGV4dC5yZXBvcnQoZGVyZWZlcmVuY2UucGFyZW50LFxuICAgICAgICAgICAgICAgIGBBc3NpZ25tZW50IHRvIG1lbWJlciBvZiBuYW1lc3BhY2UgJyR7ZGVyZWZlcmVuY2Uub2JqZWN0Lm5hbWV9Jy5gKVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gZ28gZGVlcFxuICAgICAgICB2YXIgbmFtZXNwYWNlID0gbmFtZXNwYWNlcy5nZXQoZGVyZWZlcmVuY2Uub2JqZWN0Lm5hbWUpXG4gICAgICAgIHZhciBuYW1lcGF0aCA9IFtkZXJlZmVyZW5jZS5vYmplY3QubmFtZV1cbiAgICAgICAgLy8gd2hpbGUgcHJvcGVydHkgaXMgbmFtZXNwYWNlIGFuZCBwYXJlbnQgaXMgbWVtYmVyIGV4cHJlc3Npb24sIGtlZXAgdmFsaWRhdGluZ1xuICAgICAgICB3aGlsZSAobmFtZXNwYWNlIGluc3RhbmNlb2YgRXhwb3J0cyAmJlxuICAgICAgICAgICAgICAgZGVyZWZlcmVuY2UudHlwZSA9PT0gJ01lbWJlckV4cHJlc3Npb24nKSB7XG5cbiAgICAgICAgICBpZiAoZGVyZWZlcmVuY2UuY29tcHV0ZWQpIHtcbiAgICAgICAgICAgIGlmICghYWxsb3dDb21wdXRlZCkge1xuICAgICAgICAgICAgICBjb250ZXh0LnJlcG9ydChkZXJlZmVyZW5jZS5wcm9wZXJ0eSxcbiAgICAgICAgICAgICAgICAnVW5hYmxlIHRvIHZhbGlkYXRlIGNvbXB1dGVkIHJlZmVyZW5jZSB0byBpbXBvcnRlZCBuYW1lc3BhY2UgXFwnJyArXG4gICAgICAgICAgICAgICAgZGVyZWZlcmVuY2Uub2JqZWN0Lm5hbWUgKyAnXFwnLicpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoIW5hbWVzcGFjZS5oYXMoZGVyZWZlcmVuY2UucHJvcGVydHkubmFtZSkpIHtcbiAgICAgICAgICAgIGNvbnRleHQucmVwb3J0KFxuICAgICAgICAgICAgICBkZXJlZmVyZW5jZS5wcm9wZXJ0eSxcbiAgICAgICAgICAgICAgbWFrZU1lc3NhZ2UoZGVyZWZlcmVuY2UucHJvcGVydHksIG5hbWVwYXRoKSlcbiAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgZXhwb3J0ZWQgPSBuYW1lc3BhY2UuZ2V0KGRlcmVmZXJlbmNlLnByb3BlcnR5Lm5hbWUpXG4gICAgICAgICAgaWYgKGV4cG9ydGVkID09IG51bGwpIHJldHVyblxuXG4gICAgICAgICAgLy8gc3Rhc2ggYW5kIHBvcFxuICAgICAgICAgIG5hbWVwYXRoLnB1c2goZGVyZWZlcmVuY2UucHJvcGVydHkubmFtZSlcbiAgICAgICAgICBuYW1lc3BhY2UgPSBleHBvcnRlZC5uYW1lc3BhY2VcbiAgICAgICAgICBkZXJlZmVyZW5jZSA9IGRlcmVmZXJlbmNlLnBhcmVudFxuICAgICAgICB9XG5cbiAgICAgIH0sXG5cbiAgICAgIFZhcmlhYmxlRGVjbGFyYXRvcjogZnVuY3Rpb24gKHsgaWQsIGluaXQgfSkge1xuICAgICAgICBpZiAoaW5pdCA9PSBudWxsKSByZXR1cm5cbiAgICAgICAgaWYgKGluaXQudHlwZSAhPT0gJ0lkZW50aWZpZXInKSByZXR1cm5cbiAgICAgICAgaWYgKCFuYW1lc3BhY2VzLmhhcyhpbml0Lm5hbWUpKSByZXR1cm5cblxuICAgICAgICAvLyBjaGVjayBmb3IgcmVkZWZpbml0aW9uIGluIGludGVybWVkaWF0ZSBzY29wZXNcbiAgICAgICAgaWYgKGRlY2xhcmVkU2NvcGUoY29udGV4dCwgaW5pdC5uYW1lKSAhPT0gJ21vZHVsZScpIHJldHVyblxuXG4gICAgICAgIC8vIERGUyB0cmF2ZXJzZSBjaGlsZCBuYW1lc3BhY2VzXG4gICAgICAgIGZ1bmN0aW9uIHRlc3RLZXkocGF0dGVybiwgbmFtZXNwYWNlLCBwYXRoID0gW2luaXQubmFtZV0pIHtcbiAgICAgICAgICBpZiAoIShuYW1lc3BhY2UgaW5zdGFuY2VvZiBFeHBvcnRzKSkgcmV0dXJuXG5cbiAgICAgICAgICBpZiAocGF0dGVybi50eXBlICE9PSAnT2JqZWN0UGF0dGVybicpIHJldHVyblxuXG4gICAgICAgICAgZm9yIChjb25zdCBwcm9wZXJ0eSBvZiBwYXR0ZXJuLnByb3BlcnRpZXMpIHtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgcHJvcGVydHkudHlwZSA9PT0gJ0V4cGVyaW1lbnRhbFJlc3RQcm9wZXJ0eSdcbiAgICAgICAgICAgICAgfHwgcHJvcGVydHkudHlwZSA9PT0gJ1Jlc3RFbGVtZW50J1xuICAgICAgICAgICAgICB8fCAhcHJvcGVydHkua2V5XG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgY29udGludWVcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHByb3BlcnR5LmtleS50eXBlICE9PSAnSWRlbnRpZmllcicpIHtcbiAgICAgICAgICAgICAgY29udGV4dC5yZXBvcnQoe1xuICAgICAgICAgICAgICAgIG5vZGU6IHByb3BlcnR5LFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdPbmx5IGRlc3RydWN0dXJlIHRvcC1sZXZlbCBuYW1lcy4nLFxuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICBjb250aW51ZVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIW5hbWVzcGFjZS5oYXMocHJvcGVydHkua2V5Lm5hbWUpKSB7XG4gICAgICAgICAgICAgIGNvbnRleHQucmVwb3J0KHtcbiAgICAgICAgICAgICAgICBub2RlOiBwcm9wZXJ0eSxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBtYWtlTWVzc2FnZShwcm9wZXJ0eS5rZXksIHBhdGgpLFxuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICBjb250aW51ZVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBwYXRoLnB1c2gocHJvcGVydHkua2V5Lm5hbWUpXG4gICAgICAgICAgICB0ZXN0S2V5KHByb3BlcnR5LnZhbHVlLCBuYW1lc3BhY2UuZ2V0KHByb3BlcnR5LmtleS5uYW1lKS5uYW1lc3BhY2UsIHBhdGgpXG4gICAgICAgICAgICBwYXRoLnBvcCgpXG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGVzdEtleShpZCwgbmFtZXNwYWNlcy5nZXQoaW5pdC5uYW1lKSlcbiAgICAgIH0sXG5cbiAgICAgIEpTWE1lbWJlckV4cHJlc3Npb246IGZ1bmN0aW9uKHtvYmplY3QsIHByb3BlcnR5fSkge1xuICAgICAgICAgaWYgKCFuYW1lc3BhY2VzLmhhcyhvYmplY3QubmFtZSkpIHJldHVyblxuICAgICAgICAgdmFyIG5hbWVzcGFjZSA9IG5hbWVzcGFjZXMuZ2V0KG9iamVjdC5uYW1lKVxuICAgICAgICAgaWYgKCFuYW1lc3BhY2UuaGFzKHByb3BlcnR5Lm5hbWUpKSB7XG4gICAgICAgICAgIGNvbnRleHQucmVwb3J0KHtcbiAgICAgICAgICAgICBub2RlOiBwcm9wZXJ0eSxcbiAgICAgICAgICAgICBtZXNzYWdlOiBtYWtlTWVzc2FnZShwcm9wZXJ0eSwgW29iamVjdC5uYW1lXSksXG4gICAgICAgICAgIH0pXG4gICAgICAgICB9XG4gICAgICB9LFxuICAgIH1cbiAgfSxcbn1cbiJdfQ==