@tiddlywiki/mws 0.1.13 → 0.2.0

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 (118) hide show
  1. package/README.md +41 -20
  2. package/dist/metafile-esm.json +1 -1
  3. package/dist/mws.js +40249 -20249
  4. package/dist/mws.js.map +1 -1
  5. package/mws.run.mjs +28 -8
  6. package/package.json +20 -33
  7. package/plugins/client/plugin.info +1 -1
  8. package/plugins/client/src/multiwikiclientadaptor.ts +11 -39
  9. package/plugins/client/src/mws.d.ts +2 -1
  10. package/plugins/client/src/new-multiwikiclientadaptor.ts +634 -0
  11. package/plugins/client/src/types.d.ts +2531 -1036
  12. package/plugins/client/tiddlers/managetiddleraction.js +0 -5
  13. package/plugins/client/tiddlers/syncer/multiwikiclientadaptor.js +1 -1
  14. package/plugins/client/tiddlers/syncer/new-multiwikiclientadaptor.js +432 -0
  15. package/plugins/client/tiddlers/syncer/syncer.js +123 -241
  16. package/plugins/client/tsconfig.json +5 -1
  17. package/prisma/browser.ts +2 -0
  18. package/prisma/client/browser.ts +84 -0
  19. package/prisma/client/client.ts +108 -0
  20. package/prisma/client/commonInputTypes.ts +598 -0
  21. package/prisma/client/enums.ts +42 -0
  22. package/prisma/client/internal/class.ts +326 -0
  23. package/prisma/client/internal/prismaNamespace.ts +1870 -0
  24. package/prisma/client/internal/prismaNamespaceBrowser.ts +259 -0
  25. package/prisma/client/models/Bag.ts +1701 -0
  26. package/prisma/client/models/BagPermission.ts +1284 -0
  27. package/prisma/client/models/Recipe.ts +1722 -0
  28. package/prisma/client/models/RecipeBag.ts +1518 -0
  29. package/prisma/client/models/RecipePermission.ts +1284 -0
  30. package/prisma/client/models/Roles.ts +1316 -0
  31. package/prisma/client/models/Sessions.ts +1344 -0
  32. package/prisma/client/models/Settings.ts +1093 -0
  33. package/prisma/client/models/Template.ts +1477 -0
  34. package/prisma/client/models/TemplatePermission.ts +1284 -0
  35. package/prisma/client/models/Tiddler.ts +1434 -0
  36. package/prisma/client/models/TiddlerEvent.ts +1360 -0
  37. package/prisma/client/models/Users.ts +1579 -0
  38. package/prisma/client/models.ts +24 -0
  39. package/prisma/client/pjtg.ts +183 -0
  40. package/prisma/index.ts +74 -0
  41. package/prisma/migrations/20260708160259_init/migration.sql +172 -0
  42. package/prisma/migrations-v1/migration_lock.toml +3 -0
  43. package/prisma/package.json +12 -0
  44. package/prisma/schema.prisma +147 -89
  45. package/prisma/types.ts +9 -0
  46. package/public/.default.html +1 -0
  47. package/public/admin-vanilla/fish.svg +399 -0
  48. package/public/admin-vanilla/fish2.svg +389 -0
  49. package/public/admin-vanilla/main-64WYHWYI.js +1791 -0
  50. package/public/admin-vanilla/main-64WYHWYI.js.map +7 -0
  51. package/public/admin-vanilla/main-LYDE4NDJ.css +1 -0
  52. package/public/admin-vanilla/normalize.css +349 -0
  53. package/public/admin-vanilla/polyfill-ADOI2A4V.js +2 -0
  54. package/public/admin-vanilla/polyfill-ADOI2A4V.js.map +7 -0
  55. package/public/{react-admin → admin-vanilla}/site.webmanifest +1 -1
  56. package/public/admin-vanilla.html +62 -0
  57. package/public/admin-vanilla.json +1 -0
  58. package/public/{react-admin → stats}/stats.html +5 -2
  59. package/public/{react-admin → stats}/stats.js +2 -1
  60. package/scripts/build-docs.sh +30 -0
  61. package/scripts/helpers.mjs +107 -0
  62. package/scripts/json.js +8 -0
  63. package/scripts/scripts.mjs +114 -0
  64. package/prisma/client/client.d.ts +0 -1
  65. package/prisma/client/client.js +0 -3
  66. package/prisma/client/default.d.ts +0 -1
  67. package/prisma/client/default.js +0 -3
  68. package/prisma/client/edge.d.ts +0 -1
  69. package/prisma/client/edge.js +0 -297
  70. package/prisma/client/index-browser.js +0 -275
  71. package/prisma/client/index.d.ts +0 -17770
  72. package/prisma/client/index.js +0 -324
  73. package/prisma/client/package.json +0 -173
  74. package/prisma/client/query_engine_bg.js +0 -811
  75. package/prisma/client/query_engine_bg.wasm +0 -0
  76. package/prisma/client/runtime/edge-esm.js +0 -10000
  77. package/prisma/client/runtime/edge.js +0 -10036
  78. package/prisma/client/runtime/index-browser.d.ts +0 -370
  79. package/prisma/client/runtime/index-browser.js +0 -2300
  80. package/prisma/client/runtime/library.d.ts +0 -3681
  81. package/prisma/client/runtime/library.js +0 -10604
  82. package/prisma/client/runtime/react-native.js +0 -10629
  83. package/prisma/client/runtime/wasm-compiler-edge.js +0 -11238
  84. package/prisma/client/runtime/wasm-engine-edge.js +0 -7801
  85. package/prisma/client/schema.prisma +0 -156
  86. package/prisma/client/wasm-edge-light-loader.mjs +0 -4
  87. package/prisma/client/wasm-worker-loader.mjs +0 -4
  88. package/prisma/client/wasm.d.ts +0 -1
  89. package/prisma/client/wasm.js +0 -304
  90. package/prisma/global.ts +0 -53
  91. package/public/react-admin/chunk-YALWN5OT.js +0 -2
  92. package/public/react-admin/esm-L4WLVWJN.js +0 -3
  93. package/public/react-admin/esm-L4WLVWJN.js.map +0 -7
  94. package/public/react-admin/esm-QMNGI3LF.js +0 -3
  95. package/public/react-admin/esm-QMNGI3LF.js.map +0 -7
  96. package/public/react-admin/index.html +0 -36
  97. package/public/react-admin/main.js +0 -268
  98. package/public/react-admin/main.js.map +0 -7
  99. package/public/react-admin/stats.json +0 -1
  100. package/scripts.mjs +0 -142
  101. /package/prisma/{migrations → migrations-v1}/20250606001949_init/migration.sql +0 -0
  102. /package/prisma/{migrations → migrations-v1}/20250613000526_remove_group/migration.sql +0 -0
  103. /package/prisma/{migrations → migrations-v1}/20250620014502_settings/migration.sql +0 -0
  104. /package/prisma/{migrations → migrations-v1}/20250707205229_recipes/migration.sql +0 -0
  105. /package/public/{react-admin → admin-vanilla}/android-chrome-192x192.png +0 -0
  106. /package/public/{react-admin → admin-vanilla}/android-chrome-512x512.png +0 -0
  107. /package/public/{react-admin → admin-vanilla}/apple-touch-icon.png +0 -0
  108. /package/public/{react-admin → admin-vanilla}/favicon-16x16.png +0 -0
  109. /package/public/{react-admin → admin-vanilla}/favicon-32x32.png +0 -0
  110. /package/public/{react-admin → admin-vanilla}/favicon.ico +0 -0
  111. /package/public/{react-admin → admin-vanilla}/favicon.png +0 -0
  112. /package/public/{react-admin/chunk-YALWN5OT.js.map → admin-vanilla/main-LYDE4NDJ.css.map} +0 -0
  113. /package/public/{react-admin → admin-vanilla}/missing-favicon.png +0 -0
  114. /package/public/{react-admin → admin-vanilla}/motovun-jack.jpg +0 -0
  115. /package/public/{react-admin → admin-vanilla}/mws-icon.png +0 -0
  116. /package/public/{react-admin → admin-vanilla}/vite.svg +0 -0
  117. /package/public/{react-admin → stats}/stats.css +0 -0
  118. /package/public/{react-admin → stats}/stats.svg +0 -0
@@ -5,10 +5,7 @@ module-type: widget
5
5
 
6
6
  A widget to manage tiddler actions.
7
7
  \*/
8
- (function(){
9
8
 
10
- /*jslint node: true, browser: true */
11
- /*global $tw: false */
12
9
  "use strict";
13
10
 
14
11
  var Widget = require("$:/core/modules/widgets/widget.js").widget;
@@ -61,5 +58,3 @@ ManageTiddlerAction.prototype.refresh = function(changedTiddlers) {
61
58
  };
62
59
 
63
60
  exports["action-managetiddler"] = ManageTiddlerAction;
64
-
65
- })();
@@ -37,7 +37,7 @@ class MultiWikiClientAdaptor {
37
37
  this.error = null;
38
38
  this.wiki = options.wiki;
39
39
  this.host = this.getHost();
40
- this.recipe = this.wiki.getTiddlerText("$:/config/multiwikiclient/recipe");
40
+ this.recipe = this.wiki.getTiddlerText("$:/config/multiwikiclient/recipe", "default");
41
41
  this.useServerSentEvents = this.wiki.getTiddlerText(ENABLE_SSE_TIDDLER) === "yes";
42
42
  this.isDevMode = this.wiki.getTiddlerText(IS_DEV_MODE_TIDDLER) === "yes";
43
43
  this.useGzipStream = this.wiki.getTiddlerText(ENABLE_GZIP_STREAM_TIDDLER) === "yes";
@@ -0,0 +1,432 @@
1
+ /*\
2
+ title: $:/plugins/mws/client/new-multiwikiclientadaptor.js
3
+ type: application/javascript
4
+ module-type: syncadaptor
5
+
6
+ A sync adaptor module for synchronising with MultiWikiServer-compatible servers.
7
+
8
+ It has three key areas of concern:
9
+
10
+ * Basic operations like put, get, and delete a tiddler on the server
11
+ * Real time updates from the server (handled by SSE)
12
+ * Bags and recipes, which are unknown to the syncer
13
+
14
+ A key aspect of the design is that the syncer never overlaps basic server operations; it waits for the
15
+ previous operation to complete before sending a new one.
16
+
17
+ \*/
18
+ // the blank line is important, and so is the following use strict
19
+ "use strict";
20
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
21
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
22
+ return new (P || (P = Promise))(function (resolve, reject) {
23
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
24
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
25
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
26
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
27
+ });
28
+ };
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ // ---------------------------------------------------------------------------
31
+ // Constants
32
+ // ---------------------------------------------------------------------------
33
+ const CONFIG_HOST_TIDDLER = "$:/config/multiwikiclient/host";
34
+ const DEFAULT_HOST_TIDDLER = "$protocol$//$host$/";
35
+ const CONFIG_RECIPE_TIDDLER = "$:/config/multiwikiclient/recipe";
36
+ const IS_DEV_MODE_TIDDLER = "$:/state/multiwikiclient/dev-mode";
37
+ const LAST_REVISION_ID_TIDDLER = "$:/state/multiwikiclient/recipe/last_revision_id";
38
+ const MWC_STATE_TIDDLER_PREFIX = "$:/state/multiwikiclient/";
39
+ const BAG_STATE_TIDDLER = "$:/state/multiwikiclient/tiddlers/bag";
40
+ const REVISION_STATE_TIDDLER = "$:/state/multiwikiclient/tiddlers/revision";
41
+ // ---------------------------------------------------------------------------
42
+ // Adaptor
43
+ // ---------------------------------------------------------------------------
44
+ class MultiWikiClientAdaptor {
45
+ constructor(options) {
46
+ this.name = "multiwikiclient";
47
+ this.syncer = null;
48
+ this.isLoggedIn = false;
49
+ this.isReadOnly = true;
50
+ this.offline = false;
51
+ this.username = "";
52
+ this.error = null;
53
+ this.lastSeq = "0";
54
+ this.initialLoadDone = false;
55
+ /** title → bag name, populated on load/save */
56
+ this.tiddlerBag = new Map();
57
+ /** title → revision, populated on save */
58
+ this.tiddlerRevision = new Map();
59
+ this.wiki = options.wiki;
60
+ this.host = this.getHost();
61
+ this.recipe = this.wiki.getTiddlerText(CONFIG_RECIPE_TIDDLER, "");
62
+ this.isDevMode = this.wiki.getTiddlerText(IS_DEV_MODE_TIDDLER) === "yes";
63
+ this.lastSeq = this.wiki.getTiddlerText(LAST_REVISION_ID_TIDDLER, "0");
64
+ this.initialLoadDone = this.lastSeq !== "0";
65
+ this.logger = new $tw.utils.Logger("MultiWikiClientAdaptor");
66
+ }
67
+ isReady() { return true; }
68
+ setLoggerSaveBuffer(logger) { this.logger.setSaveBuffer(logger); }
69
+ registerSyncer(syncer) { this.syncer = syncer; }
70
+ isStateTiddler(title) {
71
+ return title.startsWith(MWC_STATE_TIDDLER_PREFIX);
72
+ }
73
+ setTiddlerInfo(title, bag, revision) {
74
+ if (bag) {
75
+ this.tiddlerBag.set(title, bag);
76
+ this.wiki.setText(BAG_STATE_TIDDLER, null, title, bag, { suppressTimestamp: true });
77
+ }
78
+ else {
79
+ this.tiddlerBag.delete(title);
80
+ this.wiki.setText(BAG_STATE_TIDDLER, null, title, undefined, { suppressTimestamp: true });
81
+ }
82
+ if (revision) {
83
+ this.tiddlerRevision.set(title, revision);
84
+ this.wiki.setText(REVISION_STATE_TIDDLER, null, title, revision, { suppressTimestamp: true });
85
+ }
86
+ }
87
+ clearTiddlerInfo(title) {
88
+ this.tiddlerBag.delete(title);
89
+ this.tiddlerRevision.delete(title);
90
+ this.wiki.setText(BAG_STATE_TIDDLER, null, title, undefined, { suppressTimestamp: true });
91
+ this.wiki.setText(REVISION_STATE_TIDDLER, null, title, undefined, { suppressTimestamp: true });
92
+ }
93
+ setLastSeq(seq) {
94
+ this.lastSeq = seq;
95
+ this.wiki.setText(LAST_REVISION_ID_TIDDLER, null, "text", seq, { suppressTimestamp: true });
96
+ }
97
+ getTiddlerRevision(title) {
98
+ var _a;
99
+ return (_a = this.wiki.extractTiddlerDataItem(REVISION_STATE_TIDDLER, title)) !== null && _a !== void 0 ? _a : "";
100
+ }
101
+ getTiddlerInfo(tiddler) {
102
+ var _a, _b;
103
+ const title = tiddler.fields.title;
104
+ const bag = (_a = this.wiki.extractTiddlerDataItem(BAG_STATE_TIDDLER, title)) !== null && _a !== void 0 ? _a : this.tiddlerBag.get(title);
105
+ const revision = (_b = this.wiki.extractTiddlerDataItem(REVISION_STATE_TIDDLER, title)) !== null && _b !== void 0 ? _b : this.tiddlerRevision.get(title);
106
+ return bag && revision ? { bag, revision, title } : undefined;
107
+ }
108
+ getHost() {
109
+ let text = this.wiki.getTiddlerText(CONFIG_HOST_TIDDLER, DEFAULT_HOST_TIDDLER);
110
+ [
111
+ { name: "protocol", value: document.location.protocol },
112
+ { name: "host", value: document.location.host },
113
+ { name: "pathname", value: document.location.pathname },
114
+ ].forEach(({ name, value }) => {
115
+ text = $tw.utils.replaceString(text, new RegExp("\\$" + name + "\\$", "mg"), value);
116
+ });
117
+ return text;
118
+ }
119
+ // -------------------------------------------------------------------------
120
+ // Status
121
+ // -------------------------------------------------------------------------
122
+ getStatus(callback) {
123
+ return __awaiter(this, void 0, void 0, function* () {
124
+ var _a, _b, _c, _d;
125
+ const [ok, , result] = yield this.recipeRequest({ method: "GET", url: "/status" });
126
+ if (!ok && (result === null || result === void 0 ? void 0 : result.status) === 0) {
127
+ this.offline = true;
128
+ this.isLoggedIn = false;
129
+ this.isReadOnly = true;
130
+ this.username = "(offline)";
131
+ this.error = "The webpage is forbidden from contacting the server.";
132
+ }
133
+ else if (ok) {
134
+ const status = result.responseJSON;
135
+ this.offline = false;
136
+ this.error = null;
137
+ this.isLoggedIn = (_a = status === null || status === void 0 ? void 0 : status.isLoggedIn) !== null && _a !== void 0 ? _a : false;
138
+ this.username = (_b = status === null || status === void 0 ? void 0 : status.username) !== null && _b !== void 0 ? _b : "(anon)";
139
+ this.isReadOnly = !((_d = (_c = status === null || status === void 0 ? void 0 : status.bags) === null || _c === void 0 ? void 0 : _c.some(b => b.canUserWrite)) !== null && _d !== void 0 ? _d : false);
140
+ }
141
+ else {
142
+ this.error = `Server error ${result === null || result === void 0 ? void 0 : result.status}`;
143
+ }
144
+ callback(this.error, this.isLoggedIn, this.username, this.isReadOnly, false);
145
+ });
146
+ }
147
+ // -------------------------------------------------------------------------
148
+ // Update polling
149
+ // -------------------------------------------------------------------------
150
+ getUpdatedTiddlers(_syncer, callback) {
151
+ return __awaiter(this, void 0, void 0, function* () {
152
+ if (this.offline)
153
+ return callback(null);
154
+ try {
155
+ if (!this.initialLoadDone) {
156
+ // Fetch full list + current lastSeq in parallel on first load
157
+ const [[listOk, , listResult], [updOk, , updResult]] = yield Promise.all([
158
+ this.recipeRequest({ method: "GET", url: "/list.json" }),
159
+ this.recipeRequest({ method: "GET", url: "/updates", queryParams: { since: "0" } }),
160
+ ]);
161
+ if (!listOk)
162
+ throw new Error("Failed to fetch tiddler list");
163
+ if (!updOk)
164
+ throw new Error("Failed to fetch updates");
165
+ const list = listResult.responseJSON;
166
+ const upd = updResult.responseJSON;
167
+ this.setLastSeq(upd.lastSeq);
168
+ this.initialLoadDone = true;
169
+ callback(null, { modifications: list.map(t => t.title), deletions: [] });
170
+ }
171
+ else {
172
+ const [ok, , result] = yield this.recipeRequest({
173
+ method: "GET",
174
+ url: "/updates",
175
+ queryParams: { since: this.lastSeq },
176
+ });
177
+ if (!ok)
178
+ throw new Error("Failed to fetch updates");
179
+ const upd = result.responseJSON;
180
+ this.setLastSeq(upd.lastSeq);
181
+ callback(null, { modifications: upd.modifications, deletions: upd.deletions });
182
+ }
183
+ }
184
+ catch (e) {
185
+ callback(e);
186
+ }
187
+ });
188
+ }
189
+ // -------------------------------------------------------------------------
190
+ // Batch operations (new API)
191
+ // -------------------------------------------------------------------------
192
+ loadTiddlers(options) {
193
+ return __awaiter(this, void 0, void 0, function* () {
194
+ const { titles, onNext, onDone, onError } = options;
195
+ try {
196
+ const results = yield this.batchOp("read", { titles });
197
+ for (const item of results) {
198
+ if (!item)
199
+ continue;
200
+ this.setTiddlerInfo(item.fields.title, item.info.readFrom, typeof item.fields.revision === "string" ? item.fields.revision : undefined);
201
+ onNext(item.fields);
202
+ }
203
+ onDone();
204
+ }
205
+ catch (e) {
206
+ onError(e);
207
+ }
208
+ });
209
+ }
210
+ saveTiddlers(options) {
211
+ return __awaiter(this, void 0, void 0, function* () {
212
+ var _a, _b, _c, _d, _e, _f;
213
+ const { tiddlers, onNext, onDone, onError } = options;
214
+ try {
215
+ const results = yield this.batchOp("save", {
216
+ tiddlers: tiddlers.map(t => t.getFieldStrings()),
217
+ });
218
+ for (const item of results) {
219
+ const bag = (_b = (_a = item.info.writeTo) !== null && _a !== void 0 ? _a : item.info.readFrom) !== null && _b !== void 0 ? _b : "";
220
+ this.setTiddlerInfo(item.title, bag || null, (_c = item.revision) !== null && _c !== void 0 ? _c : "");
221
+ if ((_d = $tw.browserStorage) === null || _d === void 0 ? void 0 : _d.isEnabled())
222
+ $tw.browserStorage.removeTiddlerFromLocalStorage(item.title);
223
+ onNext(item.title, { bag, revision: (_e = item.revision) !== null && _e !== void 0 ? _e : "", title: item.title }, (_f = item.revision) !== null && _f !== void 0 ? _f : "");
224
+ }
225
+ onDone();
226
+ }
227
+ catch (e) {
228
+ onError(e);
229
+ }
230
+ });
231
+ }
232
+ deleteTiddlers(options) {
233
+ return __awaiter(this, void 0, void 0, function* () {
234
+ const { titles, onNext, onDone, onError } = options;
235
+ try {
236
+ const results = yield this.batchOp("delete", { titles });
237
+ for (const item of results) {
238
+ this.clearTiddlerInfo(item.title);
239
+ onNext(item.title);
240
+ }
241
+ onDone();
242
+ }
243
+ catch (e) {
244
+ onError(e);
245
+ }
246
+ });
247
+ }
248
+ // -------------------------------------------------------------------------
249
+ // Single-tiddler operations (fallback for older server versions)
250
+ // -------------------------------------------------------------------------
251
+ saveTiddler(tiddler, callback) {
252
+ return __awaiter(this, void 0, void 0, function* () {
253
+ var _a, _b, _c, _d, _e, _f;
254
+ const title = tiddler.fields.title;
255
+ if (title === "$:/StoryList" || this.isReadOnly || this.isStateTiddler(title))
256
+ return callback(null);
257
+ try {
258
+ const results = yield this.batchOp("save", { tiddlers: [tiddler.getFieldStrings()] });
259
+ const item = results[0];
260
+ if (!item)
261
+ return callback(new Error("No result returned"));
262
+ const bag = (_b = (_a = item.info.writeTo) !== null && _a !== void 0 ? _a : item.info.readFrom) !== null && _b !== void 0 ? _b : "";
263
+ this.setTiddlerInfo(title, bag || null, (_c = item.revision) !== null && _c !== void 0 ? _c : "");
264
+ if ((_d = $tw.browserStorage) === null || _d === void 0 ? void 0 : _d.isEnabled())
265
+ $tw.browserStorage.removeTiddlerFromLocalStorage(title);
266
+ callback(null, { bag, revision: (_e = item.revision) !== null && _e !== void 0 ? _e : "", title }, (_f = item.revision) !== null && _f !== void 0 ? _f : "");
267
+ }
268
+ catch (e) {
269
+ callback(e);
270
+ }
271
+ });
272
+ }
273
+ loadTiddler(title, callback, _options) {
274
+ return __awaiter(this, void 0, void 0, function* () {
275
+ try {
276
+ const results = yield this.batchOp("read", { titles: [title] });
277
+ const item = results[0];
278
+ if (!item)
279
+ return callback(null, null);
280
+ this.setTiddlerInfo(title, item.info.readFrom, typeof item.fields.revision === "string" ? item.fields.revision : undefined);
281
+ callback(null, item.fields);
282
+ }
283
+ catch (e) {
284
+ callback(e);
285
+ }
286
+ });
287
+ }
288
+ deleteTiddler(title, callback, _options) {
289
+ return __awaiter(this, void 0, void 0, function* () {
290
+ if (this.isReadOnly)
291
+ return callback(null);
292
+ try {
293
+ const results = yield this.batchOp("delete", { titles: [title] });
294
+ const item = results[0];
295
+ if (!item)
296
+ return callback(new Error("No result returned"));
297
+ this.clearTiddlerInfo(title);
298
+ callback(null, null);
299
+ }
300
+ catch (e) {
301
+ callback(e);
302
+ }
303
+ });
304
+ }
305
+ // -------------------------------------------------------------------------
306
+ // HTTP helpers
307
+ // -------------------------------------------------------------------------
308
+ batchOp(op, body) {
309
+ return __awaiter(this, void 0, void 0, function* () {
310
+ const [ok, err, result] = yield this.recipeRequest({
311
+ method: "PUT",
312
+ url: "/batch/" + op,
313
+ requestBodyString: JSON.stringify(body),
314
+ headers: { "content-type": "application/json" },
315
+ });
316
+ if (!ok)
317
+ throw err;
318
+ if (!result.responseJSON)
319
+ throw new Error("No response JSON from batch/" + op);
320
+ return result.responseJSON;
321
+ });
322
+ }
323
+ recipeRequest(options) {
324
+ return __awaiter(this, void 0, void 0, function* () {
325
+ if (!options.url.startsWith("/"))
326
+ throw new Error("URL must start with /");
327
+ const isDevMode = this.isDevMode;
328
+ return httpRequest(Object.assign(Object.assign({}, options), { responseType: "blob", url: this.host + "recipe/" + encodeURIComponent(this.recipe) + options.url })).then((e) => __awaiter(this, void 0, void 0, function* () {
329
+ var _a;
330
+ if (!e.ok)
331
+ return [false, new Error(`Server returned ${e.status}: ${(_a = e.headers.get("x-reason")) !== null && _a !== void 0 ? _a : "(no reason)"}`), Object.assign(Object.assign({}, e), { responseJSON: undefined })];
332
+ let responseString;
333
+ if (e.headers.get("x-gzip-stream") === "yes") {
334
+ responseString = yield new Promise((resolve) => {
335
+ let s = "";
336
+ const gz = new fflate.AsyncGunzip((err, chunk, final) => {
337
+ if (err)
338
+ return;
339
+ s += fflate.strFromU8(chunk);
340
+ if (final)
341
+ resolve(s);
342
+ });
343
+ if (isDevMode)
344
+ gz.onmember = m => console.log("gunzip member", m);
345
+ readBlobAsArrayBuffer(e.response).then(buf => {
346
+ gz.push(new Uint8Array(buf));
347
+ gz.push(new Uint8Array(0), true);
348
+ });
349
+ });
350
+ }
351
+ else {
352
+ responseString = fflate.strFromU8(new Uint8Array(yield readBlobAsArrayBuffer(e.response)));
353
+ }
354
+ return [true, undefined, Object.assign(Object.assign({}, e), { responseJSON: e.status === 200 ? tryParseJSON(responseString) : undefined })];
355
+ }), e => [false, e, undefined]);
356
+ });
357
+ }
358
+ }
359
+ // ---------------------------------------------------------------------------
360
+ // Utilities
361
+ // ---------------------------------------------------------------------------
362
+ function tryParseJSON(s) {
363
+ try {
364
+ return JSON.parse(s);
365
+ }
366
+ catch (e) {
367
+ console.error("JSON parse error", e);
368
+ return undefined;
369
+ }
370
+ }
371
+ function httpRequest(options) {
372
+ return new Promise((resolve, reject) => {
373
+ options.method = options.method.toUpperCase();
374
+ const url = new URL(options.url, location.href);
375
+ paramsInput(options.queryParams).forEach((v, k) => url.searchParams.append(k, v));
376
+ const headers = new Headers(options.headers || {});
377
+ const request = new XMLHttpRequest();
378
+ request.responseType = options.responseType;
379
+ request.open(options.method, url, true);
380
+ if (!headers.has("content-type"))
381
+ headers.set("content-type", "application/x-www-form-urlencoded; charset=UTF-8");
382
+ if (!headers.has("x-requested-with"))
383
+ headers.set("x-requested-with", "TiddlyWiki");
384
+ headers.set("accept", "application/json");
385
+ headers.forEach((v, k) => request.setRequestHeader(k, v));
386
+ request.onreadystatechange = function () {
387
+ var _a;
388
+ if (this.readyState !== 4)
389
+ return;
390
+ const h = new Headers();
391
+ (_a = request.getAllResponseHeaders()) === null || _a === void 0 ? void 0 : _a.trim().split(/[\r\n]+/).forEach(line => {
392
+ var _a;
393
+ const parts = line.split(": ");
394
+ const key = (_a = parts.shift()) === null || _a === void 0 ? void 0 : _a.toLowerCase();
395
+ if (key)
396
+ h.append(key, parts.join(": "));
397
+ });
398
+ resolve({ ok: this.status >= 200 && this.status < 300, status: this.status, statusText: this.statusText, response: this.response, headers: h });
399
+ };
400
+ request.send(options.requestBodyString);
401
+ });
402
+ function paramsInput(input) {
403
+ if (!input)
404
+ return new URLSearchParams();
405
+ if (input instanceof URLSearchParams)
406
+ return input;
407
+ if (Array.isArray(input) || typeof input === "string")
408
+ return new URLSearchParams(input);
409
+ const params = new URLSearchParams();
410
+ for (const key in input) {
411
+ if (Object.prototype.hasOwnProperty.call(input, key)) {
412
+ params.append(key, input[key]);
413
+ }
414
+ }
415
+ return params;
416
+ }
417
+ }
418
+ function readBlobAsArrayBuffer(blob) {
419
+ return new Promise((resolve, reject) => {
420
+ const reader = new FileReader();
421
+ reader.onload = () => resolve(reader.result);
422
+ reader.onerror = () => reject(new Error("Error reading blob"));
423
+ reader.readAsArrayBuffer(blob);
424
+ });
425
+ }
426
+ // ---------------------------------------------------------------------------
427
+ // Export
428
+ // ---------------------------------------------------------------------------
429
+ if ($tw.browser && document.location.protocol.startsWith("http")) {
430
+ exports.adaptorClass = MultiWikiClientAdaptor;
431
+ }
432
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV3LW11bHRpd2lraWNsaWVudGFkYXB0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbmV3LW11bHRpd2lraWNsaWVudGFkYXB0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnQkc7QUFFSCxrRUFBa0U7QUFDbEUsWUFBWSxDQUFDOzs7Ozs7Ozs7OztBQXNLYiw4RUFBOEU7QUFDOUUsWUFBWTtBQUNaLDhFQUE4RTtBQUU5RSxNQUFNLG1CQUFtQixHQUFHLGdDQUFnQyxDQUFDO0FBQzdELE1BQU0sb0JBQW9CLEdBQUcscUJBQXFCLENBQUM7QUFDbkQsTUFBTSxxQkFBcUIsR0FBRyxrQ0FBa0MsQ0FBQztBQUNqRSxNQUFNLG1CQUFtQixHQUFHLG1DQUFtQyxDQUFDO0FBQ2hFLE1BQU0sd0JBQXdCLEdBQUcsa0RBQWtELENBQUM7QUFDcEYsTUFBTSx3QkFBd0IsR0FBRywyQkFBMkIsQ0FBQztBQUM3RCxNQUFNLGlCQUFpQixHQUFHLHVDQUF1QyxDQUFDO0FBQ2xFLE1BQU0sc0JBQXNCLEdBQUcsNENBQTRDLENBQUM7QUFrQzVFLDhFQUE4RTtBQUM5RSxVQUFVO0FBQ1YsOEVBQThFO0FBRTlFLE1BQU0sc0JBQXNCO0lBdUIzQixZQUFZLE9BQXVCO1FBdEJuQyxTQUFJLEdBQUcsaUJBQWlCLENBQUM7UUFPakIsV0FBTSxHQUFrQyxJQUFJLENBQUM7UUFFN0MsZUFBVSxHQUFHLEtBQUssQ0FBQztRQUNuQixlQUFVLEdBQUcsSUFBSSxDQUFDO1FBQ2xCLFlBQU8sR0FBRyxLQUFLLENBQUM7UUFDaEIsYUFBUSxHQUFHLEVBQUUsQ0FBQztRQUN0QixVQUFLLEdBQWtCLElBQUksQ0FBQztRQUVwQixZQUFPLEdBQUcsR0FBRyxDQUFDO1FBQ2Qsb0JBQWUsR0FBRyxLQUFLLENBQUM7UUFDaEMsK0NBQStDO1FBQ3ZDLGVBQVUsR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztRQUMvQywwQ0FBMEM7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QUM7QUFDL0MsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXFxcbnRpdGxlOiAkOi9wbHVnaW5zL213cy9jbGllbnQvbmV3LW11bHRpd2lraWNsaWVudGFkYXB0b3IuanNcbnR5cGU6IGFwcGxpY2F0aW9uL2phdmFzY3JpcHRcbm1vZHVsZS10eXBlOiBzeW5jYWRhcHRvclxuXG5BIHN5bmMgYWRhcHRvciBtb2R1bGUgZm9yIHN5bmNocm9uaXNpbmcgd2l0aCBNdWx0aVdpa2lTZXJ2ZXItY29tcGF0aWJsZSBzZXJ2ZXJzLiBcblxuSXQgaGFzIHRocmVlIGtleSBhcmVhcyBvZiBjb25jZXJuOlxuXG4qIEJhc2ljIG9wZXJhdGlvbnMgbGlrZSBwdXQsIGdldCwgYW5kIGRlbGV0ZSBhIHRpZGRsZXIgb24gdGhlIHNlcnZlclxuKiBSZWFsIHRpbWUgdXBkYXRlcyBmcm9tIHRoZSBzZXJ2ZXIgKGhhbmRsZWQgYnkgU1NFKVxuKiBCYWdzIGFuZCByZWNpcGVzLCB3aGljaCBhcmUgdW5rbm93biB0byB0aGUgc3luY2VyXG5cbkEga2V5IGFzcGVjdCBvZiB0aGUgZGVzaWduIGlzIHRoYXQgdGhlIHN5bmNlciBuZXZlciBvdmVybGFwcyBiYXNpYyBzZXJ2ZXIgb3BlcmF0aW9uczsgaXQgd2FpdHMgZm9yIHRoZVxucHJldmlvdXMgb3BlcmF0aW9uIHRvIGNvbXBsZXRlIGJlZm9yZSBzZW5kaW5nIGEgbmV3IG9uZS5cblxuXFwqL1xuXG4vLyB0aGUgYmxhbmsgbGluZSBpcyBpbXBvcnRhbnQsIGFuZCBzbyBpcyB0aGUgZm9sbG93aW5nIHVzZSBzdHJpY3RcblwidXNlIHN0cmljdFwiO1xuXG4vLyBpbXBvcnQgdHlwZSB7IFNlcnZlckV2ZW50c01hcCB9IGZyb20gJ0B0aWRkbHl3aWtpL2V2ZW50cyc7XG4vLyBpbXBvcnQgdHlwZSB7IFpvZFJvdXRlLCBXaWtpU3RhdHVzUm91dGVzLCBXaWtpUmVjaXBlUm91dGVzIH0gZnJvbSAnQHRpZGRseXdpa2kvbXdzJztcbi8vIGltcG9ydCB0eXBlIHsgem9kIH0gZnJvbSAnQHRpZGRseXdpa2kvc2VydmVyJztcbmltcG9ydCB0eXBlIHsgU3luY2VyLCBUaWRkbGVyLCBUaWRkbGVyRmllbGRzLCBXaWtpIH0gZnJvbSAndGlkZGx5d2lraSc7XG5cbi8vIGltcG9ydCB7fSBmcm9tIFwiQHRpZGRseXdpa2kvbXdzLXByaXNtYVwiO1xuZGVjbGFyZSBnbG9iYWwgeyBjb25zdCBmZmxhdGU6IHR5cGVvZiBpbXBvcnQoXCIuL2ZmbGF0ZVwiKTsgfVxuZGVjbGFyZSBjb25zdCBzZWxmOiBuZXZlcjtcblxuZGVjbGFyZSBjbGFzcyBMb2dnZXIge1xuXHRjb25zdHJ1Y3Rvcihjb21wb25lbnROYW1lOiBhbnksIG9wdGlvbnM6IGFueSk7XG5cdGNvbXBvbmVudE5hbWU6IGFueTtcblx0Y29sb3VyOiBhbnk7XG5cdGVuYWJsZTogYW55O1xuXHRzYXZlOiBhbnk7XG5cdHNhdmVMaW1pdDogYW55O1xuXHRzYXZlQnVmZmVyTG9nZ2VyOiB0aGlzO1xuXHRidWZmZXI6IHN0cmluZztcblx0YWxlcnRDb3VudDogbnVtYmVyO1xuXHRzZXRTYXZlQnVmZmVyKGxvZ2dlcjogYW55KTogdm9pZDtcblx0bG9nKC4uLmFyZ3M6IGFueVtdKTogYW55O1xuXHRnZXRCdWZmZXIoKTogc3RyaW5nO1xuXHR0YWJsZSh2YWx1ZTogYW55KTogdm9pZDtcblx0YWxlcnQoLi4uYXJnczogYW55W10pOiB2b2lkO1xuXHRjbGVhckFsZXJ0cygpOiB2b2lkO1xufVxuXG5kZWNsYXJlIG1vZHVsZSAndGlkZGx5d2lraScge1xuXHRleHBvcnQgaW50ZXJmYWNlIFN5bmNlcjxBRD4ge1xuXHRcdHdpa2k6IFdpa2k7XG5cdFx0bG9nZ2VyOiBMb2dnZXI7XG5cdFx0dGlkZGxlckluZm86IFJlY29yZDxzdHJpbmcsIHtcblx0XHRcdGNoYW5nZUNvdW50OiBudW1iZXIsXG5cdFx0XHRhZGFwdG9ySW5mbzogQUQsXG5cdFx0XHRyZXZpc2lvbjogc3RyaW5nLFxuXHRcdFx0dGltZXN0YW1wTGFzdFNhdmVkOiBEYXRlXG5cdFx0fT47XG5cdFx0ZW5xdWV1ZUxvYWRUaWRkbGVyKHRpdGxlOiBzdHJpbmcpOiB2b2lkO1xuXHRcdHN0b3JlVGlkZGxlcih0aWRkbGVyOiBUaWRkbGVyKTogdm9pZDtcblx0XHRwcm9jZXNzVGFza1F1ZXVlKCk6IHZvaWQ7XG5cdFx0c3luY0Zyb21TZXJ2ZXIoKTogdm9pZDtcblx0fVxuXHRpbnRlcmZhY2UgSVRpZGRseVdpa2kge1xuXHRcdGJyb3dzZXJTdG9yYWdlOiBhbnk7XG5cdH1cbn1cblxudHlwZSBTZXJ2ZXJTdGF0dXNDYWxsYmFjayA9IChcblx0ZXJyOiBhbnksXG5cdC8qKiBcblx0ICogJDovc3RhdHVzL0lzTG9nZ2VkSW4gbW9zdGx5IGFwcGVhcnMgYWxvbmdzaWRlIHRoZSB1c2VybmFtZSBcblx0ICogb3Igb3RoZXIgbG9naW4tY29uZGl0aW9uYWwgYmVoYXZpb3IuIFxuXHQgKi9cblx0aXNMb2dnZWRJbj86IGJvb2xlYW4sXG5cdC8qKlxuXHQgKiAkOi9zdGF0dXMvVXNlck5hbWUgaXMgc3RpbGwgdXNlZCBmb3IgdGhpbmdzIGxpa2UgZHJhZnRzIGV2ZW4gaWYgdGhlIFxuXHQgKiB1c2VyIGlzbid0IGxvZ2dlZCBpbiwgYWx0aG91Z2ggdGhlIHVzZXJuYW1lIGlzIGxlc3MgbGlrZWx5IHRvIGJlIHNob3duIFxuXHQgKiB0byB0aGUgdXNlci4gXG5cdCAqL1xuXHR1c2VybmFtZT86IHN0cmluZyxcblx0LyoqIFxuXHQgKiAkOi9zdGF0dXMvSXNSZWFkT25seSBwdXRzIHRoZSBVSSBpbiByZWFkb25seSBtb2RlLCBcblx0ICogYnV0IGRvZXMgbm90IHByZXZlbnQgYXV0b21hdGljIGNoYW5nZXMgZnJvbSBhdHRlbXB0aW5nIHRvIHNhdmUuIFxuXHQgKi9cblx0aXNSZWFkT25seT86IGJvb2xlYW4sXG5cdC8qKiBcblx0ICogJDovc3RhdHVzL0lzQW5vbnltb3VzIGRvZXMgbm90IGFwcGVhciBhbnl3aGVyZSBpbiB0aGUgVFc1IHJlcG8hIFxuXHQgKiBTbyBpdCBoYXMgbm8gYXBwYXJlbnQgcHVycG9zZS4gXG5cdCAqL1xuXHRpc0Fub255bW91cz86IGJvb2xlYW5cbikgPT4gdm9pZFxuXG5pbnRlcmZhY2UgU3luY0FkYXB0b3I8QUQ+IHtcblx0bmFtZT86IHN0cmluZztcblxuXHRpc1JlYWR5PygpOiBib29sZWFuO1xuXG5cdHJlZ2lzdGVyU3luY2VyPyhzeW5jZXI6IFN5bmNlcjxBRD4pOiB2b2lkO1xuXG5cdGdldFN0YXR1cz8oXG5cdFx0Y2I6IFNlcnZlclN0YXR1c0NhbGxiYWNrXG5cdCk6IHZvaWQ7XG5cblx0Z2V0U2tpbm55VGlkZGxlcnM/KFxuXHRcdGNiOiAoZXJyOiBhbnksIHRpZGRsZXJGaWVsZHM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz5bXSkgPT4gdm9pZFxuXHQpOiB2b2lkO1xuXHRnZXRVcGRhdGVkVGlkZGxlcnM/KFxuXHRcdHN5bmNlcjogU3luY2VyPEFEPixcblx0XHRjYjogKFxuXHRcdFx0ZXJyOiBhbnksXG5cdFx0XHQvKiogQXJyYXlzIG9mIHRpdGxlcyB0aGF0IGhhdmUgYmVlbiBtb2RpZmllZCBvciBkZWxldGVkICovXG5cdFx0XHR1cGRhdGVzPzogeyBtb2RpZmljYXRpb25zOiBzdHJpbmdbXSwgZGVsZXRpb25zOiBzdHJpbmdbXSB9XG5cdFx0KSA9PiB2b2lkXG5cdCk6IHZvaWQ7XG5cblx0LyoqIFxuXHQgKiB1c2VkIHRvIG92ZXJyaWRlIHRoZSBkZWZhdWx0IFN5bmNlciBnZXRUaWRkbGVyUmV2aXNpb24gYmVoYXZpb3Jcblx0ICogb2YgcmV0dXJuaW5nIHRoZSByZXZpc2lvbiBmaWVsZFxuXHQgKiBcblx0ICovXG5cdGdldFRpZGRsZXJSZXZpc2lvbj8odGl0bGU6IHN0cmluZyk6IHN0cmluZztcblx0LyoqIFxuXHQgKiB1c2VkIHRvIGdldCB0aGUgYWRhcHRlciBpbmZvIGZyb20gYSB0aWRkbGVyIGluIHNpdHVhdGlvbnNcblx0ICogb3RoZXIgdGhhbiB0aGUgc2F2ZVRpZGRsZXIgY2FsbGJhY2tcblx0ICovXG5cdGdldFRpZGRsZXJJbmZvKHRpZGRsZXI6IFRpZGRsZXIpOiBBRCB8IHVuZGVmaW5lZDtcblxuXHRzYXZlVGlkZGxlcihcblx0XHR0aWRkbGVyOiBhbnksXG5cdFx0Y2I6IChcblx0XHRcdGVycjogYW55LFxuXHRcdFx0YWRhcHRvckluZm8/OiBBRCxcblx0XHRcdHJldmlzaW9uPzogc3RyaW5nXG5cdFx0KSA9PiB2b2lkLFxuXHRcdGV4dHJhOiB7IHRpZGRsZXJJbmZvOiBTeW5jZXJUaWRkbGVySW5mbzxBRD4gfVxuXHQpOiB2b2lkO1xuXG5cdHNhdmVUaWRkbGVycz8ob3B0aW9uczoge1xuXHRcdHN5bmNlcjogU3luY2VyPEFEPixcblx0XHR0aWRkbGVyczogVGlkZGxlcltdLFxuXHRcdG9uTmV4dDogKHRpdGxlOiBzdHJpbmcsIGFkYXB0b3JJbmZvOiBhbnksIHJldmlzaW9uOiBzdHJpbmcpID0+IHZvaWQsXG5cdFx0b25Eb25lOiAoKSA9PiB2b2lkLFxuXHRcdG9uRXJyb3I6IChlcnI6IEVycm9yKSA9PiB2b2lkXG5cdH0pOiB2b2lkO1xuXG5cdGxvYWRUaWRkbGVycz8ob3B0aW9uczoge1xuXHRcdHN5bmNlcjogU3luY2VyPEFEPixcblx0XHR0aXRsZXM6IHN0cmluZ1tdLFxuXHRcdG9uTmV4dDogKHRpZGRsZXJGaWVsZHM6IFRpZGRsZXJGaWVsZHMpID0+IHZvaWQsXG5cdFx0b25Eb25lOiAoKSA9PiB2b2lkLFxuXHRcdG9uRXJyb3I6IChlcnI6IEVycm9yKSA9PiB2b2lkXG5cdH0pOiB2b2lkO1xuXG5cdGRlbGV0ZVRpZGRsZXJzPyhvcHRpb25zOiB7XG5cdFx0c3luY2VyOiBTeW5jZXI8QUQ+LFxuXHRcdHRpdGxlczogc3RyaW5nW10sXG5cdFx0b25OZXh0OiAodGl0bGU6IHN0cmluZykgPT4gdm9pZCxcblx0XHRvbkRvbmU6ICgpID0+IHZvaWQsXG5cdFx0b25FcnJvcjogKGVycjogRXJyb3IpID0+IHZvaWRcblx0fSk6IHZvaWQ7XG5cblx0c2V0TG9nZ2VyU2F2ZUJ1ZmZlcj86IChsb2dnZXJGb3JTYXZpbmc6IExvZ2dlcikgPT4gdm9pZDtcblx0ZGlzcGxheUxvZ2luUHJvbXB0PyhzeW5jZXI6IFN5bmNlcjxBRD4pOiB2b2lkO1xuXHRsb2dpbj8odXNlcm5hbWU6IHN0cmluZywgcGFzc3dvcmQ6IHN0cmluZywgY2I6IChlcnI6IGFueSkgPT4gdm9pZCk6IHZvaWQ7XG5cdGxvZ291dD8oY2I6IChlcnI6IGFueSkgPT4gdm9pZCk6IGFueTtcblxufVxuaW50ZXJmYWNlIFN5bmNlclRpZGRsZXJJbmZvPEFEPiB7XG5cdC8qKiB0aGlzIGNvbWVzIGZyb20gdGhlIHdpa2kgY2hhbmdlQ291bnQgcmVjb3JkICovXG5cdGNoYW5nZUNvdW50OiBudW1iZXI7XG5cdC8qKiBBZGFwdGVyIGluZm8gcmV0dXJuZWQgYnkgdGhlIHN5bmMgYWRhcHRlciAqL1xuXHRhZGFwdG9ySW5mbzogQUQ7XG5cdC8qKiBSZXZpc2lvbiByZXR1cm4gYnkgdGhlIHN5bmMgYWRhcHRlciAqL1xuXHRyZXZpc2lvbjogc3RyaW5nO1xuXHQvKiogVGltZXN0YW1wIHNldCBpbiB0aGUgY2FsbGJhY2sgb2YgdGhlIHByZXZpb3VzIHNhdmUgKi9cblx0dGltZXN0YW1wTGFzdFNhdmVkOiBEYXRlO1xufVxuXG5kZWNsYXJlIGNvbnN0ICR0dzogYW55O1xuXG5kZWNsYXJlIGNvbnN0IGV4cG9ydHM6IHtcblx0YWRhcHRvckNsYXNzOiB0eXBlb2YgTXVsdGlXaWtpQ2xpZW50QWRhcHRvcjtcbn07XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gQ29uc3RhbnRzXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuY29uc3QgQ09ORklHX0hPU1RfVElERExFUiA9IFwiJDovY29uZmlnL211bHRpd2lraWNsaWVudC9ob3N0XCI7XG5jb25zdCBERUZBVUxUX0hPU1RfVElERExFUiA9IFwiJHByb3RvY29sJC8vJGhvc3QkL1wiO1xuY29uc3QgQ09ORklHX1JFQ0lQRV9USURETEVSID0gXCIkOi9jb25maWcvbXVsdGl3aWtpY2xpZW50L3JlY2lwZVwiO1xuY29uc3QgSVNfREVWX01PREVfVElERExFUiA9IFwiJDovc3RhdGUvbXVsdGl3aWtpY2xpZW50L2Rldi1tb2RlXCI7XG5jb25zdCBMQVNUX1JFVklTSU9OX0lEX1RJRERMRVIgPSBcIiQ6L3N0YXRlL211bHRpd2lraWNsaWVudC9yZWNpcGUvbGFzdF9yZXZpc2lvbl9pZFwiO1xuY29uc3QgTVdDX1NUQVRFX1RJRERMRVJfUFJFRklYID0gXCIkOi9zdGF0ZS9tdWx0aXdpa2ljbGllbnQvXCI7XG5jb25zdCBCQUdfU1RBVEVfVElERExFUiA9IFwiJDovc3RhdGUvbXVsdGl3aWtpY2xpZW50L3RpZGRsZXJzL2JhZ1wiO1xuY29uc3QgUkVWSVNJT05fU1RBVEVfVElERExFUiA9IFwiJDovc3RhdGUvbXVsdGl3aWtpY2xpZW50L3RpZGRsZXJzL3JldmlzaW9uXCI7XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gVHlwZXNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5pbnRlcmZhY2UgTVdTQWRhcHRvckluZm8ge1xuXHRiYWc6IHN0cmluZztcblx0cmV2aXNpb246IHN0cmluZztcblx0dGl0bGU6IHN0cmluZztcbn1cblxuLy8gU3RhdHVzIHJlc3BvbnNlIGZyb20gR0VUIC9yZWNpcGUvOmlkL3N0YXR1c1xuaW50ZXJmYWNlIFJlY2lwZVN0YXR1cyB7XG5cdGlzQWRtaW46IGJvb2xlYW47XG5cdHVzZXJfaWQ6IHN0cmluZztcblx0dXNlcm5hbWU6IHN0cmluZztcblx0aXNMb2dnZWRJbjogYm9vbGVhbjtcblx0dGVtcGxhdGU6IHsgdHlwZTogc3RyaW5nOyBkZWZpbml0aW9uOiB1bmtub3duOyBwYXJhbWV0ZXJzOiB1bmtub3duIH07XG5cdGJhZ3M6IHsgYmFnX2lkOiBzdHJpbmc7IGJhZ19uYW1lOiBzdHJpbmc7IGlzX3dyaXRhYmxlOiBib29sZWFuOyBwcmlvcml0eTogbnVtYmVyOyBjYW5Vc2VyV3JpdGU6IGJvb2xlYW47IGluZm86IHVua25vd24gfVtdO1xufVxuXG4vLyBUaWRkbGVySW5mbyBmcm9tIHJlc29sdmVyXG5pbnRlcmZhY2UgVGlkZGxlckluZm8ge1xuXHR0aXRsZTogc3RyaW5nO1xuXHR3cml0ZVRvOiBzdHJpbmcgfCBudWxsO1xuXHRyZWFkRnJvbTogc3RyaW5nIHwgbnVsbDtcblx0ZXhpc3RzSW46IHN0cmluZ1tdO1xuXHRjYW5Xcml0ZTogYm9vbGVhbjtcbn1cblxudHlwZSBCYXRjaE11dGF0aW9uUmVzdWx0ID0geyB0aXRsZTogc3RyaW5nOyBpbmZvOiBUaWRkbGVySW5mbzsgcmV2aXNpb24/OiBzdHJpbmcgfTtcbnR5cGUgQmF0Y2hSZWFkUmVzdWx0ID0geyBmaWVsZHM6IFJlY29yZDxzdHJpbmcsIGFueT4gJiB7IHRpdGxlOiBzdHJpbmcgfTsgaW5mbzogVGlkZGxlckluZm8gfSB8IG51bGw7XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gQWRhcHRvclxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbmNsYXNzIE11bHRpV2lraUNsaWVudEFkYXB0b3IgaW1wbGVtZW50cyBTeW5jQWRhcHRvcjxNV1NBZGFwdG9ySW5mbz4ge1xuXHRuYW1lID0gXCJtdWx0aXdpa2ljbGllbnRcIjtcblxuXHRwcml2YXRlIHdpa2k6IFdpa2k7XG5cdHByaXZhdGUgaG9zdDogc3RyaW5nO1xuXHRwcml2YXRlIHJlY2lwZTogc3RyaW5nO1xuXHRwcml2YXRlIGlzRGV2TW9kZTogYm9vbGVhbjtcblx0cHJpdmF0ZSBsb2dnZXI6IExvZ2dlcjtcblx0cHJpdmF0ZSBzeW5jZXI6IFN5bmNlcjxNV1NBZGFwdG9ySW5mbz4gfCBudWxsID0gbnVsbDtcblxuXHRwcml2YXRlIGlzTG9nZ2VkSW4gPSBmYWxzZTtcblx0cHJpdmF0ZSBpc1JlYWRPbmx5ID0gdHJ1ZTtcblx0cHJpdmF0ZSBvZmZsaW5lID0gZmFsc2U7XG5cdHByaXZhdGUgdXNlcm5hbWUgPSBcIlwiO1xuXHRlcnJvcjogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cblx0cHJpdmF0ZSBsYXN0U2VxID0gXCIwXCI7XG5cdHByaXZhdGUgaW5pdGlhbExvYWREb25lID0gZmFsc2U7XG5cdC8qKiB0aXRsZSDihpIgYmFnIG5hbWUsIHBvcHVsYXRlZCBvbiBsb2FkL3NhdmUgKi9cblx0cHJpdmF0ZSB0aWRkbGVyQmFnID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oKTtcblx0LyoqIHRpdGxlIOKGkiByZXZpc2lvbiwgcG9wdWxhdGVkIG9uIHNhdmUgKi9cblx0cHJpdmF0ZSB0aWRkbGVyUmV2aXNpb24gPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPigpO1xuXG5cdGNvbnN0cnVjdG9yKG9wdGlvbnM6IHsgd2lraTogV2lraSB9KSB7XG5cdFx0dGhpcy53aWtpID0gb3B0aW9ucy53aWtpO1xuXHRcdHRoaXMuaG9zdCA9IHRoaXMuZ2V0SG9zdCgpO1xuXHRcdHRoaXMucmVjaXBlID0gdGhpcy53aWtpLmdldFRpZGRsZXJUZXh0KENPTkZJR19SRUNJUEVfVElERExFUiwgXCJcIikhO1xuXHRcdHRoaXMuaXNEZXZNb2RlID0gdGhpcy53aWtpLmdldFRpZGRsZXJUZXh0KElTX0RFVl9NT0RFX1RJRERMRVIpID09PSBcInllc1wiO1xuXHRcdHRoaXMubGFzdFNlcSA9IHRoaXMud2lraS5nZXRUaWRkbGVyVGV4dChMQVNUX1JFVklTSU9OX0lEX1RJRERMRVIsIFwiMFwiKSE7XG5cdFx0dGhpcy5pbml0aWFsTG9hZERvbmUgPSB0aGlzLmxhc3RTZXEgIT09IFwiMFwiO1xuXHRcdHRoaXMubG9nZ2VyID0gbmV3ICR0dy51dGlscy5Mb2dnZXIoXCJNdWx0aVdpa2lDbGllbnRBZGFwdG9yXCIpO1xuXHR9XG5cblx0aXNSZWFkeSgpIHsgcmV0dXJuIHRydWU7IH1cblxuXHRzZXRMb2dnZXJTYXZlQnVmZmVyKGxvZ2dlcjogTG9nZ2VyKSB7IHRoaXMubG9nZ2VyLnNldFNhdmVCdWZmZXIobG9nZ2VyKTsgfVxuXG5cdHJlZ2lzdGVyU3luY2VyKHN5bmNlcjogU3luY2VyPE1XU0FkYXB0b3JJbmZvPikgeyB0aGlzLnN5bmNlciA9IHN5bmNlcjsgfVxuXG5cdHByaXZhdGUgaXNTdGF0ZVRpZGRsZXIodGl0bGU6IHN0cmluZykge1xuXHRcdHJldHVybiB0aXRsZS5zdGFydHNXaXRoKE1XQ19TVEFURV9USURETEVSX1BSRUZJWCk7XG5cdH1cblxuXHRwcml2YXRlIHNldFRpZGRsZXJJbmZvKHRpdGxlOiBzdHJpbmcsIGJhZzogc3RyaW5nIHwgbnVsbCwgcmV2aXNpb24/OiBzdHJpbmcpIHtcblx0XHRpZiAoYmFnKSB7XG5cdFx0XHR0aGlzLnRpZGRsZXJCYWcuc2V0KHRpdGxlLCBiYWcpO1xuXHRcdFx0dGhpcy53aWtpLnNldFRleHQoQkFHX1NUQVRFX1RJRERMRVIsIG51bGwsIHRpdGxlLCBiYWcsIHsgc3VwcHJlc3NUaW1lc3RhbXA6IHRydWUgfSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMudGlkZGxlckJhZy5kZWxldGUodGl0bGUpO1xuXHRcdFx0dGhpcy53aWtpLnNldFRleHQoQkFHX1NUQVRFX1RJRERMRVIsIG51bGwsIHRpdGxlLCB1bmRlZmluZWQsIHsgc3VwcHJlc3NUaW1lc3RhbXA6IHRydWUgfSk7XG5cdFx0fVxuXHRcdGlmIChyZXZpc2lvbikge1xuXHRcdFx0dGhpcy50aWRkbGVyUmV2aXNpb24uc2V0KHRpdGxlLCByZXZpc2lvbik7XG5cdFx0XHR0aGlzLndpa2kuc2V0VGV4dChSRVZJU0lPTl9TVEFURV9USURETEVSLCBudWxsLCB0aXRsZSwgcmV2aXNpb24sIHsgc3VwcHJlc3NUaW1lc3RhbXA6IHRydWUgfSk7XG5cdFx0fVxuXHR9XG5cblx0cHJpdmF0ZSBjbGVhclRpZGRsZXJJbmZvKHRpdGxlOiBzdHJpbmcpIHtcblx0XHR0aGlzLnRpZGRsZXJCYWcuZGVsZXRlKHRpdGxlKTtcblx0XHR0aGlzLnRpZGRsZXJSZXZpc2lvbi5kZWxldGUodGl0bGUpO1xuXHRcdHRoaXMud2lraS5zZXRUZXh0KEJBR19TVEFURV9USURETEVSLCBudWxsLCB0aXRsZSwgdW5kZWZpbmVkLCB7IHN1cHByZXNzVGltZXN0YW1wOiB0cnVlIH0pO1xuXHRcdHRoaXMud2lraS5zZXRUZXh0KFJFVklTSU9OX1NUQVRFX1RJRERMRVIsIG51bGwsIHRpdGxlLCB1bmRlZmluZWQsIHsgc3VwcHJlc3NUaW1lc3RhbXA6IHRydWUgfSk7XG5cdH1cblxuXHRwcml2YXRlIHNldExhc3RTZXEoc2VxOiBzdHJpbmcpIHtcblx0XHR0aGlzLmxhc3RTZXEgPSBzZXE7XG5cdFx0dGhpcy53aWtpLnNldFRleHQoTEFTVF9SRVZJU0lPTl9JRF9USURETEVSLCBudWxsLCBcInRleHRcIiwgc2VxLCB7IHN1cHByZXNzVGltZXN0YW1wOiB0cnVlIH0pO1xuXHR9XG5cblx0Z2V0VGlkZGxlclJldmlzaW9uKHRpdGxlOiBzdHJpbmcpIHtcblx0XHRyZXR1cm4gdGhpcy53aWtpLmV4dHJhY3RUaWRkbGVyRGF0YUl0ZW0oUkVWSVNJT05fU1RBVEVfVElERExFUiwgdGl0bGUpID8/IFwiXCI7XG5cdH1cblxuXHRnZXRUaWRkbGVySW5mbyh0aWRkbGVyOiBUaWRkbGVyKTogTVdTQWRhcHRvckluZm8gfCB1bmRlZmluZWQge1xuXHRcdGNvbnN0IHRpdGxlID0gdGlkZGxlci5maWVsZHMudGl0bGUgYXMgc3RyaW5nO1xuXHRcdGNvbnN0IGJhZyA9IHRoaXMud2lraS5leHRyYWN0VGlkZGxlckRhdGFJdGVtKEJBR19TVEFURV9USURETEVSLCB0aXRsZSkgPz8gdGhpcy50aWRkbGVyQmFnLmdldCh0aXRsZSk7XG5cdFx0Y29uc3QgcmV2aXNpb24gPSB0aGlzLndpa2kuZXh0cmFjdFRpZGRsZXJEYXRhSXRlbShSRVZJU0lPTl9TVEFURV9USURETEVSLCB0aXRsZSkgPz8gdGhpcy50aWRkbGVyUmV2aXNpb24uZ2V0KHRpdGxlKTtcblx0XHRyZXR1cm4gYmFnICYmIHJldmlzaW9uID8geyBiYWcsIHJldmlzaW9uLCB0aXRsZSB9IDogdW5kZWZpbmVkO1xuXHR9XG5cblx0cHJpdmF0ZSBnZXRIb3N0KCkge1xuXHRcdGxldCB0ZXh0ID0gdGhpcy53aWtpLmdldFRpZGRsZXJUZXh0KENPTkZJR19IT1NUX1RJRERMRVIsIERFRkFVTFRfSE9TVF9USURETEVSKSE7XG5cdFx0W1xuXHRcdFx0eyBuYW1lOiBcInByb3RvY29sXCIsIHZhbHVlOiBkb2N1bWVudC5sb2NhdGlvbi5wcm90b2NvbCB9LFxuXHRcdFx0eyBuYW1lOiBcImhvc3RcIiwgICAgIHZhbHVlOiBkb2N1bWVudC5sb2NhdGlvbi5ob3N0IH0sXG5cdFx0XHR7IG5hbWU6IFwicGF0aG5hbWVcIiwgdmFsdWU6IGRvY3VtZW50LmxvY2F0aW9uLnBhdGhuYW1lIH0sXG5cdFx0XS5mb3JFYWNoKCh7IG5hbWUsIHZhbHVlIH0pID0+IHtcblx0XHRcdHRleHQgPSAkdHcudXRpbHMucmVwbGFjZVN0cmluZyh0ZXh0LCBuZXcgUmVnRXhwKFwiXFxcXCRcIiArIG5hbWUgKyBcIlxcXFwkXCIsIFwibWdcIiksIHZhbHVlKTtcblx0XHR9KTtcblx0XHRyZXR1cm4gdGV4dDtcblx0fVxuXG5cdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0Ly8gU3RhdHVzXG5cdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRhc3luYyBnZXRTdGF0dXMoY2FsbGJhY2s6IFNlcnZlclN0YXR1c0NhbGxiYWNrKSB7XG5cdFx0Y29uc3QgW29rLCAsIHJlc3VsdF0gPSBhd2FpdCB0aGlzLnJlY2lwZVJlcXVlc3QoeyBtZXRob2Q6IFwiR0VUXCIsIHVybDogXCIvc3RhdHVzXCIgfSk7XG5cdFx0aWYgKCFvayAmJiByZXN1bHQ/LnN0YXR1cyA9PT0gMCkge1xuXHRcdFx0dGhpcy5vZmZsaW5lID0gdHJ1ZTtcblx0XHRcdHRoaXMuaXNMb2dnZWRJbiA9IGZhbHNlO1xuXHRcdFx0dGhpcy5pc1JlYWRPbmx5ID0gdHJ1ZTtcblx0XHRcdHRoaXMudXNlcm5hbWUgPSBcIihvZmZsaW5lKVwiO1xuXHRcdFx0dGhpcy5lcnJvciA9IFwiVGhlIHdlYnBhZ2UgaXMgZm9yYmlkZGVuIGZyb20gY29udGFjdGluZyB0aGUgc2VydmVyLlwiO1xuXHRcdH0gZWxzZSBpZiAob2spIHtcblx0XHRcdGNvbnN0IHN0YXR1cyA9IHJlc3VsdCEucmVzcG9uc2VKU09OIGFzIFJlY2lwZVN0YXR1cztcblx0XHRcdHRoaXMub2ZmbGluZSA9IGZhbHNlO1xuXHRcdFx0dGhpcy5lcnJvciA9IG51bGw7XG5cdFx0XHR0aGlzLmlzTG9nZ2VkSW4gPSBzdGF0dXM/LmlzTG9nZ2VkSW4gPz8gZmFsc2U7XG5cdFx0XHR0aGlzLnVzZXJuYW1lID0gc3RhdHVzPy51c2VybmFtZSA/PyBcIihhbm9uKVwiO1xuXHRcdFx0dGhpcy5pc1JlYWRPbmx5ID0gIShzdGF0dXM/LmJhZ3M/LnNvbWUoYiA9PiBiLmNhblVzZXJXcml0ZSkgPz8gZmFsc2UpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLmVycm9yID0gYFNlcnZlciBlcnJvciAke3Jlc3VsdD8uc3RhdHVzfWA7XG5cdFx0fVxuXHRcdGNhbGxiYWNrKHRoaXMuZXJyb3IsIHRoaXMuaXNMb2dnZWRJbiwgdGhpcy51c2VybmFtZSwgdGhpcy5pc1JlYWRPbmx5LCBmYWxzZSk7XG5cdH1cblxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vIFVwZGF0ZSBwb2xsaW5nXG5cdC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRhc3luYyBnZXRVcGRhdGVkVGlkZGxlcnMoXG5cdFx0X3N5bmNlcjogU3luY2VyPE1XU0FkYXB0b3JJbmZvPixcblx0XHRjYWxsYmFjazogKGVycjogYW55LCB1cGRhdGVzPzogeyBtb2RpZmljYXRpb25zOiBzdHJpbmdbXTsgZGVsZXRpb25zOiBzdHJpbmdbXSB9KSA9PiB2b2lkXG5cdCkge1xuXHRcdGlmICh0aGlzLm9mZmxpbmUpIHJldHVybiBjYWxsYmFjayhudWxsKTtcblx0XHR0cnkge1xuXHRcdFx0aWYgKCF0aGlzLmluaXRpYWxMb2FkRG9uZSkge1xuXHRcdFx0XHQvLyBGZXRjaCBmdWxsIGxpc3QgKyBjdXJyZW50IGxhc3RTZXEgaW4gcGFyYWxsZWwgb24gZmlyc3QgbG9hZFxuXHRcdFx0XHRjb25zdCBbW2xpc3RPaywgLCBsaXN0UmVzdWx0XSwgW3VwZE9rLCAsIHVwZFJlc3VsdF1dID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuXHRcdFx0XHRcdHRoaXMucmVjaXBlUmVxdWVzdCh7IG1ldGhvZDogXCJHRVRcIiwgdXJsOiBcIi9saXN0Lmpzb25cIiB9KSxcblx0XHRcdFx0XHR0aGlzLnJlY2lwZVJlcXVlc3QoeyBtZXRob2Q6IFwiR0VUXCIsIHVybDogXCIvdXBkYXRlc1wiLCBxdWVyeVBhcmFtczogeyBzaW5jZTogXCIwXCIgfSB9KSxcblx0XHRcdFx0XSk7XG5cdFx0XHRcdGlmICghbGlzdE9rKSB0aHJvdyBuZXcgRXJyb3IoXCJGYWlsZWQgdG8gZmV0Y2ggdGlkZGxlciBsaXN0XCIpO1xuXHRcdFx0XHRpZiAoIXVwZE9rKSB0aHJvdyBuZXcgRXJyb3IoXCJGYWlsZWQgdG8gZmV0Y2ggdXBkYXRlc1wiKTtcblx0XHRcdFx0Y29uc3QgbGlzdCA9IGxpc3RSZXN1bHQhLnJlc3BvbnNlSlNPTiBhcyBUaWRkbGVySW5mb1tdO1xuXHRcdFx0XHRjb25zdCB1cGQgPSB1cGRSZXN1bHQhLnJlc3BvbnNlSlNPTiBhcyB7IG1vZGlmaWNhdGlvbnM6IHN0cmluZ1tdOyBkZWxldGlvbnM6IHN0cmluZ1tdOyBsYXN0U2VxOiBzdHJpbmcgfTtcblx0XHRcdFx0dGhpcy5zZXRMYXN0U2VxKHVwZC5sYXN0U2VxKTtcblx0XHRcdFx0dGhpcy5pbml0aWFsTG9hZERvbmUgPSB0cnVlO1xuXHRcdFx0XHRjYWxsYmFjayhudWxsLCB7IG1vZGlmaWNhdGlvbnM6IGxpc3QubWFwKHQgPT4gdC50aXRsZSksIGRlbGV0aW9uczogW10gfSk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRjb25zdCBbb2ssICwgcmVzdWx0XSA9IGF3YWl0IHRoaXMucmVjaXBlUmVxdWVzdCh7XG5cdFx0XHRcdFx0bWV0aG9kOiBcIkdFVFwiLFxuXHRcdFx0XHRcdHVybDogXCIvdXBkYXRlc1wiLFxuXHRcdFx0XHRcdHF1ZXJ5UGFyYW1zOiB7IHNpbmNlOiB0aGlzLmxhc3RTZXEgfSxcblx0XHRcdFx0fSk7XG5cdFx0XHRcdGlmICghb2spIHRocm93IG5ldyBFcnJvcihcIkZhaWxlZCB0byBmZXRjaCB1cGRhdGVzXCIpO1xuXHRcdFx0XHRjb25zdCB1cGQgPSByZXN1bHQhLnJlc3BvbnNlSlNPTiBhcyB7IG1vZGlmaWNhdGlvbnM6IHN0cmluZ1tdOyBkZWxldGlvbnM6IHN0cmluZ1tdOyBsYXN0U2VxOiBzdHJpbmcgfTtcblx0XHRcdFx0dGhpcy5zZXRMYXN0U2VxKHVwZC5sYXN0U2VxKTtcblx0XHRcdFx0Y2FsbGJhY2sobnVsbCwgeyBtb2RpZmljYXRpb25zOiB1cGQubW9kaWZpY2F0aW9ucywgZGVsZXRpb25zOiB1cGQuZGVsZXRpb25zIH0pO1xuXHRcdFx0fVxuXHRcdH0gY2F0Y2ggKGU6IGFueSkge1xuXHRcdFx0Y2FsbGJhY2soZSk7XG5cdFx0fVxuXHR9XG5cblx0Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHQvLyBCYXRjaCBvcGVyYXRpb25zIChuZXcgQVBJKVxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0YXN5bmMgbG9hZFRpZGRsZXJzKG9wdGlvbnM6IHtcblx0XHRzeW5jZXI6IFN5bmNlcjxNV1NBZGFwdG9ySW5mbz47XG5cdFx0dGl0bGVzOiBzdHJpbmdbXTtcblx0XHRvbk5leHQ6IChmaWVsZHM6IFRpZGRsZXJGaWVsZHMpID0+IHZvaWQ7XG5cdFx0b25Eb25lOiAoKSA9PiB2b2lkO1xuXHRcdG9uRXJyb3I6IChlcnI6IEVycm9yKSA9PiB2b2lkO1xuXHR9KSB7XG5cdFx0Y29uc3QgeyB0aXRsZXMsIG9uTmV4dCwgb25Eb25lLCBvbkVycm9yIH0gPSBvcHRpb25zO1xuXHRcdHRyeSB7XG5cdFx0XHRjb25zdCByZXN1bHRzID0gYXdhaXQgdGhpcy5iYXRjaE9wPEJhdGNoUmVhZFJlc3VsdFtdPihcInJlYWRcIiwgeyB0aXRsZXMgfSk7XG5cdFx0XHRmb3IgKGNvbnN0IGl0ZW0gb2YgcmVzdWx0cykge1xuXHRcdFx0XHRpZiAoIWl0ZW0pIGNvbnRpbnVlO1xuXHRcdFx0XHR0aGlzLnNldFRpZGRsZXJJbmZvKGl0ZW0uZmllbGRzLnRpdGxlLCBpdGVtLmluZm8ucmVhZEZyb20sIHR5cGVvZiBpdGVtLmZpZWxkcy5yZXZpc2lvbiA9PT0gXCJzdHJpbmdcIiA/IGl0ZW0uZmllbGRzLnJldmlzaW9uIDogdW5kZWZpbmVkKTtcblx0XHRcdFx0b25OZXh0KGl0ZW0uZmllbGRzIGFzIFRpZGRsZXJGaWVsZHMpO1xuXHRcdFx0fVxuXHRcdFx0b25Eb25lKCk7XG5cdFx0fSBjYXRjaCAoZTogYW55KSB7IG9uRXJyb3IoZSk7IH1cblx0fVxuXG5cdGFzeW5jIHNhdmVUaWRkbGVycyhvcHRpb25zOiB7XG5cdFx0c3luY2VyOiBTeW5jZXI8TVdTQWRhcHRvckluZm8+O1xuXHRcdHRpZGRsZXJzOiBUaWRkbGVyW107XG5cdFx0b25OZXh0OiAodGl0bGU6IHN0cmluZywgYWRhcHRvckluZm86IE1XU0FkYXB0b3JJbmZvLCByZXZpc2lvbjogc3RyaW5nKSA9PiB2b2lkO1xuXHRcdG9uRG9uZTogKCkgPT4gdm9pZDtcblx0XHRvbkVycm9yOiAoZXJyOiBFcnJvcikgPT4gdm9pZDtcblx0fSkge1xuXHRcdGNvbnN0IHsgdGlkZGxlcnMsIG9uTmV4dCwgb25Eb25lLCBvbkVycm9yIH0gPSBvcHRpb25zO1xuXHRcdHRyeSB7XG5cdFx0XHRjb25zdCByZXN1bHRzID0gYXdhaXQgdGhpcy5iYXRjaE9wPEJhdGNoTXV0YXRpb25SZXN1bHRbXT4oXCJzYXZlXCIsIHtcblx0XHRcdFx0dGlkZGxlcnM6IHRpZGRsZXJzLm1hcCh0ID0+IHQuZ2V0RmllbGRTdHJpbmdzKCkpLFxuXHRcdFx0fSk7XG5cdFx0XHRmb3IgKGNvbnN0IGl0ZW0gb2YgcmVzdWx0cykge1xuXHRcdFx0XHRjb25zdCBiYWcgPSBpdGVtLmluZm8ud3JpdGVUbyA/PyBpdGVtLmluZm8ucmVhZEZyb20gPz8gXCJcIjtcblx0XHRcdFx0dGhpcy5zZXRUaWRkbGVySW5mbyhpdGVtLnRpdGxlLCBiYWcgfHwgbnVsbCwgaXRlbS5yZXZpc2lvbiA/PyBcIlwiKTtcblx0XHRcdFx0aWYgKCR0dy5icm93c2VyU3RvcmFnZT8uaXNFbmFibGVkKCkpICR0dy5icm93c2VyU3RvcmFnZS5yZW1vdmVUaWRkbGVyRnJvbUxvY2FsU3RvcmFnZShpdGVtLnRpdGxlKTtcblx0XHRcdFx0b25OZXh0KGl0ZW0udGl0bGUsIHsgYmFnLCByZXZpc2lvbjogaXRlbS5yZXZpc2lvbiA/PyBcIlwiLCB0aXRsZTogaXRlbS50aXRsZSB9LCBpdGVtLnJldmlzaW9uID8/IFwiXCIpO1xuXHRcdFx0fVxuXHRcdFx0b25Eb25lKCk7XG5cdFx0fSBjYXRjaCAoZTogYW55KSB7IG9uRXJyb3IoZSk7IH1cblx0fVxuXG5cdGFzeW5jIGRlbGV0ZVRpZGRsZXJzKG9wdGlvbnM6IHtcblx0XHRzeW5jZXI6IFN5bmNlcjxNV1NBZGFwdG9ySW5mbz47XG5cdFx0dGl0bGVzOiBzdHJpbmdbXTtcblx0XHRvbk5leHQ6ICh0aXRsZTogc3RyaW5nKSA9PiB2b2lkO1xuXHRcdG9uRG9uZTogKCkgPT4gdm9pZDtcblx0XHRvbkVycm9yOiAoZXJyOiBFcnJvcikgPT4gdm9pZDtcblx0fSkge1xuXHRcdGNvbnN0IHsgdGl0bGVzLCBvbk5leHQsIG9uRG9uZSwgb25FcnJvciB9ID0gb3B0aW9ucztcblx0XHR0cnkge1xuXHRcdFx0Y29uc3QgcmVzdWx0cyA9IGF3YWl0IHRoaXMuYmF0Y2hPcDxCYXRjaE11dGF0aW9uUmVzdWx0W10+KFwiZGVsZXRlXCIsIHsgdGl0bGVzIH0pO1xuXHRcdFx0Zm9yIChjb25zdCBpdGVtIG9mIHJlc3VsdHMpIHtcblx0XHRcdFx0dGhpcy5jbGVhclRpZGRsZXJJbmZvKGl0ZW0udGl0bGUpO1xuXHRcdFx0XHRvbk5leHQoaXRlbS50aXRsZSk7XG5cdFx0XHR9XG5cdFx0XHRvbkRvbmUoKTtcblx0XHR9IGNhdGNoIChlOiBhbnkpIHsgb25FcnJvcihlKTsgfVxuXHR9XG5cblx0Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHQvLyBTaW5nbGUtdGlkZGxlciBvcGVyYXRpb25zIChmYWxsYmFjayBmb3Igb2xkZXIgc2VydmVyIHZlcnNpb25zKVxuXHQvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0YXN5bmMgc2F2ZVRpZGRsZXIoXG5cdFx0dGlkZGxlcjogVGlkZGxlcixcblx0XHRjYWxsYmFjazogKGVycjogYW55LCBhZGFwdG9ySW5mbz86IE1XU0FkYXB0b3JJbmZvLCByZXZpc2lvbj86IHN0cmluZykgPT4gdm9pZFxuXHQpIHtcblx0XHRjb25zdCB0aXRsZSA9IHRpZGRsZXIuZmllbGRzLnRpdGxlIGFzIHN0cmluZztcblx0XHRpZiAodGl0bGUgPT09IFwiJDovU3RvcnlMaXN0XCIgfHwgdGhpcy5pc1JlYWRPbmx5IHx8IHRoaXMuaXNTdGF0ZVRpZGRsZXIodGl0bGUpKSByZXR1cm4gY2FsbGJhY2sobnVsbCk7XG5cdFx0dHJ5IHtcblx0XHRcdGNvbnN0IHJlc3VsdHMgPSBhd2FpdCB0aGlzLmJhdGNoT3A8QmF0Y2hNdXRhdGlvblJlc3VsdFtdPihcInNhdmVcIiwgeyB0aWRkbGVyczogW3RpZGRsZXIuZ2V0RmllbGRTdHJpbmdzKCldIH0pO1xuXHRcdFx0Y29uc3QgaXRlbSA9IHJlc3VsdHNbMF07XG5cdFx0XHRpZiAoIWl0ZW0pIHJldHVybiBjYWxsYmFjayhuZXcgRXJyb3IoXCJObyByZXN1bHQgcmV0dXJuZWRcIikpO1xuXHRcdFx0Y29uc3QgYmFnID0gaXRlbS5pbmZvLndyaXRlVG8gPz8gaXRlbS5pbmZvLnJlYWRGcm9tID8/IFwiXCI7XG5cdFx0XHR0aGlzLnNldFRpZGRsZXJJbmZvKHRpdGxlLCBiYWcgfHwgbnVsbCwgaXRlbS5yZXZpc2lvbiA/PyBcIlwiKTtcblx0XHRcdGlmICgkdHcuYnJvd3NlclN0b3JhZ2U/LmlzRW5hYmxlZCgpKSAkdHcuYnJvd3NlclN0b3JhZ2UucmVtb3ZlVGlkZGxlckZyb21Mb2NhbFN0b3JhZ2UodGl0bGUpO1xuXHRcdFx0Y2FsbGJhY2sobnVsbCwgeyBiYWcsIHJldmlzaW9uOiBpdGVtLnJldmlzaW9uID8/IFwiXCIsIHRpdGxlIH0sIGl0ZW0ucmV2aXNpb24gPz8gXCJcIik7XG5cdFx0fSBjYXRjaCAoZTogYW55KSB7IGNhbGxiYWNrKGUpOyB9XG5cdH1cblxuXHRhc3luYyBsb2FkVGlkZGxlcih0aXRsZTogc3RyaW5nLCBjYWxsYmFjazogKGVycjogYW55LCBmaWVsZHM/OiBhbnkpID0+IHZvaWQsIF9vcHRpb25zOiBhbnkpIHtcblx0XHR0cnkge1xuXHRcdFx0Y29uc3QgcmVzdWx0cyA9IGF3YWl0IHRoaXMuYmF0Y2hPcDxCYXRjaFJlYWRSZXN1bHRbXT4oXCJyZWFkXCIsIHsgdGl0bGVzOiBbdGl0bGVdIH0pO1xuXHRcdFx0Y29uc3QgaXRlbSA9IHJlc3VsdHNbMF07XG5cdFx0XHRpZiAoIWl0ZW0pIHJldHVybiBjYWxsYmFjayhudWxsLCBudWxsKTtcblx0XHRcdHRoaXMuc2V0VGlkZGxlckluZm8odGl0bGUsIGl0ZW0uaW5mby5yZWFkRnJvbSwgdHlwZW9mIGl0ZW0uZmllbGRzLnJldmlzaW9uID09PSBcInN0cmluZ1wiID8gaXRlbS5maWVsZHMucmV2aXNpb24gOiB1bmRlZmluZWQpO1xuXHRcdFx0Y2FsbGJhY2sobnVsbCwgaXRlbS5maWVsZHMpO1xuXHRcdH0gY2F0Y2ggKGU6IGFueSkgeyBjYWxsYmFjayhlKTsgfVxuXHR9XG5cblx0YXN5bmMgZGVsZXRlVGlkZGxlcih0aXRsZTogc3RyaW5nLCBjYWxsYmFjazogKGVycjogYW55LCBhZGFwdG9ySW5mbz86IGFueSkgPT4gdm9pZCwgX29wdGlvbnM6IGFueSkge1xuXHRcdGlmICh0aGlzLmlzUmVhZE9ubHkpIHJldHVybiBjYWxsYmFjayhudWxsKTtcblx0XHR0cnkge1xuXHRcdFx0Y29uc3QgcmVzdWx0cyA9IGF3YWl0IHRoaXMuYmF0Y2hPcDxCYXRjaE11dGF0aW9uUmVzdWx0W10+KFwiZGVsZXRlXCIsIHsgdGl0bGVzOiBbdGl0bGVdIH0pO1xuXHRcdFx0Y29uc3QgaXRlbSA9IHJlc3VsdHNbMF07XG5cdFx0XHRpZiAoIWl0ZW0pIHJldHVybiBjYWxsYmFjayhuZXcgRXJyb3IoXCJObyByZXN1bHQgcmV0dXJuZWRcIikpO1xuXHRcdFx0dGhpcy5jbGVhclRpZGRsZXJJbmZvKHRpdGxlKTtcblx0XHRcdGNhbGxiYWNrKG51bGwsIG51bGwpO1xuXHRcdH0gY2F0Y2ggKGU6IGFueSkgeyBjYWxsYmFjayhlKTsgfVxuXHR9XG5cblx0Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXHQvLyBIVFRQIGhlbHBlcnNcblx0Ly8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHByaXZhdGUgYXN5bmMgYmF0Y2hPcDxUPihvcDogc3RyaW5nLCBib2R5OiBSZWNvcmQ8c3RyaW5nLCBhbnk+KTogUHJvbWlzZTxUPiB7XG5cdFx0Y29uc3QgW29rLCBlcnIsIHJlc3VsdF0gPSBhd2FpdCB0aGlzLnJlY2lwZVJlcXVlc3Qoe1xuXHRcdFx0bWV0aG9kOiBcIlBVVFwiLFxuXHRcdFx0dXJsOiBcIi9iYXRjaC9cIiArIG9wLFxuXHRcdFx0cmVxdWVzdEJvZHlTdHJpbmc6IEpTT04uc3RyaW5naWZ5KGJvZHkpLFxuXHRcdFx0aGVhZGVyczogeyBcImNvbnRlbnQtdHlwZVwiOiBcImFwcGxpY2F0aW9uL2pzb25cIiB9LFxuXHRcdH0pO1xuXHRcdGlmICghb2spIHRocm93IGVycjtcblx0XHRpZiAoIXJlc3VsdCEucmVzcG9uc2VKU09OKSB0aHJvdyBuZXcgRXJyb3IoXCJObyByZXNwb25zZSBKU09OIGZyb20gYmF0Y2gvXCIgKyBvcCk7XG5cdFx0cmV0dXJuIHJlc3VsdCEucmVzcG9uc2VKU09OIGFzIFQ7XG5cdH1cblxuXHRwcml2YXRlIGFzeW5jIHJlY2lwZVJlcXVlc3Qob3B0aW9uczoge1xuXHRcdG1ldGhvZDogc3RyaW5nO1xuXHRcdHVybDogc3RyaW5nO1xuXHRcdGhlYWRlcnM/OiBIZWFkZXJzSW5pdDtcblx0XHRxdWVyeVBhcmFtcz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG5cdFx0cmVxdWVzdEJvZHlTdHJpbmc/OiBzdHJpbmc7XG5cdH0pIHtcblx0XHRpZiAoIW9wdGlvbnMudXJsLnN0YXJ0c1dpdGgoXCIvXCIpKSB0aHJvdyBuZXcgRXJyb3IoXCJVUkwgbXVzdCBzdGFydCB3aXRoIC9cIik7XG5cdFx0Y29uc3QgaXNEZXZNb2RlID0gdGhpcy5pc0Rldk1vZGU7XG5cdFx0cmV0dXJuIGh0dHBSZXF1ZXN0KHtcblx0XHRcdC4uLm9wdGlvbnMsXG5cdFx0XHRyZXNwb25zZVR5cGU6IFwiYmxvYlwiLFxuXHRcdFx0dXJsOiB0aGlzLmhvc3QgKyBcInJlY2lwZS9cIiArIGVuY29kZVVSSUNvbXBvbmVudCh0aGlzLnJlY2lwZSkgKyBvcHRpb25zLnVybCxcblx0XHR9KS50aGVuKGFzeW5jIGUgPT4ge1xuXHRcdFx0aWYgKCFlLm9rKSByZXR1cm4gW2ZhbHNlLCBuZXcgRXJyb3IoXG5cdFx0XHRcdGBTZXJ2ZXIgcmV0dXJuZWQgJHtlLnN0YXR1c306ICR7ZS5oZWFkZXJzLmdldChcIngtcmVhc29uXCIpID8/IFwiKG5vIHJlYXNvbilcIn1gXG5cdFx0XHQpLCB7IC4uLmUsIHJlc3BvbnNlSlNPTjogdW5kZWZpbmVkIH1dIGFzIGNvbnN0O1xuXG5cdFx0XHRsZXQgcmVzcG9uc2VTdHJpbmc6IHN0cmluZztcblx0XHRcdGlmIChlLmhlYWRlcnMuZ2V0KFwieC1nemlwLXN0cmVhbVwiKSA9PT0gXCJ5ZXNcIikge1xuXHRcdFx0XHRyZXNwb25zZVN0cmluZyA9IGF3YWl0IG5ldyBQcm9taXNlPHN0cmluZz4oKHJlc29sdmUpID0+IHtcblx0XHRcdFx0XHRsZXQgcyA9IFwiXCI7XG5cdFx0XHRcdFx0Y29uc3QgZ3ogPSBuZXcgZmZsYXRlLkFzeW5jR3VuemlwKChlcnIsIGNodW5rLCBmaW5hbCkgPT4ge1xuXHRcdFx0XHRcdFx0aWYgKGVycikgcmV0dXJuO1xuXHRcdFx0XHRcdFx0cyArPSBmZmxhdGUuc3RyRnJvbVU4KGNodW5rKTtcblx0XHRcdFx0XHRcdGlmIChmaW5hbCkgcmVzb2x2ZShzKTtcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRpZiAoaXNEZXZNb2RlKSBnei5vbm1lbWJlciA9IG0gPT4gY29uc29sZS5sb2coXCJndW56aXAgbWVtYmVyXCIsIG0pO1xuXHRcdFx0XHRcdHJlYWRCbG9iQXNBcnJheUJ1ZmZlcihlLnJlc3BvbnNlIGFzIEJsb2IpLnRoZW4oYnVmID0+IHtcblx0XHRcdFx0XHRcdGd6LnB1c2gobmV3IFVpbnQ4QXJyYXkoYnVmKSk7XG5cdFx0XHRcdFx0XHRnei5wdXNoKG5ldyBVaW50OEFycmF5KDApLCB0cnVlKTtcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fSk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyZXNwb25zZVN0cmluZyA9IGZmbGF0ZS5zdHJGcm9tVTgobmV3IFVpbnQ4QXJyYXkoYXdhaXQgcmVhZEJsb2JBc0FycmF5QnVmZmVyKGUucmVzcG9uc2UgYXMgQmxvYikpKTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIFt0cnVlLCB1bmRlZmluZWQsIHtcblx0XHRcdFx0Li4uZSxcblx0XHRcdFx0cmVzcG9uc2VKU09OOiBlLnN0YXR1cyA9PT0gMjAwID8gdHJ5UGFyc2VKU09OKHJlc3BvbnNlU3RyaW5nKSA6IHVuZGVmaW5lZCxcblx0XHRcdH1dIGFzIGNvbnN0O1xuXHRcdH0sIGUgPT4gW2ZhbHNlLCBlLCB1bmRlZmluZWRdIGFzIGNvbnN0KTtcblx0fVxufVxuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFV0aWxpdGllc1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbmZ1bmN0aW9uIHRyeVBhcnNlSlNPTihzOiBzdHJpbmcpIHtcblx0dHJ5IHsgcmV0dXJuIEpTT04ucGFyc2Uocyk7IH0gY2F0Y2ggKGUpIHsgY29uc29sZS5lcnJvcihcIkpTT04gcGFyc2UgZXJyb3JcIiwgZSk7IHJldHVybiB1bmRlZmluZWQ7IH1cbn1cblxudHlwZSBQYXJhbXNJbnB1dCA9IFVSTFNlYXJjaFBhcmFtcyB8IFtzdHJpbmcsIHN0cmluZ11bXSB8IG9iamVjdCB8IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuaW50ZXJmYWNlIEh0dHBSZXF1ZXN0T3B0aW9uczxUWVBFIGV4dGVuZHMgXCJhcnJheWJ1ZmZlclwiIHwgXCJibG9iXCIgfCBcInRleHRcIj4ge1xuXHRtZXRob2Q6IHN0cmluZztcblx0dXJsOiBzdHJpbmc7XG5cdHJlc3BvbnNlVHlwZTogVFlQRTtcblx0aGVhZGVycz86IEhlYWRlcnNJbml0O1xuXHRxdWVyeVBhcmFtcz86IFBhcmFtc0lucHV0O1xuXHRyZXF1ZXN0Qm9keVN0cmluZz86IHN0cmluZztcbn1cblxuZnVuY3Rpb24gaHR0cFJlcXVlc3Q8VFlQRSBleHRlbmRzIFwiYXJyYXlidWZmZXJcIiB8IFwiYmxvYlwiIHwgXCJ0ZXh0XCI+KG9wdGlvbnM6IEh0dHBSZXF1ZXN0T3B0aW9uczxUWVBFPikge1xuXHRyZXR1cm4gbmV3IFByb21pc2U8e1xuXHRcdG9rOiBib29sZWFuOyBzdGF0dXM6IG51bWJlcjsgc3RhdHVzVGV4dDogc3RyaW5nOyBoZWFkZXJzOiBIZWFkZXJzO1xuXHRcdHJlc3BvbnNlOiBUWVBFIGV4dGVuZHMgXCJhcnJheWJ1ZmZlclwiID8gQXJyYXlCdWZmZXIgOiBUWVBFIGV4dGVuZHMgXCJibG9iXCIgPyBCbG9iIDogc3RyaW5nO1xuXHR9PigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cdFx0b3B0aW9ucy5tZXRob2QgPSBvcHRpb25zLm1ldGhvZC50b1VwcGVyQ2FzZSgpO1xuXHRcdGNvbnN0IHVybCA9IG5ldyBVUkwob3B0aW9ucy51cmwsIGxvY2F0aW9uLmhyZWYpO1xuXHRcdHBhcmFtc0lucHV0KG9wdGlvbnMucXVlcnlQYXJhbXMpLmZvckVhY2goKHYsIGspID0+IHVybC5zZWFyY2hQYXJhbXMuYXBwZW5kKGssIHYpKTtcblx0XHRjb25zdCBoZWFkZXJzID0gbmV3IEhlYWRlcnMob3B0aW9ucy5oZWFkZXJzIHx8IHt9KTtcblx0XHRjb25zdCByZXF1ZXN0ID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG5cdFx0cmVxdWVzdC5yZXNwb25zZVR5cGUgPSBvcHRpb25zLnJlc3BvbnNlVHlwZTtcblx0XHRyZXF1ZXN0Lm9wZW4ob3B0aW9ucy5tZXRob2QsIHVybCwgdHJ1ZSk7XG5cdFx0aWYgKCFoZWFkZXJzLmhhcyhcImNvbnRlbnQtdHlwZVwiKSkgaGVhZGVycy5zZXQoXCJjb250ZW50LXR5cGVcIiwgXCJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQ7IGNoYXJzZXQ9VVRGLThcIik7XG5cdFx0aWYgKCFoZWFkZXJzLmhhcyhcIngtcmVxdWVzdGVkLXdpdGhcIikpIGhlYWRlcnMuc2V0KFwieC1yZXF1ZXN0ZWQtd2l0aFwiLCBcIlRpZGRseVdpa2lcIik7XG5cdFx0aGVhZGVycy5zZXQoXCJhY2NlcHRcIiwgXCJhcHBsaWNhdGlvbi9qc29uXCIpO1xuXHRcdGhlYWRlcnMuZm9yRWFjaCgodiwgaykgPT4gcmVxdWVzdC5zZXRSZXF1ZXN0SGVhZGVyKGssIHYpKTtcblx0XHRyZXF1ZXN0Lm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdGlmICh0aGlzLnJlYWR5U3RhdGUgIT09IDQpIHJldHVybjtcblx0XHRcdGNvbnN0IGggPSBuZXcgSGVhZGVycygpO1xuXHRcdFx0cmVxdWVzdC5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKT8udHJpbSgpLnNwbGl0KC9bXFxyXFxuXSsvKS5mb3JFYWNoKGxpbmUgPT4ge1xuXHRcdFx0XHRjb25zdCBwYXJ0cyA9IGxpbmUuc3BsaXQoXCI6IFwiKTtcblx0XHRcdFx0Y29uc3Qga2V5ID0gcGFydHMuc2hpZnQoKT8udG9Mb3dlckNhc2UoKTtcblx0XHRcdFx0aWYgKGtleSkgaC5hcHBlbmQoa2V5LCBwYXJ0cy5qb2luKFwiOiBcIikpO1xuXHRcdFx0fSk7XG5cdFx0XHRyZXNvbHZlKHsgb2s6IHRoaXMuc3RhdHVzID49IDIwMCAmJiB0aGlzLnN0YXR1cyA8IDMwMCwgc3RhdHVzOiB0aGlzLnN0YXR1cywgc3RhdHVzVGV4dDogdGhpcy5zdGF0dXNUZXh0LCByZXNwb25zZTogdGhpcy5yZXNwb25zZSwgaGVhZGVyczogaCB9KTtcblx0XHR9O1xuXHRcdHJlcXVlc3Quc2VuZChvcHRpb25zLnJlcXVlc3RCb2R5U3RyaW5nKTtcblx0fSk7XG5cblx0ZnVuY3Rpb24gcGFyYW1zSW5wdXQoaW5wdXQ6IFBhcmFtc0lucHV0KSB7XG5cdFx0aWYgKCFpbnB1dCkgcmV0dXJuIG5ldyBVUkxTZWFyY2hQYXJhbXMoKTtcblx0XHRpZiAoaW5wdXQgaW5zdGFuY2VvZiBVUkxTZWFyY2hQYXJhbXMpIHJldHVybiBpbnB1dDtcblx0XHRpZiAoQXJyYXkuaXNBcnJheShpbnB1dCkgfHwgdHlwZW9mIGlucHV0ID09PSBcInN0cmluZ1wiKSByZXR1cm4gbmV3IFVSTFNlYXJjaFBhcmFtcyhpbnB1dCk7XG5cdFx0Y29uc3QgcGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcygpO1xuXHRcdGZvciAoY29uc3Qga2V5IGluIGlucHV0KSB7XG5cdFx0XHRpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGlucHV0LCBrZXkpKSB7XG5cdFx0XHRcdHBhcmFtcy5hcHBlbmQoa2V5LCAoaW5wdXQgYXMgUmVjb3JkPHN0cmluZywgc3RyaW5nPilba2V5XSk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBwYXJhbXM7XG5cdH1cbn1cblxuZnVuY3Rpb24gcmVhZEJsb2JBc0FycmF5QnVmZmVyKGJsb2I6IEJsb2IpIHtcblx0cmV0dXJuIG5ldyBQcm9taXNlPEFycmF5QnVmZmVyPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cdFx0Y29uc3QgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcblx0XHRyZWFkZXIub25sb2FkID0gKCkgPT4gcmVzb2x2ZShyZWFkZXIucmVzdWx0IGFzIEFycmF5QnVmZmVyKTtcblx0XHRyZWFkZXIub25lcnJvciA9ICgpID0+IHJlamVjdChuZXcgRXJyb3IoXCJFcnJvciByZWFkaW5nIGJsb2JcIikpO1xuXHRcdHJlYWRlci5yZWFkQXNBcnJheUJ1ZmZlcihibG9iKTtcblx0fSk7XG59XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gRXhwb3J0XG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuaWYgKCR0dy5icm93c2VyICYmIGRvY3VtZW50LmxvY2F0aW9uLnByb3RvY29sLnN0YXJ0c1dpdGgoXCJodHRwXCIpKSB7XG5cdGV4cG9ydHMuYWRhcHRvckNsYXNzID0gTXVsdGlXaWtpQ2xpZW50QWRhcHRvcjtcbn1cbiJdfQ==