obsidian-dev-utils
Version:
This is the collection of useful functions that you can use for your Obsidian plugin development
203 lines (200 loc) • 27.8 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 initEsm(){if(globalThis.process){return}const browserProcess={browser:true,cwd:__name(()=>"/","cwd"),env:{},platform:"android"};globalThis.process=browserProcess})();
import {
normalizePath,
TAbstractFile,
TFile,
TFolder,
Vault
} from "obsidian";
import {
createTFileInstance,
createTFolderInstance,
parentFolderPath
} from "obsidian-typings/implementations";
import {
extname,
resolve
} from "../Path.mjs";
import { trimEnd } from "../String.mjs";
const BASE_FILE_EXTENSION = "base";
const CANVAS_FILE_EXTENSION = "canvas";
const MARKDOWN_FILE_EXTENSION = "md";
function checkExtension(app, pathOrFile, extension) {
if (isFile(pathOrFile)) {
return pathOrFile.extension === extension;
}
if (typeof pathOrFile === "string") {
const file = getFileOrNull(app, pathOrFile);
if (file) {
return file.extension === extension;
}
return extname(pathOrFile).slice(1) === extension;
}
return false;
}
function getAbstractFile(app, pathOrFile, isCaseInsensitive) {
const file = getAbstractFileOrNull(app, pathOrFile, isCaseInsensitive);
if (!file) {
throw new Error(`Abstract file not found: ${pathOrFile}`);
}
return file;
}
function getAbstractFileOrNull(app, pathOrFile, isCaseInsensitive) {
if (pathOrFile === null) {
return null;
}
if (isAbstractFile(pathOrFile)) {
return pathOrFile;
}
const file = getFileInternal(app, pathOrFile, isCaseInsensitive);
if (file) {
return file;
}
const resolvedPath = getResolvedPath(pathOrFile);
if (resolvedPath === pathOrFile) {
return null;
}
return getFileInternal(app, resolvedPath, isCaseInsensitive);
}
function getFile(app, pathOrFile, shouldIncludeNonExisting, isCaseInsensitive) {
let file = getFileOrNull(app, pathOrFile, isCaseInsensitive);
if (!file) {
if (shouldIncludeNonExisting) {
file = createTFileInstance(app, pathOrFile);
} else {
throw new Error(`File not found: ${pathOrFile}`);
}
}
return file;
}
function getFileOrNull(app, pathOrFile, isCaseInsensitive) {
const file = getAbstractFileOrNull(app, pathOrFile, isCaseInsensitive);
if (isFile(file)) {
return file;
}
return null;
}
function getFolder(app, pathOrFolder, shouldIncludeNonExisting, isCaseInsensitive) {
let folder = getFolderOrNull(app, pathOrFolder, isCaseInsensitive);
if (!folder) {
if (shouldIncludeNonExisting) {
folder = createTFolderInstance(app, pathOrFolder);
} else {
throw new Error(`Folder not found: ${pathOrFolder}`);
}
}
return folder;
}
function getFolderOrNull(app, pathOrFolder, isCaseInsensitive) {
const folder = getAbstractFileOrNull(app, pathOrFolder, isCaseInsensitive);
if (isFolder(folder)) {
return folder;
}
return null;
}
function getMarkdownFiles(app, pathOrFolder, isRecursive) {
const folder = getFolder(app, pathOrFolder);
let markdownFiles = [];
if (isRecursive) {
Vault.recurseChildren(folder, (abstractFile) => {
if (isMarkdownFile(app, abstractFile)) {
markdownFiles.push(abstractFile);
}
});
} else {
markdownFiles = folder.children.filter((file) => isMarkdownFile(app, file));
}
markdownFiles = markdownFiles.sort((a, b) => a.path.localeCompare(b.path));
return markdownFiles;
}
async function getOrCreateFile(app, path) {
const file = getFileOrNull(app, path);
if (file) {
return file;
}
const folderPath = parentFolderPath(path);
await getOrCreateFolder(app, folderPath);
return await app.vault.create(path, "");
}
async function getOrCreateFolder(app, path) {
const folder = getFolderOrNull(app, path);
if (folder) {
return folder;
}
return await app.vault.createFolder(path);
}
function getPath(app, pathOrFile) {
if (isAbstractFile(pathOrFile)) {
return pathOrFile.path;
}
const file = getAbstractFileOrNull(app, pathOrFile);
if (file) {
return file.path;
}
return getResolvedPath(pathOrFile);
}
function isAbstractFile(file) {
return file instanceof TAbstractFile;
}
function isBaseFile(app, pathOrFile) {
return checkExtension(app, pathOrFile, BASE_FILE_EXTENSION);
}
function isCanvasFile(app, pathOrFile) {
return checkExtension(app, pathOrFile, CANVAS_FILE_EXTENSION);
}
function isFile(file) {
return file instanceof TFile;
}
function isFolder(file) {
return file instanceof TFolder;
}
function isMarkdownFile(app, pathOrFile) {
return checkExtension(app, pathOrFile, MARKDOWN_FILE_EXTENSION);
}
function isNote(app, pathOrFile) {
return isMarkdownFile(app, pathOrFile) || isCanvasFile(app, pathOrFile) || isBaseFile(app, pathOrFile);
}
function trimMarkdownExtension(app, file) {
if (!isMarkdownFile(app, file)) {
return file.path;
}
return trimEnd(file.path, `.${MARKDOWN_FILE_EXTENSION}`);
}
function getFileInternal(app, path, isCaseInsensitive) {
if (isCaseInsensitive) {
return app.vault.getAbstractFileByPathInsensitive(path);
}
return app.vault.getAbstractFileByPath(path);
}
function getResolvedPath(path) {
return normalizePath(resolve("/", path));
}
export {
BASE_FILE_EXTENSION,
CANVAS_FILE_EXTENSION,
MARKDOWN_FILE_EXTENSION,
checkExtension,
getAbstractFile,
getAbstractFileOrNull,
getFile,
getFileOrNull,
getFolder,
getFolderOrNull,
getMarkdownFiles,
getOrCreateFile,
getOrCreateFolder,
getPath,
isAbstractFile,
isBaseFile,
isCanvasFile,
isFile,
isFolder,
isMarkdownFile,
isNote,
trimMarkdownExtension
};
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vc3JjL29ic2lkaWFuL0ZpbGVTeXN0ZW0udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQHBhY2thZ2VEb2N1bWVudGF0aW9uXG4gKlxuICogVGhpcyBtb2R1bGUgcHJvdmlkZXMgdXRpbGl0eSBmdW5jdGlvbnMgZm9yIHdvcmtpbmcgd2l0aCBUQWJzdHJhY3RGaWxlLCBURmlsZSwgYW5kIFRGb2xkZXIgaW5zdGFuY2VzIGluIE9ic2lkaWFuLlxuICovXG5cbmltcG9ydCB0eXBlIHsgQXBwIH0gZnJvbSAnb2JzaWRpYW4nO1xuXG5pbXBvcnQge1xuICBub3JtYWxpemVQYXRoLFxuICBUQWJzdHJhY3RGaWxlLFxuICBURmlsZSxcbiAgVEZvbGRlcixcbiAgVmF1bHRcbn0gZnJvbSAnb2JzaWRpYW4nO1xuaW1wb3J0IHtcbiAgY3JlYXRlVEZpbGVJbnN0YW5jZSxcbiAgY3JlYXRlVEZvbGRlckluc3RhbmNlLFxuICBwYXJlbnRGb2xkZXJQYXRoXG59IGZyb20gJ29ic2lkaWFuLXR5cGluZ3MvaW1wbGVtZW50YXRpb25zJztcblxuaW1wb3J0IHtcbiAgZXh0bmFtZSxcbiAgcmVzb2x2ZVxufSBmcm9tICcuLi9QYXRoLnRzJztcbmltcG9ydCB7IHRyaW1FbmQgfSBmcm9tICcuLi9TdHJpbmcudHMnO1xuXG4vKipcbiAqIFJlcHJlc2VudHMgdGhlIGZpbGUgZXh0ZW5zaW9uIGZvciBiYXNlIGZpbGVzLlxuICovXG5leHBvcnQgY29uc3QgQkFTRV9GSUxFX0VYVEVOU0lPTiA9ICdiYXNlJztcblxuLyoqXG4gKiBSZXByZXNlbnRzIHRoZSBmaWxlIGV4dGVuc2lvbiBmb3IgY2FudmFzIGZpbGVzLlxuICovXG5leHBvcnQgY29uc3QgQ0FOVkFTX0ZJTEVfRVhURU5TSU9OID0gJ2NhbnZhcyc7XG5cbi8qKlxuICogVGhlIGZpbGUgZXh0ZW5zaW9uIGZvciBNYXJrZG93biBmaWxlcy5cbiAqL1xuZXhwb3J0IGNvbnN0IE1BUktET1dOX0ZJTEVfRVhURU5TSU9OID0gJ21kJztcblxuLyoqXG4gKiBSZXByZXNlbnRzIGEgcGF0aCBvciBhbiBpbnN0YW5jZSBvZiBUQWJzdHJhY3RGaWxlLlxuICovXG5leHBvcnQgdHlwZSBQYXRoT3JBYnN0cmFjdEZpbGUgPSBzdHJpbmcgfCBUQWJzdHJhY3RGaWxlO1xuXG4vKipcbiAqIFJlcHJlc2VudHMgYSBwYXRoIG9yIGEgZmlsZS5cbiAqL1xuZXhwb3J0IHR5cGUgUGF0aE9yRmlsZSA9IHN0cmluZyB8IFRGaWxlO1xuXG4vKipcbiAqIFJlcHJlc2VudHMgYSBwYXRoIG9yIGFuIGluc3RhbmNlIG9mIFRGb2xkZXIuXG4gKi9cbmV4cG9ydCB0eXBlIFBhdGhPckZvbGRlciA9IHN0cmluZyB8IFRGb2xkZXI7XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBwYXRoIG9yIGZpbGUgaGFzIHRoZSBzcGVjaWZpZWQgZXh0ZW5zaW9uLlxuICpcbiAqIEBwYXJhbSBhcHAgLSBUaGUgT2JzaWRpYW4gQXBwIGluc3RhbmNlLlxuICogQHBhcmFtIHBhdGhPckZpbGUgLSBUaGUgcGF0aCBvciBhYnN0cmFjdCBmaWxlIHRvIGNoZWNrLlxuICogQHBhcmFtIGV4dGVuc2lvbiAtIFRoZSBleHRlbnNpb24gdG8gY29tcGFyZSBhZ2FpbnN0LlxuICogQHJldHVybnMgUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHBhdGggb3IgZmlsZSBoYXMgdGhlIHNwZWNpZmllZCBleHRlbnNpb24sIGBmYWxzZWAgb3RoZXJ3aXNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2hlY2tFeHRlbnNpb24oYXBwOiBBcHAsIHBhdGhPckZpbGU6IG51bGwgfCBQYXRoT3JBYnN0cmFjdEZpbGUsIGV4dGVuc2lvbjogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGlmIChpc0ZpbGUocGF0aE9yRmlsZSkpIHtcbiAgICByZXR1cm4gcGF0aE9yRmlsZS5leHRlbnNpb24gPT09IGV4dGVuc2lvbjtcbiAgfVxuXG4gIGlmICh0eXBlb2YgcGF0aE9yRmlsZSA9PT0gJ3N0cmluZycpIHtcbiAgICBjb25zdCBmaWxlID0gZ2V0RmlsZU9yTnVsbChhcHAsIHBhdGhPckZpbGUpO1xuICAgIGlmIChmaWxlKSB7XG4gICAgICByZXR1cm4gZmlsZS5leHRlbnNpb24gPT09IGV4dGVuc2lvbjtcbiAgICB9XG5cbiAgICByZXR1cm4gZXh0bmFtZShwYXRoT3JGaWxlKS5zbGljZSgxKSA9PT0gZXh0ZW5zaW9uO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKipcbiAqIFJldHJpZXZlcyB0aGUgVEFic3RyYWN0RmlsZSBvYmplY3QgZm9yIHRoZSBnaXZlbiBwYXRoIG9yIGFic3RyYWN0IGZpbGUuXG4gKlxuICogQHBhcmFtIGFwcCAtIFRoZSBBcHAgaW5zdGFuY2UuXG4gKiBAcGFyYW0gcGF0aE9yRmlsZSAtIFRoZSBwYXRoIG9yIGFic3RyYWN0IGZpbGUgdG8gcmV0cmlldmUgdGhlIFRBYnN0cmFjdEZpbGUgZm9yLlxuICogQHBhcmFtIGlzQ2FzZUluc2Vuc2l0aXZlIC0gU3BlY2lmaWVzIHdoZXRoZXIgdG8gcGVyZm9ybSBhIGNhc2UtaW5zZW5zaXRpdmUgc2VhcmNoLiBEZWZhdWx0IGlzIGBmYWxzZWAuXG4gKiBAcmV0dXJucyBUaGUgVEFic3RyYWN0RmlsZSBvYmplY3QuXG4gKiBAdGhyb3dzIEVycm9yIGlmIHRoZSBhYnN0cmFjdCBmaWxlIGlzIG5vdCBmb3VuZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEFic3RyYWN0RmlsZShhcHA6IEFwcCwgcGF0aE9yRmlsZTogUGF0aE9yQWJzdHJhY3RGaWxlLCBpc0Nhc2VJbnNlbnNpdGl2ZT86IGJvb2xlYW4pOiBUQWJzdHJhY3RGaWxlIHtcbiAgY29uc3QgZmlsZSA9IGdldEFic3RyYWN0RmlsZU9yTnVsbChhcHAsIHBhdGhPckZpbGUsIGlzQ2FzZUluc2Vuc2l0aXZlKTtcbiAgaWYgKCFmaWxlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBBYnN0cmFjdCBmaWxlIG5vdCBmb3VuZDogJHtwYXRoT3JGaWxlIGFzIHN0cmluZ31gKTtcbiAgfVxuXG4gIHJldHVybiBmaWxlO1xufVxuXG4vKipcbiAqIFJldHJpZXZlcyBhbiBpbnN0YW5jZSBvZiBUQWJzdHJhY3RGaWxlIG9yIG51bGwgYmFzZWQgb24gdGhlIHByb3ZpZGVkIHBhdGggb3IgYWJzdHJhY3QgZmlsZS5cbiAqXG4gKiBAcGFyYW0gYXBwIC0gVGhlIGFwcGxpY2F0aW9uIGluc3RhbmNlLlxuICogQHBhcmFtIHBhdGhPckZpbGUgLSBUaGUgcGF0aCBvciBhYnN0cmFjdCBmaWxlIHRvIHJldHJpZXZlLlxuICogQHBhcmFtIGlzQ2FzZUluc2Vuc2l0aXZlIC0gU3BlY2lmaWVzIHdoZXRoZXIgdG8gcGVyZm9ybSBhIGNhc2UtaW5zZW5zaXRpdmUgc2VhcmNoLiBEZWZhdWx0IGlzIGBmYWxzZWAuXG4gKiBAcmV0dXJucyBUaGUgaW5zdGFuY2Ugb2YgVEFic3RyYWN0RmlsZSBpZiBmb3VuZCwgb3RoZXJ3aXNlIG51bGwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRBYnN0cmFjdEZpbGVPck51bGwoYXBwOiBBcHAsIHBhdGhPckZpbGU6IG51bGwgfCBQYXRoT3JBYnN0cmFjdEZpbGUsIGlzQ2FzZUluc2Vuc2l0aXZlPzogYm9vbGVhbik6IG51bGwgfCBUQWJzdHJhY3RGaWxlIHtcbiAgaWYgKHBhdGhPckZpbGUgPT09IG51bGwpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGlmIChpc0Fic3RyYWN0RmlsZShwYXRoT3JGaWxlKSkge1xuICAgIHJldHVybiBwYXRoT3JGaWxlO1xuICB9XG5cbiAgY29uc3QgZmlsZSA9IGdldEZpbGVJbnRlcm5hbChhcHAsIHBhdGhPckZpbGUsIGlzQ2FzZUluc2Vuc2l0aXZlKTtcblxuICBpZiAoZmlsZSkge1xuICAgIHJldHVybiBmaWxlO1xuICB9XG5cbiAgY29uc3QgcmVzb2x2ZWRQYXRoID0gZ2V0UmVzb2x2ZWRQYXRoKHBhdGhPckZpbGUpO1xuXG4gIGlmIChyZXNvbHZlZFBhdGggPT09IHBhdGhPckZpbGUpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHJldHVybiBnZXRGaWxlSW50ZXJuYWwoYXBwLCByZXNvbHZlZFBhdGgsIGlzQ2FzZUluc2Vuc2l0aXZlKTtcbn1cblxuLyoqXG4gKiBSZXRyaWV2ZXMgYSBURmlsZSBvYmplY3QgYmFzZWQgb24gdGhlIHByb3ZpZGVkIHBhdGggb3IgZmlsZS5cbiAqXG4gKiBAcGFyYW0gYXBwIC0gVGhlIE9ic2lkaWFuIEFwcCBpbnN0YW5jZS5cbiAqIEBwYXJhbSBwYXRoT3JGaWxlIC0gVGhlIHBhdGggb3IgZmlsZSB0byByZXRyaWV2ZSB0aGUgVEZpbGUgb2JqZWN0IGZvci5cbiAqIEBwYXJhbSBzaG91bGRJbmNsdWRlTm9uRXhpc3RpbmcgLSBXaGV0aGVyIHRvIGluY2x1ZGUgYSBub24tZXhpc3RpbmcgZmlsZS5cbiAqICBJZiBgdHJ1ZWAsIGEgbmV3IFRGaWxlIG9iamVjdCBpcyBjcmVhdGVkIGZvciB0aGUgcHJvdmlkZWQgcGF0aC5cbiAqICBJZiBgZmFsc2VgLCBhbiBlcnJvciBpcyB0aHJvd24gaWYgdGhlIGZpbGUgaXMgbm90IGZvdW5kLlxuICogQHBhcmFtIGlzQ2FzZUluc2Vuc2l0aXZlIC0gU3BlY2lmaWVzIHdoZXRoZXIgdG8gcGVyZm9ybSBhIGNhc2UtaW5zZW5zaXRpdmUgc2VhcmNoLiBEZWZhdWx0IGlzIGBmYWxzZWAuXG4gKiBAcmV0dXJucyBUaGUgVEZpbGUgb2JqZWN0IGNvcnJlc3BvbmRpbmcgdG8gdGhlIHByb3ZpZGVkIHBhdGggb3IgZmlsZS5cbiAqIEB0aHJvd3MgRXJyb3IgaWYgdGhlIGZpbGUgaXMgbm90IGZvdW5kLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RmlsZShhcHA6IEFwcCwgcGF0aE9yRmlsZTogUGF0aE9yRmlsZSwgc2hvdWxkSW5jbHVkZU5vbkV4aXN0aW5nPzogYm9vbGVhbiwgaXNDYXNlSW5zZW5zaXRpdmU/OiBib29sZWFuKTogVEZpbGUge1xuICBsZXQgZmlsZSA9IGdldEZpbGVPck51bGwoYXBwLCBwYXRoT3JGaWxlLCBpc0Nhc2VJbnNlbnNpdGl2ZSk7XG4gIGlmICghZmlsZSkge1xuICAgIGlmIChzaG91bGRJbmNsdWRlTm9uRXhpc3RpbmcpIHtcbiAgICAgIGZpbGUgPSBjcmVhdGVURmlsZUluc3RhbmNlKGFwcCwgcGF0aE9yRmlsZSBhcyBzdHJpbmcpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEZpbGUgbm90IGZvdW5kOiAke3BhdGhPckZpbGUgYXMgc3RyaW5nfWApO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmaWxlO1xufVxuXG4vKipcbiAqIFJldHJpZXZlcyBhIFRGaWxlIG9iamVjdCBiYXNlZCBvbiB0aGUgcHJvdmlkZWQgcGF0aCBvciBmaWxlLlxuICogSWYgdGhlIHByb3ZpZGVkIGFyZ3VtZW50IGlzIGFscmVhZHkgYSBURmlsZSBvYmplY3QsIGl0IGlzIHJldHVybmVkIGFzIGlzLlxuICogT3RoZXJ3aXNlLCB0aGUgZnVuY3Rpb24gdXNlcyB0aGUgYXBwJ3MgdmF1bHQgdG8gcmV0cmlldmUgdGhlIFRGaWxlIG9iamVjdCBieSBpdHMgcGF0aC5cbiAqXG4gKiBAcGFyYW0gYXBwIC0gVGhlIE9ic2lkaWFuIEFwcCBpbnN0YW5jZS5cbiAqIEBwYXJhbSBwYXRoT3JGaWxlIC0gVGhlIHBhdGggb3IgVEZpbGUgb2JqZWN0LlxuICogQHBhcmFtIGlzQ2FzZUluc2Vuc2l0aXZlIC0gU3BlY2lmaWVzIHdoZXRoZXIgdG8gcGVyZm9ybSBhIGNhc2UtaW5zZW5zaXRpdmUgc2VhcmNoLiBEZWZhdWx0IGlzIGBmYWxzZWAuXG4gKiBAcmV0dXJucyBUaGUgVEZpbGUgb2JqZWN0IGlmIGZvdW5kLCBvdGhlcndpc2UgbnVsbC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEZpbGVPck51bGwoYXBwOiBBcHAsIHBhdGhPckZpbGU6IG51bGwgfCBQYXRoT3JGaWxlLCBpc0Nhc2VJbnNlbnNpdGl2ZT86IGJvb2xlYW4pOiBudWxsIHwgVEZpbGUge1xuICBjb25zdCBmaWxlID0gZ2V0QWJzdHJhY3RGaWxlT3JOdWxsKGFwcCwgcGF0aE9yRmlsZSwgaXNDYXNlSW5zZW5zaXRpdmUpO1xuICBpZiAoaXNGaWxlKGZpbGUpKSB7XG4gICAgcmV0dXJuIGZpbGU7XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5cbi8qKlxuICogUmV0cmlldmVzIGEgVEZvbGRlciBvYmplY3QgYmFzZWQgb24gdGhlIHByb3ZpZGVkIGFwcCBhbmQgcGF0aE9yRm9sZGVyLlxuICpcbiAqIEBwYXJhbSBhcHAgLSBUaGUgT2JzaWRpYW4gYXBwIGluc3RhbmNlLlxuICogQHBhcmFtIHBhdGhPckZvbGRlciAtIFRoZSBwYXRoIG9yIGZvbGRlciBpZGVudGlmaWVyLlxuICogQHBhcmFtIHNob3VsZEluY2x1ZGVOb25FeGlzdGluZyAtIFdoZXRoZXIgdG8gYWxsb3cgdGhlIGZvbGRlciB0byBub3QgZXhpc3QuXG4gKiAgSWYgYHRydWVgLCBhIG5ldyBURm9sZGVyIG9iamVjdCBpcyBjcmVhdGVkIGZvciB0aGUgcHJvdmlkZWQgcGF0aC5cbiAqICBJZiBgZmFsc2VgLCBhbiBlcnJvciBpcyB0aHJvd24gaWYgdGhlIGZvbGRlciBpcyBub3QgZm91bmQuXG4gKiBAcGFyYW0gaXNDYXNlSW5zZW5zaXRpdmUgLSBTcGVjaWZpZXMgd2hldGhlciB0byBwZXJmb3JtIGEgY2FzZS1pbnNlbnNpdGl2ZSBzZWFyY2guIERlZmF1bHQgaXMgYGZhbHNlYC5cbiAqIEByZXR1cm5zIFRoZSByZXRyaWV2ZWQgVEZvbGRlciBvYmplY3QuXG4gKiBAdGhyb3dzIElmIHRoZSBmb2xkZXIgaXMgbm90IGZvdW5kLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rm9sZGVyKGFwcDogQXBwLCBwYXRoT3JGb2xkZXI6IFBhdGhPckZvbGRlciwgc2hvdWxkSW5jbHVkZU5vbkV4aXN0aW5nPzogYm9vbGVhbiwgaXNDYXNlSW5zZW5zaXRpdmU/OiBib29sZWFuKTogVEZvbGRlciB7XG4gIGxldCBmb2xkZXIgPSBnZXRGb2xkZXJPck51bGwoYXBwLCBwYXRoT3JGb2xkZXIsIGlzQ2FzZUluc2Vuc2l0aXZlKTtcbiAgaWYgKCFmb2xkZXIpIHtcbiAgICBpZiAoc2hvdWxkSW5jbHVkZU5vbkV4aXN0aW5nKSB7XG4gICAgICBmb2xkZXIgPSBjcmVhdGVURm9sZGVySW5zdGFuY2UoYXBwLCBwYXRoT3JGb2xkZXIgYXMgc3RyaW5nKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBGb2xkZXIgbm90IGZvdW5kOiAke3BhdGhPckZvbGRlciBhcyBzdHJpbmd9YCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZvbGRlcjtcbn1cblxuLyoqXG4gKiBSZXRyaWV2ZXMgYSBURm9sZGVyIG9iamVjdCBvciBudWxsIGJhc2VkIG9uIHRoZSBwcm92aWRlZCBwYXRoIG9yIGZvbGRlci5cbiAqXG4gKiBAcGFyYW0gYXBwIC0gVGhlIE9ic2lkaWFuIGFwcGxpY2F0aW9uIGluc3RhbmNlLlxuICogQHBhcmFtIHBhdGhPckZvbGRlciAtIFRoZSBwYXRoIG9yIGZvbGRlciB0byByZXRyaWV2ZSB0aGUgVEZvbGRlciBmcm9tLlxuICogQHBhcmFtIGlzQ2FzZUluc2Vuc2l0aXZlIC0gU3BlY2lmaWVzIHdoZXRoZXIgdG8gcGVyZm9ybSBhIGNhc2UtaW5zZW5zaXRpdmUgc2VhcmNoLiBEZWZhdWx0IGlzIGBmYWxzZWAuXG4gKiBAcmV0dXJucyBUaGUgVEZvbGRlciBvYmplY3QgaWYgZm91bmQsIG90aGVyd2lzZSBudWxsLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rm9sZGVyT3JOdWxsKGFwcDogQXBwLCBwYXRoT3JGb2xkZXI6IG51bGwgfCBQYXRoT3JGb2xkZXIsIGlzQ2FzZUluc2Vuc2l0aXZlPzogYm9vbGVhbik6IG51bGwgfCBURm9sZGVyIHtcbiAgY29uc3QgZm9sZGVyID0gZ2V0QWJzdHJhY3RGaWxlT3JOdWxsKGFwcCwgcGF0aE9yRm9sZGVyLCBpc0Nhc2VJbnNlbnNpdGl2ZSk7XG4gIGlmIChpc0ZvbGRlcihmb2xkZXIpKSB7XG4gICAgcmV0dXJuIGZvbGRlcjtcbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuLyoqXG4gKiBSZXRyaWV2ZXMgYW4gYXJyYXkgb2YgVEZpbGUgb2JqZWN0cyByZXByZXNlbnRpbmcgdGhlIG1hcmtkb3duIGZpbGVzIHdpdGhpbiBhIHNwZWNpZmllZCBmb2xkZXIgb3IgcGF0aC5cbiAqXG4gKiBAcGFyYW0gYXBwIC0gVGhlIE9ic2lkaWFuIEFwcCBpbnN0YW5jZS5cbiAqIEBwYXJhbSBwYXRoT3JGb2xkZXIgLSBUaGUgcGF0aCBvciBmb2xkZXIgdG8gcmV0cmlldmUgdGhlIG1hcmtkb3duIGZpbGVzIGZyb20uXG4gKiBAcGFyYW0gaXNSZWN1cnNpdmUgLSBPcHRpb25hbC4gU3BlY2lmaWVzIHdoZXRoZXIgdG8gcmVjdXJzaXZlbHkgc2VhcmNoIGZvciBtYXJrZG93biBmaWxlcyB3aXRoaW4gc3ViZm9sZGVycy4gRGVmYXVsdCBpcyBmYWxzZS5cbiAqIEByZXR1cm5zIEFuIGFycmF5IG9mIFRGaWxlIG9iamVjdHMgcmVwcmVzZW50aW5nIHRoZSBtYXJrZG93biBmaWxlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldE1hcmtkb3duRmlsZXMoYXBwOiBBcHAsIHBhdGhPckZvbGRlcjogUGF0aE9yRm9sZGVyLCBpc1JlY3Vyc2l2ZT86IGJvb2xlYW4pOiBURmlsZVtdIHtcbiAgY29uc3QgZm9sZGVyID0gZ2V0Rm9sZGVyKGFwcCwgcGF0aE9yRm9sZGVyKTtcblxuICBsZXQgbWFya2Rvd25GaWxlczogVEZpbGVbXSA9IFtdO1xuXG4gIGlmIChpc1JlY3Vyc2l2ZSkge1xuICAgIFZhdWx0LnJlY3Vyc2VDaGlsZHJlbihmb2xkZXIsIChhYnN0cmFjdEZpbGUpID0+IHtcbiAgICAgIGlmIChpc01hcmtkb3duRmlsZShhcHAsIGFic3RyYWN0RmlsZSkpIHtcbiAgICAgICAgbWFya2Rvd25GaWxlcy5wdXNoKGFic3RyYWN0RmlsZSBhcyBURmlsZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgbWFya2Rvd25GaWxlcyA9IGZvbGRlci5jaGlsZHJlbi5maWx0ZXIoKGZpbGUpID0+IGlzTWFya2Rvd25GaWxlKGFwcCwgZmlsZSkpIGFzIFRGaWxlW107XG4gIH1cblxuICBtYXJrZG93bkZpbGVzID0gbWFya2Rvd25GaWxlcy5zb3J0KChhLCBiKSA9PiBhLnBhdGgubG9jYWxlQ29tcGFyZShiLnBhdGgpKTtcbiAgcmV0dXJuIG1hcmtkb3duRmlsZXM7XG59XG5cbi8qKlxuICogUmV0cmlldmVzIHRoZSBURmlsZSBvYmplY3QgZm9yIHRoZSBnaXZlbiBwYXRoIG9yIGNyZWF0ZXMgYSBuZXcgb25lIGlmIGl0IGRvZXMgbm90IGV4aXN0LlxuICpcbiAqIEBwYXJhbSBhcHAgLSBUaGUgT2JzaWRpYW4gQXBwIGluc3RhbmNlLlxuICogQHBhcmFtIHBhdGggLSBUaGUgcGF0aCBvZiB0aGUgZmlsZSB0byByZXRyaWV2ZSBvciBjcmVhdGUuXG4gKiBAcmV0dXJucyBUaGUgVEZpbGUgb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgZmlsZVxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0T3JDcmVhdGVGaWxlKGFwcDogQXBwLCBwYXRoOiBzdHJpbmcpOiBQcm9taXNlPFRGaWxlPiB7XG4gIGNvbnN0IGZpbGUgPSBnZXRGaWxlT3JOdWxsKGFwcCwgcGF0aCk7XG4gIGlmIChmaWxlKSB7XG4gICAgcmV0dXJuIGZpbGU7XG4gIH1cblxuICBjb25zdCBmb2xkZXJQYXRoID0gcGFyZW50Rm9sZGVyUGF0aChwYXRoKTtcbiAgYXdhaXQgZ2V0T3JDcmVhdGVGb2xkZXIoYXBwLCBmb2xkZXJQYXRoKTtcblxuICByZXR1cm4gYXdhaXQgYXBwLnZhdWx0LmNyZWF0ZShwYXRoLCAnJyk7XG59XG5cbi8qKlxuICogUmV0cmlldmVzIHRoZSBURm9sZGVyIG9iamVjdCBmb3IgdGhlIGdpdmVuIHBhdGggb3IgY3JlYXRlcyBhIG5ldyBvbmUgaWYgaXQgZG9lcyBub3QgZXhpc3QuXG4gKlxuICogQHBhcmFtIGFwcCAtIFRoZSBPYnNpZGlhbiBBcHAgaW5zdGFuY2UuXG4gKiBAcGFyYW0gcGF0aCAtIFRoZSBwYXRoIG9mIHRoZSBmb2xkZXIgdG8gcmV0cmlldmUgb3IgY3JlYXRlLlxuICogQHJldHVybnMgVGhlIFRGb2xkZXIgb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgZm9sZGVyLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0T3JDcmVhdGVGb2xkZXIoYXBwOiBBcHAsIHBhdGg6IHN0cmluZyk6IFByb21pc2U8VEZvbGRlcj4ge1xuICBjb25zdCBmb2xkZXIgPSBnZXRGb2xkZXJPck51bGwoYXBwLCBwYXRoKTtcbiAgaWYgKGZvbGRlcikge1xuICAgIHJldHVybiBmb2xkZXI7XG4gIH1cblxuICByZXR1cm4gYXdhaXQgYXBwLnZhdWx0LmNyZWF0ZUZvbGRlcihwYXRoKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBwYXRoIG9mIHRoZSBnaXZlbiBgcGF0aE9yRmlsZWAuXG4gKlxuICogQHBhcmFtIGFwcCAtIFRoZSBPYnNpZGlhbiBBcHAgaW5zdGFuY2UuXG4gKiBAcGFyYW0gcGF0aE9yRmlsZSAtIFRoZSBwYXRoIG9yIGFic3RyYWN0IGZpbGUuXG4gKiBAcmV0dXJucyBUaGUgcGF0aCBvZiB0aGUgYHBhdGhPckZpbGVgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0UGF0aChhcHA6IEFwcCwgcGF0aE9yRmlsZTogUGF0aE9yQWJzdHJhY3RGaWxlKTogc3RyaW5nIHtcbiAgaWYgKGlzQWJzdHJhY3RGaWxlKHBhdGhPckZpbGUpKSB7XG4gICAgcmV0dXJuIHBhdGhPckZpbGUucGF0aDtcbiAgfVxuXG4gIGNvbnN0IGZpbGUgPSBnZXRBYnN0cmFjdEZpbGVPck51bGwoYXBwLCBwYXRoT3JGaWxlKTtcbiAgaWYgKGZpbGUpIHtcbiAgICByZXR1cm4gZmlsZS5wYXRoO1xuICB9XG5cbiAgcmV0dXJuIGdldFJlc29sdmVkUGF0aChwYXRoT3JGaWxlKTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGdpdmVuIGZpbGUgaXMgYW4gaW5zdGFuY2Ugb2YgVEFic3RyYWN0RmlsZS5cbiAqXG4gKiBAcGFyYW0gZmlsZSAtIFRoZSBmaWxlIHRvIGNoZWNrLlxuICogQHJldHVybnMgQSBib29sZWFuIGluZGljYXRpbmcgd2hldGhlciB0aGUgZmlsZSBpcyBhbiBpbnN0YW5jZSBvZiBUQWJzdHJhY3RGaWxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNBYnN0cmFjdEZpbGUoZmlsZTogdW5rbm93bik6IGZpbGUgaXMgVEFic3RyYWN0RmlsZSB7XG4gIHJldHVybiBmaWxlIGluc3RhbmNlb2YgVEFic3RyYWN0RmlsZTtcbn1cblxuLyoqXG4gKiAgIENoZWNrcyBpZiB0aGUgZ2l2ZW4gZmlsZSBpcyBhIGJhc2UgZmlsZS5cbiAqXG4gKiBAcGFyYW0gYXBwIC0gVGhlIE9ic2lkaWFuIEFwcCBpbnN0YW5jZS5cbiAqIEBwYXJhbSBwYXRoT3JGaWxlIC0gVGhlIHBhdGggb3IgZmlsZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIEEgYm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIGZpbGUgaXMgYSBiYXNlIGZpbGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0Jhc2VGaWxlKGFwcDogQXBwLCBwYXRoT3JGaWxlOiBudWxsIHwgUGF0aE9yQWJzdHJhY3RGaWxlKTogYm9vbGVhbiB7XG4gIHJldHVybiBjaGVja0V4dGVuc2lvbihhcHAsIHBhdGhPckZpbGUsIEJBU0VfRklMRV9FWFRFTlNJT04pO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gZmlsZSBpcyBhIGNhbnZhcyBmaWxlLlxuICpcbiAqIEBwYXJhbSBhcHAgLSBUaGUgT2JzaWRpYW4gQXBwIGluc3RhbmNlLlxuICogQHBhcmFtIHBhdGhPckZpbGUgLSBUaGUgcGF0aCBvciBmaWxlIHRvIGNoZWNrLlxuICogQHJldHVybnMgQSBib29sZWFuIGluZGljYXRpbmcgd2hldGhlciB0aGUgZmlsZSBpcyBhIGNhbnZhcyBmaWxlIG9yIG5vdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQ2FudmFzRmlsZShhcHA6IEFwcCwgcGF0aE9yRmlsZTogbnVsbCB8IFBhdGhPckFic3RyYWN0RmlsZSk6IGJvb2xlYW4ge1xuICByZXR1cm4gY2hlY2tFeHRlbnNpb24oYXBwLCBwYXRoT3JGaWxlLCBDQU5WQVNfRklMRV9FWFRFTlNJT04pO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gZmlsZSBpcyBhbiBpbnN0YW5jZSBvZiBURmlsZS5cbiAqXG4gKiBAcGFyYW0gZmlsZSAtIFRoZSBmaWxlIHRvIGNoZWNrLlxuICogQHJldHVybnMgQSBib29sZWFuIGluZGljYXRpbmcgd2hldGhlciB0aGUgZmlsZSBpcyBhbiBpbnN0YW5jZSBvZiBURmlsZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRmlsZShmaWxlOiB1bmtub3duKTogZmlsZSBpcyBURmlsZSB7XG4gIHJldHVybiBmaWxlIGluc3RhbmNlb2YgVEZpbGU7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBmaWxlIGlzIGEgZm9sZGVyLlxuICpcbiAqIEBwYXJhbSBmaWxlIC0gVGhlIGZpbGUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGZpbGUgaXMgYSBmb2xkZXIsIGBmYWxzZWAgb3RoZXJ3aXNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNGb2xkZXIoZmlsZTogdW5rbm93bik6IGZpbGUgaXMgVEZvbGRlciB7XG4gIHJldHVybiBmaWxlIGluc3RhbmNlb2YgVEZvbGRlcjtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIGdpdmVuIGZpbGUgaXMgYSBNYXJrZG93biBmaWxlLlxuICpcbiAqIEBwYXJhbSBhcHAgLSBUaGUgT2JzaWRpYW4gQXBwIGluc3RhbmNlLlxuICogQHBhcmFtIHBhdGhPckZpbGUgLSBUaGUgcGF0aCBvciBmaWxlIHRvIGNoZWNrLlxuICogQHJldHVybnMgQSBib29sZWFuIGluZGljYXRpbmcgd2hldGhlciB0aGUgZmlsZSBpcyBhIE1hcmtkb3duIGZpbGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc01hcmtkb3duRmlsZShhcHA6IEFwcCwgcGF0aE9yRmlsZTogbnVsbCB8IFBhdGhPckFic3RyYWN0RmlsZSk6IGJvb2xlYW4ge1xuICByZXR1cm4gY2hlY2tFeHRlbnNpb24oYXBwLCBwYXRoT3JGaWxlLCBNQVJLRE9XTl9GSUxFX0VYVEVOU0lPTik7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBnaXZlbiBmaWxlIGlzIGEgbm90ZS5cbiAqXG4gKiBAcGFyYW0gYXBwIC0gVGhlIE9ic2lkaWFuIEFwcCBpbnN0YW5jZS5cbiAqIEBwYXJhbSBwYXRoT3JGaWxlIC0gVGhlIHBhdGggb3IgZmlsZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIEEgYm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIGZpbGUgaXMgYSBub3RlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNOb3RlKGFwcDogQXBwLCBwYXRoT3JGaWxlOiBudWxsIHwgUGF0aE9yQWJzdHJhY3RGaWxlKTogYm9vbGVhbiB7XG4gIHJldHVybiBpc01hcmtkb3duRmlsZShhcHAsIHBhdGhPckZpbGUpIHx8IGlzQ2FudmFzRmlsZShhcHAsIHBhdGhPckZpbGUpIHx8IGlzQmFzZUZpbGUoYXBwLCBwYXRoT3JGaWxlKTtcbn1cblxuLyoqXG4gKiBUcmltcyB0aGUgbWFya2Rvd24gZXh0ZW5zaW9uIGZyb20gdGhlIGZpbGUgcGF0aCBpZiB0aGUgZmlsZSBpcyBhIG1hcmtkb3duIGZpbGUuXG4gKiBJZiB0aGUgZmlsZSBpcyBub3QgYSBtYXJrZG93biBmaWxlLCB0aGUgb3JpZ2luYWwgZmlsZSBwYXRoIGlzIHJldHVybmVkLlxuICpcbiAqIEBwYXJhbSBhcHAgLSBUaGUgT2JzaWRpYW4gQXBwIGluc3RhbmNlLlxuICogQHBhcmFtIGZpbGUgLSBUaGUgZmlsZSB0byB0cmltIHRoZSBtYXJrZG93biBleHRlbnNpb24gZnJvbS5cbiAqIEByZXR1cm5zIFRoZSBmaWxlIHBhdGggd2l0aCB0aGUgbWFya2Rvd24gZXh0ZW5zaW9uIHRyaW1tZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0cmltTWFya2Rvd25FeHRlbnNpb24oYXBwOiBBcHAsIGZpbGU6IFRBYnN0cmFjdEZpbGUpOiBzdHJpbmcge1xuICBpZiAoIWlzTWFya2Rvd25GaWxlKGFwcCwgZmlsZSkpIHtcbiAgICByZXR1cm4gZmlsZS5wYXRoO1xuICB9XG5cbiAgcmV0dXJuIHRyaW1FbmQoZmlsZS5wYXRoLCBgLiR7TUFSS0RPV05fRklMRV9FWFRFTlNJT059YCk7XG59XG5cbmZ1bmN0aW9uIGdldEZpbGVJbnRlcm5hbChhcHA6IEFwcCwgcGF0aDogc3RyaW5nLCBpc0Nhc2VJbnNlbnNpdGl2ZT86IGJvb2xlYW4pOiBudWxsIHwgVEFic3RyYWN0RmlsZSB7XG4gIGlmIChpc0Nhc2VJbnNlbnNpdGl2ZSkge1xuICAgIHJldHVybiBhcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoSW5zZW5zaXRpdmUocGF0aCk7XG4gIH1cblxuICByZXR1cm4gYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChwYXRoKSBhcyBudWxsIHwgVEZpbGU7XG59XG5cbmZ1bmN0aW9uIGdldFJlc29sdmVkUGF0aChwYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gbm9ybWFsaXplUGF0aChyZXNvbHZlKCcvJywgcGF0aCkpO1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7OztBQVFBO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBQ1A7QUFBQSxFQUNFO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBRVA7QUFBQSxFQUNFO0FBQUEsRUFDQTtBQUFBLE9BQ0s7QUFDUCxTQUFTLGVBQWU7QUFLakIsTUFBTSxzQkFBc0I7QUFLNUIsTUFBTSx3QkFBd0I7QUFLOUIsTUFBTSwwQkFBMEI7QUF5QmhDLFNBQVMsZUFBZSxLQUFVLFlBQXVDLFdBQTRCO0FBQzFH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