@mnaoumov/obsidian-lib 10.11.0 → 10.12.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.
- package/README.md +26 -0
- package/components/all-windows-status-bar-item-component/package.json +6 -0
- package/components/shared-component-pool-component/package.json +6 -0
- package/components/workspace-layout-state-component/package.json +6 -0
- package/dist/lib/cjs/__merged.cjs +76 -1
- package/dist/lib/cjs/__merged.d.cts +11 -4
- package/dist/lib/cjs/bug-report-diagnostics.cjs +222 -0
- package/dist/lib/cjs/bug-report-diagnostics.d.cts +186 -0
- package/dist/lib/cjs/bug-report.cjs +36 -10
- package/dist/lib/cjs/bug-report.d.cts +65 -0
- package/dist/lib/cjs/command-handlers/open-bug-report-command-handler.cjs +93 -2
- package/dist/lib/cjs/command-handlers/open-bug-report-command-handler.d.cts +34 -2
- package/dist/lib/cjs/components/all-windows-status-bar-item-component.cjs +245 -0
- package/dist/lib/cjs/components/all-windows-status-bar-item-component.d.cts +146 -0
- package/dist/lib/cjs/components/embed-extensions-component.cjs +20 -3
- package/dist/lib/cjs/components/embed-extensions-component.d.cts +8 -0
- package/dist/lib/cjs/components/embeddable-markdown-editor-component.cjs +16 -2
- package/dist/lib/cjs/components/embeddable-markdown-editor-component.d.cts +9 -0
- package/dist/lib/cjs/components/index.cjs +12 -3
- package/dist/lib/cjs/components/index.d.cts +3 -0
- package/dist/lib/cjs/components/plugin-gate-component.cjs +2 -9
- package/dist/lib/cjs/components/plugin-settings-component.cjs +7 -2
- package/dist/lib/cjs/components/shared-component-pool-component.cjs +368 -0
- package/dist/lib/cjs/components/shared-component-pool-component.d.cts +129 -0
- package/dist/lib/cjs/components/workspace-layout-state-component.cjs +495 -0
- package/dist/lib/cjs/components/workspace-layout-state-component.d.cts +239 -0
- package/dist/lib/cjs/css-class.cjs +5 -1
- package/dist/lib/cjs/css-class.d.cts +16 -0
- package/dist/lib/cjs/data-handler.cjs +156 -5
- package/dist/lib/cjs/data-handler.d.cts +128 -2
- package/dist/lib/cjs/desktop-git-runner.cjs +4 -14
- package/dist/lib/cjs/desktop-git-runner.d.cts +8 -2
- package/dist/lib/cjs/generated-during-build.cjs +2 -2
- package/dist/lib/cjs/git-rename-history.cjs +1 -1
- package/dist/lib/cjs/git-rename-history.d.cts +2 -2
- package/dist/lib/cjs/i18n/locales/en.cjs +23 -1
- package/dist/lib/cjs/i18n/locales/en.d.cts +22 -0
- package/dist/lib/cjs/i18n/locales/translations-map.d.cts +22 -0
- package/dist/lib/cjs/index.cjs +4 -1
- package/dist/lib/cjs/index.d.cts +1 -0
- package/dist/lib/cjs/markdown-view.cjs +191 -3
- package/dist/lib/cjs/markdown-view.d.cts +48 -1
- package/dist/lib/cjs/modals/copy-text-manually.cjs +181 -0
- package/dist/lib/cjs/modals/copy-text-manually.d.cts +38 -0
- package/dist/lib/cjs/modals/index.cjs +7 -1
- package/dist/lib/cjs/modals/index.d.cts +2 -0
- package/dist/lib/cjs/modals/review-bug-report-diagnostics.cjs +202 -0
- package/dist/lib/cjs/modals/review-bug-report-diagnostics.d.cts +30 -0
- package/dist/lib/cjs/plugin/index.cjs +4 -1
- package/dist/lib/cjs/plugin/index.d.cts +1 -0
- package/dist/lib/cjs/plugin/plugin-api.cjs +13 -4
- package/dist/lib/cjs/plugin/plugin-api.d.cts +5 -1
- package/dist/lib/cjs/plugin/plugin-install-state.cjs +46 -1
- package/dist/lib/cjs/plugin/plugin-install-state.d.cts +30 -0
- package/dist/lib/cjs/plugin/plugin-instance.cjs +448 -0
- package/dist/lib/cjs/plugin/plugin-instance.d.cts +251 -0
- package/dist/lib/cjs/plugin/plugin.cjs +16 -1
- package/dist/lib/cjs/plugin/plugin.d.cts +7 -0
- package/dist/lib/esm/__merged.d.mts +11 -4
- package/dist/lib/esm/__merged.mjs +83 -3
- package/dist/lib/esm/bug-report-diagnostics.d.mts +186 -0
- package/dist/lib/esm/bug-report-diagnostics.mjs +127 -0
- package/dist/lib/esm/bug-report.d.mts +65 -0
- package/dist/lib/esm/bug-report.mjs +33 -10
- package/dist/lib/esm/command-handlers/open-bug-report-command-handler.d.mts +34 -2
- package/dist/lib/esm/command-handlers/open-bug-report-command-handler.mjs +99 -3
- package/dist/lib/esm/components/all-windows-status-bar-item-component.d.mts +146 -0
- package/dist/lib/esm/components/all-windows-status-bar-item-component.mjs +154 -0
- package/dist/lib/esm/components/embed-extensions-component.d.mts +8 -0
- package/dist/lib/esm/components/embed-extensions-component.mjs +20 -3
- package/dist/lib/esm/components/embeddable-markdown-editor-component.d.mts +9 -0
- package/dist/lib/esm/components/embeddable-markdown-editor-component.mjs +16 -2
- package/dist/lib/esm/components/index.d.mts +3 -0
- package/dist/lib/esm/components/index.mjs +8 -2
- package/dist/lib/esm/components/plugin-gate-component.mjs +5 -13
- package/dist/lib/esm/components/plugin-settings-component.mjs +7 -2
- package/dist/lib/esm/components/shared-component-pool-component.d.mts +129 -0
- package/dist/lib/esm/components/shared-component-pool-component.mjs +280 -0
- package/dist/lib/esm/components/workspace-layout-state-component.d.mts +239 -0
- package/dist/lib/esm/components/workspace-layout-state-component.mjs +404 -0
- package/dist/lib/esm/css-class.d.mts +16 -0
- package/dist/lib/esm/css-class.mjs +5 -1
- package/dist/lib/esm/data-handler.d.mts +128 -2
- package/dist/lib/esm/data-handler.mjs +152 -4
- package/dist/lib/esm/desktop-git-runner.d.mts +8 -2
- package/dist/lib/esm/desktop-git-runner.mjs +3 -3
- package/dist/lib/esm/generated-during-build.mjs +2 -2
- package/dist/lib/esm/git-rename-history.d.mts +2 -2
- package/dist/lib/esm/git-rename-history.mjs +1 -1
- package/dist/lib/esm/i18n/locales/en.d.mts +22 -0
- package/dist/lib/esm/i18n/locales/en.mjs +23 -1
- package/dist/lib/esm/i18n/locales/translations-map.d.mts +22 -0
- package/dist/lib/esm/index.d.mts +1 -0
- package/dist/lib/esm/index.mjs +3 -1
- package/dist/lib/esm/markdown-view.d.mts +48 -1
- package/dist/lib/esm/markdown-view.mjs +192 -2
- package/dist/lib/esm/modals/copy-text-manually.d.mts +38 -0
- package/dist/lib/esm/modals/copy-text-manually.mjs +99 -0
- package/dist/lib/esm/modals/index.d.mts +2 -0
- package/dist/lib/esm/modals/index.mjs +5 -1
- package/dist/lib/esm/modals/review-bug-report-diagnostics.d.mts +30 -0
- package/dist/lib/esm/modals/review-bug-report-diagnostics.mjs +120 -0
- package/dist/lib/esm/plugin/index.d.mts +1 -0
- package/dist/lib/esm/plugin/index.mjs +3 -1
- package/dist/lib/esm/plugin/plugin-api.d.mts +5 -1
- package/dist/lib/esm/plugin/plugin-api.mjs +13 -4
- package/dist/lib/esm/plugin/plugin-install-state.d.mts +30 -0
- package/dist/lib/esm/plugin/plugin-install-state.mjs +44 -1
- package/dist/lib/esm/plugin/plugin-instance.d.mts +251 -0
- package/dist/lib/esm/plugin/plugin-instance.mjs +366 -0
- package/dist/lib/esm/plugin/plugin.d.mts +7 -0
- package/dist/lib/esm/plugin/plugin.mjs +16 -1
- package/dist/styles.css +16 -1
- package/modals/copy-text-manually/package.json +6 -0
- package/modals/review-bug-report-diagnostics/package.json +6 -0
- package/package.json +2 -1
- package/plugin/plugin-instance/package.json +6 -0
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
/*
|
|
2
|
+
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
|
|
3
|
+
if you want to view the source, please visit the github repository of this plugin
|
|
4
|
+
*/
|
|
5
|
+
(function () {
|
|
6
|
+
function ensureBrowserProcess() {
|
|
7
|
+
const browserProcess = {
|
|
8
|
+
browser: true,
|
|
9
|
+
cwd() {
|
|
10
|
+
return "/";
|
|
11
|
+
},
|
|
12
|
+
env: {},
|
|
13
|
+
platform: "android"
|
|
14
|
+
};
|
|
15
|
+
const existingProcess = globalThis.process;
|
|
16
|
+
if (!existingProcess) {
|
|
17
|
+
globalThis.process = browserProcess;
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (existingProcess.versions?.node) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const existingProcessRecord = existingProcess;
|
|
24
|
+
for (const [key, value] of Object.entries(browserProcess)) {
|
|
25
|
+
existingProcessRecord[key] ??= value;
|
|
26
|
+
}
|
|
27
|
+
existingProcessRecord["browser"] = true;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
ensureBrowserProcess();
|
|
31
|
+
})();
|
|
32
|
+
(function patchObsidianRequire() {
|
|
33
|
+
const originalRequire = require;
|
|
34
|
+
if (!originalRequire || originalRequire.__isPatched) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
require = Object.assign(
|
|
38
|
+
(id) => requirePatched(id),
|
|
39
|
+
originalRequire,
|
|
40
|
+
{
|
|
41
|
+
__isPatched: true
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
function extractDefault($module) {
|
|
45
|
+
return $module && $module.__esModule && "default" in $module ? $module.default : $module;
|
|
46
|
+
}
|
|
47
|
+
const OBSIDIAN_BUILT_IN_MODULE_NAMES = /* @__PURE__ */ new Set([
|
|
48
|
+
"@codemirror/autocomplete",
|
|
49
|
+
"@codemirror/collab",
|
|
50
|
+
"@codemirror/commands",
|
|
51
|
+
"@codemirror/language",
|
|
52
|
+
"@codemirror/lint",
|
|
53
|
+
"@codemirror/search",
|
|
54
|
+
"@codemirror/state",
|
|
55
|
+
"@codemirror/text",
|
|
56
|
+
"@codemirror/view",
|
|
57
|
+
"@lezer/common",
|
|
58
|
+
"@lezer/highlight",
|
|
59
|
+
"@lezer/lr",
|
|
60
|
+
"obsidian"
|
|
61
|
+
]);
|
|
62
|
+
const DEPRECATED_OBSIDIAN_BUILT_IN_MODULE_NAMES = /* @__PURE__ */ new Set([
|
|
63
|
+
"@codemirror/closebrackets",
|
|
64
|
+
"@codemirror/comment",
|
|
65
|
+
"@codemirror/fold",
|
|
66
|
+
"@codemirror/gutter",
|
|
67
|
+
"@codemirror/highlight",
|
|
68
|
+
"@codemirror/history",
|
|
69
|
+
"@codemirror/matchbrackets",
|
|
70
|
+
"@codemirror/panel",
|
|
71
|
+
"@codemirror/rangeset",
|
|
72
|
+
"@codemirror/rectangular-selection",
|
|
73
|
+
"@codemirror/stream-parser",
|
|
74
|
+
"@codemirror/tooltip"
|
|
75
|
+
]);
|
|
76
|
+
function requirePatched(id) {
|
|
77
|
+
if (OBSIDIAN_BUILT_IN_MODULE_NAMES.has(id) || DEPRECATED_OBSIDIAN_BUILT_IN_MODULE_NAMES.has(id)) {
|
|
78
|
+
return originalRequire?.(id);
|
|
79
|
+
}
|
|
80
|
+
const app = globalThis.app;
|
|
81
|
+
if (app?.isMobile) {
|
|
82
|
+
if (id === "process" || id === "node:process") {
|
|
83
|
+
console.debug(`The most likely you can safely ignore this error. Module not found: ${id}. Fake process object is returned instead.`);
|
|
84
|
+
return process;
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
const $module = originalRequire?.(id);
|
|
88
|
+
if ($module) {
|
|
89
|
+
return extractDefault($module);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
console.debug(`The most likely you can safely ignore this error. Module not found: ${id}. Empty object is returned instead.`);
|
|
93
|
+
return {};
|
|
94
|
+
}
|
|
95
|
+
})();
|
|
96
|
+
|
|
97
|
+
"use strict";
|
|
98
|
+
var __defProp = Object.defineProperty;
|
|
99
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
100
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
101
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
102
|
+
var __export = (target, all) => {
|
|
103
|
+
for (var name in all)
|
|
104
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
105
|
+
};
|
|
106
|
+
var __copyProps = (to, from, except, desc) => {
|
|
107
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
108
|
+
for (let key of __getOwnPropNames(from))
|
|
109
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
110
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
111
|
+
}
|
|
112
|
+
return to;
|
|
113
|
+
};
|
|
114
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
115
|
+
var workspace_layout_state_component_exports = {};
|
|
116
|
+
__export(workspace_layout_state_component_exports, {
|
|
117
|
+
WORKSPACE_LAYOUT_STATE_LAYOUT_KEY: () => WORKSPACE_LAYOUT_STATE_LAYOUT_KEY,
|
|
118
|
+
WorkspaceLayoutStateComponent: () => WorkspaceLayoutStateComponent,
|
|
119
|
+
parseWorkspaceLayoutStateRecord: () => parseWorkspaceLayoutStateRecord,
|
|
120
|
+
serializeWorkspaceLayoutStateRecord: () => serializeWorkspaceLayoutStateRecord
|
|
121
|
+
});
|
|
122
|
+
module.exports = __toCommonJS(workspace_layout_state_component_exports);
|
|
123
|
+
var import_array = require('@mnaoumov/typescript-lib/array');
|
|
124
|
+
var import_async = require('@mnaoumov/typescript-lib/async');
|
|
125
|
+
var import_data_store_replica = require('../data-stores/data-store-replica.cjs');
|
|
126
|
+
var import_obsidian_lib_state = require('../obsidian-lib-state.cjs');
|
|
127
|
+
var import_component_ex = require('./component-ex.cjs');
|
|
128
|
+
var import_monkey_around_component = require('./monkey-around-component.cjs');
|
|
129
|
+
const WORKSPACE_LAYOUT_STATE_LAYOUT_KEY = "obsidianLibLayoutStateV1";
|
|
130
|
+
const SHARED_STATE_KEY = "workspaceLayoutStateV1";
|
|
131
|
+
const KNOWN_PLUGIN_RECORD_FIELD_COUNT = 2;
|
|
132
|
+
class WorkspaceLayoutStateKeyImpl {
|
|
133
|
+
key;
|
|
134
|
+
app;
|
|
135
|
+
defaultValue;
|
|
136
|
+
isValid;
|
|
137
|
+
pluginId;
|
|
138
|
+
subscribe;
|
|
139
|
+
constructor(params) {
|
|
140
|
+
this.app = params.app;
|
|
141
|
+
this.defaultValue = params.defaultValue;
|
|
142
|
+
this.isValid = params.isValid;
|
|
143
|
+
this.key = params.key;
|
|
144
|
+
this.pluginId = params.pluginId;
|
|
145
|
+
this.subscribe = params.subscribe;
|
|
146
|
+
}
|
|
147
|
+
get(leaf) {
|
|
148
|
+
return this.resolve(readRawValue(getSharedState(), this.pluginId, this.key, getLeafId(leaf)));
|
|
149
|
+
}
|
|
150
|
+
has(leaf) {
|
|
151
|
+
return readRawValue(getSharedState(), this.pluginId, this.key, getLeafId(leaf)) !== void 0;
|
|
152
|
+
}
|
|
153
|
+
onChange(callback) {
|
|
154
|
+
return this.subscribe((change) => {
|
|
155
|
+
if (change.key !== this.key) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
callback({
|
|
159
|
+
leaf: change.leafId === null ? null : this.app.workspace.getLeafById(change.leafId),
|
|
160
|
+
leafId: change.leafId,
|
|
161
|
+
oldValue: this.resolve(change.oldValue),
|
|
162
|
+
value: this.resolve(change.newValue)
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
set(value, leaf) {
|
|
167
|
+
assertJsonValue(value);
|
|
168
|
+
this.write(cloneJson(value), getLeafId(leaf));
|
|
169
|
+
}
|
|
170
|
+
unset(leaf) {
|
|
171
|
+
this.write(void 0, getLeafId(leaf));
|
|
172
|
+
}
|
|
173
|
+
resolve(rawValue) {
|
|
174
|
+
return cloneJson(rawValue !== void 0 && this.isValid(rawValue) ? rawValue : this.defaultValue);
|
|
175
|
+
}
|
|
176
|
+
write(newValue, leafId) {
|
|
177
|
+
const state = getSharedState();
|
|
178
|
+
const oldValue = readRawValue(state, this.pluginId, this.key, leafId);
|
|
179
|
+
if (JSON.stringify(oldValue) === JSON.stringify(newValue)) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
if (newValue === void 0) {
|
|
183
|
+
delete ensureBucket(state, this.pluginId, leafId)[this.key];
|
|
184
|
+
} else {
|
|
185
|
+
ensureBucket(state, this.pluginId, leafId)[this.key] = newValue;
|
|
186
|
+
}
|
|
187
|
+
this.app.workspace.requestSaveLayout();
|
|
188
|
+
const change = { key: this.key, leafId, newValue, oldValue, pluginId: this.pluginId };
|
|
189
|
+
for (const subscription of (0, import_array.snapshot)(state.subscriptions)) {
|
|
190
|
+
subscription.onRecordChange(change);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
class WorkspaceLayoutStateComponent extends import_component_ex.ComponentEx {
|
|
195
|
+
/**
|
|
196
|
+
* The Obsidian app instance.
|
|
197
|
+
*/
|
|
198
|
+
app;
|
|
199
|
+
/**
|
|
200
|
+
* The id of the plugin the values belong to.
|
|
201
|
+
*/
|
|
202
|
+
pluginId;
|
|
203
|
+
layoutLoadListeners = /* @__PURE__ */ new Set();
|
|
204
|
+
recordChangeListeners = /* @__PURE__ */ new Set();
|
|
205
|
+
/**
|
|
206
|
+
* Creates a new workspace layout state component.
|
|
207
|
+
*
|
|
208
|
+
* @param params - The parameters.
|
|
209
|
+
* @throws A `TypeError` if the plugin id is empty.
|
|
210
|
+
*/
|
|
211
|
+
constructor(params) {
|
|
212
|
+
super();
|
|
213
|
+
if (!params.pluginId) {
|
|
214
|
+
throw new TypeError("The plugin id must not be empty");
|
|
215
|
+
}
|
|
216
|
+
this.app = params.app;
|
|
217
|
+
this.pluginId = params.pluginId;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Defines a typed key.
|
|
221
|
+
*
|
|
222
|
+
* @typeParam T - The value type.
|
|
223
|
+
* @param definition - The key definition.
|
|
224
|
+
* @returns The key handle.
|
|
225
|
+
* @throws A `TypeError` if the key is empty or the default value is not JSON-safe.
|
|
226
|
+
*/
|
|
227
|
+
defineKey(definition) {
|
|
228
|
+
if (!definition.key) {
|
|
229
|
+
throw new TypeError("The key must not be empty");
|
|
230
|
+
}
|
|
231
|
+
assertJsonValue(definition.defaultValue);
|
|
232
|
+
return new WorkspaceLayoutStateKeyImpl({
|
|
233
|
+
app: this.app,
|
|
234
|
+
defaultValue: cloneJson(definition.defaultValue),
|
|
235
|
+
isValid: definition.isValid ?? ((_value) => true),
|
|
236
|
+
key: definition.key,
|
|
237
|
+
pluginId: this.pluginId,
|
|
238
|
+
subscribe: (listener) => this.subscribeToRecordChanges(listener)
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Subscribes to layout loads: a saved workspace loaded, the layout restored at startup, or the saved layout read when
|
|
243
|
+
* the component is first loaded after layout-ready. Every value may have changed.
|
|
244
|
+
*
|
|
245
|
+
* @param callback - Called after the layout is loaded, once its leaves exist.
|
|
246
|
+
* @returns A function that unsubscribes. Unloading the component unsubscribes too.
|
|
247
|
+
*/
|
|
248
|
+
onLayoutLoad(callback) {
|
|
249
|
+
this.layoutLoadListeners.add(callback);
|
|
250
|
+
return () => {
|
|
251
|
+
this.layoutLoadListeners.delete(callback);
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Subscribes to the shared installation, installing it when nobody has yet.
|
|
256
|
+
*/
|
|
257
|
+
onload() {
|
|
258
|
+
super.onload();
|
|
259
|
+
const state = getSharedState();
|
|
260
|
+
const subscription = {
|
|
261
|
+
install: () => installLayoutState(this.app, state),
|
|
262
|
+
onLayoutLoad: () => {
|
|
263
|
+
for (const listener of (0, import_array.snapshot)(this.layoutLoadListeners)) {
|
|
264
|
+
invokeListener(listener);
|
|
265
|
+
}
|
|
266
|
+
},
|
|
267
|
+
onRecordChange: (change) => {
|
|
268
|
+
if (change.pluginId !== this.pluginId) {
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
for (const listener of (0, import_array.snapshot)(this.recordChangeListeners)) {
|
|
272
|
+
invokeListener(() => {
|
|
273
|
+
listener(change);
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
state.subscriptions.push(subscription);
|
|
279
|
+
state.installation ??= { owner: subscription, uninstall: subscription.install() };
|
|
280
|
+
this.register(() => {
|
|
281
|
+
this.layoutLoadListeners.clear();
|
|
282
|
+
this.recordChangeListeners.clear();
|
|
283
|
+
state.subscriptions.splice(state.subscriptions.indexOf(subscription), 1);
|
|
284
|
+
if (state.installation?.owner !== subscription) {
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
state.installation.uninstall();
|
|
288
|
+
const nextOwner = state.subscriptions[0];
|
|
289
|
+
state.installation = nextOwner ? { owner: nextOwner, uninstall: nextOwner.install() } : null;
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
subscribeToRecordChanges(listener) {
|
|
293
|
+
this.recordChangeListeners.add(listener);
|
|
294
|
+
return () => {
|
|
295
|
+
this.recordChangeListeners.delete(listener);
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
function parseWorkspaceLayoutStateRecord(value) {
|
|
300
|
+
if (!isJsonObject(value)) {
|
|
301
|
+
return { plugins: {} };
|
|
302
|
+
}
|
|
303
|
+
const plugins = {};
|
|
304
|
+
const rawPlugins = value["plugins"];
|
|
305
|
+
if (isJsonObject(rawPlugins)) {
|
|
306
|
+
for (const [pluginId, rawPluginRecord] of Object.entries(rawPlugins)) {
|
|
307
|
+
const pluginRecord = parsePluginRecord(rawPluginRecord);
|
|
308
|
+
if (pluginRecord) {
|
|
309
|
+
plugins[pluginId] = pluginRecord;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
return { ...cloneJson(value), plugins };
|
|
314
|
+
}
|
|
315
|
+
function serializeWorkspaceLayoutStateRecord(record, layout) {
|
|
316
|
+
const leafIds = collectLeafIds(layout);
|
|
317
|
+
const serialized = cloneJson(record);
|
|
318
|
+
const plugins = serialized.plugins;
|
|
319
|
+
for (const [pluginId, pluginRecord] of Object.entries(plugins)) {
|
|
320
|
+
for (const [leafId, bucket] of Object.entries(pluginRecord.leaves)) {
|
|
321
|
+
if (!leafIds.has(leafId) || Object.keys(bucket).length === 0) {
|
|
322
|
+
delete pluginRecord.leaves[leafId];
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
const isEmpty = Object.keys(pluginRecord.workspace).length === 0 && Object.keys(pluginRecord.leaves).length === 0 && Object.keys(pluginRecord).length === KNOWN_PLUGIN_RECORD_FIELD_COUNT;
|
|
326
|
+
if (isEmpty) {
|
|
327
|
+
delete plugins[pluginId];
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
return Object.keys(plugins).length === 0 && Object.keys(serialized).length === 1 ? null : serialized;
|
|
331
|
+
}
|
|
332
|
+
function assertJsonValue(value) {
|
|
333
|
+
if (!(0, import_data_store_replica.isDataStoreJsonValue)(value)) {
|
|
334
|
+
throw new TypeError("A workspace layout state value must be JSON-safe");
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
function cloneJson(value) {
|
|
338
|
+
return JSON.parse(JSON.stringify(value));
|
|
339
|
+
}
|
|
340
|
+
function collectLeafIds(layout) {
|
|
341
|
+
const leafIds = /* @__PURE__ */ new Set();
|
|
342
|
+
function visit(item) {
|
|
343
|
+
if (!isPlainRecord(item)) {
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
const id = item["id"];
|
|
347
|
+
if (item["type"] === "leaf" && typeof id === "string") {
|
|
348
|
+
leafIds.add(id);
|
|
349
|
+
}
|
|
350
|
+
const children = item["children"];
|
|
351
|
+
if (Array.isArray(children)) {
|
|
352
|
+
for (const child of children) {
|
|
353
|
+
visit(child);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
if (isPlainRecord(layout)) {
|
|
358
|
+
for (const rootKey of ["main", "left", "right", "floating"]) {
|
|
359
|
+
visit(layout[rootKey]);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
return leafIds;
|
|
363
|
+
}
|
|
364
|
+
function ensureBucket(state, pluginId, leafId) {
|
|
365
|
+
const pluginRecord = state.record.plugins[pluginId] ?? { leaves: {}, workspace: {} };
|
|
366
|
+
state.record.plugins[pluginId] = pluginRecord;
|
|
367
|
+
if (leafId === null) {
|
|
368
|
+
return pluginRecord.workspace;
|
|
369
|
+
}
|
|
370
|
+
const bucket = pluginRecord.leaves[leafId] ?? {};
|
|
371
|
+
pluginRecord.leaves[leafId] = bucket;
|
|
372
|
+
return bucket;
|
|
373
|
+
}
|
|
374
|
+
function getBucket(state, pluginId, leafId) {
|
|
375
|
+
const pluginRecord = state.record.plugins[pluginId];
|
|
376
|
+
if (!pluginRecord) {
|
|
377
|
+
return null;
|
|
378
|
+
}
|
|
379
|
+
return leafId === null ? pluginRecord.workspace : pluginRecord.leaves[leafId] ?? null;
|
|
380
|
+
}
|
|
381
|
+
function getLayoutRecordValue(layout) {
|
|
382
|
+
return isPlainRecord(layout) ? layout[WORKSPACE_LAYOUT_STATE_LAYOUT_KEY] : void 0;
|
|
383
|
+
}
|
|
384
|
+
function getLeafId(leaf) {
|
|
385
|
+
return leaf ? leaf.id : null;
|
|
386
|
+
}
|
|
387
|
+
function getSharedState() {
|
|
388
|
+
return (0, import_obsidian_lib_state.getObsidianLibState)(SHARED_STATE_KEY, {
|
|
389
|
+
installation: null,
|
|
390
|
+
isHydrated: false,
|
|
391
|
+
record: { plugins: {} },
|
|
392
|
+
subscriptions: []
|
|
393
|
+
}).value;
|
|
394
|
+
}
|
|
395
|
+
function installLayoutState(app, state) {
|
|
396
|
+
let isUninstalled = false;
|
|
397
|
+
const uninstallPatch = (0, import_monkey_around_component.around)(app.workspace, {
|
|
398
|
+
getLayout: (next) => function patchedGetLayout() {
|
|
399
|
+
const layout = next.call(this);
|
|
400
|
+
const record = serializeWorkspaceLayoutStateRecord(state.record, layout);
|
|
401
|
+
if (record) {
|
|
402
|
+
layout[WORKSPACE_LAYOUT_STATE_LAYOUT_KEY] = record;
|
|
403
|
+
}
|
|
404
|
+
return layout;
|
|
405
|
+
},
|
|
406
|
+
setLayout: (next) => async function patchedSetLayout(layout) {
|
|
407
|
+
state.record = parseWorkspaceLayoutStateRecord(getLayoutRecordValue(layout));
|
|
408
|
+
state.isHydrated = true;
|
|
409
|
+
try {
|
|
410
|
+
await next.call(this, layout);
|
|
411
|
+
} finally {
|
|
412
|
+
notifyLayoutLoad(state);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
});
|
|
416
|
+
if (!state.isHydrated && app.workspace.layoutReady) {
|
|
417
|
+
(0, import_async.invokeAsyncSafely)(async () => {
|
|
418
|
+
const saved = await app.workspace.readWorkspaceFile();
|
|
419
|
+
if (isUninstalled || state.isHydrated) {
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
mergeMissing(state.record, parseWorkspaceLayoutStateRecord(getLayoutRecordValue(saved)));
|
|
423
|
+
state.isHydrated = true;
|
|
424
|
+
notifyLayoutLoad(state);
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
return () => {
|
|
428
|
+
isUninstalled = true;
|
|
429
|
+
uninstallPatch();
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
function invokeListener(listener) {
|
|
433
|
+
try {
|
|
434
|
+
listener();
|
|
435
|
+
} catch (error) {
|
|
436
|
+
console.error("A workspace layout state listener failed", error);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
function isJsonObject(value) {
|
|
440
|
+
return isPlainRecord(value) && (0, import_data_store_replica.isDataStoreJsonValue)(value);
|
|
441
|
+
}
|
|
442
|
+
function isPlainRecord(value) {
|
|
443
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
444
|
+
}
|
|
445
|
+
function mergeMissing(target, source) {
|
|
446
|
+
for (const [pluginId, sourcePlugin] of Object.entries(source.plugins)) {
|
|
447
|
+
const targetPlugin = target.plugins[pluginId];
|
|
448
|
+
if (!targetPlugin) {
|
|
449
|
+
target.plugins[pluginId] = sourcePlugin;
|
|
450
|
+
continue;
|
|
451
|
+
}
|
|
452
|
+
for (const [key, value] of Object.entries(sourcePlugin.workspace)) {
|
|
453
|
+
targetPlugin.workspace[key] ??= value;
|
|
454
|
+
}
|
|
455
|
+
for (const [leafId, bucket] of Object.entries(sourcePlugin.leaves)) {
|
|
456
|
+
targetPlugin.leaves[leafId] ??= bucket;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
function notifyLayoutLoad(state) {
|
|
461
|
+
for (const subscription of (0, import_array.snapshot)(state.subscriptions)) {
|
|
462
|
+
subscription.onLayoutLoad();
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
function parsePluginRecord(value) {
|
|
466
|
+
if (!isJsonObject(value)) {
|
|
467
|
+
return null;
|
|
468
|
+
}
|
|
469
|
+
const leaves = {};
|
|
470
|
+
const rawLeaves = value["leaves"];
|
|
471
|
+
if (isJsonObject(rawLeaves)) {
|
|
472
|
+
for (const [leafId, bucket] of Object.entries(rawLeaves)) {
|
|
473
|
+
if (isJsonObject(bucket)) {
|
|
474
|
+
leaves[leafId] = cloneJson(bucket);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
const rawWorkspace = value["workspace"];
|
|
479
|
+
return {
|
|
480
|
+
...cloneJson(value),
|
|
481
|
+
leaves,
|
|
482
|
+
workspace: isJsonObject(rawWorkspace) ? cloneJson(rawWorkspace) : {}
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
function readRawValue(state, pluginId, key, leafId) {
|
|
486
|
+
return getBucket(state, pluginId, leafId)?.[key];
|
|
487
|
+
}
|
|
488
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
489
|
+
0 && (module.exports = {
|
|
490
|
+
WORKSPACE_LAYOUT_STATE_LAYOUT_KEY,
|
|
491
|
+
WorkspaceLayoutStateComponent,
|
|
492
|
+
parseWorkspaceLayoutStateRecord,
|
|
493
|
+
serializeWorkspaceLayoutStateRecord
|
|
494
|
+
});
|
|
495
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL3dvcmtzcGFjZS1sYXlvdXQtc3RhdGUtY29tcG9uZW50LnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBLZWVwcyBhIHBsdWdpbidzIGxheW91dC1zY29wZWQgc3RhdGUgaW4gdGhlIHdvcmtzcGFjZSBsYXlvdXQgaXRzZWxmLCBzbyBlYWNoIHNhdmVkIHdvcmtzcGFjZSByZW1lbWJlcnMgaXRzIG93biB2YWx1ZVxuICogYW5kIHN3aXRjaGluZyB3b3Jrc3BhY2VzIHJlc3RvcmVzIGl0LCBpbnN0ZWFkIG9mIG9uZSBnbG9iYWwgdmFsdWUgaW4gYGRhdGEuanNvbmAuXG4gKlxuICogUmVhZCBmcm9tIE9ic2lkaWFuIGAxLjE1LjFgOiBgV29ya3NwYWNlLmdldExheW91dCgpYCBidWlsZHMgYSBmcmVzaCBvYmplY3QgKGBtYWluYCwgYGxlZnRgLCBgcmlnaHRgLCBgbGVmdC1yaWJib25gLFxuICogYGZsb2F0aW5nYCwgYGFjdGl2ZWApIGFuZCBgV29ya3NwYWNlLnNldExheW91dCgpYCBpZ25vcmVzIGV2ZXJ5IG90aGVyIHRvcC1sZXZlbCBrZXkuIGBkZXNlcmlhbGl6ZUxheW91dGAga2VlcHMgZWFjaFxuICogaXRlbSdzIGBpZGAsIHBvcG91dCBsZWF2ZXMgaW5jbHVkZWQuIFRoZSBXb3Jrc3BhY2VzIGNvcmUgcGx1Z2luIHNhdmVzIHRocm91Z2ggYGdldExheW91dCgpYCBhbmQgbG9hZHMgdGhyb3VnaFxuICogYGNoYW5nZUxheW91dCgpYCwgd2hpY2ggY2FsbHMgYHNldExheW91dCgpYC4gU3RhcnR1cCBnb2VzIHRocm91Z2ggYGxvYWRMYXlvdXQoKWAsIGByZWFkV29ya3NwYWNlRmlsZSgpYCBhbmRcbiAqIGBzZXRMYXlvdXQoKWAsIGFmdGVyIHRoZSBwbHVnaW5zIGVuYWJsZWQgYXQgc3RhcnR1cCBoYXZlIGxvYWRlZC4gU28gdHdvIHBhdGNoZXMgb24gdGhlIGBhcHAud29ya3NwYWNlYCBpbnN0YW5jZSBjYXJyeVxuICogdGhlIHdob2xlIHRoaW5nOiBgZ2V0TGF5b3V0YCB3cml0ZXMgdGhlIHJlY29yZHMgdW5kZXIge0BsaW5rIFdPUktTUEFDRV9MQVlPVVRfU1RBVEVfTEFZT1VUX0tFWX0sIGFuZCBgc2V0TGF5b3V0YFxuICogcmVwbGFjZXMgdGhlbSBmcm9tIHRoZSBsYXlvdXQgaXQgaXMgaGFuZGVkIGJlZm9yZSBhbnkgdmlldyBpcyByZXN0b3JlZC4gUGVyLWxlYWYgc3RhdGUgaXMga2V5ZWQgYnkgbGVhZiBpZCBhdCB0aGVcbiAqIGxheW91dCBsZXZlbCwgc28gbm8gYFdvcmtzcGFjZUl0ZW0uc2VyaWFsaXplYCBvciBgZGVzZXJpYWxpemVMYXlvdXRgIHBhdGNoIGlzIG5lZWRlZC5cbiAqXG4gKiBBIHZpZXcgdGhlIHBsdWdpbiBvd25zIG5lZWRzIG5vbmUgb2YgdGhpczogYFZpZXcuZ2V0U3RhdGVgIC8gYHNldFN0YXRlYCBhbHJlYWR5IHJpZGUgaW4gZWFjaCBsZWFmJ3Mgc3RhdGUuIFRoaXNcbiAqIGNvbXBvbmVudCBpcyBmb3IgdGhlIHNjb3BlIHRob3NlIG1ldGhvZHMgY2Fubm90IHJlcHJlc2VudDogdGhlIHdob2xlIGxheW91dCwgYW5kIGxlYXZlcyBvZiB2aWV3cyB0aGUgcGx1Z2luIGRvZXMgbm90XG4gKiBvd24uXG4gKlxuICogRXZlcnkgcGx1Z2luIGJ1bmRsZXMgaXRzIG93biBjb3B5IG9mIHRoaXMgbGlicmFyeSwgc28gdGhlIHJlY29yZHMsIHRoZSBzdWJzY3JpcHRpb25zIGFuZCBPTkUgaW5zdGFsbGF0aW9uIG9mIHRoZVxuICogcGF0Y2hlcyBsaXZlIGluIHRoZSBzaGFyZWQtc3RhdGUgYmFnIHVuZGVyIGEgdmVyc2lvbmVkIGtleSwgb3duZWQgYnkgb25lIHN1YnNjcmliZXIuIFdoZW4gdGhlIG93bmVyIHVubG9hZHMgd2hpbGVcbiAqIG90aGVycyByZW1haW4sIHRoZSBuZXh0IHN1YnNjcmliZXIgaW5zdGFsbHMgYWdhaW4gZnJvbSBpdHMgb3duIGNvcHkuIFdoYXQgY3Jvc3NlcyB0aGF0IGJvdW5kYXJ5IGlzIGEgd2lyZSBmb3JtYXRcbiAqIGJldHdlZW4gY29waWVzIG9mIGRpZmZlcmVudCB2ZXJzaW9uczogcGxhaW4gb2JqZWN0cyBhbmQgcGxhaW4gZnVuY3Rpb25zIG9ubHksIGZpZWxkcyBvbmx5IGV2ZXIgYWRkZWQsIGFuZCBhIGNoYW5nZSBvZlxuICogbWVhbmluZyBtb3ZlcyB0byBhIG5ldyBrZXkuIFRoZSBsYXlvdXQgcmVjb3JkIGlzIGEgd2lyZSBmb3JtYXQgdG9vLCBwZXJzaXN0ZWQgaW4gYHdvcmtzcGFjZS5qc29uYCBhbmQgaW4gZXZlcnkgc2F2ZWRcbiAqIHdvcmtzcGFjZS5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7XG4gIEFwcCxcbiAgV29ya3NwYWNlLFxuICBXb3Jrc3BhY2VMZWFmXG59IGZyb20gJ29ic2lkaWFuJztcbmltcG9ydCB0eXBlIHtcbiAgSnNvbk9iamVjdCxcbiAgSnNvblZhbHVlXG59IGZyb20gJ3R5cGUtZmVzdCc7XG5cbmltcG9ydCB7IHNuYXBzaG90IH0gZnJvbSAnQG1uYW91bW92L3R5cGVzY3JpcHQtbGliL2FycmF5JztcbmltcG9ydCB7IGludm9rZUFzeW5jU2FmZWx5IH0gZnJvbSAnQG1uYW91bW92L3R5cGVzY3JpcHQtbGliL2FzeW5jJztcblxuaW1wb3J0IHsgaXNEYXRhU3RvcmVKc29uVmFsdWUgfSBmcm9tICcuLi9kYXRhLXN0b3Jlcy9kYXRhLXN0b3JlLXJlcGxpY2EudHMnO1xuaW1wb3J0IHsgZ2V0T2JzaWRpYW5MaWJTdGF0ZSB9IGZyb20gJy4uL29ic2lkaWFuLWxpYi1zdGF0ZS50cyc7XG5pbXBvcnQgeyBDb21wb25lbnRFeCB9IGZyb20gJy4vY29tcG9uZW50LWV4LnRzJztcbmltcG9ydCB7IGFyb3VuZCB9IGZyb20gJy4vbW9ua2V5LWFyb3VuZC1jb21wb25lbnQudHMnO1xuXG4vKipcbiAqIFRoZSB0b3AtbGV2ZWwga2V5IG9mIGEgc2VyaWFsaXplZCBsYXlvdXQgdGhhdCBob2xkcyB0aGUgcmVjb3Jkcy5cbiAqL1xuZXhwb3J0IGNvbnN0IFdPUktTUEFDRV9MQVlPVVRfU1RBVEVfTEFZT1VUX0tFWSA9ICdvYnNpZGlhbkxpYkxheW91dFN0YXRlVjEnO1xuXG5jb25zdCBTSEFSRURfU1RBVEVfS0VZID0gJ3dvcmtzcGFjZUxheW91dFN0YXRlVjEnO1xuXG4vKipcbiAqIFRoZSBmaWVsZHMgb2YgYSBwbHVnaW4gcmVjb3JkIHRoaXMgdmVyc2lvbiBrbm93czogYGxlYXZlc2AgYW5kIGB3b3Jrc3BhY2VgLlxuICovXG5jb25zdCBLTk9XTl9QTFVHSU5fUkVDT1JEX0ZJRUxEX0NPVU5UID0gMjtcblxuLyoqXG4gKiBBIGNoYW5nZSBvZiBvbmUga2V5J3MgdmFsdWUsIGluIG9uZSBzY29wZS5cbiAqXG4gKiBAdHlwZVBhcmFtIFQgLSBUaGUgdmFsdWUgdHlwZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBXb3Jrc3BhY2VMYXlvdXRTdGF0ZUNoYW5nZTxUPiB7XG4gIC8qKlxuICAgKiBUaGUgbGVhZiB3aG9zZSB2YWx1ZSBjaGFuZ2VkLCBvciBgbnVsbGAgZm9yIHRoZSB3b3Jrc3BhY2Ugc2NvcGUgb3IgYSBsZWFmIG5vIGxvbmdlciBpbiB0aGUgbGF5b3V0LlxuICAgKi9cbiAgcmVhZG9ubHkgbGVhZjogbnVsbCB8IFdvcmtzcGFjZUxlYWY7XG5cbiAgLyoqXG4gICAqIFRoZSBpZCBvZiB0aGUgbGVhZiB3aG9zZSB2YWx1ZSBjaGFuZ2VkLCBvciBgbnVsbGAgZm9yIHRoZSB3b3Jrc3BhY2Ugc2NvcGUuXG4gICAqL1xuICByZWFkb25seSBsZWFmSWQ6IG51bGwgfCBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSB2YWx1ZSBiZWZvcmUgdGhlIGNoYW5nZSwgYXMge0BsaW5rIFdvcmtzcGFjZUxheW91dFN0YXRlS2V5LmdldH0gcmVhZCBpdC5cbiAgICovXG4gIHJlYWRvbmx5IG9sZFZhbHVlOiBUO1xuXG4gIC8qKlxuICAgKiBUaGUgdmFsdWUgYWZ0ZXIgdGhlIGNoYW5nZSwgYXMge0BsaW5rIFdvcmtzcGFjZUxheW91dFN0YXRlS2V5LmdldH0gcmVhZHMgaXQuXG4gICAqL1xuICByZWFkb25seSB2YWx1ZTogVDtcbn1cblxuLyoqXG4gKiBQYXJhbWV0ZXJzIGZvciB7QGxpbmsgV29ya3NwYWNlTGF5b3V0U3RhdGVDb21wb25lbnR9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFdvcmtzcGFjZUxheW91dFN0YXRlQ29tcG9uZW50Q29uc3RydWN0b3JQYXJhbXMge1xuICAvKipcbiAgICogVGhlIE9ic2lkaWFuIGFwcCBpbnN0YW5jZS5cbiAgICovXG4gIHJlYWRvbmx5IGFwcDogQXBwO1xuXG4gIC8qKlxuICAgKiBUaGUgaWQgb2YgdGhlIHBsdWdpbiB0aGUgdmFsdWVzIGJlbG9uZyB0by4gRXZlcnkgdmFsdWUgaXMgbmFtZXNwYWNlZCBieSBpdC5cbiAgICovXG4gIHJlYWRvbmx5IHBsdWdpbklkOiBzdHJpbmc7XG59XG5cbi8qKlxuICogQSB0eXBlZCBoYW5kbGUgdG8gb25lIGxheW91dC1zY29wZWQga2V5LlxuICpcbiAqIEV2ZXJ5IG1ldGhvZCB0YWtlcyBhbiBvcHRpb25hbCBsZWFmLiBXaXRob3V0IG9uZSwgdGhlIHZhbHVlIGJlbG9uZ3MgdG8gdGhlIHdob2xlIGxheW91dCAodGhlIHdvcmtzcGFjZSBzY29wZSkuXG4gKlxuICogQHR5cGVQYXJhbSBUIC0gVGhlIHZhbHVlIHR5cGUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgV29ya3NwYWNlTGF5b3V0U3RhdGVLZXk8VD4ge1xuICAvKipcbiAgICogUmVhZHMgdGhlIHZhbHVlOiBhIGNsb25lIG9mIHRoZSBzdG9yZWQgb25lLCBvciBvZiB0aGUgZGVmYXVsdCB3aGVuIG5vdGhpbmcgaXMgc3RvcmVkIG9yIHRoZSBzdG9yZWQgdmFsdWUgZmFpbHMgdGhlXG4gICAqIGtleSdzIGd1YXJkLlxuICAgKlxuICAgKiBAcGFyYW0gbGVhZiAtIFRoZSBsZWFmLCBvciBub3RoaW5nIGZvciB0aGUgd29ya3NwYWNlIHNjb3BlLlxuICAgKiBAcmV0dXJucyBUaGUgdmFsdWUuXG4gICAqL1xuICByZWFkb25seSBnZXQ6IChsZWFmPzogV29ya3NwYWNlTGVhZikgPT4gVDtcblxuICAvKipcbiAgICogQ2hlY2tzIHdoZXRoZXIgYSB2YWx1ZSBpcyBzdG9yZWQsIHZhbGlkIG9yIG5vdC5cbiAgICpcbiAgICogQHBhcmFtIGxlYWYgLSBUaGUgbGVhZiwgb3Igbm90aGluZyBmb3IgdGhlIHdvcmtzcGFjZSBzY29wZS5cbiAgICogQHJldHVybnMgV2hldGhlciBhIHZhbHVlIGlzIHN0b3JlZC5cbiAgICovXG4gIHJlYWRvbmx5IGhhczogKGxlYWY/OiBXb3Jrc3BhY2VMZWFmKSA9PiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBUaGUga2V5IG5hbWUsIHVuaXF1ZSB3aXRoaW4gdGhlIHBsdWdpbi5cbiAgICovXG4gIHJlYWRvbmx5IGtleTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBTdWJzY3JpYmVzIHRvIGNoYW5nZXMgb2YgdGhpcyBrZXkgbWFkZSB0aHJvdWdoIGBzZXRgIG9yIGB1bnNldGAsIGluIGFueSBzY29wZSBhbmQgZnJvbSBhbnkgY29weSBvZiB0aGUgbGlicmFyeS4gQVxuICAgKiBsYXlvdXQgbG9hZCBpcyByZXBvcnRlZCB0aHJvdWdoIHtAbGluayBXb3Jrc3BhY2VMYXlvdXRTdGF0ZUNvbXBvbmVudC5vbkxheW91dExvYWR9IGluc3RlYWQuXG4gICAqXG4gICAqIEBwYXJhbSBjYWxsYmFjayAtIENhbGxlZCBhZnRlciBlYWNoIGNoYW5nZS5cbiAgICogQHJldHVybnMgQSBmdW5jdGlvbiB0aGF0IHVuc3Vic2NyaWJlcy4gVW5sb2FkaW5nIHRoZSBjb21wb25lbnQgdW5zdWJzY3JpYmVzIHRvby5cbiAgICovXG4gIHJlYWRvbmx5IG9uQ2hhbmdlOiAoY2FsbGJhY2s6IChjaGFuZ2U6IFdvcmtzcGFjZUxheW91dFN0YXRlQ2hhbmdlPFQ+KSA9PiB2b2lkKSA9PiAoKSA9PiB2b2lkO1xuXG4gIC8qKlxuICAgKiBTdG9yZXMgYSBjbG9uZSBvZiB0aGUgdmFsdWUgYW5kIHJlcXVlc3RzIGEgbGF5b3V0IHNhdmUuIFN0b3JpbmcgYSB2YWx1ZSBlcXVhbCB0byB0aGUgc3RvcmVkIG9uZSBkb2VzIG5vdGhpbmcuXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZS4gSXQgbXVzdCBiZSBKU09OLXNhZmU7IGBudWxsYCBpcyBzdG9yZWQgYXMgYG51bGxgLlxuICAgKiBAcGFyYW0gbGVhZiAtIFRoZSBsZWFmLCBvciBub3RoaW5nIGZvciB0aGUgd29ya3NwYWNlIHNjb3BlLlxuICAgKiBAdGhyb3dzIEEgYFR5cGVFcnJvcmAgaWYgdGhlIHZhbHVlIGlzIG5vdCBKU09OLXNhZmUuXG4gICAqL1xuICByZWFkb25seSBzZXQ6ICh2YWx1ZTogVCwgbGVhZj86IFdvcmtzcGFjZUxlYWYpID0+IHZvaWQ7XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgdGhlIHN0b3JlZCB2YWx1ZSwgc28gYGdldGAgcmVhZHMgdGhlIGRlZmF1bHQgYWdhaW4sIGFuZCByZXF1ZXN0cyBhIGxheW91dCBzYXZlLlxuICAgKlxuICAgKiBAcGFyYW0gbGVhZiAtIFRoZSBsZWFmLCBvciBub3RoaW5nIGZvciB0aGUgd29ya3NwYWNlIHNjb3BlLlxuICAgKi9cbiAgcmVhZG9ubHkgdW5zZXQ6IChsZWFmPzogV29ya3NwYWNlTGVhZikgPT4gdm9pZDtcbn1cblxuLyoqXG4gKiBEZWZpbmVzIGEgbGF5b3V0LXNjb3BlZCBrZXkuXG4gKlxuICogQHR5cGVQYXJhbSBUIC0gVGhlIHZhbHVlIHR5cGUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgV29ya3NwYWNlTGF5b3V0U3RhdGVLZXlEZWZpbml0aW9uPFQ+IHtcbiAgLyoqXG4gICAqIFRoZSB2YWx1ZSByZWFkIHdoZW4gbm90aGluZyB2YWxpZCBpcyBzdG9yZWQuXG4gICAqL1xuICByZWFkb25seSBkZWZhdWx0VmFsdWU6IFQ7XG5cbiAgLyoqXG4gICAqIENoZWNrcyBhIHN0b3JlZCB2YWx1ZS4gQSB2YWx1ZSB0aGF0IGZhaWxzIHJlYWRzIGFzIHRoZSBkZWZhdWx0IGFuZCBzdGF5cyBzdG9yZWQgdW50aWwgaXQgaXMgcmVwbGFjZWQgb3IgdW5zZXQuXG4gICAqXG4gICAqIEBkZWZhdWx0IEFjY2VwdHMgZXZlcnkgSlNPTiB2YWx1ZS5cbiAgICovXG4gIHJlYWRvbmx5IGlzVmFsaWQ/OiAodmFsdWU6IHVua25vd24pID0+IHZhbHVlIGlzIFQ7XG5cbiAgLyoqXG4gICAqIFRoZSBrZXkgbmFtZSwgdW5pcXVlIHdpdGhpbiB0aGUgcGx1Z2luLlxuICAgKi9cbiAgcmVhZG9ubHkga2V5OiBzdHJpbmc7XG59XG5cbi8qKlxuICogT25lIHBsdWdpbidzIHJlY29yZHMuIEZpZWxkcyBhIG5ld2VyIGNvcHkgYWRkcyBhcmUgcHJlc2VydmVkLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFdvcmtzcGFjZUxheW91dFN0YXRlUGx1Z2luUmVjb3JkIHtcbiAgLyoqXG4gICAqIFRoZSB2YWx1ZXMgYnkgbGVhZiBpZCwgdGhlbiBieSBrZXkuXG4gICAqL1xuICByZWFkb25seSBsZWF2ZXM6IFJlY29yZDxzdHJpbmcsIEpzb25SZWNvcmQ+O1xuXG4gIC8qKlxuICAgKiBGaWVsZHMgYSBuZXdlciBjb3B5IG9mIHRoZSBsaWJyYXJ5IGFkZGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgW2ZpZWxkOiBzdHJpbmddOiB1bmtub3duO1xuXG4gIC8qKlxuICAgKiBUaGUgd29ya3NwYWNlLXNjb3BlIHZhbHVlcyBieSBrZXkuXG4gICAqL1xuICByZWFkb25seSB3b3Jrc3BhY2U6IEpzb25SZWNvcmQ7XG59XG5cbi8qKlxuICogVGhlIHJlY29yZCBwZXJzaXN0ZWQgdW5kZXIge0BsaW5rIFdPUktTUEFDRV9MQVlPVVRfU1RBVEVfTEFZT1VUX0tFWX0uIEZpZWxkcyBhIG5ld2VyIGNvcHkgYWRkcyBhcmUgcHJlc2VydmVkLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFdvcmtzcGFjZUxheW91dFN0YXRlUmVjb3JkIHtcbiAgLyoqXG4gICAqIFRoZSByZWNvcmRzIGJ5IHBsdWdpbiBpZC5cbiAgICovXG4gIHJlYWRvbmx5IHBsdWdpbnM6IFJlY29yZDxzdHJpbmcsIFdvcmtzcGFjZUxheW91dFN0YXRlUGx1Z2luUmVjb3JkPjtcblxuICAvKipcbiAgICogRmllbGRzIGEgbmV3ZXIgY29weSBvZiB0aGUgbGlicmFyeSBhZGRlZC5cbiAgICovXG4gIHJlYWRvbmx5IFtmaWVsZDogc3RyaW5nXTogdW5rbm93bjtcbn1cblxudHlwZSBKc29uUmVjb3JkID0gUmVjb3JkPHN0cmluZywgSnNvblZhbHVlPjtcblxuaW50ZXJmYWNlIFJlY29yZENoYW5nZSB7XG4gIHJlYWRvbmx5IGtleTogc3RyaW5nO1xuICByZWFkb25seSBsZWFmSWQ6IG51bGwgfCBzdHJpbmc7XG4gIHJlYWRvbmx5IG5ld1ZhbHVlOiBKc29uVmFsdWUgfCB1bmRlZmluZWQ7XG4gIHJlYWRvbmx5IG9sZFZhbHVlOiBKc29uVmFsdWUgfCB1bmRlZmluZWQ7XG4gIHJlYWRvbmx5IHBsdWdpbklkOiBzdHJpbmc7XG59XG5cbmludGVyZmFjZSBXb3Jrc3BhY2VMYXlvdXRTdGF0ZUluc3RhbGxhdGlvbiB7XG4gIHJlYWRvbmx5IG93bmVyOiBXb3Jrc3BhY2VMYXlvdXRTdGF0ZVN1YnNjcmlwdGlvbjtcbiAgcmVhZG9ubHkgdW5pbnN0YWxsOiAoKSA9PiB2b2lkO1xufVxuXG5pbnRlcmZhY2UgV29ya3NwYWNlTGF5b3V0U3RhdGVLZXlJbXBsUGFyYW1zPFQ+IHtcbiAgcmVhZG9ubHkgYXBwOiBBcHA7XG4gIHJlYWRvbmx5IGRlZmF1bHRWYWx1ZTogVDtcbiAgcmVhZG9ubHkgaXNWYWxpZDogKHZhbHVlOiB1bmtub3duKSA9PiB2YWx1ZSBpcyBUO1xuICByZWFkb25seSBrZXk6IHN0cmluZztcbiAgcmVhZG9ubHkgcGx1Z2luSWQ6IHN0cmluZztcbiAgcmVhZG9ubHkgc3Vic2NyaWJlOiAobGlzdGVuZXI6IChjaGFuZ2U6IFJlY29yZENoYW5nZSkgPT4gdm9pZCkgPT4gKCkgPT4gdm9pZDtcbn1cblxuaW50ZXJmYWNlIFdvcmtzcGFjZUxheW91dFN0YXRlU2hhcmVkU3RhdGUge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgdHlwZXNjcmlwdC1kZXYtdG9vbGtpdC9yZWFkb25seS1pbnRlcmZhY2UtbWVtYmVycyAtLSBTdWJzY3JpYmVyIGNoYW5nZXMgcmVwbGFjZSBvciBjbGVhciB0aGUgc2hhcmVkIGluc3RhbGxhdGlvbi5cbiAgaW5zdGFsbGF0aW9uOiBudWxsIHwgV29ya3NwYWNlTGF5b3V0U3RhdGVJbnN0YWxsYXRpb247XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSB0eXBlc2NyaXB0LWRldi10b29sa2l0L3JlYWRvbmx5LWludGVyZmFjZS1tZW1iZXJzIC0tIFNldCBvbmNlIGEgbGF5b3V0IG9yIHRoZSBzYXZlZCBsYXlvdXQgZmlsZSBoYXMgYmVlbiByZWFkLlxuICBpc0h5ZHJhdGVkOiBib29sZWFuO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgdHlwZXNjcmlwdC1kZXYtdG9vbGtpdC9yZWFkb25seS1pbnRlcmZhY2UtbWVtYmVycyAtLSBBIGxheW91dCBsb2FkIHJlcGxhY2VzIHRoZSByZWNvcmRzLlxuICByZWNvcmQ6IFdvcmtzcGFjZUxheW91dFN0YXRlUmVjb3JkO1xuICByZWFkb25seSBzdWJzY3JpcHRpb25zOiBXb3Jrc3BhY2VMYXlvdXRTdGF0ZVN1YnNjcmlwdGlvbltdO1xufVxuXG4vKipcbiAqIEEgc3Vic2NyaWJlciBpbiB0aGUgc2hhcmVkIHN0YXRlLiBUaGUgc2hhcGUgaXMgcGFydCBvZiB0aGUgd2lyZSBmb3JtYXQgYmV0d2VlbiBjb3BpZXM6IGZpZWxkcyBhcmUgb25seSBldmVyIGFkZGVkLlxuICovXG5pbnRlcmZhY2UgV29ya3NwYWNlTGF5b3V0U3RhdGVTdWJzY3JpcHRpb24ge1xuICByZWFkb25seSBpbnN0YWxsOiAoKSA9PiAoKSA9PiB2b2lkO1xuICByZWFkb25seSBvbkxheW91dExvYWQ6ICgpID0+IHZvaWQ7XG4gIHJlYWRvbmx5IG9uUmVjb3JkQ2hhbmdlOiAoY2hhbmdlOiBSZWNvcmRDaGFuZ2UpID0+IHZvaWQ7XG59XG5cbmNsYXNzIFdvcmtzcGFjZUxheW91dFN0YXRlS2V5SW1wbDxUPiBpbXBsZW1lbnRzIFdvcmtzcGFjZUxheW91dFN0YXRlS2V5PFQ+IHtcbiAgcHVibGljIHJlYWRvbmx5IGtleTogc3RyaW5nO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgYXBwOiBBcHA7XG4gIHByaXZhdGUgcmVhZG9ubHkgZGVmYXVsdFZhbHVlOiBUO1xuICBwcml2YXRlIHJlYWRvbmx5IGlzVmFsaWQ6ICh2YWx1ZTogdW5rbm93bikgPT4gdmFsdWUgaXMgVDtcbiAgcHJpdmF0ZSByZWFkb25seSBwbHVnaW5JZDogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IHN1YnNjcmliZTogKGxpc3RlbmVyOiAoY2hhbmdlOiBSZWNvcmRDaGFuZ2UpID0+IHZvaWQpID0+ICgpID0+IHZvaWQ7XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKHBhcmFtczogV29ya3NwYWNlTGF5b3V0U3RhdGVLZXlJbXBsUGFyYW1zPFQ+KSB7XG4gICAgdGhpcy5hcHAgPSBwYXJhbXMuYXBwO1xuICAgIHRoaXMuZGVmYXVsdFZhbHVlID0gcGFyYW1zLmRlZmF1bHRWYWx1ZTtcbiAgICB0aGlzLmlzVmFsaWQgPSBwYXJhbXMuaXNWYWxpZDtcbiAgICB0aGlzLmtleSA9IHBhcmFtcy5rZXk7XG4gICAgdGhpcy5wbHVnaW5JZCA9IHBhcmFtcy5wbHVnaW5JZDtcbiAgICB0aGlzLnN1YnNjcmliZSA9IHBhcmFtcy5zdWJzY3JpYmU7XG4gIH1cblxuICBwdWJsaWMgZ2V0KGxlYWY/OiBXb3Jrc3BhY2VMZWFmKTogVCB7XG4gICAgcmV0dXJuIHRoaXMucmVzb2x2ZShyZWFkUmF3VmFsdWUoZ2V0U2hhcmVkU3RhdGUoKSwgdGhpcy5wbHVnaW5JZCwgdGhpcy5rZXksIGdldExlYWZJZChsZWFmKSkpO1xuICB9XG5cbiAgcHVibGljIGhhcyhsZWFmPzogV29ya3NwYWNlTGVhZik6IGJvb2xlYW4ge1xuICAgIHJldHVybiByZWFkUmF3VmFsdWUoZ2V0U2hhcmVkU3RhdGUoKSwgdGhpcy5wbHVnaW5JZCwgdGhpcy5rZXksIGdldExlYWZJZChsZWFmKSkgIT09IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHB1YmxpYyBvbkNoYW5nZShjYWxsYmFjazogKGNoYW5nZTogV29ya3NwYWNlTGF5b3V0U3RhdGVDaGFuZ2U8VD4pID0+IHZvaWQpOiAoKSA9PiB2b2lkIHtcbiAgICByZXR1cm4gdGhpcy5zdWJzY3JpYmUoKGNoYW5nZSkgPT4ge1xuICAgICAgaWYgKGNoYW5nZS5rZXkgIT09IHRoaXMua2V5KSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNhbGxiYWNrKHtcbiAgICAgICAgbGVhZjogY2hhbmdlLmxlYWZJZCA9PT0gbnVsbCA/IG51bGwgOiB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0TGVhZkJ5SWQoY2hhbmdlLmxlYWZJZCksXG4gICAgICAgIGxlYWZJZDogY2hhbmdlLmxlYWZJZCxcbiAgICAgICAgb2xkVmFsdWU6IHRoaXMucmVzb2x2ZShjaGFuZ2Uub2xkVmFsdWUpLFxuICAgICAgICB2YWx1ZTogdGhpcy5yZXNvbHZlKGNoYW5nZS5uZXdWYWx1ZSlcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIHNldCh2YWx1ZTogVCwgbGVhZj86IFdvcmtzcGFjZUxlYWYpOiB2b2lkIHtcbiAgICBhc3NlcnRKc29uVmFsdWUodmFsdWUpO1xuICAgIHRoaXMud3JpdGUoY2xvbmVKc29uKHZhbHVlKSwgZ2V0TGVhZklkKGxlYWYpKTtcbiAgfVxuXG4gIHB1YmxpYyB1bnNldChsZWFmPzogV29ya3NwYWNlTGVhZik6IHZvaWQge1xuICAgIHRoaXMud3JpdGUodW5kZWZpbmVkLCBnZXRMZWFmSWQobGVhZikpO1xuICB9XG5cbiAgcHJpdmF0ZSByZXNvbHZlKHJhd1ZhbHVlOiBKc29uVmFsdWUgfCB1bmRlZmluZWQpOiBUIHtcbiAgICByZXR1cm4gY2xvbmVKc29uKHJhd1ZhbHVlICE9PSB1bmRlZmluZWQgJiYgdGhpcy5pc1ZhbGlkKHJhd1ZhbHVlKSA/IHJhd1ZhbHVlIDogdGhpcy5kZWZhdWx0VmFsdWUpO1xuICB9XG5cbiAgcHJpdmF0ZSB3cml0ZShuZXdWYWx1ZTogSnNvblZhbHVlIHwgdW5kZWZpbmVkLCBsZWFmSWQ6IG51bGwgfCBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBzdGF0ZSA9IGdldFNoYXJlZFN0YXRlKCk7XG4gICAgY29uc3Qgb2xkVmFsdWUgPSByZWFkUmF3VmFsdWUoc3RhdGUsIHRoaXMucGx1Z2luSWQsIHRoaXMua2V5LCBsZWFmSWQpO1xuICAgIGlmIChKU09OLnN0cmluZ2lmeShvbGRWYWx1ZSkgPT09IEpTT04uc3RyaW5naWZ5KG5ld1ZhbHVlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChuZXdWYWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBBIHN0b3JlZCBvbGQgdmFsdWUgbWVhbnMgdGhlIGJ1Y2tldCBleGlzdHMsIHNvIHRoaXMgY3JlYXRlcyBub3RoaW5nLlxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1keW5hbWljLWRlbGV0ZSAtLSBUaGUgYnVja2V0IGlzIGEgcGxhaW4gcmVjb3JkIGtleWVkIGJ5IHVzZXItY2hvc2VuIG5hbWVzLlxuICAgICAgZGVsZXRlIGVuc3VyZUJ1Y2tldChzdGF0ZSwgdGhpcy5wbHVnaW5JZCwgbGVhZklkKVt0aGlzLmtleV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGVuc3VyZUJ1Y2tldChzdGF0ZSwgdGhpcy5wbHVnaW5JZCwgbGVhZklkKVt0aGlzLmtleV0gPSBuZXdWYWx1ZTtcbiAgICB9XG5cbiAgICB0aGlzLmFwcC53b3Jrc3BhY2UucmVxdWVzdFNhdmVMYXlvdXQoKTtcbiAgICBjb25zdCBjaGFuZ2U6IFJlY29yZENoYW5nZSA9IHsga2V5OiB0aGlzLmtleSwgbGVhZklkLCBuZXdWYWx1ZSwgb2xkVmFsdWUsIHBsdWdpbklkOiB0aGlzLnBsdWdpbklkIH07XG4gICAgZm9yIChjb25zdCBzdWJzY3JpcHRpb24gb2Ygc25hcHNob3Qoc3RhdGUuc3Vic2NyaXB0aW9ucykpIHtcbiAgICAgIHN1YnNjcmlwdGlvbi5vblJlY29yZENoYW5nZShjaGFuZ2UpO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEtlZXBzIGEgcGx1Z2luJ3MgbGF5b3V0LXNjb3BlZCB2YWx1ZXMgaW4gdGhlIHdvcmtzcGFjZSBsYXlvdXQsIHNvIHNhdmVkIHdvcmtzcGFjZXMgZWFjaCByZXN0b3JlIHRoZWlyIG93bi5cbiAqXG4gKiBBbnkgbnVtYmVyIG9mIHRoZXNlLCBpbiBhbnkgbnVtYmVyIG9mIHBsdWdpbnMsIHNoYXJlIG9uZSBpbnN0YWxsYXRpb24gcGVyIHtAbGluayBBcHB9LiBWYWx1ZXMgYXJlIHJlc3RvcmVkIHdoZW4gYVxuICogbGF5b3V0IGxvYWRzLCB3aGljaCBSRVBMQUNFUyBldmVyeSB2YWx1ZTogd3JpdGUgdGhlbSBhZnRlciB7QGxpbmsgV29ya3NwYWNlLm9uTGF5b3V0UmVhZHl9LCBhbmQgcmUtcmVhZCB0aGVtIGluXG4gKiB7QGxpbmsgb25MYXlvdXRMb2FkfS5cbiAqL1xuZXhwb3J0IGNsYXNzIFdvcmtzcGFjZUxheW91dFN0YXRlQ29tcG9uZW50IGV4dGVuZHMgQ29tcG9uZW50RXgge1xuICAvKipcbiAgICogVGhlIE9ic2lkaWFuIGFwcCBpbnN0YW5jZS5cbiAgICovXG4gIHByb3RlY3RlZCByZWFkb25seSBhcHA6IEFwcDtcblxuICAvKipcbiAgICogVGhlIGlkIG9mIHRoZSBwbHVnaW4gdGhlIHZhbHVlcyBiZWxvbmcgdG8uXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgcGx1Z2luSWQ6IHN0cmluZztcblxuICBwcml2YXRlIHJlYWRvbmx5IGxheW91dExvYWRMaXN0ZW5lcnMgPSBuZXcgU2V0PCgpID0+IHZvaWQ+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVjb3JkQ2hhbmdlTGlzdGVuZXJzID0gbmV3IFNldDwoY2hhbmdlOiBSZWNvcmRDaGFuZ2UpID0+IHZvaWQ+KCk7XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgd29ya3NwYWNlIGxheW91dCBzdGF0ZSBjb21wb25lbnQuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgcGFyYW1ldGVycy5cbiAgICogQHRocm93cyBBIGBUeXBlRXJyb3JgIGlmIHRoZSBwbHVnaW4gaWQgaXMgZW1wdHkuXG4gICAqL1xuICBwdWJsaWMgY29uc3RydWN0b3IocGFyYW1zOiBXb3Jrc3BhY2VMYXlvdXRTdGF0ZUNvbXBvbmVudENvbnN0cnVjdG9yUGFyYW1zKSB7XG4gICAgc3VwZXIoKTtcbiAgICBpZiAoIXBhcmFtcy5wbHVnaW5JZCkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIHBsdWdpbiBpZCBtdXN0IG5vdCBiZSBlbXB0eScpO1xuICAgIH1cbiAgICB0aGlzLmFwcCA9IHBhcmFtcy5hcHA7XG4gICAgdGhpcy5wbHVnaW5JZCA9IHBhcmFtcy5wbHVnaW5JZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWZpbmVzIGEgdHlwZWQga2V5LlxuICAgKlxuICAgKiBAdHlwZVBhcmFtIFQgLSBUaGUgdmFsdWUgdHlwZS5cbiAgICogQHBhcmFtIGRlZmluaXRpb24gLSBUaGUga2V5IGRlZmluaXRpb24uXG4gICAqIEByZXR1cm5zIFRoZSBrZXkgaGFuZGxlLlxuICAgKiBAdGhyb3dzIEEgYFR5cGVFcnJvcmAgaWYgdGhlIGtleSBpcyBlbXB0eSBvciB0aGUgZGVmYXVsdCB2YWx1ZSBpcyBub3QgSlNPTi1zYWZlLlxuICAgKi9cbiAgcHVibGljIGRlZmluZUtleTxUPihkZWZpbml0aW9uOiBXb3Jrc3BhY2VMYXlvdXRTdGF0ZUtleURlZmluaXRpb248VD4pOiBXb3Jrc3BhY2VMYXlvdXRTdGF0ZUtleTxUPiB7XG4gICAgaWYgKCFkZWZpbml0aW9uLmtleSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignVGhlIGtleSBtdXN0IG5vdCBiZSBlbXB0eScpO1xuICAgIH1cbiAgICBhc3NlcnRKc29uVmFsdWUoZGVmaW5pdGlvbi5kZWZhdWx0VmFsdWUpO1xuICAgIHJldHVybiBuZXcgV29ya3NwYWNlTGF5b3V0U3RhdGVLZXlJbXBsPFQ+KHtcbiAgICAgIGFwcDogdGhpcy5hcHAsXG4gICAgICBkZWZhdWx0VmFsdWU6IGNsb25lSnNvbihkZWZpbml0aW9uLmRlZmF1bHRWYWx1ZSksXG4gICAgICBpc1ZhbGlkOiBkZWZpbml0aW9uLmlzVmFsaWQgPz8gKChfdmFsdWUpOiBfdmFsdWUgaXMgVCA9PiB0cnVlKSxcbiAgICAgIGtleTogZGVmaW5pdGlvbi5rZXksXG4gICAgICBwbHVnaW5JZDogdGhpcy5wbHVnaW5JZCxcbiAgICAgIHN1YnNjcmliZTogKGxpc3RlbmVyKSA9PiB0aGlzLnN1YnNjcmliZVRvUmVjb3JkQ2hhbmdlcyhsaXN0ZW5lcilcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdWJzY3JpYmVzIHRvIGxheW91dCBsb2FkczogYSBzYXZlZCB3b3Jrc3BhY2UgbG9hZGVkLCB0aGUgbGF5b3V0IHJlc3RvcmVkIGF0IHN0YXJ0dXAsIG9yIHRoZSBzYXZlZCBsYXlvdXQgcmVhZCB3aGVuXG4gICAqIHRoZSBjb21wb25lbnQgaXMgZmlyc3QgbG9hZGVkIGFmdGVyIGxheW91dC1yZWFkeS4gRXZlcnkgdmFsdWUgbWF5IGhhdmUgY2hhbmdlZC5cbiAgICpcbiAgICogQHBhcmFtIGNhbGxiYWNrIC0gQ2FsbGVkIGFmdGVyIHRoZSBsYXlvdXQgaXMgbG9hZGVkLCBvbmNlIGl0cyBsZWF2ZXMgZXhpc3QuXG4gICAqIEByZXR1cm5zIEEgZnVuY3Rpb24gdGhhdCB1bnN1YnNjcmliZXMuIFVubG9hZGluZyB0aGUgY29tcG9uZW50IHVuc3Vic2NyaWJlcyB0b28uXG4gICAqL1xuICBwdWJsaWMgb25MYXlvdXRMb2FkKGNhbGxiYWNrOiAoKSA9PiB2b2lkKTogKCkgPT4gdm9pZCB7XG4gICAgdGhpcy5sYXlvdXRMb2FkTGlzdGVuZXJzLmFkZChjYWxsYmFjayk7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIHRoaXMubGF5b3V0TG9hZExpc3RlbmVycy5kZWxldGUoY2FsbGJhY2spO1xuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogU3Vic2NyaWJlcyB0byB0aGUgc2hhcmVkIGluc3RhbGxhdGlvbiwgaW5zdGFsbGluZyBpdCB3aGVuIG5vYm9keSBoYXMgeWV0LlxuICAgKi9cbiAgcHVibGljIG92ZXJyaWRlIG9ubG9hZCgpOiB2b2lkIHtcbiAgICBzdXBlci5vbmxvYWQoKTtcblxuICAgIGNvbnN0IHN0YXRlID0gZ2V0U2hhcmVkU3RhdGUoKTtcbiAgICBjb25zdCBzdWJzY3JpcHRpb246IFdvcmtzcGFjZUxheW91dFN0YXRlU3Vic2NyaXB0aW9uID0ge1xuICAgICAgaW5zdGFsbDogKCkgPT4gaW5zdGFsbExheW91dFN0YXRlKHRoaXMuYXBwLCBzdGF0ZSksXG4gICAgICBvbkxheW91dExvYWQ6ICgpID0+IHtcbiAgICAgICAgZm9yIChjb25zdCBsaXN0ZW5lciBvZiBzbmFwc2hvdCh0aGlzLmxheW91dExvYWRMaXN0ZW5lcnMpKSB7XG4gICAgICAgICAgaW52b2tlTGlzdGVuZXIobGlzdGVuZXIpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgb25SZWNvcmRDaGFuZ2U6IChjaGFuZ2UpID0+IHtcbiAgICAgICAgaWYgKGNoYW5nZS5wbHVnaW5JZCAhPT0gdGhpcy5wbHVnaW5JZCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGNvbnN0IGxpc3RlbmVyIG9mIHNuYXBzaG90KHRoaXMucmVjb3JkQ2hhbmdlTGlzdGVuZXJzKSkge1xuICAgICAgICAgIGludm9rZUxpc3RlbmVyKCgpID0+IHtcbiAgICAgICAgICAgIGxpc3RlbmVyKGNoYW5nZSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuICAgIHN0YXRlLnN1YnNjcmlwdGlvbnMucHVzaChzdWJzY3JpcHRpb24pO1xuICAgIHN0YXRlLmluc3RhbGxhdGlvbiA/Pz0geyBvd25lcjogc3Vic2NyaXB0aW9uLCB1bmluc3RhbGw6IHN1YnNjcmlwdGlvbi5pbnN0YWxsKCkgfTtcblxuICAgIHRoaXMucmVnaXN0ZXIoKCkgPT4ge1xuICAgICAgdGhpcy5sYXlvdXRMb2FkTGlzdGVuZXJzLmNsZWFyKCk7XG4gICAgICB0aGlzLnJlY29yZENoYW5nZUxpc3RlbmVycy5jbGVhcigpO1xuICAgICAgc3RhdGUuc3Vic2NyaXB0aW9ucy5zcGxpY2Uoc3RhdGUuc3Vic2NyaXB0aW9ucy5pbmRleE9mKHN1YnNjcmlwdGlvbiksIDEpO1xuICAgICAgaWYgKHN0YXRlLmluc3RhbGxhdGlvbj8ub3duZXIgIT09IHN1YnNjcmlwdGlvbikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHN0YXRlLmluc3RhbGxhdGlvbi51bmluc3RhbGwoKTtcbiAgICAgIGNvbnN0IG5leHRPd25lciA9IHN0YXRlLnN1YnNjcmlwdGlvbnNbMF07XG4gICAgICBzdGF0ZS5pbnN0YWxsYXRpb24gPSBuZXh0T3duZXIgPyB7IG93bmVyOiBuZXh0T3duZXIsIHVuaW5zdGFsbDogbmV4dE93bmVyLmluc3RhbGwoKSB9IDogbnVsbDtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc3Vic2NyaWJlVG9SZWNvcmRDaGFuZ2VzKGxpc3RlbmVyOiAoY2hhbmdlOiBSZWNvcmRDaGFuZ2UpID0+IHZvaWQpOiAoKSA9PiB2b2lkIHtcbiAgICB0aGlzLnJlY29yZENoYW5nZUxpc3RlbmVycy5hZGQobGlzdGVuZXIpO1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICB0aGlzLnJlY29yZENoYW5nZUxpc3RlbmVycy5kZWxldGUobGlzdGVuZXIpO1xuICAgIH07XG4gIH1cbn1cblxuLyoqXG4gKiBQYXJzZXMgYSBwZXJzaXN0ZWQgcmVjb3JkLiBBIHBhcnQgdGhhdCBpcyBtYWxmb3JtZWQgaXMgZHJvcHBlZCBvbmUgbGV2ZWwgYXQgYSB0aW1lOiBhIG1hbGZvcm1lZCByZWNvcmQgcmVhZHMgYXNcbiAqIGVtcHR5LCBhIG1hbGZvcm1lZCBwbHVnaW4gcmVjb3JkIGRyb3BzIG9ubHkgdGhhdCBwbHVnaW4sIGFuZCBhIG1hbGZvcm1lZCBsZWFmIGJ1Y2tldCBkcm9wcyBvbmx5IHRoYXQgbGVhZi4gRmllbGRzIHRoaXNcbiAqIGNvcHkgZG9lcyBub3Qga25vdyBhcmUga2VwdC5cbiAqXG4gKiBAcGFyYW0gdmFsdWUgLSBUaGUgdmFsdWUgZm91bmQgdW5kZXIge0BsaW5rIFdPUktTUEFDRV9MQVlPVVRfU1RBVEVfTEFZT1VUX0tFWX0uXG4gKiBAcmV0dXJucyBUaGUgcGFyc2VkIHJlY29yZCwgc2hhcmluZyBub3RoaW5nIHdpdGggdGhlIGlucHV0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VXb3Jrc3BhY2VMYXlvdXRTdGF0ZVJlY29yZCh2YWx1ZTogdW5rbm93bik6IFdvcmtzcGFjZUxheW91dFN0YXRlUmVjb3JkIHtcbiAgaWYgKCFpc0pzb25PYmplY3QodmFsdWUpKSB7XG4gICAgcmV0dXJuIHsgcGx1Z2luczoge30gfTtcbiAgfVxuXG4gIGNvbnN0IHBsdWdpbnM6IFJlY29yZDxzdHJpbmcsIFdvcmtzcGFjZUxheW91dFN0YXRlUGx1Z2luUmVjb3JkPiA9IHt9O1xuICBjb25zdCByYXdQbHVnaW5zID0gdmFsdWVbJ3BsdWdpbnMnXTtcbiAgaWYgKGlzSnNvbk9iamVjdChyYXdQbHVnaW5zKSkge1xuICAgIGZvciAoY29uc3QgW3BsdWdpbklkLCByYXdQbHVnaW5SZWNvcmRdIG9mIE9iamVjdC5lbnRyaWVzKHJhd1BsdWdpbnMpKSB7XG4gICAgICBjb25zdCBwbHVnaW5SZWNvcmQgPSBwYXJzZVBsdWdpblJlY29yZChyYXdQbHVnaW5SZWNvcmQpO1xuICAgICAgaWYgKHBsdWdpblJlY29yZCkge1xuICAgICAgICBwbHVnaW5zW3BsdWdpbklkXSA9IHBsdWdpblJlY29yZDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4geyAuLi5jbG9uZUpzb24odmFsdWUpLCBwbHVnaW5zIH07XG59XG5cbi8qKlxuICogQnVpbGRzIHRoZSByZWNvcmQgdG8gcGVyc2lzdCBpbnRvIGEgc2VyaWFsaXplZCBsYXlvdXQ6IGxlYWYgYnVja2V0cyBmb3IgbGVhdmVzIGFic2VudCBmcm9tIHRoZSBsYXlvdXQgYXJlIGxlZnQgb3V0LFxuICogYW5kIHNvIGFyZSBwbHVnaW5zIHdpdGggbm90aGluZyBsZWZ0LlxuICpcbiAqIEBwYXJhbSByZWNvcmQgLSBUaGUgY3VycmVudCByZWNvcmQuXG4gKiBAcGFyYW0gbGF5b3V0IC0gVGhlIHNlcmlhbGl6ZWQgbGF5b3V0LlxuICogQHJldHVybnMgVGhlIHJlY29yZCB0byBwZXJzaXN0LCBvciBgbnVsbGAgd2hlbiB0aGVyZSBpcyBub3RoaW5nIHRvIHBlcnNpc3QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXJpYWxpemVXb3Jrc3BhY2VMYXlvdXRTdGF0ZVJlY29yZChyZWNvcmQ6IFdvcmtzcGFjZUxheW91dFN0YXRlUmVjb3JkLCBsYXlvdXQ6IHVua25vd24pOiBudWxsIHwgV29ya3NwYWNlTGF5b3V0U3RhdGVSZWNvcmQge1xuICBjb25zdCBsZWFmSWRzID0gY29sbGVjdExlYWZJZHMobGF5b3V0KTtcbiAgY29uc3Qgc2VyaWFsaXplZCA9IGNsb25lSnNvbihyZWNvcmQpO1xuICBjb25zdCBwbHVnaW5zID0gc2VyaWFsaXplZC5wbHVnaW5zO1xuICBmb3IgKGNvbnN0IFtwbHVnaW5JZCwgcGx1Z2luUmVjb3JkXSBvZiBPYmplY3QuZW50cmllcyhwbHVnaW5zKSkge1xuICAgIGZvciAoY29uc3QgW2xlYWZJZCwgYnVja2V0XSBvZiBPYmplY3QuZW50cmllcyhwbHVnaW5SZWNvcmQubGVhdmVzKSkge1xuICAgICAgaWYgKCFsZWFmSWRzLmhhcyhsZWFmSWQpIHx8IE9iamVjdC5rZXlzKGJ1Y2tldCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZHluYW1pYy1kZWxldGUgLS0gTGVhZiBpZHMgYXJlIHJlY29yZCBrZXlzLlxuICAgICAgICBkZWxldGUgcGx1Z2luUmVjb3JkLmxlYXZlc1tsZWFmSWRdO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBpc0VtcHR5ID0gT2JqZWN0LmtleXMocGx1Z2luUmVjb3JkLndvcmtzcGFjZSkubGVuZ3RoID09PSAwICYmIE9iamVjdC5rZXlzKHBsdWdpblJlY29yZC5sZWF2ZXMpLmxlbmd0aCA9PT0gMFxuICAgICAgJiYgT2JqZWN0LmtleXMocGx1Z2luUmVjb3JkKS5sZW5ndGggPT09IEtOT1dOX1BMVUdJTl9SRUNPUkRfRklFTERfQ09VTlQ7XG4gICAgaWYgKGlzRW1wdHkpIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZHluYW1pYy1kZWxldGUgLS0gUGx1Z2luIGlkcyBhcmUgcmVjb3JkIGtleXMuXG4gICAgICBkZWxldGUgcGx1Z2luc1twbHVnaW5JZF07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIE9iamVjdC5rZXlzKHBsdWdpbnMpLmxlbmd0aCA9PT0gMCAmJiBPYmplY3Qua2V5cyhzZXJpYWxpemVkKS5sZW5ndGggPT09IDEgPyBudWxsIDogc2VyaWFsaXplZDtcbn1cblxuZnVuY3Rpb24gYXNzZXJ0SnNvblZhbHVlKHZhbHVlOiB1bmtub3duKTogYXNzZXJ0cyB2YWx1ZSBpcyBKc29uVmFsdWUge1xuICBpZiAoIWlzRGF0YVN0b3JlSnNvblZhbHVlKHZhbHVlKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0Egd29ya3NwYWNlIGxheW91dCBzdGF0ZSB2YWx1ZSBtdXN0IGJlIEpTT04tc2FmZScpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNsb25lSnNvbjxUPih2YWx1ZTogVCk6IFQge1xuICByZXR1cm4gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh2YWx1ZSkgYXMgc3RyaW5nKSBhcyBUO1xufVxuXG5mdW5jdGlvbiBjb2xsZWN0TGVhZklkcyhsYXlvdXQ6IHVua25vd24pOiBTZXQ8c3RyaW5nPiB7XG4gIGNvbnN0IGxlYWZJZHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgZnVuY3Rpb24gdmlzaXQoaXRlbTogdW5rbm93bik6IHZvaWQge1xuICAgIGlmICghaXNQbGFpblJlY29yZChpdGVtKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBpZCA9IGl0ZW1bJ2lkJ107XG4gICAgaWYgKGl0ZW1bJ3R5cGUnXSA9PT0gJ2xlYWYnICYmIHR5cGVvZiBpZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGxlYWZJZHMuYWRkKGlkKTtcbiAgICB9XG4gICAgY29uc3QgY2hpbGRyZW4gPSBpdGVtWydjaGlsZHJlbiddO1xuICAgIGlmIChBcnJheS5pc0FycmF5KGNoaWxkcmVuKSkge1xuICAgICAgZm9yIChjb25zdCBjaGlsZCBvZiBjaGlsZHJlbikge1xuICAgICAgICB2aXNpdChjaGlsZCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKGlzUGxhaW5SZWNvcmQobGF5b3V0KSkge1xuICAgIGZvciAoY29uc3Qgcm9vdEtleSBvZiBbJ21haW4nLCAnbGVmdCcsICdyaWdodCcsICdmbG9hdGluZyddKSB7XG4gICAgICB2aXNpdChsYXlvdXRbcm9vdEtleV0pO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbGVhZklkcztcbn1cblxuZnVuY3Rpb24gZW5zdXJlQnVja2V0KHN0YXRlOiBXb3Jrc3BhY2VMYXlvdXRTdGF0ZVNoYXJlZFN0YXRlLCBwbHVnaW5JZDogc3RyaW5nLCBsZWFmSWQ6IG51bGwgfCBzdHJpbmcpOiBKc29uUmVjb3JkIHtcbiAgY29uc3QgcGx1Z2luUmVjb3JkID0gc3RhdGUucmVjb3JkLnBsdWdpbnNbcGx1Z2luSWRdID8/IHsgbGVhdmVzOiB7fSwgd29ya3NwYWNlOiB7fSB9O1xuICBzdGF0ZS5yZWNvcmQucGx1Z2luc1twbHVnaW5JZF0gPSBwbHVnaW5SZWNvcmQ7XG4gIGlmIChsZWFmSWQgPT09IG51bGwpIHtcbiAgICByZXR1cm4gcGx1Z2luUmVjb3JkLndvcmtzcGFjZTtcbiAgfVxuXG4gIGNvbnN0IGJ1Y2tldCA9IHBsdWdpblJlY29yZC5sZWF2ZXNbbGVhZklkXSA/PyB7fTtcbiAgcGx1Z2luUmVjb3JkLmxlYXZlc1tsZWFmSWRdID0gYnVja2V0O1xuICByZXR1cm4gYnVja2V0O1xufVxuXG5mdW5jdGlvbiBnZXRCdWNrZXQoc3RhdGU6IFdvcmtzcGFjZUxheW91dFN0YXRlU2hhcmVkU3RhdGUsIHBsdWdpbklkOiBzdHJpbmcsIGxlYWZJZDogbnVsbCB8IHN0cmluZyk6IEpzb25SZWNvcmQgfCBudWxsIHtcbiAgY29uc3QgcGx1Z2luUmVjb3JkID0gc3RhdGUucmVjb3JkLnBsdWdpbnNbcGx1Z2luSWRdO1xuICBpZiAoIXBsdWdpblJlY29yZCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHJldHVybiBsZWFmSWQgPT09IG51bGwgPyBwbHVnaW5SZWNvcmQud29ya3NwYWNlIDogcGx1Z2luUmVjb3JkLmxlYXZlc1tsZWFmSWRdID8/IG51bGw7XG59XG5cbmZ1bmN0aW9uIGdldExheW91dFJlY29yZFZhbHVlKGxheW91dDogdW5rbm93bik6IHVua25vd24ge1xuICByZXR1cm4gaXNQbGFpblJlY29yZChsYXlvdXQpID8gbGF5b3V0W1dPUktTUEFDRV9MQVlPVVRfU1RBVEVfTEFZT1VUX0tFWV0gOiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGdldExlYWZJZChsZWFmOiB1bmRlZmluZWQgfCBXb3Jrc3BhY2VMZWFmKTogbnVsbCB8IHN0cmluZyB7XG4gIHJldHVybiBsZWFmID8gbGVhZi5pZCA6IG51bGw7XG59XG5cbmZ1bmN0aW9uIGdldFNoYXJlZFN0YXRlKCk6IFdvcmtzcGFjZUxheW91dFN0YXRlU2hhcmVkU3RhdGUge1xuICByZXR1cm4gZ2V0T2JzaWRpYW5MaWJTdGF0ZTxXb3Jrc3BhY2VMYXlvdXRTdGF0ZVNoYXJlZFN0YXRlPihTSEFSRURfU1RBVEVfS0VZLCB7XG4gICAgaW5zdGFsbGF0aW9uOiBudWxsLFxuICAgIGlzSHlkcmF0ZWQ6IGZhbHNlLFxuICAgIHJlY29yZDogeyBwbHVnaW5zOiB7fSB9LFxuICAgIHN1YnNjcmlwdGlvbnM6IFtdXG4gIH0pLnZhbHVlO1xufVxuXG5mdW5jdGlvbiBpbnN0YWxsTGF5b3V0U3RhdGUoYXBwOiBBcHAsIHN0YXRlOiBXb3Jrc3BhY2VMYXlvdXRTdGF0ZVNoYXJlZFN0YXRlKTogKCkgPT4gdm9pZCB7XG4gIGxldCBpc1VuaW5zdGFsbGVkID0gZmFsc2U7XG4gIGNvbnN0IHVuaW5zdGFsbFBhdGNoID0gYXJvdW5kKGFwcC53b3Jrc3BhY2UsIHtcbiAgICBnZXRMYXlvdXQ6IChuZXh0KSA9PlxuICAgICAgZnVuY3Rpb24gcGF0Y2hlZEdldExheW91dCh0aGlzOiBXb3Jrc3BhY2UpOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gICAgICAgIGNvbnN0IGxheW91dCA9IG5leHQuY2FsbCh0aGlzKTtcbiAgICAgICAgY29uc3QgcmVjb3JkID0gc2VyaWFsaXplV29ya3NwYWNlTGF5b3V0U3RhdGVSZWNvcmQoc3RhdGUucmVjb3JkLCBsYXlvdXQpO1xuICAgICAgICBpZiAocmVjb3JkKSB7XG4gICAgICAgICAgbGF5b3V0W1dPUktTUEFDRV9MQVlPVVRfU1RBVEVfTEFZT1VUX0tFWV0gPSByZWNvcmQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGxheW91dDtcbiAgICAgIH0sXG4gICAgc2V0TGF5b3V0OiAobmV4dCkgPT5cbiAgICAgIGFzeW5jIGZ1bmN0aW9uIHBhdGNoZWRTZXRMYXlvdXQodGhpczogV29ya3NwYWNlLCBsYXlvdXQ6IFBhcmFtZXRlcnM8V29ya3NwYWNlWydzZXRMYXlvdXQnXT5bMF0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgc3RhdGUucmVjb3JkID0gcGFyc2VXb3Jrc3BhY2VMYXlvdXRTdGF0ZVJlY29yZChnZXRMYXlvdXRSZWNvcmRWYWx1ZShsYXlvdXQpKTtcbiAgICAgICAgc3RhdGUuaXNIeWRyYXRlZCA9IHRydWU7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgbmV4dC5jYWxsKHRoaXMsIGxheW91dCk7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgbm90aWZ5TGF5b3V0TG9hZChzdGF0ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgfSk7XG5cbiAgaWYgKCFzdGF0ZS5pc0h5ZHJhdGVkICYmIGFwcC53b3Jrc3BhY2UubGF5b3V0UmVhZHkpIHtcbiAgICAvLyBMb2FkZWQgYWZ0ZXIgdGhlIGxheW91dDogcmVhZCB0aGUgbGF5b3V0IHRoZSBsYXN0IGluc3RhbGxhdGlvbiBzYXZlZCwgb25jZSwga2VlcGluZyB3aGF0IHdhcyBzZXQgbWVhbndoaWxlLlxuICAgIGludm9rZUFzeW5jU2FmZWx5KGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHNhdmVkID0gYXdhaXQgYXBwLndvcmtzcGFjZS5yZWFkV29ya3NwYWNlRmlsZSgpO1xuICAgICAgaWYgKGlzVW5pbnN0YWxsZWQgfHwgc3RhdGUuaXNIeWRyYXRlZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBtZXJnZU1pc3Npbmcoc3RhdGUucmVjb3JkLCBwYXJzZVdvcmtzcGFjZUxheW91dFN0YXRlUmVjb3JkKGdldExheW91dFJlY29yZFZhbHVlKHNhdmVkKSkpO1xuICAgICAgc3RhdGUuaXNIeWRyYXRlZCA9IHRydWU7XG4gICAgICBub3RpZnlMYXlvdXRMb2FkKHN0YXRlKTtcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiAoKSA9PiB7XG4gICAgaXNVbmluc3RhbGxlZCA9IHRydWU7XG4gICAgdW5pbnN0YWxsUGF0Y2goKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gaW52b2tlTGlzdGVuZXIobGlzdGVuZXI6ICgpID0+IHZvaWQpOiB2b2lkIHtcbiAgdHJ5IHtcbiAgICBsaXN0ZW5lcigpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGNvbnNvbGUuZXJyb3IoJ0Egd29ya3NwYWNlIGxheW91dCBzdGF0ZSBsaXN0ZW5lciBmYWlsZWQnLCBlcnJvcik7XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNKc29uT2JqZWN0KHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgSnNvbk9iamVjdCB7XG4gIHJldHVybiBpc1BsYWluUmVjb3JkKHZhbHVlKSAmJiBpc0RhdGFTdG9yZUpzb25WYWx1ZSh2YWx1ZSk7XG59XG5cbmZ1bmN0aW9uIGlzUGxhaW5SZWNvcmQodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsICYmICFBcnJheS5pc0FycmF5KHZhbHVlKTtcbn1cblxuZnVuY3Rpb24gbWVyZ2VNaXNzaW5nKHRhcmdldDogV29ya3NwYWNlTGF5b3V0U3RhdGVSZWNvcmQsIHNvdXJjZTogV29ya3NwYWNlTGF5b3V0U3RhdGVSZWNvcmQpOiB2b2lkIHtcbiAgZm9yIChjb25zdCBbcGx1Z2luSWQsIHNvdXJjZVBsdWdpbl0gb2YgT2JqZWN0LmVudHJpZXMoc291cmNlLnBsdWdpbnMpKSB7XG4gICAgY29uc3QgdGFyZ2V0UGx1Z2luID0gdGFyZ2V0LnBsdWdpbnNbcGx1Z2luSWRdO1xuICAgIGlmICghdGFyZ2V0UGx1Z2luKSB7XG4gICAgICB0YXJnZXQucGx1Z2luc1twbHVnaW5JZF0gPSBzb3VyY2VQbHVnaW47XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoc291cmNlUGx1Z2luLndvcmtzcGFjZSkpIHtcbiAgICAgIHRhcmdldFBsdWdpbi53b3Jrc3BhY2Vba2V5XSA/Pz0gdmFsdWU7XG4gICAgfVxuICAgIGZvciAoY29uc3QgW2xlYWZJZCwgYnVja2V0XSBvZiBPYmplY3QuZW50cmllcyhzb3VyY2VQbHVnaW4ubGVhdmVzKSkge1xuICAgICAgdGFyZ2V0UGx1Z2luLmxlYXZlc1tsZWFmSWRdID8/PSBidWNrZXQ7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIG5vdGlmeUxheW91dExvYWQoc3RhdGU6IFdvcmtzcGFjZUxheW91dFN0YXRlU2hhcmVkU3RhdGUpOiB2b2lkIHtcbiAgZm9yIChjb25zdCBzdWJzY3JpcHRpb24gb2Ygc25hcHNob3Qoc3RhdGUuc3Vic2NyaXB0aW9ucykpIHtcbiAgICBzdWJzY3JpcHRpb24ub25MYXlvdXRMb2FkKCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcGFyc2VQbHVnaW5SZWNvcmQodmFsdWU6IHVua25vd24pOiBudWxsIHwgV29ya3NwYWNlTGF5b3V0U3RhdGVQbHVnaW5SZWNvcmQge1xuICBpZiAoIWlzSnNvbk9iamVjdCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IGxlYXZlczogUmVjb3JkPHN0cmluZywgSnNvblJlY29yZD4gPSB7fTtcbiAgY29uc3QgcmF3TGVhdmVzID0gdmFsdWVbJ2xlYXZlcyddO1xuICBpZiAoaXNKc29uT2JqZWN0KHJhd0xlYXZlcykpIHtcbiAgICBmb3IgKGNvbnN0IFtsZWFmSWQsIGJ1Y2tldF0gb2YgT2JqZWN0LmVudHJpZXMocmF3TGVhdmVzKSkge1xuICAgICAgaWYgKGlzSnNvbk9iamVjdChidWNrZXQpKSB7XG4gICAgICAgIGxlYXZlc1tsZWFmSWRdID0gY2xvbmVKc29uPEpzb25SZWNvcmQ+KGJ1Y2tldCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29uc3QgcmF3V29ya3NwYWNlID0gdmFsdWVbJ3dvcmtzcGFjZSddO1xuICByZXR1cm4ge1xuICAgIC4uLmNsb25lSnNvbih2YWx1ZSksXG4gICAgbGVhdmVzLFxuICAgIHdvcmtzcGFjZTogaXNKc29uT2JqZWN0KHJhd1dvcmtzcGFjZSkgPyBjbG9uZUpzb248SnNvblJlY29yZD4ocmF3V29ya3NwYWNlKSA6IHt9XG4gIH07XG59XG5cbmZ1bmN0aW9uIHJlYWRSYXdWYWx1ZShzdGF0ZTogV29ya3NwYWNlTGF5b3V0U3RhdGVTaGFyZWRTdGF0ZSwgcGx1Z2luSWQ6IHN0cmluZywga2V5OiBzdHJpbmcsIGxlYWZJZDogbnVsbCB8IHN0cmluZyk6IEpzb25WYWx1ZSB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiBnZXRCdWNrZXQoc3RhdGUsIHBsdWdpbklkLCBsZWFmSWQpPy5ba2V5XTtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQXFDQSxtQkFBeUI7QUFDekIsbUJBQWtDO0FBRWxDLGdDQUFxQztBQUNyQyxnQ0FBb0M7QUFDcEMsMEJBQTRCO0FBQzVCLHFDQUF1QjtBQUtoQixNQUFNLG9DQUFvQztBQUVqRCxNQUFNLG1CQUFtQjtBQUt6QixNQUFNLGtDQUFrQztBQTBNeEMsTUFBTSw0QkFBcUU7QUFBQSxFQUN6RDtBQUFBLEVBRUM7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFFVixZQUFZLFFBQThDO0FBQy9ELFNBQUssTUFBTSxPQUFPO0FBQ2xCLFNBQUssZUFBZSxPQUFPO0FBQzNCLFNBQUssVUFBVSxPQUFPO0FBQ3RCLFNBQUssTUFBTSxPQUFPO0FBQ2xCLFNBQUssV0FBVyxPQUFPO0FBQ3ZCLFNBQUssWUFBWSxPQUFPO0FBQUEsRUFDMUI7QUFBQSxFQUVPLElBQUksTUFBeUI7QUFDbEMsV0FBTyxLQUFLLFFBQVEsYUFBYSxlQUFlLEdBQUcsS0FBSyxVQUFVLEtBQUssS0FBSyxVQUFVLElBQUksQ0FBQyxDQUFDO0FBQUEsRUFDOUY7QUFBQSxFQUVPLElBQUksTUFBK0I7QUFDeEMsV0FBTyxhQUFhLGVBQWUsR0FBRyxLQUFLLFVBQVUsS0FBSyxLQUFLLFVBQVUsSUFBSSxDQUFDLE1BQU07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
|