obsidian-dev-utils
Version:
This is the collection of useful functions that you can use for your Obsidian plugin development
224 lines (210 loc) • 17.7 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) {
// eslint-disable-next-line no-global-assign, no-implicit-globals -- We need to patch the `require()` function.
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;
}
function extractDefault(module) {
return module && module.__esModule && 'default' in module ? module.default : module;
}
const OBSIDIAN_BUILT_IN_MODULE_NAMES = [
'obsidian',
'@codemirror/autocomplete',
'@codemirror/collab',
'@codemirror/commands',
'@codemirror/language',
'@codemirror/lint',
'@codemirror/search',
'@codemirror/state',
'@codemirror/text',
'@codemirror/view',
'@lezer/common',
'@lezer/lr',
'@lezer/highlight'];
const DEPRECATED_OBSIDIAN_BUILT_IN_MODULE_NAMES = [
'@codemirror/closebrackets',
'@codemirror/comment',
'@codemirror/fold',
'@codemirror/gutter',
'@codemirror/highlight',
'@codemirror/history',
'@codemirror/matchbrackets',
'@codemirror/panel',
'@codemirror/rangeset',
'@codemirror/rectangular-selection',
'@codemirror/stream-parser',
'@codemirror/tooltip'];
function requirePatched(id) {
if (OBSIDIAN_BUILT_IN_MODULE_NAMES.includes(id) || DEPRECATED_OBSIDIAN_BUILT_IN_MODULE_NAMES.includes(id)) {
return originalRequire?.(id);
}
// eslint-disable-next-line @typescript-eslint/no-deprecated, @typescript-eslint/no-unnecessary-condition -- We need access to app here which might not be available yet.
if (globalThis?.app?.isMobile) {
if (id === 'process' || id === 'node:process') {
console.debug(`The most likely you can safely ignore this error. Module not found: ${id}. Fake process object is returned instead.`);
return globalThis.process;
}
} else {
const module = originalRequire?.(id);
if (module) {
return extractDefault(module);
}
}
console.debug(`The most likely you can safely ignore this error. Module not found: ${id}. Empty object is returned instead.`);
return {};
}
})();
;
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 Loop_exports = {};
__export(Loop_exports, {
loop: () => loop
});
module.exports = __toCommonJS(Loop_exports);
var import_obsidian = require('obsidian');
var import_AbortController = require('../AbortController.cjs');
var import_Async = require('../Async.cjs');
var import_Debug = require('../Debug.cjs');
var import_Error = require('../Error.cjs');
var import_Function = require('../Function.cjs');
var import_PluginContext = require('./Plugin/PluginContext.cjs');
async function loop(options) {
const DEFAULT_OPTIONS = {
abortSignal: (0, import_AbortController.abortSignalNever)(),
buildNoticeMessage() {
throw new Error("buildNoticeMessage is required");
},
items: [],
// eslint-disable-next-line no-magic-numbers -- Extracting magic number as a constant would be repetitive, as the value is used only once and its name would be the same as the property.
noticeBeforeShownTimeoutInMilliseconds: 500,
// eslint-disable-next-line no-magic-numbers -- Extracting magic number as a constant would be repetitive, as the value is used only once and its name would be the same as the property.
noticeMinTimeoutInMilliseconds: 2e3,
processItem: import_Function.noop,
progressBarTitle: "",
shouldContinueOnError: true,
shouldShowNotice: true,
shouldShowProgressBar: true,
// eslint-disable-next-line no-magic-numbers -- Extracting magic number as a constant would be repetitive, as the value is used only once and its name would be the same as the property.
uiUpdateThresholdInMilliseconds: 100
};
const fullOptions = {
...DEFAULT_OPTIONS,
...options
};
const stackTrace = (0, import_Error.getStackTrace)(1);
const items = fullOptions.items;
let iterationCount = 0;
let notice = null;
let isDone = false;
(0, import_Async.invokeAsyncSafely)(() => showNotice());
const noticeMinTimeoutPromise = sleep(fullOptions.noticeMinTimeoutInMilliseconds);
const progressBarEl = createEl("progress");
(0, import_PluginContext.addPluginCssClasses)(progressBarEl, "loop");
progressBarEl.max = items.length;
let lastUIUpdateTimestamp = performance.now();
for (const item of items) {
if (fullOptions.abortSignal.aborted) {
notice?.hide();
return;
}
iterationCount++;
const iterationStr = `# ${String(iterationCount)} / ${String(items.length)}`;
const message = fullOptions.buildNoticeMessage(item, iterationStr);
if (!fullOptions.shouldShowProgressBar) {
notice?.setMessage(message);
}
(0, import_Debug.getLibDebugger)("Loop")(message);
try {
if (performance.now() - lastUIUpdateTimestamp > fullOptions.uiUpdateThresholdInMilliseconds) {
await (0, import_Async.requestAnimationFrameAsync)();
lastUIUpdateTimestamp = performance.now();
}
await fullOptions.processItem(item);
} catch (error) {
console.error("Error processing item", item);
if (!fullOptions.shouldContinueOnError) {
notice?.hide();
throw new import_Error.CustomStackTraceError("loop failed", stackTrace, error);
}
(0, import_Error.emitAsyncErrorEvent)(new import_Error.CustomStackTraceError(import_Error.ASYNC_WRAPPER_ERROR_MESSAGE, stackTrace, error));
}
progressBarEl.value++;
}
if (notice) {
await noticeMinTimeoutPromise;
}
notice?.hide();
isDone = true;
async function showNotice() {
if (!fullOptions.shouldShowNotice) {
return;
}
await sleep(fullOptions.noticeBeforeShownTimeoutInMilliseconds);
if (isDone) {
return;
}
notice = new import_obsidian.Notice("", 0);
if (!fullOptions.shouldShowProgressBar) {
return;
}
const fragment = createFragment();
fragment.createDiv({ text: fullOptions.progressBarTitle });
fragment.appendChild(progressBarEl);
notice.setMessage(fragment);
}
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
loop
});
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vc3JjL29ic2lkaWFuL0xvb3AudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQHBhY2thZ2VEb2N1bWVudGF0aW9uXG4gKlxuICogQ29udGFpbnMgdXRpbGl0eSBmdW5jdGlvbnMgZm9yIGxvb3BpbmcgaW4gT2JzaWRpYW4uXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBQcm9taXNhYmxlIH0gZnJvbSAndHlwZS1mZXN0JztcblxuaW1wb3J0IHsgTm90aWNlIH0gZnJvbSAnb2JzaWRpYW4nO1xuXG5pbXBvcnQgeyBhYm9ydFNpZ25hbE5ldmVyIH0gZnJvbSAnLi4vQWJvcnRDb250cm9sbGVyLnRzJztcbmltcG9ydCB7XG4gIGludm9rZUFzeW5jU2FmZWx5LFxuICByZXF1ZXN0QW5pbWF0aW9uRnJhbWVBc3luY1xufSBmcm9tICcuLi9Bc3luYy50cyc7XG5pbXBvcnQgeyBnZXRMaWJEZWJ1Z2dlciB9IGZyb20gJy4uL0RlYnVnLnRzJztcbmltcG9ydCB7XG4gIEFTWU5DX1dSQVBQRVJfRVJST1JfTUVTU0FHRSxcbiAgQ3VzdG9tU3RhY2tUcmFjZUVycm9yLFxuICBlbWl0QXN5bmNFcnJvckV2ZW50LFxuICBnZXRTdGFja1RyYWNlXG59IGZyb20gJy4uL0Vycm9yLnRzJztcbmltcG9ydCB7IG5vb3AgfSBmcm9tICcuLi9GdW5jdGlvbi50cyc7XG5pbXBvcnQgeyBhZGRQbHVnaW5Dc3NDbGFzc2VzIH0gZnJvbSAnLi9QbHVnaW4vUGx1Z2luQ29udGV4dC50cyc7XG5cbi8qKlxuICogT3B0aW9ucyBmb3Ige0BsaW5rIGxvb3B9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIExvb3BPcHRpb25zPFQ+IHtcbiAgLyoqXG4gICAqIEFuIG9wdGlvbmFsIGFib3J0IHNpZ25hbCB0byBjYW5jZWwgdGhlIGxvb3AuXG4gICAqL1xuICBhYm9ydFNpZ25hbD86IEFib3J0U2lnbmFsO1xuXG4gIC8qKlxuICAgKiBCdWlsZCBhIG5vdGljZSBtZXNzYWdlIGZvciBlYWNoIGl0ZW0uXG4gICAqXG4gICAqIEBwYXJhbSBpdGVtIC0gVGhlIGN1cnJlbnQgaXRlbS5cbiAgICogQHBhcmFtIGl0ZXJhdGlvblN0ciAtIEEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgY3VycmVudCBpdGVyYXRpb24uXG4gICAqIEByZXR1cm5zIEEgc3RyaW5nIHRvIGRpc3BsYXkgaW4gdGhlIG5vdGljZS5cbiAgICovXG4gIGJ1aWxkTm90aWNlTWVzc2FnZShpdGVtOiBULCBpdGVyYXRpb25TdHI6IHN0cmluZyk6IHN0cmluZztcblxuICAvKipcbiAgICogSXRlbXMgdG8gbG9vcCBvdmVyLlxuICAgKi9cbiAgaXRlbXM6IFRbXTtcblxuICAvKipcbiAgICogQSB0aW1lb3V0IGZvciB0aGUgbm90aWNlIGJlZm9yZSBpdCBpcyBzaG93bi4gRGVmYXVsdCBpcyBgNTAwYC5cbiAgICovXG4gIG5vdGljZUJlZm9yZVNob3duVGltZW91dEluTWlsbGlzZWNvbmRzPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBBIG1pbmltdW0gdGltZW91dCBmb3IgdGhlIG5vdGljZS4gRGVmYXVsdCBpcyBgMjAwMGAuXG4gICAqL1xuICBub3RpY2VNaW5UaW1lb3V0SW5NaWxsaXNlY29uZHM/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFByb2Nlc3MgZWFjaCBpdGVtLlxuICAgKlxuICAgKiBAcGFyYW0gaXRlbSAtIFRoZSBjdXJyZW50IGl0ZW0uXG4gICAqL1xuICBwcm9jZXNzSXRlbShpdGVtOiBUKTogUHJvbWlzYWJsZTx2b2lkPjtcblxuICAvKipcbiAgICogQSB0aXRsZSBvZiB0aGUgcHJvZ3Jlc3MgYmFyLiBEZWZhdWx0IGlzIGAnJ2AuXG4gICAqL1xuICBwcm9ncmVzc0JhclRpdGxlPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGNvbnRpbnVlIHRoZSBsb29wIG9uIGVycm9yLiBEZWZhdWx0IGlzIGB0cnVlYC5cbiAgICovXG4gIHNob3VsZENvbnRpbnVlT25FcnJvcj86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gc2hvdyBhIG5vdGljZS4gRGVmYXVsdCBpcyBgdHJ1ZWAuXG4gICAqL1xuICBzaG91bGRTaG93Tm90aWNlPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogV2hldGhlciB0byBzaG93IGEgcHJvZ3Jlc3MgYmFyLiBEZWZhdWx0IGlzIGB0cnVlYC5cbiAgICovXG4gIHNob3VsZFNob3dQcm9ncmVzc0Jhcj86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEEgdGhyZXNob2xkIGZvciB0aGUgVUkgdXBkYXRlLiBEZWZhdWx0IGlzIGAxMDBgLlxuICAgKi9cbiAgdWlVcGRhdGVUaHJlc2hvbGRJbk1pbGxpc2Vjb25kcz86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBMb29wcyBvdmVyIGEgbGlzdCBvZiBpdGVtcyBhbmQgcHJvY2Vzc2VzIGVhY2ggaXRlbS5cbiAqXG4gKiBAcGFyYW0gb3B0aW9ucyAtIFRoZSBvcHRpb25zIGZvciB0aGUgbG9vcC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxvb3A8VD4ob3B0aW9uczogTG9vcE9wdGlvbnM8VD4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgREVGQVVMVF9PUFRJT05TOiBSZXF1aXJlZDxMb29wT3B0aW9uczxUPj4gPSB7XG4gICAgYWJvcnRTaWduYWw6IGFib3J0U2lnbmFsTmV2ZXIoKSxcbiAgICBidWlsZE5vdGljZU1lc3NhZ2UoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2J1aWxkTm90aWNlTWVzc2FnZSBpcyByZXF1aXJlZCcpO1xuICAgIH0sXG4gICAgaXRlbXM6IFtdLFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1tYWdpYy1udW1iZXJzIC0tIEV4dHJhY3RpbmcgbWFnaWMgbnVtYmVyIGFzIGEgY29uc3RhbnQgd291bGQgYmUgcmVwZXRpdGl2ZSwgYXMgdGhlIHZhbHVlIGlzIHVzZWQgb25seSBvbmNlIGFuZCBpdHMgbmFtZSB3b3VsZCBiZSB0aGUgc2FtZSBhcyB0aGUgcHJvcGVydHkuXG4gICAgbm90aWNlQmVmb3JlU2hvd25UaW1lb3V0SW5NaWxsaXNlY29uZHM6IDUwMCxcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tbWFnaWMtbnVtYmVycyAtLSBFeHRyYWN0aW5nIG1hZ2ljIG51bWJlciBhcyBhIGNvbnN0YW50IHdvdWxkIGJlIHJlcGV0aXRpdmUsIGFzIHRoZSB2YWx1ZSBpcyB1c2VkIG9ubHkgb25jZSBhbmQgaXRzIG5hbWUgd291bGQgYmUgdGhlIHNhbWUgYXMgdGhlIHByb3BlcnR5LlxuICAgIG5vdGljZU1pblRpbWVvdXRJbk1pbGxpc2Vjb25kczogMjAwMCxcbiAgICBwcm9jZXNzSXRlbTogbm9vcCxcbiAgICBwcm9ncmVzc0JhclRpdGxlOiAnJyxcbiAgICBzaG91bGRDb250aW51ZU9uRXJyb3I6IHRydWUsXG4gICAgc2hvdWxkU2hvd05vdGljZTogdHJ1ZSxcbiAgICBzaG91bGRTaG93UHJvZ3Jlc3NCYXI6IHRydWUsXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLW1hZ2ljLW51bWJlcnMgLS0gRXh0cmFjdGluZyBtYWdpYyBudW1iZXIgYXMgYSBjb25zdGFudCB3b3VsZCBiZSByZXBldGl0aXZlLCBhcyB0aGUgdmFsdWUgaXMgdXNlZCBvbmx5IG9uY2UgYW5kIGl0cyBuYW1lIHdvdWxkIGJlIHRoZSBzYW1lIGFzIHRoZSBwcm9wZXJ0eS5cbiAgICB1aVVwZGF0ZVRocmVzaG9sZEluTWlsbGlzZWNvbmRzOiAxMDBcbiAgfTtcblxuICBjb25zdCBmdWxsT3B0aW9uczogUmVxdWlyZWQ8TG9vcE9wdGlvbnM8VD4+ID0ge1xuICAgIC4uLkRFRkFVTFRfT1BUSU9OUyxcbiAgICAuLi5vcHRpb25zXG4gIH07XG5cbiAgY29uc3Qgc3RhY2tUcmFjZSA9IGdldFN0YWNrVHJhY2UoMSk7XG5cbiAgY29uc3QgaXRlbXMgPSBmdWxsT3B0aW9ucy5pdGVtcztcbiAgbGV0IGl0ZXJhdGlvbkNvdW50ID0gMDtcbiAgbGV0IG5vdGljZSA9IG51bGwgYXMgTm90aWNlIHwgbnVsbDtcbiAgbGV0IGlzRG9uZSA9IGZhbHNlO1xuICBpbnZva2VBc3luY1NhZmVseSgoKSA9PiBzaG93Tm90aWNlKCkpO1xuXG4gIGNvbnN0IG5vdGljZU1pblRpbWVvdXRQcm9taXNlID0gc2xlZXAoZnVsbE9wdGlvbnMubm90aWNlTWluVGltZW91dEluTWlsbGlzZWNvbmRzKTtcbiAgY29uc3QgcHJvZ3Jlc3NCYXJFbCA9IGNyZWF0ZUVsKCdwcm9ncmVzcycpO1xuICBhZGRQbHVnaW5Dc3NDbGFzc2VzKHByb2dyZXNzQmFyRWwsICdsb29wJyk7XG4gIHByb2dyZXNzQmFyRWwubWF4ID0gaXRlbXMubGVuZ3RoO1xuXG4gIGxldCBsYXN0VUlVcGRhdGVUaW1lc3RhbXAgPSBwZXJmb3JtYW5jZS5ub3coKTtcblxuICBmb3IgKGNvbnN0IGl0ZW0gb2YgaXRlbXMpIHtcbiAgICBpZiAoZnVsbE9wdGlvbnMuYWJvcnRTaWduYWwuYWJvcnRlZCkge1xuICAgICAgbm90aWNlPy5oaWRlKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGl0ZXJhdGlvbkNvdW50Kys7XG4gICAgY29uc3QgaXRlcmF0aW9uU3RyID0gYCMgJHtTdHJpbmcoaXRlcmF0aW9uQ291bnQpfSAvICR7U3RyaW5nKGl0ZW1zLmxlbmd0aCl9YDtcbiAgICBjb25zdCBtZXNzYWdlID0gZnVsbE9wdGlvbnMuYnVpbGROb3RpY2VNZXNzYWdlKGl0ZW0sIGl0ZXJhdGlvblN0cik7XG4gICAgaWYgKCFmdWxsT3B0aW9ucy5zaG91bGRTaG93UHJvZ3Jlc3NCYXIpIHtcbiAgICAgIG5vdGljZT8uc2V0TWVzc2FnZShtZXNzYWdlKTtcbiAgICB9XG4gICAgZ2V0TGliRGVidWdnZXIoJ0xvb3AnKShtZXNzYWdlKTtcblxuICAgIHRyeSB7XG4gICAgICBpZiAocGVyZm9ybWFuY2Uubm93KCkgLSBsYXN0VUlVcGRhdGVUaW1lc3RhbXAgPiBmdWxsT3B0aW9ucy51aVVwZGF0ZVRocmVzaG9sZEluTWlsbGlzZWNvbmRzKSB7XG4gICAgICAgIGF3YWl0IHJlcXVlc3RBbmltYXRpb25GcmFtZUFzeW5jKCk7XG4gICAgICAgIGxhc3RVSVVwZGF0ZVRpbWVzdGFtcCA9IHBlcmZvcm1hbmNlLm5vdygpO1xuICAgICAgfVxuICAgICAgYXdhaXQgZnVsbE9wdGlvbnMucHJvY2Vzc0l0ZW0oaXRlbSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHByb2Nlc3NpbmcgaXRlbScsIGl0ZW0pO1xuICAgICAgaWYgKCFmdWxsT3B0aW9ucy5zaG91bGRDb250aW51ZU9uRXJyb3IpIHtcbiAgICAgICAgbm90aWNlPy5oaWRlKCk7XG4gICAgICAgIHRocm93IG5ldyBDdXN0b21TdGFja1RyYWNlRXJyb3IoJ2xvb3AgZmFpbGVkJywgc3RhY2tUcmFjZSwgZXJyb3IpO1xuICAgICAgfVxuXG4gICAgICBlbWl0QXN5bmNFcnJvckV2ZW50KG5ldyBDdXN0b21TdGFja1RyYWNlRXJyb3IoQVNZTkNfV1JBUFBFUl9FUlJPUl9NRVNTQUdFLCBzdGFja1RyYWNlLCBlcnJvcikpO1xuICAgIH1cbiAgICBwcm9ncmVzc0JhckVsLnZhbHVlKys7XG4gIH1cbiAgaWYgKG5vdGljZSkge1xuICAgIGF3YWl0IG5vdGljZU1pblRpbWVvdXRQcm9taXNlO1xuICB9XG4gIG5vdGljZT8uaGlkZSgpO1xuICBpc0RvbmUgPSB0cnVlO1xuXG4gIGFzeW5jIGZ1bmN0aW9uIHNob3dOb3RpY2UoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCFmdWxsT3B0aW9ucy5zaG91bGRTaG93Tm90aWNlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGF3YWl0IHNsZWVwKGZ1bGxPcHRpb25zLm5vdGljZUJlZm9yZVNob3duVGltZW91dEluTWlsbGlzZWNvbmRzKTtcbiAgICBpZiAoaXNEb25lKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIG5vdGljZSA9IG5ldyBOb3RpY2UoJycsIDApO1xuICAgIGlmICghZnVsbE9wdGlvbnMuc2hvdWxkU2hvd1Byb2dyZXNzQmFyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGZyYWdtZW50ID0gY3JlYXRlRnJhZ21lbnQoKTtcbiAgICBmcmFnbWVudC5jcmVhdGVEaXYoeyB0ZXh0OiBmdWxsT3B0aW9ucy5wcm9ncmVzc0JhclRpdGxlIH0pO1xuICAgIGZyYWdtZW50LmFwcGVuZENoaWxkKHByb2dyZXNzQmFyRWwpO1xuICAgIG5vdGljZS5zZXRNZXNzYWdlKGZyYWdtZW50KTtcbiAgfVxufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFRQSxzQkFBdUI7QUFFdkIsNkJBQWlDO0FBQ2pDLG1CQUdPO0FBQ1AsbUJBQStCO0FBQy9CLG1CQUtPO0FBQ1Asc0JBQXFCO0FBQ3JCLDJCQUFvQztBQXlFcEMsZUFBc0IsS0FBUSxTQUF3QztBQUNwRSxRQUFNLGtCQUE0QztBQUFBLElBQ2hELGlCQUFhLHlDQUFpQjtBQUFBLElBQzlCLHFCQUFxQjtBQUNuQixZQUFNLElBQUksTUFBTSxnQ0FBZ0M7QUFBQSxJQUNsRDtBQUFBLElBQ0EsT0FBTyxDQUFDO0FBQUE7QUFBQSxJQUVSLHdDQUF3QztBQUFBO0FBQUEsSUFFeEMsZ0NBQWdDO0FBQUEsSUFDaEMsYUFBYTtBQUFBLElBQ2Isa0JBQWtCO0FBQUEsSUFDbEIsdUJBQXVCO0FBQUEsSUFDdkIsa0JBQWtCO0FBQUEsSUFDbEIsdUJBQXVCO0FBQUE7QUFBQSxJQUV2QixpQ0FBaUM7QUFBQSxFQUNuQztBQUVBLFFBQU0sY0FBd0M7QUFBQSxJQUM1QyxHQUFHO0FBQUEsSUFDSCxHQUFHO0FBQUEsRUFDTDtBQUVBLFFBQU0saUJBQWEsNEJBQWMsQ0FBQztBQUVsQyxRQUFNLFFBQVEsWUFBWTtBQUMxQixNQUFJLGlCQUFpQjtBQUNyQixNQUFJLFNBQVM7QUFDYixNQUFJLFNBQVM7QUFDYixzQ0FBa0IsTUFBTSxXQUFXLENBQUM7QUFFcEMsUUFBTSwwQkFBMEIsTUFBTSxZQUFZLDhCQUE4QjtBQUNoRixRQUFNLGdCQUFnQixTQUFTLFVBQVU7QUFDekMsZ0RBQW9CLGVBQWUsTUFBTTtBQUN6QyxnQkFBYyxNQUFNLE1BQU07QUFFMUIsTUFBSSx3QkFBd0IsWUFBWSxJQUFJO0FBRTVDLGFBQVcsUUFBUSxPQUFPO0FBQ3hCLFFBQUksWUFBWSxZQUFZLFNBQVM7QUFDbkMsY0FBUSxLQUFLO0FBQ2I7QUFBQSxJQUNGO0FBQ0E7QUFDQSxVQUFNLGVBQWUsS0FBSyxPQUFPLGNBQWMsQ0FBQyxNQUFNLE9BQU8sTUFBTSxNQUFNLENBQUM7QUFDMUUsVUFBTSxVQUFVLFlBQVksbUJBQW1CLE1BQU0sWUFBWTtBQUNqRSxRQUFJLENBQUMsWUFBWSx1QkFBdUI7QUFDdEMsY0FBUSxXQUFXLE9BQU87QUFBQSxJQUM1QjtBQUNBLHFDQUFlLE1BQU0sRUFBRSxPQUFPO0FBRTlCLFFBQUk7QUFDRixVQUFJLFlBQVksSUFBSSxJQUFJLHdCQUF3QixZQUFZLGlDQUFpQztBQUMzRixrQkFBTSx5Q0FBMkI7QUFDakMsZ0NBQXdCLFlBQVksSUFBSTtBQUFBLE1BQzFDO0FBQ0EsWUFBTSxZQUFZLFlBQVksSUFBSTtBQUFBLElBQ3BDLFNBQVMsT0FBTztBQUNkLGNBQVEsTUFBTSx5QkFBeUIsSUFBSTtBQUMzQyxVQUFJLENBQUMsWUFBWSx1QkFBdUI7QUFDdEMsZ0JBQVEsS0FBSztBQUNiLGNBQU0sSUFBSSxtQ0FBc0IsZUFBZSxZQUFZLEtBQUs7QUFBQSxNQUNsRTtBQUVBLDRDQUFvQixJQUFJLG1DQUFzQiwwQ0FBNkIsWUFBWSxLQUFLLENBQUM7QUFBQSxJQUMvRjtBQUNBLGtCQUFjO0FBQUEsRUFDaEI7QUFDQSxNQUFJLFFBQVE7QUFDVixVQUFNO0FBQUEsRUFDUjtBQUNBLFVBQVEsS0FBSztBQUNiLFdBQVM7QUFFVCxpQkFBZSxhQUE0QjtBQUN6QyxRQUFJLENBQUMsWUFBWSxrQkFBa0I7QUFDakM7QUFBQSxJQUNGO0FBQ0EsVUFBTSxNQUFNLFlBQVksc0NBQXNDO0FBQzlELFFBQUksUUFBUTtBQUNWO0FBQUEsSUFDRjtBQUNBLGFBQVMsSUFBSSx1QkFBTyxJQUFJLENBQUM7QUFDekIsUUFBSSxDQUFDLFlBQVksdUJBQXVCO0FBQ3RDO0FBQUEsSUFDRjtBQUNBLFVBQU0sV0FBVyxlQUFlO0FBQ2hDLGFBQVMsVUFBVSxFQUFFLE1BQU0sWUFBWSxpQkFBaUIsQ0FBQztBQUN6RCxhQUFTLFlBQVksYUFBYTtBQUNsQyxXQUFPLFdBQVcsUUFBUTtBQUFBLEVBQzVCO0FBQ0Y7IiwKICAibmFtZXMiOiBbXQp9Cg==