objectsQueries.js 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.needToGetAllKeys = exports.getObject = exports.findObjects = exports.calculateSkipAndLimit = void 0;
  6. var _node = _interopRequireDefault(require("parse/node"));
  7. var _graphqlRelay = require("graphql-relay");
  8. var _rest = _interopRequireDefault(require("../../rest"));
  9. var _query = require("../transformers/query");
  10. function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
  11. // Eslint/Prettier conflict
  12. /* eslint-disable*/
  13. const needToGetAllKeys = (fields, keys, parseClasses) => keys ? keys.split(',').some(keyName => {
  14. const key = keyName.split('.');
  15. if (fields[key[0]]) {
  16. if (fields[key[0]].type === 'Relation') return false;
  17. if (fields[key[0]].type === 'Pointer') {
  18. const subClass = parseClasses[fields[key[0]].targetClass];
  19. if (subClass && subClass.fields[key[1]]) {
  20. // Current sub key is not custom
  21. return false;
  22. }
  23. } else if (!key[1] || fields[key[0]].type === 'Array' || fields[key[0]].type === 'Object') {
  24. // current key is not custom
  25. return false;
  26. }
  27. }
  28. // Key not found into Parse Schema so it's custom
  29. return true;
  30. }) : true;
  31. /* eslint-enable*/
  32. exports.needToGetAllKeys = needToGetAllKeys;
  33. const getObject = async (className, objectId, keys, include, readPreference, includeReadPreference, config, auth, info, parseClasses) => {
  34. const options = {};
  35. try {
  36. if (!needToGetAllKeys(parseClasses[className].fields, keys, parseClasses)) {
  37. options.keys = keys;
  38. }
  39. } catch (e) {
  40. console.error(e);
  41. }
  42. if (include) {
  43. options.include = include;
  44. if (includeReadPreference) {
  45. options.includeReadPreference = includeReadPreference;
  46. }
  47. }
  48. if (readPreference) {
  49. options.readPreference = readPreference;
  50. }
  51. const response = await _rest.default.get(config, auth, className, objectId, options, info.clientSDK, info.context);
  52. if (!response.results || response.results.length == 0) {
  53. throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Object not found.');
  54. }
  55. const object = response.results[0];
  56. if (className === '_User') {
  57. delete object.sessionToken;
  58. }
  59. return object;
  60. };
  61. exports.getObject = getObject;
  62. const findObjects = async (className, where, order, skipInput, first, after, last, before, keys, include, includeAll, readPreference, includeReadPreference, subqueryReadPreference, config, auth, info, selectedFields, parseClasses) => {
  63. if (!where) {
  64. where = {};
  65. }
  66. (0, _query.transformQueryInputToParse)(where, className, parseClasses);
  67. const skipAndLimitCalculation = calculateSkipAndLimit(skipInput, first, after, last, before, config.maxLimit);
  68. let {
  69. skip
  70. } = skipAndLimitCalculation;
  71. const {
  72. limit,
  73. needToPreCount
  74. } = skipAndLimitCalculation;
  75. let preCount = undefined;
  76. if (needToPreCount) {
  77. const preCountOptions = {
  78. limit: 0,
  79. count: true
  80. };
  81. if (readPreference) {
  82. preCountOptions.readPreference = readPreference;
  83. }
  84. if (Object.keys(where).length > 0 && subqueryReadPreference) {
  85. preCountOptions.subqueryReadPreference = subqueryReadPreference;
  86. }
  87. preCount = (await _rest.default.find(config, auth, className, where, preCountOptions, info.clientSDK, info.context)).count;
  88. if ((skip || 0) + limit < preCount) {
  89. skip = preCount - limit;
  90. }
  91. }
  92. const options = {};
  93. if (selectedFields.find(field => field.startsWith('edges.') || field.startsWith('pageInfo.'))) {
  94. if (limit || limit === 0) {
  95. options.limit = limit;
  96. } else {
  97. options.limit = 100;
  98. }
  99. if (options.limit !== 0) {
  100. if (order) {
  101. options.order = order;
  102. }
  103. if (skip) {
  104. options.skip = skip;
  105. }
  106. if (config.maxLimit && options.limit > config.maxLimit) {
  107. // Silently replace the limit on the query with the max configured
  108. options.limit = config.maxLimit;
  109. }
  110. if (!needToGetAllKeys(parseClasses[className].fields, keys, parseClasses)) {
  111. options.keys = keys;
  112. }
  113. if (includeAll === true) {
  114. options.includeAll = includeAll;
  115. }
  116. if (!options.includeAll && include) {
  117. options.include = include;
  118. }
  119. if ((options.includeAll || options.include) && includeReadPreference) {
  120. options.includeReadPreference = includeReadPreference;
  121. }
  122. }
  123. } else {
  124. options.limit = 0;
  125. }
  126. if ((selectedFields.includes('count') || selectedFields.includes('pageInfo.hasPreviousPage') || selectedFields.includes('pageInfo.hasNextPage')) && !needToPreCount) {
  127. options.count = true;
  128. }
  129. if (readPreference) {
  130. options.readPreference = readPreference;
  131. }
  132. if (Object.keys(where).length > 0 && subqueryReadPreference) {
  133. options.subqueryReadPreference = subqueryReadPreference;
  134. }
  135. let results, count;
  136. if (options.count || !options.limit || options.limit && options.limit > 0) {
  137. const findResult = await _rest.default.find(config, auth, className, where, options, info.clientSDK, info.context);
  138. results = findResult.results;
  139. count = findResult.count;
  140. }
  141. let edges = null;
  142. let pageInfo = null;
  143. if (results) {
  144. edges = results.map((result, index) => ({
  145. cursor: (0, _graphqlRelay.offsetToCursor)((skip || 0) + index),
  146. node: result
  147. }));
  148. pageInfo = {
  149. hasPreviousPage: (preCount && preCount > 0 || count && count > 0) && skip !== undefined && skip > 0,
  150. startCursor: (0, _graphqlRelay.offsetToCursor)(skip || 0),
  151. endCursor: (0, _graphqlRelay.offsetToCursor)((skip || 0) + (results.length || 1) - 1),
  152. hasNextPage: (preCount || count) > (skip || 0) + results.length
  153. };
  154. }
  155. return {
  156. edges,
  157. pageInfo,
  158. count: preCount || count
  159. };
  160. };
  161. exports.findObjects = findObjects;
  162. const calculateSkipAndLimit = (skipInput, first, after, last, before, maxLimit) => {
  163. let skip = undefined;
  164. let limit = undefined;
  165. let needToPreCount = false;
  166. // Validates the skip input
  167. if (skipInput || skipInput === 0) {
  168. if (skipInput < 0) {
  169. throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'Skip should be a positive number');
  170. }
  171. skip = skipInput;
  172. }
  173. // Validates the after param
  174. if (after) {
  175. after = (0, _graphqlRelay.cursorToOffset)(after);
  176. if (!after && after !== 0 || after < 0) {
  177. throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'After is not a valid cursor');
  178. }
  179. // If skip and after are passed, a new skip is calculated by adding them
  180. skip = (skip || 0) + (after + 1);
  181. }
  182. // Validates the first param
  183. if (first || first === 0) {
  184. if (first < 0) {
  185. throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'First should be a positive number');
  186. }
  187. // The first param is translated to the limit param of the Parse legacy API
  188. limit = first;
  189. }
  190. // Validates the before param
  191. if (before || before === 0) {
  192. // This method converts the cursor to the index of the object
  193. before = (0, _graphqlRelay.cursorToOffset)(before);
  194. if (!before && before !== 0 || before < 0) {
  195. throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'Before is not a valid cursor');
  196. }
  197. if ((skip || 0) >= before) {
  198. // If the before index is less than the skip, no objects will be returned
  199. limit = 0;
  200. } else if (!limit && limit !== 0 || (skip || 0) + limit > before) {
  201. // If there is no limit set, the limit is calculated. Or, if the limit (plus skip) is bigger than the before index, the new limit is set.
  202. limit = before - (skip || 0);
  203. }
  204. }
  205. // Validates the last param
  206. if (last || last === 0) {
  207. if (last < 0) {
  208. throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'Last should be a positive number');
  209. }
  210. if (last > maxLimit) {
  211. // Last can't be bigger than Parse server maxLimit config.
  212. last = maxLimit;
  213. }
  214. if (limit || limit === 0) {
  215. // If there is a previous limit set, it may be adjusted
  216. if (last < limit) {
  217. // if last is less than the current limit
  218. skip = (skip || 0) + (limit - last); // The skip is adjusted
  219. limit = last; // the limit is adjusted
  220. }
  221. } else if (last === 0) {
  222. // No objects will be returned
  223. limit = 0;
  224. } else {
  225. // No previous limit set, the limit will be equal to last and pre count is needed.
  226. limit = last;
  227. needToPreCount = true;
  228. }
  229. }
  230. return {
  231. skip,
  232. limit,
  233. needToPreCount
  234. };
  235. };
  236. exports.calculateSkipAndLimit = calculateSkipAndLimit;
  237. //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbm9kZSIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJyZXF1aXJlIiwiX2dyYXBocWxSZWxheSIsIl9yZXN0IiwiX3F1ZXJ5IiwiZSIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwibmVlZFRvR2V0QWxsS2V5cyIsImZpZWxkcyIsImtleXMiLCJwYXJzZUNsYXNzZXMiLCJzcGxpdCIsInNvbWUiLCJrZXlOYW1lIiwia2V5IiwidHlwZSIsInN1YkNsYXNzIiwidGFyZ2V0Q2xhc3MiLCJleHBvcnRzIiwiZ2V0T2JqZWN0IiwiY2xhc3NOYW1lIiwib2JqZWN0SWQiLCJpbmNsdWRlIiwicmVhZFByZWZlcmVuY2UiLCJpbmNsdWRlUmVhZFByZWZlcmVuY2UiLCJjb25maWciLCJhdXRoIiwiaW5mbyIsIm9wdGlvbnMiLCJjb25zb2xlIiwiZXJyb3IiLCJyZXNwb25zZSIsInJlc3QiLCJnZXQiLCJjbGllbnRTREsiLCJjb250ZXh0IiwicmVzdWx0cyIsImxlbmd0aCIsIlBhcnNlIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwib2JqZWN0Iiwic2Vzc2lvblRva2VuIiwiZmluZE9iamVjdHMiLCJ3aGVyZSIsIm9yZGVyIiwic2tpcElucHV0IiwiZmlyc3QiLCJhZnRlciIsImxhc3QiLCJiZWZvcmUiLCJpbmNsdWRlQWxsIiwic3VicXVlcnlSZWFkUHJlZmVyZW5jZSIsInNlbGVjdGVkRmllbGRzIiwidHJhbnNmb3JtUXVlcnlJbnB1dFRvUGFyc2UiLCJza2lwQW5kTGltaXRDYWxjdWxhdGlvbiIsImNhbGN1bGF0ZVNraXBBbmRMaW1pdCIsIm1heExpbWl0Iiwic2tpcCIsImxpbWl0IiwibmVlZFRvUHJlQ291bnQiLCJwcmVDb3VudCIsInVuZGVmaW5lZCIsInByZUNvdW50T3B0aW9ucyIsImNvdW50IiwiT2JqZWN0IiwiZmluZCIsImZpZWxkIiwic3RhcnRzV2l0aCIsImluY2x1ZGVzIiwiZmluZFJlc3VsdCIsImVkZ2VzIiwicGFnZUluZm8iLCJtYXAiLCJyZXN1bHQiLCJpbmRleCIsImN1cnNvciIsIm9mZnNldFRvQ3Vyc29yIiwibm9kZSIsImhhc1ByZXZpb3VzUGFnZSIsInN0YXJ0Q3Vyc29yIiwiZW5kQ3Vyc29yIiwiaGFzTmV4dFBhZ2UiLCJJTlZBTElEX1FVRVJZIiwiY3Vyc29yVG9PZmZzZXQiXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvR3JhcGhRTC9oZWxwZXJzL29iamVjdHNRdWVyaWVzLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCB7IG9mZnNldFRvQ3Vyc29yLCBjdXJzb3JUb09mZnNldCB9IGZyb20gJ2dyYXBocWwtcmVsYXknO1xuaW1wb3J0IHJlc3QgZnJvbSAnLi4vLi4vcmVzdCc7XG5pbXBvcnQgeyB0cmFuc2Zvcm1RdWVyeUlucHV0VG9QYXJzZSB9IGZyb20gJy4uL3RyYW5zZm9ybWVycy9xdWVyeSc7XG5cbi8vIEVzbGludC9QcmV0dGllciBjb25mbGljdFxuLyogZXNsaW50LWRpc2FibGUqL1xuY29uc3QgbmVlZFRvR2V0QWxsS2V5cyA9IChmaWVsZHMsIGtleXMsIHBhcnNlQ2xhc3NlcykgPT5cbiAga2V5c1xuICAgID8ga2V5cy5zcGxpdCgnLCcpLnNvbWUoa2V5TmFtZSA9PiB7XG4gICAgICAgIGNvbnN0IGtleSA9IGtleU5hbWUuc3BsaXQoJy4nKTtcbiAgICAgICAgaWYgKGZpZWxkc1trZXlbMF1dKSB7XG4gICAgICAgICAgaWYgKGZpZWxkc1trZXlbMF1dLnR5cGUgPT09ICdSZWxhdGlvbicpIHJldHVybiBmYWxzZTtcbiAgICAgICAgICBpZiAoZmllbGRzW2tleVswXV0udHlwZSA9PT0gJ1BvaW50ZXInKSB7XG4gICAgICAgICAgICBjb25zdCBzdWJDbGFzcyA9IHBhcnNlQ2xhc3Nlc1tmaWVsZHNba2V5WzBdXS50YXJnZXRDbGFzc107XG4gICAgICAgICAgICBpZiAoc3ViQ2xhc3MgJiYgc3ViQ2xhc3MuZmllbGRzW2tleVsxXV0pIHtcbiAgICAgICAgICAgICAgLy8gQ3VycmVudCBzdWIga2V5IGlzIG5vdCBjdXN0b21cbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgICAha2V5WzFdIHx8XG4gICAgICAgICAgICBmaWVsZHNba2V5WzBdXS50eXBlID09PSAnQXJyYXknIHx8XG4gICAgICAgICAgICBmaWVsZHNba2V5WzBdXS50eXBlID09PSAnT2JqZWN0J1xuICAgICAgICAgICkge1xuICAgICAgICAgICAgLy8gY3VycmVudCBrZXkgaXMgbm90IGN1c3RvbVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBLZXkgbm90IGZvdW5kIGludG8gUGFyc2UgU2NoZW1hIHNvIGl0J3MgY3VzdG9tXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSlcbiAgICA6IHRydWU7XG4vKiBlc2xpbnQtZW5hYmxlKi9cblxuY29uc3QgZ2V0T2JqZWN0ID0gYXN5bmMgKFxuICBjbGFzc05hbWUsXG4gIG9iamVjdElkLFxuICBrZXlzLFxuICBpbmNsdWRlLFxuICByZWFkUHJlZmVyZW5jZSxcbiAgaW5jbHVkZVJlYWRQcmVmZXJlbmNlLFxuICBjb25maWcsXG4gIGF1dGgsXG4gIGluZm8sXG4gIHBhcnNlQ2xhc3Nlc1xuKSA9PiB7XG4gIGNvbnN0IG9wdGlvbnMgPSB7fTtcbiAgdHJ5IHtcbiAgICBpZiAoIW5lZWRUb0dldEFsbEtleXMocGFyc2VDbGFzc2VzW2NsYXNzTmFtZV0uZmllbGRzLCBrZXlzLCBwYXJzZUNsYXNzZXMpKSB7XG4gICAgICBvcHRpb25zLmtleXMgPSBrZXlzO1xuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gIH1cbiAgaWYgKGluY2x1ZGUpIHtcbiAgICBvcHRpb25zLmluY2x1ZGUgPSBpbmNsdWRlO1xuICAgIGlmIChpbmNsdWRlUmVhZFByZWZlcmVuY2UpIHtcbiAgICAgIG9wdGlvbnMuaW5jbHVkZVJlYWRQcmVmZXJlbmNlID0gaW5jbHVkZVJlYWRQcmVmZXJlbmNlO1xuICAgIH1cbiAgfVxuICBpZiAocmVhZFByZWZlcmVuY2UpIHtcbiAgICBvcHRpb25zLnJlYWRQcmVmZXJlbmNlID0gcmVhZFByZWZlcmVuY2U7XG4gIH1cblxuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHJlc3QuZ2V0KFxuICAgIGNvbmZpZyxcbiAgICBhdXRoLFxuICAgIGNsYXNzTmFtZSxcbiAgICBvYmplY3RJZCxcbiAgICBvcHRpb25zLFxuICAgIGluZm8uY2xpZW50U0RLLFxuICAgIGluZm8uY29udGV4dFxuICApO1xuXG4gIGlmICghcmVzcG9uc2UucmVzdWx0cyB8fCByZXNwb25zZS5yZXN1bHRzLmxlbmd0aCA9PSAwKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdPYmplY3Qgbm90IGZvdW5kLicpO1xuICB9XG5cbiAgY29uc3Qgb2JqZWN0ID0gcmVzcG9uc2UucmVzdWx0c1swXTtcbiAgaWYgKGNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgIGRlbGV0ZSBvYmplY3Quc2Vzc2lvblRva2VuO1xuICB9XG4gIHJldHVybiBvYmplY3Q7XG59O1xuXG5jb25zdCBmaW5kT2JqZWN0cyA9IGFzeW5jIChcbiAgY2xhc3NOYW1lLFxuICB3aGVyZSxcbiAgb3JkZXIsXG4gIHNraXBJbnB1dCxcbiAgZmlyc3QsXG4gIGFmdGVyLFxuICBsYXN0LFxuICBiZWZvcmUsXG4gIGtleXMsXG4gIGluY2x1ZGUsXG4gIGluY2x1ZGVBbGwsXG4gIHJlYWRQcmVmZXJlbmNlLFxuICBpbmNsdWRlUmVhZFByZWZlcmVuY2UsXG4gIHN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UsXG4gIGNvbmZpZyxcbiAgYXV0aCxcbiAgaW5mbyxcbiAgc2VsZWN0ZWRGaWVsZHMsXG4gIHBhcnNlQ2xhc3Nlc1xuKSA9PiB7XG4gIGlmICghd2hlcmUpIHtcbiAgICB3aGVyZSA9IHt9O1xuICB9XG4gIHRyYW5zZm9ybVF1ZXJ5SW5wdXRUb1BhcnNlKHdoZXJlLCBjbGFzc05hbWUsIHBhcnNlQ2xhc3Nlcyk7XG4gIGNvbnN0IHNraXBBbmRMaW1pdENhbGN1bGF0aW9uID0gY2FsY3VsYXRlU2tpcEFuZExpbWl0KFxuICAgIHNraXBJbnB1dCxcbiAgICBmaXJzdCxcbiAgICBhZnRlcixcbiAgICBsYXN0LFxuICAgIGJlZm9yZSxcbiAgICBjb25maWcubWF4TGltaXRcbiAgKTtcbiAgbGV0IHsgc2tpcCB9ID0gc2tpcEFuZExpbWl0Q2FsY3VsYXRpb247XG4gIGNvbnN0IHsgbGltaXQsIG5lZWRUb1ByZUNvdW50IH0gPSBza2lwQW5kTGltaXRDYWxjdWxhdGlvbjtcbiAgbGV0IHByZUNvdW50ID0gdW5kZWZpbmVkO1xuICBpZiAobmVlZFRvUHJlQ291bnQpIHtcbiAgICBjb25zdCBwcmVDb3VudE9wdGlvbnMgPSB7XG4gICAgICBsaW1pdDogMCxcbiAgICAgIGNvdW50OiB0cnVlLFxuICAgIH07XG4gICAgaWYgKHJlYWRQcmVmZXJlbmNlKSB7XG4gICAgICBwcmVDb3VudE9wdGlvbnMucmVhZFByZWZlcmVuY2UgPSByZWFkUHJlZmVyZW5jZTtcbiAgICB9XG4gICAgaWYgKE9iamVjdC5rZXlzKHdoZXJlKS5sZW5ndGggPiAwICYmIHN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UpIHtcbiAgICAgIHByZUNvdW50T3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlID0gc3VicXVlcnlSZWFkUHJlZmVyZW5jZTtcbiAgICB9XG4gICAgcHJlQ291bnQgPSAoXG4gICAgICBhd2FpdCByZXN0LmZpbmQoY29uZmlnLCBhdXRoLCBjbGFzc05hbWUsIHdoZXJlLCBwcmVDb3VudE9wdGlvbnMsIGluZm8uY2xpZW50U0RLLCBpbmZvLmNvbnRleHQpXG4gICAgKS5jb3VudDtcbiAgICBpZiAoKHNraXAgfHwgMCkgKyBsaW1pdCA8IHByZUNvdW50KSB7XG4gICAgICBza2lwID0gcHJlQ291bnQgLSBsaW1pdDtcbiAgICB9XG4gIH1cblxuICBjb25zdCBvcHRpb25zID0ge307XG5cbiAgaWYgKHNlbGVjdGVkRmllbGRzLmZpbmQoZmllbGQgPT4gZmllbGQuc3RhcnRzV2l0aCgnZWRnZXMuJykgfHwgZmllbGQuc3RhcnRzV2l0aCgncGFnZUluZm8uJykpKSB7XG4gICAgaWYgKGxpbWl0IHx8IGxpbWl0ID09PSAwKSB7XG4gICAgICBvcHRpb25zLmxpbWl0ID0gbGltaXQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9wdGlvbnMubGltaXQgPSAxMDA7XG4gICAgfVxuICAgIGlmIChvcHRpb25zLmxpbWl0ICE9PSAwKSB7XG4gICAgICBpZiAob3JkZXIpIHtcbiAgICAgICAgb3B0aW9ucy5vcmRlciA9IG9yZGVyO1xuICAgICAgfVxuICAgICAgaWYgKHNraXApIHtcbiAgICAgICAgb3B0aW9ucy5za2lwID0gc2tpcDtcbiAgICAgIH1cbiAgICAgIGlmIChjb25maWcubWF4TGltaXQgJiYgb3B0aW9ucy5saW1pdCA+IGNvbmZpZy5tYXhMaW1pdCkge1xuICAgICAgICAvLyBTaWxlbnRseSByZXBsYWNlIHRoZSBsaW1pdCBvbiB0aGUgcXVlcnkgd2l0aCB0aGUgbWF4IGNvbmZpZ3VyZWRcbiAgICAgICAgb3B0aW9ucy5saW1pdCA9IGNvbmZpZy5tYXhMaW1pdDtcbiAgICAgIH1cbiAgICAgIGlmICghbmVlZFRvR2V0QWxsS2V5cyhwYXJzZUNsYXNzZXNbY2xhc3NOYW1lXS5maWVsZHMsIGtleXMsIHBhcnNlQ2xhc3NlcykpIHtcbiAgICAgICAgb3B0aW9ucy5rZXlzID0ga2V5cztcbiAgICAgIH1cbiAgICAgIGlmIChpbmNsdWRlQWxsID09PSB0cnVlKSB7XG4gICAgICAgIG9wdGlvbnMuaW5jbHVkZUFsbCA9IGluY2x1ZGVBbGw7XG4gICAgICB9XG4gICAgICBpZiAoIW9wdGlvbnMuaW5jbHVkZUFsbCAmJiBpbmNsdWRlKSB7XG4gICAgICAgIG9wdGlvbnMuaW5jbHVkZSA9IGluY2x1ZGU7XG4gICAgICB9XG4gICAgICBpZiAoKG9wdGlvbnMuaW5jbHVkZUFsbCB8fCBvcHRpb25zLmluY2x1ZGUpICYmIGluY2x1ZGVSZWFkUHJlZmVyZW5jZSkge1xuICAgICAgICBvcHRpb25zLmluY2x1ZGVSZWFkUHJlZmVyZW5jZSA9IGluY2x1ZGVSZWFkUHJlZmVyZW5jZTtcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgb3B0aW9ucy5saW1pdCA9IDA7XG4gIH1cblxuICBpZiAoXG4gICAgKHNlbGVjdGVkRmllbGRzLmluY2x1ZGVzKCdjb3VudCcpIHx8XG4gICAgICBzZWxlY3RlZEZpZWxkcy5pbmNsdWRlcygncGFnZUluZm8uaGFzUHJldmlvdXNQYWdlJykgfHxcbiAgICAgIHNlbGVjdGVkRmllbGRzLmluY2x1ZGVzKCdwYWdlSW5mby5oYXNOZXh0UGFnZScpKSAmJlxuICAgICFuZWVkVG9QcmVDb3VudFxuICApIHtcbiAgICBvcHRpb25zLmNvdW50ID0gdHJ1ZTtcbiAgfVxuXG4gIGlmIChyZWFkUHJlZmVyZW5jZSkge1xuICAgIG9wdGlvbnMucmVhZFByZWZlcmVuY2UgPSByZWFkUHJlZmVyZW5jZTtcbiAgfVxuICBpZiAoT2JqZWN0LmtleXMod2hlcmUpLmxlbmd0aCA+IDAgJiYgc3VicXVlcnlSZWFkUHJlZmVyZW5jZSkge1xuICAgIG9wdGlvbnMuc3VicXVlcnlSZWFkUHJlZmVyZW5jZSA9IHN1YnF1ZXJ5UmVhZFByZWZlcmVuY2U7XG4gIH1cblxuICBsZXQgcmVzdWx0cywgY291bnQ7XG4gIGlmIChvcHRpb25zLmNvdW50IHx8ICFvcHRpb25zLmxpbWl0IHx8IChvcHRpb25zLmxpbWl0ICYmIG9wdGlvbnMubGltaXQgPiAwKSkge1xuICAgIGNvbnN0IGZpbmRSZXN1bHQgPSBhd2FpdCByZXN0LmZpbmQoXG4gICAgICBjb25maWcsXG4gICAgICBhdXRoLFxuICAgICAgY2xhc3NOYW1lLFxuICAgICAgd2hlcmUsXG4gICAgICBvcHRpb25zLFxuICAgICAgaW5mby5jbGllbnRTREssXG4gICAgICBpbmZvLmNvbnRleHRcbiAgICApO1xuICAgIHJlc3VsdHMgPSBmaW5kUmVzdWx0LnJlc3VsdHM7XG4gICAgY291bnQgPSBmaW5kUmVzdWx0LmNvdW50O1xuICB9XG5cbiAgbGV0IGVkZ2VzID0gbnVsbDtcbiAgbGV0IHBhZ2VJbmZvID0gbnVsbDtcbiAgaWYgKHJlc3VsdHMpIHtcbiAgICBlZGdlcyA9IHJlc3VsdHMubWFwKChyZXN1bHQsIGluZGV4KSA9PiAoe1xuICAgICAgY3Vyc29yOiBvZmZzZXRUb0N1cnNvcigoc2tpcCB8fCAwKSArIGluZGV4KSxcbiAgICAgIG5vZGU6IHJlc3VsdCxcbiAgICB9KSk7XG5cbiAgICBwYWdlSW5mbyA9IHtcbiAgICAgIGhhc1ByZXZpb3VzUGFnZTpcbiAgICAgICAgKChwcmVDb3VudCAmJiBwcmVDb3VudCA+IDApIHx8IChjb3VudCAmJiBjb3VudCA+IDApKSAmJiBza2lwICE9PSB1bmRlZmluZWQgJiYgc2tpcCA+IDAsXG4gICAgICBzdGFydEN1cnNvcjogb2Zmc2V0VG9DdXJzb3Ioc2tpcCB8fCAwKSxcbiAgICAgIGVuZEN1cnNvcjogb2Zmc2V0VG9DdXJzb3IoKHNraXAgfHwgMCkgKyAocmVzdWx0cy5sZW5ndGggfHwgMSkgLSAxKSxcbiAgICAgIGhhc05leHRQYWdlOiAocHJlQ291bnQgfHwgY291bnQpID4gKHNraXAgfHwgMCkgKyByZXN1bHRzLmxlbmd0aCxcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBlZGdlcyxcbiAgICBwYWdlSW5mbyxcbiAgICBjb3VudDogcHJlQ291bnQgfHwgY291bnQsXG4gIH07XG59O1xuXG5jb25zdCBjYWxjdWxhdGVTa2lwQW5kTGltaXQgPSAoc2tpcElucHV0LCBmaXJzdCwgYWZ0ZXIsIGxhc3QsIGJlZm9yZSwgbWF4TGltaXQpID0+IHtcbiAgbGV0IHNraXAgPSB1bmRlZmluZWQ7XG4gIGxldCBsaW1pdCA9IHVuZGVmaW5lZDtcbiAgbGV0IG5lZWRUb1ByZUNvdW50ID0gZmFsc2U7XG5cbiAgLy8gVmFsaWRhdGVzIHRoZSBza2lwIGlucHV0XG4gIGlmIChza2lwSW5wdXQgfHwgc2tpcElucHV0ID09PSAwKSB7XG4gICAgaWYgKHNraXBJbnB1dCA8IDApIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLCAnU2tpcCBzaG91bGQgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgICB9XG4gICAgc2tpcCA9IHNraXBJbnB1dDtcbiAgfVxuXG4gIC8vIFZhbGlkYXRlcyB0aGUgYWZ0ZXIgcGFyYW1cbiAgaWYgKGFmdGVyKSB7XG4gICAgYWZ0ZXIgPSBjdXJzb3JUb09mZnNldChhZnRlcik7XG4gICAgaWYgKCghYWZ0ZXIgJiYgYWZ0ZXIgIT09IDApIHx8IGFmdGVyIDwgMCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksICdBZnRlciBpcyBub3QgYSB2YWxpZCBjdXJzb3InKTtcbiAgICB9XG5cbiAgICAvLyBJZiBza2lwIGFuZCBhZnRlciBhcmUgcGFzc2VkLCBhIG5ldyBza2lwIGlzIGNhbGN1bGF0ZWQgYnkgYWRkaW5nIHRoZW1cbiAgICBza2lwID0gKHNraXAgfHwgMCkgKyAoYWZ0ZXIgKyAxKTtcbiAgfVxuXG4gIC8vIFZhbGlkYXRlcyB0aGUgZmlyc3QgcGFyYW1cbiAgaWYgKGZpcnN0IHx8IGZpcnN0ID09PSAwKSB7XG4gICAgaWYgKGZpcnN0IDwgMCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksICdGaXJzdCBzaG91bGQgYmUgYSBwb3NpdGl2ZSBudW1iZXInKTtcbiAgICB9XG5cbiAgICAvLyBUaGUgZmlyc3QgcGFyYW0gaXMgdHJhbnNsYXRlZCB0byB0aGUgbGltaXQgcGFyYW0gb2YgdGhlIFBhcnNlIGxlZ2FjeSBBUElcbiAgICBsaW1pdCA9IGZpcnN0O1xuICB9XG5cbiAgLy8gVmFsaWRhdGVzIHRoZSBiZWZvcmUgcGFyYW1cbiAgaWYgKGJlZm9yZSB8fCBiZWZvcmUgPT09IDApIHtcbiAgICAvLyBUaGlzIG1ldGhvZCBjb252ZXJ0cyB0aGUgY3Vyc29yIHRvIHRoZSBpbmRleCBvZiB0aGUgb2JqZWN0XG4gICAgYmVmb3JlID0gY3Vyc29yVG9PZmZzZXQoYmVmb3JlKTtcbiAgICBpZiAoKCFiZWZvcmUgJiYgYmVmb3JlICE9PSAwKSB8fCBiZWZvcmUgPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSwgJ0JlZm9yZSBpcyBub3QgYSB2YWxpZCBjdXJzb3InKTtcbiAgICB9XG5cbiAgICBpZiAoKHNraXAgfHwgMCkgPj0gYmVmb3JlKSB7XG4gICAgICAvLyBJZiB0aGUgYmVmb3JlIGluZGV4IGlzIGxlc3MgdGhhbiB0aGUgc2tpcCwgbm8gb2JqZWN0cyB3aWxsIGJlIHJldHVybmVkXG4gICAgICBsaW1pdCA9IDA7XG4gICAgfSBlbHNlIGlmICgoIWxpbWl0ICYmIGxpbWl0ICE9PSAwKSB8fCAoc2tpcCB8fCAwKSArIGxpbWl0ID4gYmVmb3JlKSB7XG4gICAgICAvLyBJZiB0aGVyZSBpcyBubyBsaW1pdCBzZXQsIHRoZSBsaW1pdCBpcyBjYWxjdWxhdGVkLiBPciwgaWYgdGhlIGxpbWl0IChwbHVzIHNraXApIGlzIGJpZ2dlciB0aGFuIHRoZSBiZWZvcmUgaW5kZXgsIHRoZSBuZXcgbGltaXQgaXMgc2V0LlxuICAgICAgbGltaXQgPSBiZWZvcmUgLSAoc2tpcCB8fCAwKTtcbiAgICB9XG4gIH1cblxuICAvLyBWYWxpZGF0ZXMgdGhlIGxhc3QgcGFyYW1cbiAgaWYgKGxhc3QgfHwgbGFzdCA9PT0gMCkge1xuICAgIGlmIChsYXN0IDwgMCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksICdMYXN0IHNob3VsZCBiZSBhIHBvc2l0aXZlIG51bWJlcicpO1xuICAgIH1cblxuICAgIGlmIChsYXN0ID4gbWF4TGltaXQpIHtcbiAgICAgIC8vIExhc3QgY2FuJ3QgYmUgYmlnZ2VyIHRoYW4gUGFyc2Ugc2VydmVyIG1heExpbWl0IGNvbmZpZy5cbiAgICAgIGxhc3QgPSBtYXhMaW1pdDtcbiAgICB9XG5cbiAgICBpZiAobGltaXQgfHwgbGltaXQgPT09IDApIHtcbiAgICAgIC8vIElmIHRoZXJlIGlzIGEgcHJldmlvdXMgbGltaXQgc2V0LCBpdCBtYXkgYmUgYWRqdXN0ZWRcbiAgICAgIGlmIChsYXN0IDwgbGltaXQpIHtcbiAgICAgICAgLy8gaWYgbGFzdCBpcyBsZXNzIHRoYW4gdGhlIGN1cnJlbnQgbGltaXRcbiAgICAgICAgc2tpcCA9IChza2lwIHx8IDApICsgKGxpbWl0IC0gbGFzdCk7IC8vIFRoZSBza2lwIGlzIGFkanVzdGVkXG4gICAgICAgIGxpbWl0ID0gbGFzdDsgLy8gdGhlIGxpbWl0IGlzIGFkanVzdGVkXG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChsYXN0ID09PSAwKSB7XG4gICAgICAvLyBObyBvYmplY3RzIHdpbGwgYmUgcmV0dXJuZWRcbiAgICAgIGxpbWl0ID0gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTm8gcHJldmlvdXMgbGltaXQgc2V0LCB0aGUgbGltaXQgd2lsbCBiZSBlcXVhbCB0byBsYXN0IGFuZCBwcmUgY291bnQgaXMgbmVlZGVkLlxuICAgICAgbGltaXQgPSBsYXN0O1xuICAgICAgbmVlZFRvUHJlQ291bnQgPSB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4ge1xuICAgIHNraXAsXG4gICAgbGltaXQsXG4gICAgbmVlZFRvUHJlQ291bnQsXG4gIH07XG59O1xuXG5leHBvcnQgeyBnZXRPYmplY3QsIGZpbmRPYmplY3RzLCBjYWxjdWxhdGVTa2lwQW5kTGltaXQsIG5lZWRUb0dldEFsbEtleXMgfTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsSUFBQUEsS0FBQSxHQUFBQyxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUMsYUFBQSxHQUFBRCxPQUFBO0FB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