@tiddlywiki/mws 0.0.21 → 0.1.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.
- package/README.md +42 -9
- package/dist/metafile-esm.json +1 -0
- package/dist/mws.d.ts +1 -0
- package/dist/mws.js +34710 -0
- package/dist/mws.js.map +1 -0
- package/editions/mws-docs/tiddlers/$__StoryList.tid +1 -2
- package/editions/mws-docs/tiddlers/2025-02-18 - User Management.md.meta +2 -2
- package/editions/mws-docs/tiddlers/2025-04-14 - client plugins /342/234/224/357/270/217.md" +31 -0
- package/editions/mws-docs/tiddlers/2025-04-14 - client plugins /342/234/224/357/270/217.md.meta" +5 -0
- package/editions/mws-docs/tiddlers/{2025-05-04.md → 2025-05-04 - event hooks /342/234/224/357/270/217.md" } +7 -1
- package/editions/mws-docs/tiddlers/2025-05-04 - event hooks /342/234/224/357/270/217.md.meta" +5 -0
- package/editions/mws-docs/tiddlers/{2025-05-06.md → 2025-05-06 - syncer design.md } +0 -4
- package/editions/mws-docs/tiddlers/2025-05-06 - syncer design.md.meta +5 -0
- package/editions/mws-docs/tiddlers/Allowed Methods.tid +8 -0
- package/editions/mws-docs/tiddlers/Application Access & Security.md +14 -84
- package/editions/mws-docs/tiddlers/Application Access & Security.md.meta +1 -1
- package/editions/mws-docs/tiddlers/Body Format.md +19 -0
- package/editions/mws-docs/tiddlers/Body Format.md.meta +4 -0
- package/editions/mws-docs/tiddlers/Checklists and Features.md +0 -3
- package/editions/mws-docs/tiddlers/Checklists and Features.md.meta +1 -1
- package/editions/mws-docs/tiddlers/Client Plugins.md +17 -0
- package/editions/mws-docs/tiddlers/Client Plugins.md.meta +5 -0
- package/editions/mws-docs/tiddlers/HTTP API.md +4 -3
- package/editions/mws-docs/tiddlers/HTTP API.md.meta +1 -1
- package/editions/mws-docs/tiddlers/HelloThere.tid +2 -2
- package/editions/mws-docs/tiddlers/Installation.tid +2 -3
- package/editions/mws-docs/tiddlers/MWS Architecture.tid +6 -1
- package/editions/mws-docs/tiddlers/Multi-user Trust.md +12 -0
- package/editions/mws-docs/tiddlers/Multi-user Trust.md.meta +5 -0
- package/editions/mws-docs/tiddlers/Notes.tid +5 -3
- package/editions/mws-docs/tiddlers/Oracle Attacks.md +29 -0
- package/editions/mws-docs/tiddlers/Oracle Attacks.md.meta +5 -0
- package/editions/mws-docs/tiddlers/Reference.md +1 -0
- package/editions/mws-docs/tiddlers/Reference.md.meta +1 -1
- package/editions/mws-docs/tiddlers/Request Handling.md +53 -0
- package/editions/mws-docs/tiddlers/Request Handling.md.meta +5 -0
- package/editions/mws-docs/tiddlers/Roadmap.tid +7 -0
- package/editions/mws-docs/tiddlers/Route Definers.md +206 -0
- package/editions/mws-docs/tiddlers/Route Definers.md.meta +5 -0
- package/editions/mws-docs/tiddlers/Security.md +75 -0
- package/editions/mws-docs/tiddlers/Security.md.meta +5 -0
- package/editions/mws-docs/tiddlers/Server Plugins.md +7 -0
- package/editions/mws-docs/tiddlers/Server Plugins.md.meta +5 -0
- package/editions/mws-docs/tiddlers/Startup Cache.md +28 -0
- package/editions/mws-docs/tiddlers/Startup Cache.md.meta +5 -0
- package/editions/mws-docs/tiddlers/TiddlerFields.md +5 -0
- package/editions/mws-docs/tiddlers/TiddlerFields.md.meta +4 -0
- package/editions/mws-docs/tiddlers/Usage.tid +2 -2
- package/editions/mws-docs/tiddlers/system/$__mws_cssvar-macro.tid +10 -0
- package/editions/mws-docs/tiddlers/system/$__palettes_MUI +143 -0
- package/editions/mws-docs/tiddlers/system/$__palettes_MUI.meta +7 -0
- package/editions/mws-docs/tiddlers/system/$__palettes_MUI_styles.css +567 -0
- package/editions/mws-docs/tiddlers/system/$__palettes_MUI_styles.css.meta +6 -0
- package/editions/mws-docs/tiddlers/system/$__theme.tid +6 -0
- package/editions/mws-docs/tiddlers/system/SplashScreen.tid +21 -0
- package/editions/mws-docs/tiddlers/system/StaticBanner.tid +1 -1
- package/editions/mws-docs/tiddlers/system/Styles.tid +13 -0
- package/editions/mws-docs/tiddlers/system/palette.tid +4 -1
- package/editions/mws-docs/tiddlers/system/sidebarlayout.tid +4 -1
- package/editions/mws-docs/tiddlers/x-mws-tiddler.md +35 -0
- package/editions/mws-docs/tiddlers/x-mws-tiddler.md.meta +5 -0
- package/mws.run.mjs +30 -0
- package/package.json +47 -36
- package/plugins/client/package-lock.json +46 -83
- package/plugins/client/package.json +1 -6
- package/plugins/client/plugin.info +2 -2
- package/plugins/client/src/fflate.d.ts +1501 -0
- package/plugins/client/src/multiwikiclientadaptor.ts +768 -317
- package/plugins/client/src/mws.d.ts +4 -0
- package/plugins/client/src/types.d.ts +3928 -0
- package/plugins/client/tiddlers/en-US.multids +3 -0
- package/plugins/client/tiddlers/status/SaveWikiButtonTemplate.tid +3 -0
- package/plugins/client/tiddlers/status/icon-cloud.tid +4 -0
- package/plugins/client/tiddlers/status/info-segment.tid +8 -0
- package/plugins/client/tiddlers/status/readonly-styles.tid +27 -0
- package/plugins/client/tiddlers/status/save-offline.tid +7 -0
- package/plugins/client/tiddlers/status/save-wiki-button.tid +26 -0
- package/plugins/client/tiddlers/status/styles.tid +44 -0
- package/plugins/client/tiddlers/status/syncer-actions-copy-logs.tid +6 -0
- package/plugins/client/tiddlers/status/syncer-actions-login-status.tid +9 -0
- package/plugins/client/tiddlers/status/syncer-actions-login.tid +8 -0
- package/plugins/client/tiddlers/status/syncer-actions-logout.tid +8 -0
- package/plugins/client/tiddlers/status/syncer-actions-refresh.tid +9 -0
- package/plugins/client/tiddlers/status/syncer-actions-save-snapshot.tid +9 -0
- package/plugins/client/tiddlers/status/tags-syncerdropdown.tid +2 -0
- package/plugins/client/tiddlers/syncer/multiwikiclientadaptor.js +640 -0
- package/plugins/client/tiddlers/syncer/syncer.js +831 -0
- package/plugins/client/tsconfig.json +19 -16
- package/plugins/filter-ast-to-sql/example-run-series.ts +146 -0
- package/plugins/server/SplashScreen.tid +150 -0
- package/plugins/server/fflate.js +9 -0
- package/plugins/server/plugin.info +8 -0
- package/plugins/server/readme +1 -0
- package/plugins/server/url-polyfill.js +294 -0
- package/prisma/client/client.d.ts +1 -0
- package/prisma/client/client.js +3 -0
- package/prisma/client/default.d.ts +1 -0
- package/prisma/client/default.js +3 -0
- package/prisma/client/edge.d.ts +1 -0
- package/prisma/client/edge.js +297 -0
- package/prisma/client/index-browser.js +275 -0
- package/prisma/client/index.d.ts +17770 -0
- package/prisma/client/index.js +324 -0
- package/prisma/client/package.json +173 -0
- package/prisma/client/query_engine_bg.js +811 -0
- package/prisma/client/query_engine_bg.wasm +0 -0
- package/prisma/client/runtime/edge-esm.js +10000 -0
- package/prisma/client/runtime/edge.js +10036 -0
- package/prisma/client/runtime/index-browser.d.ts +370 -0
- package/prisma/client/runtime/index-browser.js +2300 -0
- package/prisma/client/runtime/library.d.ts +3681 -0
- package/prisma/client/runtime/library.js +10604 -0
- package/prisma/client/runtime/react-native.js +10629 -0
- package/prisma/client/runtime/wasm-compiler-edge.js +11238 -0
- package/prisma/client/runtime/wasm-engine-edge.js +7801 -0
- package/prisma/client/schema.prisma +156 -0
- package/prisma/client/wasm-edge-light-loader.mjs +4 -0
- package/prisma/client/wasm-worker-loader.mjs +4 -0
- package/prisma/client/wasm.d.ts +1 -0
- package/prisma/client/wasm.js +304 -0
- package/prisma/global.ts +53 -0
- package/prisma/migrations/{20250406213424_init → 20250606001949_init}/migration.sql +46 -48
- package/prisma/migrations/20250613000526_remove_group/migration.sql +22 -0
- package/prisma/migrations/20250620014502_settings/migration.sql +5 -0
- package/prisma/migrations/20250707205229_recipes/migration.sql +20 -0
- package/prisma/migrations/migration_lock.toml +1 -1
- package/prisma/notes.md +1 -2
- package/prisma/schema.prisma +52 -49
- package/prisma/test.sqlite +0 -0
- package/prisma/test.sqlite-journal +0 -0
- package/public/react-admin/android-chrome-192x192.png +0 -0
- package/public/react-admin/android-chrome-512x512.png +0 -0
- package/public/react-admin/apple-touch-icon.png +0 -0
- package/{react-user-mgmt/public/esm-QKDFEP3B.js → public/react-admin/esm-L4WLVWJN.js} +1 -1
- package/public/react-admin/esm-L4WLVWJN.js.map +7 -0
- package/public/react-admin/esm-QMNGI3LF.js +3 -0
- package/public/react-admin/favicon-16x16.png +0 -0
- package/public/react-admin/favicon-32x32.png +0 -0
- package/public/react-admin/favicon.ico +0 -0
- package/public/react-admin/index.html +36 -0
- package/public/react-admin/main.js +268 -0
- package/public/react-admin/main.js.map +7 -0
- package/public/react-admin/site.webmanifest +20 -0
- package/public/react-admin/stats.json +1 -0
- package/scripts.mjs +134 -25
- package/dist/server.d.ts +0 -945
- package/dist/server.js +0 -20775
- package/dist/server.js.map +0 -1
- package/editions/mws-docs/tiddlers/2025-04-03 - Phases of Development.md +0 -64
- package/editions/mws-docs/tiddlers/2025-04-03 - Phases of Development.md.meta +0 -5
- package/editions/mws-docs/tiddlers/2025-04-13 - Plugins.md +0 -18
- package/editions/mws-docs/tiddlers/2025-04-13 - Plugins.md.meta +0 -5
- package/editions/mws-docs/tiddlers/2025-05-04.md.meta +0 -5
- package/editions/mws-docs/tiddlers/2025-05-06.md.meta +0 -5
- package/editions/mws-docs/tiddlers/Moduler Design.md +0 -29
- package/editions/mws-docs/tiddlers/Moduler Design.md.meta +0 -5
- package/editions/mws-docs/tiddlers/Request Server.md +0 -20
- package/editions/mws-docs/tiddlers/Request Server.md.meta +0 -5
- package/editions/mws-docs/tiddlers/system/$__palettes_MUI-Dark +0 -173
- package/editions/mws-docs/tiddlers/system/$__palettes_MUI-Dark.meta +0 -6
- package/editions/mws-docs/tiddlers/system/$__palettes_MUI-Light +0 -172
- package/editions/mws-docs/tiddlers/system/$__palettes_MUI-Light.meta +0 -6
- package/plugins/client/tiddlers/config-tiddlers-filter.tid +0 -2
- package/plugins/client/tiddlers/config-use-server-sent-events.tid +0 -2
- package/plugins/client/tiddlers/info-segment.tid +0 -8
- package/plugins/client/tiddlers/multiwikiclientadaptor.js +0 -444
- package/prisma/migrations/20250407002306_disconnect_user_tables/migration.sql +0 -52
- package/prisma/old-db.sql +0 -144
- package/react-user-mgmt/README.md +0 -50
- package/react-user-mgmt/eslint.config.js +0 -28
- package/react-user-mgmt/package-lock.json +0 -2738
- package/react-user-mgmt/package.json +0 -31
- package/react-user-mgmt/public/index.html +0 -1
- package/react-user-mgmt/public/main.js +0 -295
- package/react-user-mgmt/public/main.js.map +0 -7
- package/react-user-mgmt/public/stats.json +0 -1
- package/react-user-mgmt/tsconfig.json +0 -40
- package/react-user-mgmt/types.d.ts +0 -2
- package/tiddlywiki-types/boot/boot.d.ts +0 -378
- package/tiddlywiki-types/boot/bootprefix.d.ts +0 -110
- package/tiddlywiki-types/core/modules/filters.d.ts +0 -107
- package/tiddlywiki-types/core/modules/tiddler.d.ts +0 -47
- package/tiddlywiki-types/core/modules/wiki-bulkops.d.ts +0 -36
- package/tiddlywiki-types/core/modules/wiki.d.ts +0 -208
- package/tiddlywiki-types/index.d.ts +0 -7
- package/tiddlywiki-types/package.json +0 -3
- /package/plugins/client/tiddlers/{sidebarsegment.tid → status/sidebarsegment.tid} +0 -0
- /package/plugins/client/tiddlers/{GettingStarted.tid → syncer/GettingStarted.tid} +0 -0
- /package/plugins/client/tiddlers/{config-incoming-updates-filter.tid → syncer/config-incoming-updates-filter.tid} +0 -0
- /package/plugins/client/tiddlers/{readme.tid → syncer/readme.tid} +0 -0
- /package/{react-user-mgmt/public → public/react-admin}/chunk-YALWN5OT.js +0 -0
- /package/{react-user-mgmt/public → public/react-admin}/chunk-YALWN5OT.js.map +0 -0
- /package/{react-user-mgmt/public/esm-QKDFEP3B.js.map → public/react-admin/esm-QMNGI3LF.js.map} +0 -0
- /package/{react-user-mgmt/public → public/react-admin}/favicon.png +0 -0
- /package/{react-user-mgmt/public → public/react-admin}/missing-favicon.png +0 -0
- /package/{react-user-mgmt/public → public/react-admin}/motovun-jack.jpg +0 -0
- /package/{react-user-mgmt/public → public/react-admin}/mws-icon.png +0 -0
- /package/{react-user-mgmt/public → public/react-admin}/stats.css +0 -0
- /package/{react-user-mgmt/public → public/react-admin}/stats.html +0 -0
- /package/{react-user-mgmt/public → public/react-admin}/stats.js +0 -0
- /package/{react-user-mgmt/public → public/react-admin}/stats.svg +0 -0
- /package/{react-user-mgmt/public → public/react-admin}/vite.svg +0 -0
|
@@ -1,444 +0,0 @@
|
|
|
1
|
-
/*\
|
|
2
|
-
title: $:/plugins/tiddlywiki/tiddlyweb/tiddlywebadaptor.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
|
-
var CONFIG_HOST_TIDDLER = "$:/config/multiwikiclient/host", DEFAULT_HOST_TIDDLER = "$protocol$//$host$/", MWC_STATE_TIDDLER_PREFIX = "$:/state/multiwikiclient/", BAG_STATE_TIDDLER = "$:/state/multiwikiclient/tiddlers/bag", REVISION_STATE_TIDDLER = "$:/state/multiwikiclient/tiddlers/revision", CONNECTION_STATE_TIDDLER = "$:/state/multiwikiclient/connection", INCOMING_UPDATES_FILTER_TIDDLER = "$:/config/multiwikiclient/incoming-updates-filter", ENABLE_SSE_TIDDLER = "$:/config/multiwikiclient/use-server-sent-events";
|
|
31
|
-
var SERVER_NOT_CONNECTED = "NOT CONNECTED", SERVER_CONNECTING_SSE = "CONNECTING SSE", SERVER_CONNECTED_SSE = "CONNECTED SSE", SERVER_POLLING = "SERVER POLLING";
|
|
32
|
-
class MultiWikiClientAdaptor {
|
|
33
|
-
constructor(options) {
|
|
34
|
-
this.name = "multiwikiclient";
|
|
35
|
-
this.supportsLazyLoading = true;
|
|
36
|
-
this.wiki = options.wiki;
|
|
37
|
-
this.host = this.getHost();
|
|
38
|
-
this.recipe = this.wiki.getTiddlerText("$:/config/multiwikiclient/recipe");
|
|
39
|
-
this.useServerSentEvents = this.wiki.getTiddlerText(ENABLE_SSE_TIDDLER) === "yes";
|
|
40
|
-
this.last_known_tiddler_id = $tw.utils.parseNumber(this.wiki.getTiddlerText("$:/state/multiwikiclient/recipe/last_tiddler_id", "0"));
|
|
41
|
-
this.outstandingRequests = Object.create(null); // Hashmap by title of outstanding request object: {type: "PUT"|"GET"|"DELETE"}
|
|
42
|
-
this.lastRecordedUpdate = Object.create(null); // Hashmap by title of last recorded update via SSE: {type: "update"|"detetion", tiddler_id:}
|
|
43
|
-
this.logger = new $tw.utils.Logger("MultiWikiClientAdaptor");
|
|
44
|
-
this.isLoggedIn = false;
|
|
45
|
-
this.isReadOnly = false;
|
|
46
|
-
this.logoutIsAvailable = true;
|
|
47
|
-
// Compile the dirty tiddler filter
|
|
48
|
-
this.incomingUpdatesFilterFn = this.wiki.compileFilter(this.wiki.getTiddlerText(INCOMING_UPDATES_FILTER_TIDDLER));
|
|
49
|
-
this.setUpdateConnectionStatus(SERVER_NOT_CONNECTED);
|
|
50
|
-
}
|
|
51
|
-
setUpdateConnectionStatus(status) {
|
|
52
|
-
this.serverUpdateConnectionStatus = status;
|
|
53
|
-
this.wiki.addTiddler({
|
|
54
|
-
title: CONNECTION_STATE_TIDDLER,
|
|
55
|
-
text: status
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
setLoggerSaveBuffer(loggerForSaving) {
|
|
59
|
-
this.logger.setSaveBuffer(loggerForSaving);
|
|
60
|
-
}
|
|
61
|
-
isReady() {
|
|
62
|
-
return true;
|
|
63
|
-
}
|
|
64
|
-
getHost() {
|
|
65
|
-
var text = this.wiki.getTiddlerText(CONFIG_HOST_TIDDLER, DEFAULT_HOST_TIDDLER), substitutions = [
|
|
66
|
-
{ name: "protocol", value: document.location.protocol },
|
|
67
|
-
{ name: "host", value: document.location.host },
|
|
68
|
-
{ name: "pathname", value: document.location.pathname }
|
|
69
|
-
];
|
|
70
|
-
for (var t = 0; t < substitutions.length; t++) {
|
|
71
|
-
var s = substitutions[t];
|
|
72
|
-
text = $tw.utils.replaceString(text, new RegExp("\\$" + s.name + "\\$", "mg"), s.value);
|
|
73
|
-
}
|
|
74
|
-
return text;
|
|
75
|
-
}
|
|
76
|
-
getTiddlerInfo(tiddler) {
|
|
77
|
-
var title = tiddler.fields.title, revision = this.wiki.extractTiddlerDataItem(REVISION_STATE_TIDDLER, title), bag = this.wiki.extractTiddlerDataItem(BAG_STATE_TIDDLER, title);
|
|
78
|
-
if (revision && bag) {
|
|
79
|
-
return {
|
|
80
|
-
title: title,
|
|
81
|
-
revision: revision,
|
|
82
|
-
bag: bag
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
return undefined;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
getTiddlerBag(title) {
|
|
90
|
-
return this.wiki.extractTiddlerDataItem(BAG_STATE_TIDDLER, title);
|
|
91
|
-
}
|
|
92
|
-
getTiddlerRevision(title) {
|
|
93
|
-
return this.wiki.extractTiddlerDataItem(REVISION_STATE_TIDDLER, title);
|
|
94
|
-
}
|
|
95
|
-
setTiddlerInfo(title, revision, bag) {
|
|
96
|
-
this.wiki.setText(BAG_STATE_TIDDLER, null, title, bag, { suppressTimestamp: true });
|
|
97
|
-
this.wiki.setText(REVISION_STATE_TIDDLER, null, title, revision, { suppressTimestamp: true });
|
|
98
|
-
}
|
|
99
|
-
removeTiddlerInfo(title) {
|
|
100
|
-
this.wiki.setText(BAG_STATE_TIDDLER, null, title, undefined, { suppressTimestamp: true });
|
|
101
|
-
this.wiki.setText(REVISION_STATE_TIDDLER, null, title, undefined, { suppressTimestamp: true });
|
|
102
|
-
}
|
|
103
|
-
httpRequest(options) {
|
|
104
|
-
return (new Promise((resolve) => {
|
|
105
|
-
$tw.utils.httpRequest(Object.assign(Object.assign({}, options), { responseType: options.responseType === "json" ? "text" : options.responseType, callback: (err, data, request) => {
|
|
106
|
-
var _a;
|
|
107
|
-
if (err)
|
|
108
|
-
return resolve([false, err || new Error("Unknown error"), undefined]);
|
|
109
|
-
// Create a map of header names to values
|
|
110
|
-
const headers = {};
|
|
111
|
-
(_a = request.getAllResponseHeaders()) === null || _a === void 0 ? void 0 : _a.trim().split(/[\r\n]+/).forEach((line) => {
|
|
112
|
-
var _a;
|
|
113
|
-
const parts = line.split(": ");
|
|
114
|
-
const header = (_a = parts.shift()) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
115
|
-
const value = parts.join(": ");
|
|
116
|
-
if (header)
|
|
117
|
-
headers[header] = value;
|
|
118
|
-
});
|
|
119
|
-
// Resolve the promise with the response data and headers
|
|
120
|
-
resolve([true, undefined, {
|
|
121
|
-
headers,
|
|
122
|
-
data: options.responseType === "json" ? $tw.utils.parseJSONSafe(data, () => undefined) : data,
|
|
123
|
-
}]);
|
|
124
|
-
} }));
|
|
125
|
-
}));
|
|
126
|
-
}
|
|
127
|
-
/*
|
|
128
|
-
Get the current status of the server connection
|
|
129
|
-
*/
|
|
130
|
-
getStatus(callback) {
|
|
131
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
132
|
-
var _a, _b, _c;
|
|
133
|
-
const [ok, error, data] = yield this.httpRequest({
|
|
134
|
-
url: this.host + "recipes/" + this.recipe + "/status",
|
|
135
|
-
type: "GET",
|
|
136
|
-
responseType: "json",
|
|
137
|
-
headers: {
|
|
138
|
-
'Content-Type': 'application/json',
|
|
139
|
-
"X-Requested-With": "TiddlyWiki"
|
|
140
|
-
},
|
|
141
|
-
});
|
|
142
|
-
if (!ok) {
|
|
143
|
-
this.logger.log("Error getting status", error);
|
|
144
|
-
if (callback)
|
|
145
|
-
callback(error);
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
/** @type {Partial<UserAuthStatus>} */
|
|
149
|
-
const status = data.data;
|
|
150
|
-
if (callback) {
|
|
151
|
-
callback(
|
|
152
|
-
// Error
|
|
153
|
-
null,
|
|
154
|
-
// Is logged in
|
|
155
|
-
(_a = status.isLoggedIn) !== null && _a !== void 0 ? _a : false,
|
|
156
|
-
// Username
|
|
157
|
-
(_b = status.username) !== null && _b !== void 0 ? _b : "(anon)",
|
|
158
|
-
// Is read only
|
|
159
|
-
(_c = status.isReadOnly) !== null && _c !== void 0 ? _c : true,
|
|
160
|
-
// Is anonymous
|
|
161
|
-
!status.isLoggedIn);
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
/*
|
|
166
|
-
Get details of changed tiddlers from the server
|
|
167
|
-
*/
|
|
168
|
-
getUpdatedTiddlers(syncer, callback) {
|
|
169
|
-
if (!this.useServerSentEvents) {
|
|
170
|
-
this.pollServer({
|
|
171
|
-
callback: function (err, changes) {
|
|
172
|
-
callback(null, changes);
|
|
173
|
-
}
|
|
174
|
-
});
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
177
|
-
var self = this;
|
|
178
|
-
// Do nothing if there's already a connection in progress.
|
|
179
|
-
if (this.serverUpdateConnectionStatus !== SERVER_NOT_CONNECTED) {
|
|
180
|
-
return callback(null, {
|
|
181
|
-
modifications: [],
|
|
182
|
-
deletions: []
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
// Try to connect a server stream
|
|
186
|
-
this.setUpdateConnectionStatus(SERVER_CONNECTING_SSE);
|
|
187
|
-
this.connectServerStream({
|
|
188
|
-
syncer: syncer,
|
|
189
|
-
onerror: function (err) {
|
|
190
|
-
self.logger.log("Error connecting SSE stream", err);
|
|
191
|
-
// If the stream didn't work, try polling
|
|
192
|
-
self.setUpdateConnectionStatus(SERVER_POLLING);
|
|
193
|
-
self.pollServer({
|
|
194
|
-
callback: function (err, changes) {
|
|
195
|
-
self.setUpdateConnectionStatus(SERVER_NOT_CONNECTED);
|
|
196
|
-
callback(null, changes);
|
|
197
|
-
}
|
|
198
|
-
});
|
|
199
|
-
},
|
|
200
|
-
onopen: function () {
|
|
201
|
-
self.setUpdateConnectionStatus(SERVER_CONNECTED_SSE);
|
|
202
|
-
// The syncer is expecting a callback but we don't have any data to send
|
|
203
|
-
callback(null, {
|
|
204
|
-
modifications: [],
|
|
205
|
-
deletions: []
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
/*
|
|
211
|
-
Attempt to establish an SSE stream with the server and transfer tiddler changes. Options include:
|
|
212
|
-
|
|
213
|
-
syncer: reference to syncer object used for storing data
|
|
214
|
-
onopen: invoked when the stream is successfully opened
|
|
215
|
-
onerror: invoked if there is an error
|
|
216
|
-
*/
|
|
217
|
-
connectServerStream(options) {
|
|
218
|
-
var self = this;
|
|
219
|
-
const eventSource = new EventSource("/recipes/" + this.recipe + "/events?last_known_tiddler_id=" + this.last_known_tiddler_id);
|
|
220
|
-
eventSource.onerror = function (event) {
|
|
221
|
-
if (options.onerror) {
|
|
222
|
-
options.onerror(event);
|
|
223
|
-
}
|
|
224
|
-
};
|
|
225
|
-
eventSource.onopen = function (event) {
|
|
226
|
-
if (options.onopen) {
|
|
227
|
-
options.onopen(event);
|
|
228
|
-
}
|
|
229
|
-
};
|
|
230
|
-
eventSource.addEventListener("change", function (event) {
|
|
231
|
-
const data = $tw.utils.parseJSONSafe(event.data);
|
|
232
|
-
if (!data)
|
|
233
|
-
return;
|
|
234
|
-
console.log("SSE data", data);
|
|
235
|
-
// Update last seen tiddler_id
|
|
236
|
-
if (data.tiddler_id > self.last_known_tiddler_id) {
|
|
237
|
-
self.last_known_tiddler_id = data.tiddler_id;
|
|
238
|
-
}
|
|
239
|
-
// Record the last update to this tiddler
|
|
240
|
-
self.lastRecordedUpdate[data.title] = {
|
|
241
|
-
type: data.is_deleted ? "deletion" : "update",
|
|
242
|
-
tiddler_id: data.tiddler_id
|
|
243
|
-
};
|
|
244
|
-
console.log(`Oustanding requests is ${JSON.stringify(self.outstandingRequests[data.title])}`);
|
|
245
|
-
// Process the update if the tiddler is not the subject of an outstanding request
|
|
246
|
-
if (self.outstandingRequests[data.title])
|
|
247
|
-
return;
|
|
248
|
-
if (data.is_deleted) {
|
|
249
|
-
self.removeTiddlerInfo(data.title);
|
|
250
|
-
delete options.syncer.tiddlerInfo[data.title];
|
|
251
|
-
options.syncer.logger.log("Deleting tiddler missing from server:", data.title);
|
|
252
|
-
options.syncer.wiki.deleteTiddler(data.title);
|
|
253
|
-
options.syncer.processTaskQueue();
|
|
254
|
-
}
|
|
255
|
-
else {
|
|
256
|
-
var result = self.incomingUpdatesFilterFn.call(self.wiki, self.wiki.makeTiddlerIterator([data.title]));
|
|
257
|
-
if (result.length > 0) {
|
|
258
|
-
self.setTiddlerInfo(data.title, data.tiddler_id.toString(), data.bag_name);
|
|
259
|
-
options.syncer.storeTiddler(data.tiddler);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
|
-
/*
|
|
265
|
-
Poll the server for changes. Options include:
|
|
266
|
-
|
|
267
|
-
callback: invoked on completion as (err,changes)
|
|
268
|
-
*/
|
|
269
|
-
pollServer(options) {
|
|
270
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
271
|
-
var self = this;
|
|
272
|
-
const [ok, err, result] = yield this.httpRequest({
|
|
273
|
-
url: this.host + "recipes/" + this.recipe + "/tiddlers.json",
|
|
274
|
-
data: {
|
|
275
|
-
last_known_tiddler_id: this.last_known_tiddler_id,
|
|
276
|
-
include_deleted: "true"
|
|
277
|
-
},
|
|
278
|
-
responseType: "json",
|
|
279
|
-
});
|
|
280
|
-
if (!ok) {
|
|
281
|
-
return options.callback(err);
|
|
282
|
-
}
|
|
283
|
-
const { data: tiddlerInfoArray = [] } = result;
|
|
284
|
-
var modifications = [], deletions = [];
|
|
285
|
-
$tw.utils.each(tiddlerInfoArray,
|
|
286
|
-
/**
|
|
287
|
-
* @param {{ title: string; tiddler_id: number; is_deleted: boolean; bag_name: string; }} tiddlerInfo
|
|
288
|
-
*/
|
|
289
|
-
function (tiddlerInfo) {
|
|
290
|
-
if (tiddlerInfo.tiddler_id > self.last_known_tiddler_id) {
|
|
291
|
-
self.last_known_tiddler_id = tiddlerInfo.tiddler_id;
|
|
292
|
-
}
|
|
293
|
-
if (tiddlerInfo.is_deleted) {
|
|
294
|
-
deletions.push(tiddlerInfo.title);
|
|
295
|
-
}
|
|
296
|
-
else {
|
|
297
|
-
modifications.push(tiddlerInfo.title);
|
|
298
|
-
}
|
|
299
|
-
});
|
|
300
|
-
// Invoke the callback with the results
|
|
301
|
-
options.callback(null, {
|
|
302
|
-
modifications: modifications,
|
|
303
|
-
deletions: deletions
|
|
304
|
-
});
|
|
305
|
-
setTimeout(() => {
|
|
306
|
-
// If Browswer Storage tiddlers were cached on reloading the wiki, add them after sync from server completes in the above callback.
|
|
307
|
-
if ($tw.browserStorage && $tw.browserStorage.isEnabled()) {
|
|
308
|
-
$tw.browserStorage.addCachedTiddlers();
|
|
309
|
-
}
|
|
310
|
-
});
|
|
311
|
-
});
|
|
312
|
-
}
|
|
313
|
-
/*
|
|
314
|
-
Queue a load for a tiddler if there has been an update for it since the specified revision
|
|
315
|
-
*/
|
|
316
|
-
checkLastRecordedUpdate(title, revision) {
|
|
317
|
-
var lru = this.lastRecordedUpdate[title];
|
|
318
|
-
if (lru) {
|
|
319
|
-
var numRevision = $tw.utils.getInt(revision, 0);
|
|
320
|
-
if (!numRevision) {
|
|
321
|
-
this.logger.log("Error: revision is not a number", revision);
|
|
322
|
-
return;
|
|
323
|
-
}
|
|
324
|
-
console.log(`Checking for updates to ${title} since ${JSON.stringify(revision)} comparing to ${numRevision}`);
|
|
325
|
-
if (lru.tiddler_id > numRevision) {
|
|
326
|
-
this.syncer && this.syncer.enqueueLoadTiddler(title);
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
get syncer() {
|
|
331
|
-
//@ts-expect-error
|
|
332
|
-
if ($tw.syncadaptor === this)
|
|
333
|
-
return $tw.syncer;
|
|
334
|
-
}
|
|
335
|
-
/*
|
|
336
|
-
Save a tiddler and invoke the callback with (err,adaptorInfo,revision)
|
|
337
|
-
*/
|
|
338
|
-
saveTiddler(tiddler, callback, options) {
|
|
339
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
340
|
-
var self = this, title = tiddler.fields.title;
|
|
341
|
-
if (this.isReadOnly || title.substr(0, MWC_STATE_TIDDLER_PREFIX.length) === MWC_STATE_TIDDLER_PREFIX) {
|
|
342
|
-
return callback(null);
|
|
343
|
-
}
|
|
344
|
-
self.outstandingRequests[title] = { type: "PUT" };
|
|
345
|
-
// TODO: not using getFieldStringBlock because what happens if a field name has a colon in it?
|
|
346
|
-
let body = JSON.stringify(tiddler.getFieldStrings({ exclude: ["text"] }));
|
|
347
|
-
if (tiddler.hasField("text")) {
|
|
348
|
-
if (typeof tiddler.fields.text !== "string" && tiddler.fields.text)
|
|
349
|
-
return callback(new Error("Error saving tiddler " + tiddler.fields.title + ": the text field is truthy but not a string"));
|
|
350
|
-
body += `\n\n${tiddler.fields.text}`;
|
|
351
|
-
}
|
|
352
|
-
const [ok, err, result] = yield this.httpRequest({
|
|
353
|
-
url: this.host + "recipes/" + encodeURIComponent(this.recipe) + "/tiddlers/" + encodeURIComponent(title),
|
|
354
|
-
type: "PUT",
|
|
355
|
-
headers: {
|
|
356
|
-
"Content-type": "application/x-mws-tiddler"
|
|
357
|
-
},
|
|
358
|
-
data: body,
|
|
359
|
-
responseType: "json",
|
|
360
|
-
});
|
|
361
|
-
delete self.outstandingRequests[title];
|
|
362
|
-
if (!ok)
|
|
363
|
-
return callback(err);
|
|
364
|
-
const { headers, data } = result;
|
|
365
|
-
//If Browser-Storage plugin is present, remove tiddler from local storage after successful sync to the server
|
|
366
|
-
if ($tw.browserStorage && $tw.browserStorage.isEnabled()) {
|
|
367
|
-
$tw.browserStorage.removeTiddlerFromLocalStorage(title);
|
|
368
|
-
}
|
|
369
|
-
// Save the details of the new revision of the tiddler
|
|
370
|
-
const revision = data.tiddler_id, bag_name = data.bag_name;
|
|
371
|
-
console.log(`Saved ${title} with revision ${revision} and bag ${bag_name}`);
|
|
372
|
-
// If there has been a more recent update from the server then enqueue a load of this tiddler
|
|
373
|
-
self.checkLastRecordedUpdate(title, revision);
|
|
374
|
-
// Invoke the callback
|
|
375
|
-
self.setTiddlerInfo(title, revision, bag_name);
|
|
376
|
-
callback(null, { bag: bag_name }, revision);
|
|
377
|
-
});
|
|
378
|
-
}
|
|
379
|
-
/*
|
|
380
|
-
Load a tiddler and invoke the callback with (err,tiddlerFields)
|
|
381
|
-
|
|
382
|
-
The syncer does not pass itself into options.
|
|
383
|
-
*/
|
|
384
|
-
loadTiddler(title, callback, options) {
|
|
385
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
386
|
-
var self = this;
|
|
387
|
-
self.outstandingRequests[title] = { type: "GET" };
|
|
388
|
-
const [ok, err, result] = yield this.httpRequest({
|
|
389
|
-
url: this.host + "recipes/" + encodeURIComponent(this.recipe) + "/tiddlers/" + encodeURIComponent(title),
|
|
390
|
-
});
|
|
391
|
-
delete self.outstandingRequests[title];
|
|
392
|
-
if (err === 404) {
|
|
393
|
-
return callback(null, null);
|
|
394
|
-
}
|
|
395
|
-
else if (!ok) {
|
|
396
|
-
return callback(err);
|
|
397
|
-
}
|
|
398
|
-
const { data, headers } = result;
|
|
399
|
-
const revision = headers["x-revision-number"], bag_name = headers["x-bag-name"];
|
|
400
|
-
// If there has been a more recent update from the server then enqueue a load of this tiddler
|
|
401
|
-
self.checkLastRecordedUpdate(title, revision);
|
|
402
|
-
// Invoke the callback
|
|
403
|
-
self.setTiddlerInfo(title, revision, bag_name);
|
|
404
|
-
callback(null, $tw.utils.parseJSONSafe(data));
|
|
405
|
-
});
|
|
406
|
-
}
|
|
407
|
-
/*
|
|
408
|
-
Delete a tiddler and invoke the callback with (err)
|
|
409
|
-
options include:
|
|
410
|
-
tiddlerInfo: the syncer's tiddlerInfo for this tiddler
|
|
411
|
-
*/
|
|
412
|
-
deleteTiddler(title, callback, options) {
|
|
413
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
414
|
-
var self = this;
|
|
415
|
-
if (this.isReadOnly) {
|
|
416
|
-
return callback(null);
|
|
417
|
-
}
|
|
418
|
-
// If we don't have a bag it means that the tiddler hasn't been seen by the server, so we don't need to delete it
|
|
419
|
-
// var bag = this.getTiddlerBag(title);
|
|
420
|
-
// if(!bag) { return callback(null, options.tiddlerInfo.adaptorInfo); }
|
|
421
|
-
self.outstandingRequests[title] = { type: "DELETE" };
|
|
422
|
-
// Issue HTTP request to delete the tiddler
|
|
423
|
-
const [ok, err, result] = yield this.httpRequest({
|
|
424
|
-
url: this.host + "recipes/" + encodeURIComponent(this.recipe) + "/tiddlers/" + encodeURIComponent(title),
|
|
425
|
-
type: "DELETE",
|
|
426
|
-
});
|
|
427
|
-
delete self.outstandingRequests[title];
|
|
428
|
-
if (!ok) {
|
|
429
|
-
return callback(err);
|
|
430
|
-
}
|
|
431
|
-
const { data } = result;
|
|
432
|
-
const revision = data.tiddler_id, bag_name = data.bag_name;
|
|
433
|
-
// If there has been a more recent update from the server then enqueue a load of this tiddler
|
|
434
|
-
self.checkLastRecordedUpdate(title, revision);
|
|
435
|
-
self.removeTiddlerInfo(title);
|
|
436
|
-
// Invoke the callback & return null adaptorInfo
|
|
437
|
-
callback(null, null);
|
|
438
|
-
});
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
if ($tw.browser && document.location.protocol.startsWith("http")) {
|
|
442
|
-
exports.adaptorClass = MultiWikiClientAdaptor;
|
|
443
|
-
}
|
|
444
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVsdGl3aWtpY2xpZW50YWRhcHRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9tdWx0aXdpa2ljbGllbnRhZGFwdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7O0dBZ0JHO0FBRUgsa0VBQWtFO0FBQ2xFLFlBQVksQ0FBQzs7Ozs7Ozs7Ozs7QUFzQmIsSUFBSSxtQkFBbUIsR0FBRyxnQ0FBZ0MsRUFDekQsb0JBQW9CLEdBQUcscUJBQXFCLEVBQzVDLHdCQUF3QixHQUFHLDJCQUEyQixFQUN0RCxpQkFBaUIsR0FBRyx1Q0FBdUMsRUFDM0Qsc0JBQXNCLEdBQUcsNENBQTRDLEVBQ3JFLHdCQUF3QixHQUFHLHFDQUFxQyxFQUNoRSwrQkFBK0IsR0FBRyxtREFBbUQsRUFDckYsa0JBQWtCLEdBQUcsa0RBQWtELENBQUM7QUFFekUsSUFBSSxvQkFBb0IsR0FBRyxlQUFlLEVBQ3pDLHFCQUFxQixHQUFHLGdCQUFnQixFQUN4QyxvQkFBb0IsR0FBRyxlQUFlLEVBQ3RDLGNBQWMsR0FBRyxnQkFBZ0IsQ0FBQztBQUVuQyxNQUFNLHNCQUFzQjtJQWlCM0IsWUFBWSxPQUFzQjtRQUZsQyxTQUFJLEdBQUcsaUJBQWlCLENBQUM7UUFDekIsd0JBQW1CLEdBQUcsSUFBSSxDQUFDO1FBRTFCLElBQUksQ0FBQyxJQUFJLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQztRQUN6QixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUMzQixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLGtDQUFrQyxDQUFDLENBQUM7UUFDM0UsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLGtCQUFrQixDQUFDLEtBQUssS0FBSyxDQUFDO1FBQ2xGLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxHQUFHLENBQUMsS0FB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QUFJLEdBQUcsVUFBVSxHQUFHLGtCQUFrQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxZQUFZLEdBQUcsa0JBQWtCLENBQUMsS0FBSyxDQUFDO2dCQUN4RyxJQUFJLEVBQUUsUUFBUTthQUNkLENBQUMsQ0FBQztZQUNILE9BQU8sSUFBSSxDQUFDLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3ZDLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQztnQkFBQyxPQUFPLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUFDLENBQUM7WUFDbEMsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHLE1BQU0sQ0FBQztZQUN4QixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDO1lBQzNELDZGQUE2RjtZQUM3RixJQUFJLENBQUMsdUJBQXVCLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQzlDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUM5QixnREFBZ0Q7WUFDaEQsUUFBUSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztRQUN0QixDQUFDO0tBQUE7Q0FDRDtBQUdELElBQUksR0FBRyxDQUFDLE9BQU8sSUFBSSxRQUFRLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztJQUNsRSxPQUFPLENBQUMsWUFBWSxHQUFHLHNCQUFzQixDQUFDO0FBQy9DLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxcXG50aXRsZTogJDovcGx1Z2lucy90aWRkbHl3aWtpL3RpZGRseXdlYi90aWRkbHl3ZWJhZGFwdG9yLmpzXG50eXBlOiBhcHBsaWNhdGlvbi9qYXZhc2NyaXB0XG5tb2R1bGUtdHlwZTogc3luY2FkYXB0b3JcblxuQSBzeW5jIGFkYXB0b3IgbW9kdWxlIGZvciBzeW5jaHJvbmlzaW5nIHdpdGggTXVsdGlXaWtpU2VydmVyLWNvbXBhdGlibGUgc2VydmVycy4gXG5cbkl0IGhhcyB0aHJlZSBrZXkgYXJlYXMgb2YgY29uY2VybjpcblxuKiBCYXNpYyBvcGVyYXRpb25zIGxpa2UgcHV0LCBnZXQsIGFuZCBkZWxldGUgYSB0aWRkbGVyIG9uIHRoZSBzZXJ2ZXJcbiogUmVhbCB0aW1lIHVwZGF0ZXMgZnJvbSB0aGUgc2VydmVyIChoYW5kbGVkIGJ5IFNTRSlcbiogQmFncyBhbmQgcmVjaXBlcywgd2hpY2ggYXJlIHVua25vd24gdG8gdGhlIHN5bmNlclxuXG5BIGtleSBhc3BlY3Qgb2YgdGhlIGRlc2lnbiBpcyB0aGF0IHRoZSBzeW5jZXIgbmV2ZXIgb3ZlcmxhcHMgYmFzaWMgc2VydmVyIG9wZXJhdGlvbnM7IGl0IHdhaXRzIGZvciB0aGVcbnByZXZpb3VzIG9wZXJhdGlvbiB0byBjb21wbGV0ZSBiZWZvcmUgc2VuZGluZyBhIG5ldyBvbmUuXG5cblxcKi9cblxuLy8gdGhlIGJsYW5rIGxpbmUgaXMgaW1wb3J0YW50LCBhbmQgc28gaXMgdGhlIGZvbGxvd2luZyB1c2Ugc3RyaWN0XG5cInVzZSBzdHJpY3RcIjtcbmltcG9ydCB0eXBlIHsgTG9nZ2VyIH0gZnJvbSBcIiQ6L2NvcmUvbW9kdWxlcy91dGlscy9sb2dnZXIuanNcIjtcbmltcG9ydCB0eXBlIHsgU3luY2VyLCBUaWRkbGVyLCBJVGlkZGx5V2lraSB9IGZyb20gXCJ0aWRkbHl3aWtpXCI7XG5cbmRlY2xhcmUgbW9kdWxlICd0aWRkbHl3aWtpJyB7XG5cdGV4cG9ydCBpbnRlcmZhY2UgU3luY2VyIHtcblx0XHR3aWtpOiBXaWtpO1xuXHRcdGxvZ2dlcjogTG9nZ2VyO1xuXHRcdHRpZGRsZXJJbmZvOiBSZWNvcmQ8c3RyaW5nLCB7IGJhZzogc3RyaW5nOyByZXZpc2lvbjogc3RyaW5nIH0+O1xuXHRcdGVucXVldWVMb2FkVGlkZGxlcih0aXRsZTogc3RyaW5nKTogdm9pZDtcblx0XHRzdG9yZVRpZGRsZXIodGlkZGxlcjogVGlkZGxlcik6IHZvaWQ7XG5cdFx0cHJvY2Vzc1Rhc2tRdWV1ZSgpOiB2b2lkO1xuXHR9XG5cdGludGVyZmFjZSBJVGlkZGx5V2lraSB7XG5cdFx0YnJvd3NlclN0b3JhZ2U6IGFueTtcblx0fVxufVxuXG5kZWNsYXJlIGNvbnN0IGV4cG9ydHM6IHtcblx0YWRhcHRvckNsYXNzOiB0eXBlb2YgTXVsdGlXaWtpQ2xpZW50QWRhcHRvcjtcbn07XG5cbnZhciBDT05GSUdfSE9TVF9USURETEVSID0gXCIkOi9jb25maWcvbXVsdGl3aWtpY2xpZW50L2hvc3RcIixcblx0REVGQVVMVF9IT1NUX1RJRERMRVIgPSBcIiRwcm90b2NvbCQvLyRob3N0JC9cIixcblx0TVdDX1NUQVRFX1RJRERMRVJfUFJFRklYID0gXCIkOi9zdGF0ZS9tdWx0aXdpa2ljbGllbnQvXCIsXG5cdEJBR19TVEFURV9USURETEVSID0gXCIkOi9zdGF0ZS9tdWx0aXdpa2ljbGllbnQvdGlkZGxlcnMvYmFnXCIsXG5cdFJFVklTSU9OX1NUQVRFX1RJRERMRVIgPSBcIiQ6L3N0YXRlL211bHRpd2lraWNsaWVudC90aWRkbGVycy9yZXZpc2lvblwiLFxuXHRDT05ORUNUSU9OX1NUQVRFX1RJRERMRVIgPSBcIiQ6L3N0YXRlL211bHRpd2lraWNsaWVudC9jb25uZWN0aW9uXCIsXG5cdElOQ09NSU5HX1VQREFURVNfRklMVEVSX1RJRERMRVIgPSBcIiQ6L2NvbmZpZy9tdWx0aXdpa2ljbGllbnQvaW5jb21pbmctdXBkYXRlcy1maWx0ZXJcIixcblx0RU5BQkxFX1NTRV9USURETEVSID0gXCIkOi9jb25maWcvbXVsdGl3aWtpY2xpZW50L3VzZS1zZXJ2ZXItc2VudC1ldmVudHNcIjtcblxudmFyIFNFUlZFUl9OT1RfQ09OTkVDVEVEID0gXCJOT1QgQ09OTkVDVEVEXCIsXG5cdFNFUlZFUl9DT05ORUNUSU5HX1NTRSA9IFwiQ09OTkVDVElORyBTU0VcIixcblx0U0VSVkVSX0NPTk5FQ1RFRF9TU0UgPSBcIkNPTk5FQ1RFRCBTU0VcIixcblx0U0VSVkVSX1BPTExJTkcgPSBcIlNFUlZFUiBQT0xMSU5HXCI7XG5cbmNsYXNzIE11bHRpV2lraUNsaWVudEFkYXB0b3Ige1xuXHR3aWtpO1xuXHRob3N0O1xuXHRyZWNpcGU7XG5cdHVzZVNlcnZlclNlbnRFdmVudHM7XG5cdGxhc3Rfa25vd25fdGlkZGxlcl9pZDtcblx0b3V0c3RhbmRpbmdSZXF1ZXN0cztcblx0bGFzdFJlY29yZGVkVXBkYXRlO1xuXHRsb2dnZXI7XG5cdGlzTG9nZ2VkSW47XG5cdGlzUmVhZE9ubHk7XG5cdGxvZ291dElzQXZhaWxhYmxlO1xuXHRpbmNvbWluZ1VwZGF0ZXNGaWx0ZXJGbjtcblx0c2VydmVyVXBkYXRlQ29ubmVjdGlvblN0YXR1cyE6IHN0cmluZztcblxuXHRuYW1lID0gXCJtdWx0aXdpa2ljbGllbnRcIjtcblx0c3VwcG9ydHNMYXp5TG9hZGluZyA9IHRydWU7XG5cdGNvbnN0cnVjdG9yKG9wdGlvbnM6IHsgd2lraTogYW55IH0pIHtcblx0XHR0aGlzLndpa2kgPSBvcHRpb25zLndpa2k7XG5cdFx0dGhpcy5ob3N0ID0gdGhpcy5nZXRIb3N0KCk7XG5cdFx0dGhpcy5yZWNpcGUgPSB0aGlzLndpa2kuZ2V0VGlkZGxlclRleHQoXCIkOi9jb25maWcvbXVsdGl3aWtpY2xpZW50L3JlY2lwZVwiKTtcblx0XHR0aGlzLnVzZVNlcnZlclNlbnRFdmVudHMgPSB0aGlzLndpa2kuZ2V0VGlkZGxlclRleHQoRU5BQkxFX1NTRV9USURETEVSKSA9PT0gXCJ5ZXNcIjtcblx0XHR0aGlzLmxhc3Rfa25vd25fdGlkZGxlcl9pZCA9ICR0dy51dGlscy5wYXJzZU51bWJlcih0aGlzLndpa2kuZ2V0VGlkZGxlclRleHQoXCIkOi9zdGF0ZS9tdWx0aXdpa2ljbGllbnQvcmVjaXBlL2xhc3RfdGlkZGxlcl9pZFwiLCBcIjBcIikpO1xuXHRcdHRoaXMub3V0c3RhbmRpbmdSZXF1ZXN0cyA9IE9iamVjdC5jcmVhdGUobnVsbCk7IC8vIEhhc2htYXAgYnkgdGl0bGUgb2Ygb3V0c3RhbmRpbmcgcmVxdWVzdCBvYmplY3Q6IHt0eXBlOiBcIlBVVFwifFwiR0VUXCJ8XCJERUxFVEVcIn1cblx0XHR0aGlzLmxhc3RSZWNvcmRlZFVwZGF0ZSA9IE9iamVjdC5jcmVhdGUobnVsbCk7IC8vIEhhc2htYXAgYnkgdGl0bGUgb2YgbGFzdCByZWNvcmRlZCB1cGRhdGUgdmlhIFNTRToge3R5cGU6IFwidXBkYXRlXCJ8XCJkZXRldGlvblwiLCB0aWRkbGVyX2lkOn1cblx0XHR0aGlzLmxvZ2dlciA9IG5ldyAkdHcudXRpbHMuTG9nZ2VyKFwiTXVsdGlXaWtpQ2xpZW50QWRhcHRvclwiKTtcblx0XHR0aGlzLmlzTG9nZ2VkSW4gPSBmYWxzZTtcblx0XHR0aGlzLmlzUmVhZE9ubHkgPSBmYWxzZTtcblx0XHR0aGlzLmxvZ291dElzQXZhaWxhYmxlID0gdHJ1ZTtcblx0XHQvLyBDb21waWxlIHRoZSBkaXJ0eSB0aWRkbGVyIGZpbHRlclxuXHRcdHRoaXMuaW5jb21pbmdVcGRhdGVzRmlsdGVyRm4gPSB0aGlzLndpa2kuY29tcGlsZUZpbHRlcih0aGlzLndpa2kuZ2V0VGlkZGxlclRleHQoSU5DT01JTkdfVVBEQVRFU19GSUxURVJfVElERExFUikpO1xuXHRcdHRoaXMuc2V0VXBkYXRlQ29ubmVjdGlvblN0YXR1cyhTRVJWRVJfTk9UX0NPTk5FQ1RFRCk7XG5cdH1cblxuXHRzZXRVcGRhdGVDb25uZWN0aW9uU3RhdHVzKHN0YXR1czogc3RyaW5nKSB7XG5cdFx0dGhpcy5zZXJ2ZXJVcGRhdGVDb25uZWN0aW9uU3RhdHVzID0gc3RhdHVzO1xuXHRcdHRoaXMud2lraS5hZGRUaWRkbGVyKHtcblx0XHRcdHRpdGxlOiBDT05ORUNUSU9OX1NUQVRFX1RJRERMRVIsXG5cdFx0XHR0ZXh0OiBzdGF0dXNcblx0XHR9KTtcblx0fVxuXHRzZXRMb2dnZXJTYXZlQnVmZmVyKGxvZ2dlckZvclNhdmluZzogTG9nZ2VyKSB7XG5cdFx0dGhpcy5sb2dnZXIuc2V0U2F2ZUJ1ZmZlcihsb2dnZXJGb3JTYXZpbmcpO1xuXHR9XG5cdGlzUmVhZHkoKSB7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblx0Z2V0SG9zdCgpIHtcblx0XHR2YXIgdGV4dCA9IHRoaXMud2lraS5nZXRUaWRkbGVyVGV4dChDT05GSUdfSE9TVF9USURETEVSLCBERUZBVUxUX0hPU1RfVElERExFUiksIHN1YnN0aXR1dGlvbnMgPSBbXG5cdFx0XHR7IG5hbWU6IFwicHJvdG9jb2xcIiwgdmFsdWU6IGRvY3VtZW50LmxvY2F0aW9uLnByb3RvY29sIH0sXG5cdFx0XHR7IG5hbWU6IFwiaG9zdFwiLCB2YWx1ZTogZG9jdW1lbnQubG9jYXRpb24uaG9zdCB9LFxuXHRcdFx0eyBuYW1lOiBcInBhdGhuYW1lXCIsIHZhbHVlOiBkb2N1bWVudC5sb2NhdGlvbi5wYXRobmFtZSB9XG5cdFx0XTtcblx0XHRmb3IgKHZhciB0ID0gMDsgdCA8IHN1YnN0aXR1dGlvbnMubGVuZ3RoOyB0KyspIHtcblx0XHRcdHZhciBzID0gc3Vic3RpdHV0aW9uc1t0XTtcblx0XHRcdHRleHQgPSAkdHcudXRpbHMucmVwbGFjZVN0cmluZyh0ZXh0LCBuZXcgUmVnRXhwKFwiXFxcXCRcIiArIHMubmFtZSArIFwiXFxcXCRcIiwgXCJtZ1wiKSwgcy52YWx1ZSk7XG5cdFx0fVxuXHRcdHJldHVybiB0ZXh0O1xuXHR9XG5cdGdldFRpZGRsZXJJbmZvKHRpZGRsZXI6IFRpZGRsZXIpIHtcblx0XHR2YXIgdGl0bGUgPSB0aWRkbGVyLmZpZWxkcy50aXRsZSwgcmV2aXNpb24gPSB0aGlzLndpa2kuZXh0cmFjdFRpZGRsZXJEYXRhSXRlbShSRVZJU0lPTl9TVEFURV9USURETEVSLCB0aXRsZSksIGJhZyA9IHRoaXMud2lraS5leHRyYWN0VGlkZGxlckRhdGFJdGVtKEJBR19TVEFURV9USURETEVSLCB0aXRsZSk7XG5cdFx0aWYgKHJldmlzaW9uICYmIGJhZykge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0dGl0bGU6IHRpdGxlLFxuXHRcdFx0XHRyZXZpc2lvbjogcmV2aXNpb24sXG5cdFx0XHRcdGJhZzogYmFnXG5cdFx0XHR9O1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHRcdH1cblx0fVxuXHRnZXRUaWRkbGVyQmFnKHRpdGxlOiBzdHJpbmcpIHtcblx0XHRyZXR1cm4gdGhpcy53aWtpLmV4dHJhY3RUaWRkbGVyRGF0YUl0ZW0oQkFHX1NUQVRFX1RJRERMRVIsIHRpdGxlKTtcblx0fVxuXHRnZXRUaWRkbGVyUmV2aXNpb24odGl0bGU6IHN0cmluZykge1xuXHRcdHJldHVybiB0aGlzLndpa2kuZXh0cmFjdFRpZGRsZXJEYXRhSXRlbShSRVZJU0lPTl9TVEFURV9USURETEVSLCB0aXRsZSk7XG5cdH1cblx0c2V0VGlkZGxlckluZm8odGl0bGU6IHN0cmluZywgcmV2aXNpb246IHN0cmluZywgYmFnOiBzdHJpbmcpIHtcblx0XHR0aGlzLndpa2kuc2V0VGV4dChCQUdfU1RBVEVfVElERExFUiwgbnVsbCwgdGl0bGUsIGJhZywgeyBzdXBwcmVzc1RpbWVzdGFtcDogdHJ1ZSB9KTtcblx0XHR0aGlzLndpa2kuc2V0VGV4dChSRVZJU0lPTl9TVEFURV9USURETEVSLCBudWxsLCB0aXRsZSwgcmV2aXNpb24sIHsgc3VwcHJlc3NUaW1lc3RhbXA6IHRydWUgfSk7XG5cdH1cblx0cmVtb3ZlVGlkZGxlckluZm8odGl0bGU6IHN0cmluZykge1xuXHRcdHRoaXMud2lraS5zZXRUZXh0KEJBR19TVEFURV9USURETEVSLCBudWxsLCB0aXRsZSwgdW5kZWZpbmVkLCB7IHN1cHByZXNzVGltZXN0YW1wOiB0cnVlIH0pO1xuXHRcdHRoaXMud2lraS5zZXRUZXh0KFJFVklTSU9OX1NUQVRFX1RJRERMRVIsIG51bGwsIHRpdGxlLCB1bmRlZmluZWQsIHsgc3VwcHJlc3NUaW1lc3RhbXA6IHRydWUgfSk7XG5cdH1cblxuXHRodHRwUmVxdWVzdDxSVCBleHRlbmRzIFwidGV4dFwiIHwgXCJhcnJheWJ1ZmZlclwiIHwgXCJqc29uXCI+KG9wdGlvbnM6IHtcblx0XHQvKiogdXJsIHRvIHJldHJpZXZlIChtdXN0IG5vdCBjb250YWluIGA/YCBpZiBHRVQgb3IgSEVBRCkgKi9cblx0XHR1cmw6IHN0cmluZztcblx0XHQvKiogaGFzaG1hcCBvZiBoZWFkZXJzIHRvIHNlbmQgKi9cblx0XHRoZWFkZXJzPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcblx0XHQvKiogcmVxdWVzdCBtZXRob2Q6IEdFVCwgUFVULCBQT1NUIGV0YyAqL1xuXHRcdHR5cGU/OiBzdHJpbmc7XG5cdFx0LyoqIG9wdGlvbmFsIGZ1bmN0aW9uIGludm9rZWQgd2l0aCAobGVuZ3RoQ29tcHV0YWJsZSxsb2FkZWQsdG90YWwpICovXG5cdFx0cHJvZ3Jlc3M/OiAobGVuZ3RoQ29tcHV0YWJsZTogYm9vbGVhbiwgbG9hZGVkOiBudW1iZXIsIHRvdGFsOiBudW1iZXIpID0+IHZvaWQ7XG5cdFx0LyoqIG5hbWUgb2YgdGhlIHByb3BlcnR5IHRvIHJldHVybiBhcyBmaXJzdCBhcmd1bWVudCBvZiBjYWxsYmFjayAqL1xuXHRcdHJldHVyblByb3A/OiBzdHJpbmc7XG5cdFx0cmVzcG9uc2VUeXBlPzogUlQ7XG5cdFx0dXNlRGVmYXVsdEhlYWRlcnM/OiBib29sZWFuO1xuXHRcdC8qKiB1cmxlbmNvZGVkIHN0cmluZyBvciBoYXNobWFwIG9mIGRhdGEgdG8gc2VuZC4gSWYgdHlwZSBpcyBHRVQgb3IgSEVBRCwgdGhpcyBpcyBhcHBlbmRlZCB0byB0aGUgVVJMIGFzIGEgcXVlcnkgc3RyaW5nICovXG5cdFx0ZGF0YT86IG9iamVjdCB8IHN0cmluZztcblx0fSkge1xuXHRcdHR5cGUgUmVzcG9uc2VFcnIgPSBbZmFsc2UsIGFueSwgdW5kZWZpbmVkXTtcblx0XHR0eXBlIFJlc3BvbnNlT2sgPSBbdHJ1ZSwgdW5kZWZpbmVkLCB7XG5cdFx0XHRkYXRhOlxuXHRcdFx0XCJqc29uXCIgZXh0ZW5kcyBSVCA/IGFueSA6XG5cdFx0XHRcInRleHRcIiBleHRlbmRzIFJUID8gc3RyaW5nIDpcblx0XHRcdFwiYXJyYXlidWZmZXJcIiBleHRlbmRzIFJUID8gQXJyYXlCdWZmZXIgOlxuXHRcdFx0dW5rbm93bjtcblx0XHRcdGhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz5cblx0XHR9XTtcblx0XHRyZXR1cm4gKG5ldyBQcm9taXNlPFJlc3BvbnNlRXJyIHwgUmVzcG9uc2VPaz4oKHJlc29sdmUpID0+IHtcblx0XHRcdCR0dy51dGlscy5odHRwUmVxdWVzdCh7XG5cdFx0XHRcdC4uLm9wdGlvbnMsXG5cdFx0XHRcdHJlc3BvbnNlVHlwZTogb3B0aW9ucy5yZXNwb25zZVR5cGUgPT09IFwianNvblwiID8gXCJ0ZXh0XCIgOiBvcHRpb25zLnJlc3BvbnNlVHlwZSxcblx0XHRcdFx0Y2FsbGJhY2s6IChlcnI6IGFueSwgZGF0YTogYW55LCByZXF1ZXN0OiBYTUxIdHRwUmVxdWVzdCkgPT4ge1xuXHRcdFx0XHRcdGlmIChlcnIpIHJldHVybiByZXNvbHZlKFtmYWxzZSwgZXJyIHx8IG5ldyBFcnJvcihcIlVua25vd24gZXJyb3JcIiksIHVuZGVmaW5lZF0pO1xuXG5cdFx0XHRcdFx0Ly8gQ3JlYXRlIGEgbWFwIG9mIGhlYWRlciBuYW1lcyB0byB2YWx1ZXNcblxuXHRcdFx0XHRcdGNvbnN0IGhlYWRlcnMgPSB7fSBhcyBhbnk7XG5cdFx0XHRcdFx0cmVxdWVzdC5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKT8udHJpbSgpLnNwbGl0KC9bXFxyXFxuXSsvKS5mb3JFYWNoKChsaW5lKSA9PiB7XG5cdFx0XHRcdFx0XHRjb25zdCBwYXJ0cyA9IGxpbmUuc3BsaXQoXCI6IFwiKTtcblx0XHRcdFx0XHRcdGNvbnN0IGhlYWRlciA9IHBhcnRzLnNoaWZ0KCk/LnRvTG93ZXJDYXNlKCk7XG5cdFx0XHRcdFx0XHRjb25zdCB2YWx1ZSA9IHBhcnRzLmpvaW4oXCI6IFwiKTtcblx0XHRcdFx0XHRcdGlmIChoZWFkZXIpIGhlYWRlcnNbaGVhZGVyXSA9IHZhbHVlO1xuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdC8vIFJlc29sdmUgdGhlIHByb21pc2Ugd2l0aCB0aGUgcmVzcG9uc2UgZGF0YSBhbmQgaGVhZGVyc1xuXHRcdFx0XHRcdHJlc29sdmUoW3RydWUsIHVuZGVmaW5lZCwge1xuXHRcdFx0XHRcdFx0aGVhZGVycyxcblx0XHRcdFx0XHRcdGRhdGE6IG9wdGlvbnMucmVzcG9uc2VUeXBlID09PSBcImpzb25cIiA/ICR0dy51dGlscy5wYXJzZUpTT05TYWZlKGRhdGEsICgpID0+IHVuZGVmaW5lZCkgOiBkYXRhLFxuXHRcdFx0XHRcdH1dKTtcblx0XHRcdFx0fSxcblx0XHRcdH0pO1xuXHRcdH0pKTtcblx0fVxuXHQvKlxuXHRHZXQgdGhlIGN1cnJlbnQgc3RhdHVzIG9mIHRoZSBzZXJ2ZXIgY29ubmVjdGlvblxuXHQqL1xuXHRhc3luYyBnZXRTdGF0dXMoY2FsbGJhY2s6IChcblx0XHRlcnI6IGFueSxcblx0XHRpc0xvZ2dlZEluPzogYm9vbGVhbixcblx0XHR1c2VybmFtZT86IHN0cmluZyxcblx0XHRpc1JlYWRPbmx5PzogYm9vbGVhbixcblx0XHRpc0Fub255bW91cz86IGJvb2xlYW4sXG5cdCkgPT4gdm9pZCkge1xuXHRcdGludGVyZmFjZSBVc2VyQXV0aFN0YXR1cyB7XG5cdFx0XHRpc0FkbWluOiBib29sZWFuO1xuXHRcdFx0dXNlcl9pZDogbnVtYmVyO1xuXHRcdFx0dXNlcm5hbWU6IHN0cmluZztcblx0XHRcdGlzTG9nZ2VkSW46IGJvb2xlYW47XG5cdFx0XHRpc1JlYWRPbmx5OiBib29sZWFuO1xuXHRcdFx0YWxsb3dBbm9uUmVhZHM6IGJvb2xlYW47XG5cdFx0XHRhbGxvd0Fub25Xcml0ZXM6IGJvb2xlYW47XG5cdFx0fVxuXG5cdFx0Y29uc3QgW29rLCBlcnJvciwgZGF0YV0gPSBhd2FpdCB0aGlzLmh0dHBSZXF1ZXN0KHtcblx0XHRcdHVybDogdGhpcy5ob3N0ICsgXCJyZWNpcGVzL1wiICsgdGhpcy5yZWNpcGUgKyBcIi9zdGF0dXNcIixcblx0XHRcdHR5cGU6IFwiR0VUXCIsXG5cdFx0XHRyZXNwb25zZVR5cGU6IFwianNvblwiLFxuXHRcdFx0aGVhZGVyczoge1xuXHRcdFx0XHQnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuXHRcdFx0XHRcIlgtUmVxdWVzdGVkLVdpdGhcIjogXCJUaWRkbHlXaWtpXCJcblx0XHRcdH0sXG5cdFx0fSk7XG5cdFx0aWYgKCFvaykge1xuXHRcdFx0dGhpcy5sb2dnZXIubG9nKFwiRXJyb3IgZ2V0dGluZyBzdGF0dXNcIiwgZXJyb3IpO1xuXHRcdFx0aWYgKGNhbGxiYWNrKSBjYWxsYmFjayhlcnJvcik7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdC8qKiBAdHlwZSB7UGFydGlhbDxVc2VyQXV0aFN0YXR1cz59ICovXG5cdFx0Y29uc3Qgc3RhdHVzID0gZGF0YS5kYXRhO1xuXHRcdGlmIChjYWxsYmFjaykge1xuXHRcdFx0Y2FsbGJhY2soXG5cdFx0XHRcdC8vIEVycm9yXG5cdFx0XHRcdG51bGwsXG5cdFx0XHRcdC8vIElzIGxvZ2dlZCBpblxuXHRcdFx0XHRzdGF0dXMuaXNMb2dnZWRJbiA/PyBmYWxzZSxcblx0XHRcdFx0Ly8gVXNlcm5hbWVcblx0XHRcdFx0c3RhdHVzLnVzZXJuYW1lID8/IFwiKGFub24pXCIsXG5cdFx0XHRcdC8vIElzIHJlYWQgb25seVxuXHRcdFx0XHRzdGF0dXMuaXNSZWFkT25seSA/PyB0cnVlLFxuXHRcdFx0XHQvLyBJcyBhbm9ueW1vdXNcblx0XHRcdFx0IXN0YXR1cy5pc0xvZ2dlZEluLFxuXHRcdFx0KTtcblx0XHR9XG5cdH1cblx0Lypcblx0R2V0IGRldGFpbHMgb2YgY2hhbmdlZCB0aWRkbGVycyBmcm9tIHRoZSBzZXJ2ZXJcblx0Ki9cblx0Z2V0VXBkYXRlZFRpZGRsZXJzKHN5bmNlcjogU3luY2VyLCBjYWxsYmFjazogKGVycjogYW55LCBjaGFuZ2VzPzogeyBtb2RpZmljYXRpb25zOiBzdHJpbmdbXTsgZGVsZXRpb25zOiBzdHJpbmdbXSB9KSA9PiB2b2lkKSB7XG5cdFx0aWYgKCF0aGlzLnVzZVNlcnZlclNlbnRFdmVudHMpIHtcblx0XHRcdHRoaXMucG9sbFNlcnZlcih7XG5cdFx0XHRcdGNhbGxiYWNrOiBmdW5jdGlvbiAoZXJyLCBjaGFuZ2VzKSB7XG5cdFx0XHRcdFx0Y2FsbGJhY2sobnVsbCwgY2hhbmdlcyk7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHZhciBzZWxmID0gdGhpcztcblx0XHQvLyBEbyBub3RoaW5nIGlmIHRoZXJlJ3MgYWxyZWFkeSBhIGNvbm5lY3Rpb24gaW4gcHJvZ3Jlc3MuXG5cdFx0aWYgKHRoaXMuc2VydmVyVXBkYXRlQ29ubmVjdGlvblN0YXR1cyAhPT0gU0VSVkVSX05PVF9DT05ORUNURUQpIHtcblx0XHRcdHJldHVybiBjYWxsYmFjayhudWxsLCB7XG5cdFx0XHRcdG1vZGlmaWNhdGlvbnM6IFtdLFxuXHRcdFx0XHRkZWxldGlvbnM6IFtdXG5cdFx0XHR9KTtcblx0XHR9XG5cdFx0Ly8gVHJ5IHRvIGNvbm5lY3QgYSBzZXJ2ZXIgc3RyZWFtXG5cdFx0dGhpcy5zZXRVcGRhdGVDb25uZWN0aW9uU3RhdHVzKFNFUlZFUl9DT05ORUNUSU5HX1NTRSk7XG5cdFx0dGhpcy5jb25uZWN0U2VydmVyU3RyZWFtKHtcblx0XHRcdHN5bmNlcjogc3luY2VyLFxuXHRcdFx0b25lcnJvcjogZnVuY3Rpb24gKGVycikge1xuXHRcdFx0XHRzZWxmLmxvZ2dlci5sb2coXCJFcnJvciBjb25uZWN0aW5nIFNTRSBzdHJlYW1cIiwgZXJyKTtcblx0XHRcdFx0Ly8gSWYgdGhlIHN0cmVhbSBkaWRuJ3Qgd29yaywgdHJ5IHBvbGxpbmdcblx0XHRcdFx0c2VsZi5zZXRVcGRhdGVDb25uZWN0aW9uU3RhdHVzKFNFUlZFUl9QT0xMSU5HKTtcblx0XHRcdFx0c2VsZi5wb2xsU2VydmVyKHtcblx0XHRcdFx0XHRjYWxsYmFjazogZnVuY3Rpb24gKGVyciwgY2hhbmdlcykge1xuXHRcdFx0XHRcdFx0c2VsZi5zZXRVcGRhdGVDb25uZWN0aW9uU3RhdHVzKFNFUlZFUl9OT1RfQ09OTkVDVEVEKTtcblx0XHRcdFx0XHRcdGNhbGxiYWNrKG51bGwsIGNoYW5nZXMpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cdFx0XHR9LFxuXHRcdFx0b25vcGVuOiBmdW5jdGlvbiAoKSB7XG5cdFx0XHRcdHNlbGYuc2V0VXBkYXRlQ29ubmVjdGlvblN0YXR1cyhTRVJWRVJfQ09OTkVDVEVEX1NTRSk7XG5cdFx0XHRcdC8vIFRoZSBzeW5jZXIgaXMgZXhwZWN0aW5nIGEgY2FsbGJhY2sgYnV0IHdlIGRvbid0IGhhdmUgYW55IGRhdGEgdG8gc2VuZFxuXHRcdFx0XHRjYWxsYmFjayhudWxsLCB7XG5cdFx0XHRcdFx0bW9kaWZpY2F0aW9uczogW10sXG5cdFx0XHRcdFx0ZGVsZXRpb25zOiBbXVxuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHR9KTtcblxuXHR9XG5cdC8qXG5cdEF0dGVtcHQgdG8gZXN0YWJsaXNoIGFuIFNTRSBzdHJlYW0gd2l0aCB0aGUgc2VydmVyIGFuZCB0cmFuc2ZlciB0aWRkbGVyIGNoYW5nZXMuIE9wdGlvbnMgaW5jbHVkZTpcbiAgXG5cdHN5bmNlcjogcmVmZXJlbmNlIHRvIHN5bmNlciBvYmplY3QgdXNlZCBmb3Igc3RvcmluZyBkYXRhXG5cdG9ub3BlbjogaW52b2tlZCB3aGVuIHRoZSBzdHJlYW0gaXMgc3VjY2Vzc2Z1bGx5IG9wZW5lZFxuXHRvbmVycm9yOiBpbnZva2VkIGlmIHRoZXJlIGlzIGFuIGVycm9yXG5cdCovXG5cdGNvbm5lY3RTZXJ2ZXJTdHJlYW0ob3B0aW9uczoge1xuXHRcdHN5bmNlcjogU3luY2VyO1xuXHRcdG9ub3BlbjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZDtcblx0XHRvbmVycm9yOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkO1xuXHR9KSB7XG5cdFx0dmFyIHNlbGYgPSB0aGlzO1xuXHRcdGNvbnN0IGV2ZW50U291cmNlID0gbmV3IEV2ZW50U291cmNlKFwiL3JlY2lwZXMvXCIgKyB0aGlzLnJlY2lwZSArIFwiL2V2ZW50cz9sYXN0X2tub3duX3RpZGRsZXJfaWQ9XCIgKyB0aGlzLmxhc3Rfa25vd25fdGlkZGxlcl9pZCk7XG5cdFx0ZXZlbnRTb3VyY2Uub25lcnJvciA9IGZ1bmN0aW9uIChldmVudCkge1xuXHRcdFx0aWYgKG9wdGlvbnMub25lcnJvcikge1xuXHRcdFx0XHRvcHRpb25zLm9uZXJyb3IoZXZlbnQpO1xuXHRcdFx0fVxuXHRcdH07XG5cdFx0ZXZlbnRTb3VyY2Uub25vcGVuID0gZnVuY3Rpb24gKGV2ZW50KSB7XG5cdFx0XHRpZiAob3B0aW9ucy5vbm9wZW4pIHtcblx0XHRcdFx0b3B0aW9ucy5vbm9wZW4oZXZlbnQpO1xuXHRcdFx0fVxuXHRcdH07XG5cdFx0ZXZlbnRTb3VyY2UuYWRkRXZlbnRMaXN0ZW5lcihcImNoYW5nZVwiLCBmdW5jdGlvbiAoZXZlbnQpIHtcblxuXHRcdFx0Y29uc3QgZGF0YToge1xuXHRcdFx0XHR0aXRsZTogc3RyaW5nO1xuXHRcdFx0XHR0aWRkbGVyX2lkOiBudW1iZXI7XG5cdFx0XHRcdGlzX2RlbGV0ZWQ6IGJvb2xlYW47XG5cdFx0XHRcdGJhZ19uYW1lOiBzdHJpbmc7XG5cdFx0XHRcdHRpZGRsZXI6IGFueTtcblx0XHRcdH0gPSAkdHcudXRpbHMucGFyc2VKU09OU2FmZShldmVudC5kYXRhKTtcblx0XHRcdGlmICghZGF0YSkgcmV0dXJuO1xuXG5cdFx0XHRjb25zb2xlLmxvZyhcIlNTRSBkYXRhXCIsIGRhdGEpO1xuXHRcdFx0Ly8gVXBkYXRlIGxhc3Qgc2VlbiB0aWRkbGVyX2lkXG5cdFx0XHRpZiAoZGF0YS50aWRkbGVyX2lkID4gc2VsZi5sYXN0X2tub3duX3RpZGRsZXJfaWQpIHtcblx0XHRcdFx0c2VsZi5sYXN0X2tub3duX3RpZGRsZXJfaWQgPSBkYXRhLnRpZGRsZXJfaWQ7XG5cdFx0XHR9XG5cdFx0XHQvLyBSZWNvcmQgdGhlIGxhc3QgdXBkYXRlIHRvIHRoaXMgdGlkZGxlclxuXHRcdFx0c2VsZi5sYXN0UmVjb3JkZWRVcGRhdGVbZGF0YS50aXRsZV0gPSB7XG5cdFx0XHRcdHR5cGU6IGRhdGEuaXNfZGVsZXRlZCA/IFwiZGVsZXRpb25cIiA6IFwidXBkYXRlXCIsXG5cdFx0XHRcdHRpZGRsZXJfaWQ6IGRhdGEudGlkZGxlcl9pZFxuXHRcdFx0fTtcblx0XHRcdGNvbnNvbGUubG9nKGBPdXN0YW5kaW5nIHJlcXVlc3RzIGlzICR7SlNPTi5zdHJpbmdpZnkoc2VsZi5vdXRzdGFuZGluZ1JlcXVlc3RzW2RhdGEudGl0bGVdKX1gKTtcblx0XHRcdC8vIFByb2Nlc3MgdGhlIHVwZGF0ZSBpZiB0aGUgdGlkZGxlciBpcyBub3QgdGhlIHN1YmplY3Qgb2YgYW4gb3V0c3RhbmRpbmcgcmVxdWVzdFxuXHRcdFx0aWYgKHNlbGYub3V0c3RhbmRpbmdSZXF1ZXN0c1tkYXRhLnRpdGxlXSkgcmV0dXJuO1xuXHRcdFx0aWYgKGRhdGEuaXNfZGVsZXRlZCkge1xuXHRcdFx0XHRzZWxmLnJlbW92ZVRpZGRsZXJJbmZvKGRhdGEudGl0bGUpO1xuXHRcdFx0XHRkZWxldGUgb3B0aW9ucy5zeW5jZXIudGlkZGxlckluZm9bZGF0YS50aXRsZV07XG5cdFx0XHRcdG9wdGlvbnMuc3luY2VyLmxvZ2dlci5sb2coXCJEZWxldGluZyB0aWRkbGVyIG1pc3NpbmcgZnJvbSBzZXJ2ZXI6XCIsIGRhdGEudGl0bGUpO1xuXHRcdFx0XHRvcHRpb25zLnN5bmNlci53aWtpLmRlbGV0ZVRpZGRsZXIoZGF0YS50aXRsZSk7XG5cdFx0XHRcdG9wdGlvbnMuc3luY2VyLnByb2Nlc3NUYXNrUXVldWUoKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHZhciByZXN1bHQgPSBzZWxmLmluY29taW5nVXBkYXRlc0ZpbHRlckZuLmNhbGwoc2VsZi53aWtpLCBzZWxmLndpa2kubWFrZVRpZGRsZXJJdGVyYXRvcihbZGF0YS50aXRsZV0pKTtcblx0XHRcdFx0aWYgKHJlc3VsdC5sZW5ndGggPiAwKSB7XG5cdFx0XHRcdFx0c2VsZi5zZXRUaWRkbGVySW5mbyhkYXRhLnRpdGxlLCBkYXRhLnRpZGRsZXJfaWQudG9TdHJpbmcoKSwgZGF0YS5iYWdfbmFtZSk7XG5cdFx0XHRcdFx0b3B0aW9ucy5zeW5jZXIuc3RvcmVUaWRkbGVyKGRhdGEudGlkZGxlcik7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXG5cdFx0fSk7XG5cdH1cblx0Lypcblx0UG9sbCB0aGUgc2VydmVyIGZvciBjaGFuZ2VzLiBPcHRpb25zIGluY2x1ZGU6XG4gIFxuXHRjYWxsYmFjazogaW52b2tlZCBvbiBjb21wbGV0aW9uIGFzIChlcnIsY2hhbmdlcylcblx0Ki9cblx0YXN5bmMgcG9sbFNlcnZlcihvcHRpb25zOiB7XG5cdFx0Y2FsbGJhY2s6IChlcnI6IGFueSwgY2hhbmdlcz86IHsgbW9kaWZpY2F0aW9uczogc3RyaW5nW107IGRlbGV0aW9uczogc3RyaW5nW10gfSkgPT4gdm9pZDtcblx0fSkge1xuXHRcdHZhciBzZWxmID0gdGhpcztcblx0XHRjb25zdCBbb2ssIGVyciwgcmVzdWx0XSA9IGF3YWl0IHRoaXMuaHR0cFJlcXVlc3Qoe1xuXHRcdFx0dXJsOiB0aGlzLmhvc3QgKyBcInJlY2lwZXMvXCIgKyB0aGlzLnJlY2lwZSArIFwiL3RpZGRsZXJzLmpzb25cIixcblx0XHRcdGRhdGE6IHtcblx0XHRcdFx0bGFzdF9rbm93bl90aWRkbGVyX2lkOiB0aGlzLmxhc3Rfa25vd25fdGlkZGxlcl9pZCxcblx0XHRcdFx0aW5jbHVkZV9kZWxldGVkOiBcInRydWVcIlxuXHRcdFx0fSxcblx0XHRcdHJlc3BvbnNlVHlwZTogXCJqc29uXCIsXG5cdFx0fSk7XG5cblx0XHRpZiAoIW9rKSB7IHJldHVybiBvcHRpb25zLmNhbGxiYWNrKGVycik7IH1cblx0XHRjb25zdCB7IGRhdGE6IHRpZGRsZXJJbmZvQXJyYXkgPSBbXSB9ID0gcmVzdWx0O1xuXG5cdFx0dmFyIG1vZGlmaWNhdGlvbnM6IHN0cmluZ1tdID0gW10sIGRlbGV0aW9uczogc3RyaW5nW10gPSBbXTtcblxuXHRcdCR0dy51dGlscy5lYWNoKHRpZGRsZXJJbmZvQXJyYXksXG5cdFx0XHQvKipcblx0XHRcdCAqIEBwYXJhbSB7eyB0aXRsZTogc3RyaW5nOyB0aWRkbGVyX2lkOiBudW1iZXI7IGlzX2RlbGV0ZWQ6IGJvb2xlYW47IGJhZ19uYW1lOiBzdHJpbmc7IH19IHRpZGRsZXJJbmZvIFxuXHRcdFx0ICovXG5cdFx0XHRmdW5jdGlvbiAodGlkZGxlckluZm8pIHtcblx0XHRcdFx0aWYgKHRpZGRsZXJJbmZvLnRpZGRsZXJfaWQgPiBzZWxmLmxhc3Rfa25vd25fdGlkZGxlcl9pZCkge1xuXHRcdFx0XHRcdHNlbGYubGFzdF9rbm93bl90aWRkbGVyX2lkID0gdGlkZGxlckluZm8udGlkZGxlcl9pZDtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAodGlkZGxlckluZm8uaXNfZGVsZXRlZCkge1xuXHRcdFx0XHRcdGRlbGV0aW9ucy5wdXNoKHRpZGRsZXJJbmZvLnRpdGxlKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRtb2RpZmljYXRpb25zLnB1c2godGlkZGxlckluZm8udGl0bGUpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0KTtcblxuXHRcdC8vIEludm9rZSB0aGUgY2FsbGJhY2sgd2l0aCB0aGUgcmVzdWx0c1xuXHRcdG9wdGlvbnMuY2FsbGJhY2sobnVsbCwge1xuXHRcdFx0bW9kaWZpY2F0aW9uczogbW9kaWZpY2F0aW9ucyxcblx0XHRcdGRlbGV0aW9uczogZGVsZXRpb25zXG5cdFx0fSk7XG5cblx0XHRzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdC8vIElmIEJyb3dzd2VyIFN0b3JhZ2UgdGlkZGxlcnMgd2VyZSBjYWNoZWQgb24gcmVsb2FkaW5nIHRoZSB3aWtpLCBhZGQgdGhlbSBhZnRlciBzeW5jIGZyb20gc2VydmVyIGNvbXBsZXRlcyBpbiB0aGUgYWJvdmUgY2FsbGJhY2suXG5cdFx0XHRpZiAoJHR3LmJyb3dzZXJTdG9yYWdlICYmICR0dy5icm93c2VyU3RvcmFnZS5pc0VuYWJsZWQoKSkge1xuXHRcdFx0XHQkdHcuYnJvd3NlclN0b3JhZ2UuYWRkQ2FjaGVkVGlkZGxlcnMoKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fVxuXHQvKlxuXHRRdWV1ZSBhIGxvYWQgZm9yIGEgdGlkZGxlciBpZiB0aGVyZSBoYXMgYmVlbiBhbiB1cGRhdGUgZm9yIGl0IHNpbmNlIHRoZSBzcGVjaWZpZWQgcmV2aXNpb25cblx0Ki9cblx0Y2hlY2tMYXN0UmVjb3JkZWRVcGRhdGUodGl0bGU6IHN0cmluZywgcmV2aXNpb246IHN0cmluZykge1xuXHRcdHZhciBscnUgPSB0aGlzLmxhc3RSZWNvcmRlZFVwZGF0ZVt0aXRsZV07XG5cdFx0aWYgKGxydSkge1xuXHRcdFx0dmFyIG51bVJldmlzaW9uID0gJHR3LnV0aWxzLmdldEludChyZXZpc2lvbiwgMCk7XG5cdFx0XHRpZiAoIW51bVJldmlzaW9uKSB7XG5cdFx0XHRcdHRoaXMubG9nZ2VyLmxvZyhcIkVycm9yOiByZXZpc2lvbiBpcyBub3QgYSBudW1iZXJcIiwgcmV2aXNpb24pO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cdFx0XHRjb25zb2xlLmxvZyhgQ2hlY2tpbmcgZm9yIHVwZGF0ZXMgdG8gJHt0aXRsZX0gc2luY2UgJHtKU09OLnN0cmluZ2lmeShyZXZpc2lvbil9IGNvbXBhcmluZyB0byAke251bVJldmlzaW9ufWApO1xuXHRcdFx0aWYgKGxydS50aWRkbGVyX2lkID4gbnVtUmV2aXNpb24pIHtcblx0XHRcdFx0dGhpcy5zeW5jZXIgJiYgdGhpcy5zeW5jZXIuZW5xdWV1ZUxvYWRUaWRkbGVyKHRpdGxlKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblx0Z2V0IHN5bmNlcigpIHtcblx0XHQvL0B0cy1leHBlY3QtZXJyb3Jcblx0XHRpZiAoJHR3LnN5bmNhZGFwdG9yID09PSB0aGlzKSByZXR1cm4gJHR3LnN5bmNlcjtcblx0fVxuXHQvKlxuXHRTYXZlIGEgdGlkZGxlciBhbmQgaW52b2tlIHRoZSBjYWxsYmFjayB3aXRoIChlcnIsYWRhcHRvckluZm8scmV2aXNpb24pXG5cdCovXG5cdGFzeW5jIHNhdmVUaWRkbGVyKFxuXHRcdHRpZGRsZXI6IFRpZGRsZXIsXG5cdFx0Y2FsbGJhY2s6IChlcnI6IGFueSwgYWRhcHRvckluZm8/OiB7IGJhZzogc3RyaW5nIH0sIHJldmlzaW9uPzogc3RyaW5nKSA9PiB2b2lkLFxuXHRcdG9wdGlvbnM/OiB7fVxuXHQpIHtcblx0XHR2YXIgc2VsZiA9IHRoaXMsIHRpdGxlID0gdGlkZGxlci5maWVsZHMudGl0bGU7XG5cdFx0aWYgKHRoaXMuaXNSZWFkT25seSB8fCB0aXRsZS5zdWJzdHIoMCwgTVdDX1NUQVRFX1RJRERMRVJfUFJFRklYLmxlbmd0aCkgPT09IE1XQ19TVEFURV9USURETEVSX1BSRUZJWCkge1xuXHRcdFx0cmV0dXJuIGNhbGxiYWNrKG51bGwpO1xuXHRcdH1cblx0XHRzZWxmLm91dHN0YW5kaW5nUmVxdWVzdHNbdGl0bGVdID0geyB0eXBlOiBcIlBVVFwiIH07XG5cdFx0Ly8gVE9ETzogbm90IHVzaW5nIGdldEZpZWxkU3RyaW5nQmxvY2sgYmVjYXVzZSB3aGF0IGhhcHBlbnMgaWYgYSBmaWVsZCBuYW1lIGhhcyBhIGNvbG9uIGluIGl0P1xuXHRcdGxldCBib2R5ID0gSlNPTi5zdHJpbmdpZnkodGlkZGxlci5nZXRGaWVsZFN0cmluZ3MoeyBleGNsdWRlOiBbXCJ0ZXh0XCJdIH0pKTtcblx0XHRpZiAodGlkZGxlci5oYXNGaWVsZChcInRleHRcIikpIHtcblx0XHRcdGlmICh0eXBlb2YgdGlkZGxlci5maWVsZHMudGV4dCAhPT0gXCJzdHJpbmdcIiAmJiB0aWRkbGVyLmZpZWxkcy50ZXh0KVxuXHRcdFx0XHRyZXR1cm4gY2FsbGJhY2sobmV3IEVycm9yKFwiRXJyb3Igc2F2aW5nIHRpZGRsZXIgXCIgKyB0aWRkbGVyLmZpZWxkcy50aXRsZSArIFwiOiB0aGUgdGV4dCBmaWVsZCBpcyB0cnV0aHkgYnV0IG5vdCBhIHN0cmluZ1wiKSk7XG5cdFx0XHRib2R5ICs9IGBcXG5cXG4ke3RpZGRsZXIuZmllbGRzLnRleHR9YFxuXHRcdH1cblxuXHRcdGNvbnN0IFtvaywgZXJyLCByZXN1bHRdID0gYXdhaXQgdGhpcy5odHRwUmVxdWVzdCh7XG5cdFx0XHR1cmw6IHRoaXMuaG9zdCArIFwicmVjaXBlcy9cIiArIGVuY29kZVVSSUNvbXBvbmVudCh0aGlzLnJlY2lwZSkgKyBcIi90aWRkbGVycy9cIiArIGVuY29kZVVSSUNvbXBvbmVudCh0aXRsZSksXG5cdFx0XHR0eXBlOiBcIlBVVFwiLFxuXHRcdFx0aGVhZGVyczoge1xuXHRcdFx0XHRcIkNvbnRlbnQtdHlwZVwiOiBcImFwcGxpY2F0aW9uL3gtbXdzLXRpZGRsZXJcIlxuXHRcdFx0fSxcblx0XHRcdGRhdGE6IGJvZHksXG5cdFx0XHRyZXNwb25zZVR5cGU6IFwianNvblwiLFxuXHRcdH0pO1xuXHRcdGRlbGV0ZSBzZWxmLm91dHN0YW5kaW5nUmVxdWVzdHNbdGl0bGVdO1xuXHRcdGlmICghb2spIHJldHVybiBjYWxsYmFjayhlcnIpO1xuXHRcdGNvbnN0IHsgaGVhZGVycywgZGF0YSB9ID0gcmVzdWx0O1xuXG5cdFx0Ly9JZiBCcm93c2VyLVN0b3JhZ2UgcGx1Z2luIGlzIHByZXNlbnQsIHJlbW92ZSB0aWRkbGVyIGZyb20gbG9jYWwgc3RvcmFnZSBhZnRlciBzdWNjZXNzZnVsIHN5bmMgdG8gdGhlIHNlcnZlclxuXHRcdGlmICgkdHcuYnJvd3NlclN0b3JhZ2UgJiYgJHR3LmJyb3dzZXJTdG9yYWdlLmlzRW5hYmxlZCgpKSB7XG5cdFx0XHQkdHcuYnJvd3NlclN0b3JhZ2UucmVtb3ZlVGlkZGxlckZyb21Mb2NhbFN0b3JhZ2UodGl0bGUpO1xuXHRcdH1cblxuXHRcdC8vIFNhdmUgdGhlIGRldGFpbHMgb2YgdGhlIG5ldyByZXZpc2lvbiBvZiB0aGUgdGlkZGxlclxuXHRcdGNvbnN0IHJldmlzaW9uID0gZGF0YS50aWRkbGVyX2lkLCBiYWdfbmFtZSA9IGRhdGEuYmFnX25hbWU7XG5cdFx0Y29uc29sZS5sb2coYFNhdmVkICR7dGl0bGV9IHdpdGggcmV2aXNpb24gJHtyZXZpc2lvbn0gYW5kIGJhZyAke2JhZ19uYW1lfWApO1xuXHRcdC8vIElmIHRoZXJlIGhhcyBiZWVuIGEgbW9yZSByZWNlbnQgdXBkYXRlIGZyb20gdGhlIHNlcnZlciB0aGVuIGVucXVldWUgYSBsb2FkIG9mIHRoaXMgdGlkZGxlclxuXHRcdHNlbGYuY2hlY2tMYXN0UmVjb3JkZWRVcGRhdGUodGl0bGUsIHJldmlzaW9uKTtcblx0XHQvLyBJbnZva2UgdGhlIGNhbGxiYWNrXG5cdFx0c2VsZi5zZXRUaWRkbGVySW5mbyh0aXRsZSwgcmV2aXNpb24sIGJhZ19uYW1lKTtcblx0XHRjYWxsYmFjayhudWxsLCB7IGJhZzogYmFnX25hbWUgfSwgcmV2aXNpb24pO1xuXG5cdH1cblx0Lypcblx0TG9hZCBhIHRpZGRsZXIgYW5kIGludm9rZSB0aGUgY2FsbGJhY2sgd2l0aCAoZXJyLHRpZGRsZXJGaWVsZHMpXG5cblx0VGhlIHN5bmNlciBkb2VzIG5vdCBwYXNzIGl0c2VsZiBpbnRvIG9wdGlvbnMuXG5cdCovXG5cdGFzeW5jIGxvYWRUaWRkbGVyKHRpdGxlOiBzdHJpbmcsIGNhbGxiYWNrOiAoZXJyOiBhbnksIGZpZWxkcz86IGFueSkgPT4gdm9pZCwgb3B0aW9uczogYW55KSB7XG5cdFx0dmFyIHNlbGYgPSB0aGlzO1xuXHRcdHNlbGYub3V0c3RhbmRpbmdSZXF1ZXN0c1t0aXRsZV0gPSB7IHR5cGU6IFwiR0VUXCIgfTtcblx0XHRjb25zdCBbb2ssIGVyciwgcmVzdWx0XSA9IGF3YWl0IHRoaXMuaHR0cFJlcXVlc3Qoe1xuXHRcdFx0dXJsOiB0aGlzLmhvc3QgKyBcInJlY2lwZXMvXCIgKyBlbmNvZGVVUklDb21wb25lbnQodGhpcy5yZWNpcGUpICsgXCIvdGlkZGxlcnMvXCIgKyBlbmNvZGVVUklDb21wb25lbnQodGl0bGUpLFxuXHRcdH0pO1xuXHRcdGRlbGV0ZSBzZWxmLm91dHN0YW5kaW5nUmVxdWVzdHNbdGl0bGVdO1xuXHRcdGlmIChlcnIgPT09IDQwNCkge1xuXHRcdFx0cmV0dXJuIGNhbGxiYWNrKG51bGwsIG51bGwpO1xuXHRcdH0gZWxzZSBpZiAoIW9rKSB7XG5cdFx0XHRyZXR1cm4gY2FsbGJhY2soZXJyKTtcblx0XHR9XG5cdFx0Y29uc3QgeyBkYXRhLCBoZWFkZXJzIH0gPSByZXN1bHQ7XG5cdFx0Y29uc3QgcmV2aXNpb24gPSBoZWFkZXJzW1wieC1yZXZpc2lvbi1udW1iZXJcIl0sIGJhZ19uYW1lID0gaGVhZGVyc1tcIngtYmFnLW5hbWVcIl07XG5cdFx0Ly8gSWYgdGhlcmUgaGFzIGJlZW4gYSBtb3JlIHJlY2VudCB1cGRhdGUgZnJvbSB0aGUgc2VydmVyIHRoZW4gZW5xdWV1ZSBhIGxvYWQgb2YgdGhpcyB0aWRkbGVyXG5cdFx0c2VsZi5jaGVja0xhc3RSZWNvcmRlZFVwZGF0ZSh0aXRsZSwgcmV2aXNpb24pO1xuXHRcdC8vIEludm9rZSB0aGUgY2FsbGJhY2tcblx0XHRzZWxmLnNldFRpZGRsZXJJbmZvKHRpdGxlLCByZXZpc2lvbiwgYmFnX25hbWUpO1xuXHRcdGNhbGxiYWNrKG51bGwsICR0dy51dGlscy5wYXJzZUpTT05TYWZlKGRhdGEpKTtcblx0fVxuXHQvKlxuXHREZWxldGUgYSB0aWRkbGVyIGFuZCBpbnZva2UgdGhlIGNhbGxiYWNrIHdpdGggKGVycilcblx0b3B0aW9ucyBpbmNsdWRlOlxuXHR0aWRkbGVySW5mbzogdGhlIHN5bmNlcidzIHRpZGRsZXJJbmZvIGZvciB0aGlzIHRpZGRsZXJcblx0Ki9cblx0YXN5bmMgZGVsZXRlVGlkZGxlcih0aXRsZTogc3RyaW5nLCBjYWxsYmFjazogKGVycjogYW55LCBhZGFwdG9ySW5mbz86IGFueSkgPT4gdm9pZCwgb3B0aW9uczogYW55KSB7XG5cdFx0dmFyIHNlbGYgPSB0aGlzO1xuXHRcdGlmICh0aGlzLmlzUmVhZE9ubHkpIHsgcmV0dXJuIGNhbGxiYWNrKG51bGwpOyB9XG5cdFx0Ly8gSWYgd2UgZG9uJ3QgaGF2ZSBhIGJhZyBpdCBtZWFucyB0aGF0IHRoZSB0aWRkbGVyIGhhc24ndCBiZWVuIHNlZW4gYnkgdGhlIHNlcnZlciwgc28gd2UgZG9uJ3QgbmVlZCB0byBkZWxldGUgaXRcblx0XHQvLyB2YXIgYmFnID0gdGhpcy5nZXRUaWRkbGVyQmFnKHRpdGxlKTtcblx0XHQvLyBpZighYmFnKSB7IHJldHVybiBjYWxsYmFjayhudWxsLCBvcHRpb25zLnRpZGRsZXJJbmZvLmFkYXB0b3JJbmZvKTsgfVxuXHRcdHNlbGYub3V0c3RhbmRpbmdSZXF1ZXN0c1t0aXRsZV0gPSB7IHR5cGU6IFwiREVMRVRFXCIgfTtcblx0XHQvLyBJc3N1ZSBIVFRQIHJlcXVlc3QgdG8gZGVsZXRlIHRoZSB0aWRkbGVyXG5cdFx0Y29uc3QgW29rLCBlcnIsIHJlc3VsdF0gPSBhd2FpdCB0aGlzLmh0dHBSZXF1ZXN0KHtcblx0XHRcdHVybDogdGhpcy5ob3N0ICsgXCJyZWNpcGVzL1wiICsgZW5jb2RlVVJJQ29tcG9uZW50KHRoaXMucmVjaXBlKSArIFwiL3RpZGRsZXJzL1wiICsgZW5jb2RlVVJJQ29tcG9uZW50KHRpdGxlKSxcblx0XHRcdHR5cGU6IFwiREVMRVRFXCIsXG5cdFx0fSk7XG5cdFx0ZGVsZXRlIHNlbGYub3V0c3RhbmRpbmdSZXF1ZXN0c1t0aXRsZV07XG5cdFx0aWYgKCFvaykgeyByZXR1cm4gY2FsbGJhY2soZXJyKTsgfVxuXHRcdGNvbnN0IHsgZGF0YSB9ID0gcmVzdWx0O1xuXHRcdGNvbnN0IHJldmlzaW9uID0gZGF0YS50aWRkbGVyX2lkLCBiYWdfbmFtZSA9IGRhdGEuYmFnX25hbWU7XG5cdFx0Ly8gSWYgdGhlcmUgaGFzIGJlZW4gYSBtb3JlIHJlY2VudCB1cGRhdGUgZnJvbSB0aGUgc2VydmVyIHRoZW4gZW5xdWV1ZSBhIGxvYWQgb2YgdGhpcyB0aWRkbGVyXG5cdFx0c2VsZi5jaGVja0xhc3RSZWNvcmRlZFVwZGF0ZSh0aXRsZSwgcmV2aXNpb24pO1xuXHRcdHNlbGYucmVtb3ZlVGlkZGxlckluZm8odGl0bGUpO1xuXHRcdC8vIEludm9rZSB0aGUgY2FsbGJhY2sgJiByZXR1cm4gbnVsbCBhZGFwdG9ySW5mb1xuXHRcdGNhbGxiYWNrKG51bGwsIG51bGwpO1xuXHR9XG59XG5cblxuaWYgKCR0dy5icm93c2VyICYmIGRvY3VtZW50LmxvY2F0aW9uLnByb3RvY29sLnN0YXJ0c1dpdGgoXCJodHRwXCIpKSB7XG5cdGV4cG9ydHMuYWRhcHRvckNsYXNzID0gTXVsdGlXaWtpQ2xpZW50QWRhcHRvcjtcbn1cbiJdfQ==
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
Warnings:
|
|
3
|
-
|
|
4
|
-
- Made the column `recipe_id` on table `recipe_acl` required. This step will fail if there are existing NULL values in that column.
|
|
5
|
-
|
|
6
|
-
*/
|
|
7
|
-
-- RedefineTables
|
|
8
|
-
PRAGMA defer_foreign_keys=ON;
|
|
9
|
-
PRAGMA foreign_keys=OFF;
|
|
10
|
-
CREATE TABLE "new_bag_acl" (
|
|
11
|
-
"acl_id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
12
|
-
"bag_id" INTEGER NOT NULL,
|
|
13
|
-
"role_id" INTEGER NOT NULL,
|
|
14
|
-
"permission" TEXT NOT NULL,
|
|
15
|
-
CONSTRAINT "bag_acl_bag_id_fkey" FOREIGN KEY ("bag_id") REFERENCES "bags" ("bag_id") ON DELETE CASCADE ON UPDATE CASCADE
|
|
16
|
-
);
|
|
17
|
-
INSERT INTO "new_bag_acl" ("acl_id", "bag_id", "permission", "role_id") SELECT "acl_id", "bag_id", "permission", "role_id" FROM "bag_acl";
|
|
18
|
-
DROP TABLE "bag_acl";
|
|
19
|
-
ALTER TABLE "new_bag_acl" RENAME TO "bag_acl";
|
|
20
|
-
CREATE TABLE "new_bags" (
|
|
21
|
-
"bag_id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
22
|
-
"bag_name" TEXT NOT NULL,
|
|
23
|
-
"description" TEXT NOT NULL,
|
|
24
|
-
"is_plugin" BOOLEAN NOT NULL,
|
|
25
|
-
"owner_id" INTEGER
|
|
26
|
-
);
|
|
27
|
-
INSERT INTO "new_bags" ("bag_id", "bag_name", "description", "is_plugin", "owner_id") SELECT "bag_id", "bag_name", "description", "is_plugin", "owner_id" FROM "bags";
|
|
28
|
-
DROP TABLE "bags";
|
|
29
|
-
ALTER TABLE "new_bags" RENAME TO "bags";
|
|
30
|
-
CREATE UNIQUE INDEX "bags_bag_name_key" ON "bags"("bag_name");
|
|
31
|
-
CREATE TABLE "new_recipe_acl" (
|
|
32
|
-
"acl_id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
33
|
-
"role_id" INTEGER NOT NULL,
|
|
34
|
-
"permission" TEXT NOT NULL,
|
|
35
|
-
"recipe_id" INTEGER NOT NULL,
|
|
36
|
-
CONSTRAINT "recipe_acl_recipe_id_fkey" FOREIGN KEY ("recipe_id") REFERENCES "recipes" ("recipe_id") ON DELETE CASCADE ON UPDATE CASCADE
|
|
37
|
-
);
|
|
38
|
-
INSERT INTO "new_recipe_acl" ("acl_id", "permission", "recipe_id", "role_id") SELECT "acl_id", "permission", "recipe_id", "role_id" FROM "recipe_acl";
|
|
39
|
-
DROP TABLE "recipe_acl";
|
|
40
|
-
ALTER TABLE "new_recipe_acl" RENAME TO "recipe_acl";
|
|
41
|
-
CREATE TABLE "new_recipes" (
|
|
42
|
-
"recipe_id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
43
|
-
"recipe_name" TEXT NOT NULL,
|
|
44
|
-
"description" TEXT NOT NULL,
|
|
45
|
-
"owner_id" INTEGER
|
|
46
|
-
);
|
|
47
|
-
INSERT INTO "new_recipes" ("description", "owner_id", "recipe_id", "recipe_name") SELECT "description", "owner_id", "recipe_id", "recipe_name" FROM "recipes";
|
|
48
|
-
DROP TABLE "recipes";
|
|
49
|
-
ALTER TABLE "new_recipes" RENAME TO "recipes";
|
|
50
|
-
CREATE UNIQUE INDEX "recipes_recipe_name_key" ON "recipes"("recipe_name");
|
|
51
|
-
PRAGMA foreign_keys=ON;
|
|
52
|
-
PRAGMA defer_foreign_keys=OFF;
|