parse-server 4.10.2 → 5.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/README.md +450 -153
  2. package/lib/AccountLockout.js +23 -2
  3. package/lib/Adapters/AdapterLoader.js +1 -1
  4. package/lib/Adapters/Analytics/AnalyticsAdapter.js +1 -1
  5. package/lib/Adapters/Auth/AuthAdapter.js +1 -1
  6. package/lib/Adapters/Auth/OAuth1Client.js +1 -1
  7. package/lib/Adapters/Auth/facebook.js +110 -10
  8. package/lib/Adapters/Auth/gcenter.js +1 -1
  9. package/lib/Adapters/Auth/gpgames.js +1 -1
  10. package/lib/Adapters/Auth/instagram.js +4 -2
  11. package/lib/Adapters/Auth/keycloak.js +1 -1
  12. package/lib/Adapters/Auth/ldap.js +3 -1
  13. package/lib/Adapters/Auth/oauth2.js +1 -1
  14. package/lib/Adapters/Auth/phantauth.js +1 -1
  15. package/lib/Adapters/Cache/CacheAdapter.js +1 -1
  16. package/lib/Adapters/Cache/RedisCacheAdapter.js +143 -0
  17. package/lib/Adapters/Cache/SchemaCache.js +31 -0
  18. package/lib/Adapters/Email/MailAdapter.js +1 -1
  19. package/lib/Adapters/Files/FilesAdapter.js +1 -1
  20. package/lib/Adapters/Files/GridFSBucketAdapter.js +1 -1
  21. package/lib/Adapters/Files/GridStoreAdapter.js +1 -1
  22. package/lib/Adapters/Logger/LoggerAdapter.js +1 -1
  23. package/lib/Adapters/Logger/WinstonLogger.js +4 -4
  24. package/lib/Adapters/PubSub/EventEmitterPubSub.js +5 -1
  25. package/lib/Adapters/PubSub/PubSubAdapter.js +1 -1
  26. package/lib/Adapters/Push/PushAdapter.js +1 -1
  27. package/lib/Adapters/Storage/Mongo/MongoCollection.js +1 -1
  28. package/lib/Adapters/Storage/Mongo/MongoSchemaCollection.js +1 -1
  29. package/lib/Adapters/Storage/Mongo/MongoStorageAdapter.js +51 -11
  30. package/lib/Adapters/Storage/Mongo/MongoTransform.js +9 -6
  31. package/lib/Adapters/Storage/Postgres/PostgresClient.js +11 -1
  32. package/lib/Adapters/Storage/Postgres/PostgresStorageAdapter.js +91 -57
  33. package/lib/Adapters/WebSocketServer/WSAdapter.js +1 -1
  34. package/lib/Adapters/WebSocketServer/WSSAdapter.js +1 -1
  35. package/lib/Auth.js +2 -39
  36. package/lib/Config.js +149 -8
  37. package/lib/Controllers/AdaptableController.js +1 -9
  38. package/lib/Controllers/CacheController.js +1 -1
  39. package/lib/Controllers/DatabaseController.js +148 -44
  40. package/lib/Controllers/FilesController.js +1 -1
  41. package/lib/Controllers/HooksController.js +2 -2
  42. package/lib/Controllers/LiveQueryController.js +16 -3
  43. package/lib/Controllers/LoggerController.js +1 -1
  44. package/lib/Controllers/ParseGraphQLController.js +2 -2
  45. package/lib/Controllers/PushController.js +1 -1
  46. package/lib/Controllers/SchemaController.js +101 -88
  47. package/lib/Controllers/UserController.js +16 -5
  48. package/lib/Controllers/index.js +10 -11
  49. package/lib/Deprecator/Deprecations.js +28 -0
  50. package/lib/Deprecator/Deprecator.js +135 -0
  51. package/lib/GraphQL/ParseGraphQLSchema.js +71 -39
  52. package/lib/GraphQL/ParseGraphQLServer.js +3 -3
  53. package/lib/GraphQL/loaders/defaultGraphQLMutations.js +2 -2
  54. package/lib/GraphQL/loaders/defaultGraphQLQueries.js +2 -2
  55. package/lib/GraphQL/loaders/defaultGraphQLTypes.js +4 -7
  56. package/lib/GraphQL/loaders/defaultRelaySchema.js +3 -3
  57. package/lib/GraphQL/loaders/filesMutations.js +2 -2
  58. package/lib/GraphQL/loaders/functionsMutations.js +9 -5
  59. package/lib/GraphQL/loaders/parseClassMutations.js +21 -9
  60. package/lib/GraphQL/loaders/parseClassQueries.js +9 -6
  61. package/lib/GraphQL/loaders/parseClassTypes.js +5 -5
  62. package/lib/GraphQL/loaders/schemaDirectives.js +1 -1
  63. package/lib/GraphQL/loaders/schemaMutations.js +8 -6
  64. package/lib/GraphQL/loaders/schemaQueries.js +6 -4
  65. package/lib/GraphQL/loaders/usersMutations.js +65 -7
  66. package/lib/GraphQL/transformers/constraintType.js +2 -2
  67. package/lib/GraphQL/transformers/inputType.js +2 -2
  68. package/lib/GraphQL/transformers/mutation.js +45 -10
  69. package/lib/GraphQL/transformers/outputType.js +2 -2
  70. package/lib/GraphQL/transformers/query.js +2 -2
  71. package/lib/GraphQL/transformers/schemaFields.js +1 -1
  72. package/lib/KeyPromiseQueue.js +59 -0
  73. package/lib/LiveQuery/Client.js +1 -1
  74. package/lib/LiveQuery/Id.js +1 -1
  75. package/lib/LiveQuery/ParseLiveQueryServer.js +158 -38
  76. package/lib/LiveQuery/ParseWebSocketServer.js +2 -2
  77. package/lib/LiveQuery/QueryTools.js +50 -1
  78. package/lib/LiveQuery/equalObjects.js +1 -1
  79. package/lib/Options/Definitions.js +220 -33
  80. package/lib/Options/docs.js +79 -21
  81. package/lib/Options/index.js +3 -1
  82. package/lib/Page.js +53 -0
  83. package/lib/ParseServer.js +37 -16
  84. package/lib/ParseServerRESTController.js +55 -45
  85. package/lib/PromiseRouter.js +7 -20
  86. package/lib/Push/PushQueue.js +1 -1
  87. package/lib/Push/PushWorker.js +2 -2
  88. package/lib/Push/utils.js +1 -1
  89. package/lib/RestQuery.js +45 -9
  90. package/lib/RestWrite.js +60 -10
  91. package/lib/Routers/AggregateRouter.js +23 -18
  92. package/lib/Routers/AudiencesRouter.js +2 -2
  93. package/lib/Routers/ClassesRouter.js +11 -11
  94. package/lib/Routers/CloudCodeRouter.js +1 -1
  95. package/lib/Routers/FeaturesRouter.js +2 -2
  96. package/lib/Routers/FilesRouter.js +34 -7
  97. package/lib/Routers/FunctionsRouter.js +2 -2
  98. package/lib/Routers/GlobalConfigRouter.js +2 -2
  99. package/lib/Routers/GraphQLRouter.js +3 -3
  100. package/lib/Routers/HooksRouter.js +2 -2
  101. package/lib/Routers/LogsRouter.js +2 -2
  102. package/lib/Routers/PagesRouter.js +722 -0
  103. package/lib/Routers/PurgeRouter.js +2 -2
  104. package/lib/Routers/PushRouter.js +3 -3
  105. package/lib/Routers/SchemasRouter.js +2 -2
  106. package/lib/Routers/SecurityRouter.js +47 -0
  107. package/lib/Routers/SessionsRouter.js +4 -2
  108. package/lib/Routers/UsersRouter.js +88 -17
  109. package/lib/Security/Check.js +118 -0
  110. package/lib/Security/CheckGroup.js +54 -0
  111. package/lib/Security/CheckGroups/CheckGroupDatabase.js +57 -0
  112. package/lib/Security/CheckGroups/CheckGroupServerConfig.js +82 -0
  113. package/lib/Security/CheckGroups/CheckGroups.js +24 -0
  114. package/lib/Security/CheckRunner.js +236 -0
  115. package/lib/StatusHandler.js +27 -36
  116. package/lib/TestUtils.js +1 -1
  117. package/lib/Utils.js +226 -0
  118. package/lib/batch.js +55 -44
  119. package/lib/cli/utils/commander.js +8 -3
  120. package/lib/cloud-code/HTTPResponse.js +1 -1
  121. package/lib/cloud-code/Parse.Cloud.js +155 -19
  122. package/lib/cloud-code/httpRequest.js +1 -1
  123. package/lib/index.js +6 -12
  124. package/lib/middlewares.js +39 -4
  125. package/lib/rest.js +4 -4
  126. package/lib/triggers.js +134 -121
  127. package/lib/vendor/mongodbUrl.js +8 -10
  128. package/package.json +54 -29
  129. package/CHANGELOG.md +0 -1769
  130. package/lib/Adapters/Cache/RedisCacheAdapter/KeyPromiseQueue.js +0 -59
  131. package/lib/Adapters/Cache/RedisCacheAdapter/index.js +0 -130
  132. package/lib/Controllers/SchemaCache.js +0 -75
@@ -9,6 +9,8 @@ exports.pushStatusHandler = pushStatusHandler;
9
9
 
10
10
  var _cryptoUtils = require("./cryptoUtils");
11
11
 
12
+ var _KeyPromiseQueue = require("./KeyPromiseQueue");
13
+
12
14
  var _logger = require("./logger");
13
15
 
14
16
  var _rest = _interopRequireDefault(require("./rest"));
@@ -17,8 +19,16 @@ var _Auth = _interopRequireDefault(require("./Auth"));
17
19
 
18
20
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
21
 
22
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
23
+
24
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
25
+
26
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
27
+
20
28
  const PUSH_STATUS_COLLECTION = '_PushStatus';
21
29
  const JOB_STATUS_COLLECTION = '_JobStatus';
30
+ const pushPromiseQueue = new _KeyPromiseQueue.KeyPromiseQueue();
31
+ const jobPromiseQueue = new _KeyPromiseQueue.KeyPromiseQueue();
22
32
 
23
33
  const incrementOp = function (object = {}, key, amount = 1) {
24
34
  if (!object[key]) {
@@ -48,22 +58,14 @@ function flatten(array) {
48
58
  }
49
59
 
50
60
  function statusHandler(className, database) {
51
- let lastPromise = Promise.resolve();
52
-
53
61
  function create(object) {
54
- lastPromise = lastPromise.then(() => {
55
- return database.create(className, object).then(() => {
56
- return Promise.resolve(object);
57
- });
62
+ return database.create(className, object).then(() => {
63
+ return Promise.resolve(object);
58
64
  });
59
- return lastPromise;
60
65
  }
61
66
 
62
67
  function update(where, object) {
63
- lastPromise = lastPromise.then(() => {
64
- return database.update(className, where, object);
65
- });
66
- return lastPromise;
68
+ return jobPromiseQueue.enqueue(where.objectId, () => database.update(className, where, object));
67
69
  }
68
70
 
69
71
  return Object.freeze({
@@ -73,35 +75,24 @@ function statusHandler(className, database) {
73
75
  }
74
76
 
75
77
  function restStatusHandler(className, config) {
76
- let lastPromise = Promise.resolve();
77
-
78
78
  const auth = _Auth.default.master(config);
79
79
 
80
80
  function create(object) {
81
- lastPromise = lastPromise.then(() => {
82
- return _rest.default.create(config, auth, className, object).then(({
83
- response
84
- }) => {
85
- // merge the objects
86
- return Promise.resolve(Object.assign({}, object, response));
87
- });
81
+ return _rest.default.create(config, auth, className, object).then(({
82
+ response
83
+ }) => {
84
+ return _objectSpread(_objectSpread({}, object), response);
88
85
  });
89
- return lastPromise;
90
86
  }
91
87
 
92
88
  function update(where, object) {
93
- // TODO: when we have updateWhere, use that for proper interfacing
94
- lastPromise = lastPromise.then(() => {
95
- return _rest.default.update(config, auth, className, {
96
- objectId: where.objectId
97
- }, object).then(({
98
- response
99
- }) => {
100
- // merge the objects
101
- return Promise.resolve(Object.assign({}, object, response));
102
- });
103
- });
104
- return lastPromise;
89
+ return pushPromiseQueue.enqueue(where.objectId, () => _rest.default.update(config, auth, className, {
90
+ objectId: where.objectId
91
+ }, object).then(({
92
+ response
93
+ }) => {
94
+ return _objectSpread(_objectSpread({}, object), response);
95
+ }));
105
96
  }
106
97
 
107
98
  return Object.freeze({
@@ -330,10 +321,10 @@ function pushStatusHandler(config, existingObjectId) {
330
321
  acl: undefined,
331
322
  many: true
332
323
  });
333
- } // indicate this batch is complete
334
-
324
+ }
335
325
 
336
326
  incrementOp(update, 'count', -1);
327
+ update.status = 'running';
337
328
  return handler.update({
338
329
  objectId
339
330
  }, update).then(res => {
@@ -383,4 +374,4 @@ function pushStatusHandler(config, existingObjectId) {
383
374
  });
384
375
  return Object.freeze(rval);
385
376
  }
386
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9TdGF0dXNIYW5kbGVyLmpzIl0sIm5hbWVzIjpbIlBVU0hfU1RBVFVTX0NPTExFQ1RJT04iLCJKT0JfU1RBVFVTX0NPTExFQ1RJT04iLCJpbmNyZW1lbnRPcCIsIm9iamVjdCIsImtleSIsImFtb3VudCIsIl9fb3AiLCJmbGF0dGVuIiwiYXJyYXkiLCJmbGF0dGVuZWQiLCJpIiwibGVuZ3RoIiwiQXJyYXkiLCJpc0FycmF5IiwiY29uY2F0IiwicHVzaCIsInN0YXR1c0hhbmRsZXIiLCJjbGFzc05hbWUiLCJkYXRhYmFzZSIsImxhc3RQcm9taXNlIiwiUHJvbWlzZSIsInJlc29sdmUiLCJjcmVhdGUiLCJ0aGVuIiwidXBkYXRlIiwid2hlcmUiLCJPYmplY3QiLCJmcmVlemUiLCJyZXN0U3RhdHVzSGFuZGxlciIsImNvbmZpZyIsImF1dGgiLCJBdXRoIiwibWFzdGVyIiwicmVzdCIsInJlc3BvbnNlIiwiYXNzaWduIiwib2JqZWN0SWQiLCJqb2JTdGF0dXNIYW5kbGVyIiwiam9iU3RhdHVzIiwib2JqZWN0SWRTaXplIiwiaGFuZGxlciIsInNldFJ1bm5pbmciLCJqb2JOYW1lIiwicGFyYW1zIiwibm93IiwiRGF0ZSIsInN0YXR1cyIsInNvdXJjZSIsImNyZWF0ZWRBdCIsIkFDTCIsInNldE1lc3NhZ2UiLCJtZXNzYWdlIiwic2V0U3VjY2VlZGVkIiwic2V0RmluYWxTdGF0dXMiLCJzZXRGYWlsZWQiLCJ1bmRlZmluZWQiLCJmaW5pc2hlZEF0IiwiRXJyb3IiLCJwdXNoU3RhdHVzSGFuZGxlciIsImV4aXN0aW5nT2JqZWN0SWQiLCJwdXNoU3RhdHVzIiwic2V0SW5pdGlhbCIsImJvZHkiLCJvcHRpb25zIiwicHVzaFRpbWUiLCJ0b0lTT1N0cmluZyIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImhhc1B1c2hTY2hlZHVsZWRTdXBwb3J0IiwicHVzaF90aW1lIiwibG9nZ2VyIiwid2FybiIsImRhdGEiLCJwYXlsb2FkU3RyaW5nIiwiSlNPTiIsInN0cmluZ2lmeSIsInB1c2hIYXNoIiwiYWxlcnQiLCJxdWVyeSIsInBheWxvYWQiLCJ0aXRsZSIsImV4cGlyeSIsImV4cGlyYXRpb25fdGltZSIsImV4cGlyYXRpb25faW50ZXJ2YWwiLCJudW1TZW50IiwicmVzdWx0IiwiYmF0Y2hlcyIsInZlcmJvc2UiLCJjb3VudCIsInRyYWNrU2VudCIsInJlc3VsdHMiLCJVVENPZmZzZXQiLCJjbGVhbnVwSW5zdGFsbGF0aW9ucyIsInByb2Nlc3MiLCJlbnYiLCJQQVJTRV9TRVJWRVJfQ0xFQU5VUF9JTlZBTElEX0lOU1RBTExBVElPTlMiLCJudW1GYWlsZWQiLCJkZXZpY2VzVG9SZW1vdmUiLCJyZWR1Y2UiLCJtZW1vIiwiZGV2aWNlIiwiZGV2aWNlVHlwZSIsInRyYW5zbWl0dGVkIiwib2Zmc2V0S2V5IiwiZXJyb3IiLCJkZXZpY2VUb2tlbiIsInRva2VuIiwiZm9yRWFjaCIsImluZm8iLCIkaW4iLCJhY2wiLCJtYW55IiwicmVzIiwiY29tcGxldGUiLCJmYWlsIiwiZXJyIiwiZXJyb3JNZXNzYWdlIiwicnZhbCIsImRlZmluZVByb3BlcnR5IiwiZ2V0Il0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7OztBQUVBLE1BQU1BLHNCQUFzQixHQUFHLGFBQS9CO0FBQ0EsTUFBTUMscUJBQXFCLEdBQUcsWUFBOUI7O0FBRUEsTUFBTUMsV0FBVyxHQUFHLFVBQVVDLE1BQU0sR0FBRyxFQUFuQixFQUF1QkMsR0FBdkIsRUFBNEJDLE1BQU0sR0FBRyxDQUFyQyxFQUF3QztBQUMxRCxNQUFJLENBQUNGLE1BQU0sQ0FBQ0MsR0FBRCxDQUFYLEVBQWtCO0FBQ2hCRCxJQUFBQSxNQUFNLENBQUNDLEdBQUQsQ0FBTixHQUFjO0FBQUVFLE1BQUFBLElBQUksRUFBRSxXQUFSO0FBQXFCRCxNQUFBQSxNQUFNLEVBQUVBO0FBQTdCLEtBQWQ7QUFDRCxHQUZELE1BRU87QUFDTEYsSUFBQUEsTUFBTSxDQUFDQyxHQUFELENBQU4s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QUFNOEYsSUFBSSxHQUFHO0FBQ1h6RCxJQUFBQSxVQURXO0FBRVhwQixJQUFBQSxVQUZXO0FBR1hpRCxJQUFBQSxTQUhXO0FBSVh3QixJQUFBQSxRQUpXO0FBS1hDLElBQUFBO0FBTFcsR0FBYixDQTNMMEQsQ0FtTTFEOztBQUNBekYsRUFBQUEsTUFBTSxDQUFDNkYsY0FBUCxDQUFzQkQsSUFBdEIsRUFBNEIsVUFBNUIsRUFBd0M7QUFDdENFLElBQUFBLEdBQUcsRUFBRSxNQUFNcEY7QUFEMkIsR0FBeEM7QUFJQSxTQUFPVixNQUFNLENBQUNDLE1BQVAsQ0FBYzJGLElBQWQsQ0FBUDtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgbWQ1SGFzaCwgbmV3T2JqZWN0SWQgfSBmcm9tICcuL2NyeXB0b1V0aWxzJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4vbG9nZ2VyJztcbmltcG9ydCByZXN0IGZyb20gJy4vcmVzdCc7XG5pbXBvcnQgQXV0aCBmcm9tICcuL0F1dGgnO1xuXG5jb25zdCBQVVNIX1NUQVRVU19DT0xMRUNUSU9OID0gJ19QdXNoU3RhdHVzJztcbmNvbnN0IEpPQl9TVEFUVVNfQ09MTEVDVElPTiA9ICdfSm9iU3RhdHVzJztcblxuY29uc3QgaW5jcmVtZW50T3AgPSBmdW5jdGlvbiAob2JqZWN0ID0ge30sIGtleSwgYW1vdW50ID0gMSkge1xuICBpZiAoIW9iamVjdFtrZXldKSB7XG4gICAgb2JqZWN0W2tleV0gPSB7IF9fb3A6ICdJbmNyZW1lbnQnLCBhbW91bnQ6IGFtb3VudCB9O1xuICB9IGVsc2Uge1xuICAgIG9iamVjdFtrZXldLmFtb3VudCArPSBhbW91bnQ7XG4gIH1cbiAgcmV0dXJuIG9iamVjdFtrZXldO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGZsYXR0ZW4oYXJyYXkpIHtcbiAgdmFyIGZsYXR0ZW5lZCA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoYXJyYXlbaV0pKSB7XG4gICAgICBmbGF0dGVuZWQgPSBmbGF0dGVuZWQuY29uY2F0KGZsYXR0ZW4oYXJyYXlbaV0pKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZmxhdHRlbmVkLnB1c2goYXJyYXlbaV0pO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmxhdHRlbmVkO1xufVxuXG5mdW5jdGlvbiBzdGF0dXNIYW5kbGVyKGNsYXNzTmFtZSwgZGF0YWJhc2UpIHtcbiAgbGV0IGxhc3RQcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKCk7XG5cbiAgZnVuY3Rpb24gY3JlYXRlKG9iamVjdCkge1xuICAgIGxhc3RQcm9taXNlID0gbGFzdFByb21pc2UudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gZGF0YWJhc2UuY3JlYXRlKGNsYXNzTmFtZSwgb2JqZWN0KS50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShvYmplY3QpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGxhc3RQcm9taXNlO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlKHdoZXJlLCBvYmplY3QpIHtcbiAgICBsYXN0UHJvbWlzZSA9IGxhc3RQcm9taXNlLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIGRhdGFiYXNlLnVwZGF0ZShjbGFzc05hbWUsIHdoZXJlLCBvYmplY3QpO1xuICAgIH0pO1xuICAgIHJldHVybiBsYXN0UHJvbWlzZTtcbiAgfVxuXG4gIHJldHVybiBPYmplY3QuZnJlZXplKHtcbiAgICBjcmVhdGUsXG4gICAgdXBkYXRlLFxuICB9KTtcbn1cblxuZnVuY3Rpb24gcmVzdFN0YXR1c0hhbmRsZXIoY2xhc3NOYW1lLCBjb25maWcpIHtcbiAgbGV0IGxhc3RQcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIGNvbnN0IGF1dGggPSBBdXRoLm1hc3Rlcihjb25maWcpO1xuICBmdW5jdGlvbiBjcmVhdGUob2JqZWN0KSB7XG4gICAgbGFzdFByb21pc2UgPSBsYXN0UHJvbWlzZS50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiByZXN0LmNyZWF0ZShjb25maWcsIGF1dGgsIGNsYXNzTmFtZSwgb2JqZWN0KS50aGVuKCh7IHJlc3BvbnNlIH0pID0+IHtcbiAgICAgICAgLy8gbWVyZ2UgdGhlIG9iamVjdHNcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShPYmplY3QuYXNzaWduKHt9LCBvYmplY3QsIHJlc3BvbnNlKSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICByZXR1cm4gbGFzdFByb21pc2U7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGUod2hlcmUsIG9iamVjdCkge1xuICAgIC8vIFRPRE86IHdoZW4gd2UgaGF2ZSB1cGRhdGVXaGVyZSwgdXNlIHRoYXQgZm9yIHByb3BlciBpbnRlcmZhY2luZ1xuICAgIGxhc3RQcm9taXNlID0gbGFzdFByb21pc2UudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gcmVzdFxuICAgICAgICAudXBkYXRlKGNvbmZpZywgYXV0aCwgY2xhc3NOYW1lLCB7IG9iamVjdElkOiB3aGVyZS5vYmplY3RJZCB9LCBvYmplY3QpXG4gICAgICAgIC50aGVuKCh7IHJlc3BvbnNlIH0pID0+IHtcbiAgICAgICAgICAvLyBtZXJnZSB0aGUgb2JqZWN0c1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoT2JqZWN0LmFzc2lnbih7fSwgb2JqZWN0LCByZXNwb25zZSkpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgICByZXR1cm4gbGFzdFByb21pc2U7XG4gIH1cblxuICByZXR1cm4gT2JqZWN0LmZyZWV6ZSh7XG4gICAgY3JlYXRlLFxuICAgIHVwZGF0ZSxcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBqb2JTdGF0dXNIYW5kbGVyKGNvbmZpZykge1xuICBsZXQgam9iU3RhdHVzO1xuICBjb25zdCBvYmplY3RJZCA9IG5ld09iamVjdElkKGNvbmZpZy5vYmplY3RJZFNpemUpO1xuICBjb25zdCBkYXRhYmFzZSA9IGNvbmZpZy5kYXRhYmFzZTtcbiAgY29uc3QgaGFuZGxlciA9IHN0YXR1c0hhbmRsZXIoSk9CX1NUQVRVU19DT0xMRUNUSU9OLCBkYXRhYmFzZSk7XG4gIGNvbnN0IHNldFJ1bm5pbmcgPSBmdW5jdGlvbiAoam9iTmFtZSwgcGFyYW1zKSB7XG4gICAgY29uc3Qgbm93ID0gbmV3IERhdGUoKTtcbiAgICBqb2JTdGF0dXMgPSB7XG4gICAgICBvYmplY3RJZCxcbiAgICAgIGpvYk5hbWUsXG4gICAgICBwYXJhbXMsXG4gICAgICBzdGF0dXM6ICdydW5uaW5nJyxcbiAgICAgIHNvdXJjZTogJ2FwaScsXG4gICAgICBjcmVhdGVkQXQ6IG5vdyxcbiAgICAgIC8vIGxvY2tkb3duIVxuICAgICAgQUNMOiB7fSxcbiAgICB9O1xuXG4gICAgcmV0dXJuIGhhbmRsZXIuY3JlYXRlKGpvYlN0YXR1cyk7XG4gIH07XG5cbiAgY29uc3Qgc2V0TWVzc2FnZSA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XG4gICAgaWYgKCFtZXNzYWdlIHx8IHR5cGVvZiBtZXNzYWdlICE9PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cbiAgICByZXR1cm4gaGFuZGxlci51cGRhdGUoeyBvYmplY3RJZCB9LCB7IG1lc3NhZ2UgfSk7XG4gIH07XG5cbiAgY29uc3Qgc2V0U3VjY2VlZGVkID0gZnVuY3Rpb24gKG1lc3NhZ2UpIHtcbiAgICByZXR1cm4gc2V0RmluYWxTdGF0dXMoJ3N1Y2NlZWRlZCcsIG1lc3NhZ2UpO1xuICB9O1xuXG4gIGNvbnN0IHNldEZhaWxlZCA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XG4gICAgcmV0dXJuIHNldEZpbmFsU3RhdHVzKCdmYWlsZWQnLCBtZXNzYWdlKTtcbiAgfTtcblxuICBjb25zdCBzZXRGaW5hbFN0YXR1cyA9IGZ1bmN0aW9uIChzdGF0dXMsIG1lc3NhZ2UgPSB1bmRlZmluZWQpIHtcbiAgICBjb25zdCBmaW5pc2hlZEF0ID0gbmV3IERhdGUoKTtcbiAgICBjb25zdCB1cGRhdGUgPSB7IHN0YXR1cywgZmluaXNoZWRBdCB9O1xuICAgIGlmIChtZXNzYWdlICYmIHR5cGVvZiBtZXNzYWdlID09PSAnc3RyaW5nJykge1xuICAgICAgdXBkYXRlLm1lc3NhZ2UgPSBtZXNzYWdlO1xuICAgIH1cbiAgICBpZiAobWVzc2FnZSBpbnN0YW5jZW9mIEVycm9yICYmIHR5cGVvZiBtZXNzYWdlLm1lc3NhZ2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICB1cGRhdGUubWVzc2FnZSA9IG1lc3NhZ2UubWVzc2FnZTtcbiAgICB9XG4gICAgcmV0dXJuIGhhbmRsZXIudXBkYXRlKHsgb2JqZWN0SWQgfSwgdXBkYXRlKTtcbiAgfTtcblxuICByZXR1cm4gT2JqZWN0LmZyZWV6ZSh7XG4gICAgc2V0UnVubmluZyxcbiAgICBzZXRTdWNjZWVkZWQsXG4gICAgc2V0TWVzc2FnZSxcbiAgICBzZXRGYWlsZWQsXG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcHVzaFN0YXR1c0hhbmRsZXIoY29uZmlnLCBleGlzdGluZ09iamVjdElkKSB7XG4gIGxldCBwdXNoU3RhdHVzO1xuICBjb25zdCBkYXRhYmFzZSA9IGNvbmZpZy5kYXRhYmFzZTtcbiAgY29uc3QgaGFuZGxlciA9IHJlc3RTdGF0dXNIYW5kbGVyKFBVU0hfU1RBVFVTX0NPTExFQ1RJT04sIGNvbmZpZyk7XG4gIGxldCBvYmplY3RJZCA9IGV4aXN0aW5nT2JqZWN0SWQ7XG4gIGNvbnN0IHNldEluaXRpYWwgPSBmdW5jdGlvbiAoYm9keSA9IHt9LCB3aGVyZSwgb3B0aW9ucyA9IHsgc291cmNlOiAncmVzdCcgfSkge1xuICAgIGNvbnN0IG5vdyA9IG5ldyBEYXRlKCk7XG4gICAgbGV0IHB1c2hUaW1lID0gbm93LnRvSVNPU3RyaW5nKCk7XG4gICAgbGV0IHN0YXR1cyA9ICdwZW5kaW5nJztcbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGJvZHksICdwdXNoX3RpbWUnKSkge1xuICAgICAgaWYgKGNvbmZpZy5oYXNQdXNoU2NoZWR1bGVkU3VwcG9ydCkge1xuICAgICAgICBwdXNoVGltZSA9IGJvZHkucHVzaF90aW1lO1xuICAgICAgICBzdGF0dXMgPSAnc2NoZWR1bGVkJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdUcnlpbmcgdG8gc2NoZWR1bGUgYSBwdXNoIHdoaWxlIHNlcnZlciBpcyBub3QgY29uZmlndXJlZC4nKTtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1B1c2ggd2lsbCBiZSBzZW50IGltbWVkaWF0ZWx5Jyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgZGF0YSA9IGJvZHkuZGF0YSB8fCB7fTtcbiAgICBjb25zdCBwYXlsb2FkU3RyaW5nID0gSlNPTi5zdHJpbmdpZnkoZGF0YSk7XG4gICAgbGV0IHB1c2hIYXNoO1xuICAgIGlmICh0eXBlb2YgZGF0YS5hbGVydCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHB1c2hIYXNoID0gbWQ1SGFzaChkYXRhLmFsZXJ0KTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBkYXRhLmFsZXJ0ID09PSAnb2JqZWN0Jykge1xuICAgICAgcHVzaEhhc2ggPSBtZDVIYXNoKEpTT04uc3RyaW5naWZ5KGRhdGEuYWxlcnQpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHVzaEhhc2ggPSAnZDQxZDhjZDk4ZjAwYjIwNGU5ODAwOTk4ZWNmODQyN2UnO1xuICAgIH1cbiAgICBjb25zdCBvYmplY3QgPSB7XG4gICAgICBwdXNoVGltZSxcbiAgICAgIHF1ZXJ5OiBKU09OLnN0cmluZ2lmeSh3aGVyZSksXG4gICAgICBwYXlsb2FkOiBwYXlsb2FkU3RyaW5nLFxuICAgICAgc291cmNlOiBvcHRpb25zLnNvdXJjZSxcbiAgICAgIHRpdGxlOiBvcHRpb25zLnRpdGxlLFxuICAgICAgZXhwaXJ5OiBib2R5LmV4cGlyYXRpb25fdGltZSxcbiAgICAgIGV4cGlyYXRpb25faW50ZXJ2YWw6IGJvZHkuZXhwaXJhdGlvbl9pbnRlcnZhbCxcbiAgICAgIHN0YXR1czogc3RhdHVzLFxuICAgICAgbnVtU2VudDogMCxcbiAgICAgIHB1c2hIYXNoLFxuICAgICAgLy8gbG9ja2Rvd24hXG4gICAgICBBQ0w6IHt9LFxuICAgIH07XG4gICAgcmV0dXJuIGhhbmRsZXIuY3JlYXRlKG9iamVjdCkudGhlbihyZXN1bHQgPT4ge1xuICAgICAgb2JqZWN0SWQgPSByZXN1bHQub2JqZWN0SWQ7XG4gICAgICBwdXNoU3RhdHVzID0ge1xuICAgICAgICBvYmplY3RJZCxcbiAgICAgIH07XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHB1c2hTdGF0dXMpO1xuICAgIH0pO1xuICB9O1xuXG4gIGNvbnN0IHNldFJ1bm5pbmcgPSBmdW5jdGlvbiAoYmF0Y2hlcykge1xuICAgIGxvZ2dlci52ZXJib3NlKFxuICAgICAgYF9QdXNoU3RhdHVzICR7b2JqZWN0SWR9OiBzZW5kaW5nIHB1c2ggdG8gaW5zdGFsbGF0aW9ucyB3aXRoICVkIGJhdGNoZXNgLFxuICAgICAgYmF0Y2hlc1xuICAgICk7XG4gICAgcmV0dXJuIGhhbmRsZXIudXBkYXRlKFxuICAgICAge1xuICAgICAgICBzdGF0dXM6ICdwZW5kaW5nJyxcbiAgICAgICAgb2JqZWN0SWQ6IG9iamVjdElkLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgc3RhdHVzOiAncnVubmluZycsXG4gICAgICAgIGNvdW50OiBiYXRjaGVzLFxuICAgICAgfVxuICAgICk7XG4gIH07XG5cbiAgY29uc3QgdHJhY2tTZW50ID0gZnVuY3Rpb24gKFxuICAgIHJlc3VsdHMsXG4gICAgVVRDT2Zmc2V0LFxuICAgIGNsZWFudXBJbnN0YWxsYXRpb25zID0gcHJvY2Vzcy5lbnYuUEFSU0VfU0VSVkVSX0NMRUFOVVBfSU5WQUxJRF9JTlNUQUxMQVRJT05TXG4gICkge1xuICAgIGNvbnN0IHVwZGF0ZSA9IHtcbiAgICAgIG51bVNlbnQ6IDAsXG4gICAgICBudW1GYWlsZWQ6IDAsXG4gICAgfTtcbiAgICBjb25zdCBkZXZpY2VzVG9SZW1vdmUgPSBbXTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShyZXN1bHRzKSkge1xuICAgICAgcmVzdWx0cyA9IGZsYXR0ZW4ocmVzdWx0cyk7XG4gICAgICByZXN1bHRzLnJlZHVjZSgobWVtbywgcmVzdWx0KSA9PiB7XG4gICAgICAgIC8vIENhbm5vdCBoYW5kbGUgdGhhdFxuICAgICAgICBpZiAoIXJlc3VsdCB8fCAhcmVzdWx0LmRldmljZSB8fCAhcmVzdWx0LmRldmljZS5kZXZpY2VUeXBlKSB7XG4gICAgICAgICAgcmV0dXJuIG1lbW87XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZGV2aWNlVHlwZSA9IHJlc3VsdC5kZXZpY2UuZGV2aWNlVHlwZTtcbiAgICAgICAgY29uc3Qga2V5ID0gcmVzdWx0LnRyYW5zbWl0dGVkXG4gICAgICAgICAgPyBgc2VudFBlclR5cGUuJHtkZXZpY2VUeXBlfWBcbiAgICAgICAgICA6IGBmYWlsZWRQZXJUeXBlLiR7ZGV2aWNlVHlwZX1gO1xuICAgICAgICBtZW1vW2tleV0gPSBpbmNyZW1lbnRPcChtZW1vLCBrZXkpO1xuICAgICAgICBpZiAodHlwZW9mIFVUQ09mZnNldCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICBjb25zdCBvZmZzZXRLZXkgPSByZXN1bHQudHJhbnNtaXR0ZWRcbiAgICAgICAgICAgID8gYHNlbnRQZXJVVENPZmZzZXQuJHtVVENPZmZzZXR9YFxuICAgICAgICAgICAgOiBgZmFpbGVkUGVyVVRDT2Zmc2V0LiR7VVRDT2Zmc2V0fWA7XG4gICAgICAgICAgbWVtb1tvZmZzZXRLZXldID0gaW5jcmVtZW50T3AobWVtbywgb2Zmc2V0S2V5KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVzdWx0LnRyYW5zbWl0dGVkKSB7XG4gICAgICAgICAgbWVtby5udW1TZW50Kys7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgcmVzdWx0ICYmXG4gICAgICAgICAgICByZXN1bHQucmVzcG9uc2UgJiZcbiAgICAgICAgICAgIHJlc3VsdC5yZXNwb25zZS5lcnJvciAmJlxuICAgICAgICAgICAgcmVzdWx0LmRldmljZSAmJlxuICAgICAgICAgICAgcmVzdWx0LmRldmljZS5kZXZpY2VUb2tlblxuICAgICAgICAgICkge1xuICAgICAgICAgICAgY29uc3QgdG9rZW4gPSByZXN1bHQuZGV2aWNlLmRldmljZVRva2VuO1xuICAgICAgICAgICAgY29uc3QgZXJyb3IgPSByZXN1bHQucmVzcG9uc2UuZXJyb3I7XG4gICAgICAgICAgICAvLyBHQ00gZXJyb3JzXG4gICAgICAgICAgICBpZiAoZXJyb3IgPT09ICdOb3RSZWdpc3RlcmVkJyB8fCBlcnJvciA9PT0gJ0ludmFsaWRSZWdpc3RyYXRpb24nKSB7XG4gICAgICAgICAgICAgIGRldmljZXNUb1JlbW92ZS5wdXNoKHRva2VuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEFQTlMgZXJyb3JzXG4gICAgICAgICAgICBpZiAoZXJyb3IgPT09ICdVbnJlZ2lzdGVyZWQnIHx8IGVycm9yID09PSAnQmFkRGV2aWNlVG9rZW4nKSB7XG4gICAgICAgICAgICAgIGRldmljZXNUb1JlbW92ZS5wdXNoKHRva2VuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgbWVtby5udW1GYWlsZWQrKztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWVtbztcbiAgICAgIH0sIHVwZGF0ZSk7XG4gICAgfVxuXG4gICAgbG9nZ2VyLnZlcmJvc2UoXG4gICAgICBgX1B1c2hTdGF0dXMgJHtvYmplY3RJZH06IHNlbnQgcHVzaCEgJWQgc3VjY2VzcywgJWQgZmFpbHVyZXNgLFxuICAgICAgdXBkYXRlLm51bVNlbnQsXG4gICAgICB1cGRhdGUubnVtRmFpbGVkXG4gICAgKTtcbiAgICBsb2dnZXIudmVyYm9zZShgX1B1c2hTdGF0dXMgJHtvYmplY3RJZH06IG5lZWRzIGNsZWFudXBgLCB7XG4gICAgICBkZXZpY2VzVG9SZW1vdmUsXG4gICAgfSk7XG4gICAgWydudW1TZW50JywgJ251bUZhaWxlZCddLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGlmICh1cGRhdGVba2V5XSA+IDApIHtcbiAgICAgICAgdXBkYXRlW2tleV0gPSB7XG4gICAgICAgICAgX19vcDogJ0luY3JlbWVudCcsXG4gICAgICAgICAgYW1vdW50OiB1cGRhdGVba2V5XSxcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlbGV0ZSB1cGRhdGVba2V5XTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmIChkZXZpY2VzVG9SZW1vdmUubGVuZ3RoID4gMCAmJiBjbGVhbnVwSW5zdGFsbGF0aW9ucykge1xuICAgICAgbG9nZ2VyLmluZm8oYFJlbW92aW5nIGRldmljZSB0b2tlbnMgb24gJHtkZXZpY2VzVG9SZW1vdmUubGVuZ3RofSBfSW5zdGFsbGF0aW9uc2ApO1xuICAgICAgZGF0YWJhc2UudXBkYXRlKFxuICAgICAgICAnX0luc3RhbGxhdGlvbicsXG4gICAgICAgIHsgZGV2aWNlVG9rZW46IHsgJGluOiBkZXZpY2VzVG9SZW1vdmUgfSB9LFxuICAgICAgICB7IGRldmljZVRva2VuOiB7IF9fb3A6ICdEZWxldGUnIH0gfSxcbiAgICAgICAge1xuICAgICAgICAgIGFjbDogdW5kZWZpbmVkLFxuICAgICAgICAgIG1hbnk6IHRydWUsXG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gaW5kaWNhdGUgdGhpcyBiYXRjaCBpcyBjb21wbGV0ZVxuICAgIGluY3JlbWVudE9wKHVwZGF0ZSwgJ2NvdW50JywgLTEpO1xuXG4gICAgcmV0dXJuIGhhbmRsZXIudXBkYXRlKHsgb2JqZWN0SWQgfSwgdXBkYXRlKS50aGVuKHJlcyA9PiB7XG4gICAgICBpZiAocmVzICYmIHJlcy5jb3VudCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb21wbGV0ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9O1xuXG4gIGNvbnN0IGNvbXBsZXRlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBoYW5kbGVyLnVwZGF0ZShcbiAgICAgIHsgb2JqZWN0SWQgfSxcbiAgICAgIHtcbiAgICAgICAgc3RhdHVzOiAnc3VjY2VlZGVkJyxcbiAgICAgICAgY291bnQ6IHsgX19vcDogJ0RlbGV0ZScgfSxcbiAgICAgIH1cbiAgICApO1xuICB9O1xuXG4gIGNvbnN0IGZhaWwgPSBmdW5jdGlvbiAoZXJyKSB7XG4gICAgaWYgKHR5cGVvZiBlcnIgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlcnIgPSB7IG1lc3NhZ2U6IGVyciB9O1xuICAgIH1cbiAgICBjb25zdCB1cGRhdGUgPSB7XG4gICAgICBlcnJvck1lc3NhZ2U6IGVycixcbiAgICAgIHN0YXR1czogJ2ZhaWxlZCcsXG4gICAgfTtcbiAgICByZXR1cm4gaGFuZGxlci51cGRhdGUoeyBvYmplY3RJZCB9LCB1cGRhdGUpO1xuICB9O1xuXG4gIGNvbnN0IHJ2YWwgPSB7XG4gICAgc2V0SW5pdGlhbCxcbiAgICBzZXRSdW5uaW5nLFxuICAgIHRyYWNrU2VudCxcbiAgICBjb21wbGV0ZSxcbiAgICBmYWlsLFxuICB9O1xuXG4gIC8vIGRlZmluZSBvYmplY3RJZCB0byBiZSBkeW5hbWljXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShydmFsLCAnb2JqZWN0SWQnLCB7XG4gICAgZ2V0OiAoKSA9PiBvYmplY3RJZCxcbiAgfSk7XG5cbiAgcmV0dXJuIE9iamVjdC5mcmVlemUocnZhbCk7XG59XG4iXX0=
377
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9TdGF0dXNIYW5kbGVyLmpzIl0sIm5hbWVzIjpbIlBVU0hfU1RBVFVTX0NPTExFQ1RJT04iLCJKT0JfU1RBVFVTX0NPTExFQ1RJT04iLCJwdXNoUHJvbWlzZVF1ZXVlIiwiS2V5UHJvbWlzZVF1ZXVlIiwiam9iUHJvbWlzZVF1ZXVlIiwiaW5jcmVtZW50T3AiLCJvYmplY3QiLCJrZXkiLCJhbW91bnQiLCJfX29wIiwiZmxhdHRlbiIsImFycmF5IiwiZmxhdHRlbmVkIiwiaSIsImxlbmd0aCIsIkFycmF5IiwiaXNBcnJheSIsImNvbmNhdCIsInB1c2giLCJzdGF0dXNIYW5kbGVyIiwiY2xhc3NOYW1lIiwiZGF0YWJhc2UiLCJjcmVhdGUiLCJ0aGVuIiwiUHJvbWlzZSIsInJlc29sdmUiLCJ1cGRhdGUiLCJ3aGVyZSIsImVucXVldWUiLCJvYmplY3RJZCIsIk9iamVjdCIsImZyZWV6ZSIsInJlc3RTdGF0dXNIYW5kbGVyIiwiY29uZmlnIiwiYXV0aCIsIkF1dGgiLCJtYXN0ZXIiLCJyZXN0IiwicmVzcG9uc2UiLCJqb2JTdGF0dXNIYW5kbGVyIiwiam9iU3RhdHVzIiwib2JqZWN0SWRTaXplIiwiaGFuZGxlciIsInNldFJ1bm5pbmciLCJqb2JOYW1lIiwicGFyYW1zIiwibm93IiwiRGF0ZSIsInN0YXR1cyIsInNvdXJjZSIsImNyZWF0ZWRBdCIsIkFDTCIsInNldE1lc3NhZ2UiLCJtZXNzYWdlIiwic2V0U3VjY2VlZGVkIiwic2V0RmluYWxTdGF0dXMiLCJzZXRGYWlsZWQiLCJ1bmRlZmluZWQiLCJmaW5pc2hlZEF0IiwiRXJyb3IiLCJwdXNoU3RhdHVzSGFuZGxlciIsImV4aXN0aW5nT2JqZWN0SWQiLCJwdXNoU3RhdHVzIiwic2V0SW5pdGlhbCIsImJvZHkiLCJvcHRpb25zIiwicHVzaFRpbWUiLCJ0b0lTT1N0cmluZyIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImhhc1B1c2hTY2hlZHVsZWRTdXBwb3J0IiwicHVzaF90aW1lIiwibG9nZ2VyIiwid2FybiIsImRhdGEiLCJwYXlsb2FkU3RyaW5nIiwiSlNPTiIsInN0cmluZ2lmeSIsInB1c2hIYXNoIiwiYWxlcnQiLCJxdWVyeSIsInBheWxvYWQiLCJ0aXRsZSIsImV4cGlyeSIsImV4cGlyYXRpb25fdGltZSIsImV4cGlyYXRpb25faW50ZXJ2YWwiLCJudW1TZW50IiwicmVzdWx0IiwiYmF0Y2hlcyIsInZlcmJvc2UiLCJjb3VudCIsInRyYWNrU2VudCIsInJlc3VsdHMiLCJVVENPZmZzZXQiLCJjbGVhbnVwSW5zdGFsbGF0aW9ucyIsInByb2Nlc3MiLCJlbnYiLCJQQVJTRV9TRVJWRVJfQ0xFQU5VUF9JTlZBTElEX0lOU1RBTExBVElPTlMiLCJudW1GYWlsZWQiLCJkZXZpY2VzVG9SZW1vdmUiLCJyZWR1Y2UiLCJtZW1vIiwiZGV2aWNlIiwiZGV2aWNlVHlwZSIsInRyYW5zbWl0dGVkIiwib2Zmc2V0S2V5IiwiZXJyb3IiLCJkZXZpY2VUb2tlbiIsInRva2VuIiwiZm9yRWFjaCIsImluZm8iLCIkaW4iLCJhY2wiLCJtYW55IiwicmVzIiwiY29tcGxldGUiLCJmYWlsIiwiZXJyIiwiZXJyb3JNZXNzYWdlIiwicnZhbCIsImRlZmluZVByb3BlcnR5IiwiZ2V0Il0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7OztBQUVBLE1BQU1BLHNCQUFzQixHQUFHLGFBQS9CO0FBQ0EsTUFBTUMscUJBQXFCLEdBQUcsWUFBOUI7QUFFQSxNQUFNQyxnQkFBZ0IsR0FBRyxJQUFJQyxnQ0FBSixFQUF6QjtBQUNBLE1BQU1DLGVBQWUsR0FBRyxJQUFJRCxnQ0FBSixFQUF4Qjs7QUFFQSxNQUFNRSxXQUFXLEdBQUcsVUFBVUMsTUFBTSxHQUFHLEVBQW5CLEVBQXVCQyxHQUF2QixFQUE0QkMsTUFBTSxHQUFHLENBQXJDLEVBQXdDO0FBQzFELE1BQUksQ0FBQ0YsTUFBTSxDQUFDQyxHQUFELENBQVgsRUFBa0I7QUFDaEJELElBQUFBLE1B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cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgbWQ1SGFzaCwgbmV3T2JqZWN0SWQgfSBmcm9tICcuL2NyeXB0b1V0aWxzJztcbmltcG9ydCB7IEtleVByb21pc2VRdWV1ZSB9IGZyb20gJy4vS2V5UHJvbWlzZVF1ZXVlJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4vbG9nZ2VyJztcbmltcG9ydCByZXN0IGZyb20gJy4vcmVzdCc7XG5pbXBvcnQgQXV0aCBmcm9tICcuL0F1dGgnO1xuXG5jb25zdCBQVVNIX1NUQVRVU19DT0xMRUNUSU9OID0gJ19QdXNoU3RhdHVzJztcbmNvbnN0IEpPQl9TVEFUVVNfQ09MTEVDVElPTiA9ICdfSm9iU3RhdHVzJztcblxuY29uc3QgcHVzaFByb21pc2VRdWV1ZSA9IG5ldyBLZXlQcm9taXNlUXVldWUoKTtcbmNvbnN0IGpvYlByb21pc2VRdWV1ZSA9IG5ldyBLZXlQcm9taXNlUXVldWUoKTtcblxuY29uc3QgaW5jcmVtZW50T3AgPSBmdW5jdGlvbiAob2JqZWN0ID0ge30sIGtleSwgYW1vdW50ID0gMSkge1xuICBpZiAoIW9iamVjdFtrZXldKSB7XG4gICAgb2JqZWN0W2tleV0gPSB7IF9fb3A6ICdJbmNyZW1lbnQnLCBhbW91bnQ6IGFtb3VudCB9O1xuICB9IGVsc2Uge1xuICAgIG9iamVjdFtrZXldLmFtb3VudCArPSBhbW91bnQ7XG4gIH1cbiAgcmV0dXJuIG9iamVjdFtrZXldO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGZsYXR0ZW4oYXJyYXkpIHtcbiAgdmFyIGZsYXR0ZW5lZCA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoYXJyYXlbaV0pKSB7XG4gICAgICBmbGF0dGVuZWQgPSBmbGF0dGVuZWQuY29uY2F0KGZsYXR0ZW4oYXJyYXlbaV0pKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZmxhdHRlbmVkLnB1c2goYXJyYXlbaV0pO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmxhdHRlbmVkO1xufVxuXG5mdW5jdGlvbiBzdGF0dXNIYW5kbGVyKGNsYXNzTmFtZSwgZGF0YWJhc2UpIHtcbiAgZnVuY3Rpb24gY3JlYXRlKG9iamVjdCkge1xuICAgIHJldHVybiBkYXRhYmFzZS5jcmVhdGUoY2xhc3NOYW1lLCBvYmplY3QpLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShvYmplY3QpO1xuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlKHdoZXJlLCBvYmplY3QpIHtcbiAgICByZXR1cm4gam9iUHJvbWlzZVF1ZXVlLmVucXVldWUod2hlcmUub2JqZWN0SWQsICgpID0+IGRhdGFiYXNlLnVwZGF0ZShjbGFzc05hbWUsIHdoZXJlLCBvYmplY3QpKTtcbiAgfVxuXG4gIHJldHVybiBPYmplY3QuZnJlZXplKHtcbiAgICBjcmVhdGUsXG4gICAgdXBkYXRlLFxuICB9KTtcbn1cblxuZnVuY3Rpb24gcmVzdFN0YXR1c0hhbmRsZXIoY2xhc3NOYW1lLCBjb25maWcpIHtcbiAgY29uc3QgYXV0aCA9IEF1dGgubWFzdGVyKGNvbmZpZyk7XG4gIGZ1bmN0aW9uIGNyZWF0ZShvYmplY3QpIHtcbiAgICByZXR1cm4gcmVzdC5jcmVhdGUoY29uZmlnLCBhdXRoLCBjbGFzc05hbWUsIG9iamVjdCkudGhlbigoeyByZXNwb25zZSB9KSA9PiB7XG4gICAgICByZXR1cm4geyAuLi5vYmplY3QsIC4uLnJlc3BvbnNlIH07XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGUod2hlcmUsIG9iamVjdCkge1xuICAgIHJldHVybiBwdXNoUHJvbWlzZVF1ZXVlLmVucXVldWUod2hlcmUub2JqZWN0SWQsICgpID0+XG4gICAgICByZXN0XG4gICAgICAgIC51cGRhdGUoY29uZmlnLCBhdXRoLCBjbGFzc05hbWUsIHsgb2JqZWN0SWQ6IHdoZXJlLm9iamVjdElkIH0sIG9iamVjdClcbiAgICAgICAgLnRoZW4oKHsgcmVzcG9uc2UgfSkgPT4ge1xuICAgICAgICAgIHJldHVybiB7IC4uLm9iamVjdCwgLi4ucmVzcG9uc2UgfTtcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgcmV0dXJuIE9iamVjdC5mcmVlemUoe1xuICAgIGNyZWF0ZSxcbiAgICB1cGRhdGUsXG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gam9iU3RhdHVzSGFuZGxlcihjb25maWcpIHtcbiAgbGV0IGpvYlN0YXR1cztcbiAgY29uc3Qgb2JqZWN0SWQgPSBuZXdPYmplY3RJZChjb25maWcub2JqZWN0SWRTaXplKTtcbiAgY29uc3QgZGF0YWJhc2UgPSBjb25maWcuZGF0YWJhc2U7XG4gIGNvbnN0IGhhbmRsZXIgPSBzdGF0dXNIYW5kbGVyKEpPQl9TVEFUVVNfQ09MTEVDVElPTiwgZGF0YWJhc2UpO1xuICBjb25zdCBzZXRSdW5uaW5nID0gZnVuY3Rpb24gKGpvYk5hbWUsIHBhcmFtcykge1xuICAgIGNvbnN0IG5vdyA9IG5ldyBEYXRlKCk7XG4gICAgam9iU3RhdHVzID0ge1xuICAgICAgb2JqZWN0SWQsXG4gICAgICBqb2JOYW1lLFxuICAgICAgcGFyYW1zLFxuICAgICAgc3RhdHVzOiAncnVubmluZycsXG4gICAgICBzb3VyY2U6ICdhcGknLFxuICAgICAgY3JlYXRlZEF0OiBub3csXG4gICAgICAvLyBsb2NrZG93biFcbiAgICAgIEFDTDoge30sXG4gICAgfTtcblxuICAgIHJldHVybiBoYW5kbGVyLmNyZWF0ZShqb2JTdGF0dXMpO1xuICB9O1xuXG4gIGNvbnN0IHNldE1lc3NhZ2UgPSBmdW5jdGlvbiAobWVzc2FnZSkge1xuICAgIGlmICghbWVzc2FnZSB8fCB0eXBlb2YgbWVzc2FnZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG4gICAgcmV0dXJuIGhhbmRsZXIudXBkYXRlKHsgb2JqZWN0SWQgfSwgeyBtZXNzYWdlIH0pO1xuICB9O1xuXG4gIGNvbnN0IHNldFN1Y2NlZWRlZCA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XG4gICAgcmV0dXJuIHNldEZpbmFsU3RhdHVzKCdzdWNjZWVkZWQnLCBtZXNzYWdlKTtcbiAgfTtcblxuICBjb25zdCBzZXRGYWlsZWQgPSBmdW5jdGlvbiAobWVzc2FnZSkge1xuICAgIHJldHVybiBzZXRGaW5hbFN0YXR1cygnZmFpbGVkJywgbWVzc2FnZSk7XG4gIH07XG5cbiAgY29uc3Qgc2V0RmluYWxTdGF0dXMgPSBmdW5jdGlvbiAoc3RhdHVzLCBtZXNzYWdlID0gdW5kZWZpbmVkKSB7XG4gICAgY29uc3QgZmluaXNoZWRBdCA9IG5ldyBEYXRlKCk7XG4gICAgY29uc3QgdXBkYXRlID0geyBzdGF0dXMsIGZpbmlzaGVkQXQgfTtcbiAgICBpZiAobWVzc2FnZSAmJiB0eXBlb2YgbWVzc2FnZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHVwZGF0ZS5tZXNzYWdlID0gbWVzc2FnZTtcbiAgICB9XG4gICAgaWYgKG1lc3NhZ2UgaW5zdGFuY2VvZiBFcnJvciAmJiB0eXBlb2YgbWVzc2FnZS5tZXNzYWdlID09PSAnc3RyaW5nJykge1xuICAgICAgdXBkYXRlLm1lc3NhZ2UgPSBtZXNzYWdlLm1lc3NhZ2U7XG4gICAgfVxuICAgIHJldHVybiBoYW5kbGVyLnVwZGF0ZSh7IG9iamVjdElkIH0sIHVwZGF0ZSk7XG4gIH07XG5cbiAgcmV0dXJuIE9iamVjdC5mcmVlemUoe1xuICAgIHNldFJ1bm5pbmcsXG4gICAgc2V0U3VjY2VlZGVkLFxuICAgIHNldE1lc3NhZ2UsXG4gICAgc2V0RmFpbGVkLFxuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHB1c2hTdGF0dXNIYW5kbGVyKGNvbmZpZywgZXhpc3RpbmdPYmplY3RJZCkge1xuICBsZXQgcHVzaFN0YXR1cztcbiAgY29uc3QgZGF0YWJhc2UgPSBjb25maWcuZGF0YWJhc2U7XG4gIGNvbnN0IGhhbmRsZXIgPSByZXN0U3RhdHVzSGFuZGxlcihQVVNIX1NUQVRVU19DT0xMRUNUSU9OLCBjb25maWcpO1xuICBsZXQgb2JqZWN0SWQgPSBleGlzdGluZ09iamVjdElkO1xuICBjb25zdCBzZXRJbml0aWFsID0gZnVuY3Rpb24gKGJvZHkgPSB7fSwgd2hlcmUsIG9wdGlvbnMgPSB7IHNvdXJjZTogJ3Jlc3QnIH0pIHtcbiAgICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpO1xuICAgIGxldCBwdXNoVGltZSA9IG5vdy50b0lTT1N0cmluZygpO1xuICAgIGxldCBzdGF0dXMgPSAncGVuZGluZyc7XG4gICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChib2R5LCAncHVzaF90aW1lJykpIHtcbiAgICAgIGlmIChjb25maWcuaGFzUHVzaFNjaGVkdWxlZFN1cHBvcnQpIHtcbiAgICAgICAgcHVzaFRpbWUgPSBib2R5LnB1c2hfdGltZTtcbiAgICAgICAgc3RhdHVzID0gJ3NjaGVkdWxlZCc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2dnZXIud2FybignVHJ5aW5nIHRvIHNjaGVkdWxlIGEgcHVzaCB3aGlsZSBzZXJ2ZXIgaXMgbm90IGNvbmZpZ3VyZWQuJyk7XG4gICAgICAgIGxvZ2dlci53YXJuKCdQdXNoIHdpbGwgYmUgc2VudCBpbW1lZGlhdGVseScpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGRhdGEgPSBib2R5LmRhdGEgfHwge307XG4gICAgY29uc3QgcGF5bG9hZFN0cmluZyA9IEpTT04uc3RyaW5naWZ5KGRhdGEpO1xuICAgIGxldCBwdXNoSGFzaDtcbiAgICBpZiAodHlwZW9mIGRhdGEuYWxlcnQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBwdXNoSGFzaCA9IG1kNUhhc2goZGF0YS5hbGVydCk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZGF0YS5hbGVydCA9PT0gJ29iamVjdCcpIHtcbiAgICAgIHB1c2hIYXNoID0gbWQ1SGFzaChKU09OLnN0cmluZ2lmeShkYXRhLmFsZXJ0KSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHB1c2hIYXNoID0gJ2Q0MWQ4Y2Q5OGYwMGIyMDRlOTgwMDk5OGVjZjg0MjdlJztcbiAgICB9XG4gICAgY29uc3Qgb2JqZWN0ID0ge1xuICAgICAgcHVzaFRpbWUsXG4gICAgICBxdWVyeTogSlNPTi5zdHJpbmdpZnkod2hlcmUpLFxuICAgICAgcGF5bG9hZDogcGF5bG9hZFN0cmluZyxcbiAgICAgIHNvdXJjZTogb3B0aW9ucy5zb3VyY2UsXG4gICAgICB0aXRsZTogb3B0aW9ucy50aXRsZSxcbiAgICAgIGV4cGlyeTogYm9keS5leHBpcmF0aW9uX3RpbWUsXG4gICAgICBleHBpcmF0aW9uX2ludGVydmFsOiBib2R5LmV4cGlyYXRpb25faW50ZXJ2YWwsXG4gICAgICBzdGF0dXM6IHN0YXR1cyxcbiAgICAgIG51bVNlbnQ6IDAsXG4gICAgICBwdXNoSGFzaCxcbiAgICAgIC8vIGxvY2tkb3duIVxuICAgICAgQUNMOiB7fSxcbiAgICB9O1xuICAgIHJldHVybiBoYW5kbGVyLmNyZWF0ZShvYmplY3QpLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgIG9iamVjdElkID0gcmVzdWx0Lm9iamVjdElkO1xuICAgICAgcHVzaFN0YXR1cyA9IHtcbiAgICAgICAgb2JqZWN0SWQsXG4gICAgICB9O1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShwdXNoU3RhdHVzKTtcbiAgICB9KTtcbiAgfTtcblxuICBjb25zdCBzZXRSdW5uaW5nID0gZnVuY3Rpb24gKGJhdGNoZXMpIHtcbiAgICBsb2dnZXIudmVyYm9zZShcbiAgICAgIGBfUHVzaFN0YXR1cyAke29iamVjdElkfTogc2VuZGluZyBwdXNoIHRvIGluc3RhbGxhdGlvbnMgd2l0aCAlZCBiYXRjaGVzYCxcbiAgICAgIGJhdGNoZXNcbiAgICApO1xuICAgIHJldHVybiBoYW5kbGVyLnVwZGF0ZShcbiAgICAgIHtcbiAgICAgICAgc3RhdHVzOiAncGVuZGluZycsXG4gICAgICAgIG9iamVjdElkOiBvYmplY3RJZCxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIHN0YXR1czogJ3J1bm5pbmcnLFxuICAgICAgICBjb3VudDogYmF0Y2hlcyxcbiAgICAgIH1cbiAgICApO1xuICB9O1xuXG4gIGNvbnN0IHRyYWNrU2VudCA9IGZ1bmN0aW9uIChcbiAgICByZXN1bHRzLFxuICAgIFVUQ09mZnNldCxcbiAgICBjbGVhbnVwSW5zdGFsbGF0aW9ucyA9IHByb2Nlc3MuZW52LlBBUlNFX1NFUlZFUl9DTEVBTlVQX0lOVkFMSURfSU5TVEFMTEFUSU9OU1xuICApIHtcbiAgICBjb25zdCB1cGRhdGUgPSB7XG4gICAgICBudW1TZW50OiAwLFxuICAgICAgbnVtRmFpbGVkOiAwLFxuICAgIH07XG4gICAgY29uc3QgZGV2aWNlc1RvUmVtb3ZlID0gW107XG4gICAgaWYgKEFycmF5LmlzQXJyYXkocmVzdWx0cykpIHtcbiAgICAgIHJlc3VsdHMgPSBmbGF0dGVuKHJlc3VsdHMpO1xuICAgICAgcmVzdWx0cy5yZWR1Y2UoKG1lbW8sIHJlc3VsdCkgPT4ge1xuICAgICAgICAvLyBDYW5ub3QgaGFuZGxlIHRoYXRcbiAgICAgICAgaWYgKCFyZXN1bHQgfHwgIXJlc3VsdC5kZXZpY2UgfHwgIXJlc3VsdC5kZXZpY2UuZGV2aWNlVHlwZSkge1xuICAgICAgICAgIHJldHVybiBtZW1vO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGRldmljZVR5cGUgPSByZXN1bHQuZGV2aWNlLmRldmljZVR5cGU7XG4gICAgICAgIGNvbnN0IGtleSA9IHJlc3VsdC50cmFuc21pdHRlZFxuICAgICAgICAgID8gYHNlbnRQZXJUeXBlLiR7ZGV2aWNlVHlwZX1gXG4gICAgICAgICAgOiBgZmFpbGVkUGVyVHlwZS4ke2RldmljZVR5cGV9YDtcbiAgICAgICAgbWVtb1trZXldID0gaW5jcmVtZW50T3AobWVtbywga2V5KTtcbiAgICAgICAgaWYgKHR5cGVvZiBVVENPZmZzZXQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgY29uc3Qgb2Zmc2V0S2V5ID0gcmVzdWx0LnRyYW5zbWl0dGVkXG4gICAgICAgICAgICA/IGBzZW50UGVyVVRDT2Zmc2V0LiR7VVRDT2Zmc2V0fWBcbiAgICAgICAgICAgIDogYGZhaWxlZFBlclVUQ09mZnNldC4ke1VUQ09mZnNldH1gO1xuICAgICAgICAgIG1lbW9bb2Zmc2V0S2V5XSA9IGluY3JlbWVudE9wKG1lbW8sIG9mZnNldEtleSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlc3VsdC50cmFuc21pdHRlZCkge1xuICAgICAgICAgIG1lbW8ubnVtU2VudCsrO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHJlc3VsdCAmJlxuICAgICAgICAgICAgcmVzdWx0LnJlc3BvbnNlICYmXG4gICAgICAgICAgICByZXN1bHQucmVzcG9uc2UuZXJyb3IgJiZcbiAgICAgICAgICAgIHJlc3VsdC5kZXZpY2UgJiZcbiAgICAgICAgICAgIHJlc3VsdC5kZXZpY2UuZGV2aWNlVG9rZW5cbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbnN0IHRva2VuID0gcmVzdWx0LmRldmljZS5kZXZpY2VUb2tlbjtcbiAgICAgICAgICAgIGNvbnN0IGVycm9yID0gcmVzdWx0LnJlc3BvbnNlLmVycm9yO1xuICAgICAgICAgICAgLy8gR0NNIGVycm9yc1xuICAgICAgICAgICAgaWYgKGVycm9yID09PSAnTm90UmVnaXN0ZXJlZCcgfHwgZXJyb3IgPT09ICdJbnZhbGlkUmVnaXN0cmF0aW9uJykge1xuICAgICAgICAgICAgICBkZXZpY2VzVG9SZW1vdmUucHVzaCh0b2tlbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBBUE5TIGVycm9yc1xuICAgICAgICAgICAgaWYgKGVycm9yID09PSAnVW5yZWdpc3RlcmVkJyB8fCBlcnJvciA9PT0gJ0JhZERldmljZVRva2VuJykge1xuICAgICAgICAgICAgICBkZXZpY2VzVG9SZW1vdmUucHVzaCh0b2tlbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIG1lbW8ubnVtRmFpbGVkKys7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1lbW87XG4gICAgICB9LCB1cGRhdGUpO1xuICAgIH1cblxuICAgIGxvZ2dlci52ZXJib3NlKFxuICAgICAgYF9QdXNoU3RhdHVzICR7b2JqZWN0SWR9OiBzZW50IHB1c2ghICVkIHN1Y2Nlc3MsICVkIGZhaWx1cmVzYCxcbiAgICAgIHVwZGF0ZS5udW1TZW50LFxuICAgICAgdXBkYXRlLm51bUZhaWxlZFxuICAgICk7XG4gICAgbG9nZ2VyLnZlcmJvc2UoYF9QdXNoU3RhdHVzICR7b2JqZWN0SWR9OiBuZWVkcyBjbGVhbnVwYCwge1xuICAgICAgZGV2aWNlc1RvUmVtb3ZlLFxuICAgIH0pO1xuICAgIFsnbnVtU2VudCcsICdudW1GYWlsZWQnXS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICBpZiAodXBkYXRlW2tleV0gPiAwKSB7XG4gICAgICAgIHVwZGF0ZVtrZXldID0ge1xuICAgICAgICAgIF9fb3A6ICdJbmNyZW1lbnQnLFxuICAgICAgICAgIGFtb3VudDogdXBkYXRlW2tleV0sXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkZWxldGUgdXBkYXRlW2tleV07XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpZiAoZGV2aWNlc1RvUmVtb3ZlLmxlbmd0aCA+IDAgJiYgY2xlYW51cEluc3RhbGxhdGlvbnMpIHtcbiAgICAgIGxvZ2dlci5pbmZvKGBSZW1vdmluZyBkZXZpY2UgdG9rZW5zIG9uICR7ZGV2aWNlc1RvUmVtb3ZlLmxlbmd0aH0gX0luc3RhbGxhdGlvbnNgKTtcbiAgICAgIGRhdGFiYXNlLnVwZGF0ZShcbiAgICAgICAgJ19JbnN0YWxsYXRpb24nLFxuICAgICAgICB7IGRldmljZVRva2VuOiB7ICRpbjogZGV2aWNlc1RvUmVtb3ZlIH0gfSxcbiAgICAgICAgeyBkZXZpY2VUb2tlbjogeyBfX29wOiAnRGVsZXRlJyB9IH0sXG4gICAgICAgIHtcbiAgICAgICAgICBhY2w6IHVuZGVmaW5lZCxcbiAgICAgICAgICBtYW55OiB0cnVlLFxuICAgICAgICB9XG4gICAgICApO1xuICAgIH1cbiAgICBpbmNyZW1lbnRPcCh1cGRhdGUsICdjb3VudCcsIC0xKTtcbiAgICB1cGRhdGUuc3RhdHVzID0gJ3J1bm5pbmcnO1xuXG4gICAgcmV0dXJuIGhhbmRsZXIudXBkYXRlKHsgb2JqZWN0SWQgfSwgdXBkYXRlKS50aGVuKHJlcyA9PiB7XG4gICAgICBpZiAocmVzICYmIHJlcy5jb3VudCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb21wbGV0ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9O1xuXG4gIGNvbnN0IGNvbXBsZXRlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBoYW5kbGVyLnVwZGF0ZShcbiAgICAgIHsgb2JqZWN0SWQgfSxcbiAgICAgIHtcbiAgICAgICAgc3RhdHVzOiAnc3VjY2VlZGVkJyxcbiAgICAgICAgY291bnQ6IHsgX19vcDogJ0RlbGV0ZScgfSxcbiAgICAgIH1cbiAgICApO1xuICB9O1xuXG4gIGNvbnN0IGZhaWwgPSBmdW5jdGlvbiAoZXJyKSB7XG4gICAgaWYgKHR5cGVvZiBlcnIgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlcnIgPSB7IG1lc3NhZ2U6IGVyciB9O1xuICAgIH1cbiAgICBjb25zdCB1cGRhdGUgPSB7XG4gICAgICBlcnJvck1lc3NhZ2U6IGVycixcbiAgICAgIHN0YXR1czogJ2ZhaWxlZCcsXG4gICAgfTtcbiAgICByZXR1cm4gaGFuZGxlci51cGRhdGUoeyBvYmplY3RJZCB9LCB1cGRhdGUpO1xuICB9O1xuXG4gIGNvbnN0IHJ2YWwgPSB7XG4gICAgc2V0SW5pdGlhbCxcbiAgICBzZXRSdW5uaW5nLFxuICAgIHRyYWNrU2VudCxcbiAgICBjb21wbGV0ZSxcbiAgICBmYWlsLFxuICB9O1xuXG4gIC8vIGRlZmluZSBvYmplY3RJZCB0byBiZSBkeW5hbWljXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShydmFsLCAnb2JqZWN0SWQnLCB7XG4gICAgZ2V0OiAoKSA9PiBvYmplY3RJZCxcbiAgfSk7XG5cbiAgcmV0dXJuIE9iamVjdC5mcmVlemUocnZhbCk7XG59XG4iXX0=
package/lib/TestUtils.js CHANGED
@@ -28,4 +28,4 @@ function destroyAllDataPermanently(fast) {
28
28
  }
29
29
  }));
30
30
  }
31
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9UZXN0VXRpbHMuanMiXSwibmFtZXMiOlsiZGVzdHJveUFsbERhdGFQZXJtYW5lbnRseSIsImZhc3QiLCJwcm9jZXNzIiwiZW52IiwiVEVTVElORyIsIlByb21pc2UiLCJhbGwiLCJPYmplY3QiLCJrZXlzIiwiQXBwQ2FjaGUiLCJjYWNoZSIsIm1hcCIsImFwcElkIiwiYXBwIiwiZ2V0IiwiZGF0YWJhc2VDb250cm9sbGVyIiwiZGVsZXRlRXZlcnl0aGluZyIsInJlc29sdmUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7OztBQUVBOzs7O0FBSU8sU0FBU0EseUJBQVQsQ0FBbUNDLElBQW5DLEVBQXlDO0FBQzlDLE1BQUksQ0FBQ0MsT0FBTyxDQUFDQyxHQUFSLENBQVlDLE9BQWpCLEVBQTBCO0FBQ3hCLFVBQU0sb0NBQU47QUFDRDs7QUFDRCxTQUFPQyxPQUFPLENBQUNDLEdBQVIsQ0FDTEMsTUFBTSxDQUFDQyxJQUFQLENBQVlDLGVBQVNDLEtBQXJCLEVBQTRCQyxHQUE1QixDQUFnQ0MsS0FBSyxJQUFJO0FBQ3ZDLFVBQU1DLEdBQUcsR0FBR0osZUFBU0ssR0FBVCxDQUFhRixLQUFiLENBQVo7O0FBQ0EsUUFBSUMsR0FBRyxDQUFDRSxrQkFBUixFQUE0QjtBQUMxQixhQUFPRixHQUFHLENBQUNFLGtCQUFKLENBQXVCQyxnQkFBdkIsQ0FBd0NmLElBQXhDLENBQVA7QUFDRCxLQUZELE1BRU87QUFDTCxhQUFPSSxPQUFPLENBQUNZLE9BQVIsRUFBUDtBQUNEO0FBQ0YsR0FQRCxDQURLLENBQVA7QUFVRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBBcHBDYWNoZSBmcm9tICcuL2NhY2hlJztcblxuLyoqXG4gKiBEZXN0cm95cyBhbGwgZGF0YSBpbiB0aGUgZGF0YWJhc2VcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gZmFzdCBzZXQgdG8gdHJ1ZSBpZiBpdCdzIG9rIHRvIGp1c3QgZHJvcCBvYmplY3RzIGFuZCBub3QgaW5kZXhlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlc3Ryb3lBbGxEYXRhUGVybWFuZW50bHkoZmFzdCkge1xuICBpZiAoIXByb2Nlc3MuZW52LlRFU1RJTkcpIHtcbiAgICB0aHJvdyAnT25seSBzdXBwb3J0ZWQgaW4gdGVzdCBlbnZpcm9ubWVudCc7XG4gIH1cbiAgcmV0dXJuIFByb21pc2UuYWxsKFxuICAgIE9iamVjdC5rZXlzKEFwcENhY2hlLmNhY2hlKS5tYXAoYXBwSWQgPT4ge1xuICAgICAgY29uc3QgYXBwID0gQXBwQ2FjaGUuZ2V0KGFwcElkKTtcbiAgICAgIGlmIChhcHAuZGF0YWJhc2VDb250cm9sbGVyKSB7XG4gICAgICAgIHJldHVybiBhcHAuZGF0YWJhc2VDb250cm9sbGVyLmRlbGV0ZUV2ZXJ5dGhpbmcoZmFzdCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICB9XG4gICAgfSlcbiAgKTtcbn1cbiJdfQ==
31
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9UZXN0VXRpbHMuanMiXSwibmFtZXMiOlsiZGVzdHJveUFsbERhdGFQZXJtYW5lbnRseSIsImZhc3QiLCJwcm9jZXNzIiwiZW52IiwiVEVTVElORyIsIlByb21pc2UiLCJhbGwiLCJPYmplY3QiLCJrZXlzIiwiQXBwQ2FjaGUiLCJjYWNoZSIsIm1hcCIsImFwcElkIiwiYXBwIiwiZ2V0IiwiZGF0YWJhc2VDb250cm9sbGVyIiwiZGVsZXRlRXZlcnl0aGluZyIsInJlc29sdmUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7OztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0EseUJBQVQsQ0FBbUNDLElBQW5DLEVBQXlDO0FBQzlDLE1BQUksQ0FBQ0MsT0FBTyxDQUFDQyxHQUFSLENBQVlDLE9BQWpCLEVBQTBCO0FBQ3hCLFVBQU0sb0NBQU47QUFDRDs7QUFDRCxTQUFPQyxPQUFPLENBQUNDLEdBQVIsQ0FDTEMsTUFBTSxDQUFDQyxJQUFQLENBQVlDLGVBQVNDLEtBQXJCLEVBQTRCQyxHQUE1QixDQUFnQ0MsS0FBSyxJQUFJO0FBQ3ZDLFVBQU1DLEdBQUcsR0FBR0osZUFBU0ssR0FBVCxDQUFhRixLQUFiLENBQVo7O0FBQ0EsUUFBSUMsR0FBRyxDQUFDRSxrQkFBUixFQUE0QjtBQUMxQixhQUFPRixHQUFHLENBQUNFLGtCQUFKLENBQXVCQyxnQkFBdkIsQ0FBd0NmLElBQXhDLENBQVA7QUFDRCxLQUZELE1BRU87QUFDTCxhQUFPSSxPQUFPLENBQUNZLE9BQVIsRUFBUDtBQUNEO0FBQ0YsR0FQRCxDQURLLENBQVA7QUFVRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBBcHBDYWNoZSBmcm9tICcuL2NhY2hlJztcblxuLyoqXG4gKiBEZXN0cm95cyBhbGwgZGF0YSBpbiB0aGUgZGF0YWJhc2VcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gZmFzdCBzZXQgdG8gdHJ1ZSBpZiBpdCdzIG9rIHRvIGp1c3QgZHJvcCBvYmplY3RzIGFuZCBub3QgaW5kZXhlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlc3Ryb3lBbGxEYXRhUGVybWFuZW50bHkoZmFzdCkge1xuICBpZiAoIXByb2Nlc3MuZW52LlRFU1RJTkcpIHtcbiAgICB0aHJvdyAnT25seSBzdXBwb3J0ZWQgaW4gdGVzdCBlbnZpcm9ubWVudCc7XG4gIH1cbiAgcmV0dXJuIFByb21pc2UuYWxsKFxuICAgIE9iamVjdC5rZXlzKEFwcENhY2hlLmNhY2hlKS5tYXAoYXBwSWQgPT4ge1xuICAgICAgY29uc3QgYXBwID0gQXBwQ2FjaGUuZ2V0KGFwcElkKTtcbiAgICAgIGlmIChhcHAuZGF0YWJhc2VDb250cm9sbGVyKSB7XG4gICAgICAgIHJldHVybiBhcHAuZGF0YWJhc2VDb250cm9sbGVyLmRlbGV0ZUV2ZXJ5dGhpbmcoZmFzdCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICB9XG4gICAgfSlcbiAgKTtcbn1cbiJdfQ==
package/lib/Utils.js ADDED
@@ -0,0 +1,226 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * utils.js
5
+ * @file General purpose utilities
6
+ * @description General purpose utilities.
7
+ */
8
+ const path = require('path');
9
+
10
+ const fs = require('fs').promises;
11
+ /**
12
+ * The general purpose utilities.
13
+ */
14
+
15
+
16
+ class Utils {
17
+ /**
18
+ * @function getLocalizedPath
19
+ * @description Returns a localized file path accoring to the locale.
20
+ *
21
+ * Localized files are searched in subfolders of a given path, e.g.
22
+ *
23
+ * root/
24
+ * ├── base/ // base path to files
25
+ * │ ├── example.html // default file
26
+ * │ └── de/ // de language folder
27
+ * │ │ └── example.html // de localized file
28
+ * │ └── de-AT/ // de-AT locale folder
29
+ * │ │ └── example.html // de-AT localized file
30
+ *
31
+ * Files are matched with the locale in the following order:
32
+ * 1. Locale match, e.g. locale `de-AT` matches file in folder `de-AT`.
33
+ * 2. Language match, e.g. locale `de-AT` matches file in folder `de`.
34
+ * 3. Default; file in base folder is returned.
35
+ *
36
+ * @param {String} defaultPath The absolute file path, which is also
37
+ * the default path returned if localization is not available.
38
+ * @param {String} locale The locale.
39
+ * @returns {Promise<Object>} The object contains:
40
+ * - `path`: The path to the localized file, or the original path if
41
+ * localization is not available.
42
+ * - `subdir`: The subdirectory of the localized file, or undefined if
43
+ * there is no matching localized file.
44
+ */
45
+ static async getLocalizedPath(defaultPath, locale) {
46
+ // Get file name and paths
47
+ const file = path.basename(defaultPath);
48
+ const basePath = path.dirname(defaultPath); // If locale is not set return default file
49
+
50
+ if (!locale) {
51
+ return {
52
+ path: defaultPath
53
+ };
54
+ } // Check file for locale exists
55
+
56
+
57
+ const localePath = path.join(basePath, locale, file);
58
+ const localeFileExists = await Utils.fileExists(localePath); // If file for locale exists return file
59
+
60
+ if (localeFileExists) {
61
+ return {
62
+ path: localePath,
63
+ subdir: locale
64
+ };
65
+ } // Check file for language exists
66
+
67
+
68
+ const language = locale.split('-')[0];
69
+ const languagePath = path.join(basePath, language, file);
70
+ const languageFileExists = await Utils.fileExists(languagePath); // If file for language exists return file
71
+
72
+ if (languageFileExists) {
73
+ return {
74
+ path: languagePath,
75
+ subdir: language
76
+ };
77
+ } // Return default file
78
+
79
+
80
+ return {
81
+ path: defaultPath
82
+ };
83
+ }
84
+ /**
85
+ * @function fileExists
86
+ * @description Checks whether a file exists.
87
+ * @param {String} path The file path.
88
+ * @returns {Promise<Boolean>} Is true if the file can be accessed, false otherwise.
89
+ */
90
+
91
+
92
+ static async fileExists(path) {
93
+ try {
94
+ await fs.access(path);
95
+ return true;
96
+ } catch (e) {
97
+ return false;
98
+ }
99
+ }
100
+ /**
101
+ * @function isPath
102
+ * @description Evaluates whether a string is a file path (as opposed to a URL for example).
103
+ * @param {String} s The string to evaluate.
104
+ * @returns {Boolean} Returns true if the evaluated string is a path.
105
+ */
106
+
107
+
108
+ static isPath(s) {
109
+ return /(^\/)|(^\.\/)|(^\.\.\/)/.test(s);
110
+ }
111
+ /**
112
+ * Flattens an object and crates new keys with custom delimiters.
113
+ * @param {Object} obj The object to flatten.
114
+ * @param {String} [delimiter='.'] The delimiter of the newly generated keys.
115
+ * @param {Object} result
116
+ * @returns {Object} The flattened object.
117
+ **/
118
+
119
+
120
+ static flattenObject(obj, parentKey, delimiter = '.', result = {}) {
121
+ for (const key in obj) {
122
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
123
+ const newKey = parentKey ? parentKey + delimiter + key : key;
124
+
125
+ if (typeof obj[key] === 'object' && obj[key] !== null) {
126
+ this.flattenObject(obj[key], newKey, delimiter, result);
127
+ } else {
128
+ result[newKey] = obj[key];
129
+ }
130
+ }
131
+ }
132
+
133
+ return result;
134
+ }
135
+ /**
136
+ * Determines whether an object is a Promise.
137
+ * @param {any} object The object to validate.
138
+ * @returns {Boolean} Returns true if the object is a promise.
139
+ */
140
+
141
+
142
+ static isPromise(object) {
143
+ return object instanceof Promise;
144
+ }
145
+ /**
146
+ * Creates an object with all permutations of the original keys.
147
+ * For example, this definition:
148
+ * ```
149
+ * {
150
+ * a: [true, false],
151
+ * b: [1, 2],
152
+ * c: ['x']
153
+ * }
154
+ * ```
155
+ * permutates to:
156
+ * ```
157
+ * [
158
+ * { a: true, b: 1, c: 'x' },
159
+ * { a: true, b: 2, c: 'x' },
160
+ * { a: false, b: 1, c: 'x' },
161
+ * { a: false, b: 2, c: 'x' }
162
+ * ]
163
+ * ```
164
+ * @param {Object} object The object to permutate.
165
+ * @param {Integer} [index=0] The current key index.
166
+ * @param {Object} [current={}] The current result entry being composed.
167
+ * @param {Array} [results=[]] The resulting array of permutations.
168
+ */
169
+
170
+
171
+ static getObjectKeyPermutations(object, index = 0, current = {}, results = []) {
172
+ const keys = Object.keys(object);
173
+ const key = keys[index];
174
+ const values = object[key];
175
+
176
+ for (const value of values) {
177
+ current[key] = value;
178
+ const nextIndex = index + 1;
179
+
180
+ if (nextIndex < keys.length) {
181
+ Utils.getObjectKeyPermutations(object, nextIndex, current, results);
182
+ } else {
183
+ const result = Object.assign({}, current);
184
+ results.push(result);
185
+ }
186
+ }
187
+
188
+ return results;
189
+ }
190
+ /**
191
+ * Validates parameters and throws if a parameter is invalid.
192
+ * Example parameter types syntax:
193
+ * ```
194
+ * {
195
+ * parameterName: {
196
+ * t: 'boolean',
197
+ * v: isBoolean,
198
+ * o: true
199
+ * },
200
+ * ...
201
+ * }
202
+ * ```
203
+ * @param {Object} params The parameters to validate.
204
+ * @param {Array<Object>} types The parameter types used for validation.
205
+ * @param {Object} types.t The parameter type; used for error message, not for validation.
206
+ * @param {Object} types.v The function to validate the parameter value.
207
+ * @param {Boolean} [types.o=false] Is true if the parameter is optional.
208
+ */
209
+
210
+
211
+ static validateParams(params, types) {
212
+ for (const key of Object.keys(params)) {
213
+ const type = types[key];
214
+ const isOptional = !!type.o;
215
+ const param = params[key];
216
+
217
+ if (!(isOptional && param == null) && !type.v(param)) {
218
+ throw `Invalid parameter ${key} must be of type ${type.t} but is ${typeof param}`;
219
+ }
220
+ }
221
+ }
222
+
223
+ }
224
+
225
+ module.exports = Utils;
226
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9VdGlscy5qcyJdLCJuYW1lcyI6WyJwYXRoIiwicmVxdWlyZSIsImZzIiwicHJvbWlzZXMiLCJVdGlscyIsImdldExvY2FsaXplZFBhdGgiLCJkZWZhdWx0UGF0aCIsImxvY2FsZSIsImZpbGUiLCJiYXNlbmFtZSIsImJhc2VQYXRoIiwiZGlybmFtZSIsImxvY2FsZVBhdGgiLCJqb2luIiwibG9jYWxlRmlsZUV4aXN0cyIsImZpbGVFeGlzdHMiLCJzdWJkaXIiLCJsYW5ndWFnZSIsInNwbGl0IiwibGFuZ3VhZ2VQYXRoIiwibGFuZ3VhZ2VGaWxlRXhpc3RzIiwiYWNjZXNzIiwiZSIsImlzUGF0aCIsInMiLCJ0ZXN0IiwiZmxhdHRlbk9iamVjdCIsIm9iaiIsInBhcmVudEtleSIsImRlbGltaXRlciIsInJlc3VsdCIsImtleSIsIk9iamVjdCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsIm5ld0tleSIsImlzUHJvbWlzZSIsIm9iamVjdCIsIlByb21pc2UiLCJnZXRPYmplY3RLZXlQZXJtdXRhdGlvbnMiLCJpbmRleCIsImN1cnJlbnQiLCJyZXN1bHRzIiwia2V5cyIsInZhbHVlcyIsInZhbHVlIiwibmV4dEluZGV4IiwibGVuZ3RoIiwiYXNzaWduIiwicHVzaCIsInZhbGlkYXRlUGFyYW1zIiwicGFyYW1zIiwidHlwZXMiLCJ0eXBlIiwiaXNPcHRpb25hbCIsIm8iLCJwYXJhbSIsInYiLCJ0IiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUEsTUFBTUEsSUFBSSxHQUFHQyxPQUFPLENBQUMsTUFBRCxDQUFwQjs7QUFDQSxNQUFNQyxFQUFFLEdBQUdELE9BQU8sQ0FBQyxJQUFELENBQVAsQ0FBY0UsUUFBekI7QUFFQTtBQUNBO0FBQ0E7OztBQUNBLE1BQU1DLEtBQU4sQ0FBWTtBQUNWO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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Q0wsY0FBTWIsTUFBTSxHQUFHRSxNQUFNLENBQUNpQixNQUFQLENBQWMsRUFBZCxFQUFrQlAsT0FBbEIsQ0FBZjtBQUNBQyxRQUFBQSxPQUFPLENBQUNPLElBQVIsQ0FBYXBCLE1BQWI7QUFDRDtBQUNGOztBQUNELFdBQU9hLE9BQVA7QUFDRDtBQUVEO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDdUIsU0FBZFEsY0FBYyxDQUFDQyxNQUFELEVBQVNDLEtBQVQsRUFBZ0I7QUFDbkMsU0FBSyxNQUFNdEIsR0FBWCxJQUFrQkMsTUFBTSxDQUFDWSxJQUFQLENBQVlRLE1BQVosQ0FBbEIsRUFBdUM7QUFDckMsWUFBTUUsSUFBSSxHQUFHRCxLQUFLLENBQUN0QixHQUFELENBQWxCO0FBQ0EsWUFBTXdCLFVBQVUsR0FBRyxDQUFDLENBQUNELElBQUksQ0FBQ0UsQ0FBMUI7QUFDQSxZQUFNQyxLQUFLLEdBQUdMLE1BQU0sQ0FBQ3JCLEdBQUQsQ0FBcEI7O0FBQ0EsVUFBSSxFQUFFd0IsVUFBVSxJQUFJRSxLQUFLLElBQUksSUFBekIsS0FBa0MsQ0FBQ0gsSUFBSSxDQUFDSSxDQUFMLENBQU9ELEtBQVAsQ0FBdkMsRUFBc0Q7QUFDcEQsY0FBTyxxQkFBb0IxQixHQUFJLG9CQUFtQnVCLElBQUksQ0FBQ0ssQ0FBRSxXQUFVLE9BQU9GLEtBQU0sRUFBaEY7QUFDRDtBQUNGO0FBQ0Y7O0FBN0xTOztBQWdNWkcsTUFBTSxDQUFDQyxPQUFQLEdBQWlCekQsS0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIHV0aWxzLmpzXG4gKiBAZmlsZSBHZW5lcmFsIHB1cnBvc2UgdXRpbGl0aWVzXG4gKiBAZGVzY3JpcHRpb24gR2VuZXJhbCBwdXJwb3NlIHV0aWxpdGllcy5cbiAqL1xuXG5jb25zdCBwYXRoID0gcmVxdWlyZSgncGF0aCcpO1xuY29uc3QgZnMgPSByZXF1aXJlKCdmcycpLnByb21pc2VzO1xuXG4vKipcbiAqIFRoZSBnZW5lcmFsIHB1cnBvc2UgdXRpbGl0aWVzLlxuICovXG5jbGFzcyBVdGlscyB7XG4gIC8qKlxuICAgKiBAZnVuY3Rpb24gZ2V0TG9jYWxpemVkUGF0aFxuICAgKiBAZGVzY3JpcHRpb24gUmV0dXJucyBhIGxvY2FsaXplZCBmaWxlIHBhdGggYWNjb3JpbmcgdG8gdGhlIGxvY2FsZS5cbiAgICpcbiAgICogTG9jYWxpemVkIGZpbGVzIGFyZSBzZWFyY2hlZCBpbiBzdWJmb2xkZXJzIG9mIGEgZ2l2ZW4gcGF0aCwgZS5nLlxuICAgKlxuICAgKiByb290L1xuICAgKiDilJzilIDilIAgYmFzZS8gICAgICAgICAgICAgICAgICAgIC8vIGJhc2UgcGF0aCB0byBmaWxlc1xuICAgKiDilIIgICDilJzilIDilIAgZXhhbXBsZS5odG1sICAgICAgICAgLy8gZGVmYXVsdCBmaWxlXG4gICAqIOKUgiAgIOKUlOKUgOKUgCBkZS8gICAgICAgICAgICAgICAgICAvLyBkZSBsYW5ndWFnZSBmb2xkZXJcbiAgICog4pSCICAg4pSCICAg4pSU4pSA4pSAIGV4YW1wbGUuaHRtbCAgICAgLy8gZGUgbG9jYWxpemVkIGZpbGVcbiAgICog4pSCICAg4pSU4pSA4pSAIGRlLUFULyAgICAgICAgICAgICAgIC8vIGRlLUFUIGxvY2FsZSBmb2xkZXJcbiAgICog4pSCICAg4pSCICAg4pSU4pSA4pSAIGV4YW1wbGUuaHRtbCAgICAgLy8gZGUtQVQgbG9jYWxpemVkIGZpbGVcbiAgICpcbiAgICogRmlsZXMgYXJlIG1hdGNoZWQgd2l0aCB0aGUgbG9jYWxlIGluIHRoZSBmb2xsb3dpbmcgb3JkZXI6XG4gICAqIDEuIExvY2FsZSBtYXRjaCwgZS5nLiBsb2NhbGUgYGRlLUFUYCBtYXRjaGVzIGZpbGUgaW4gZm9sZGVyIGBkZS1BVGAuXG4gICAqIDIuIExhbmd1YWdlIG1hdGNoLCBlLmcuIGxvY2FsZSBgZGUtQVRgIG1hdGNoZXMgZmlsZSBpbiBmb2xkZXIgYGRlYC5cbiAgICogMy4gRGVmYXVsdDsgZmlsZSBpbiBiYXNlIGZvbGRlciBpcyByZXR1cm5lZC5cbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IGRlZmF1bHRQYXRoIFRoZSBhYnNvbHV0ZSBmaWxlIHBhdGgsIHdoaWNoIGlzIGFsc29cbiAgICogdGhlIGRlZmF1bHQgcGF0aCByZXR1cm5lZCBpZiBsb2NhbGl6YXRpb24gaXMgbm90IGF2YWlsYWJsZS5cbiAgICogQHBhcmFtIHtTdHJpbmd9IGxvY2FsZSBUaGUgbG9jYWxlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxPYmplY3Q+fSBUaGUgb2JqZWN0IGNvbnRhaW5zOlxuICAgKiAtIGBwYXRoYDogVGhlIHBhdGggdG8gdGhlIGxvY2FsaXplZCBmaWxlLCBvciB0aGUgb3JpZ2luYWwgcGF0aCBpZlxuICAgKiAgIGxvY2FsaXphdGlvbiBpcyBub3QgYXZhaWxhYmxlLlxuICAgKiAtIGBzdWJkaXJgOiBUaGUgc3ViZGlyZWN0b3J5IG9mIHRoZSBsb2NhbGl6ZWQgZmlsZSwgb3IgdW5kZWZpbmVkIGlmXG4gICAqICAgdGhlcmUgaXMgbm8gbWF0Y2hpbmcgbG9jYWxpemVkIGZpbGUuXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgZ2V0TG9jYWxpemVkUGF0aChkZWZhdWx0UGF0aCwgbG9jYWxlKSB7XG4gICAgLy8gR2V0IGZpbGUgbmFtZSBhbmQgcGF0aHNcbiAgICBjb25zdCBmaWxlID0gcGF0aC5iYXNlbmFtZShkZWZhdWx0UGF0aCk7XG4gICAgY29uc3QgYmFzZVBhdGggPSBwYXRoLmRpcm5hbWUoZGVmYXVsdFBhdGgpO1xuXG4gICAgLy8gSWYgbG9jYWxlIGlzIG5vdCBzZXQgcmV0dXJuIGRlZmF1bHQgZmlsZVxuICAgIGlmICghbG9jYWxlKSB7XG4gICAgICByZXR1cm4geyBwYXRoOiBkZWZhdWx0UGF0aCB9O1xuICAgIH1cblxuICAgIC8vIENoZWNrIGZpbGUgZm9yIGxvY2FsZSBleGlzdHNcbiAgICBjb25zdCBsb2NhbGVQYXRoID0gcGF0aC5qb2luKGJhc2VQYXRoLCBsb2NhbGUsIGZpbGUpO1xuICAgIGNvbnN0IGxvY2FsZUZpbGVFeGlzdHMgPSBhd2FpdCBVdGlscy5maWxlRXhpc3RzKGxvY2FsZVBhdGgpO1xuXG4gICAgLy8gSWYgZmlsZSBmb3IgbG9jYWxlIGV4aXN0cyByZXR1cm4gZmlsZVxuICAgIGlmIChsb2NhbGVGaWxlRXhpc3RzKSB7XG4gICAgICByZXR1cm4geyBwYXRoOiBsb2NhbGVQYXRoLCBzdWJkaXI6IGxvY2FsZSB9O1xuICAgIH1cblxuICAgIC8vIENoZWNrIGZpbGUgZm9yIGxhbmd1YWdlIGV4aXN0c1xuICAgIGNvbnN0IGxhbmd1YWdlID0gbG9jYWxlLnNwbGl0KCctJylbMF07XG4gICAgY29uc3QgbGFuZ3VhZ2VQYXRoID0gcGF0aC5qb2luKGJhc2VQYXRoLCBsYW5ndWFnZSwgZmlsZSk7XG4gICAgY29uc3QgbGFuZ3VhZ2VGaWxlRXhpc3RzID0gYXdhaXQgVXRpbHMuZmlsZUV4aXN0cyhsYW5ndWFnZVBhdGgpO1xuXG4gICAgLy8gSWYgZmlsZSBmb3IgbGFuZ3VhZ2UgZXhpc3RzIHJldHVybiBmaWxlXG4gICAgaWYgKGxhbmd1YWdlRmlsZUV4aXN0cykge1xuICAgICAgcmV0dXJuIHsgcGF0aDogbGFuZ3VhZ2VQYXRoLCBzdWJkaXI6IGxhbmd1YWdlIH07XG4gICAgfVxuXG4gICAgLy8gUmV0dXJuIGRlZmF1bHQgZmlsZVxuICAgIHJldHVybiB7IHBhdGg6IGRlZmF1bHRQYXRoIH07XG4gIH1cblxuICAvKipcbiAgICogQGZ1bmN0aW9uIGZpbGVFeGlzdHNcbiAgICogQGRlc2NyaXB0aW9uIENoZWNrcyB3aGV0aGVyIGEgZmlsZSBleGlzdHMuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwYXRoIFRoZSBmaWxlIHBhdGguXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPEJvb2xlYW4+fSBJcyB0cnVlIGlmIHRoZSBmaWxlIGNhbiBiZSBhY2Nlc3NlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICAgKi9cbiAgc3RhdGljIGFzeW5jIGZpbGVFeGlzdHMocGF0aCkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBmcy5hY2Nlc3MocGF0aCk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBmdW5jdGlvbiBpc1BhdGhcbiAgICogQGRlc2NyaXB0aW9uIEV2YWx1YXRlcyB3aGV0aGVyIGEgc3RyaW5nIGlzIGEgZmlsZSBwYXRoIChhcyBvcHBvc2VkIHRvIGEgVVJMIGZvciBleGFtcGxlKS5cbiAgICogQHBhcmFtIHtTdHJpbmd9IHMgVGhlIHN0cmluZyB0byBldmFsdWF0ZS5cbiAgICogQHJldHVybnMge0Jvb2xlYW59IFJldHVybnMgdHJ1ZSBpZiB0aGUgZXZhbHVhdGVkIHN0cmluZyBpcyBhIHBhdGguXG4gICAqL1xuICBzdGF0aWMgaXNQYXRoKHMpIHtcbiAgICByZXR1cm4gLyheXFwvKXwoXlxcLlxcLyl8KF5cXC5cXC5cXC8pLy50ZXN0KHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZsYXR0ZW5zIGFuIG9iamVjdCBhbmQgY3JhdGVzIG5ldyBrZXlzIHdpdGggY3VzdG9tIGRlbGltaXRlcnMuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmogVGhlIG9iamVjdCB0byBmbGF0dGVuLlxuICAgKiBAcGFyYW0ge1N0cmluZ30gW2RlbGltaXRlcj0nLiddIFRoZSBkZWxpbWl0ZXIgb2YgdGhlIG5ld2x5IGdlbmVyYXRlZCBrZXlzLlxuICAgKiBAcGFyYW0ge09iamVjdH0gcmVzdWx0XG4gICAqIEByZXR1cm5zIHtPYmplY3R9IFRoZSBmbGF0dGVuZWQgb2JqZWN0LlxuICAgKiovXG4gIHN0YXRpYyBmbGF0dGVuT2JqZWN0KG9iaiwgcGFyZW50S2V5LCBkZWxpbWl0ZXIgPSAnLicsIHJlc3VsdCA9IHt9KSB7XG4gICAgZm9yIChjb25zdCBrZXkgaW4gb2JqKSB7XG4gICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkge1xuICAgICAgICBjb25zdCBuZXdLZXkgPSBwYXJlbnRLZXkgPyBwYXJlbnRLZXkgKyBkZWxpbWl0ZXIgKyBrZXkgOiBrZXk7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBvYmpba2V5XSA9PT0gJ29iamVjdCcgJiYgb2JqW2tleV0gIT09IG51bGwpIHtcbiAgICAgICAgICB0aGlzLmZsYXR0ZW5PYmplY3Qob2JqW2tleV0sIG5ld0tleSwgZGVsaW1pdGVyLCByZXN1bHQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlc3VsdFtuZXdLZXldID0gb2JqW2tleV07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgYW4gb2JqZWN0IGlzIGEgUHJvbWlzZS5cbiAgICogQHBhcmFtIHthbnl9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHZhbGlkYXRlLlxuICAgKiBAcmV0dXJucyB7Qm9vbGVhbn0gUmV0dXJucyB0cnVlIGlmIHRoZSBvYmplY3QgaXMgYSBwcm9taXNlLlxuICAgKi9cbiAgc3RhdGljIGlzUHJvbWlzZShvYmplY3QpIHtcbiAgICByZXR1cm4gb2JqZWN0IGluc3RhbmNlb2YgUHJvbWlzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIG9iamVjdCB3aXRoIGFsbCBwZXJtdXRhdGlvbnMgb2YgdGhlIG9yaWdpbmFsIGtleXMuXG4gICAqIEZvciBleGFtcGxlLCB0aGlzIGRlZmluaXRpb246XG4gICAqIGBgYFxuICAgKiB7XG4gICAqICAgYTogW3RydWUsIGZhbHNlXSxcbiAgICogICBiOiBbMSwgMl0sXG4gICAqICAgYzogWyd4J11cbiAgICogfVxuICAgKiBgYGBcbiAgICogcGVybXV0YXRlcyB0bzpcbiAgICogYGBgXG4gICAqIFtcbiAgICogICB7IGE6IHRydWUsIGI6IDEsIGM6ICd4JyB9LFxuICAgKiAgIHsgYTogdHJ1ZSwgYjogMiwgYzogJ3gnIH0sXG4gICAqICAgeyBhOiBmYWxzZSwgYjogMSwgYzogJ3gnIH0sXG4gICAqICAgeyBhOiBmYWxzZSwgYjogMiwgYzogJ3gnIH1cbiAgICogXVxuICAgKiBgYGBcbiAgICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHBlcm11dGF0ZS5cbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBbaW5kZXg9MF0gVGhlIGN1cnJlbnQga2V5IGluZGV4LlxuICAgKiBAcGFyYW0ge09iamVjdH0gW2N1cnJlbnQ9e31dIFRoZSBjdXJyZW50IHJlc3VsdCBlbnRyeSBiZWluZyBjb21wb3NlZC5cbiAgICogQHBhcmFtIHtBcnJheX0gW3Jlc3VsdHM9W11dIFRoZSByZXN1bHRpbmcgYXJyYXkgb2YgcGVybXV0YXRpb25zLlxuICAgKi9cbiAgc3RhdGljIGdldE9iamVjdEtleVBlcm11dGF0aW9ucyhvYmplY3QsIGluZGV4ID0gMCwgY3VycmVudCA9IHt9LCByZXN1bHRzID0gW10pIHtcbiAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMob2JqZWN0KTtcbiAgICBjb25zdCBrZXkgPSBrZXlzW2luZGV4XTtcbiAgICBjb25zdCB2YWx1ZXMgPSBvYmplY3Rba2V5XTtcblxuICAgIGZvciAoY29uc3QgdmFsdWUgb2YgdmFsdWVzKSB7XG4gICAgICBjdXJyZW50W2tleV0gPSB2YWx1ZTtcbiAgICAgIGNvbnN0IG5leHRJbmRleCA9IGluZGV4ICsgMTtcblxuICAgICAgaWYgKG5leHRJbmRleCA8IGtleXMubGVuZ3RoKSB7XG4gICAgICAgIFV0aWxzLmdldE9iamVjdEtleVBlcm11dGF0aW9ucyhvYmplY3QsIG5leHRJbmRleCwgY3VycmVudCwgcmVzdWx0cyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBPYmplY3QuYXNzaWduKHt9LCBjdXJyZW50KTtcbiAgICAgICAgcmVzdWx0cy5wdXNoKHJlc3VsdCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHRzO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyBwYXJhbWV0ZXJzIGFuZCB0aHJvd3MgaWYgYSBwYXJhbWV0ZXIgaXMgaW52YWxpZC5cbiAgICogRXhhbXBsZSBwYXJhbWV0ZXIgdHlwZXMgc3ludGF4OlxuICAgKiBgYGBcbiAgICoge1xuICAgKiAgIHBhcmFtZXRlck5hbWU6IHtcbiAgICogICAgICB0OiAnYm9vbGVhbicsXG4gICAqICAgICAgdjogaXNCb29sZWFuLFxuICAgKiAgICAgIG86IHRydWVcbiAgICogICB9LFxuICAgKiAgIC4uLlxuICAgKiB9XG4gICAqIGBgYFxuICAgKiBAcGFyYW0ge09iamVjdH0gcGFyYW1zIFRoZSBwYXJhbWV0ZXJzIHRvIHZhbGlkYXRlLlxuICAgKiBAcGFyYW0ge0FycmF5PE9iamVjdD59IHR5cGVzIFRoZSBwYXJhbWV0ZXIgdHlwZXMgdXNlZCBmb3IgdmFsaWRhdGlvbi5cbiAgICogQHBhcmFtIHtPYmplY3R9IHR5cGVzLnQgVGhlIHBhcmFtZXRlciB0eXBlOyB1c2VkIGZvciBlcnJvciBtZXNzYWdlLCBub3QgZm9yIHZhbGlkYXRpb24uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSB0eXBlcy52IFRoZSBmdW5jdGlvbiB0byB2YWxpZGF0ZSB0aGUgcGFyYW1ldGVyIHZhbHVlLlxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IFt0eXBlcy5vPWZhbHNlXSBJcyB0cnVlIGlmIHRoZSBwYXJhbWV0ZXIgaXMgb3B0aW9uYWwuXG4gICAqL1xuICBzdGF0aWMgdmFsaWRhdGVQYXJhbXMocGFyYW1zLCB0eXBlcykge1xuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHBhcmFtcykpIHtcbiAgICAgIGNvbnN0IHR5cGUgPSB0eXBlc1trZXldO1xuICAgICAgY29uc3QgaXNPcHRpb25hbCA9ICEhdHlwZS5vO1xuICAgICAgY29uc3QgcGFyYW0gPSBwYXJhbXNba2V5XTtcbiAgICAgIGlmICghKGlzT3B0aW9uYWwgJiYgcGFyYW0gPT0gbnVsbCkgJiYgIXR5cGUudihwYXJhbSkpIHtcbiAgICAgICAgdGhyb3cgYEludmFsaWQgcGFyYW1ldGVyICR7a2V5fSBtdXN0IGJlIG9mIHR5cGUgJHt0eXBlLnR9IGJ1dCBpcyAke3R5cGVvZiBwYXJhbX1gO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFV0aWxzO1xuIl19