@payloadcms/plugin-stripe 0.0.15-beta.0 → 0.0.16-beta.1

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 (52) hide show
  1. package/README.md +36 -36
  2. package/dist/admin.js +33 -32
  3. package/dist/extendWebpackConfig.js +28 -26
  4. package/dist/fields/getFields.js +36 -42
  5. package/dist/hooks/createNewInStripe.js +82 -124
  6. package/dist/hooks/deleteFromStripe.js +44 -87
  7. package/dist/hooks/syncExistingWithStripe.js +55 -93
  8. package/dist/index.js +109 -135
  9. package/dist/routes/rest.js +35 -76
  10. package/dist/routes/webhooks.js +59 -94
  11. package/dist/types.js +5 -2
  12. package/dist/ui/LinkToDoc.js +43 -31
  13. package/dist/utilities/deepen.js +20 -17
  14. package/dist/utilities/stripeProxy.js +52 -88
  15. package/dist/webhooks/handleCreatedOrUpdated.js +125 -196
  16. package/dist/webhooks/handleDeleted.js +53 -102
  17. package/dist/webhooks/index.js +55 -89
  18. package/package.json +13 -26
  19. package/types.d.ts +1 -1
  20. package/types.js +1 -1
  21. package/dist/admin.d.ts +0 -3
  22. package/dist/admin.js.map +0 -1
  23. package/dist/extendWebpackConfig.d.ts +0 -3
  24. package/dist/extendWebpackConfig.js.map +0 -1
  25. package/dist/fields/getFields.d.ts +0 -11
  26. package/dist/fields/getFields.js.map +0 -1
  27. package/dist/hooks/createNewInStripe.d.ts +0 -7
  28. package/dist/hooks/createNewInStripe.js.map +0 -1
  29. package/dist/hooks/deleteFromStripe.d.ts +0 -7
  30. package/dist/hooks/deleteFromStripe.js.map +0 -1
  31. package/dist/hooks/syncExistingWithStripe.d.ts +0 -7
  32. package/dist/hooks/syncExistingWithStripe.js.map +0 -1
  33. package/dist/index.d.ts +0 -3
  34. package/dist/index.js.map +0 -1
  35. package/dist/routes/rest.d.ts +0 -9
  36. package/dist/routes/rest.js.map +0 -1
  37. package/dist/routes/webhooks.d.ts +0 -11
  38. package/dist/routes/webhooks.js.map +0 -1
  39. package/dist/types.d.ts +0 -44
  40. package/dist/types.js.map +0 -1
  41. package/dist/ui/LinkToDoc.d.ts +0 -7
  42. package/dist/ui/LinkToDoc.js.map +0 -1
  43. package/dist/utilities/deepen.d.ts +0 -1
  44. package/dist/utilities/deepen.js.map +0 -1
  45. package/dist/utilities/stripeProxy.d.ts +0 -2
  46. package/dist/utilities/stripeProxy.js.map +0 -1
  47. package/dist/webhooks/handleCreatedOrUpdated.d.ts +0 -7
  48. package/dist/webhooks/handleCreatedOrUpdated.js.map +0 -1
  49. package/dist/webhooks/handleDeleted.d.ts +0 -7
  50. package/dist/webhooks/handleDeleted.js.map +0 -1
  51. package/dist/webhooks/index.d.ts +0 -2
  52. package/dist/webhooks/index.js.map +0 -1
@@ -1,201 +1,130 @@
1
1
  "use strict";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
- return new (P || (P = Promise))(function (resolve, reject) {
16
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
- step((generator = generator.apply(thisArg, _arguments || [])).next());
20
- });
21
- };
22
- var __generator = (this && this.__generator) || function (thisArg, body) {
23
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
- function verb(n) { return function (v) { return step([n, v]); }; }
26
- function step(op) {
27
- if (f) throw new TypeError("Generator is already executing.");
28
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
29
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
- if (y = 0, t) op = [op[0] & 2, t.value];
31
- switch (op[0]) {
32
- case 0: case 1: t = op; break;
33
- case 4: _.label++; return { value: op[1], done: false };
34
- case 5: _.label++; y = op[1]; op = [0]; continue;
35
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
- default:
37
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
- if (t[2]) _.ops.pop();
42
- _.trys.pop(); continue;
43
- }
44
- op = body.call(thisArg, _);
45
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "handleCreatedOrUpdated", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return handleCreatedOrUpdated;
47
9
  }
48
- };
49
- Object.defineProperty(exports, "__esModule", { value: true });
50
- exports.handleCreatedOrUpdated = void 0;
51
- var uuid_1 = require("uuid");
52
- var deepen_1 = require("../utilities/deepen");
53
- var handleCreatedOrUpdated = function (args) { return __awaiter(void 0, void 0, void 0, function () {
54
- var payload, event, resourceType, stripeConfig, payloadConfig, syncConfig, logs, stripeDoc, stripeID, eventObject, isNestedChange, collectionSlug_1, isAuthCollection, payloadQuery, foundDoc, syncedData, authDoc, authQuery, err_1, msg, error_1, msg, password, error_2, msg, error_3, msg;
55
- var _a, _b, _c;
56
- return __generator(this, function (_d) {
57
- switch (_d.label) {
58
- case 0:
59
- payload = args.payload, event = args.event, resourceType = args.resourceType, stripeConfig = args.stripeConfig, payloadConfig = args.config, syncConfig = args.syncConfig;
60
- logs = (stripeConfig || {}).logs;
61
- stripeDoc = ((_a = event === null || event === void 0 ? void 0 : event.data) === null || _a === void 0 ? void 0 : _a.object) || {};
62
- stripeID = stripeDoc.id, eventObject = stripeDoc.object;
63
- isNestedChange = eventObject !== resourceType;
64
- // let stripeID = docID;
65
- // if (isNestedChange) {
66
- // const parentResource = stripeDoc[resourceType];
67
- // stripeID = parentResource;
68
- // }
69
- if (isNestedChange) {
70
- if (logs)
71
- payload.logger.info("- This change occurred on a nested field of ".concat(resourceType, ". Nested fields are not yet supported in auto-sync but can be manually setup."));
10
+ });
11
+ const _uuid = require("uuid");
12
+ const _deepen = require("../utilities/deepen");
13
+ const handleCreatedOrUpdated = async (args)=>{
14
+ const { config: payloadConfig, event, payload, resourceType, stripeConfig, syncConfig } = args;
15
+ const { logs } = stripeConfig || {};
16
+ const stripeDoc = event?.data?.object || {};
17
+ const { id: stripeID, object: eventObject } = stripeDoc;
18
+ // NOTE: the Stripe API does not nest fields, everything is an object at the top level
19
+ // if the event object and resource type don't match, this change was not top-level
20
+ const isNestedChange = eventObject !== resourceType;
21
+ // let stripeID = docID;
22
+ // if (isNestedChange) {
23
+ // const parentResource = stripeDoc[resourceType];
24
+ // stripeID = parentResource;
25
+ // }
26
+ if (isNestedChange) {
27
+ if (logs) payload.logger.info(`- This change occurred on a nested field of ${resourceType}. Nested fields are not yet supported in auto-sync but can be manually setup.`);
28
+ }
29
+ if (!isNestedChange) {
30
+ if (logs) payload.logger.info(`- A new document was created or updated in Stripe, now syncing to Payload...`);
31
+ const collectionSlug = syncConfig?.collection;
32
+ const isAuthCollection = Boolean(payloadConfig?.collections?.find((collection)=>collection.slug === collectionSlug)?.auth);
33
+ // First, search for an existing document in Payload
34
+ const payloadQuery = await payload.find({
35
+ collection: collectionSlug,
36
+ where: {
37
+ stripeID: {
38
+ equals: stripeID
72
39
  }
73
- if (!!isNestedChange) return [3 /*break*/, 20];
74
- if (logs)
75
- payload.logger.info("- A new document was created or updated in Stripe, now syncing to Payload...");
76
- collectionSlug_1 = syncConfig === null || syncConfig === void 0 ? void 0 : syncConfig.collection;
77
- isAuthCollection = Boolean((_c = (_b = payloadConfig === null || payloadConfig === void 0 ? void 0 : payloadConfig.collections) === null || _b === void 0 ? void 0 : _b.find(function (collection) { return collection.slug === collectionSlug_1; })) === null || _c === void 0 ? void 0 : _c.auth);
78
- return [4 /*yield*/, payload.find({
79
- collection: collectionSlug_1,
80
- where: {
81
- stripeID: {
82
- equals: stripeID,
83
- },
84
- },
85
- })];
86
- case 1:
87
- payloadQuery = _d.sent();
88
- foundDoc = payloadQuery.docs[0];
89
- syncedData = syncConfig.fields.reduce(function (acc, field) {
90
- var fieldPath = field.fieldPath, stripeProperty = field.stripeProperty;
91
- acc[fieldPath] = stripeDoc[stripeProperty];
92
- return acc;
93
- }, {});
94
- syncedData = (0, deepen_1.deepen)(__assign(__assign({}, syncedData), { stripeID: stripeID, skipSync: true }));
95
- if (!!foundDoc) return [3 /*break*/, 16];
96
- if (logs)
97
- payload.logger.info("- No existing '".concat(collectionSlug_1, "' document found with Stripe ID: '").concat(stripeID, "', creating new..."));
98
- authDoc = null;
99
- if (!isAuthCollection) return [3 /*break*/, 11];
100
- _d.label = 2;
101
- case 2:
102
- _d.trys.push([2, 10, , 11]);
103
- if (!(stripeDoc === null || stripeDoc === void 0 ? void 0 : stripeDoc.email)) return [3 /*break*/, 8];
104
- return [4 /*yield*/, payload.find({
105
- collection: collectionSlug_1,
106
- where: {
107
- email: {
108
- equals: stripeDoc.email,
109
- },
40
+ }
41
+ });
42
+ const foundDoc = payloadQuery.docs[0];
43
+ // combine all properties of the Stripe doc and match their respective fields within the document
44
+ let syncedData = syncConfig.fields.reduce((acc, field)=>{
45
+ const { fieldPath, stripeProperty } = field;
46
+ acc[fieldPath] = stripeDoc[stripeProperty];
47
+ return acc;
48
+ }, {});
49
+ syncedData = (0, _deepen.deepen)({
50
+ ...syncedData,
51
+ skipSync: true,
52
+ stripeID
53
+ });
54
+ if (!foundDoc) {
55
+ if (logs) payload.logger.info(`- No existing '${collectionSlug}' document found with Stripe ID: '${stripeID}', creating new...`);
56
+ // auth docs must use unique emails
57
+ let authDoc = null;
58
+ if (isAuthCollection) {
59
+ try {
60
+ if (stripeDoc?.email) {
61
+ const authQuery = await payload.find({
62
+ collection: collectionSlug,
63
+ where: {
64
+ email: {
65
+ equals: stripeDoc.email
66
+ }
67
+ }
68
+ });
69
+ authDoc = authQuery.docs[0];
70
+ if (authDoc) {
71
+ if (logs) payload.logger.info(`- Account already exists with e-mail: ${stripeDoc.email}, updating now...`);
72
+ // account exists by email, so update it instead
73
+ try {
74
+ await payload.update({
75
+ id: authDoc.id,
76
+ collection: collectionSlug,
77
+ data: syncedData
78
+ });
79
+ if (logs) payload.logger.info(`✅ Successfully updated '${collectionSlug}' document in Payload with ID: '${authDoc.id}.'`);
80
+ } catch (err) {
81
+ const msg = err instanceof Error ? err.message : err;
82
+ if (logs) payload.logger.error(`- Error updating existing '${collectionSlug}' document: ${msg}`);
83
+ }
84
+ }
85
+ } else {
86
+ if (logs) payload.logger.error(`No email was provided from Stripe, cannot create new '${collectionSlug}' document.`);
87
+ }
88
+ } catch (error) {
89
+ const msg = error instanceof Error ? error.message : error;
90
+ if (logs) payload.logger.error(`Error looking up '${collectionSlug}' document in Payload: ${msg}`);
91
+ }
92
+ }
93
+ if (!isAuthCollection || isAuthCollection && !authDoc) {
94
+ try {
95
+ if (logs) payload.logger.info(`- Creating new '${collectionSlug}' document in Payload with Stripe ID: '${stripeID}'.`);
96
+ // generate a strong, unique password for the new user
97
+ const password = (0, _uuid.v4)();
98
+ await payload.create({
99
+ collection: collectionSlug,
100
+ data: {
101
+ ...syncedData,
102
+ password,
103
+ passwordConfirm: password
110
104
  },
111
- })];
112
- case 3:
113
- authQuery = _d.sent();
114
- authDoc = authQuery.docs[0];
115
- if (!authDoc) return [3 /*break*/, 7];
116
- if (logs)
117
- payload.logger.info("- Account already exists with e-mail: ".concat(stripeDoc.email, ", updating now..."));
118
- _d.label = 4;
119
- case 4:
120
- _d.trys.push([4, 6, , 7]);
121
- return [4 /*yield*/, payload.update({
122
- collection: collectionSlug_1,
123
- id: authDoc.id,
124
- data: syncedData,
125
- })];
126
- case 5:
127
- _d.sent();
128
- if (logs)
129
- payload.logger.info("\u2705 Successfully updated '".concat(collectionSlug_1, "' document in Payload with ID: '").concat(authDoc.id, ".'"));
130
- return [3 /*break*/, 7];
131
- case 6:
132
- err_1 = _d.sent();
133
- msg = err_1 instanceof Error ? err_1.message : err_1;
134
- if (logs)
135
- payload.logger.error("- Error updating existing '".concat(collectionSlug_1, "' document: ").concat(msg));
136
- return [3 /*break*/, 7];
137
- case 7: return [3 /*break*/, 9];
138
- case 8:
139
- if (logs)
140
- payload.logger.error("No email was provided from Stripe, cannot create new '".concat(collectionSlug_1, "' document."));
141
- _d.label = 9;
142
- case 9: return [3 /*break*/, 11];
143
- case 10:
144
- error_1 = _d.sent();
145
- msg = error_1 instanceof Error ? error_1.message : error_1;
146
- if (logs)
147
- payload.logger.error("Error looking up '".concat(collectionSlug_1, "' document in Payload: ").concat(msg));
148
- return [3 /*break*/, 11];
149
- case 11:
150
- if (!(!isAuthCollection || (isAuthCollection && !authDoc))) return [3 /*break*/, 15];
151
- _d.label = 12;
152
- case 12:
153
- _d.trys.push([12, 14, , 15]);
154
- if (logs)
155
- payload.logger.info("- Creating new '".concat(collectionSlug_1, "' document in Payload with Stripe ID: '").concat(stripeID, "'."));
156
- password = (0, uuid_1.v4)();
157
- return [4 /*yield*/, payload.create({
158
- collection: collectionSlug_1,
159
- data: __assign(__assign({}, syncedData), { password: password, passwordConfirm: password }),
160
- disableVerificationEmail: isAuthCollection ? true : undefined,
161
- })];
162
- case 13:
163
- _d.sent();
164
- if (logs)
165
- payload.logger.info("\u2705 Successfully created new '".concat(collectionSlug_1, "' document in Payload with Stripe ID: '").concat(stripeID, "'."));
166
- return [3 /*break*/, 15];
167
- case 14:
168
- error_2 = _d.sent();
169
- msg = error_2 instanceof Error ? error_2.message : error_2;
170
- if (logs)
171
- payload.logger.error("Error creating new document in Payload: ".concat(msg));
172
- return [3 /*break*/, 15];
173
- case 15: return [3 /*break*/, 20];
174
- case 16:
175
- if (logs)
176
- payload.logger.info("- Existing '".concat(collectionSlug_1, "' document found in Payload with Stripe ID: '").concat(stripeID, "', updating now..."));
177
- _d.label = 17;
178
- case 17:
179
- _d.trys.push([17, 19, , 20]);
180
- return [4 /*yield*/, payload.update({
181
- collection: collectionSlug_1,
182
- id: foundDoc.id,
183
- data: syncedData,
184
- })];
185
- case 18:
186
- _d.sent();
187
- if (logs)
188
- payload.logger.info("\u2705 Successfully updated '".concat(collectionSlug_1, "' document in Payload from Stripe ID: '").concat(stripeID, "'."));
189
- return [3 /*break*/, 20];
190
- case 19:
191
- error_3 = _d.sent();
192
- msg = error_3 instanceof Error ? error_3.message : error_3;
193
- if (logs)
194
- payload.logger.error("Error updating '".concat(collectionSlug_1, "' document in Payload: ").concat(msg));
195
- return [3 /*break*/, 20];
196
- case 20: return [2 /*return*/];
105
+ disableVerificationEmail: isAuthCollection ? true : undefined
106
+ });
107
+ if (logs) payload.logger.info(`✅ Successfully created new '${collectionSlug}' document in Payload with Stripe ID: '${stripeID}'.`);
108
+ } catch (error) {
109
+ const msg = error instanceof Error ? error.message : error;
110
+ if (logs) payload.logger.error(`Error creating new document in Payload: ${msg}`);
111
+ }
112
+ }
113
+ } else {
114
+ if (logs) payload.logger.info(`- Existing '${collectionSlug}' document found in Payload with Stripe ID: '${stripeID}', updating now...`);
115
+ try {
116
+ await payload.update({
117
+ id: foundDoc.id,
118
+ collection: collectionSlug,
119
+ data: syncedData
120
+ });
121
+ if (logs) payload.logger.info(`✅ Successfully updated '${collectionSlug}' document in Payload from Stripe ID: '${stripeID}'.`);
122
+ } catch (error) {
123
+ const msg = error instanceof Error ? error.message : error;
124
+ if (logs) payload.logger.error(`Error updating '${collectionSlug}' document in Payload: ${msg}`);
125
+ }
197
126
  }
198
- });
199
- }); };
200
- exports.handleCreatedOrUpdated = handleCreatedOrUpdated;
201
- //# sourceMappingURL=handleCreatedOrUpdated.js.map
127
+ }
128
+ };
129
+
130
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy93ZWJob29rcy9oYW5kbGVDcmVhdGVkT3JVcGRhdGVkLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHY0IGFzIHV1aWQgfSBmcm9tICd1dWlkJ1xuXG5pbXBvcnQgdHlwZSB7IFNhbml0aXplZFN0cmlwZUNvbmZpZywgU3RyaXBlV2ViaG9va0hhbmRsZXIgfSBmcm9tICcuLi90eXBlcydcblxuaW1wb3J0IHsgZGVlcGVuIH0gZnJvbSAnLi4vdXRpbGl0aWVzL2RlZXBlbidcblxudHlwZSBIYW5kbGVDcmVhdGVkT3JVcGRhdGVkID0gKFxuICBhcmdzOiBQYXJhbWV0ZXJzPFN0cmlwZVdlYmhvb2tIYW5kbGVyPlswXSAmIHtcbiAgICByZXNvdXJjZVR5cGU6IHN0cmluZ1xuICAgIHN5bmNDb25maWc6IFNhbml0aXplZFN0cmlwZUNvbmZpZ1snc3luYyddWzBdXG4gIH0sXG4pID0+IHZvaWRcblxuZXhwb3J0IGNvbnN0IGhhbmRsZUNyZWF0ZWRPclVwZGF0ZWQ6IEhhbmRsZUNyZWF0ZWRPclVwZGF0ZWQgPSBhc3luYyAoYXJncykgPT4ge1xuICBjb25zdCB7IGNvbmZpZzogcGF5bG9hZENvbmZpZywgZXZlbnQsIHBheWxvYWQsIHJlc291cmNlVHlwZSwgc3RyaXBlQ29uZmlnLCBzeW5jQ29uZmlnIH0gPSBhcmdzXG5cbiAgY29uc3QgeyBsb2dzIH0gPSBzdHJpcGVDb25maWcgfHwge31cblxuICBjb25zdCBzdHJpcGVEb2M6IGFueSA9IGV2ZW50Py5kYXRhPy5vYmplY3QgfHwge31cblxuICBjb25zdCB7IGlkOiBzdHJpcGVJRCwgb2JqZWN0OiBldmVudE9iamVjdCB9ID0gc3RyaXBlRG9jXG5cbiAgLy8gTk9URTogdGhlIFN0cmlwZSBBUEkgZG9lcyBub3QgbmVzdCBmaWVsZHMsIGV2ZXJ5dGhpbmcgaXMgYW4gb2JqZWN0IGF0IHRoZSB0b3AgbGV2ZWxcbiAgLy8gaWYgdGhlIGV2ZW50IG9iamVjdCBhbmQgcmVzb3VyY2UgdHlwZSBkb24ndCBtYXRjaCwgdGhpcyBjaGFuZ2Ugd2FzIG5vdCB0b3AtbGV2ZWxcbiAgY29uc3QgaXNOZXN0ZWRDaGFuZ2UgPSBldmVudE9iamVjdCAhPT0gcmVzb3VyY2VUeXBlXG5cbiAgLy8gbGV0IHN0cmlwZUlEID0gZG9jSUQ7XG4gIC8vIGlmIChpc05lc3RlZENoYW5nZSkge1xuICAvLyAgIGNvbnN0IHBhcmVudFJlc291cmNlID0gc3RyaXBlRG9jW3Jlc291cmNlVHlwZV07XG4gIC8vICAgc3RyaXBlSUQgPSBwYXJlbnRSZXNvdXJjZTtcbiAgLy8gfVxuXG4gIGlmIChpc05lc3RlZENoYW5nZSkge1xuICAgIGlmIChsb2dzKVxuICAgICAgcGF5bG9hZC5sb2dnZXIuaW5mbyhcbiAgICAgICAgYC0gVGhpcyBjaGFuZ2Ugb2NjdXJyZWQgb24gYSBuZXN0ZWQgZmllbGQgb2YgJHtyZXNvdXJjZVR5cGV9LiBOZXN0ZWQgZmllbGRzIGFyZSBub3QgeWV0IHN1cHBvcnRlZCBpbiBhdXRvLXN5bmMgYnV0IGNhbiBiZSBtYW51YWxseSBzZXR1cC5gLFxuICAgICAgKVxuICB9XG5cbiAgaWYgKCFpc05lc3RlZENoYW5nZSkge1xuICAgIGlmIChsb2dzKVxuICAgICAgcGF5bG9hZC5sb2dnZXIuaW5mbyhcbiAgICAgICAgYC0gQSBuZXcgZG9jdW1lbnQgd2FzIGNyZWF0ZWQgb3IgdXBkYXRlZCBpbiBTdHJpcGUsIG5vdyBzeW5jaW5nIHRvIFBheWxvYWQuLi5gLFxuICAgICAgKVxuXG4gICAgY29uc3QgY29sbGVjdGlvblNsdWcgPSBzeW5jQ29uZmlnPy5jb2xsZWN0aW9uXG5cbiAgICBjb25zdCBpc0F1dGhDb2xsZWN0aW9uID0gQm9vbGVhbihcbiAgICAgIHBheWxvYWRDb25maWc/LmNvbGxlY3Rpb25zPy5maW5kKChjb2xsZWN0aW9uKSA9PiBjb2xsZWN0aW9uLnNsdWcgPT09IGNvbGxlY3Rpb25TbHVnKT8uYXV0aCxcbiAgICApXG5cbiAgICAvLyBGaXJzdCwgc2VhcmNoIGZvciBhbiBleGlzdGluZyBkb2N1bWVudCBpbiBQYXlsb2FkXG4gICAgY29uc3QgcGF5bG9hZFF1ZXJ5ID0gYXdhaXQgcGF5bG9hZC5maW5kKHtcbiAgICAgIGNvbGxlY3Rpb246IGNvbGxlY3Rpb25TbHVnLFxuICAgICAgd2hlcmU6IHtcbiAgICAgICAgc3RyaXBlSUQ6IHtcbiAgICAgICAgICBlcXVhbHM6IHN0cmlwZUlELFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9KVxuXG4gICAgY29uc3QgZm91bmREb2MgPSBwYXlsb2FkUXVlcnkuZG9jc1swXSBhcyBhbnlcblxuICAgIC8vIGNvbWJpbmUgYWxsIHByb3BlcnRpZXMgb2YgdGhlIFN0cmlwZSBkb2MgYW5kIG1hdGNoIHRoZWlyIHJlc3BlY3RpdmUgZmllbGRzIHdpdGhpbiB0aGUgZG9jdW1lbnRcbiAgICBsZXQgc3luY2VkRGF0YSA9IHN5bmNDb25maWcuZmllbGRzLnJlZHVjZShcbiAgICAgIChhY2MsIGZpZWxkKSA9PiB7XG4gICAgICAgIGNvbnN0IHsgZmllbGRQYXRoLCBzdHJpcGVQcm9wZXJ0eSB9ID0gZmllbGRcblxuICAgICAgICBhY2NbZmllbGRQYXRoXSA9IHN0cmlwZURvY1tzdHJpcGVQcm9wZXJ0eV1cbiAgICAgICAgcmV0dXJuIGFjY1xuICAgICAgfSxcbiAgICAgIHt9IGFzIFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgKVxuXG4gICAgc3luY2VkRGF0YSA9IGRlZXBlbih7XG4gICAgICAuLi5zeW5jZWREYXRhLFxuICAgICAgc2tpcFN5bmM6IHRydWUsXG4gICAgICBzdHJpcGVJRCxcbiAgICB9KVxuXG4gICAgaWYgKCFmb3VuZERvYykge1xuICAgICAgaWYgKGxvZ3MpXG4gICAgICAgIHBheWxvYWQubG9nZ2VyLmluZm8oXG4gICAgICAgICAgYC0gTm8gZXhpc3RpbmcgJyR7Y29sbGVjdGlvblNsdWd9JyBkb2N1bWVudCBmb3VuZCB3aXRoIFN0cmlwZSBJRDogJyR7c3RyaXBlSUR9JywgY3JlYXRpbmcgbmV3Li4uYCxcbiAgICAgICAgKVxuXG4gICAgICAvLyBhdXRoIGRvY3MgbXVzdCB1c2UgdW5pcXVlIGVtYWlsc1xuICAgICAgbGV0IGF1dGhEb2MgPSBudWxsXG5cbiAgICAgIGlmIChpc0F1dGhDb2xsZWN0aW9uKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgaWYgKHN0cmlwZURvYz8uZW1haWwpIHtcbiAgICAgICAgICAgIGNvbnN0IGF1dGhRdWVyeSA9IGF3YWl0IHBheWxvYWQuZmluZCh7XG4gICAgICAgICAgICAgIGNvbGxlY3Rpb246IGNvbGxlY3Rpb25TbHVnLFxuICAgICAgICAgICAgICB3aGVyZToge1xuICAgICAgICAgICAgICAgIGVtYWlsOiB7XG4gICAgICAgICAgICAgICAgICBlcXVhbHM6IHN0cmlwZURvYy5lbWFpbCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgYXV0aERvYyA9IGF1dGhRdWVyeS5kb2NzWzBdIGFzIGFueVxuXG4gICAgICAgICAgICBpZiAoYXV0aERvYykge1xuICAgICAgICAgICAgICBpZiAobG9ncylcbiAgICAgICAgICAgICAgICBwYXlsb2FkLmxvZ2dlci5pbmZvKFxuICAgICAgICAgICAgICAgICAgYC0gQWNjb3VudCBhbHJlYWR5IGV4aXN0cyB3aXRoIGUtbWFpbDogJHtzdHJpcGVEb2MuZW1haWx9LCB1cGRhdGluZyBub3cuLi5gLFxuICAgICAgICAgICAgICAgIClcblxuICAgICAgICAgICAgICAvLyBhY2NvdW50IGV4aXN0cyBieSBlbWFpbCwgc28gdXBkYXRlIGl0IGluc3RlYWRcbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBhd2FpdCBwYXlsb2FkLnVwZGF0ZSh7XG4gICAgICAgICAgICAgICAgICBpZDogYXV0aERvYy5pZCxcbiAgICAgICAgICAgICAgICAgIGNvbGxlY3Rpb246IGNvbGxlY3Rpb25TbHVnLFxuICAgICAgICAgICAgICAgICAgZGF0YTogc3luY2VkRGF0YSxcbiAgICAgICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICAgICAgaWYgKGxvZ3MpXG4gICAgICAgICAgICAgICAgICBwYXlsb2FkLmxvZ2dlci5pbmZvKFxuICAgICAgICAgICAgICAgICAgICBg4pyFIFN1Y2Nlc3NmdWxseSB1cGRhdGVkICcke2NvbGxlY3Rpb25TbHVnfScgZG9jdW1lbnQgaW4gUGF5bG9hZCB3aXRoIElEOiAnJHthdXRoRG9jLmlkfS4nYCxcbiAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyOiB1bmtub3duKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbXNnID0gZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IGVyclxuICAgICAgICAgICAgICAgIGlmIChsb2dzKVxuICAgICAgICAgICAgICAgICAgcGF5bG9hZC5sb2dnZXIuZXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIGAtIEVycm9yIHVwZGF0aW5nIGV4aXN0aW5nICcke2NvbGxlY3Rpb25TbHVnfScgZG9jdW1lbnQ6ICR7bXNnfWAsXG4gICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGxvZ3MpXG4gICAgICAgICAgICAgIHBheWxvYWQubG9nZ2VyLmVycm9yKFxuICAgICAgICAgICAgICAgIGBObyBlbWFpbCB3YXMgcHJvdmlkZWQgZnJvbSBTdHJpcGUsIGNhbm5vdCBjcmVhdGUgbmV3ICcke2NvbGxlY3Rpb25TbHVnfScgZG9jdW1lbnQuYCxcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgICAgICBjb25zdCBtc2cgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IGVycm9yXG4gICAgICAgICAgaWYgKGxvZ3MpXG4gICAgICAgICAgICBwYXlsb2FkLmxvZ2dlci5lcnJvcihgRXJyb3IgbG9va2luZyB1cCAnJHtjb2xsZWN0aW9uU2x1Z30nIGRvY3VtZW50IGluIFBheWxvYWQ6ICR7bXNnfWApXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKCFpc0F1dGhDb2xsZWN0aW9uIHx8IChpc0F1dGhDb2xsZWN0aW9uICYmICFhdXRoRG9jKSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGlmIChsb2dzKVxuICAgICAgICAgICAgcGF5bG9hZC5sb2dnZXIuaW5mbyhcbiAgICAgICAgICAgICAgYC0gQ3JlYXRpbmcgbmV3ICcke2NvbGxlY3Rpb25TbHVnfScgZG9jdW1lbnQgaW4gUGF5bG9hZCB3aXRoIFN0cmlwZSBJRDogJyR7c3RyaXBlSUR9Jy5gLFxuICAgICAgICAgICAgKVxuXG4gICAgICAgICAgLy8gZ2VuZXJhdGUgYSBzdHJvbmcsIHVuaXF1ZSBwYXNzd29yZCBmb3IgdGhlIG5ldyB1c2VyXG4gICAgICAgICAgY29uc3QgcGFzc3dvcmQ6IHN0cmluZyA9IHV1aWQoKVxuXG4gICAgICAgICAgYXdhaXQgcGF5bG9hZC5jcmVhdGUoe1xuICAgICAgICAgICAgY29sbGVjdGlvbjogY29sbGVjdGlvblNsdWcsXG4gICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgIC4uLnN5bmNlZERhdGEsXG4gICAgICAgICAgICAgIHBhc3N3b3JkLFxuICAgICAgICAgICAgICBwYXNzd29yZENvbmZpcm06IHBhc3N3b3JkLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGRpc2FibGVWZXJpZmljYXRpb25FbWFpbDogaXNBdXRoQ29sbGVjdGlvbiA/IHRydWUgOiB1bmRlZmluZWQsXG4gICAgICAgICAgfSlcblxuICAgICAgICAgIGlmIChsb2dzKVxuICAgICAgICAgICAgcGF5bG9hZC5sb2dnZXIuaW5mbyhcbiAgICAgICAgICAgICAgYOKchSBTdWNjZXNzZnVsbHkgY3JlYXRlZCBuZXcgJyR7Y29sbGVjdGlvblNsdWd9JyBkb2N1bWVudCBpbiBQYXlsb2FkIHdpdGggU3RyaXBlIElEOiAnJHtzdHJpcGVJRH0nLmAsXG4gICAgICAgICAgICApXG4gICAgICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICAgICAgY29uc3QgbXNnID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBlcnJvclxuICAgICAgICAgIGlmIChsb2dzKSBwYXlsb2FkLmxvZ2dlci5lcnJvcihgRXJyb3IgY3JlYXRpbmcgbmV3IGRvY3VtZW50IGluIFBheWxvYWQ6ICR7bXNnfWApXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGxvZ3MpXG4gICAgICAgIHBheWxvYWQubG9nZ2VyLmluZm8oXG4gICAgICAgICAgYC0gRXhpc3RpbmcgJyR7Y29sbGVjdGlvblNsdWd9JyBkb2N1bWVudCBmb3VuZCBpbiBQYXlsb2FkIHdpdGggU3RyaXBlIElEOiAnJHtzdHJpcGVJRH0nLCB1cGRhdGluZyBub3cuLi5gLFxuICAgICAgICApXG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHBheWxvYWQudXBkYXRlKHtcbiAgICAgICAgICBpZDogZm91bmREb2MuaWQsXG4gICAgICAgICAgY29sbGVjdGlvbjogY29sbGVjdGlvblNsdWcsXG4gICAgICAgICAgZGF0YTogc3luY2VkRGF0YSxcbiAgICAgICAgfSlcblxuICAgICAgICBpZiAobG9ncylcbiAgICAgICAgICBwYXlsb2FkLmxvZ2dlci5pbmZvKFxuICAgICAgICAgICAgYOKchSBTdWNjZXNzZnVsbHkgdXBkYXRlZCAnJHtjb2xsZWN0aW9uU2x1Z30nIGRvY3VtZW50IGluIFBheWxvYWQgZnJvbSBTdHJpcGUgSUQ6ICcke3N0cmlwZUlEfScuYCxcbiAgICAgICAgICApXG4gICAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgICBjb25zdCBtc2cgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IGVycm9yXG4gICAgICAgIGlmIChsb2dzKVxuICAgICAgICAgIHBheWxvYWQubG9nZ2VyLmVycm9yKGBFcnJvciB1cGRhdGluZyAnJHtjb2xsZWN0aW9uU2x1Z30nIGRvY3VtZW50IGluIFBheWxvYWQ6ICR7bXNnfWApXG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iXSwibmFtZXMiOlsiaGFuZGxlQ3JlYXRlZE9yVXBkYXRlZCIsImFyZ3MiLCJjb25maWciLCJwYXlsb2FkQ29uZmlnIiwiZXZlbnQiLCJwYXlsb2FkIiwicmVzb3VyY2VUeXBlIiwic3RyaXBlQ29uZmlnIiwic3luY0NvbmZpZyIsImxvZ3MiLCJzdHJpcGVEb2MiLCJkYXRhIiwib2JqZWN0IiwiaWQiLCJzdHJpcGVJRCIsImV2ZW50T2JqZWN0IiwiaXNOZXN0ZWRDaGFuZ2UiLCJsb2dnZXIiLCJpbmZvIiwiY29sbGVjdGlvblNsdWciLCJjb2xsZWN0aW9uIiwiaXNBdXRoQ29sbGVjdGlvbiIsIkJvb2xlYW4iLCJjb2xsZWN0aW9ucyIsImZpbmQiLCJzbHVnIiwiYXV0aCIsInBheWxvYWRRdWVyeSIsIndoZXJlIiwiZXF1YWxzIiwiZm91bmREb2MiLCJkb2NzIiwic3luY2VkRGF0YSIsImZpZWxkcyIsInJlZHVjZSIsImFjYyIsImZpZWxkIiwiZmllbGRQYXRoIiwic3RyaXBlUHJvcGVydHkiLCJkZWVwZW4iLCJza2lwU3luYyIsImF1dGhEb2MiLCJlbWFpbCIsImF1dGhRdWVyeSIsInVwZGF0ZSIsImVyciIsIm1zZyIsIkVycm9yIiwibWVzc2FnZSIsImVycm9yIiwicGFzc3dvcmQiLCJ1dWlkIiwiY3JlYXRlIiwicGFzc3dvcmRDb25maXJtIiwiZGlzYWJsZVZlcmlmaWNhdGlvbkVtYWlsIiwidW5kZWZpbmVkIl0sIm1hcHBpbmdzIjoiOzs7OytCQWFhQTs7O2VBQUFBOzs7c0JBYmM7d0JBSUo7QUFTaEIsTUFBTUEseUJBQWlELE9BQU9DO0lBQ25FLE1BQU0sRUFBRUMsUUFBUUMsYUFBYSxFQUFFQyxLQUFLLEVBQUVDLE9BQU8sRUFBRUMsWUFBWSxFQUFFQyxZQUFZLEVBQUVDLFVBQVUsRUFBRSxHQUFHUDtJQUUxRixNQUFNLEVBQUVRLElBQUksRUFBRSxHQUFHRixnQkFBZ0IsQ0FBQztJQUVsQyxNQUFNRyxZQUFpQk4sT0FBT08sTUFBTUMsVUFBVSxDQUFDO0lBRS9DLE1BQU0sRUFBRUMsSUFBSUMsUUFBUSxFQUFFRixRQUFRRyxXQUFXLEVBQUUsR0FBR0w7SUFFOUMsc0ZBQXNGO0lBQ3RGLG1GQUFtRjtJQUNuRixNQUFNTSxpQkFBaUJELGdCQUFnQlQ7SUFFdkMsd0JBQXdCO0lBQ3hCLHdCQUF3QjtJQUN4QixvREFBb0Q7SUFDcEQsK0JBQStCO0lBQy9CLElBQUk7SUFFSixJQUFJVSxnQkFBZ0I7UUFDbEIsSUFBSVAsTUFDRkosUUFBUVksTUFBTSxDQUFDQyxJQUFJLENBQ2pCLENBQUMsNENBQTRDLEVBQUVaLGFBQWEsNkVBQTZFLENBQUM7SUFFaEo7SUFFQSxJQUFJLENBQUNVLGdCQUFnQjtRQUNuQixJQUFJUCxNQUNGSixRQUFRWSxNQUFNLENBQUNDLElBQUksQ0FDakIsQ0FBQyw0RUFBNEUsQ0FBQztRQUdsRixNQUFNQyxpQkFBaUJYLFlBQVlZO1FBRW5DLE1BQU1DLG1CQUFtQkMsUUFDdkJuQixlQUFlb0IsYUFBYUMsS0FBSyxDQUFDSixhQUFlQSxXQUFXSyxJQUFJLEtBQUtOLGlCQUFpQk87UUFHeEYsb0RBQW9EO1FBQ3BELE1BQU1DLGVBQWUsTUFBTXRCLFFBQVFtQixJQUFJLENBQUM7WUFDdENKLFlBQVlEO1lBQ1pTLE9BQU87Z0JBQ0xkLFVBQVU7b0JBQ1JlLFFBQVFmO2dCQUNWO1lBQ0Y7UUFDRjtRQUVBLE1BQU1nQixXQUFXSCxhQUFhSSxJQUFJLENBQUMsRUFBRTtRQUVyQyxpR0FBaUc7UUFDakcsSUFBSUMsYUFBYXhCLFdBQVd5QixNQUFNLENBQUNDLE1BQU0sQ0FDdkMsQ0FBQ0MsS0FBS0M7WUFDSixNQUFNLEVBQUVDLFNBQVMsRUFBRUMsY0FBYyxFQUFFLEdBQUdGO1lBRXRDRCxHQUFHLENBQUNFLFVBQVUsR0FBRzNCLFNBQVMsQ0FBQzRCLGVBQWU7WUFDMUMsT0FBT0g7UUFDVCxHQUNBLENBQUM7UUFHSEgsYUFBYU8sSUFBQUEsY0FBTSxFQUFDO1lBQ2xCLEdBQUdQLFVBQVU7WUFDYlEsVUFBVTtZQUNWMUI7UUFDRjtRQUVBLElBQUksQ0FBQ2dCLFVBQVU7WUFDYixJQUFJckIsTUFDRkosUUFBUVksTUFBTSxDQUFDQyxJQUFJLENBQ2pCLENBQUMsZUFBZSxFQUFFQyxlQUFlLGtDQUFrQyxFQUFFTCxTQUFTLGtCQUFrQixDQUFDO1lBR3JHLG1DQUFtQztZQUNuQyxJQUFJMkIsVUFBVTtZQUVkLElBQUlwQixrQkFBa0I7Z0JBQ3BCLElBQUk7b0JBQ0YsSUFBSVgsV0FBV2dDLE9BQU87d0JBQ3BCLE1BQU1DLFlBQVksTUFBTXRDLFFBQVFtQixJQUFJLENBQUM7NEJBQ25DSixZQUFZRDs0QkFDWlMsT0FBTztnQ0FDTGMsT0FBTztvQ0FDTGIsUUFBUW5CLFVBQVVnQyxLQUFLO2dDQUN6Qjs0QkFDRjt3QkFDRjt3QkFFQUQsVUFBVUUsVUFBVVosSUFBSSxDQUFDLEVBQUU7d0JBRTNCLElBQUlVLFNBQVM7NEJBQ1gsSUFBSWhDLE1BQ0ZKLFFBQVFZLE1BQU0sQ0FBQ0MsSUFBSSxDQUNqQixDQUFDLHNDQUFzQyxFQUFFUixVQUFVZ0MsS0FBSyxDQUFDLGlCQUFpQixDQUFDOzRCQUcvRSxnREFBZ0Q7NEJBQ2hELElBQUk7Z0NBQ0YsTUFBTXJDLFFBQVF1QyxNQUFNLENBQUM7b0NBQ25CL0IsSUFBSTRCLFFBQVE1QixFQUFFO29DQUNkTyxZQUFZRDtvQ0FDWlIsTUFBTXFCO2dDQUNSO2dDQUVBLElBQUl2QixNQUNGSixRQUFRWSxNQUFNLENBQUNDLElBQUksQ0FDakIsQ0FBQyx3QkFBd0IsRUFBRUMsZUFBZSxnQ0FBZ0MsRUFBRXNCLFFBQVE1QixFQUFFLENBQUMsRUFBRSxDQUFDOzRCQUVoRyxFQUFFLE9BQU9nQyxLQUFjO2dDQUNyQixNQUFNQyxNQUFNRCxlQUFlRSxRQUFRRixJQUFJRyxPQUFPLEdBQUdIO2dDQUNqRCxJQUFJcEMsTUFDRkosUUFBUVksTUFBTSxDQUFDZ0MsS0FBSyxDQUNsQixDQUFDLDJCQUEyQixFQUFFOUIsZUFBZSxZQUFZLEVBQUUyQixJQUFJLENBQUM7NEJBRXRFO3dCQUNGO29CQUNGLE9BQU87d0JBQ0wsSUFBSXJDLE1BQ0ZKLFFBQVFZLE1BQU0sQ0FBQ2dDLEtBQUssQ0FDbEIsQ0FBQyxzREFBc0QsRUFBRTlCLGVBQWUsV0FBVyxDQUFDO29CQUUxRjtnQkFDRixFQUFFLE9BQU84QixPQUFnQjtvQkFDdkIsTUFBTUgsTUFBTUcsaUJBQWlCRixRQUFRRSxNQUFNRCxPQUFPLEdBQUdDO29CQUNyRCxJQUFJeEMsTUFDRkosUUFBUVksTUFBTSxDQUFDZ0MsS0FBSyxDQUFDLENBQUMsa0JBQWtCLEVBQUU5QixlQUFlLHVCQUF1QixFQUFFMkIsSUFBSSxDQUFDO2dCQUMzRjtZQUNGO1lBRUEsSUFBSSxDQUFDekIsb0JBQXFCQSxvQkFBb0IsQ0FBQ29CLFNBQVU7Z0JBQ3ZELElBQUk7b0JBQ0YsSUFBSWhDLE1BQ0ZKLFFBQVFZLE1BQU0sQ0FBQ0MsSUFBSSxDQUNqQixDQUFDLGdCQUFnQixFQUFFQyxlQUFlLHVDQUF1QyxFQUFFTCxTQUFTLEVBQUUsQ0FBQztvQkFHM0Ysc0RBQXNEO29CQUN0RCxNQUFNb0MsV0FBbUJDLElBQUFBLFFBQUk7b0JBRTdCLE1BQU05QyxRQUFRK0MsTUFBTSxDQUFDO3dCQUNuQmhDLFlBQVlEO3dCQUNaUixNQUFNOzRCQUNKLEdBQUdxQixVQUFVOzRCQUNia0I7NEJBQ0FHLGlCQUFpQkg7d0JBQ25CO3dCQUNBSSwwQkFBMEJqQyxtQkFBbUIsT0FBT2tDO29CQUN0RDtvQkFFQSxJQUFJOUMsTUFDRkosUUFBUVksTUFBTSxDQUFDQyxJQUFJLENBQ2pCLENBQUMsNEJBQTRCLEVBQUVDLGVBQWUsdUNBQXVDLEVBQUVMLFNBQVMsRUFBRSxDQUFDO2dCQUV6RyxFQUFFLE9BQU9tQyxPQUFnQjtvQkFDdkIsTUFBTUgsTUFBTUcsaUJBQWlCRixRQUFRRSxNQUFNRCxPQUFPLEdBQUdDO29CQUNyRCxJQUFJeEMsTUFBTUosUUFBUVksTUFBTSxDQUFDZ0MsS0FBSyxDQUFDLENBQUMsd0NBQXdDLEVBQUVILElBQUksQ0FBQztnQkFDakY7WUFDRjtRQUNGLE9BQU87WUFDTCxJQUFJckMsTUFDRkosUUFBUVksTUFBTSxDQUFDQyxJQUFJLENBQ2pCLENBQUMsWUFBWSxFQUFFQyxlQUFlLDZDQUE2QyxFQUFFTCxTQUFTLGtCQUFrQixDQUFDO1lBRzdHLElBQUk7Z0JBQ0YsTUFBTVQsUUFBUXVDLE1BQU0sQ0FBQztvQkFDbkIvQixJQUFJaUIsU0FBU2pCLEVBQUU7b0JBQ2ZPLFlBQVlEO29CQUNaUixNQUFNcUI7Z0JBQ1I7Z0JBRUEsSUFBSXZCLE1BQ0ZKLFFBQVFZLE1BQU0sQ0FBQ0MsSUFBSSxDQUNqQixDQUFDLHdCQUF3QixFQUFFQyxlQUFlLHVDQUF1QyxFQUFFTCxTQUFTLEVBQUUsQ0FBQztZQUVyRyxFQUFFLE9BQU9tQyxPQUFnQjtnQkFDdkIsTUFBTUgsTUFBTUcsaUJBQWlCRixRQUFRRSxNQUFNRCxPQUFPLEdBQUdDO2dCQUNyRCxJQUFJeEMsTUFDRkosUUFBUVksTUFBTSxDQUFDZ0MsS0FBSyxDQUFDLENBQUMsZ0JBQWdCLEVBQUU5QixlQUFlLHVCQUF1QixFQUFFMkIsSUFBSSxDQUFDO1lBQ3pGO1FBQ0Y7SUFDRjtBQUNGIn0=
@@ -1,107 +1,58 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __generator = (this && this.__generator) || function (thisArg, body) {
12
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
- function verb(n) { return function (v) { return step([n, v]); }; }
15
- function step(op) {
16
- if (f) throw new TypeError("Generator is already executing.");
17
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
- if (y = 0, t) op = [op[0] & 2, t.value];
20
- switch (op[0]) {
21
- case 0: case 1: t = op; break;
22
- case 4: _.label++; return { value: op[1], done: false };
23
- case 5: _.label++; y = op[1]; op = [0]; continue;
24
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
- default:
26
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
- if (t[2]) _.ops.pop();
31
- _.trys.pop(); continue;
32
- }
33
- op = body.call(thisArg, _);
34
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "handleDeleted", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return handleDeleted;
36
9
  }
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.handleDeleted = void 0;
40
- var handleDeleted = function (args) { return __awaiter(void 0, void 0, void 0, function () {
41
- var payload, event, stripeConfig, resourceType, syncConfig, logs, collectionSlug, _a, stripeID, eventObject, isNestedDelete, payloadQuery, foundDoc, msg, error_1, msg;
42
- var _b;
43
- return __generator(this, function (_c) {
44
- switch (_c.label) {
45
- case 0:
46
- payload = args.payload, event = args.event, stripeConfig = args.stripeConfig, resourceType = args.resourceType, syncConfig = args.syncConfig;
47
- logs = (stripeConfig || {}).logs;
48
- collectionSlug = syncConfig === null || syncConfig === void 0 ? void 0 : syncConfig.collection;
49
- _a = ((_b = event === null || event === void 0 ? void 0 : event.data) === null || _b === void 0 ? void 0 : _b.object) || {}, stripeID = _a.id, eventObject = _a.object;
50
- isNestedDelete = eventObject !== resourceType;
51
- if (isNestedDelete) {
52
- if (logs)
53
- payload.logger.info("- This deletion occurred on a nested field of ".concat(resourceType, ". Nested fields are not yet supported."));
54
- }
55
- if (!!isNestedDelete) return [3 /*break*/, 4];
56
- if (logs)
57
- payload.logger.info("- A '".concat(resourceType, "' resource was deleted in Stripe, now deleting '").concat(collectionSlug, "' document in Payload with Stripe ID: '").concat(stripeID, "'..."));
58
- _c.label = 1;
59
- case 1:
60
- _c.trys.push([1, 3, , 4]);
61
- return [4 /*yield*/, payload.find({
62
- collection: collectionSlug,
63
- where: {
64
- stripeID: {
65
- equals: stripeID,
66
- },
67
- },
68
- })];
69
- case 2:
70
- payloadQuery = _c.sent();
71
- foundDoc = payloadQuery.docs[0];
72
- if (!foundDoc) {
73
- if (logs)
74
- payload.logger.info("- Nothing to delete, no existing document found with Stripe ID: '".concat(stripeID, "'."));
75
- }
76
- if (foundDoc) {
77
- if (logs)
78
- payload.logger.info("- Deleting Payload document with ID: '".concat(foundDoc.id, "'..."));
79
- try {
80
- payload.delete({
81
- collection: collectionSlug,
82
- id: foundDoc.id,
83
- });
84
- // NOTE: the `afterDelete` hook will trigger, which will attempt to delete the document from Stripe and safely error out
85
- // There is no known way of preventing this from happening. In other hooks we use the `skipSync` field, but here the document is already deleted.
86
- if (logs)
87
- payload.logger.info("- \u2705 Successfully deleted Payload document with ID: '".concat(foundDoc.id, "'."));
88
- }
89
- catch (error) {
90
- msg = error instanceof Error ? error.message : error;
91
- if (logs)
92
- payload.logger.error("Error deleting document: ".concat(msg));
10
+ });
11
+ const handleDeleted = async (args)=>{
12
+ const { event, payload, resourceType, stripeConfig, syncConfig } = args;
13
+ const { logs } = stripeConfig || {};
14
+ const collectionSlug = syncConfig?.collection;
15
+ const { id: stripeID, object: eventObject } = event?.data?.object || {};
16
+ // if the event object and resource type don't match, this deletion was not top-level
17
+ const isNestedDelete = eventObject !== resourceType;
18
+ if (isNestedDelete) {
19
+ if (logs) payload.logger.info(`- This deletion occurred on a nested field of ${resourceType}. Nested fields are not yet supported.`);
20
+ }
21
+ if (!isNestedDelete) {
22
+ if (logs) payload.logger.info(`- A '${resourceType}' resource was deleted in Stripe, now deleting '${collectionSlug}' document in Payload with Stripe ID: '${stripeID}'...`);
23
+ try {
24
+ const payloadQuery = await payload.find({
25
+ collection: collectionSlug,
26
+ where: {
27
+ stripeID: {
28
+ equals: stripeID
93
29
  }
94
30
  }
95
- return [3 /*break*/, 4];
96
- case 3:
97
- error_1 = _c.sent();
98
- msg = error_1 instanceof Error ? error_1.message : error_1;
99
- if (logs)
100
- payload.logger.error("Error deleting document: ".concat(msg));
101
- return [3 /*break*/, 4];
102
- case 4: return [2 /*return*/];
31
+ });
32
+ const foundDoc = payloadQuery.docs[0];
33
+ if (!foundDoc) {
34
+ if (logs) payload.logger.info(`- Nothing to delete, no existing document found with Stripe ID: '${stripeID}'.`);
35
+ }
36
+ if (foundDoc) {
37
+ if (logs) payload.logger.info(`- Deleting Payload document with ID: '${foundDoc.id}'...`);
38
+ try {
39
+ payload.delete({
40
+ id: foundDoc.id,
41
+ collection: collectionSlug
42
+ });
43
+ // NOTE: the `afterDelete` hook will trigger, which will attempt to delete the document from Stripe and safely error out
44
+ // There is no known way of preventing this from happening. In other hooks we use the `skipSync` field, but here the document is already deleted.
45
+ if (logs) payload.logger.info(`- ✅ Successfully deleted Payload document with ID: '${foundDoc.id}'.`);
46
+ } catch (error) {
47
+ const msg = error instanceof Error ? error.message : error;
48
+ if (logs) payload.logger.error(`Error deleting document: ${msg}`);
49
+ }
50
+ }
51
+ } catch (error) {
52
+ const msg = error instanceof Error ? error.message : error;
53
+ if (logs) payload.logger.error(`Error deleting document: ${msg}`);
103
54
  }
104
- });
105
- }); };
106
- exports.handleDeleted = handleDeleted;
107
- //# sourceMappingURL=handleDeleted.js.map
55
+ }
56
+ };
57
+
58
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy93ZWJob29rcy9oYW5kbGVEZWxldGVkLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgU2FuaXRpemVkU3RyaXBlQ29uZmlnLCBTdHJpcGVXZWJob29rSGFuZGxlciB9IGZyb20gJy4uL3R5cGVzJ1xuXG50eXBlIEhhbmRsZURlbGV0ZWQgPSAoXG4gIGFyZ3M6IFBhcmFtZXRlcnM8U3RyaXBlV2ViaG9va0hhbmRsZXI+WzBdICYge1xuICAgIHJlc291cmNlVHlwZTogc3RyaW5nXG4gICAgc3luY0NvbmZpZzogU2FuaXRpemVkU3RyaXBlQ29uZmlnWydzeW5jJ11bMF1cbiAgfSxcbikgPT4gdm9pZFxuXG5leHBvcnQgY29uc3QgaGFuZGxlRGVsZXRlZDogSGFuZGxlRGVsZXRlZCA9IGFzeW5jIChhcmdzKSA9PiB7XG4gIGNvbnN0IHsgZXZlbnQsIHBheWxvYWQsIHJlc291cmNlVHlwZSwgc3RyaXBlQ29uZmlnLCBzeW5jQ29uZmlnIH0gPSBhcmdzXG5cbiAgY29uc3QgeyBsb2dzIH0gPSBzdHJpcGVDb25maWcgfHwge31cblxuICBjb25zdCBjb2xsZWN0aW9uU2x1ZyA9IHN5bmNDb25maWc/LmNvbGxlY3Rpb25cblxuICBjb25zdCB7XG4gICAgaWQ6IHN0cmlwZUlELFxuICAgIG9iamVjdDogZXZlbnRPYmplY3QsIC8vIHVzZSB0aGlzIHRvIGRldGVybWluZSBpZiB0aGlzIGlzIGEgbmVzdGVkIGZpZWxkXG4gIH06IGFueSA9IGV2ZW50Py5kYXRhPy5vYmplY3QgfHwge31cblxuICAvLyBpZiB0aGUgZXZlbnQgb2JqZWN0IGFuZCByZXNvdXJjZSB0eXBlIGRvbid0IG1hdGNoLCB0aGlzIGRlbGV0aW9uIHdhcyBub3QgdG9wLWxldmVsXG4gIGNvbnN0IGlzTmVzdGVkRGVsZXRlID0gZXZlbnRPYmplY3QgIT09IHJlc291cmNlVHlwZVxuXG4gIGlmIChpc05lc3RlZERlbGV0ZSkge1xuICAgIGlmIChsb2dzKVxuICAgICAgcGF5bG9hZC5sb2dnZXIuaW5mbyhcbiAgICAgICAgYC0gVGhpcyBkZWxldGlvbiBvY2N1cnJlZCBvbiBhIG5lc3RlZCBmaWVsZCBvZiAke3Jlc291cmNlVHlwZX0uIE5lc3RlZCBmaWVsZHMgYXJlIG5vdCB5ZXQgc3VwcG9ydGVkLmAsXG4gICAgICApXG4gIH1cblxuICBpZiAoIWlzTmVzdGVkRGVsZXRlKSB7XG4gICAgaWYgKGxvZ3MpXG4gICAgICBwYXlsb2FkLmxvZ2dlci5pbmZvKFxuICAgICAgICBgLSBBICcke3Jlc291cmNlVHlwZX0nIHJlc291cmNlIHdhcyBkZWxldGVkIGluIFN0cmlwZSwgbm93IGRlbGV0aW5nICcke2NvbGxlY3Rpb25TbHVnfScgZG9jdW1lbnQgaW4gUGF5bG9hZCB3aXRoIFN0cmlwZSBJRDogJyR7c3RyaXBlSUR9Jy4uLmAsXG4gICAgICApXG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcGF5bG9hZFF1ZXJ5ID0gYXdhaXQgcGF5bG9hZC5maW5kKHtcbiAgICAgICAgY29sbGVjdGlvbjogY29sbGVjdGlvblNsdWcsXG4gICAgICAgIHdoZXJlOiB7XG4gICAgICAgICAgc3RyaXBlSUQ6IHtcbiAgICAgICAgICAgIGVxdWFsczogc3RyaXBlSUQsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pXG5cbiAgICAgIGNvbnN0IGZvdW5kRG9jID0gcGF5bG9hZFF1ZXJ5LmRvY3NbMF0gYXMgYW55XG5cbiAgICAgIGlmICghZm91bmREb2MpIHtcbiAgICAgICAgaWYgKGxvZ3MpXG4gICAgICAgICAgcGF5bG9hZC5sb2dnZXIuaW5mbyhcbiAgICAgICAgICAgIGAtIE5vdGhpbmcgdG8gZGVsZXRlLCBubyBleGlzdGluZyBkb2N1bWVudCBmb3VuZCB3aXRoIFN0cmlwZSBJRDogJyR7c3RyaXBlSUR9Jy5gLFxuICAgICAgICAgIClcbiAgICAgIH1cblxuICAgICAgaWYgKGZvdW5kRG9jKSB7XG4gICAgICAgIGlmIChsb2dzKSBwYXlsb2FkLmxvZ2dlci5pbmZvKGAtIERlbGV0aW5nIFBheWxvYWQgZG9jdW1lbnQgd2l0aCBJRDogJyR7Zm91bmREb2MuaWR9Jy4uLmApXG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBwYXlsb2FkLmRlbGV0ZSh7XG4gICAgICAgICAgICBpZDogZm91bmREb2MuaWQsXG4gICAgICAgICAgICBjb2xsZWN0aW9uOiBjb2xsZWN0aW9uU2x1ZyxcbiAgICAgICAgICB9KVxuXG4gICAgICAgICAgLy8gTk9URTogdGhlIGBhZnRlckRlbGV0ZWAgaG9vayB3aWxsIHRyaWdnZXIsIHdoaWNoIHdpbGwgYXR0ZW1wdCB0byBkZWxldGUgdGhlIGRvY3VtZW50IGZyb20gU3RyaXBlIGFuZCBzYWZlbHkgZXJyb3Igb3V0XG4gICAgICAgICAgLy8gVGhlcmUgaXMgbm8ga25vd24gd2F5IG9mIHByZXZlbnRpbmcgdGhpcyBmcm9tIGhhcHBlbmluZy4gSW4gb3RoZXIgaG9va3Mgd2UgdXNlIHRoZSBgc2tpcFN5bmNgIGZpZWxkLCBidXQgaGVyZSB0aGUgZG9jdW1lbnQgaXMgYWxyZWFkeSBkZWxldGVkLlxuICAgICAgICAgIGlmIChsb2dzKVxuICAgICAgICAgICAgcGF5bG9hZC5sb2dnZXIuaW5mbyhcbiAgICAgICAgICAgICAgYC0g4pyFIFN1Y2Nlc3NmdWxseSBkZWxldGVkIFBheWxvYWQgZG9jdW1lbnQgd2l0aCBJRDogJyR7Zm91bmREb2MuaWR9Jy5gLFxuICAgICAgICAgICAgKVxuICAgICAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgICAgIGNvbnN0IG1zZyA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogZXJyb3JcbiAgICAgICAgICBpZiAobG9ncykgcGF5bG9hZC5sb2dnZXIuZXJyb3IoYEVycm9yIGRlbGV0aW5nIGRvY3VtZW50OiAke21zZ31gKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIGNvbnN0IG1zZyA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogZXJyb3JcbiAgICAgIGlmIChsb2dzKSBwYXlsb2FkLmxvZ2dlci5lcnJvcihgRXJyb3IgZGVsZXRpbmcgZG9jdW1lbnQ6ICR7bXNnfWApXG4gICAgfVxuICB9XG59XG4iXSwibmFtZXMiOlsiaGFuZGxlRGVsZXRlZCIsImFyZ3MiLCJldmVudCIsInBheWxvYWQiLCJyZXNvdXJjZVR5cGUiLCJzdHJpcGVDb25maWciLCJzeW5jQ29uZmlnIiwibG9ncyIsImNvbGxlY3Rpb25TbHVnIiwiY29sbGVjdGlvbiIsImlkIiwic3RyaXBlSUQiLCJvYmplY3QiLCJldmVudE9iamVjdCIsImRhdGEiLCJpc05lc3RlZERlbGV0ZSIsImxvZ2dlciIsImluZm8iLCJwYXlsb2FkUXVlcnkiLCJmaW5kIiwid2hlcmUiLCJlcXVhbHMiLCJmb3VuZERvYyIsImRvY3MiLCJkZWxldGUiLCJlcnJvciIsIm1zZyIsIkVycm9yIiwibWVzc2FnZSJdLCJtYXBwaW5ncyI6Ijs7OzsrQkFTYUE7OztlQUFBQTs7O0FBQU4sTUFBTUEsZ0JBQStCLE9BQU9DO0lBQ2pELE1BQU0sRUFBRUMsS0FBSyxFQUFFQyxPQUFPLEVBQUVDLFlBQVksRUFBRUMsWUFBWSxFQUFFQyxVQUFVLEVBQUUsR0FBR0w7SUFFbkUsTUFBTSxFQUFFTSxJQUFJLEVBQUUsR0FBR0YsZ0JBQWdCLENBQUM7SUFFbEMsTUFBTUcsaUJBQWlCRixZQUFZRztJQUVuQyxNQUFNLEVBQ0pDLElBQUlDLFFBQVEsRUFDWkMsUUFBUUMsV0FBVyxFQUNwQixHQUFRWCxPQUFPWSxNQUFNRixVQUFVLENBQUM7SUFFakMscUZBQXFGO0lBQ3JGLE1BQU1HLGlCQUFpQkYsZ0JBQWdCVDtJQUV2QyxJQUFJVyxnQkFBZ0I7UUFDbEIsSUFBSVIsTUFDRkosUUFBUWEsTUFBTSxDQUFDQyxJQUFJLENBQ2pCLENBQUMsOENBQThDLEVBQUViLGFBQWEsc0NBQXNDLENBQUM7SUFFM0c7SUFFQSxJQUFJLENBQUNXLGdCQUFnQjtRQUNuQixJQUFJUixNQUNGSixRQUFRYSxNQUFNLENBQUNDLElBQUksQ0FDakIsQ0FBQyxLQUFLLEVBQUViLGFBQWEsZ0RBQWdELEVBQUVJLGVBQWUsdUNBQXVDLEVBQUVHLFNBQVMsSUFBSSxDQUFDO1FBR2pKLElBQUk7WUFDRixNQUFNTyxlQUFlLE1BQU1mLFFBQVFnQixJQUFJLENBQUM7Z0JBQ3RDVixZQUFZRDtnQkFDWlksT0FBTztvQkFDTFQsVUFBVTt3QkFDUlUsUUFBUVY7b0JBQ1Y7Z0JBQ0Y7WUFDRjtZQUVBLE1BQU1XLFdBQVdKLGFBQWFLLElBQUksQ0FBQyxFQUFFO1lBRXJDLElBQUksQ0FBQ0QsVUFBVTtnQkFDYixJQUFJZixNQUNGSixRQUFRYSxNQUFNLENBQUNDLElBQUksQ0FDakIsQ0FBQyxpRUFBaUUsRUFBRU4sU0FBUyxFQUFFLENBQUM7WUFFdEY7WUFFQSxJQUFJVyxVQUFVO2dCQUNaLElBQUlmLE1BQU1KLFFBQVFhLE1BQU0sQ0FBQ0MsSUFBSSxDQUFDLENBQUMsc0NBQXNDLEVBQUVLLFNBQVNaLEVBQUUsQ0FBQyxJQUFJLENBQUM7Z0JBRXhGLElBQUk7b0JBQ0ZQLFFBQVFxQixNQUFNLENBQUM7d0JBQ2JkLElBQUlZLFNBQVNaLEVBQUU7d0JBQ2ZELFlBQVlEO29CQUNkO29CQUVBLHdIQUF3SDtvQkFDeEgsaUpBQWlKO29CQUNqSixJQUFJRCxNQUNGSixRQUFRYSxNQUFNLENBQUNDLElBQUksQ0FDakIsQ0FBQyxvREFBb0QsRUFBRUssU0FBU1osRUFBRSxDQUFDLEVBQUUsQ0FBQztnQkFFNUUsRUFBRSxPQUFPZSxPQUFnQjtvQkFDdkIsTUFBTUMsTUFBTUQsaUJBQWlCRSxRQUFRRixNQUFNRyxPQUFPLEdBQUdIO29CQUNyRCxJQUFJbEIsTUFBTUosUUFBUWEsTUFBTSxDQUFDUyxLQUFLLENBQUMsQ0FBQyx5QkFBeUIsRUFBRUMsSUFBSSxDQUFDO2dCQUNsRTtZQUNGO1FBQ0YsRUFBRSxPQUFPRCxPQUFnQjtZQUN2QixNQUFNQyxNQUFNRCxpQkFBaUJFLFFBQVFGLE1BQU1HLE9BQU8sR0FBR0g7WUFDckQsSUFBSWxCLE1BQU1KLFFBQVFhLE1BQU0sQ0FBQ1MsS0FBSyxDQUFDLENBQUMseUJBQXlCLEVBQUVDLElBQUksQ0FBQztRQUNsRTtJQUNGO0FBQ0YifQ==