obsidian-dev-utils
Version:
This is the collection of useful functions that you can use for your Obsidian plugin development
238 lines (235 loc) • 32.3 kB
JavaScript
/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/
(function initCjs(){const globalThisRecord=globalThis;globalThisRecord["__name"]??=name;const originalRequire=require;if(originalRequire&&!originalRequire.__isPatched){require=Object.assign(id=>requirePatched(id),originalRequire,{__isPatched:true})}const newFuncs={__extractDefault(){return extractDefault},process(){const browserProcess={browser:true,cwd(){return"/"},env:{},platform:"android"};return browserProcess}};for(const key of Object.keys(newFuncs)){globalThisRecord[key]??=newFuncs[key]?.()}function name(obj){return obj}__name(name,"name");function extractDefault(module){return module&&module.__esModule&&"default"in module?module.default:module}__name(extractDefault,"extractDefault");function requirePatched(id){const module=originalRequire?.(id);if(module){return extractDefault(module)}if(id==="process"||id==="node:process"){console.error(`Module not found: ${id}. Fake process object is returned instead.`);return globalThis.process}console.error(`Module not found: ${id}. Empty object is returned instead.`);return{}}__name(requirePatched,"requirePatched")})();
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var String_exports = {};
__export(String_exports, {
ensureEndsWith: () => ensureEndsWith,
ensureLfEndings: () => ensureLfEndings,
ensureStartsWith: () => ensureStartsWith,
escape: () => escape,
getLfNormalizedOffsetToOriginalOffsetMapper: () => getLfNormalizedOffsetToOriginalOffsetMapper,
hasSingleOccurrence: () => hasSingleOccurrence,
indent: () => indent,
insertAt: () => insertAt,
makeValidVariableName: () => makeValidVariableName,
normalize: () => normalize,
replace: () => replace,
replaceAll: () => replaceAll,
replaceAllAsync: () => replaceAllAsync,
trimEnd: () => trimEnd,
trimStart: () => trimStart,
unescape: () => unescape,
unindent: () => unindent
});
module.exports = __toCommonJS(String_exports);
var import_AbortController = require('./AbortController.cjs');
var import_Error = require('./Error.cjs');
var import_RegExp = require('./RegExp.cjs');
var import_ValueProvider = require('./ValueProvider.cjs');
const ESCAPE_MAP = {
"\n": "\\n",
"\r": "\\r",
" ": "\\t",
"\b": "\\b",
"\f": "\\f",
"'": "\\'",
'"': '\\"',
"\\": "\\\\"
};
const CR = "\r";
const LF = "\n";
const NOT_FOUND_INDEX = -1;
const UNESCAPE_MAP = {};
for (const [key, value] of Object.entries(ESCAPE_MAP)) {
UNESCAPE_MAP[value] = key;
}
function ensureEndsWith(str, suffix) {
return str.endsWith(suffix) ? str : str + suffix;
}
function ensureLfEndings(str) {
return str.replaceAll(/\r\n?/g, "\n");
}
function ensureStartsWith(str, prefix) {
return str.startsWith(prefix) ? str : prefix + str;
}
function escape(str) {
return replace(str, ESCAPE_MAP);
}
function getLfNormalizedOffsetToOriginalOffsetMapper(str) {
const lfStr = ensureLfEndings(str);
const lfOffsetToOriginalOffsetMap = [];
for (let i = 0; i < str.length; i++) {
if (str[i] === CR && str[i + 1] === LF) {
lfOffsetToOriginalOffsetMap.push(i + 1);
i++;
} else {
lfOffsetToOriginalOffsetMap.push(i);
}
}
return (lfOffset) => {
if (lfOffset < 0) {
return lfOffset;
}
if (lfOffset >= lfOffsetToOriginalOffsetMap.length) {
return lfOffset - lfOffsetToOriginalOffsetMap.length + str.length;
}
if (lfOffsetToOriginalOffsetMap[lfOffset] === void 0) {
const message = "Could not map offset";
console.error(message, {
lfOffset,
lfStr,
str
});
throw new Error(message);
}
return lfOffsetToOriginalOffsetMap[lfOffset];
};
}
function hasSingleOccurrence(str, searchValue) {
const firstIndex = str.indexOf(searchValue);
const lastIndex = str.lastIndexOf(searchValue);
return firstIndex !== NOT_FOUND_INDEX && firstIndex === lastIndex;
}
function indent(text, prefix) {
return text.split("\n").map((line) => `${prefix}${line}`).join("\n");
}
function insertAt(str, substring, startIndex, endIndex) {
endIndex ??= startIndex;
return str.slice(0, startIndex) + substring + str.slice(endIndex);
}
function makeValidVariableName(str) {
return replaceAll(str, /[^a-zA-Z0-9_]/g, "_");
}
function normalize(str) {
return replaceAll(str, /\u00A0|\u202F/g, " ").normalize("NFC");
}
function replace(str, replacementsMap) {
const regExp = new RegExp(Object.keys(replacementsMap).map((source) => (0, import_RegExp.escapeRegExp)(source)).join("|"), "g");
return replaceAll(str, regExp, ({ substring: source }) => replacementsMap[source] ?? (0, import_Error.throwExpression)(new Error(`Unexpected replacement source: ${source}`)));
}
function replaceAll(str, searchValue, replacer) {
if (typeof replacer === "undefined") {
return str;
}
if (searchValue instanceof RegExp && !searchValue.global) {
searchValue = new RegExp(searchValue.source, `${searchValue.flags}g`);
}
if (typeof replacer === "string") {
return str.replaceAll(searchValue, replacer);
}
return str.replaceAll(searchValue, (substring, ...args) => {
const SOURCE_INDEX_OFFSET_FOR_GROUP_ARG = 2;
const hasGroupsArg = typeof args.at(-1) === "object";
const sourceIndex = hasGroupsArg ? args.length - SOURCE_INDEX_OFFSET_FOR_GROUP_ARG : args.length - 1;
const commonArgs = {
groups: hasGroupsArg ? args.at(-1) : void 0,
missingGroupIndices: [],
offset: args.at(sourceIndex - 1),
source: args.at(sourceIndex),
substring
};
const groupArgs = args.slice(0, sourceIndex - 1).map((arg, index) => {
if (typeof arg === "string") {
return arg;
}
if (typeof arg === "undefined") {
commonArgs.missingGroupIndices.push(index);
return "";
}
throw new Error(`Unexpected argument type: ${typeof arg}`);
});
return replacer(commonArgs, ...groupArgs) ?? commonArgs.substring;
});
}
async function replaceAllAsync(str, searchValue, replacer, abortSignal) {
abortSignal ??= (0, import_AbortController.abortSignalNever)();
abortSignal.throwIfAborted();
if (typeof replacer === "string") {
return replaceAll(str, searchValue, replacer);
}
const replacementAsyncFns = [];
replaceAll(str, searchValue, (commonArgs, ...groupArgs) => {
replacementAsyncFns.push(() => (0, import_ValueProvider.resolveValue)(replacer, abortSignal, commonArgs, ...groupArgs));
return "";
});
const replacements = [];
for (const asyncFn of replacementAsyncFns) {
abortSignal.throwIfAborted();
replacements.push(await asyncFn());
}
abortSignal.throwIfAborted();
return replaceAll(str, searchValue, (args) => replacements.shift() ?? args.substring);
}
function trimEnd(str, suffix, shouldValidate) {
if (str.endsWith(suffix)) {
return str.slice(0, -suffix.length);
}
if (shouldValidate) {
throw new Error(`String ${str} does not end with suffix ${suffix}`);
}
return str;
}
function trimStart(str, prefix, validate) {
if (str.startsWith(prefix)) {
return str.slice(prefix.length);
}
if (validate) {
throw new Error(`String ${str} does not start with prefix ${prefix}`);
}
return str;
}
function unescape(str) {
return replace(str, UNESCAPE_MAP);
}
function unindent(text, prefix, shouldThrowIfNotIndented = false) {
return text.split("\n").map((line) => {
if (line.startsWith(prefix)) {
return line.slice(prefix.length);
}
if (shouldThrowIfNotIndented) {
throw new Error(`Line "${line}" is not indented with "${prefix}"`);
}
return line;
}).join("\n");
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
ensureEndsWith,
ensureLfEndings,
ensureStartsWith,
escape,
getLfNormalizedOffsetToOriginalOffsetMapper,
hasSingleOccurrence,
indent,
insertAt,
makeValidVariableName,
normalize,
replace,
replaceAll,
replaceAllAsync,
trimEnd,
trimStart,
unescape,
unindent
});
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL1N0cmluZy50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAcGFja2FnZURvY3VtZW50YXRpb25cbiAqXG4gKiBDb250YWlucyB1dGlsaXR5IGZ1bmN0aW9ucyBmb3Igc3RyaW5nIG9wZXJhdGlvbnMuXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBNYXliZVJldHVybiB9IGZyb20gJy4vVHlwZS50cyc7XG5pbXBvcnQgdHlwZSB7IFZhbHVlUHJvdmlkZXIgfSBmcm9tICcuL1ZhbHVlUHJvdmlkZXIudHMnO1xuXG5pbXBvcnQgeyBhYm9ydFNpZ25hbE5ldmVyIH0gZnJvbSAnLi9BYm9ydENvbnRyb2xsZXIudHMnO1xuaW1wb3J0IHsgdGhyb3dFeHByZXNzaW9uIH0gZnJvbSAnLi9FcnJvci50cyc7XG5pbXBvcnQgeyBlc2NhcGVSZWdFeHAgfSBmcm9tICcuL1JlZ0V4cC50cyc7XG5pbXBvcnQgeyByZXNvbHZlVmFsdWUgfSBmcm9tICcuL1ZhbHVlUHJvdmlkZXIudHMnO1xuXG4vKipcbiAqIEEgc3luY2hyb25vdXMvYXN5bmNocm9ub3VzIGZ1bmN0aW9uIHRoYXQgZ2VuZXJhdGVzIHJlcGxhY2VtZW50IHN0cmluZ3MsIG9yIGEgc3RyaW5nIHRvIHJlcGxhY2Ugd2l0aC5cbiAqL1xuZXhwb3J0IHR5cGUgQXN5bmNSZXBsYWNlcjxSZXBsYWNlR3JvdXBBcmdzIGV4dGVuZHMgc3RyaW5nW10+ID0gVmFsdWVQcm92aWRlcjxTdHJpbmdSZXBsYWNlbWVudCwgW1JlcGxhY2VDb21tb25BcmdzLCAuLi5SZXBsYWNlR3JvdXBBcmdzXT47XG5cbi8qKlxuICogQ29tbW9uIGFyZ3VtZW50cyBmb3IgdGhlIGByZXBsYWNlQWxsYC9gcmVwbGFjZUFsbEFzeW5jYCBmdW5jdGlvbnMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVwbGFjZUNvbW1vbkFyZ3Mge1xuICAvKipcbiAgICogR3JvdXBzIG9mIHRoZSBtYXRjaC5cbiAgICovXG4gIGdyb3VwczogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPiB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogSW5kaWNlcyBvZiB0aGUgZ3JvdXBzIHRoYXQgd2VyZSBub3QgZm91bmQgaW4gdGhlIG1hdGNoLlxuICAgKi9cbiAgbWlzc2luZ0dyb3VwSW5kaWNlczogbnVtYmVyW107XG5cbiAgLyoqXG4gICAqIEFuIG9mZnNldCBvZiB0aGUgbWF0Y2guXG4gICAqL1xuICBvZmZzZXQ6IG51bWJlcjtcblxuICAvKipcbiAgICogQSBzb3VyY2Ugb2YgdGhlIG1hdGNoLlxuICAgKi9cbiAgc291cmNlOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEEgc3Vic3RyaW5nIG9mIHRoZSBtYXRjaC5cbiAgICovXG4gIHN1YnN0cmluZzogc3RyaW5nO1xufVxuXG4vKipcbiAqIEEgc3luY2hyb25vdXMgZnVuY3Rpb24gdGhhdCBnZW5lcmF0ZXMgcmVwbGFjZW1lbnQgc3RyaW5ncywgb3IgYSBzdHJpbmcgdG8gcmVwbGFjZSB3aXRoLlxuICovXG5leHBvcnQgdHlwZSBSZXBsYWNlcjxSZXBsYWNlR3JvdXBBcmdzIGV4dGVuZHMgc3RyaW5nW10+ID0gKCguLi5hcmdzOiBbUmVwbGFjZUNvbW1vbkFyZ3MsIC4uLlJlcGxhY2VHcm91cEFyZ3NdKSA9PiBTdHJpbmdSZXBsYWNlbWVudCkgfCBTdHJpbmdSZXBsYWNlbWVudDtcblxudHlwZSBTdHJpbmdSZXBsYWNlbWVudCA9IE1heWJlUmV0dXJuPHN0cmluZz47XG5cbi8qKlxuICogTWFwcGluZyBvZiBzcGVjaWFsIGNoYXJhY3RlcnMgdG8gdGhlaXIgZXNjYXBlZCBjb3VudGVycGFydHMuXG4gKi9cbmNvbnN0IEVTQ0FQRV9NQVA6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICdcXG4nOiAnXFxcXG4nLFxuICAnXFxyJzogJ1xcXFxyJyxcbiAgJ1xcdCc6ICdcXFxcdCcsXG4gICdcXGInOiAnXFxcXGInLFxuICAnXFxmJzogJ1xcXFxmJyxcbiAgJ1xcJyc6ICdcXFxcXFwnJyxcbiAgJ1wiJzogJ1xcXFxcIicsXG4gICdcXFxcJzogJ1xcXFxcXFxcJ1xufSBhcyBjb25zdDtcblxuY29uc3QgQ1IgPSAnXFxyJztcbmNvbnN0IExGID0gJ1xcbic7XG5jb25zdCBOT1RfRk9VTkRfSU5ERVggPSAtMTtcblxuLyoqXG4gKiBNYXBwaW5nIG9mIGVzY2FwZWQgc3BlY2lhbCBjaGFyYWN0ZXJzIHRvIHRoZWlyIHVuZXNjYXBlZCBjb3VudGVycGFydHMuXG4gKi9cbmNvbnN0IFVORVNDQVBFX01BUDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoRVNDQVBFX01BUCkpIHtcbiAgVU5FU0NBUEVfTUFQW3ZhbHVlXSA9IGtleTtcbn1cblxuLyoqXG4gKiBFbnN1cmVzIHRoYXQgYSBzdHJpbmcgZW5kcyB3aXRoIHRoZSBzcGVjaWZpZWQgc3VmZml4LCBhZGRpbmcgaXQgaWYgbmVjZXNzYXJ5LlxuICpcbiAqIEBwYXJhbSBzdHIgLSBUaGUgc3RyaW5nIHRvIGNoZWNrLlxuICogQHBhcmFtIHN1ZmZpeCAtIFRoZSBzdWZmaXggdG8gZW5zdXJlLlxuICogQHJldHVybnMgVGhlIHN0cmluZyB0aGF0IGVuZHMgd2l0aCB0aGUgc3VmZml4LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZW5zdXJlRW5kc1dpdGgoc3RyOiBzdHJpbmcsIHN1ZmZpeDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHN0ci5lbmRzV2l0aChzdWZmaXgpID8gc3RyIDogc3RyICsgc3VmZml4O1xufVxuXG4vKipcbiAqIEVuc3VyZXMgdGhhdCBhIHN0cmluZyBoYXMgYExGYCBsaW5lIGVuZGluZ3MuXG4gKlxuICogSXQgcmVwbGFjZXMgYENSTEZgIGxpbmUgZW5kaW5ncyB3aXRoIGBMRmAuXG4gKlxuICogQHBhcmFtIHN0ciAtIFRoZSBzdHJpbmcuXG4gKiBAcmV0dXJucyBUaGUgc3RyaW5nIHdpdGggYExGYCBsaW5lIGVuZGluZ3MuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbnN1cmVMZkVuZGluZ3Moc3RyOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gc3RyLnJlcGxhY2VBbGwoL1xcclxcbj8vZywgJ1xcbicpO1xufVxuXG4vKipcbiAqIEVuc3VyZXMgdGhhdCBhIHN0cmluZyBzdGFydHMgd2l0aCB0aGUgc3BlY2lmaWVkIHByZWZpeCwgYWRkaW5nIGl0IGlmIG5lY2Vzc2FyeS5cbiAqXG4gKiBAcGFyYW0gc3RyIC0gVGhlIHN0cmluZyB0byBjaGVjay5cbiAqIEBwYXJhbSBwcmVmaXggLSBUaGUgcHJlZml4IHRvIGVuc3VyZS5cbiAqIEByZXR1cm5zIFRoZSBzdHJpbmcgdGhhdCBzdGFydHMgd2l0aCB0aGUgcHJlZml4LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZW5zdXJlU3RhcnRzV2l0aChzdHI6IHN0cmluZywgcHJlZml4OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gc3RyLnN0YXJ0c1dpdGgocHJlZml4KSA/IHN0ciA6IHByZWZpeCArIHN0cjtcbn1cblxuLyoqXG4gKiBFc2NhcGVzIHNwZWNpYWwgY2hhcmFjdGVycyBpbiBhIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0gc3RyIC0gVGhlIHN0cmluZyB0byBlc2NhcGUuXG4gKiBAcmV0dXJucyBUaGUgZXNjYXBlZCBzdHJpbmcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlc2NhcGUoc3RyOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gcmVwbGFjZShzdHIsIEVTQ0FQRV9NQVApO1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBmdW5jdGlvbiB0aGF0IG1hcHMgTEYtbm9ybWFsaXplZCBvZmZzZXRzIHRvIG9yaWdpbmFsIG9mZnNldHMuXG4gKlxuICogQHBhcmFtIHN0ciAtIFRoZSBzdHJpbmcgdG8gZ2V0IHRoZSBMRi1ub3JtYWxpemVkIGluZGljZXMgZnJvbS5cbiAqIEByZXR1cm5zIEEgZnVuY3Rpb24gdGhhdCBtYXBzIExGLW5vcm1hbGl6ZWQgb2Zmc2V0cyB0byBvcmlnaW5hbCBvZmZzZXRzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0TGZOb3JtYWxpemVkT2Zmc2V0VG9PcmlnaW5hbE9mZnNldE1hcHBlcihzdHI6IHN0cmluZyk6IChsZk9mZnNldDogbnVtYmVyKSA9PiBudW1iZXIge1xuICBjb25zdCBsZlN0ciA9IGVuc3VyZUxmRW5kaW5ncyhzdHIpO1xuICBjb25zdCBsZk9mZnNldFRvT3JpZ2luYWxPZmZzZXRNYXA6IG51bWJlcltdID0gW107XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoc3RyW2ldID09PSBDUiAmJiBzdHJbaSArIDFdID09PSBMRikge1xuICAgICAgbGZPZmZzZXRUb09yaWdpbmFsT2Zmc2V0TWFwLnB1c2goaSArIDEpO1xuICAgICAgaSsrO1xuICAgIH0gZWxzZSB7XG4gICAgICBsZk9mZnNldFRvT3JpZ2luYWxPZmZzZXRNYXAucHVzaChpKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gKGxmT2Zmc2V0OiBudW1iZXIpOiBudW1iZXIgPT4ge1xuICAgIGlmIChsZk9mZnNldCA8IDApIHtcbiAgICAgIHJldHVybiBsZk9mZnNldDtcbiAgICB9XG4gICAgaWYgKGxmT2Zmc2V0ID49IGxmT2Zmc2V0VG9PcmlnaW5hbE9mZnNldE1hcC5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBsZk9mZnNldCAtIGxmT2Zmc2V0VG9PcmlnaW5hbE9mZnNldE1hcC5sZW5ndGggKyBzdHIubGVuZ3RoO1xuICAgIH1cblxuICAgIGlmIChsZk9mZnNldFRvT3JpZ2luYWxPZmZzZXRNYXBbbGZPZmZzZXRdID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IG1lc3NhZ2UgPSAnQ291bGQgbm90IG1hcCBvZmZzZXQnO1xuICAgICAgY29uc29sZS5lcnJvcihtZXNzYWdlLCB7XG4gICAgICAgIGxmT2Zmc2V0LFxuICAgICAgICBsZlN0cixcbiAgICAgICAgc3RyXG4gICAgICB9KTtcbiAgICAgIHRocm93IG5ldyBFcnJvcihtZXNzYWdlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbGZPZmZzZXRUb09yaWdpbmFsT2Zmc2V0TWFwW2xmT2Zmc2V0XTtcbiAgfTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYSBzdHJpbmcgaGFzIGEgc2luZ2xlIG9jY3VycmVuY2Ugb2YgYSBzZWFyY2ggdmFsdWUuXG4gKlxuICogQHBhcmFtIHN0ciAtIFRoZSBzdHJpbmcgdG8gY2hlY2suXG4gKiBAcGFyYW0gc2VhcmNoVmFsdWUgLSBUaGUgc2VhcmNoIHZhbHVlIHRvIGNoZWNrIGZvci5cbiAqIEByZXR1cm5zIGB0cnVlYCBpZiB0aGUgc3RyaW5nIGhhcyBhIHNpbmdsZSBvY2N1cnJlbmNlIG9mIHRoZSBzZWFyY2ggdmFsdWUsIGBmYWxzZWAgb3RoZXJ3aXNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaGFzU2luZ2xlT2NjdXJyZW5jZShzdHI6IHN0cmluZywgc2VhcmNoVmFsdWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBjb25zdCBmaXJzdEluZGV4ID0gc3RyLmluZGV4T2Yoc2VhcmNoVmFsdWUpO1xuICBjb25zdCBsYXN0SW5kZXggPSBzdHIubGFzdEluZGV4T2Yoc2VhcmNoVmFsdWUpO1xuICByZXR1cm4gZmlyc3RJbmRleCAhPT0gTk9UX0ZPVU5EX0lOREVYICYmIGZpcnN0SW5kZXggPT09IGxhc3RJbmRleDtcbn1cblxuLyoqXG4gKiBJbmRlbnRzIGEgc3RyaW5nIGJ5IGFkZGluZyBhIHByZWZpeCB0byBlYWNoIGxpbmUuXG4gKlxuICogQHBhcmFtIHRleHQgLSBUaGUgc3RyaW5nIHRvIGluZGVudC5cbiAqIEBwYXJhbSBwcmVmaXggLSBUaGUgcHJlZml4IHRvIGFkZCB0byBlYWNoIGxpbmUuXG4gKiBAcmV0dXJucyBUaGUgaW5kZW50ZWQgc3RyaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaW5kZW50KHRleHQ6IHN0cmluZywgcHJlZml4OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gdGV4dC5zcGxpdCgnXFxuJykubWFwKChsaW5lKSA9PiBgJHtwcmVmaXh9JHtsaW5lfWApLmpvaW4oJ1xcbicpO1xufVxuXG4vKipcbiAqIEluc2VydHMgYSBzdWJzdHJpbmcgYXQgYSBzcGVjaWZpZWQgcG9zaXRpb24gaW4gYSBzdHJpbmcuXG4gKlxuICogQHBhcmFtIHN0ciAtIFRoZSBzdHJpbmcgdG8gaW5zZXJ0IHRoZSBzdWJzdHJpbmcgaW50by5cbiAqIEBwYXJhbSBzdWJzdHJpbmcgLSBUaGUgc3Vic3RyaW5nIHRvIGluc2VydC5cbiAqIEBwYXJhbSBzdGFydEluZGV4IC0gVGhlIGluZGV4IHRvIGluc2VydCB0aGUgc3Vic3RyaW5nIGF0LlxuICogQHBhcmFtIGVuZEluZGV4IC0gVGhlIGluZGV4IHRvIGVuZCB0aGUgc3Vic3RyaW5nIGF0LlxuICogQHJldHVybnMgVGhlIG1vZGlmaWVkIHN0cmluZyB3aXRoIHRoZSBzdWJzdHJpbmcgaW5zZXJ0ZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbnNlcnRBdChzdHI6IHN0cmluZywgc3Vic3RyaW5nOiBzdHJpbmcsIHN0YXJ0SW5kZXg6IG51bWJlciwgZW5kSW5kZXg/OiBudW1iZXIpOiBzdHJpbmcge1xuICBlbmRJbmRleCA/Pz0gc3RhcnRJbmRleDtcbiAgcmV0dXJuIHN0ci5zbGljZSgwLCBzdGFydEluZGV4KSArIHN1YnN0cmluZyArIHN0ci5zbGljZShlbmRJbmRleCk7XG59XG5cbi8qKlxuICogQ29udmVydHMgYSBzdHJpbmcgaW50byBhIHZhbGlkIEphdmFTY3JpcHQgdmFyaWFibGUgbmFtZSBieSByZXBsYWNpbmcgaW52YWxpZCBjaGFyYWN0ZXJzIHdpdGggdW5kZXJzY29yZXMuXG4gKlxuICogQHBhcmFtIHN0ciAtIFRoZSBzdHJpbmcgdG8gY29udmVydC5cbiAqIEByZXR1cm5zIFRoZSB2YWxpZCB2YXJpYWJsZSBuYW1lLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbWFrZVZhbGlkVmFyaWFibGVOYW1lKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJlcGxhY2VBbGwoc3RyLCAvW15hLXpBLVowLTlfXS9nLCAnXycpO1xufVxuXG4vKipcbiAqIE5vcm1hbGl6ZXMgYSBzdHJpbmcgYnkgY29udmVydGluZyBpdCB0byB0aGUgTkZDIGZvcm0gYW5kIHJlcGxhY2luZyBub24tYnJlYWtpbmcgc3BhY2VzIHdpdGggcmVndWxhciBzcGFjZXMuXG4gKlxuICogQHBhcmFtIHN0ciAtIFRoZSBzdHJpbmcgdG8gbm9ybWFsaXplLlxuICogQHJldHVybnMgVGhlIG5vcm1hbGl6ZWQgc3RyaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJlcGxhY2VBbGwoc3RyLCAvXFx1MDBBMHxcXHUyMDJGL2csICcgJykubm9ybWFsaXplKCdORkMnKTtcbn1cblxuLyoqXG4gKiBSZXBsYWNlcyBvY2N1cnJlbmNlcyBvZiBzdHJpbmdzIGluIGEgZ2l2ZW4gc3RyaW5nIGJhc2VkIG9uIGEgcmVwbGFjZW1lbnRzIG1hcC5cbiAqXG4gKiBAcGFyYW0gc3RyIC0gVGhlIHN0cmluZyB0byBwZXJmb3JtIHJlcGxhY2VtZW50cyBvbi5cbiAqIEBwYXJhbSByZXBsYWNlbWVudHNNYXAgLSBBbiBvYmplY3QgbWFwcGluZyBzdHJpbmdzIHRvIHRoZWlyIHJlcGxhY2VtZW50IHZhbHVlcy5cbiAqIEByZXR1cm5zIFRoZSBtb2RpZmllZCBzdHJpbmcgd2l0aCByZXBsYWNlbWVudHMgYXBwbGllZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcGxhY2Uoc3RyOiBzdHJpbmcsIHJlcGxhY2VtZW50c01hcDogUmVjb3JkPHN0cmluZywgc3RyaW5nPik6IHN0cmluZyB7XG4gIGNvbnN0IHJlZ0V4cCA9IG5ldyBSZWdFeHAoT2JqZWN0LmtleXMocmVwbGFjZW1lbnRzTWFwKS5tYXAoKHNvdXJjZSkgPT4gZXNjYXBlUmVnRXhwKHNvdXJjZSkpLmpvaW4oJ3wnKSwgJ2cnKTtcbiAgcmV0dXJuIHJlcGxhY2VBbGwoc3RyLCByZWdFeHAsICh7IHN1YnN0cmluZzogc291cmNlIH0pID0+IHJlcGxhY2VtZW50c01hcFtzb3VyY2VdID8/IHRocm93RXhwcmVzc2lvbihuZXcgRXJyb3IoYFVuZXhwZWN0ZWQgcmVwbGFjZW1lbnQgc291cmNlOiAke3NvdXJjZX1gKSkpO1xufVxuXG4vKipcbiAqIFJlcGxhY2VzIGFsbCBvY2N1cnJlbmNlcyBvZiBhIHNlYXJjaCBzdHJpbmcgb3IgcGF0dGVybiB3aXRoIHRoZSByZXN1bHRzIG9mIGFuIHJlcGxhY2VyIGZ1bmN0aW9uLlxuICpcbiAqIEB0eXBlUGFyYW0gUmVwbGFjZUdyb3VwQXJncyAtIFRoZSB0eXBlIG9mIGFkZGl0aW9uYWwgYXJndW1lbnRzIHBhc3NlZCB0byB0aGUgcmVwbGFjZXIgZnVuY3Rpb24uXG4gKiBAcGFyYW0gc3RyIC0gVGhlIHN0cmluZyBpbiB3aGljaCB0byBwZXJmb3JtIHJlcGxhY2VtZW50cy5cbiAqIEBwYXJhbSBzZWFyY2hWYWx1ZSAtIFRoZSBzdHJpbmcgb3IgcmVndWxhciBleHByZXNzaW9uIHRvIHNlYXJjaCBmb3IuXG4gKiBAcGFyYW0gcmVwbGFjZXIgLSBBIHJlcGxhY2VyIGZ1bmN0aW9uIHRoYXQgZ2VuZXJhdGVzIHJlcGxhY2VtZW50IHN0cmluZ3MsIG9yIGEgc3RyaW5nIHRvIHJlcGxhY2Ugd2l0aC5cbiAqIEByZXR1cm5zIFRoZSBzdHJpbmcgd2l0aCBhbGwgcmVwbGFjZW1lbnRzIG1hZGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXBsYWNlQWxsPFJlcGxhY2VHcm91cEFyZ3MgZXh0ZW5kcyBzdHJpbmdbXT4oXG4gIHN0cjogc3RyaW5nLFxuICBzZWFyY2hWYWx1ZTogUmVnRXhwIHwgc3RyaW5nLFxuICByZXBsYWNlcjogUmVwbGFjZXI8UmVwbGFjZUdyb3VwQXJncz5cbik6IHN0cmluZyB7XG4gIGlmICh0eXBlb2YgcmVwbGFjZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgcmV0dXJuIHN0cjtcbiAgfVxuXG4gIGlmIChzZWFyY2hWYWx1ZSBpbnN0YW5jZW9mIFJlZ0V4cCAmJiAhc2VhcmNoVmFsdWUuZ2xvYmFsKSB7XG4gICAgc2VhcmNoVmFsdWUgPSBuZXcgUmVnRXhwKHNlYXJjaFZhbHVlLnNvdXJjZSwgYCR7c2VhcmNoVmFsdWUuZmxhZ3N9Z2ApO1xuICB9XG5cbiAgaWYgKHR5cGVvZiByZXBsYWNlciA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gc3RyLnJlcGxhY2VBbGwoc2VhcmNoVmFsdWUsIHJlcGxhY2VyKTtcbiAgfVxuXG4gIHJldHVybiBzdHIucmVwbGFjZUFsbChzZWFyY2hWYWx1ZSwgKHN1YnN0cmluZzogc3RyaW5nLCAuLi5hcmdzOiB1bmtub3duW10pID0+IHtcbiAgICBjb25zdCBTT1VSQ0VfSU5ERVhfT0ZGU0VUX0ZPUl9HUk9VUF9BUkcgPSAyO1xuICAgIGNvbnN0IGhhc0dyb3Vwc0FyZyA9IHR5cGVvZiBhcmdzLmF0KC0xKSA9PT0gJ29iamVjdCc7XG4gICAgY29uc3Qgc291cmNlSW5kZXggPSBoYXNHcm91cHNBcmcgPyBhcmdzLmxlbmd0aCAtIFNPVVJDRV9JTkRFWF9PRkZTRVRfRk9SX0dST1VQX0FSRyA6IGFyZ3MubGVuZ3RoIC0gMTtcblxuICAgIGNvbnN0IGNvbW1vbkFyZ3M6IFJlcGxhY2VDb21tb25BcmdzID0ge1xuICAgICAgZ3JvdXBzOiBoYXNHcm91cHNBcmcgPyBhcmdzLmF0KC0xKSBhcyBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+IDogdW5kZWZpbmVkLFxuICAgICAgbWlzc2luZ0dyb3VwSW5kaWNlczogW10sXG4gICAgICBvZmZzZXQ6IGFyZ3MuYXQoc291cmNlSW5kZXggLSAxKSBhcyBudW1iZXIsXG4gICAgICBzb3VyY2U6IGFyZ3MuYXQoc291cmNlSW5kZXgpIGFzIHN0cmluZyxcbiAgICAgIHN1YnN0cmluZ1xuICAgIH07XG5cbiAgICBjb25zdCBncm91cEFyZ3MgPSBhcmdzLnNsaWNlKDAsIHNvdXJjZUluZGV4IC0gMSkubWFwKChhcmcsIGluZGV4KSA9PiB7XG4gICAgICBpZiAodHlwZW9mIGFyZyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIGFyZztcbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiBhcmcgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGNvbW1vbkFyZ3MubWlzc2luZ0dyb3VwSW5kaWNlcy5wdXNoKGluZGV4KTtcbiAgICAgICAgcmV0dXJuICcnO1xuICAgICAgfVxuXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuZXhwZWN0ZWQgYXJndW1lbnQgdHlwZTogJHt0eXBlb2YgYXJnfWApO1xuICAgIH0pIGFzIFJlcGxhY2VHcm91cEFyZ3M7XG5cbiAgICByZXR1cm4gKHJlcGxhY2VyKGNvbW1vbkFyZ3MsIC4uLmdyb3VwQXJncykgYXMgc3RyaW5nIHwgdW5kZWZpbmVkKSA/PyBjb21tb25BcmdzLnN1YnN0cmluZztcbiAgfSk7XG59XG5cbi8qKlxuICogQXN5bmNocm9ub3VzbHkgcmVwbGFjZXMgYWxsIG9jY3VycmVuY2VzIG9mIGEgc2VhcmNoIHN0cmluZyBvciBwYXR0ZXJuIHdpdGggdGhlIHJlc3VsdHMgb2YgYW4gYXN5bmNocm9ub3VzIHJlcGxhY2VyIGZ1bmN0aW9uLlxuICpcbiAqIEB0eXBlUGFyYW0gUmVwbGFjZUdyb3VwQXJncyAtIFRoZSB0eXBlIG9mIGFkZGl0aW9uYWwgYXJndW1lbnRzIHBhc3NlZCB0byB0aGUgcmVwbGFjZXIgZnVuY3Rpb24uXG4gKiBAcGFyYW0gc3RyIC0gVGhlIHN0cmluZyBpbiB3aGljaCB0byBwZXJmb3JtIHJlcGxhY2VtZW50cy5cbiAqIEBwYXJhbSBzZWFyY2hWYWx1ZSAtIFRoZSBzdHJpbmcgb3IgcmVndWxhciBleHByZXNzaW9uIHRvIHNlYXJjaCBmb3IuXG4gKiBAcGFyYW0gcmVwbGFjZXIgLSBBIHN5bmNocm9ub3VzL2FzeW5jaHJvbm91cyBmdW5jdGlvbiB0aGF0IGdlbmVyYXRlcyByZXBsYWNlbWVudCBzdHJpbmdzLCBvciBhIHN0cmluZyB0byByZXBsYWNlIHdpdGguXG4gKiBAcGFyYW0gYWJvcnRTaWduYWwgLSBUaGUgYWJvcnQgc2lnbmFsIHRvIGNvbnRyb2wgdGhlIGV4ZWN1dGlvbiBvZiB0aGUgZnVuY3Rpb24uXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIHRvIHRoZSBzdHJpbmcgd2l0aCBhbGwgcmVwbGFjZW1lbnRzIG1hZGUuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZXBsYWNlQWxsQXN5bmM8UmVwbGFjZUdyb3VwQXJncyBleHRlbmRzIHN0cmluZ1tdPihcbiAgc3RyOiBzdHJpbmcsXG4gIHNlYXJjaFZhbHVlOiBSZWdFeHAgfCBzdHJpbmcsXG4gIHJlcGxhY2VyOiBBc3luY1JlcGxhY2VyPFJlcGxhY2VHcm91cEFyZ3M+LFxuICBhYm9ydFNpZ25hbD86IEFib3J0U2lnbmFsXG4pOiBQcm9taXNlPHN0cmluZz4ge1xuICBhYm9ydFNpZ25hbCA/Pz0gYWJvcnRTaWduYWxOZXZlcigpO1xuICBhYm9ydFNpZ25hbC50aHJvd0lmQWJvcnRlZCgpO1xuICBpZiAodHlwZW9mIHJlcGxhY2VyID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiByZXBsYWNlQWxsKHN0ciwgc2VhcmNoVmFsdWUsIHJlcGxhY2VyKTtcbiAgfVxuXG4gIGNvbnN0IHJlcGxhY2VtZW50QXN5bmNGbnM6ICgoKSA9PiBQcm9taXNlPFN0cmluZ1JlcGxhY2VtZW50PilbXSA9IFtdO1xuXG4gIHJlcGxhY2VBbGw8UmVwbGFjZUdyb3VwQXJncz4oc3RyLCBzZWFyY2hWYWx1ZSwgKGNvbW1vbkFyZ3MsIC4uLmdyb3VwQXJncykgPT4ge1xuICAgIHJlcGxhY2VtZW50QXN5bmNGbnMucHVzaCgoKSA9PiByZXNvbHZlVmFsdWUocmVwbGFjZXIsIGFib3J0U2lnbmFsLCBjb21tb25BcmdzLCAuLi5ncm91cEFyZ3MpKTtcbiAgICByZXR1cm4gJyc7XG4gIH0pO1xuXG4gIGNvbnN0IHJlcGxhY2VtZW50czogU3RyaW5nUmVwbGFjZW1lbnRbXSA9IFtdO1xuXG4gIGZvciAoY29uc3QgYXN5bmNGbiBvZiByZXBsYWNlbWVudEFzeW5jRm5zKSB7XG4gICAgYWJvcnRTaWduYWwudGhyb3dJZkFib3J0ZWQoKTtcbiAgICByZXBsYWNlbWVudHMucHVzaChhd2FpdCBhc3luY0ZuKCkpO1xuICB9XG5cbiAgYWJvcnRTaWduYWwudGhyb3dJZkFib3J0ZWQoKTtcbiAgcmV0dXJuIHJlcGxhY2VBbGwoc3RyLCBzZWFyY2hWYWx1ZSwgKGFyZ3MpOiBzdHJpbmcgPT4gcmVwbGFjZW1lbnRzLnNoaWZ0KCkgPz8gYXJncy5zdWJzdHJpbmcpO1xufVxuXG4vKipcbiAqIFRyaW1zIHRoZSBzcGVjaWZpZWQgc3VmZml4IGZyb20gdGhlIGVuZCBvZiBhIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0gc3RyIC0gVGhlIHN0cmluZyB0byB0cmltLlxuICogQHBhcmFtIHN1ZmZpeCAtIFRoZSBzdWZmaXggdG8gcmVtb3ZlIGZyb20gdGhlIGVuZCBvZiB0aGUgc3RyaW5nLlxuICogQHBhcmFtIHNob3VsZFZhbGlkYXRlIC0gSWYgdHJ1ZSwgdGhyb3dzIGFuIGVycm9yIGlmIHRoZSBzdHJpbmcgZG9lcyBub3QgZW5kIHdpdGggdGhlIHN1ZmZpeC5cbiAqIEByZXR1cm5zIFRoZSB0cmltbWVkIHN0cmluZy5cbiAqIEB0aHJvd3MgSWYgYHZhbGlkYXRlYCBpcyB0cnVlIGFuZCB0aGUgc3RyaW5nIGRvZXMgbm90IGVuZCB3aXRoIHRoZSBzdWZmaXguXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cmltRW5kKHN0cjogc3RyaW5nLCBzdWZmaXg6IHN0cmluZywgc2hvdWxkVmFsaWRhdGU/OiBib29sZWFuKTogc3RyaW5nIHtcbiAgaWYgKHN0ci5lbmRzV2l0aChzdWZmaXgpKSB7XG4gICAgcmV0dXJuIHN0ci5zbGljZSgwLCAtc3VmZml4Lmxlbmd0aCk7XG4gIH1cblxuICBpZiAoc2hvdWxkVmFsaWRhdGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFN0cmluZyAke3N0cn0gZG9lcyBub3QgZW5kIHdpdGggc3VmZml4ICR7c3VmZml4fWApO1xuICB9XG5cbiAgcmV0dXJuIHN0cjtcbn1cblxuLyoqXG4gKiBUcmltcyB0aGUgc3BlY2lmaWVkIHByZWZpeCBmcm9tIHRoZSBzdGFydCBvZiBhIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0gc3RyIC0gVGhlIHN0cmluZyB0byB0cmltLlxuICogQHBhcmFtIHByZWZpeCAtIFRoZSBwcmVmaXggdG8gcmVtb3ZlIGZyb20gdGhlIHN0YXJ0IG9mIHRoZSBzdHJpbmcuXG4gKiBAcGFyYW0gdmFsaWRhdGUgLSBJZiB0cnVlLCB0aHJvd3MgYW4gZXJyb3IgaWYgdGhlIHN0cmluZyBkb2VzIG5vdCBzdGFydCB3aXRoIHRoZSBwcmVmaXguXG4gKiBAcmV0dXJucyBUaGUgdHJpbW1lZCBzdHJpbmcuXG4gKiBAdGhyb3dzIElmIGB2YWxpZGF0ZWAgaXMgdHJ1ZSBhbmQgdGhlIHN0cmluZyBkb2VzIG5vdCBzdGFydCB3aXRoIHRoZSBwcmVmaXguXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cmltU3RhcnQoc3RyOiBzdHJpbmcsIHByZWZpeDogc3RyaW5nLCB2YWxpZGF0ZT86IGJvb2xlYW4pOiBzdHJpbmcge1xuICBpZiAoc3RyLnN0YXJ0c1dpdGgocHJlZml4KSkge1xuICAgIHJldHVybiBzdHIuc2xpY2UocHJlZml4Lmxlbmd0aCk7XG4gIH1cblxuICBpZiAodmFsaWRhdGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFN0cmluZyAke3N0cn0gZG9lcyBub3Qgc3RhcnQgd2l0aCBwcmVmaXggJHtwcmVmaXh9YCk7XG4gIH1cblxuICByZXR1cm4gc3RyO1xufVxuXG4vKipcbiAqIFVuZXNjYXBlcyBhIHN0cmluZyBieSByZXBsYWNpbmcgZXNjYXBlIHNlcXVlbmNlcyB3aXRoIHRoZWlyIGNvcnJlc3BvbmRpbmcgY2hhcmFjdGVycy5cbiAqXG4gKiBAcGFyYW0gc3RyIC0gVGhlIHN0cmluZyB0byB1bmVzY2FwZS5cbiAqIEByZXR1cm5zIFRoZSB1bmVzY2FwZWQgc3RyaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdW5lc2NhcGUoc3RyOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gcmVwbGFjZShzdHIsIFVORVNDQVBFX01BUCk7XG59XG5cbi8qKlxuICogVW5pbmRlbnRzIGEgc3RyaW5nIGJ5IHJlbW92aW5nIGEgcHJlZml4IGZyb20gZWFjaCBsaW5lLlxuICpcbiAqIEBwYXJhbSB0ZXh0IC0gVGhlIHN0cmluZyB0byB1bmluZGVudC5cbiAqIEBwYXJhbSBwcmVmaXggLSBUaGUgcHJlZml4IHRvIHJlbW92ZSBmcm9tIGVhY2ggbGluZS5cbiAqIEBwYXJhbSBzaG91bGRUaHJvd0lmTm90SW5kZW50ZWQgLSBJZiBgdHJ1ZWAsIHRocm93cyBhbiBlcnJvciBpZiBhIGxpbmUgaXMgbm90IGluZGVudGVkIHdpdGggdGhlIHByZWZpeC5cbiAqIEByZXR1cm5zIFRoZSB1bmluZGVudGVkIHN0cmluZy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVuaW5kZW50KHRleHQ6IHN0cmluZywgcHJlZml4OiBzdHJpbmcsIHNob3VsZFRocm93SWZOb3RJbmRlbnRlZCA9IGZhbHNlKTogc3RyaW5nIHtcbiAgcmV0dXJuIHRleHQuc3BsaXQoJ1xcbicpLm1hcCgobGluZSkgPT4ge1xuICAgIGlmIChsaW5lLnN0YXJ0c1dpdGgocHJlZml4KSkge1xuICAgICAgcmV0dXJuIGxpbmUuc2xpY2UocHJlZml4Lmxlbmd0aCk7XG4gICAgfVxuICAgIGlmIChzaG91bGRUaHJvd0lmTm90SW5kZW50ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTGluZSBcIiR7bGluZX1cIiBpcyBub3QgaW5kZW50ZWQgd2l0aCBcIiR7cHJlZml4fVwiYCk7XG4gICAgfVxuICAgIHJldHVybiBsaW5lO1xuICB9KS5qb2luKCdcXG4nKTtcbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtB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