@mnaoumov/obsidian-lib 10.5.1 → 10.7.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/codemirror/inline-token-widgets/package.json +6 -0
- package/codemirror/settings-facet/package.json +6 -0
- package/command-handlers/open-discussion-command-handler/package.json +6 -0
- package/command-handlers/open-feature-request-command-handler/package.json +6 -0
- package/command-handlers/open-git-hub-command-handler/package.json +6 -0
- package/components/settings-facet-component/package.json +6 -0
- package/components/style-sheet-component/package.json +6 -0
- package/dist/lib/cjs/__merged.cjs +137 -1
- package/dist/lib/cjs/__merged.d.cts +26 -0
- package/dist/lib/cjs/anchored-suggest.cjs +232 -0
- package/dist/lib/cjs/anchored-suggest.d.cts +116 -0
- package/dist/lib/cjs/broken-link-candidates.cjs +366 -0
- package/dist/lib/cjs/broken-link-candidates.d.cts +181 -0
- package/dist/lib/cjs/bug-report.cjs +4 -2
- package/dist/lib/cjs/bug-report.d.cts +1 -1
- package/dist/lib/cjs/code-block-render-handoff.cjs +272 -0
- package/dist/lib/cjs/code-block-render-handoff.d.cts +131 -0
- package/dist/lib/cjs/codemirror/index.cjs +7 -1
- package/dist/lib/cjs/codemirror/index.d.cts +2 -0
- package/dist/lib/cjs/codemirror/inline-token-widgets.cjs +250 -0
- package/dist/lib/cjs/codemirror/inline-token-widgets.d.cts +109 -0
- package/dist/lib/cjs/codemirror/settings-facet.cjs +132 -0
- package/dist/lib/cjs/codemirror/settings-facet.d.cts +19 -0
- package/dist/lib/cjs/command-handlers/index.cjs +10 -1
- package/dist/lib/cjs/command-handlers/index.d.cts +3 -0
- package/dist/lib/cjs/command-handlers/open-bug-report-command-handler.cjs +9 -12
- package/dist/lib/cjs/command-handlers/open-bug-report-command-handler.d.cts +6 -8
- package/dist/lib/cjs/command-handlers/open-discussion-command-handler.cjs +127 -0
- package/dist/lib/cjs/command-handlers/open-discussion-command-handler.d.cts +45 -0
- package/dist/lib/cjs/command-handlers/open-feature-request-command-handler.cjs +119 -0
- package/dist/lib/cjs/command-handlers/open-feature-request-command-handler.d.cts +33 -0
- package/dist/lib/cjs/command-handlers/open-git-hub-command-handler.cjs +121 -0
- package/dist/lib/cjs/command-handlers/open-git-hub-command-handler.d.cts +43 -0
- package/dist/lib/cjs/components/index.cjs +7 -1
- package/dist/lib/cjs/components/index.d.cts +2 -0
- package/dist/lib/cjs/components/settings-facet-component.cjs +136 -0
- package/dist/lib/cjs/components/settings-facet-component.d.cts +68 -0
- package/dist/lib/cjs/components/style-sheet-component.cjs +198 -0
- package/dist/lib/cjs/components/style-sheet-component.d.cts +79 -0
- package/dist/lib/cjs/css-class.cjs +8 -1
- package/dist/lib/cjs/css-class.d.cts +28 -0
- package/dist/lib/cjs/data-stores/data-store-transport.cjs +7 -4
- package/dist/lib/cjs/data-stores/data-store-transport.d.cts +1 -1
- package/dist/lib/cjs/data-stores/shared-data-store.cjs +1 -1
- package/dist/lib/cjs/data-stores/shared-data-store.d.cts +1 -1
- package/dist/lib/cjs/desktop-git-runner.cjs +117 -0
- package/dist/lib/cjs/desktop-git-runner.d.cts +17 -0
- package/dist/lib/cjs/desktop-request-url-stream.cjs +258 -0
- package/dist/lib/cjs/desktop-request-url-stream.d.cts +22 -0
- package/dist/lib/cjs/editor-suggest-registrar.cjs +8 -2
- package/dist/lib/cjs/editor-suggest-registrar.d.cts +14 -2
- package/dist/lib/cjs/editor-suggest.cjs +197 -0
- package/dist/lib/cjs/editor-suggest.d.cts +103 -0
- package/dist/lib/cjs/feature-request.cjs +115 -0
- package/dist/lib/cjs/feature-request.d.cts +54 -0
- package/dist/lib/cjs/generated-during-build.cjs +2 -2
- package/dist/lib/cjs/git-hub-discussion.cjs +101 -0
- package/dist/lib/cjs/git-hub-discussion.d.cts +28 -0
- package/dist/lib/cjs/git-rename-history.cjs +148 -0
- package/dist/lib/cjs/git-rename-history.d.cts +43 -0
- package/dist/lib/cjs/hotkey.cjs +185 -0
- package/dist/lib/cjs/hotkey.d.cts +59 -0
- package/dist/lib/cjs/i18n/locales/en.cjs +13 -1
- package/dist/lib/cjs/i18n/locales/en.d.cts +12 -0
- package/dist/lib/cjs/i18n/locales/translations-map.d.cts +12 -0
- package/dist/lib/cjs/index.cjs +46 -1
- package/dist/lib/cjs/index.d.cts +15 -0
- package/dist/lib/cjs/inline-token-renderer.cjs +145 -0
- package/dist/lib/cjs/inline-token-renderer.d.cts +88 -0
- package/dist/lib/cjs/link-and-tag-input-suggest.cjs +325 -0
- package/dist/lib/cjs/link-and-tag-input-suggest.d.cts +229 -0
- package/dist/lib/cjs/markdown-code-block-processor.cjs +13 -1
- package/dist/lib/cjs/markdown-code-block-processor.d.cts +18 -0
- package/dist/lib/cjs/markdown.cjs +6 -1
- package/dist/lib/cjs/markdown.d.cts +10 -1
- package/dist/lib/cjs/rendered-markdown.cjs +306 -0
- package/dist/lib/cjs/rendered-markdown.d.cts +77 -0
- package/dist/lib/cjs/request-url.cjs +523 -0
- package/dist/lib/cjs/request-url.d.cts +233 -0
- package/dist/lib/cjs/setting-components/folder-list-component.cjs +216 -0
- package/dist/lib/cjs/setting-components/folder-list-component.d.cts +73 -0
- package/dist/lib/cjs/setting-components/hotkey-component.cjs +260 -0
- package/dist/lib/cjs/setting-components/hotkey-component.d.cts +85 -0
- package/dist/lib/cjs/setting-components/index.cjs +13 -1
- package/dist/lib/cjs/setting-components/index.d.cts +4 -0
- package/dist/lib/cjs/setting-components/list-component.cjs +291 -0
- package/dist/lib/cjs/setting-components/list-component.d.cts +106 -0
- package/dist/lib/cjs/setting-components/tag-list-component.cjs +220 -0
- package/dist/lib/cjs/setting-components/tag-list-component.d.cts +82 -0
- package/dist/lib/cjs/setting-ex.cjs +51 -1
- package/dist/lib/cjs/setting-ex.d.cts +35 -1
- package/dist/lib/cjs/settings-tabs.cjs +258 -0
- package/dist/lib/cjs/settings-tabs.d.cts +101 -0
- package/dist/lib/cjs/vault.cjs +2 -2
- package/dist/lib/cjs/vault.d.cts +3 -1
- package/dist/lib/esm/__merged.d.mts +26 -0
- package/dist/lib/esm/__merged.mjs +139 -1
- package/dist/lib/esm/anchored-suggest.d.mts +116 -0
- package/dist/lib/esm/anchored-suggest.mjs +144 -0
- package/dist/lib/esm/broken-link-candidates.d.mts +181 -0
- package/dist/lib/esm/broken-link-candidates.mjs +275 -0
- package/dist/lib/esm/bug-report.d.mts +1 -1
- package/dist/lib/esm/bug-report.mjs +4 -2
- package/dist/lib/esm/code-block-render-handoff.d.mts +131 -0
- package/dist/lib/esm/code-block-render-handoff.mjs +183 -0
- package/dist/lib/esm/codemirror/index.d.mts +2 -0
- package/dist/lib/esm/codemirror/index.mjs +5 -1
- package/dist/lib/esm/codemirror/inline-token-widgets.d.mts +109 -0
- package/dist/lib/esm/codemirror/inline-token-widgets.mjs +167 -0
- package/dist/lib/esm/codemirror/settings-facet.d.mts +19 -0
- package/dist/lib/esm/codemirror/settings-facet.mjs +44 -0
- package/dist/lib/esm/command-handlers/index.d.mts +3 -0
- package/dist/lib/esm/command-handlers/index.mjs +7 -1
- package/dist/lib/esm/command-handlers/open-bug-report-command-handler.d.mts +6 -8
- package/dist/lib/esm/command-handlers/open-bug-report-command-handler.mjs +9 -12
- package/dist/lib/esm/command-handlers/open-discussion-command-handler.d.mts +45 -0
- package/dist/lib/esm/command-handlers/open-discussion-command-handler.mjs +39 -0
- package/dist/lib/esm/command-handlers/open-feature-request-command-handler.d.mts +33 -0
- package/dist/lib/esm/command-handlers/open-feature-request-command-handler.mjs +31 -0
- package/dist/lib/esm/command-handlers/open-git-hub-command-handler.d.mts +43 -0
- package/dist/lib/esm/command-handlers/open-git-hub-command-handler.mjs +33 -0
- package/dist/lib/esm/components/index.d.mts +2 -0
- package/dist/lib/esm/components/index.mjs +5 -1
- package/dist/lib/esm/components/settings-facet-component.d.mts +68 -0
- package/dist/lib/esm/components/settings-facet-component.mjs +48 -0
- package/dist/lib/esm/components/style-sheet-component.d.mts +79 -0
- package/dist/lib/esm/components/style-sheet-component.mjs +109 -0
- package/dist/lib/esm/css-class.d.mts +28 -0
- package/dist/lib/esm/css-class.mjs +8 -1
- package/dist/lib/esm/data-stores/data-store-transport.d.mts +1 -1
- package/dist/lib/esm/data-stores/data-store-transport.mjs +7 -4
- package/dist/lib/esm/data-stores/shared-data-store.d.mts +1 -1
- package/dist/lib/esm/data-stores/shared-data-store.mjs +1 -1
- package/dist/lib/esm/desktop-git-runner.d.mts +17 -0
- package/dist/lib/esm/desktop-git-runner.mjs +19 -0
- package/dist/lib/esm/desktop-request-url-stream.d.mts +22 -0
- package/dist/lib/esm/desktop-request-url-stream.mjs +170 -0
- package/dist/lib/esm/editor-suggest-registrar.d.mts +14 -2
- package/dist/lib/esm/editor-suggest-registrar.mjs +8 -2
- package/dist/lib/esm/editor-suggest.d.mts +103 -0
- package/dist/lib/esm/editor-suggest.mjs +108 -0
- package/dist/lib/esm/feature-request.d.mts +54 -0
- package/dist/lib/esm/feature-request.mjs +25 -0
- package/dist/lib/esm/generated-during-build.mjs +2 -2
- package/dist/lib/esm/git-hub-discussion.d.mts +28 -0
- package/dist/lib/esm/git-hub-discussion.mjs +13 -0
- package/dist/lib/esm/git-rename-history.d.mts +43 -0
- package/dist/lib/esm/git-rename-history.mjs +59 -0
- package/dist/lib/esm/hotkey.d.mts +59 -0
- package/dist/lib/esm/hotkey.mjs +95 -0
- package/dist/lib/esm/i18n/locales/en.d.mts +12 -0
- package/dist/lib/esm/i18n/locales/en.mjs +13 -1
- package/dist/lib/esm/i18n/locales/translations-map.d.mts +12 -0
- package/dist/lib/esm/index.d.mts +15 -0
- package/dist/lib/esm/index.mjs +31 -1
- package/dist/lib/esm/inline-token-renderer.d.mts +88 -0
- package/dist/lib/esm/inline-token-renderer.mjs +59 -0
- package/dist/lib/esm/link-and-tag-input-suggest.d.mts +229 -0
- package/dist/lib/esm/link-and-tag-input-suggest.mjs +239 -0
- package/dist/lib/esm/markdown-code-block-processor.d.mts +18 -0
- package/dist/lib/esm/markdown-code-block-processor.mjs +16 -1
- package/dist/lib/esm/markdown.d.mts +10 -1
- package/dist/lib/esm/markdown.mjs +9 -1
- package/dist/lib/esm/rendered-markdown.d.mts +77 -0
- package/dist/lib/esm/rendered-markdown.mjs +219 -0
- package/dist/lib/esm/request-url.d.mts +233 -0
- package/dist/lib/esm/request-url.mjs +428 -0
- package/dist/lib/esm/setting-components/folder-list-component.d.mts +73 -0
- package/dist/lib/esm/setting-components/folder-list-component.mjs +131 -0
- package/dist/lib/esm/setting-components/hotkey-component.d.mts +85 -0
- package/dist/lib/esm/setting-components/hotkey-component.mjs +178 -0
- package/dist/lib/esm/setting-components/index.d.mts +4 -0
- package/dist/lib/esm/setting-components/index.mjs +9 -1
- package/dist/lib/esm/setting-components/list-component.d.mts +106 -0
- package/dist/lib/esm/setting-components/list-component.mjs +206 -0
- package/dist/lib/esm/setting-components/tag-list-component.d.mts +82 -0
- package/dist/lib/esm/setting-components/tag-list-component.mjs +131 -0
- package/dist/lib/esm/setting-ex.d.mts +35 -1
- package/dist/lib/esm/setting-ex.mjs +51 -1
- package/dist/lib/esm/settings-tabs.d.mts +101 -0
- package/dist/lib/esm/settings-tabs.mjs +170 -0
- package/dist/lib/esm/vault.d.mts +3 -1
- package/dist/lib/esm/vault.mjs +2 -2
- package/dist/styles.css +83 -1
- package/package.json +2 -2
- package/setting-components/folder-list-component/package.json +6 -0
- package/setting-components/hotkey-component/package.json +6 -0
- package/setting-components/list-component/package.json +6 -0
- package/setting-components/tag-list-component/package.json +6 -0
|
@@ -0,0 +1,523 @@
|
|
|
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 ensureDisposeSymbols(symbolConstructor = Symbol) {
|
|
7
|
+
symbolConstructor.asyncDispose ??= symbolConstructor.for("Symbol.asyncDispose");
|
|
8
|
+
symbolConstructor.dispose ??= symbolConstructor.for("Symbol.dispose");
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function ensureBrowserProcess() {
|
|
12
|
+
const browserProcess = {
|
|
13
|
+
browser: true,
|
|
14
|
+
cwd() {
|
|
15
|
+
return "/";
|
|
16
|
+
},
|
|
17
|
+
env: {},
|
|
18
|
+
platform: "android"
|
|
19
|
+
};
|
|
20
|
+
const existingProcess = globalThis.process;
|
|
21
|
+
if (!existingProcess) {
|
|
22
|
+
globalThis.process = browserProcess;
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (existingProcess.versions?.node) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const existingProcessRecord = existingProcess;
|
|
29
|
+
for (const [key, value] of Object.entries(browserProcess)) {
|
|
30
|
+
existingProcessRecord[key] ??= value;
|
|
31
|
+
}
|
|
32
|
+
existingProcessRecord["browser"] = true;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
ensureDisposeSymbols();
|
|
36
|
+
ensureBrowserProcess();
|
|
37
|
+
})();
|
|
38
|
+
(function patchObsidianRequire() {
|
|
39
|
+
const originalRequire = require;
|
|
40
|
+
if (!originalRequire || originalRequire.__isPatched) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
require = Object.assign(
|
|
44
|
+
(id) => requirePatched(id),
|
|
45
|
+
originalRequire,
|
|
46
|
+
{
|
|
47
|
+
__isPatched: true
|
|
48
|
+
}
|
|
49
|
+
);
|
|
50
|
+
function extractDefault($module) {
|
|
51
|
+
return $module && $module.__esModule && "default" in $module ? $module.default : $module;
|
|
52
|
+
}
|
|
53
|
+
const OBSIDIAN_BUILT_IN_MODULE_NAMES = /* @__PURE__ */ new Set([
|
|
54
|
+
"@codemirror/autocomplete",
|
|
55
|
+
"@codemirror/collab",
|
|
56
|
+
"@codemirror/commands",
|
|
57
|
+
"@codemirror/language",
|
|
58
|
+
"@codemirror/lint",
|
|
59
|
+
"@codemirror/search",
|
|
60
|
+
"@codemirror/state",
|
|
61
|
+
"@codemirror/text",
|
|
62
|
+
"@codemirror/view",
|
|
63
|
+
"@lezer/common",
|
|
64
|
+
"@lezer/highlight",
|
|
65
|
+
"@lezer/lr",
|
|
66
|
+
"obsidian"
|
|
67
|
+
]);
|
|
68
|
+
const DEPRECATED_OBSIDIAN_BUILT_IN_MODULE_NAMES = /* @__PURE__ */ new Set([
|
|
69
|
+
"@codemirror/closebrackets",
|
|
70
|
+
"@codemirror/comment",
|
|
71
|
+
"@codemirror/fold",
|
|
72
|
+
"@codemirror/gutter",
|
|
73
|
+
"@codemirror/highlight",
|
|
74
|
+
"@codemirror/history",
|
|
75
|
+
"@codemirror/matchbrackets",
|
|
76
|
+
"@codemirror/panel",
|
|
77
|
+
"@codemirror/rangeset",
|
|
78
|
+
"@codemirror/rectangular-selection",
|
|
79
|
+
"@codemirror/stream-parser",
|
|
80
|
+
"@codemirror/tooltip"
|
|
81
|
+
]);
|
|
82
|
+
function requirePatched(id) {
|
|
83
|
+
if (OBSIDIAN_BUILT_IN_MODULE_NAMES.has(id) || DEPRECATED_OBSIDIAN_BUILT_IN_MODULE_NAMES.has(id)) {
|
|
84
|
+
return originalRequire?.(id);
|
|
85
|
+
}
|
|
86
|
+
const app = globalThis.app;
|
|
87
|
+
if (app?.isMobile) {
|
|
88
|
+
if (id === "process" || id === "node:process") {
|
|
89
|
+
console.debug(`The most likely you can safely ignore this error. Module not found: ${id}. Fake process object is returned instead.`);
|
|
90
|
+
return process;
|
|
91
|
+
}
|
|
92
|
+
} else {
|
|
93
|
+
const $module = originalRequire?.(id);
|
|
94
|
+
if ($module) {
|
|
95
|
+
return extractDefault($module);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
console.debug(`The most likely you can safely ignore this error. Module not found: ${id}. Empty object is returned instead.`);
|
|
99
|
+
return {};
|
|
100
|
+
}
|
|
101
|
+
})();
|
|
102
|
+
|
|
103
|
+
"use strict";
|
|
104
|
+
var __create = Object.create;
|
|
105
|
+
var __defProp = Object.defineProperty;
|
|
106
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
107
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
108
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
109
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
110
|
+
var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : /* @__PURE__ */ Symbol.for("Symbol." + name);
|
|
111
|
+
var __typeError = (msg) => {
|
|
112
|
+
throw TypeError(msg);
|
|
113
|
+
};
|
|
114
|
+
var __export = (target, all) => {
|
|
115
|
+
for (var name in all)
|
|
116
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
117
|
+
};
|
|
118
|
+
var __copyProps = (to, from, except, desc) => {
|
|
119
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
120
|
+
for (let key of __getOwnPropNames(from))
|
|
121
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
122
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
123
|
+
}
|
|
124
|
+
return to;
|
|
125
|
+
};
|
|
126
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
127
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
128
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
129
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
130
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
131
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
132
|
+
mod
|
|
133
|
+
));
|
|
134
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
135
|
+
var __using = (stack, value, async) => {
|
|
136
|
+
if (value != null) {
|
|
137
|
+
if (typeof value !== "object" && typeof value !== "function") __typeError("Object expected");
|
|
138
|
+
var dispose, inner;
|
|
139
|
+
if (async) dispose = value[__knownSymbol("asyncDispose")];
|
|
140
|
+
if (dispose === void 0) {
|
|
141
|
+
dispose = value[__knownSymbol("dispose")];
|
|
142
|
+
if (async) inner = dispose;
|
|
143
|
+
}
|
|
144
|
+
if (typeof dispose !== "function") __typeError("Object not disposable");
|
|
145
|
+
if (inner) dispose = function() {
|
|
146
|
+
try {
|
|
147
|
+
inner.call(this);
|
|
148
|
+
} catch (e) {
|
|
149
|
+
return Promise.reject(e);
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
stack.push([async, dispose, value]);
|
|
153
|
+
} else if (async) {
|
|
154
|
+
stack.push([async]);
|
|
155
|
+
}
|
|
156
|
+
return value;
|
|
157
|
+
};
|
|
158
|
+
var __callDispose = (stack, error, hasError) => {
|
|
159
|
+
var E = typeof SuppressedError === "function" ? SuppressedError : function(e, s, m, _) {
|
|
160
|
+
return _ = Error(m), _.name = "SuppressedError", _.error = e, _.suppressed = s, _;
|
|
161
|
+
};
|
|
162
|
+
var fail = (e) => error = hasError ? new E(e, error, "An error was suppressed during disposal") : (hasError = true, e);
|
|
163
|
+
var next = (it) => {
|
|
164
|
+
while (it = stack.pop()) {
|
|
165
|
+
try {
|
|
166
|
+
var result = it[1] && it[1].call(it[2]);
|
|
167
|
+
if (it[0]) return Promise.resolve(result).then(next, (e) => (fail(e), next()));
|
|
168
|
+
} catch (e) {
|
|
169
|
+
fail(e);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (hasError) throw error;
|
|
173
|
+
};
|
|
174
|
+
return next();
|
|
175
|
+
};
|
|
176
|
+
var request_url_exports = {};
|
|
177
|
+
__export(request_url_exports, {
|
|
178
|
+
RequestUrlError: () => RequestUrlError,
|
|
179
|
+
createRequestUrlFetch: () => createRequestUrlFetch,
|
|
180
|
+
encodeRequestUrlRequest: () => encodeRequestUrlRequest,
|
|
181
|
+
requestUrlEx: () => requestUrlEx,
|
|
182
|
+
requestUrlStream: () => requestUrlStream
|
|
183
|
+
});
|
|
184
|
+
module.exports = __toCommonJS(request_url_exports);
|
|
185
|
+
var import_abort_controller = require('@mnaoumov/typescript-lib/abort-controller');
|
|
186
|
+
var import_function = require('@mnaoumov/typescript-lib/function');
|
|
187
|
+
var import_object_utils = require('@mnaoumov/typescript-lib/object-utils');
|
|
188
|
+
var import_obsidian = require('obsidian');
|
|
189
|
+
const HTTP_ERROR_STATUS_MIN = 400;
|
|
190
|
+
const ERROR_MESSAGE_BODY_LENGTH = 200;
|
|
191
|
+
const HTTP_SWITCHING_PROTOCOLS_STATUS = 101;
|
|
192
|
+
const HTTP_EARLY_HINTS_STATUS = 103;
|
|
193
|
+
const HTTP_NO_CONTENT_STATUS = 204;
|
|
194
|
+
const HTTP_RESET_CONTENT_STATUS = 205;
|
|
195
|
+
const HTTP_NOT_MODIFIED_STATUS = 304;
|
|
196
|
+
const NULL_BODY_STATUSES = /* @__PURE__ */ new Set([
|
|
197
|
+
HTTP_EARLY_HINTS_STATUS,
|
|
198
|
+
HTTP_NO_CONTENT_STATUS,
|
|
199
|
+
HTTP_NOT_MODIFIED_STATUS,
|
|
200
|
+
HTTP_RESET_CONTENT_STATUS,
|
|
201
|
+
HTTP_SWITCHING_PROTOCOLS_STATUS
|
|
202
|
+
]);
|
|
203
|
+
const SUPPORTED_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:"]);
|
|
204
|
+
const CONTENT_TYPE_HEADER = "content-type";
|
|
205
|
+
const HEX_RADIX = 16;
|
|
206
|
+
const BOUNDARY_RANDOM_PART_COUNT = 2;
|
|
207
|
+
const RANDOM_PART_START = 2;
|
|
208
|
+
class RequestUrlError extends Error {
|
|
209
|
+
/**
|
|
210
|
+
* The response headers.
|
|
211
|
+
*/
|
|
212
|
+
headers;
|
|
213
|
+
/**
|
|
214
|
+
* The HTTP method.
|
|
215
|
+
*/
|
|
216
|
+
method;
|
|
217
|
+
/**
|
|
218
|
+
* The status code.
|
|
219
|
+
*/
|
|
220
|
+
status;
|
|
221
|
+
/**
|
|
222
|
+
* The response body as text.
|
|
223
|
+
*/
|
|
224
|
+
text;
|
|
225
|
+
/**
|
|
226
|
+
* The URL.
|
|
227
|
+
*/
|
|
228
|
+
url;
|
|
229
|
+
/**
|
|
230
|
+
* Creates a {@link RequestUrlError}.
|
|
231
|
+
*
|
|
232
|
+
* @param params - The failed request and its response.
|
|
233
|
+
*/
|
|
234
|
+
constructor(params) {
|
|
235
|
+
const bodyExcerpt = params.text.length > ERROR_MESSAGE_BODY_LENGTH ? `${params.text.slice(0, ERROR_MESSAGE_BODY_LENGTH)}\u2026` : params.text;
|
|
236
|
+
super(`${params.method} ${params.url} failed with status ${String(params.status)}${bodyExcerpt ? `: ${bodyExcerpt}` : ""}`);
|
|
237
|
+
this.name = "RequestUrlError";
|
|
238
|
+
this.headers = params.headers;
|
|
239
|
+
this.method = params.method;
|
|
240
|
+
this.status = params.status;
|
|
241
|
+
this.text = params.text;
|
|
242
|
+
this.url = params.url;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Parses the response body as JSON.
|
|
246
|
+
*
|
|
247
|
+
* @returns The parsed body.
|
|
248
|
+
*/
|
|
249
|
+
json() {
|
|
250
|
+
return JSON.parse(this.text);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
function createRequestUrlFetch(options = {}) {
|
|
254
|
+
return async (input, init = {}) => {
|
|
255
|
+
let request = null;
|
|
256
|
+
let url;
|
|
257
|
+
if (typeof input === "string") {
|
|
258
|
+
url = input;
|
|
259
|
+
} else if ("method" in input) {
|
|
260
|
+
request = input;
|
|
261
|
+
url = input.url;
|
|
262
|
+
} else {
|
|
263
|
+
url = input.href;
|
|
264
|
+
}
|
|
265
|
+
const method = (init.method ?? request?.method ?? "GET").toUpperCase();
|
|
266
|
+
const headers = toHeaderRecord(request?.headers, init.headers);
|
|
267
|
+
let body = init.body ?? void 0;
|
|
268
|
+
if (body === void 0 && request && method !== "GET" && method !== "HEAD") {
|
|
269
|
+
body = await request.arrayBuffer();
|
|
270
|
+
}
|
|
271
|
+
const params = {
|
|
272
|
+
abortSignal: init.signal ?? request?.signal ?? void 0,
|
|
273
|
+
body,
|
|
274
|
+
headers,
|
|
275
|
+
method,
|
|
276
|
+
shouldThrowOnHttpError: false,
|
|
277
|
+
timeoutInMilliseconds: options.timeoutInMilliseconds,
|
|
278
|
+
url
|
|
279
|
+
};
|
|
280
|
+
if (options.shouldStream) {
|
|
281
|
+
const streamResponse = await requestUrlStream(params);
|
|
282
|
+
return createResponse(streamResponse.status, streamResponse.headers, streamResponse.body, streamResponse.url);
|
|
283
|
+
}
|
|
284
|
+
const response = await requestUrlEx(params);
|
|
285
|
+
return createResponse(response.status, response.headers, response.arrayBuffer, url);
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
async function encodeRequestUrlRequest(params) {
|
|
289
|
+
const url = assertHttpUrl(params.url);
|
|
290
|
+
const abortSignal = (0, import_abort_controller.abortSignalAny)(
|
|
291
|
+
params.abortSignal,
|
|
292
|
+
params.timeoutInMilliseconds === void 0 ? void 0 : (0, import_abort_controller.abortSignalTimeout)(params.timeoutInMilliseconds)
|
|
293
|
+
);
|
|
294
|
+
abortSignal.throwIfAborted();
|
|
295
|
+
const encodedBody = await encodeBody(params.body);
|
|
296
|
+
abortSignal.throwIfAborted();
|
|
297
|
+
const headers = { ...params.headers };
|
|
298
|
+
const hasContentTypeHeader = Object.keys(headers).some((name) => name.toLowerCase() === CONTENT_TYPE_HEADER);
|
|
299
|
+
const contentType = params.contentType ?? (hasContentTypeHeader ? void 0 : encodedBody.contentType);
|
|
300
|
+
if (contentType !== void 0) {
|
|
301
|
+
for (const name of Object.keys(headers)) {
|
|
302
|
+
if (name.toLowerCase() === CONTENT_TYPE_HEADER) {
|
|
303
|
+
delete headers[name];
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
headers["Content-Type"] = contentType;
|
|
307
|
+
}
|
|
308
|
+
return (0, import_object_utils.normalizeOptionalProperties)({
|
|
309
|
+
abortSignal,
|
|
310
|
+
body: encodedBody.body,
|
|
311
|
+
headers,
|
|
312
|
+
method: (params.method ?? "GET").toUpperCase(),
|
|
313
|
+
url
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
async function requestUrlEx(params) {
|
|
317
|
+
const request = await encodeRequestUrlRequest(params);
|
|
318
|
+
const obsidianRequest = (0, import_object_utils.normalizeOptionalProperties)({
|
|
319
|
+
body: request.body,
|
|
320
|
+
headers: { ...request.headers },
|
|
321
|
+
method: request.method,
|
|
322
|
+
throw: false,
|
|
323
|
+
url: request.url
|
|
324
|
+
});
|
|
325
|
+
const response = await raceWithAbort(Promise.resolve((0, import_obsidian.requestUrl)(obsidianRequest)), request.abortSignal);
|
|
326
|
+
if ((params.shouldThrowOnHttpError ?? true) && response.status >= HTTP_ERROR_STATUS_MIN) {
|
|
327
|
+
throw new RequestUrlError({
|
|
328
|
+
headers: response.headers,
|
|
329
|
+
method: request.method,
|
|
330
|
+
status: response.status,
|
|
331
|
+
text: response.text,
|
|
332
|
+
url: request.url
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
return response;
|
|
336
|
+
}
|
|
337
|
+
async function requestUrlStream(params) {
|
|
338
|
+
const request = await encodeRequestUrlRequest(params);
|
|
339
|
+
let response;
|
|
340
|
+
if (import_obsidian.Platform.isDesktopApp) {
|
|
341
|
+
const { openDesktopRequestUrlStream } = await import("./desktop-request-url-stream.cjs");
|
|
342
|
+
response = await openDesktopRequestUrlStream(request);
|
|
343
|
+
} else {
|
|
344
|
+
const bufferedResponse = await requestUrlEx({
|
|
345
|
+
abortSignal: request.abortSignal,
|
|
346
|
+
body: request.body,
|
|
347
|
+
headers: request.headers,
|
|
348
|
+
method: request.method,
|
|
349
|
+
shouldThrowOnHttpError: false,
|
|
350
|
+
url: request.url
|
|
351
|
+
});
|
|
352
|
+
response = {
|
|
353
|
+
body: createSingleChunkStream(bufferedResponse.arrayBuffer),
|
|
354
|
+
headers: bufferedResponse.headers,
|
|
355
|
+
status: bufferedResponse.status,
|
|
356
|
+
url: request.url
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
if ((params.shouldThrowOnHttpError ?? true) && response.status >= HTTP_ERROR_STATUS_MIN) {
|
|
360
|
+
const text = new TextDecoder().decode(await readStream(response.body));
|
|
361
|
+
throw new RequestUrlError({
|
|
362
|
+
headers: response.headers,
|
|
363
|
+
method: request.method,
|
|
364
|
+
status: response.status,
|
|
365
|
+
text,
|
|
366
|
+
url: response.url
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
return response;
|
|
370
|
+
}
|
|
371
|
+
function assertHttpUrl(url) {
|
|
372
|
+
let parsedUrl;
|
|
373
|
+
try {
|
|
374
|
+
parsedUrl = new URL(url);
|
|
375
|
+
} catch {
|
|
376
|
+
throw new TypeError(`Invalid URL: ${url}`);
|
|
377
|
+
}
|
|
378
|
+
if (!SUPPORTED_PROTOCOLS.has(parsedUrl.protocol)) {
|
|
379
|
+
throw new TypeError(`Unsupported protocol ${parsedUrl.protocol} in ${url}: only http: and https: URLs can be requested`);
|
|
380
|
+
}
|
|
381
|
+
return url;
|
|
382
|
+
}
|
|
383
|
+
function concatBytes(chunks) {
|
|
384
|
+
const length = chunks.reduce((sum, chunk) => sum + chunk.byteLength, 0);
|
|
385
|
+
const bytes = new Uint8Array(length);
|
|
386
|
+
let offset = 0;
|
|
387
|
+
for (const chunk of chunks) {
|
|
388
|
+
bytes.set(chunk, offset);
|
|
389
|
+
offset += chunk.byteLength;
|
|
390
|
+
}
|
|
391
|
+
return bytes.buffer;
|
|
392
|
+
}
|
|
393
|
+
function createResponse(status, headers, body, url) {
|
|
394
|
+
const response = new Response(NULL_BODY_STATUSES.has(status) ? null : body, {
|
|
395
|
+
headers: new Headers({ ...headers }),
|
|
396
|
+
status
|
|
397
|
+
});
|
|
398
|
+
Object.defineProperty(response, "url", { value: url });
|
|
399
|
+
return response;
|
|
400
|
+
}
|
|
401
|
+
function createSingleChunkStream(arrayBuffer) {
|
|
402
|
+
return new ReadableStream({
|
|
403
|
+
start(controller) {
|
|
404
|
+
if (arrayBuffer.byteLength > 0) {
|
|
405
|
+
controller.enqueue(new Uint8Array(arrayBuffer));
|
|
406
|
+
}
|
|
407
|
+
controller.close();
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
async function encodeBody(body) {
|
|
412
|
+
if (body === void 0 || typeof body === "string") {
|
|
413
|
+
return (0, import_object_utils.normalizeOptionalProperties)({ body });
|
|
414
|
+
}
|
|
415
|
+
switch (Object.prototype.toString.call(body)) {
|
|
416
|
+
case "[object ArrayBuffer]": {
|
|
417
|
+
return { body };
|
|
418
|
+
}
|
|
419
|
+
case "[object Blob]":
|
|
420
|
+
case "[object File]": {
|
|
421
|
+
const blob = body;
|
|
422
|
+
return (0, import_object_utils.normalizeOptionalProperties)({ body: await blob.arrayBuffer(), contentType: blob.type || void 0 });
|
|
423
|
+
}
|
|
424
|
+
case "[object FormData]": {
|
|
425
|
+
return await encodeFormData(body);
|
|
426
|
+
}
|
|
427
|
+
case "[object ReadableStream]": {
|
|
428
|
+
return { body: await readStream(body) };
|
|
429
|
+
}
|
|
430
|
+
case "[object URLSearchParams]": {
|
|
431
|
+
return { body: body.toString(), contentType: "application/x-www-form-urlencoded;charset=UTF-8" };
|
|
432
|
+
}
|
|
433
|
+
default: {
|
|
434
|
+
if (ArrayBuffer.isView(body)) {
|
|
435
|
+
return { body: new Uint8Array(body.buffer, body.byteOffset, body.byteLength).slice().buffer };
|
|
436
|
+
}
|
|
437
|
+
throw new TypeError(`Unsupported request body: ${Object.prototype.toString.call(body)}`);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
async function encodeFormData(formData) {
|
|
442
|
+
const boundary = `----ObsidianLibFormBoundary${generateRandomHex()}`;
|
|
443
|
+
const textEncoder = new TextEncoder();
|
|
444
|
+
const chunks = [];
|
|
445
|
+
const entries = [];
|
|
446
|
+
formData.forEach((value, name) => {
|
|
447
|
+
entries.push([name, value]);
|
|
448
|
+
});
|
|
449
|
+
for (const [name, value] of entries) {
|
|
450
|
+
let header = `--${boundary}\r
|
|
451
|
+
Content-Disposition: form-data; name="${escapeMultipartName(name)}"`;
|
|
452
|
+
if (typeof value === "string") {
|
|
453
|
+
chunks.push(textEncoder.encode(`${header}\r
|
|
454
|
+
\r
|
|
455
|
+
${value}\r
|
|
456
|
+
`));
|
|
457
|
+
continue;
|
|
458
|
+
}
|
|
459
|
+
header += `; filename="${escapeMultipartName(value.name)}"\r
|
|
460
|
+
Content-Type: ${value.type || "application/octet-stream"}\r
|
|
461
|
+
\r
|
|
462
|
+
`;
|
|
463
|
+
chunks.push(textEncoder.encode(header), new Uint8Array(await value.arrayBuffer()), textEncoder.encode("\r\n"));
|
|
464
|
+
}
|
|
465
|
+
chunks.push(textEncoder.encode(`--${boundary}--\r
|
|
466
|
+
`));
|
|
467
|
+
return { body: concatBytes(chunks), contentType: `multipart/form-data; boundary=${boundary}` };
|
|
468
|
+
}
|
|
469
|
+
function escapeMultipartName(name) {
|
|
470
|
+
return name.replaceAll('"', "%22").replaceAll("\r", "%0D").replaceAll("\n", "%0A");
|
|
471
|
+
}
|
|
472
|
+
function generateRandomHex() {
|
|
473
|
+
return Array.from({ length: BOUNDARY_RANDOM_PART_COUNT }, () => Math.random().toString(HEX_RADIX).slice(RANDOM_PART_START)).join("");
|
|
474
|
+
}
|
|
475
|
+
async function raceWithAbort(promise, abortSignal) {
|
|
476
|
+
var _stack = [];
|
|
477
|
+
try {
|
|
478
|
+
let rejectOnAbort = import_function.noop;
|
|
479
|
+
const abortPromise = new Promise((_resolve, reject) => {
|
|
480
|
+
rejectOnAbort = reject;
|
|
481
|
+
});
|
|
482
|
+
const _abortListener = __using(_stack, (0, import_abort_controller.onAbort)(abortSignal, () => {
|
|
483
|
+
rejectOnAbort(abortSignal.reason);
|
|
484
|
+
}));
|
|
485
|
+
return await Promise.race([promise, abortPromise]);
|
|
486
|
+
} catch (_) {
|
|
487
|
+
var _error = _, _hasError = true;
|
|
488
|
+
} finally {
|
|
489
|
+
__callDispose(_stack, _error, _hasError);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
async function readStream(stream) {
|
|
493
|
+
const reader = stream.getReader();
|
|
494
|
+
const chunks = [];
|
|
495
|
+
for (; ; ) {
|
|
496
|
+
const result = await reader.read();
|
|
497
|
+
if (result.done) {
|
|
498
|
+
break;
|
|
499
|
+
}
|
|
500
|
+
chunks.push(result.value);
|
|
501
|
+
}
|
|
502
|
+
return concatBytes(chunks);
|
|
503
|
+
}
|
|
504
|
+
function toHeaderRecord(requestHeaders, initHeaders) {
|
|
505
|
+
const headers = new Headers(requestHeaders);
|
|
506
|
+
new Headers(initHeaders).forEach((value, name) => {
|
|
507
|
+
headers.set(name, value);
|
|
508
|
+
});
|
|
509
|
+
const record = {};
|
|
510
|
+
headers.forEach((value, name) => {
|
|
511
|
+
record[name] = value;
|
|
512
|
+
});
|
|
513
|
+
return record;
|
|
514
|
+
}
|
|
515
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
516
|
+
0 && (module.exports = {
|
|
517
|
+
RequestUrlError,
|
|
518
|
+
createRequestUrlFetch,
|
|
519
|
+
encodeRequestUrlRequest,
|
|
520
|
+
requestUrlEx,
|
|
521
|
+
requestUrlStream
|
|
522
|
+
});
|
|
523
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9yZXF1ZXN0LXVybC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBuL25vLXVuc3VwcG9ydGVkLWZlYXR1cmVzL25vZGUtYnVpbHRpbnMgLS0gVGhlc2UgYXJlIE9ic2lkaWFuIHJlbmRlcmVyIFdlYiBBUElzLCBub3QgTm9kZSBidWlsdGlucy4gKi9cbi8qKlxuICogQGZpbGVcbiAqXG4gKiBBIHdyYXBwZXIgb3ZlciBPYnNpZGlhbidzIHtAbGluayByZXF1ZXN0VXJsfSB0aGF0IGZpbGxzIHRoZSBnYXBzIHBsdWdpbnMga2VlcCBoYW5kLXJvbGxpbmc6IGFuIGFib3J0IHNpZ25hbCBhbmQgYVxuICogdGltZW91dCwgcmVxdWVzdCBib2RpZXMgYmV5b25kIGBzdHJpbmcgfCBBcnJheUJ1ZmZlcmAgKGBGb3JtRGF0YWAsIGBVUkxTZWFyY2hQYXJhbXNgLCBgQmxvYmAsIHR5cGVkIGFycmF5cyBhbmRcbiAqIHN0cmVhbXMpLCBhbiBlcnJvciB0aGF0IGNhcnJpZXMgdGhlIHN0YXR1cyBhbmQgdGhlIGJvZHksIGFuIHVwLWZyb250IHByb3RvY29sIGNoZWNrLCBhIHN0cmVhbWVkIHJlc3BvbnNlIGJvZHksIGFuZFxuICogYSBgZmV0Y2hgLWNvbXBhdGlibGUgYWRhcHRlciB0aGF0IHRoaXJkLXBhcnR5IFNES3MgY2FuIHRha2UuXG4gKlxuICogYHJlcXVlc3RVcmxgIGl0c2VsZiBjYW5ub3QgYmUgY2FuY2VsbGVkOiBhbiBhYm9ydCBvciBhIHRpbWVvdXQgc2V0dGxlcyB0aGUgcmV0dXJuZWQgcHJvbWlzZSBhdCBvbmNlLCB3aGlsZSB0aGVcbiAqIHVuZGVybHlpbmcgcmVxdWVzdCBydW5zIHRvIGNvbXBsZXRpb24gYW5kIGl0cyByZXN1bHQgaXMgZHJvcHBlZC4gVGhlIHN0cmVhbWVkIHZhcmlhbnQgcmVhbGx5IGNhbmNlbHMgb24gZGVza3RvcCxcbiAqIHdoZXJlIGl0IGdvZXMgdGhyb3VnaCBgbm9kZTpodHRwYCAvIGBub2RlOmh0dHBzYDsgdGhhdCBtb2R1bGUgaXMgaW1wb3J0ZWQgZHluYW1pY2FsbHksIHNvIHRoaXMgb25lIHN0YXlzXG4gKiBjcm9zcy1wbGF0Zm9ybS1sb2FkYWJsZS4gT24gbW9iaWxlIHRoZSBzdHJlYW1lZCB2YXJpYW50IGZhbGxzIGJhY2sgdG8gYHJlcXVlc3RVcmxgIGFuZCBkZWxpdmVycyB0aGUgd2hvbGUgYm9keSBhcyBhXG4gKiBzaW5nbGUgY2h1bmsuXG4gKi9cblxuaW1wb3J0IHR5cGUge1xuICBSZXF1ZXN0VXJsUGFyYW0sXG4gIFJlcXVlc3RVcmxSZXNwb25zZVxufSBmcm9tICdvYnNpZGlhbic7XG5cbmltcG9ydCB7XG4gIGFib3J0U2lnbmFsQW55LFxuICBhYm9ydFNpZ25hbFRpbWVvdXQsXG4gIG9uQWJvcnRcbn0gZnJvbSAnQG1uYW91bW92L3R5cGVzY3JpcHQtbGliL2Fib3J0LWNvbnRyb2xsZXInO1xuaW1wb3J0IHsgbm9vcCB9IGZyb20gJ0BtbmFvdW1vdi90eXBlc2NyaXB0LWxpYi9mdW5jdGlvbic7XG5pbXBvcnQgeyBub3JtYWxpemVPcHRpb25hbFByb3BlcnRpZXMgfSBmcm9tICdAbW5hb3Vtb3YvdHlwZXNjcmlwdC1saWIvb2JqZWN0LXV0aWxzJztcbmltcG9ydCB7XG4gIFBsYXRmb3JtLFxuICByZXF1ZXN0VXJsXG59IGZyb20gJ29ic2lkaWFuJztcblxuLyoqXG4gKiBPcHRpb25zIGZvciB7QGxpbmsgY3JlYXRlUmVxdWVzdFVybEZldGNofS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDcmVhdGVSZXF1ZXN0VXJsRmV0Y2hPcHRpb25zIHtcbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gc3RyZWFtIHRoZSByZXNwb25zZSBib2R5IHRocm91Z2gge0BsaW5rIHJlcXVlc3RVcmxTdHJlYW19IHJhdGhlciB0aGFuIGJ1ZmZlciBpdC4gU3RyZWFtaW5nIGlzIHJlYWwgb25cbiAgICogZGVza3RvcCBvbmx5OyBvbiBtb2JpbGUgdGhlIGJvZHkgc3RpbGwgYXJyaXZlcyBhcyBvbmUgY2h1bmsuIERlZmF1bHRzIHRvIGBmYWxzZWAuXG4gICAqL1xuICByZWFkb25seSBzaG91bGRTdHJlYW0/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBUaGUgdGltZW91dCBpbiBtaWxsaXNlY29uZHMgYXBwbGllZCB0byBldmVyeSByZXF1ZXN0LCBvbiB0b3Agb2YgdGhlIHJlcXVlc3QncyBvd24gYHNpZ25hbGAuXG4gICAqL1xuICByZWFkb25seSB0aW1lb3V0SW5NaWxsaXNlY29uZHM/OiBudW1iZXI7XG59XG5cbi8qKlxuICogVGhlIHJlcXVlc3QgaW4gdGhlIGZvcm0gdGhlIHRyYW5zcG9ydHMgdGFrZTogdmFsaWRhdGVkLCB3aXRoIHRoZSBib2R5IGVuY29kZWQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRW5jb2RlZFJlcXVlc3RVcmxSZXF1ZXN0IHtcbiAgLyoqXG4gICAqIEFib3J0cyB0aGUgcmVxdWVzdC5cbiAgICovXG4gIHJlYWRvbmx5IGFib3J0U2lnbmFsOiBBYm9ydFNpZ25hbDtcblxuICAvKipcbiAgICogVGhlIGVuY29kZWQgYm9keS5cbiAgICovXG4gIHJlYWRvbmx5IGJvZHk/OiBBcnJheUJ1ZmZlciB8IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHJlcXVlc3QgaGVhZGVycywgaW5jbHVkaW5nIHRoZSBjb250ZW50IHR5cGUuXG4gICAqL1xuICByZWFkb25seSBoZWFkZXJzOiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+PjtcblxuICAvKipcbiAgICogVGhlIEhUVFAgbWV0aG9kLCB1cHBlcmNhc2UuXG4gICAqL1xuICByZWFkb25seSBtZXRob2Q6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIFVSTC5cbiAgICovXG4gIHJlYWRvbmx5IHVybDogc3RyaW5nO1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBlbmNvZGVSZXF1ZXN0VXJsUmVxdWVzdH0uXG4gKi9cbmV4cG9ydCB0eXBlIEVuY29kZVJlcXVlc3RVcmxSZXF1ZXN0UGFyYW1zID0gUmVxdWVzdFVybEV4UGFyYW1zO1xuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHRoZSB7QGxpbmsgUmVxdWVzdFVybEVycm9yfSBjb25zdHJ1Y3Rvci5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXF1ZXN0VXJsRXJyb3JDb25zdHJ1Y3RvclBhcmFtcyB7XG4gIC8qKlxuICAgKiBUaGUgcmVzcG9uc2UgaGVhZGVycy5cbiAgICovXG4gIHJlYWRvbmx5IGhlYWRlcnM6IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHN0cmluZz4+O1xuXG4gIC8qKlxuICAgKiBUaGUgSFRUUCBtZXRob2QuXG4gICAqL1xuICByZWFkb25seSBtZXRob2Q6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHN0YXR1cyBjb2RlLlxuICAgKi9cbiAgcmVhZG9ubHkgc3RhdHVzOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSByZXNwb25zZSBib2R5IGFzIHRleHQuXG4gICAqL1xuICByZWFkb25seSB0ZXh0OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBVUkwuXG4gICAqL1xuICByZWFkb25seSB1cmw6IHN0cmluZztcbn1cblxuLyoqXG4gKiBBIHJlcXVlc3QgYm9keSB7QGxpbmsgcmVxdWVzdFVybEV4fSBhY2NlcHRzOiBldmVyeXRoaW5nIGBmZXRjaGAgYWNjZXB0cy5cbiAqL1xuZXhwb3J0IHR5cGUgUmVxdWVzdFVybEV4Qm9keSA9IEFycmF5QnVmZmVyIHwgQXJyYXlCdWZmZXJWaWV3IHwgQmxvYiB8IEZvcm1EYXRhIHwgUmVhZGFibGVTdHJlYW08VWludDhBcnJheT4gfCBzdHJpbmcgfCBVUkxTZWFyY2hQYXJhbXM7XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIHJlcXVlc3RVcmxFeH0uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVxdWVzdFVybEV4UGFyYW1zIHtcbiAgLyoqXG4gICAqIEFib3J0cyB0aGUgcmVxdWVzdC4gVGhlIHByb21pc2UgcmVqZWN0cyB3aXRoIHRoZSBzaWduYWwncyByZWFzb24uXG4gICAqL1xuICByZWFkb25seSBhYm9ydFNpZ25hbD86IEFib3J0U2lnbmFsIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBUaGUgcmVxdWVzdCBib2R5LlxuICAgKi9cbiAgcmVhZG9ubHkgYm9keT86IFJlcXVlc3RVcmxFeEJvZHkgfCB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIFRoZSBjb250ZW50IHR5cGUuIFdoZW4gb21pdHRlZCwgaXQgaXMgZGVyaXZlZCBmcm9tIHRoZSBib2R5OiBhIGBGb3JtRGF0YWAgYm9keSBnZXRzIGBtdWx0aXBhcnQvZm9ybS1kYXRhYCB3aXRoIGl0c1xuICAgKiBib3VuZGFyeSwgYSBgVVJMU2VhcmNoUGFyYW1zYCBib2R5IGBhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWRgIGFuZCBhIGBCbG9iYCBib2R5IGl0cyBvd24gdHlwZSDigJQgdW5sZXNzXG4gICAqIHtAbGluayBSZXF1ZXN0VXJsRXhQYXJhbXMuaGVhZGVyc30gYWxyZWFkeSBjYXJyaWVzIGEgYENvbnRlbnQtVHlwZWAuXG4gICAqL1xuICByZWFkb25seSBjb250ZW50VHlwZT86IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogVGhlIHJlcXVlc3QgaGVhZGVycy5cbiAgICovXG4gIHJlYWRvbmx5IGhlYWRlcnM/OiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+PiB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogVGhlIEhUVFAgbWV0aG9kLiBEZWZhdWx0cyB0byBgR0VUYC5cbiAgICovXG4gIHJlYWRvbmx5IG1ldGhvZD86IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogV2hldGhlciB0byB0aHJvdyBhIHtAbGluayBSZXF1ZXN0VXJsRXJyb3J9IHdoZW4gdGhlIHN0YXR1cyBjb2RlIGlzIDQwMCBvciBoaWdoZXIuIERlZmF1bHRzIHRvIGB0cnVlYC5cbiAgICovXG4gIHJlYWRvbmx5IHNob3VsZFRocm93T25IdHRwRXJyb3I/OiBib29sZWFuIHwgdW5kZWZpbmVkO1xuXG4gIC8qKlxuICAgKiBUaGUgdGltZW91dCBpbiBtaWxsaXNlY29uZHMuIFRoZSBwcm9taXNlIHJlamVjdHMgd2l0aCBhIGBUaW1lb3V0RXJyb3JgIHtAbGluayBET01FeGNlcHRpb259IG9uY2UgaXQgZWxhcHNlcy5cbiAgICovXG4gIHJlYWRvbmx5IHRpbWVvdXRJbk1pbGxpc2Vjb25kcz86IG51bWJlciB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogVGhlIFVSTC4gT25seSBgaHR0cDpgIGFuZCBgaHR0cHM6YCBVUkxzIGFyZSBhY2NlcHRlZC5cbiAgICovXG4gIHJlYWRvbmx5IHVybDogc3RyaW5nO1xufVxuXG4vKipcbiAqIEEgYGZldGNoYC1jb21wYXRpYmxlIGZ1bmN0aW9uIGJ1aWx0IG9uIHtAbGluayByZXF1ZXN0VXJsfS5cbiAqL1xuZXhwb3J0IHR5cGUgUmVxdWVzdFVybEZldGNoID0gKGlucHV0OiBSZXF1ZXN0IHwgc3RyaW5nIHwgVVJMLCBpbml0PzogUmVxdWVzdEluaXQpID0+IFByb21pc2U8UmVzcG9uc2U+O1xuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayByZXF1ZXN0VXJsU3RyZWFtfS5cbiAqL1xuZXhwb3J0IHR5cGUgUmVxdWVzdFVybFN0cmVhbVBhcmFtcyA9IFJlcXVlc3RVcmxFeFBhcmFtcztcblxuLyoqXG4gKiBUaGUgcmVzcG9uc2Ugb2Yge0BsaW5rIHJlcXVlc3RVcmxTdHJlYW19LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlcXVlc3RVcmxTdHJlYW1SZXNwb25zZSB7XG4gIC8qKlxuICAgKiBUaGUgcmVzcG9uc2UgYm9keS5cbiAgICovXG4gIHJlYWRvbmx5IGJvZHk6IFJlYWRhYmxlU3RyZWFtPFVpbnQ4QXJyYXk+O1xuXG4gIC8qKlxuICAgKiBUaGUgcmVzcG9uc2UgaGVhZGVycywgd2l0aCBsb3dlcmNhc2UgbmFtZXMuXG4gICAqL1xuICByZWFkb25seSBoZWFkZXJzOiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+PjtcblxuICAvKipcbiAgICogVGhlIHN0YXR1cyBjb2RlLlxuICAgKi9cbiAgcmVhZG9ubHkgc3RhdHVzOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBmaW5hbCBVUkwsIGFmdGVyIGFueSByZWRpcmVjdHMuXG4gICAqL1xuICByZWFkb25seSB1cmw6IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIEVuY29kZWRCb2R5IHtcbiAgcmVhZG9ubHkgYm9keT86IEFycmF5QnVmZmVyIHwgc3RyaW5nO1xuICByZWFkb25seSBjb250ZW50VHlwZT86IHN0cmluZztcbn1cblxuY29uc3QgSFRUUF9FUlJPUl9TVEFUVVNfTUlOID0gNDAwO1xuY29uc3QgRVJST1JfTUVTU0FHRV9CT0RZX0xFTkdUSCA9IDIwMDtcbmNvbnN0IEhUVFBfU1dJVENISU5HX1BST1RPQ09MU19TVEFUVVMgPSAxMDE7XG5jb25zdCBIVFRQX0VBUkxZX0hJTlRTX1NUQVRVUyA9IDEwMztcbmNvbnN0IEhUVFBfTk9fQ09OVEVOVF9TVEFUVVMgPSAyMDQ7XG5jb25zdCBIVFRQX1JFU0VUX0NPTlRFTlRfU1RBVFVTID0gMjA1O1xuY29uc3QgSFRUUF9OT1RfTU9ESUZJRURfU1RBVFVTID0gMzA0O1xuLy8gVGhlIHN0YXR1c2VzIGEgUmVzcG9uc2UgcmVmdXNlcyBhIGJvZHkgZm9yLlxuY29uc3QgTlVMTF9CT0RZX1NUQVRVU0VTID0gbmV3IFNldChbXG4gIEhUVFBfRUFSTFlfSElOVFNfU1RBVFVTLFxuICBIVFRQX05PX0NPTlRFTlRfU1RBVFVTLFxuICBIVFRQX05PVF9NT0RJRklFRF9TVEFUVVMsXG4gIEhUVFBfUkVTRVRfQ09OVEVOVF9TVEFUVVMsXG4gIEhUVFBfU1dJVENISU5HX1BST1RPQ09MU19TVEFUVVNcbl0pO1xuY29uc3QgU1VQUE9SVEVEX1BST1RPQ09MUyA9IG5ldyBTZXQoWydodHRwOicsICdodHRwczonXSk7XG5jb25zdCBDT05URU5UX1RZUEVfSEVBREVSID0gJ2NvbnRlbnQtdHlwZSc7XG5jb25zdCBIRVhfUkFESVggPSAxNjtcbmNvbnN0IEJPVU5EQVJZX1JBTkRPTV9QQVJUX0NPVU5UID0gMjtcbmNvbnN0IFJBTkRPTV9QQVJUX1NUQVJUID0gMjtcblxuLyoqXG4gKiBUaGUgZXJyb3Ige0BsaW5rIHJlcXVlc3RVcmxFeH0gYW5kIHtAbGluayByZXF1ZXN0VXJsU3RyZWFtfSB0aHJvdyBmb3IgYSBzdGF0dXMgY29kZSBvZiA0MDAgb3IgaGlnaGVyLlxuICovXG5leHBvcnQgY2xhc3MgUmVxdWVzdFVybEVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAvKipcbiAgICogVGhlIHJlc3BvbnNlIGhlYWRlcnMuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgaGVhZGVyczogUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgc3RyaW5nPj47XG5cbiAgLyoqXG4gICAqIFRoZSBIVFRQIG1ldGhvZC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBtZXRob2Q6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHN0YXR1cyBjb2RlLlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHN0YXR1czogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgcmVzcG9uc2UgYm9keSBhcyB0ZXh0LlxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHRleHQ6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIFVSTC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSB1cmw6IHN0cmluZztcblxuICAvKipcbiAgICogQ3JlYXRlcyBhIHtAbGluayBSZXF1ZXN0VXJsRXJyb3J9LlxuICAgKlxuICAgKiBAcGFyYW0gcGFyYW1zIC0gVGhlIGZhaWxlZCByZXF1ZXN0IGFuZCBpdHMgcmVzcG9uc2UuXG4gICAqL1xuICBwdWJsaWMgY29uc3RydWN0b3IocGFyYW1zOiBSZXF1ZXN0VXJsRXJyb3JDb25zdHJ1Y3RvclBhcmFtcykge1xuICAgIGNvbnN0IGJvZHlFeGNlcnB0ID0gcGFyYW1zLnRleHQubGVuZ3RoID4gRVJST1JfTUVTU0FHRV9CT0RZX0xFTkdUSCA/IGAke3BhcmFtcy50ZXh0LnNsaWNlKDAsIEVSUk9SX01FU1NBR0VfQk9EWV9MRU5HVEgpfeKApmAgOiBwYXJhbXMudGV4dDtcbiAgICBzdXBlcihgJHtwYXJhbXMubWV0aG9kfSAke3BhcmFtcy51cmx9IGZhaWxlZCB3aXRoIHN0YXR1cyAke1N0cmluZyhwYXJhbXMuc3RhdHVzKX0ke2JvZHlFeGNlcnB0ID8gYDogJHtib2R5RXhjZXJwdH1gIDogJyd9YCk7XG4gICAgdGhpcy5uYW1lID0gJ1JlcXVlc3RVcmxFcnJvcic7XG4gICAgdGhpcy5oZWFkZXJzID0gcGFyYW1zLmhlYWRlcnM7XG4gICAgdGhpcy5tZXRob2QgPSBwYXJhbXMubWV0aG9kO1xuICAgIHRoaXMuc3RhdHVzID0gcGFyYW1zLnN0YXR1cztcbiAgICB0aGlzLnRleHQgPSBwYXJhbXMudGV4dDtcbiAgICB0aGlzLnVybCA9IHBhcmFtcy51cmw7XG4gIH1cblxuICAvKipcbiAgICogUGFyc2VzIHRoZSByZXNwb25zZSBib2R5IGFzIEpTT04uXG4gICAqXG4gICAqIEByZXR1cm5zIFRoZSBwYXJzZWQgYm9keS5cbiAgICovXG4gIHB1YmxpYyBqc29uKCk6IHVua25vd24ge1xuICAgIHJldHVybiBKU09OLnBhcnNlKHRoaXMudGV4dCk7XG4gIH1cbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgYGZldGNoYC1jb21wYXRpYmxlIGZ1bmN0aW9uIGJ1aWx0IG9uIHtAbGluayByZXF1ZXN0VXJsfSwgZm9yIFNES3MgdGhhdCB0YWtlIGEgY3VzdG9tIGBmZXRjaGAgKE9wZW5BSSxcbiAqIExhbmdDaGFpbiwgT0F1dGggY2xpZW50cykgYW5kIHdvdWxkIG90aGVyd2lzZSBoaXQgQ09SUy5cbiAqXG4gKiBVbmxpa2UgYGZldGNoYCwgaXQgbmV2ZXIgcmVqZWN0cyBvbiBhbiBIVFRQIGVycm9yIHN0YXR1czogaXQgcmVzb2x2ZXMgd2l0aCBhIHtAbGluayBSZXNwb25zZX0gY2FycnlpbmcgdGhhdCBzdGF0dXMsXG4gKiBleGFjdGx5IGFzIGBmZXRjaGAgZG9lcy4gSXQgcmVqZWN0cyB3aXRoIGEgYFR5cGVFcnJvcmAgZm9yIGEgVVJMIHRoYXQgaXMgbm90IGBodHRwOmAgb3IgYGh0dHBzOmAuXG4gKlxuICogQHBhcmFtIG9wdGlvbnMgLSBUaGUgb3B0aW9ucy5cbiAqIEByZXR1cm5zIFRoZSBgZmV0Y2hgLWNvbXBhdGlibGUgZnVuY3Rpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVSZXF1ZXN0VXJsRmV0Y2gob3B0aW9uczogQ3JlYXRlUmVxdWVzdFVybEZldGNoT3B0aW9ucyA9IHt9KTogUmVxdWVzdFVybEZldGNoIHtcbiAgcmV0dXJuIGFzeW5jIChpbnB1dCwgaW5pdCA9IHt9KSA9PiB7XG4gICAgbGV0IHJlcXVlc3Q6IG51bGwgfCBSZXF1ZXN0ID0gbnVsbDtcbiAgICBsZXQgdXJsOiBzdHJpbmc7XG4gICAgaWYgKHR5cGVvZiBpbnB1dCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHVybCA9IGlucHV0O1xuICAgIH0gZWxzZSBpZiAoJ21ldGhvZCcgaW4gaW5wdXQpIHtcbiAgICAgIC8vIEEgYFVSTGAgaGFzIG5vIGBtZXRob2RgOyBgaW5zdGFuY2VvZmAgd291bGQgZmFpbCBhY3Jvc3Mgd2luZG93cy5cbiAgICAgIHJlcXVlc3QgPSBpbnB1dDtcbiAgICAgIHVybCA9IGlucHV0LnVybDtcbiAgICB9IGVsc2Uge1xuICAgICAgdXJsID0gaW5wdXQuaHJlZjtcbiAgICB9XG4gICAgY29uc3QgbWV0aG9kID0gKGluaXQubWV0aG9kID8/IHJlcXVlc3Q/Lm1ldGhvZCA/PyAnR0VUJykudG9VcHBlckNhc2UoKTtcbiAgICBjb25zdCBoZWFkZXJzID0gdG9IZWFkZXJSZWNvcmQocmVxdWVzdD8uaGVhZGVycywgaW5pdC5oZWFkZXJzKTtcbiAgICBsZXQgYm9keTogUmVxdWVzdFVybEV4Qm9keSB8IHVuZGVmaW5lZCA9IGluaXQuYm9keSA/PyB1bmRlZmluZWQ7XG4gICAgaWYgKGJvZHkgPT09IHVuZGVmaW5lZCAmJiByZXF1ZXN0ICYmIG1ldGhvZCAhPT0gJ0dFVCcgJiYgbWV0aG9kICE9PSAnSEVBRCcpIHtcbiAgICAgIGJvZHkgPSBhd2FpdCByZXF1ZXN0LmFycmF5QnVmZmVyKCk7XG4gICAgfVxuICAgIGNvbnN0IHBhcmFtczogUmVxdWVzdFVybEV4UGFyYW1zID0ge1xuICAgICAgYWJvcnRTaWduYWw6IGluaXQuc2lnbmFsID8/IHJlcXVlc3Q/LnNpZ25hbCA/PyB1bmRlZmluZWQsXG4gICAgICBib2R5LFxuICAgICAgaGVhZGVycyxcbiAgICAgIG1ldGhvZCxcbiAgICAgIHNob3VsZFRocm93T25IdHRwRXJyb3I6IGZhbHNlLFxuICAgICAgdGltZW91dEluTWlsbGlzZWNvbmRzOiBvcHRpb25zLnRpbWVvdXRJbk1pbGxpc2Vjb25kcyxcbiAgICAgIHVybFxuICAgIH07XG5cbiAgICBpZiAob3B0aW9ucy5zaG91bGRTdHJlYW0pIHtcbiAgICAgIGNvbnN0IHN0cmVhbVJlc3BvbnNlID0gYXdhaXQgcmVxdWVzdFVybFN0cmVhbShwYXJhbXMpO1xuICAgICAgcmV0dXJuIGNyZWF0ZVJlc3BvbnNlKHN0cmVhbVJlc3BvbnNlLnN0YXR1cywgc3RyZWFtUmVzcG9uc2UuaGVhZGVycywgc3RyZWFtUmVzcG9uc2UuYm9keSwgc3RyZWFtUmVzcG9uc2UudXJsKTtcbiAgICB9XG5cbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHJlcXVlc3RVcmxFeChwYXJhbXMpO1xuICAgIHJldHVybiBjcmVhdGVSZXNwb25zZShyZXNwb25zZS5zdGF0dXMsIHJlc3BvbnNlLmhlYWRlcnMsIHJlc3BvbnNlLmFycmF5QnVmZmVyLCB1cmwpO1xuICB9O1xufVxuXG4vKipcbiAqIEVuY29kZXMgYSByZXF1ZXN0IGZvciBhIHRyYW5zcG9ydDogdmFsaWRhdGVzIHRoZSBVUkwsIGNvbWJpbmVzIHRoZSBhYm9ydCBzaWduYWwgd2l0aCB0aGUgdGltZW91dCwgZW5jb2RlcyB0aGUgYm9keVxuICogYW5kIHNldHRsZXMgdGhlIGNvbnRlbnQgdHlwZS5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHJlcXVlc3QuXG4gKiBAcmV0dXJucyBUaGUgZW5jb2RlZCByZXF1ZXN0LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZW5jb2RlUmVxdWVzdFVybFJlcXVlc3QocGFyYW1zOiBFbmNvZGVSZXF1ZXN0VXJsUmVxdWVzdFBhcmFtcyk6IFByb21pc2U8RW5jb2RlZFJlcXVlc3RVcmxSZXF1ZXN0PiB7XG4gIGNvbnN0IHVybCA9IGFzc2VydEh0dHBVcmwocGFyYW1zLnVybCk7XG4gIGNvbnN0IGFib3J0U2lnbmFsID0gYWJvcnRTaWduYWxBbnkoXG4gICAgcGFyYW1zLmFib3J0U2lnbmFsLFxuICAgIHBhcmFtcy50aW1lb3V0SW5NaWxsaXNlY29uZHMgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IGFib3J0U2lnbmFsVGltZW91dChwYXJhbXMudGltZW91dEluTWlsbGlzZWNvbmRzKVxuICApO1xuICBhYm9ydFNpZ25hbC50aHJvd0lmQWJvcnRlZCgpO1xuXG4gIGNvbnN0IGVuY29kZWRCb2R5ID0gYXdhaXQgZW5jb2RlQm9keShwYXJhbXMuYm9keSk7XG4gIGFib3J0U2lnbmFsLnRocm93SWZBYm9ydGVkKCk7XG5cbiAgY29uc3QgaGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHsgLi4ucGFyYW1zLmhlYWRlcnMgfTtcbiAgY29uc3QgaGFzQ29udGVudFR5cGVIZWFkZXIgPSBPYmplY3Qua2V5cyhoZWFkZXJzKS5zb21lKChuYW1lKSA9PiBuYW1lLnRvTG93ZXJDYXNlKCkgPT09IENPTlRFTlRfVFlQRV9IRUFERVIpO1xuICBjb25zdCBjb250ZW50VHlwZSA9IHBhcmFtcy5jb250ZW50VHlwZSA/PyAoaGFzQ29udGVudFR5cGVIZWFkZXIgPyB1bmRlZmluZWQgOiBlbmNvZGVkQm9keS5jb250ZW50VHlwZSk7XG4gIGlmIChjb250ZW50VHlwZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgZm9yIChjb25zdCBuYW1lIG9mIE9iamVjdC5rZXlzKGhlYWRlcnMpKSB7XG4gICAgICBpZiAobmFtZS50b0xvd2VyQ2FzZSgpID09PSBDT05URU5UX1RZUEVfSEVBREVSKSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZHluYW1pYy1kZWxldGUgLS0gQSBoZWFkZXIgcmVjb3JkIGlzIGtleWVkIGJ5IG5hbWUuXG4gICAgICAgIGRlbGV0ZSBoZWFkZXJzW25hbWVdO1xuICAgICAgfVxuICAgIH1cbiAgICBoZWFkZXJzWydDb250ZW50LVR5cGUnXSA9IGNvbnRlbnRUeXBlO1xuICB9XG5cbiAgcmV0dXJuIG5vcm1hbGl6ZU9wdGlvbmFsUHJvcGVydGllczxFbmNvZGVkUmVxdWVzdFVybFJlcXVlc3Q+KHtcbiAgICBhYm9ydFNpZ25hbCxcbiAgICBib2R5OiBlbmNvZGVkQm9keS5ib2R5LFxuICAgIGhlYWRlcnMsXG4gICAgbWV0aG9kOiAocGFyYW1zLm1ldGhvZCA/PyAnR0VUJykudG9VcHBlckNhc2UoKSxcbiAgICB1cmxcbiAgfSk7XG59XG5cbi8qKlxuICogUmVxdWVzdHMgYSBVUkwgdGhyb3VnaCB7QGxpbmsgcmVxdWVzdFVybH0sIHdpdGggYW4gYWJvcnQgc2lnbmFsLCBhIHRpbWVvdXQsIHJpY2hlciBib2RpZXMsIGEgcHJvdG9jb2wgY2hlY2sgYW5kIGFcbiAqIHtAbGluayBSZXF1ZXN0VXJsRXJyb3J9IGZvciBhbiBIVFRQIGVycm9yIHN0YXR1cy5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHJlcXVlc3QuXG4gKiBAcmV0dXJucyBUaGUgcmVzcG9uc2UuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZXF1ZXN0VXJsRXgocGFyYW1zOiBSZXF1ZXN0VXJsRXhQYXJhbXMpOiBQcm9taXNlPFJlcXVlc3RVcmxSZXNwb25zZT4ge1xuICBjb25zdCByZXF1ZXN0ID0gYXdhaXQgZW5jb2RlUmVxdWVzdFVybFJlcXVlc3QocGFyYW1zKTtcbiAgY29uc3Qgb2JzaWRpYW5SZXF1ZXN0OiBSZXF1ZXN0VXJsUGFyYW0gPSBub3JtYWxpemVPcHRpb25hbFByb3BlcnRpZXM8UmVxdWVzdFVybFBhcmFtPih7XG4gICAgYm9keTogcmVxdWVzdC5ib2R5LFxuICAgIGhlYWRlcnM6IHsgLi4ucmVxdWVzdC5oZWFkZXJzIH0sXG4gICAgbWV0aG9kOiByZXF1ZXN0Lm1ldGhvZCxcbiAgICB0aHJvdzogZmFsc2UsXG4gICAgdXJsOiByZXF1ZXN0LnVybFxuICB9KTtcbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCByYWNlV2l0aEFib3J0KFByb21pc2UucmVzb2x2ZShyZXF1ZXN0VXJsKG9ic2lkaWFuUmVxdWVzdCkpLCByZXF1ZXN0LmFib3J0U2lnbmFsKTtcbiAgaWYgKChwYXJhbXMuc2hvdWxkVGhyb3dPbkh0dHBFcnJvciA/PyB0cnVlKSAmJiByZXNwb25zZS5zdGF0dXMgPj0gSFRUUF9FUlJPUl9TVEFUVVNfTUlOKSB7XG4gICAgdGhyb3cgbmV3IFJlcXVlc3RVcmxFcnJvcih7XG4gICAgICBoZWFkZXJzOiByZXNwb25zZS5oZWFkZXJzLFxuICAgICAgbWV0aG9kOiByZXF1ZXN0Lm1ldGhvZCxcbiAgICAgIHN0YXR1czogcmVzcG9uc2Uuc3RhdHVzLFxuICAgICAgdGV4dDogcmVzcG9uc2UudGV4dCxcbiAgICAgIHVybDogcmVxdWVzdC51cmxcbiAgICB9KTtcbiAgfVxuICByZXR1cm4gcmVzcG9uc2U7XG59XG5cbi8qKlxuICogUmVxdWVzdHMgYSBVUkwgYW5kIHJldHVybnMgaXRzIGJvZHkgYXMgYSBzdHJlYW0uXG4gKlxuICogT24gZGVza3RvcCB0aGUgcmVxdWVzdCBnb2VzIHRocm91Z2ggYG5vZGU6aHR0cGAgLyBgbm9kZTpodHRwc2AsIHNvIHRoZSBib2R5IHN0cmVhbXMgYXMgaXQgYXJyaXZlcywgYW4gYWJvcnQgcmVhbGx5XG4gKiBjYW5jZWxzIHRoZSByZXF1ZXN0LCBhbmQgcmVkaXJlY3RzIGFyZSBmb2xsb3dlZC4gT24gbW9iaWxlIGl0IGZhbGxzIGJhY2sgdG8ge0BsaW5rIHJlcXVlc3RVcmx9LCBhbmQgdGhlIHdob2xlIGJvZHlcbiAqIGFycml2ZXMgYXMgYSBzaW5nbGUgY2h1bmsuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSByZXF1ZXN0LlxuICogQHJldHVybnMgVGhlIHJlc3BvbnNlLCB3aXRoIGEgc3RyZWFtZWQgYm9keS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlcXVlc3RVcmxTdHJlYW0ocGFyYW1zOiBSZXF1ZXN0VXJsU3RyZWFtUGFyYW1zKTogUHJvbWlzZTxSZXF1ZXN0VXJsU3RyZWFtUmVzcG9uc2U+IHtcbiAgY29uc3QgcmVxdWVzdCA9IGF3YWl0IGVuY29kZVJlcXVlc3RVcmxSZXF1ZXN0KHBhcmFtcyk7XG4gIGxldCByZXNwb25zZTogUmVxdWVzdFVybFN0cmVhbVJlc3BvbnNlO1xuICBpZiAoUGxhdGZvcm0uaXNEZXNrdG9wQXBwKSB7XG4gICAgY29uc3QgeyBvcGVuRGVza3RvcFJlcXVlc3RVcmxTdHJlYW0gfSA9IGF3YWl0IGltcG9ydCgnLi9kZXNrdG9wLXJlcXVlc3QtdXJsLXN0cmVhbS50cycpO1xuICAgIHJlc3BvbnNlID0gYXdhaXQgb3BlbkRlc2t0b3BSZXF1ZXN0VXJsU3RyZWFtKHJlcXVlc3QpO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IGJ1ZmZlcmVkUmVzcG9uc2UgPSBhd2FpdCByZXF1ZXN0VXJsRXgoe1xuICAgICAgYWJvcnRTaWduYWw6IHJlcXVlc3QuYWJvcnRTaWduYWwsXG4gICAgICBib2R5OiByZXF1ZXN0LmJvZHksXG4gICAgICBoZWFkZXJzOiByZXF1ZXN0LmhlYWRlcnMsXG4gICAgICBtZXRob2Q6IHJlcXVlc3QubWV0aG9kLFxuICAgICAgc2hvdWxkVGhyb3dPbkh0dHBFcnJvcjogZmFsc2UsXG4gICAgICB1cmw6IHJlcXVlc3QudXJsXG4gICAgfSk7XG4gICAgcmVzcG9uc2UgPSB7XG4gICAgICBib2R5OiBjcmVhdGVTaW5nbGVDaHVua1N0cmVhbShidWZmZXJlZFJlc3BvbnNlLmFycmF5QnVmZmVyKSxcbiAgICAgIGhlYWRlcnM6IGJ1ZmZlcmVkUmVzcG9uc2UuaGVhZGVycyxcbiAgICAgIHN0YXR1czogYnVmZmVyZWRSZXNwb25zZS5zdGF0dXMsXG4gICAgICB1cmw6IHJlcXVlc3QudXJsXG4gICAgfTtcbiAgfVxuXG4gIGlmICgocGFyYW1zLnNob3VsZFRocm93T25IdHRwRXJyb3IgPz8gdHJ1ZSkgJiYgcmVzcG9uc2Uuc3RhdHVzID49IEhUVFBfRVJST1JfU1RBVFVTX01JTikge1xuICAgIGNvbnN0IHRleHQgPSBuZXcgVGV4dERlY29kZXIoKS5kZWNvZGUoYXdhaXQgcmVhZFN0cmVhbShyZXNwb25zZS5ib2R5KSk7XG4gICAgdGhyb3cgbmV3IFJlcXVlc3RVcmxFcnJvcih7XG4gICAgICBoZWFkZXJzOiByZXNwb25zZS5oZWFkZXJzLFxuICAgICAgbWV0aG9kOiByZXF1ZXN0Lm1ldGhvZCxcbiAgICAgIHN0YXR1czogcmVzcG9uc2Uuc3RhdHVzLFxuICAgICAgdGV4dCxcbiAgICAgIHVybDogcmVzcG9uc2UudXJsXG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIHJlc3BvbnNlO1xufVxuXG5mdW5jdGlvbiBhc3NlcnRIdHRwVXJsKHVybDogc3RyaW5nKTogc3RyaW5nIHtcbiAgbGV0IHBhcnNlZFVybDogVVJMO1xuICB0cnkge1xuICAgIHBhcnNlZFVybCA9IG5ldyBVUkwodXJsKTtcbiAgfSBjYXRjaCB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgSW52YWxpZCBVUkw6ICR7dXJsfWApO1xuICB9XG4gIGlmICghU1VQUE9SVEVEX1BST1RPQ09MUy5oYXMocGFyc2VkVXJsLnByb3RvY29sKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYFVuc3VwcG9ydGVkIHByb3RvY29sICR7cGFyc2VkVXJsLnByb3RvY29sfSBpbiAke3VybH06IG9ubHkgaHR0cDogYW5kIGh0dHBzOiBVUkxzIGNhbiBiZSByZXF1ZXN0ZWRgKTtcbiAgfVxuICByZXR1cm4gdXJsO1xufVxuXG5mdW5jdGlvbiBjb25jYXRCeXRlcyhjaHVua3M6IHJlYWRvbmx5IFVpbnQ4QXJyYXlbXSk6IEFycmF5QnVmZmVyIHtcbiAgY29uc3QgbGVuZ3RoID0gY2h1bmtzLnJlZHVjZSgoc3VtLCBjaHVuaykgPT4gc3VtICsgY2h1bmsuYnl0ZUxlbmd0aCwgMCk7XG4gIGNvbnN0IGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkobGVuZ3RoKTtcbiAgbGV0IG9mZnNldCA9IDA7XG4gIGZvciAoY29uc3QgY2h1bmsgb2YgY2h1bmtzKSB7XG4gICAgYnl0ZXMuc2V0KGNodW5rLCBvZmZzZXQpO1xuICAgIG9mZnNldCArPSBjaHVuay5ieXRlTGVuZ3RoO1xuICB9XG4gIHJldHVybiBieXRlcy5idWZmZXI7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVJlc3BvbnNlKHN0YXR1czogbnVtYmVyLCBoZWFkZXJzOiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+PiwgYm9keTogQXJyYXlCdWZmZXIgfCBSZWFkYWJsZVN0cmVhbTxVaW50OEFycmF5PiwgdXJsOiBzdHJpbmcpOiBSZXNwb25zZSB7XG4gIGNvbnN0IHJlc3BvbnNlID0gbmV3IFJlc3BvbnNlKE5VTExfQk9EWV9TVEFUVVNFUy5oYXMoc3RhdHVzKSA/IG51bGwgOiBib2R5LCB7XG4gICAgaGVhZGVyczogbmV3IEhlYWRlcnMoeyAuLi5oZWFkZXJzIH0pLFxuICAgIHN0YXR1c1xuICB9KTtcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHJlc3BvbnNlLCAndXJsJywgeyB2YWx1ZTogdXJsIH0pO1xuICByZXR1cm4gcmVzcG9uc2U7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVNpbmdsZUNodW5rU3RyZWFtKGFycmF5QnVmZmVyOiBBcnJheUJ1ZmZlcik6IFJlYWRhYmxlU3RyZWFtPFVpbnQ4QXJyYXk+IHtcbiAgcmV0dXJuIG5ldyBSZWFkYWJsZVN0cmVhbTxVaW50OEFycmF5Pih7XG4gICAgc3RhcnQoY29udHJvbGxlcik6IHZvaWQge1xuICAgICAgaWYgKGFycmF5QnVmZmVyLmJ5dGVMZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnRyb2xsZXIuZW5xdWV1ZShuZXcgVWludDhBcnJheShhcnJheUJ1ZmZlcikpO1xuICAgICAgfVxuICAgICAgY29udHJvbGxlci5jbG9zZSgpO1xuICAgIH1cbiAgfSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGVuY29kZUJvZHkoYm9keTogUmVxdWVzdFVybEV4Qm9keSB8IHVuZGVmaW5lZCk6IFByb21pc2U8RW5jb2RlZEJvZHk+IHtcbiAgaWYgKGJvZHkgPT09IHVuZGVmaW5lZCB8fCB0eXBlb2YgYm9keSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gbm9ybWFsaXplT3B0aW9uYWxQcm9wZXJ0aWVzPEVuY29kZWRCb2R5Pih7IGJvZHkgfSk7XG4gIH1cblxuICAvLyBgaW5zdGFuY2VvZmAgZmFpbHMgYWNyb3NzIHdpbmRvd3MsIHNvIHRoZSBib2R5IGtpbmRzIGFyZSB0b2xkIGFwYXJ0IGJ5IHRoZWlyIGJ1aWx0LWluIHRhZ3MuXG4gIHN3aXRjaCAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGJvZHkpKSB7XG4gICAgY2FzZSAnW29iamVjdCBBcnJheUJ1ZmZlcl0nOiB7XG4gICAgICByZXR1cm4geyBib2R5OiBib2R5IGFzIEFycmF5QnVmZmVyIH07XG4gICAgfVxuICAgIGNhc2UgJ1tvYmplY3QgQmxvYl0nOlxuICAgIGNhc2UgJ1tvYmplY3QgRmlsZV0nOiB7XG4gICAgICBjb25zdCBibG9iID0gYm9keSBhcyBCbG9iO1xuICAgICAgcmV0dXJuIG5vcm1hbGl6ZU9wdGlvbmFsUHJvcGVydGllczxFbmNvZGVkQm9keT4oeyBib2R5OiBhd2FpdCBibG9iLmFycmF5QnVmZmVyKCksIGNvbnRlbnRUeXBlOiBibG9iLnR5cGUgfHwgdW5kZWZpbmVkIH0pO1xuICAgIH1cbiAgICBjYXNlICdbb2JqZWN0IEZvcm1EYXRhXSc6IHtcbiAgICAgIHJldHVybiBhd2FpdCBlbmNvZGVGb3JtRGF0YShib2R5IGFzIEZvcm1EYXRhKTtcbiAgICB9XG4gICAgY2FzZSAnW29iamVjdCBSZWFkYWJsZVN0cmVhbV0nOiB7XG4gICAgICByZXR1cm4geyBib2R5OiBhd2FpdCByZWFkU3RyZWFtKGJvZHkgYXMgUmVhZGFibGVTdHJlYW08VWludDhBcnJheT4pIH07XG4gICAgfVxuICAgIGNhc2UgJ1tvYmplY3QgVVJMU2VhcmNoUGFyYW1zXSc6IHtcbiAgICAgIHJldHVybiB7IGJvZHk6IChib2R5IGFzIFVSTFNlYXJjaFBhcmFtcykudG9TdHJpbmcoKSwgY29udGVudFR5cGU6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQ7Y2hhcnNldD1VVEYtOCcgfTtcbiAgICB9XG4gICAgZGVmYXVsdDoge1xuICAgICAgaWYgKEFycmF5QnVmZmVyLmlzVmlldyhib2R5KSkge1xuICAgICAgICByZXR1cm4geyBib2R5OiBuZXcgVWludDhBcnJheShib2R5LmJ1ZmZlciwgYm9keS5ieXRlT2Zmc2V0LCBib2R5LmJ5dGVMZW5ndGgpLnNsaWNlKCkuYnVmZmVyIH07XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBVbnN1cHBvcnRlZCByZXF1ZXN0IGJvZHk6ICR7T2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGJvZHkpfWApO1xuICAgIH1cbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBlbmNvZGVGb3JtRGF0YShmb3JtRGF0YTogRm9ybURhdGEpOiBQcm9taXNlPEVuY29kZWRCb2R5PiB7XG4gIGNvbnN0IGJvdW5kYXJ5ID0gYC0tLS1PYnNpZGlhbkxpYkZvcm1Cb3VuZGFyeSR7Z2VuZXJhdGVSYW5kb21IZXgoKX1gO1xuICBjb25zdCB0ZXh0RW5jb2RlciA9IG5ldyBUZXh0RW5jb2RlcigpO1xuICBjb25zdCBjaHVua3M6IFVpbnQ4QXJyYXlbXSA9IFtdO1xuICBjb25zdCBlbnRyaWVzOiBbc3RyaW5nLCBGb3JtRGF0YUVudHJ5VmFsdWVdW10gPSBbXTtcbiAgZm9ybURhdGEuZm9yRWFjaCgodmFsdWUsIG5hbWUpID0+IHtcbiAgICBlbnRyaWVzLnB1c2goW25hbWUsIHZhbHVlXSk7XG4gIH0pO1xuXG4gIGZvciAoY29uc3QgW25hbWUsIHZhbHVlXSBvZiBlbnRyaWVzKSB7XG4gICAgbGV0IGhlYWRlciA9IGAtLSR7Ym91bmRhcnl9XFxyXFxuQ29udGVudC1EaXNwb3NpdGlvbjogZm9ybS1kYXRhOyBuYW1lPVwiJHtlc2NhcGVNdWx0aXBhcnROYW1lKG5hbWUpfVwiYDtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgY2h1bmtzLnB1c2godGV4dEVuY29kZXIuZW5jb2RlKGAke2hlYWRlcn1cXHJcXG5cXHJcXG4ke3ZhbHVlfVxcclxcbmApKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBoZWFkZXIgKz0gYDsgZmlsZW5hbWU9XCIke2VzY2FwZU11bHRpcGFydE5hbWUodmFsdWUubmFtZSl9XCJcXHJcXG5Db250ZW50LVR5cGU6ICR7dmFsdWUudHlwZSB8fCAnYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtJ31cXHJcXG5cXHJcXG5gO1xuICAgIGNodW5rcy5wdXNoKHRleHRFbmNvZGVyLmVuY29kZShoZWFkZXIpLCBuZXcgVWludDhBcnJheShhd2FpdCB2YWx1ZS5hcnJheUJ1ZmZlcigpKSwgdGV4dEVuY29kZXIuZW5jb2RlKCdcXHJcXG4nKSk7XG4gIH1cblxuICBjaHVua3MucHVzaCh0ZXh0RW5jb2Rlci5lbmNvZGUoYC0tJHtib3VuZGFyeX0tLVxcclxcbmApKTtcbiAgcmV0dXJuIHsgYm9keTogY29uY2F0Qnl0ZXMoY2h1bmtzKSwgY29udGVudFR5cGU6IGBtdWx0aXBhcnQvZm9ybS1kYXRhOyBib3VuZGFyeT0ke2JvdW5kYXJ5fWAgfTtcbn1cblxuZnVuY3Rpb24gZXNjYXBlTXVsdGlwYXJ0TmFtZShuYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICAvLyBUaGUgZXNjYXBpbmcgdGhlIEhUTUwgc3RhbmRhcmQgcHJlc2NyaWJlcyBmb3IgbXVsdGlwYXJ0L2Zvcm0tZGF0YSBuYW1lcyBhbmQgZmlsZSBuYW1lcy5cbiAgcmV0dXJuIG5hbWUucmVwbGFjZUFsbCgnXCInLCAnJTIyJykucmVwbGFjZUFsbCgnXFxyJywgJyUwRCcpLnJlcGxhY2VBbGwoJ1xcbicsICclMEEnKTtcbn1cblxuZnVuY3Rpb24gZ2VuZXJhdGVSYW5kb21IZXgoKTogc3RyaW5nIHtcbiAgcmV0dXJuIEFycmF5LmZyb20oeyBsZW5ndGg6IEJPVU5EQVJZX1JBTkRPTV9QQVJUX0NPVU5UIH0sICgpID0+IE1hdGgucmFuZG9tKCkudG9TdHJpbmcoSEVYX1JBRElYKS5zbGljZShSQU5ET01fUEFSVF9TVEFSVCkpLmpvaW4oJycpO1xufVxuXG5hc3luYyBmdW5jdGlvbiByYWNlV2l0aEFib3J0PFQ+KHByb21pc2U6IFByb21pc2U8VD4sIGFib3J0U2lnbmFsOiBBYm9ydFNpZ25hbCk6IFByb21pc2U8VD4ge1xuICBsZXQgcmVqZWN0T25BYm9ydDogKHJlYXNvbjogRXJyb3IpID0+IHZvaWQgPSBub29wO1xuICBjb25zdCBhYm9ydFByb21pc2UgPSBuZXcgUHJvbWlzZTxuZXZlcj4oKF9yZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICByZWplY3RPbkFib3J0ID0gcmVqZWN0O1xuICB9KTtcbiAgdXNpbmcgX2Fib3J0TGlzdGVuZXIgPSBvbkFib3J0KGFib3J0U2lnbmFsLCAoKSA9PiB7XG4gICAgLy8gVGhlIHJlYXNvbiBpcyB3aGF0ZXZlciB0aGUgY2FsbGVyIGFib3J0ZWQgd2l0aCwgYW4gYEFib3J0RXJyb3JgIG9yIGBUaW1lb3V0RXJyb3JgIGJ5IGRlZmF1bHQuXG4gICAgcmVqZWN0T25BYm9ydChhYm9ydFNpZ25hbC5yZWFzb24gYXMgRXJyb3IpO1xuICB9KTtcbiAgcmV0dXJuIGF3YWl0IFByb21pc2UucmFjZShbcHJvbWlzZSwgYWJvcnRQcm9taXNlXSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJlYWRTdHJlYW0oc3RyZWFtOiBSZWFkYWJsZVN0cmVhbTxVaW50OEFycmF5Pik6IFByb21pc2U8QXJyYXlCdWZmZXI+IHtcbiAgY29uc3QgcmVhZGVyID0gc3RyZWFtLmdldFJlYWRlcigpO1xuICBjb25zdCBjaHVua3M6IFVpbnQ4QXJyYXlbXSA9IFtdO1xuICBmb3IgKDs7KSB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVhZGVyLnJlYWQoKTtcbiAgICBpZiAocmVzdWx0LmRvbmUpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBjaHVua3MucHVzaChyZXN1bHQudmFsdWUpO1xuICB9XG4gIHJldHVybiBjb25jYXRCeXRlcyhjaHVua3MpO1xufVxuXG5mdW5jdGlvbiB0b0hlYWRlclJlY29yZChyZXF1ZXN0SGVhZGVyczogSGVhZGVycyB8IHVuZGVmaW5lZCwgaW5pdEhlYWRlcnM6IEhlYWRlcnNJbml0IHwgdW5kZWZpbmVkKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG4gIGNvbnN0IGhlYWRlcnMgPSBuZXcgSGVhZGVycyhyZXF1ZXN0SGVhZGVycyk7XG4gIG5ldyBIZWFkZXJzKGluaXRIZWFkZXJzKS5mb3JFYWNoKCh2YWx1ZSwgbmFtZSkgPT4ge1xuICAgIGhlYWRlcnMuc2V0KG5hbWUsIHZhbHVlKTtcbiAgfSk7XG4gIGNvbnN0IHJlY29yZDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBoZWFkZXJzLmZvckVhY2goKHZhbHVlLCBuYW1lKSA9PiB7XG4gICAgcmVjb3JkW25hbWVdID0gdmFsdWU7XG4gIH0pO1xuICByZXR1cm4gcmVjb3JkO1xufVxuLyogZXNsaW50LWVuYWJsZSBuL25vLXVuc3VwcG9ydGVkLWZlYXR1cmVzL25vZGUtYnVpbHRpbnMgLS0gVGhlc2UgYXJlIE9ic2lkaWFuIHJlbmRlcmVyIFdlYiBBUElzLCBub3QgTm9kZSBidWlsdGlucy4gKi9cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7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
|