From ebf539c3562f8fcfe2c791c5038a1f82b35ecbdb Mon Sep 17 00:00:00 2001 From: blongty Date: Mon, 18 Oct 2021 12:47:01 -0700 Subject: [PATCH] Pre-0.2 commit --- .obsidian/community-plugins.json | 6 +- .obsidian/graph.json | 4 +- .../main.js | 159 - .../manifest.json | 9 - .../obsidian-sort-and-permute-lines/main.js | 237 - .../manifest.json | 9 - .../plugins/obsidian-task-archiver/main.js | 294 - .../obsidian-task-archiver/manifest.json | 10 - .obsidian/plugins/quickadd/data.json | 610 - .obsidian/plugins/quickadd/main.js | 15223 ---------------- .obsidian/plugins/quickadd/manifest.json | 10 - .obsidian/plugins/quickadd/styles.css | 168 - .obsidian/plugins/tag-wrangler/main.js | 7381 ++++++++ .obsidian/plugins/tag-wrangler/manifest.json | 8 + .obsidian/plugins/tag-wrangler/styles.css | 172 + .../plugins/templater-obsidian/data.json | 2 +- .obsidian/plugins/vantage-obsidian/main.js | 815 - .../plugins/vantage-obsidian/manifest.json | 10 - .obsidian/starred.json | 17 +- .obsidian/workspace | 119 +- "00 \360\237\217\240 Main Dashboard.md" | 114 +- "000 Inbox/00 \342\235\227 Readme.md" | 113 +- 000 Inbox/Other Useful Functionality.md | 18 - "01 \360\237\224\201 Habits Dashboard.md" | 43 - .../00 \342\234\250 Example Habit.md" | 214 - ...1 \360\237\214\212 Tasks Example Habit.md" | 12 - ...60\237\222\241 Ramblings Example Habit.md" | 9 - ...10 \360\237\216\200 Example Discipline.md" | 231 +- ...0\237\214\212 Tasks Example Discipline.md" | 11 - ...7\222\241 Ramblings Example Discipline.md" | 9 - .../00 \360\237\216\201 Example Project.md" | 192 - ...\360\237\214\212 Tasks Example Project.md" | 15 - ...\237\222\241 Ramblings Example Project.md" | 11 - .../Setup/00 \360\237\247\260 Setup.md" | 44 + .../10 \360\237\222\227 Defining Life.md" | 64 + ...\237\224\200 Divergence to Disciplines.md" | 93 + ...\360\237\224\202 Convergence to Ikigai.md" | 154 + .../13 \360\237\216\216 Ikigai Expansion.md" | 69 + .../210 Daily/2021-10-06 Stand-up.md | 97 - 200 Alignment/210 Daily/2021-10-06.md | 16 - 200 Alignment/220 Weekly/2021-W41.md | 189 - 200 Alignment/230 Monthly/2021-10.md | 182 - 200 Alignment/240 Quarterly/2021-Q4.md | 65 - 200 Alignment/250 Yearly/2021.md | 72 - 300 Resources/Agile Project Management.md | 6 +- 300 Resources/Artifacts (Scrum).md | 8 +- 300 Resources/Atomic Habits.md | 133 - 300 Resources/Burnout.md | 31 - 300 Resources/Ceremonies (Scrum).md | 8 +- 300 Resources/Ceremonies.md | 10 - 300 Resources/Default Mode Network.md | 28 - 300 Resources/Disciplines.md | 65 +- 300 Resources/Dynamics.md | 10 + 300 Resources/Eisenhower Matrix.md | 57 - 300 Resources/Flow.md | 28 - 300 Resources/Friction.md | 36 +- 300 Resources/Fundamentals of LDP.md | 74 + 300 Resources/Getting Things Done.md | 2 +- 300 Resources/Habits.md | 57 - 300 Resources/Ikigai-9.md | 23 - 300 Resources/Ikigai.md | 7 +- 300 Resources/Inbox.md | 6 + 300 Resources/Kanban (Agile).md | 31 +- 300 Resources/Kanban vs Scrum.md | 28 +- 300 Resources/Life (LDP).md | 12 + 300 Resources/Ongoing Tasks.md | 8 + .../Philosophy - How to Approach LDP.md | 44 + .../Pillars, Pipelines, Vaults (PPV).md | 8 +- 300 Resources/Pillars.md | 4 +- 300 Resources/Product Backlog.md | 19 - 300 Resources/Projects.md | 118 +- 300 Resources/Scrum (Agile).md | 12 +- 300 Resources/Scrum Metrics.md | 28 - .../Simple Integration Into Obsidian.md | 57 + 300 Resources/Sprint Backlog.md | 8 - 300 Resources/Sprints (Scrum).md | 4 +- .../Suggestions After Learning Initial LDP.md | 10 + 300 Resources/Systems Thinking.md | 20 +- 300 Resources/Systems.md | 10 + 300 Resources/Tasks.md | 123 +- 300 Resources/True Deadlines.md | 12 + 300 Resources/Work Hierarchy (Scrum).md | 2 +- 300 Resources/Working with LDP.md | 36 + 300 Resources/scrum_process_atlassian.svg | 540 + 700 Views/Curation.md | 6 - 700 Views/Disciplines (View).md | 8 - 700 Views/Habits (View).md | 13 - 700 Views/Ikigai (View).md | 12 - 700 Views/Life Dynamic.md | 6 - 700 Views/Life Pillars.md | 6 - 700 Views/Ongoing Project Reference.md | 13 - .../Project-Disciplines Touched Last Month.md | 9 - .../Project-Disciplines Touched Last Week.md | 9 - 700 Views/Projects Touched Last Month.md | 9 - 700 Views/Projects Touched Last Week.md | 9 - 700 Views/Recently Touched.md | 7 - 700 Views/Reminder.md | 7 - 700 Views/Tasks Completed Last Week.md | 76 - 700 Views/Tasks Completed Today.md | 43 - 700 Views/Tasks Completed Yesterday.md | 43 - 700 Views/Tasks Ongoing.md | 29 - 700 Views/Work-Minutes Last 1 Months.md | 8 - 700 Views/Work-Minutes Last 1-2 Months.md | 8 - 700 Views/Work-Minutes Last 7 Days.md | 8 - 700 Views/Work-Minutes Last 7-14 Days.md | 8 - "80 \360\237\214\212 Tasks Life.md" | 11 - 800 Templates/Dashboard Discipline.md | 215 - 800 Templates/Dashboard Habit.md | 235 - 800 Templates/Dashboard Project.md | 203 - 800 Templates/Journal 00 Daily.md | 33 - 800 Templates/Journal 01 Daily Stand-up.md | 99 - 800 Templates/Journal 20 Weekly.md | 189 - 800 Templates/Journal 30 Monthly.md | 182 - 800 Templates/Journal 40 Quarterly.md | 65 - 800 Templates/Journal 50 Yearly.md | 72 - 800 Templates/Note.md | 2 +- 800 Templates/Ramblings.md | 11 - 800 Templates/Tasks (Catalog).md | 13 - 800 Templates/{leftarrow.md => arrowleft.md} | 0 .../{rightarrow.md => arrowright.md} | 0 800 Templates/task.md | 1 - 800 Templates/test.md | 1 - ...237\227\203\357\270\217 Master Backlog.md" | 11 - "99 \360\237\222\227 Life.md" | 39 +- .../00 \360\237\222\227 Defining Life.md" | 44 - ...\237\224\200 Divergence to Disciplines.md" | 73 - ...\360\237\224\202 Convergence to Ikigai.md" | 139 - .../03 \360\237\216\216 Ikigai Expansion.md" | 74 - Workbench.md | 7 - 129 files changed, 8969 insertions(+), 22110 deletions(-) delete mode 100644 .obsidian/plugins/obsidian-shortcuts-for-starred-files/main.js delete mode 100644 .obsidian/plugins/obsidian-shortcuts-for-starred-files/manifest.json delete mode 100644 .obsidian/plugins/obsidian-sort-and-permute-lines/main.js delete mode 100644 .obsidian/plugins/obsidian-sort-and-permute-lines/manifest.json delete mode 100644 .obsidian/plugins/obsidian-task-archiver/main.js delete mode 100644 .obsidian/plugins/obsidian-task-archiver/manifest.json delete mode 100644 .obsidian/plugins/quickadd/data.json delete mode 100644 .obsidian/plugins/quickadd/main.js delete mode 100644 .obsidian/plugins/quickadd/manifest.json delete mode 100644 .obsidian/plugins/quickadd/styles.css create mode 100644 .obsidian/plugins/tag-wrangler/main.js create mode 100644 .obsidian/plugins/tag-wrangler/manifest.json create mode 100644 .obsidian/plugins/tag-wrangler/styles.css delete mode 100644 .obsidian/plugins/vantage-obsidian/main.js delete mode 100644 .obsidian/plugins/vantage-obsidian/manifest.json delete mode 100644 000 Inbox/Other Useful Functionality.md delete mode 100644 "01 \360\237\224\201 Habits Dashboard.md" delete mode 100644 "100 Disciplines/110 \360\237\216\200 Example Discipline/00 Habit - Example Habit/00 \342\234\250 Example Habit.md" delete mode 100644 "100 Disciplines/110 \360\237\216\200 Example Discipline/00 Habit - Example Habit/01 \360\237\214\212 Tasks Example Habit.md" delete mode 100644 "100 Disciplines/110 \360\237\216\200 Example Discipline/00 Habit - Example Habit/02 \360\237\222\241 Ramblings Example Habit.md" delete mode 100644 "100 Disciplines/110 \360\237\216\200 Example Discipline/111 \360\237\214\212 Tasks Example Discipline.md" delete mode 100644 "100 Disciplines/110 \360\237\216\200 Example Discipline/112 \360\237\222\241 Ramblings Example Discipline.md" delete mode 100644 "100 Disciplines/110 \360\237\216\200 Example Discipline/Example Project/00 \360\237\216\201 Example Project.md" delete mode 100644 "100 Disciplines/110 \360\237\216\200 Example Discipline/Example Project/01 \360\237\214\212 Tasks Example Project.md" delete mode 100644 "100 Disciplines/110 \360\237\216\200 Example Discipline/Example Project/02 \360\237\222\241 Ramblings Example Project.md" create mode 100644 "100 Disciplines/110 \360\237\216\200 Example Discipline/Setup/00 \360\237\247\260 Setup.md" create mode 100644 "100 Disciplines/110 \360\237\216\200 Example Discipline/Setup/10 \360\237\222\227 Defining Life.md" create mode 100644 "100 Disciplines/110 \360\237\216\200 Example Discipline/Setup/11 \360\237\224\200 Divergence to Disciplines.md" create mode 100644 "100 Disciplines/110 \360\237\216\200 Example Discipline/Setup/12 \360\237\224\202 Convergence to Ikigai.md" create mode 100644 "100 Disciplines/110 \360\237\216\200 Example Discipline/Setup/13 \360\237\216\216 Ikigai Expansion.md" delete mode 100644 200 Alignment/210 Daily/2021-10-06 Stand-up.md delete mode 100644 200 Alignment/210 Daily/2021-10-06.md delete mode 100644 200 Alignment/220 Weekly/2021-W41.md delete mode 100644 200 Alignment/230 Monthly/2021-10.md delete mode 100644 200 Alignment/240 Quarterly/2021-Q4.md delete mode 100644 200 Alignment/250 Yearly/2021.md delete mode 100644 300 Resources/Atomic Habits.md delete mode 100644 300 Resources/Burnout.md delete mode 100644 300 Resources/Ceremonies.md delete mode 100644 300 Resources/Default Mode Network.md create mode 100644 300 Resources/Dynamics.md delete mode 100644 300 Resources/Eisenhower Matrix.md delete mode 100644 300 Resources/Flow.md create mode 100644 300 Resources/Fundamentals of LDP.md delete mode 100644 300 Resources/Habits.md delete mode 100644 300 Resources/Ikigai-9.md create mode 100644 300 Resources/Inbox.md create mode 100644 300 Resources/Life (LDP).md create mode 100644 300 Resources/Ongoing Tasks.md create mode 100644 300 Resources/Philosophy - How to Approach LDP.md delete mode 100644 300 Resources/Product Backlog.md delete mode 100644 300 Resources/Scrum Metrics.md create mode 100644 300 Resources/Simple Integration Into Obsidian.md delete mode 100644 300 Resources/Sprint Backlog.md create mode 100644 300 Resources/Suggestions After Learning Initial LDP.md create mode 100644 300 Resources/Systems.md create mode 100644 300 Resources/True Deadlines.md create mode 100644 300 Resources/Working with LDP.md create mode 100644 300 Resources/scrum_process_atlassian.svg delete mode 100644 700 Views/Curation.md delete mode 100644 700 Views/Disciplines (View).md delete mode 100644 700 Views/Habits (View).md delete mode 100644 700 Views/Ikigai (View).md delete mode 100644 700 Views/Life Dynamic.md delete mode 100644 700 Views/Life Pillars.md delete mode 100644 700 Views/Ongoing Project Reference.md delete mode 100644 700 Views/Project-Disciplines Touched Last Month.md delete mode 100644 700 Views/Project-Disciplines Touched Last Week.md delete mode 100644 700 Views/Projects Touched Last Month.md delete mode 100644 700 Views/Projects Touched Last Week.md delete mode 100644 700 Views/Recently Touched.md delete mode 100644 700 Views/Reminder.md delete mode 100644 700 Views/Tasks Completed Last Week.md delete mode 100644 700 Views/Tasks Completed Today.md delete mode 100644 700 Views/Tasks Completed Yesterday.md delete mode 100644 700 Views/Tasks Ongoing.md delete mode 100644 700 Views/Work-Minutes Last 1 Months.md delete mode 100644 700 Views/Work-Minutes Last 1-2 Months.md delete mode 100644 700 Views/Work-Minutes Last 7 Days.md delete mode 100644 700 Views/Work-Minutes Last 7-14 Days.md delete mode 100644 "80 \360\237\214\212 Tasks Life.md" delete mode 100644 800 Templates/Dashboard Discipline.md delete mode 100644 800 Templates/Dashboard Habit.md delete mode 100644 800 Templates/Dashboard Project.md delete mode 100644 800 Templates/Journal 00 Daily.md delete mode 100644 800 Templates/Journal 01 Daily Stand-up.md delete mode 100644 800 Templates/Journal 20 Weekly.md delete mode 100644 800 Templates/Journal 30 Monthly.md delete mode 100644 800 Templates/Journal 40 Quarterly.md delete mode 100644 800 Templates/Journal 50 Yearly.md delete mode 100644 800 Templates/Ramblings.md delete mode 100644 800 Templates/Tasks (Catalog).md rename 800 Templates/{leftarrow.md => arrowleft.md} (100%) rename 800 Templates/{rightarrow.md => arrowright.md} (100%) delete mode 100644 800 Templates/task.md delete mode 100644 800 Templates/test.md delete mode 100644 "90 \360\237\227\203\357\270\217 Master Backlog.md" delete mode 100644 "999 Setup/00 \360\237\222\227 Defining Life.md" delete mode 100644 "999 Setup/01 \360\237\224\200 Divergence to Disciplines.md" delete mode 100644 "999 Setup/02 \360\237\224\202 Convergence to Ikigai.md" delete mode 100644 "999 Setup/03 \360\237\216\216 Ikigai Expansion.md" diff --git a/.obsidian/community-plugins.json b/.obsidian/community-plugins.json index 40170a3..33cecbd 100644 --- a/.obsidian/community-plugins.json +++ b/.obsidian/community-plugins.json @@ -5,13 +5,9 @@ "periodic-notes", "obsidian-tasks-plugin", "templater-obsidian", - "quickadd", "sliding-panes-obsidian", "maximise-active-pane-obsidian", - "obsidian-task-archiver", - "obsidian-shortcuts-for-starred-files", "hotkeysplus-obsidian", - "obsidian-sort-and-permute-lines", "note-refactor-obsidian", - "vantage-obsidian" + "tag-wrangler" ] \ No newline at end of file diff --git a/.obsidian/graph.json b/.obsidian/graph.json index 32ec246..98e0ef6 100644 --- a/.obsidian/graph.json +++ b/.obsidian/graph.json @@ -1,6 +1,6 @@ { "collapse-filter": false, - "search": "-path:800", + "search": "-path:000", "showTags": false, "showAttachments": false, "hideUnresolved": false, @@ -25,6 +25,6 @@ "repelStrength": 10, "linkStrength": 1, "linkDistance": 250, - "scale": 0.6346285676930601, + "scale": 0.9681619554185495, "close": false } \ No newline at end of file diff --git a/.obsidian/plugins/obsidian-shortcuts-for-starred-files/main.js b/.obsidian/plugins/obsidian-shortcuts-for-starred-files/main.js deleted file mode 100644 index 1fa0c5e..0000000 --- a/.obsidian/plugins/obsidian-shortcuts-for-starred-files/main.js +++ /dev/null @@ -1,159 +0,0 @@ -'use strict'; - -var obsidian = require('obsidian'); - -/*! ***************************************************************************** -Copyright (c) Microsoft Corporation. - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. -***************************************************************************** */ -/* global Reflect, Promise */ - -var extendStatics = function(d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; - return extendStatics(d, b); -}; - -function __extends(d, b) { - if (typeof b !== "function" && b !== null) - throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -} - -function __awaiter(thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -} - -function __generator(thisArg, body) { - var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; - return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; - function verb(n) { return function (v) { return step([n, v]); }; } - function step(op) { - if (f) throw new TypeError("Generator is already executing."); - while (_) try { - if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [op[0] & 2, t.value]; - switch (op[0]) { - case 0: case 1: t = op; break; - case 4: _.label++; return { value: op[1], done: false }; - case 5: _.label++; y = op[1]; op = [0]; continue; - case 7: op = _.ops.pop(); _.trys.pop(); continue; - default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } - if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } - if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } - if (t[2]) _.ops.pop(); - _.trys.pop(); continue; - } - op = body.call(thisArg, _); - } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } - if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; - } -} - -var MyPlugin = /** @class */ (function (_super) { - __extends(MyPlugin, _super); - function MyPlugin() { - return _super !== null && _super.apply(this, arguments) || this; - } - MyPlugin.prototype.onload = function () { - var _this = this; - console.log('loading ' + this.manifest.name); - var _loop_1 = function (i) { - this_1.addCommand({ - id: "open-file-" + i, - name: "Open starred file: " + i, - callback: (function () { return _this.open(i - 1, false); }), - }); - }; - var this_1 = this; - for (var i = 1; i <= 9; i++) { - _loop_1(i); - } - var _loop_2 = function (i) { - this_2.addCommand({ - id: "open-file-in-new-pane-" + i, - name: "Open starred file in a new pane: " + i, - callback: (function () { return _this.open(i - 1, true); }), - }); - }; - var this_2 = this; - for (var i = 1; i <= 9; i++) { - _loop_2(i); - } - }; - MyPlugin.prototype.open = function (index, inNewPane) { - return __awaiter(this, void 0, void 0, function () { - var rawItems, items, _i, rawItems_1, item, exists, searchPlugin; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - rawItems = this.app.internalPlugins.plugins.starred.instance.items; - items = []; - _i = 0, rawItems_1 = rawItems; - _a.label = 1; - case 1: - if (!(_i < rawItems_1.length)) return [3 /*break*/, 5]; - item = rawItems_1[_i]; - if (items.length == 9) { - return [3 /*break*/, 5]; - } - if (!(item.type == "file")) return [3 /*break*/, 3]; - return [4 /*yield*/, this.app.vault.adapter.exists(item.path)]; - case 2: - exists = _a.sent(); - if (exists) - items.push(item); - return [3 /*break*/, 4]; - case 3: - items.push(item); - _a.label = 4; - case 4: - _i++; - return [3 /*break*/, 1]; - case 5: - if (items[index]) { - if (items[index].type == "file") { - this.app.workspace.openLinkText(items[index].path, "", inNewPane); - } - else if (items[index].type == "search") { - searchPlugin = this.app.internalPlugins.plugins["global-search"]; - searchPlugin.instance.openGlobalSearch(items[index].query); - } - } - else { - new obsidian.Notice("There is nothing starred at index " + (index + 1)); - } - return [2 /*return*/]; - } - }); - }); - }; - MyPlugin.prototype.onunload = function () { - console.log('unloading ' + this.manifest.name); - }; - return MyPlugin; -}(obsidian.Plugin)); - -module.exports = MyPlugin; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZXMiOlsibm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsIm1haW4udHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyohICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcbkNvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLlxyXG5cclxuUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IgYW55XHJcbnB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZC5cclxuXHJcblRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEhcclxuUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZXHJcbkFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIERJUkVDVCxcclxuSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NXHJcbkxPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SXHJcbk9USEVSIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1JcclxuUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS5cclxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi9cclxuLyogZ2xvYmFsIFJlZmxlY3QsIFByb21pc2UgKi9cclxuXHJcbnZhciBleHRlbmRTdGF0aWNzID0gZnVuY3Rpb24oZCwgYikge1xyXG4gICAgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHRlbmRzKGQsIGIpIHtcclxuICAgIGlmICh0eXBlb2YgYiAhPT0gXCJmdW5jdGlvblwiICYmIGIgIT09IG51bGwpXHJcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNsYXNzIGV4dGVuZHMgdmFsdWUgXCIgKyBTdHJpbmcoYikgKyBcIiBpcyBub3QgYSBjb25zdHJ1Y3RvciBvciBudWxsXCIpO1xyXG4gICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fYXNzaWduID0gZnVuY3Rpb24oKSB7XHJcbiAgICBfX2Fzc2lnbiA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gX19hc3NpZ24odCkge1xyXG4gICAgICAgIGZvciAodmFyIHMsIGkgPSAxLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IG47IGkrKykge1xyXG4gICAgICAgICAgICBzID0gYXJndW1lbnRzW2ldO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkpIHRbcF0gPSBzW3BdO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdDtcclxuICAgIH1cclxuICAgIHJldHVybiBfX2Fzc2lnbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZXN0KHMsIGUpIHtcclxuICAgIHZhciB0ID0ge307XHJcbiAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkgJiYgZS5pbmRleE9mKHApIDwgMClcclxuICAgICAgICB0W3BdID0gc1twXTtcclxuICAgIGlmIChzICE9IG51bGwgJiYgdHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPT09IFwiZnVuY3Rpb25cIilcclxuICAgICAgICBmb3IgKHZhciBpID0gMCwgcCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMocyk7IGkgPCBwLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmIChlLmluZGV4T2YocFtpXSkgPCAwICYmIE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChzLCBwW2ldKSlcclxuICAgICAgICAgICAgICAgIHRbcFtpXV0gPSBzW3BbaV1dO1xyXG4gICAgICAgIH1cclxuICAgIHJldHVybiB0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYykge1xyXG4gICAgdmFyIGMgPSBhcmd1bWVudHMubGVuZ3RoLCByID0gYyA8IDMgPyB0YXJnZXQgOiBkZXNjID09PSBudWxsID8gZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBrZXkpIDogZGVzYywgZDtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5kZWNvcmF0ZSA9PT0gXCJmdW5jdGlvblwiKSByID0gUmVmbGVjdC5kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYyk7XHJcbiAgICBlbHNlIGZvciAodmFyIGkgPSBkZWNvcmF0b3JzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSBpZiAoZCA9IGRlY29yYXRvcnNbaV0pIHIgPSAoYyA8IDMgPyBkKHIpIDogYyA+IDMgPyBkKHRhcmdldCwga2V5LCByKSA6IGQodGFyZ2V0LCBrZXkpKSB8fCByO1xyXG4gICAgcmV0dXJuIGMgPiAzICYmIHIgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCByKSwgcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcGFyYW0ocGFyYW1JbmRleCwgZGVjb3JhdG9yKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwga2V5KSB7IGRlY29yYXRvcih0YXJnZXQsIGtleSwgcGFyYW1JbmRleCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fbWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpIHtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5tZXRhZGF0YSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gUmVmbGVjdC5tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2F3YWl0ZXIodGhpc0FyZywgX2FyZ3VtZW50cywgUCwgZ2VuZXJhdG9yKSB7XHJcbiAgICBmdW5jdGlvbiBhZG9wdCh2YWx1ZSkgeyByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBQID8gdmFsdWUgOiBuZXcgUChmdW5jdGlvbiAocmVzb2x2ZSkgeyByZXNvbHZlKHZhbHVlKTsgfSk7IH1cclxuICAgIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIGZ1bGZpbGxlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvci5uZXh0KHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiByZWplY3RlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvcltcInRocm93XCJdKHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IGFkb3B0KHJlc3VsdC52YWx1ZSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxyXG4gICAgICAgIHN0ZXAoKGdlbmVyYXRvciA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSkubmV4dCgpKTtcclxuICAgIH0pO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19nZW5lcmF0b3IodGhpc0FyZywgYm9keSkge1xyXG4gICAgdmFyIF8gPSB7IGxhYmVsOiAwLCBzZW50OiBmdW5jdGlvbigpIHsgaWYgKHRbMF0gJiAxKSB0aHJvdyB0WzFdOyByZXR1cm4gdFsxXTsgfSwgdHJ5czogW10sIG9wczogW10gfSwgZiwgeSwgdCwgZztcclxuICAgIHJldHVybiBnID0geyBuZXh0OiB2ZXJiKDApLCBcInRocm93XCI6IHZlcmIoMSksIFwicmV0dXJuXCI6IHZlcmIoMikgfSwgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIChnW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXM7IH0pLCBnO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IHJldHVybiBmdW5jdGlvbiAodikgeyByZXR1cm4gc3RlcChbbiwgdl0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzdGVwKG9wKSB7XHJcbiAgICAgICAgaWYgKGYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJHZW5lcmF0b3IgaXMgYWxyZWFkeSBleGVjdXRpbmcuXCIpO1xyXG4gICAgICAgIHdoaWxlIChfKSB0cnkge1xyXG4gICAgICAgICAgICBpZiAoZiA9IDEsIHkgJiYgKHQgPSBvcFswXSAmIDIgPyB5W1wicmV0dXJuXCJdIDogb3BbMF0gPyB5W1widGhyb3dcIl0gfHwgKCh0ID0geVtcInJldHVyblwiXSkgJiYgdC5jYWxsKHkpLCAwKSA6IHkubmV4dCkgJiYgISh0ID0gdC5jYWxsKHksIG9wWzFdKSkuZG9uZSkgcmV0dXJuIHQ7XHJcbiAgICAgICAgICAgIGlmICh5ID0gMCwgdCkgb3AgPSBbb3BbMF0gJiAyLCB0LnZhbHVlXTtcclxuICAgICAgICAgICAgc3dpdGNoIChvcFswXSkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAwOiBjYXNlIDE6IHQgPSBvcDsgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDQ6IF8ubGFiZWwrKzsgcmV0dXJuIHsgdmFsdWU6IG9wWzFdLCBkb25lOiBmYWxzZSB9O1xyXG4gICAgICAgICAgICAgICAgY2FzZSA1OiBfLmxhYmVsKys7IHkgPSBvcFsxXTsgb3AgPSBbMF07IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA3OiBvcCA9IF8ub3BzLnBvcCgpOyBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoISh0ID0gXy50cnlzLCB0ID0gdC5sZW5ndGggPiAwICYmIHRbdC5sZW5ndGggLSAxXSkgJiYgKG9wWzBdID09PSA2IHx8IG9wWzBdID09PSAyKSkgeyBfID0gMDsgY29udGludWU7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDMgJiYgKCF0IHx8IChvcFsxXSA+IHRbMF0gJiYgb3BbMV0gPCB0WzNdKSkpIHsgXy5sYWJlbCA9IG9wWzFdOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gNiAmJiBfLmxhYmVsIDwgdFsxXSkgeyBfLmxhYmVsID0gdFsxXTsgdCA9IG9wOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ICYmIF8ubGFiZWwgPCB0WzJdKSB7IF8ubGFiZWwgPSB0WzJdOyBfLm9wcy5wdXNoKG9wKTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodFsyXSkgXy5vcHMucG9wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBvcCA9IGJvZHkuY2FsbCh0aGlzQXJnLCBfKTtcclxuICAgICAgICB9IGNhdGNoIChlKSB7IG9wID0gWzYsIGVdOyB5ID0gMDsgfSBmaW5hbGx5IHsgZiA9IHQgPSAwOyB9XHJcbiAgICAgICAgaWYgKG9wWzBdICYgNSkgdGhyb3cgb3BbMV07IHJldHVybiB7IHZhbHVlOiBvcFswXSA/IG9wWzFdIDogdm9pZCAwLCBkb25lOiB0cnVlIH07XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCB2YXIgX19jcmVhdGVCaW5kaW5nID0gT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xyXG4gICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9KTtcclxufSkgOiAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcclxuICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XHJcbiAgICBvW2syXSA9IG1ba107XHJcbn0pO1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXhwb3J0U3RhcihtLCBvKSB7XHJcbiAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG8sIHApKSBfX2NyZWF0ZUJpbmRpbmcobywgbSwgcCk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3ZhbHVlcyhvKSB7XHJcbiAgICB2YXIgcyA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBTeW1ib2wuaXRlcmF0b3IsIG0gPSBzICYmIG9bc10sIGkgPSAwO1xyXG4gICAgaWYgKG0pIHJldHVybiBtLmNhbGwobyk7XHJcbiAgICBpZiAobyAmJiB0eXBlb2Ygby5sZW5ndGggPT09IFwibnVtYmVyXCIpIHJldHVybiB7XHJcbiAgICAgICAgbmV4dDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAobyAmJiBpID49IG8ubGVuZ3RoKSBvID0gdm9pZCAwO1xyXG4gICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogbyAmJiBvW2krK10sIGRvbmU6ICFvIH07XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IocyA/IFwiT2JqZWN0IGlzIG5vdCBpdGVyYWJsZS5cIiA6IFwiU3ltYm9sLml0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVhZChvLCBuKSB7XHJcbiAgICB2YXIgbSA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvW1N5bWJvbC5pdGVyYXRvcl07XHJcbiAgICBpZiAoIW0pIHJldHVybiBvO1xyXG4gICAgdmFyIGkgPSBtLmNhbGwobyksIHIsIGFyID0gW10sIGU7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIHdoaWxlICgobiA9PT0gdm9pZCAwIHx8IG4tLSA+IDApICYmICEociA9IGkubmV4dCgpKS5kb25lKSBhci5wdXNoKHIudmFsdWUpO1xyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGVycm9yKSB7IGUgPSB7IGVycm9yOiBlcnJvciB9OyB9XHJcbiAgICBmaW5hbGx5IHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBpZiAociAmJiAhci5kb25lICYmIChtID0gaVtcInJldHVyblwiXSkpIG0uY2FsbChpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZmluYWxseSB7IGlmIChlKSB0aHJvdyBlLmVycm9yOyB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbi8qKiBAZGVwcmVjYXRlZCAqL1xyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWQoKSB7XHJcbiAgICBmb3IgKHZhciBhciA9IFtdLCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKylcclxuICAgICAgICBhciA9IGFyLmNvbmNhdChfX3JlYWQoYXJndW1lbnRzW2ldKSk7XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbi8qKiBAZGVwcmVjYXRlZCAqL1xyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWRBcnJheXMoKSB7XHJcbiAgICBmb3IgKHZhciBzID0gMCwgaSA9IDAsIGlsID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGlsOyBpKyspIHMgKz0gYXJndW1lbnRzW2ldLmxlbmd0aDtcclxuICAgIGZvciAodmFyIHIgPSBBcnJheShzKSwgayA9IDAsIGkgPSAwOyBpIDwgaWw7IGkrKylcclxuICAgICAgICBmb3IgKHZhciBhID0gYXJndW1lbnRzW2ldLCBqID0gMCwgamwgPSBhLmxlbmd0aDsgaiA8IGpsOyBqKyssIGsrKylcclxuICAgICAgICAgICAgcltrXSA9IGFbal07XHJcbiAgICByZXR1cm4gcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkQXJyYXkodG8sIGZyb20pIHtcclxuICAgIGZvciAodmFyIGkgPSAwLCBpbCA9IGZyb20ubGVuZ3RoLCBqID0gdG8ubGVuZ3RoOyBpIDwgaWw7IGkrKywgaisrKVxyXG4gICAgICAgIHRvW2pdID0gZnJvbVtpXTtcclxuICAgIHJldHVybiB0bztcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXQodikge1xyXG4gICAgcmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBfX2F3YWl0ID8gKHRoaXMudiA9IHYsIHRoaXMpIDogbmV3IF9fYXdhaXQodik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jR2VuZXJhdG9yKHRoaXNBcmcsIF9hcmd1bWVudHMsIGdlbmVyYXRvcikge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBnID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pLCBpLCBxID0gW107XHJcbiAgICByZXR1cm4gaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgaWYgKGdbbl0pIGlbbl0gPSBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKGEsIGIpIHsgcS5wdXNoKFtuLCB2LCBhLCBiXSkgPiAxIHx8IHJlc3VtZShuLCB2KTsgfSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHJlc3VtZShuLCB2KSB7IHRyeSB7IHN0ZXAoZ1tuXSh2KSk7IH0gY2F0Y2ggKGUpIHsgc2V0dGxlKHFbMF1bM10sIGUpOyB9IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAocikgeyByLnZhbHVlIGluc3RhbmNlb2YgX19hd2FpdCA/IFByb21pc2UucmVzb2x2ZShyLnZhbHVlLnYpLnRoZW4oZnVsZmlsbCwgcmVqZWN0KSA6IHNldHRsZShxWzBdWzJdLCByKTsgfVxyXG4gICAgZnVuY3Rpb24gZnVsZmlsbCh2YWx1ZSkgeyByZXN1bWUoXCJuZXh0XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gcmVqZWN0KHZhbHVlKSB7IHJlc3VtZShcInRocm93XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKGYsIHYpIHsgaWYgKGYodiksIHEuc2hpZnQoKSwgcS5sZW5ndGgpIHJlc3VtZShxWzBdWzBdLCBxWzBdWzFdKTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0RlbGVnYXRvcihvKSB7XHJcbiAgICB2YXIgaSwgcDtcclxuICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiwgZnVuY3Rpb24gKGUpIHsgdGhyb3cgZTsgfSksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4sIGYpIHsgaVtuXSA9IG9bbl0gPyBmdW5jdGlvbiAodikgeyByZXR1cm4gKHAgPSAhcCkgPyB7IHZhbHVlOiBfX2F3YWl0KG9bbl0odikpLCBkb25lOiBuID09PSBcInJldHVyblwiIH0gOiBmID8gZih2KSA6IHY7IH0gOiBmOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jVmFsdWVzKG8pIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgbSA9IG9bU3ltYm9sLmFzeW5jSXRlcmF0b3JdLCBpO1xyXG4gICAgcmV0dXJuIG0gPyBtLmNhbGwobykgOiAobyA9IHR5cGVvZiBfX3ZhbHVlcyA9PT0gXCJmdW5jdGlvblwiID8gX192YWx1ZXMobykgOiBvW1N5bWJvbC5pdGVyYXRvcl0oKSwgaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGkpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IGlbbl0gPSBvW25dICYmIGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7IHYgPSBvW25dKHYpLCBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCB2LmRvbmUsIHYudmFsdWUpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgZCwgdikgeyBQcm9taXNlLnJlc29sdmUodikudGhlbihmdW5jdGlvbih2KSB7IHJlc29sdmUoeyB2YWx1ZTogdiwgZG9uZTogZCB9KTsgfSwgcmVqZWN0KTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tYWtlVGVtcGxhdGVPYmplY3QoY29va2VkLCByYXcpIHtcclxuICAgIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvb2tlZCwgXCJyYXdcIiwgeyB2YWx1ZTogcmF3IH0pOyB9IGVsc2UgeyBjb29rZWQucmF3ID0gcmF3OyB9XHJcbiAgICByZXR1cm4gY29va2VkO1xyXG59O1xyXG5cclxudmFyIF9fc2V0TW9kdWxlRGVmYXVsdCA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgdikge1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIFwiZGVmYXVsdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2IH0pO1xyXG59KSA6IGZ1bmN0aW9uKG8sIHYpIHtcclxuICAgIG9bXCJkZWZhdWx0XCJdID0gdjtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydFN0YXIobW9kKSB7XHJcbiAgICBpZiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSByZXR1cm4gbW9kO1xyXG4gICAgdmFyIHJlc3VsdCA9IHt9O1xyXG4gICAgaWYgKG1vZCAhPSBudWxsKSBmb3IgKHZhciBrIGluIG1vZCkgaWYgKGsgIT09IFwiZGVmYXVsdFwiICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChtb2QsIGspKSBfX2NyZWF0ZUJpbmRpbmcocmVzdWx0LCBtb2QsIGspO1xyXG4gICAgX19zZXRNb2R1bGVEZWZhdWx0KHJlc3VsdCwgbW9kKTtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydERlZmF1bHQobW9kKSB7XHJcbiAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IGRlZmF1bHQ6IG1vZCB9O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZEdldChyZWNlaXZlciwgcHJpdmF0ZU1hcCkge1xyXG4gICAgaWYgKCFwcml2YXRlTWFwLmhhcyhyZWNlaXZlcikpIHtcclxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYXR0ZW1wdGVkIHRvIGdldCBwcml2YXRlIGZpZWxkIG9uIG5vbi1pbnN0YW5jZVwiKTtcclxuICAgIH1cclxuICAgIHJldHVybiBwcml2YXRlTWFwLmdldChyZWNlaXZlcik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KHJlY2VpdmVyLCBwcml2YXRlTWFwLCB2YWx1ZSkge1xyXG4gICAgaWYgKCFwcml2YXRlTWFwLmhhcyhyZWNlaXZlcikpIHtcclxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiYXR0ZW1wdGVkIHRvIHNldCBwcml2YXRlIGZpZWxkIG9uIG5vbi1pbnN0YW5jZVwiKTtcclxuICAgIH1cclxuICAgIHByaXZhdGVNYXAuc2V0KHJlY2VpdmVyLCB2YWx1ZSk7XHJcbiAgICByZXR1cm4gdmFsdWU7XHJcbn1cclxuIiwiaW1wb3J0IHsgTm90aWNlLCBQbHVnaW4gfSBmcm9tICdvYnNpZGlhbic7XG5pbnRlcmZhY2UgSXRlbSB7XG5cdHR5cGU6IFwiZmlsZVwiIHwgXCJzZWFyY2hcIjtcblx0dGl0bGU6IHN0cmluZyxcblx0cGF0aD86IHN0cmluZyxcblx0cXVlcnk/OiBzdHJpbmcsXG59XG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNeVBsdWdpbiBleHRlbmRzIFBsdWdpbiB7XG5cdG9ubG9hZCgpIHtcblx0XHRjb25zb2xlLmxvZygnbG9hZGluZyAnICsgdGhpcy5tYW5pZmVzdC5uYW1lKTtcblx0XHRmb3IgKGxldCBpID0gMTsgaSA8PSA5OyBpKyspIHtcblx0XHRcdHRoaXMuYWRkQ29tbWFuZCh7XG5cdFx0XHRcdGlkOiBgb3Blbi1maWxlLSR7aX1gLFxuXHRcdFx0XHRuYW1lOiBgT3BlbiBzdGFycmVkIGZpbGU6ICR7aX1gLFxuXHRcdFx0XHRjYWxsYmFjazogKCgpID0+IHRoaXMub3BlbihpIC0gMSwgZmFsc2UpKSxcblx0XHRcdH0pO1xuXHRcdH1cblx0XHRmb3IgKGxldCBpID0gMTsgaSA8PSA5OyBpKyspIHtcblx0XHRcdHRoaXMuYWRkQ29tbWFuZCh7XG5cdFx0XHRcdGlkOiBgb3Blbi1maWxlLWluLW5ldy1wYW5lLSR7aX1gLFxuXHRcdFx0XHRuYW1lOiBgT3BlbiBzdGFycmVkIGZpbGUgaW4gYSBuZXcgcGFuZTogJHtpfWAsXG5cdFx0XHRcdGNhbGxiYWNrOiAoKCkgPT4gdGhpcy5vcGVuKGkgLSAxLCB0cnVlKSksXG5cdFx0XHR9KTtcblx0XHR9XG5cdH1cblx0YXN5bmMgb3BlbihpbmRleDogbnVtYmVyLCBpbk5ld1BhbmU6IGJvb2xlYW4pIHtcblx0XHRjb25zdCByYXdJdGVtcyA9IHRoaXMuYXBwLmludGVybmFsUGx1Z2lucy5wbHVnaW5zLnN0YXJyZWQuaW5zdGFuY2UuaXRlbXMgYXMgSXRlbVtdO1xuXHRcdGxldCBpdGVtczogSXRlbVtdID0gW107XG5cblx0XHRmb3IgKGxldCBpdGVtIG9mIHJhd0l0ZW1zKSB7XG5cdFx0XHRpZiAoaXRlbXMubGVuZ3RoID09IDkpIHtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0XHRpZiAoaXRlbS50eXBlID09IFwiZmlsZVwiKSB7XG5cdFx0XHRcdGNvbnN0IGV4aXN0cyA9IGF3YWl0IHRoaXMuYXBwLnZhdWx0LmFkYXB0ZXIuZXhpc3RzKGl0ZW0ucGF0aCk7XG5cdFx0XHRcdGlmIChleGlzdHMpIGl0ZW1zLnB1c2goaXRlbSk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRpdGVtcy5wdXNoKGl0ZW0pO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmIChpdGVtc1tpbmRleF0pIHtcblx0XHRcdGlmIChpdGVtc1tpbmRleF0udHlwZSA9PSBcImZpbGVcIikge1xuXHRcdFx0XHR0aGlzLmFwcC53b3Jrc3BhY2Uub3BlbkxpbmtUZXh0KGl0ZW1zW2luZGV4XS5wYXRoLCBcIlwiLCBpbk5ld1BhbmUpO1xuXHRcdFx0fSBlbHNlIGlmIChpdGVtc1tpbmRleF0udHlwZSA9PSBcInNlYXJjaFwiKSB7XG5cdFx0XHRcdGNvbnN0IHNlYXJjaFBsdWdpbiA9IHRoaXMuYXBwLmludGVybmFsUGx1Z2lucy5wbHVnaW5zW1wiZ2xvYmFsLXNlYXJjaFwiXTtcblx0XHRcdFx0c2VhcmNoUGx1Z2luLmluc3RhbmNlLm9wZW5HbG9iYWxTZWFyY2goaXRlbXNbaW5kZXhdLnF1ZXJ5KTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0bmV3IE5vdGljZShgVGhlcmUgaXMgbm90aGluZyBzdGFycmVkIGF0IGluZGV4ICR7aW5kZXggKyAxfWApO1xuXHRcdH1cblx0fVxuXHRvbnVubG9hZCgpIHtcblx0XHRjb25zb2xlLmxvZygndW5sb2FkaW5nICcgKyB0aGlzLm1hbmlmZXN0Lm5hbWUpO1xuXHR9XG59Il0sIm5hbWVzIjpbIk5vdGljZSIsIlBsdWdpbiJdLCJtYXBwaW5ncyI6Ijs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxhQUFhLEdBQUcsU0FBUyxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ25DLElBQUksYUFBYSxHQUFHLE1BQU0sQ0FBQyxjQUFjO0FBQ3pDLFNBQVMsRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFLFlBQVksS0FBSyxJQUFJLFVBQVUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQztBQUNwRixRQUFRLFVBQVUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksTUFBTSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztBQUMxRyxJQUFJLE9BQU8sYUFBYSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUMvQixDQUFDLENBQUM7QUFDRjtBQUNPLFNBQVMsU0FBUyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDaEMsSUFBSSxJQUFJLE9BQU8sQ0FBQyxLQUFLLFVBQVUsSUFBSSxDQUFDLEtBQUssSUFBSTtBQUM3QyxRQUFRLE1BQU0sSUFBSSxTQUFTLENBQUMsc0JBQXNCLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLCtCQUErQixDQUFDLENBQUM7QUFDbEcsSUFBSSxhQUFhLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ3hCLElBQUksU0FBUyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQyxFQUFFO0FBQzNDLElBQUksQ0FBQyxDQUFDLFNBQVMsR0FBRyxDQUFDLEtBQUssSUFBSSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztBQUN6RixDQUFDO0FBdUNEO0FBQ08sU0FBUyxTQUFTLENBQUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxDQUFDLEVBQUUsU0FBUyxFQUFFO0FBQzdELElBQUksU0FBUyxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsT0FBTyxLQUFLLFlBQVksQ0FBQyxHQUFHLEtBQUssR0FBRyxJQUFJLENBQUMsQ0FBQyxVQUFVLE9BQU8sRUFBRSxFQUFFLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFO0FBQ2hILElBQUksT0FBTyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsT0FBTyxDQUFDLEVBQUUsVUFBVSxPQUFPLEVBQUUsTUFBTSxFQUFFO0FBQy9ELFFBQVEsU0FBUyxTQUFTLENBQUMsS0FBSyxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtBQUNuRyxRQUFRLFNBQVMsUUFBUSxDQUFDLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtBQUN0RyxRQUFRLFNBQVMsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLE1BQU0sQ0FBQyxJQUFJLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsUUFBUSxDQUFDLENBQUMsRUFBRTtBQUN0SCxRQUFRLElBQUksQ0FBQyxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxVQUFVLElBQUksRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztBQUM5RSxLQUFLLENBQUMsQ0FBQztBQUNQLENBQUM7QUFDRDtBQUNPLFNBQVMsV0FBVyxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUU7QUFDM0MsSUFBSSxJQUFJLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3JILElBQUksT0FBTyxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLE9BQU8sTUFBTSxLQUFLLFVBQVUsS0FBSyxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxHQUFHLFdBQVcsRUFBRSxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDN0osSUFBSSxTQUFTLElBQUksQ0FBQyxDQUFDLEVBQUUsRUFBRSxPQUFPLFVBQVUsQ0FBQyxFQUFFLEVBQUUsT0FBTyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUN0RSxJQUFJLFNBQVMsSUFBSSxDQUFDLEVBQUUsRUFBRTtBQUN0QixRQUFRLElBQUksQ0FBQyxFQUFFLE1BQU0sSUFBSSxTQUFTLENBQUMsaUNBQWlDLENBQUMsQ0FBQztBQUN0RSxRQUFRLE9BQU8sQ0FBQyxFQUFFLElBQUk7QUFDdEIsWUFBWSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztBQUN6SyxZQUFZLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDcEQsWUFBWSxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDekIsZ0JBQWdCLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLE1BQU07QUFDOUMsZ0JBQWdCLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsQ0FBQztBQUN4RSxnQkFBZ0IsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUztBQUNqRSxnQkFBZ0IsS0FBSyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsU0FBUztBQUNqRSxnQkFBZ0I7QUFDaEIsb0JBQW9CLElBQUksRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxTQUFTLEVBQUU7QUFDaEksb0JBQW9CLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUU7QUFDMUcsb0JBQW9CLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFD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 diff --git a/.obsidian/plugins/obsidian-shortcuts-for-starred-files/manifest.json b/.obsidian/plugins/obsidian-shortcuts-for-starred-files/manifest.json deleted file mode 100644 index 9494b48..0000000 --- a/.obsidian/plugins/obsidian-shortcuts-for-starred-files/manifest.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "id": "obsidian-shortcuts-for-starred-files", - "name": "Hotkeys for starred files and searches", - "version": "0.0.4", - "description": "Set an individual hotkey for the first 9 starred files and searches and open them just with your keyboard.", - "author": "Vinzent", - "authorUrl": "https://github.com/Vinzent03", - "isDesktopOnly": false -} \ No newline at end of file diff --git a/.obsidian/plugins/obsidian-sort-and-permute-lines/main.js b/.obsidian/plugins/obsidian-sort-and-permute-lines/main.js deleted file mode 100644 index 0dc4913..0000000 --- a/.obsidian/plugins/obsidian-sort-and-permute-lines/main.js +++ /dev/null @@ -1,237 +0,0 @@ -'use strict'; - -var obsidian = require('obsidian'); - -/*! ***************************************************************************** -Copyright (c) Microsoft Corporation. - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. -***************************************************************************** */ -/* global Reflect, Promise */ - -var extendStatics = function(d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; - return extendStatics(d, b); -}; - -function __extends(d, b) { - if (typeof b !== "function" && b !== null) - throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -} - -function __awaiter(thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -} - -function __generator(thisArg, body) { - var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; - return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; - function verb(n) { return function (v) { return step([n, v]); }; } - function step(op) { - if (f) throw new TypeError("Generator is already executing."); - while (_) try { - if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [op[0] & 2, t.value]; - switch (op[0]) { - case 0: case 1: t = op; break; - case 4: _.label++; return { value: op[1], done: false }; - case 5: _.label++; y = op[1]; op = [0]; continue; - case 7: op = _.ops.pop(); _.trys.pop(); continue; - default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } - if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } - if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } - if (t[2]) _.ops.pop(); - _.trys.pop(); continue; - } - op = body.call(thisArg, _); - } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } - if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; - } -} - -/** @deprecated */ -function __spreadArrays() { - for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; - for (var r = Array(s), k = 0, i = 0; i < il; i++) - for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) - r[k] = a[j]; - return r; -} - -var MyPlugin = /** @class */ (function (_super) { - __extends(MyPlugin, _super); - function MyPlugin() { - return _super !== null && _super.apply(this, arguments) || this; - } - MyPlugin.prototype.onload = function () { - return __awaiter(this, void 0, void 0, function () { - var compare; - var _this = this; - return __generator(this, function (_a) { - console.log('loading ' + this.manifest.name); - compare = new Intl.Collator(undefined, { - usage: 'sort', - sensitivity: 'base', - numeric: true, - ignorePunctuation: true, - }).compare; - this.compare = compare; - this.addCommand({ - id: 'sort-alphabetically', - name: 'Sort alphabetically', - callback: (function () { return _this.sortAlphabetically(); }), - }); - this.addCommand({ - id: 'sort-length', - name: 'Sort by length of line', - callback: (function () { return _this.sortLengthOfLine(); }), - }); - this.addCommand({ - id: 'permute-reverse', - name: 'Reverse lines', - callback: (function () { return _this.permuteReverse(); }), - }); - this.addCommand({ - id: 'permute-shuffle', - name: 'Shuffle lines', - callback: (function () { return _this.permuteShuffle(); }), - }); - return [2 /*return*/]; - }); - }); - }; - MyPlugin.prototype.onunload = function () { - console.log('unloading ' + this.manifest.name); - }; - MyPlugin.prototype.sortAlphabetically = function () { - var _this = this; - var lines = this.getLines(); - if (lines.length === 0) - return; - var sortFunc = function (a, b) { return _this.compare(a.formatted.trim(), b.formatted.trim()); }; - lines.sort(sortFunc); - this.setLines(lines); - }; - MyPlugin.prototype.sortLengthOfLine = function () { - var lines = this.getLines(); - if (lines.length === 0) - return; - lines.sort(function (a, b) { return a.formatted.length - b.formatted.length; }); - this.setLines(lines); - }; - MyPlugin.prototype.permuteReverse = function () { - var lines = this.getLines(); - if (lines.length === 0) - return; - lines.reverse(); - this.setLines(lines); - }; - MyPlugin.prototype.permuteShuffle = function () { - var lines = this.getLines(); - if (lines.length === 0) - return; - lines.shuffle(); - this.setLines(lines); - }; - MyPlugin.prototype.getLines = function () { - var _a, _b; - var view = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView); - if (!view) - return; - var editor = view.editor; - var file = view.file; - var lines = editor.getValue().split("\n"); - var start = editor.getCursor("from").line; - var end = editor.getCursor("to").line; - var cache = this.app.metadataCache.getFileCache(file); - var links = __spreadArrays((_a = cache === null || cache === void 0 ? void 0 : cache.links) !== null && _a !== void 0 ? _a : [], (_b = cache === null || cache === void 0 ? void 0 : cache.embeds) !== null && _b !== void 0 ? _b : []); - var myLines = lines.map(function (line, index) { - var myLine = { source: line, formatted: line }; - links.forEach(function (e) { - if (e.position.start.line != index) - return; - var start = e.position.start; - var end = e.position.end; - myLine.formatted = myLine.formatted.replace(line.substring(start.col, end.col), e.displayText); - }); - if (myLine.formatted.startsWith("- [x]")) { - myLine.formatted = myLine.formatted.substring(6); - } - return myLine; - }); - if (start != end) { - return myLines.slice(start, end + 1); - } - else if (cache.frontmatter) { - return myLines.slice(cache.frontmatter.position.end.line + 1); - } - else { - return myLines; - } - }; - MyPlugin.prototype.setLines = function (lines) { - var view = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView); - var res = this.getPosition(view); - var editor = view.editor; - if (res.start != res.end) { - editor.replaceRange(lines.map(function (e) { return e.source; }).join("\n"), { line: res.start, ch: 0 }, { line: res.end, ch: res.endLineLength }); - } - else { - editor.setValue(lines.map(function (e) { return e.source; }).join("\n")); - } - }; - MyPlugin.prototype.getPosition = function (view) { - var _a, _b, _c; - var cache = this.app.metadataCache.getFileCache(view.file); - var editor = view.editor; - var cursorStart = editor.getCursor("from").line; - var cursorEnd = editor.getCursor("to").line; - var curserEndLineLength = editor.getLine(cursorEnd).length; - var frontStart = ((_c = (_b = (_a = cache.frontmatter) === null || _a === void 0 ? void 0 : _a.position) === null || _b === void 0 ? void 0 : _b.end) === null || _c === void 0 ? void 0 : _c.line) + 1; - if (isNaN(frontStart)) { - frontStart = 0; - } - var frontEnd = editor.lastLine(); - var frontEndLineLength = editor.getLine(frontEnd).length; - if (cursorStart != cursorEnd) { - return { - start: cursorStart, - end: cursorEnd, - endLineLength: curserEndLineLength, - }; - } - else { - return { - start: frontStart, - end: frontEnd, - endLineLength: frontEndLineLength, - }; - } - }; - return MyPlugin; -}(obsidian.Plugin)); - -module.exports = MyPlugin; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZXMiOlsibm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsIm1haW4udHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyohICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcbkNvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLlxyXG5cclxuUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IgYW55XHJcbnB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZC5cclxuXHJcblRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEhcclxuUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZXHJcbkFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIERJUkVDVCxcclxuSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NXHJcbkxPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SXHJcbk9USEVSIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1JcclxuUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS5cclxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi9cclxuLyogZ2xvYmFsIFJlZmxlY3QsIFByb21pc2UgKi9cclxuXHJcbnZhciBleHRlbmRTdGF0aWNzID0gZnVuY3Rpb24oZCwgYikge1xyXG4gICAgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHRlbmRzKGQsIGIpIHtcclxuICAgIGlmICh0eXBlb2YgYiAhPT0gXCJmdW5jdGlvblwiICYmIGIgIT09IG51bGwpXHJcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNsYXNzIGV4dGVuZHMgdmFsdWUgXCIgKyBTdHJpbmcoYikgKyBcIiBpcyBub3QgYSBjb25zdHJ1Y3RvciBvciBudWxsXCIpO1xyXG4gICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fYXNzaWduID0gZnVuY3Rpb24oKSB7XHJcbiAgICBfX2Fzc2lnbiA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gX19hc3NpZ24odCkge1xyXG4gICAgICAgIGZvciAodmFyIHMsIGkgPSAxLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IG47IGkrKykge1xyXG4gICAgICAgICAgICBzID0gYXJndW1lbnRzW2ldO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkpIHRbcF0gPSBzW3BdO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdDtcclxuICAgIH1cclxuICAgIHJldHVybiBfX2Fzc2lnbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZXN0KHMsIGUpIHtcclxuICAgIHZhciB0ID0ge307XHJcbiAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkgJiYgZS5pbmRleE9mKHApIDwgMClcclxuICAgICAgICB0W3BdID0gc1twXTtcclxuICAgIGlmIChzICE9IG51bGwgJiYgdHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPT09IFwiZnVuY3Rpb25cIilcclxuICAgICAgICBmb3IgKHZhciBpID0gMCwgcCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMocyk7IGkgPCBwLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmIChlLmluZGV4T2YocFtpXSkgPCAwICYmIE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChzLCBwW2ldKSlcclxuICAgICAgICAgICAgICAgIHRbcFtpXV0gPSBzW3BbaV1dO1xyXG4gICAgICAgIH1cclxuICAgIHJldHVybiB0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYykge1xyXG4gICAgdmFyIGMgPSBhcmd1bWVudHMubGVuZ3RoLCByID0gYyA8IDMgPyB0YXJnZXQgOiBkZXNjID09PSBudWxsID8gZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBrZXkpIDogZGVzYywgZDtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5kZWNvcmF0ZSA9PT0gXCJmdW5jdGlvblwiKSByID0gUmVmbGVjdC5kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYyk7XHJcbiAgICBlbHNlIGZvciAodmFyIGkgPSBkZWNvcmF0b3JzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSBpZiAoZCA9IGRlY29yYXRvcnNbaV0pIHIgPSAoYyA8IDMgPyBkKHIpIDogYyA+IDMgPyBkKHRhcmdldCwga2V5LCByKSA6IGQodGFyZ2V0LCBrZXkpKSB8fCByO1xyXG4gICAgcmV0dXJuIGMgPiAzICYmIHIgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCByKSwgcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcGFyYW0ocGFyYW1JbmRleCwgZGVjb3JhdG9yKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwga2V5KSB7IGRlY29yYXRvcih0YXJnZXQsIGtleSwgcGFyYW1JbmRleCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fbWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpIHtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5tZXRhZGF0YSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gUmVmbGVjdC5tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2F3YWl0ZXIodGhpc0FyZywgX2FyZ3VtZW50cywgUCwgZ2VuZXJhdG9yKSB7XHJcbiAgICBmdW5jdGlvbiBhZG9wdCh2YWx1ZSkgeyByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBQID8gdmFsdWUgOiBuZXcgUChmdW5jdGlvbiAocmVzb2x2ZSkgeyByZXNvbHZlKHZhbHVlKTsgfSk7IH1cclxuICAgIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIGZ1bGZpbGxlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvci5uZXh0KHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiByZWplY3RlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvcltcInRocm93XCJdKHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IGFkb3B0KHJlc3VsdC52YWx1ZSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxyXG4gICAgICAgIHN0ZXAoKGdlbmVyYXRvciA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSkubmV4dCgpKTtcclxuICAgIH0pO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19nZW5lcmF0b3IodGhpc0FyZywgYm9keSkge1xyXG4gICAgdmFyIF8gPSB7IGxhYmVsOiAwLCBzZW50OiBmdW5jdGlvbigpIHsgaWYgKHRbMF0gJiAxKSB0aHJvdyB0WzFdOyByZXR1cm4gdFsxXTsgfSwgdHJ5czogW10sIG9wczogW10gfSwgZiwgeSwgdCwgZztcclxuICAgIHJldHVybiBnID0geyBuZXh0OiB2ZXJiKDApLCBcInRocm93XCI6IHZlcmIoMSksIFwicmV0dXJuXCI6IHZlcmIoMikgfSwgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIChnW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXM7IH0pLCBnO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IHJldHVybiBmdW5jdGlvbiAodikgeyByZXR1cm4gc3RlcChbbiwgdl0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzdGVwKG9wKSB7XHJcbiAgICAgICAgaWYgKGYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJHZW5lcmF0b3IgaXMgYWxyZWFkeSBleGVjdXRpbmcuXCIpO1xyXG4gICAgICAgIHdoaWxlIChfKSB0cnkge1xyXG4gICAgICAgICAgICBpZiAoZiA9IDEsIHkgJiYgKHQgPSBvcFswXSAmIDIgPyB5W1wicmV0dXJuXCJdIDogb3BbMF0gPyB5W1widGhyb3dcIl0gfHwgKCh0ID0geVtcInJldHVyblwiXSkgJiYgdC5jYWxsKHkpLCAwKSA6IHkubmV4dCkgJiYgISh0ID0gdC5jYWxsKHksIG9wWzFdKSkuZG9uZSkgcmV0dXJuIHQ7XHJcbiAgICAgICAgICAgIGlmICh5ID0gMCwgdCkgb3AgPSBbb3BbMF0gJiAyLCB0LnZhbHVlXTtcclxuICAgICAgICAgICAgc3dpdGNoIChvcFswXSkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAwOiBjYXNlIDE6IHQgPSBvcDsgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDQ6IF8ubGFiZWwrKzsgcmV0dXJuIHsgdmFsdWU6IG9wWzFdLCBkb25lOiBmYWxzZSB9O1xyXG4gICAgICAgICAgICAgICAgY2FzZSA1OiBfLmxhYmVsKys7IHkgPSBvcFsxXTsgb3AgPSBbMF07IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA3OiBvcCA9IF8ub3BzLnBvcCgpOyBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoISh0ID0gXy50cnlzLCB0ID0gdC5sZW5ndGggPiAwICYmIHRbdC5sZW5ndGggLSAxXSkgJiYgKG9wWzBdID09PSA2IHx8IG9wWzBdID09PSAyKSkgeyBfID0gMDsgY29udGludWU7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDMgJiYgKCF0IHx8IChvcFsxXSA+IHRbMF0gJiYgb3BbMV0gPCB0WzNdKSkpIHsgXy5sYWJlbCA9IG9wWzFdOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gNiAmJiBfLmxhYmVsIDwgdFsxXSkgeyBfLmxhYmVsID0gdFsxXTsgdCA9IG9wOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ICYmIF8ubGFiZWwgPCB0WzJdKSB7IF8ubGFiZWwgPSB0WzJdOyBfLm9wcy5wdXNoKG9wKTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodFsyXSkgXy5vcHMucG9wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBvcCA9IGJvZHkuY2FsbCh0aGlzQXJnLCBfKTtcclxuICAgICAgICB9IGNhdGNoIChlKSB7IG9wID0gWzYsIGVdOyB5ID0gMDsgfSBmaW5hbGx5IHsgZiA9IHQgPSAwOyB9XHJcbiAgICAgICAgaWYgKG9wWzBdICYgNSkgdGhyb3cgb3BbMV07IHJldHVybiB7IHZhbHVlOiBvcFswXSA/IG9wWzFdIDogdm9pZCAwLCBkb25lOiB0cnVlIH07XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCB2YXIgX19jcmVhdGVCaW5kaW5nID0gT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xyXG4gICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9KTtcclxufSkgOiAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcclxuICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XHJcbiAgICBvW2syXSA9IG1ba107XHJcbn0pO1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXhwb3J0U3RhcihtLCBvKSB7XHJcbiAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG8sIHApKSBfX2NyZWF0ZUJpbmRpbmcobywgbSwgcCk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3ZhbHVlcyhvKSB7XHJcbiAgICB2YXIgcyA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBTeW1ib2wuaXRlcmF0b3IsIG0gPSBzICYmIG9bc10sIGkgPSAwO1xyXG4gICAgaWYgKG0pIHJldHVybiBtLmNhbGwobyk7XHJcbiAgICBpZiAobyAmJiB0eXBlb2Ygby5sZW5ndGggPT09IFwibnVtYmVyXCIpIHJldHVybiB7XHJcbiAgICAgICAgbmV4dDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAobyAmJiBpID49IG8ubGVuZ3RoKSBvID0gdm9pZCAwO1xyXG4gICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogbyAmJiBvW2krK10sIGRvbmU6ICFvIH07XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IocyA/IFwiT2JqZWN0IGlzIG5vdCBpdGVyYWJsZS5cIiA6IFwiU3ltYm9sLml0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVhZChvLCBuKSB7XHJcbiAgICB2YXIgbSA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvW1N5bWJvbC5pdGVyYXRvcl07XHJcbiAgICBpZiAoIW0pIHJldHVybiBvO1xyXG4gICAgdmFyIGkgPSBtLmNhbGwobyksIHIsIGFyID0gW10sIGU7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIHdoaWxlICgobiA9PT0gdm9pZCAwIHx8IG4tLSA+IDApICYmICEociA9IGkubmV4dCgpKS5kb25lKSBhci5wdXNoKHIudmFsdWUpO1xyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGVycm9yKSB7IGUgPSB7IGVycm9yOiBlcnJvciB9OyB9XHJcbiAgICBmaW5hbGx5IHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBpZiAociAmJiAhci5kb25lICYmIChtID0gaVtcInJldHVyblwiXSkpIG0uY2FsbChpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZmluYWxseSB7IGlmIChlKSB0aHJvdyBlLmVycm9yOyB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbi8qKiBAZGVwcmVjYXRlZCAqL1xyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWQoKSB7XHJcbiAgICBmb3IgKHZhciBhciA9IFtdLCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKylcclxuICAgICAgICBhciA9IGFyLmNvbmNhdChfX3JlYWQoYXJndW1lbnRzW2ldKSk7XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbi8qKiBAZGVwcmVjYXRlZCAqL1xyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWRBcnJheXMoKSB7XHJcbiAgICBmb3IgKHZhciBzID0gMCwgaSA9IDAsIGlsID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGlsOyBpKyspIHMgKz0gYXJndW1lbnRzW2ldLmxlbmd0aDtcclxuICAgIGZvciAodmFyIHIgPSBBcnJheShzKSwgayA9IDAsIGkgPSAwOyBpIDwgaWw7IGkrKylcclxuICAgICAgICBmb3IgKHZhciBhID0gYXJndW1lbnRzW2ldLCBqID0gMCwgamwgPSBhLmxlbmd0aDsgaiA8IGpsOyBqKyssIGsrKylcclxuICAgICAgICAgICAgcltrXSA9IGFbal07XHJcbiAgICByZXR1cm4gcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkQXJyYXkodG8sIGZyb20sIHBhY2spIHtcclxuICAgIGlmIChwYWNrIHx8IGFyZ3VtZW50cy5sZW5ndGggPT09IDIpIGZvciAodmFyIGkgPSAwLCBsID0gZnJvbS5sZW5ndGgsIGFyOyBpIDwgbDsgaSsrKSB7XHJcbiAgICAgICAgaWYgKGFyIHx8ICEoaSBpbiBmcm9tKSkge1xyXG4gICAgICAgICAgICBpZiAoIWFyKSBhciA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGZyb20sIDAsIGkpO1xyXG4gICAgICAgICAgICBhcltpXSA9IGZyb21baV07XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRvLmNvbmNhdChhciB8fCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChmcm9tKSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2F3YWl0KHYpIHtcclxuICAgIHJldHVybiB0aGlzIGluc3RhbmNlb2YgX19hd2FpdCA/ICh0aGlzLnYgPSB2LCB0aGlzKSA6IG5ldyBfX2F3YWl0KHYpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0dlbmVyYXRvcih0aGlzQXJnLCBfYXJndW1lbnRzLCBnZW5lcmF0b3IpIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgZyA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSwgaSwgcSA9IFtdO1xyXG4gICAgcmV0dXJuIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IGlmIChnW25dKSBpW25dID0gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChhLCBiKSB7IHEucHVzaChbbiwgdiwgYSwgYl0pID4gMSB8fCByZXN1bWUobiwgdik7IH0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiByZXN1bWUobiwgdikgeyB0cnkgeyBzdGVwKGdbbl0odikpOyB9IGNhdGNoIChlKSB7IHNldHRsZShxWzBdWzNdLCBlKTsgfSB9XHJcbiAgICBmdW5jdGlvbiBzdGVwKHIpIHsgci52YWx1ZSBpbnN0YW5jZW9mIF9fYXdhaXQgPyBQcm9taXNlLnJlc29sdmUoci52YWx1ZS52KS50aGVuKGZ1bGZpbGwsIHJlamVjdCkgOiBzZXR0bGUocVswXVsyXSwgcik7IH1cclxuICAgIGZ1bmN0aW9uIGZ1bGZpbGwodmFsdWUpIHsgcmVzdW1lKFwibmV4dFwiLCB2YWx1ZSk7IH1cclxuICAgIGZ1bmN0aW9uIHJlamVjdCh2YWx1ZSkgeyByZXN1bWUoXCJ0aHJvd1wiLCB2YWx1ZSk7IH1cclxuICAgIGZ1bmN0aW9uIHNldHRsZShmLCB2KSB7IGlmIChmKHYpLCBxLnNoaWZ0KCksIHEubGVuZ3RoKSByZXN1bWUocVswXVswXSwgcVswXVsxXSk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXN5bmNEZWxlZ2F0b3Iobykge1xyXG4gICAgdmFyIGksIHA7XHJcbiAgICByZXR1cm4gaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIsIGZ1bmN0aW9uIChlKSB7IHRocm93IGU7IH0pLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuLCBmKSB7IGlbbl0gPSBvW25dID8gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIChwID0gIXApID8geyB2YWx1ZTogX19hd2FpdChvW25dKHYpKSwgZG9uZTogbiA9PT0gXCJyZXR1cm5cIiB9IDogZiA/IGYodikgOiB2OyB9IDogZjsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY1ZhbHVlcyhvKSB7XHJcbiAgICBpZiAoIVN5bWJvbC5hc3luY0l0ZXJhdG9yKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiU3ltYm9sLmFzeW5jSXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgdmFyIG0gPSBvW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSwgaTtcclxuICAgIHJldHVybiBtID8gbS5jYWxsKG8pIDogKG8gPSB0eXBlb2YgX192YWx1ZXMgPT09IFwiZnVuY3Rpb25cIiA/IF9fdmFsdWVzKG8pIDogb1tTeW1ib2wuaXRlcmF0b3JdKCksIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiKSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpKTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobikgeyBpW25dID0gb1tuXSAmJiBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkgeyB2ID0gb1tuXSh2KSwgc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgdi5kb25lLCB2LnZhbHVlKTsgfSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHNldHRsZShyZXNvbHZlLCByZWplY3QsIGQsIHYpIHsgUHJvbWlzZS5yZXNvbHZlKHYpLnRoZW4oZnVuY3Rpb24odikgeyByZXNvbHZlKHsgdmFsdWU6IHYsIGRvbmU6IGQgfSk7IH0sIHJlamVjdCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fbWFrZVRlbXBsYXRlT2JqZWN0KGNvb2tlZCwgcmF3KSB7XHJcbiAgICBpZiAoT2JqZWN0LmRlZmluZVByb3BlcnR5KSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb29rZWQsIFwicmF3XCIsIHsgdmFsdWU6IHJhdyB9KTsgfSBlbHNlIHsgY29va2VkLnJhdyA9IHJhdzsgfVxyXG4gICAgcmV0dXJuIGNvb2tlZDtcclxufTtcclxuXHJcbnZhciBfX3NldE1vZHVsZURlZmF1bHQgPSBPYmplY3QuY3JlYXRlID8gKGZ1bmN0aW9uKG8sIHYpIHtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBcImRlZmF1bHRcIiwgeyBlbnVtZXJhYmxlOiB0cnVlLCB2YWx1ZTogdiB9KTtcclxufSkgOiBmdW5jdGlvbihvLCB2KSB7XHJcbiAgICBvW1wiZGVmYXVsdFwiXSA9IHY7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19pbXBvcnRTdGFyKG1vZCkge1xyXG4gICAgaWYgKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgcmV0dXJuIG1vZDtcclxuICAgIHZhciByZXN1bHQgPSB7fTtcclxuICAgIGlmIChtb2QgIT0gbnVsbCkgZm9yICh2YXIgayBpbiBtb2QpIGlmIChrICE9PSBcImRlZmF1bHRcIiAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobW9kLCBrKSkgX19jcmVhdGVCaW5kaW5nKHJlc3VsdCwgbW9kLCBrKTtcclxuICAgIF9fc2V0TW9kdWxlRGVmYXVsdChyZXN1bHQsIG1vZCk7XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19pbXBvcnREZWZhdWx0KG1vZCkge1xyXG4gICAgcmV0dXJuIChtb2QgJiYgbW9kLl9fZXNNb2R1bGUpID8gbW9kIDogeyBkZWZhdWx0OiBtb2QgfTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fY2xhc3NQcml2YXRlRmllbGRHZXQocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmKSB7XHJcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBnZXR0ZXJcIik7XHJcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCByZWFkIHByaXZhdGUgbWVtYmVyIGZyb20gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcclxuICAgIHJldHVybiBraW5kID09PSBcIm1cIiA/IGYgOiBraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlcikgOiBmID8gZi52YWx1ZSA6IHN0YXRlLmdldChyZWNlaXZlcik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KHJlY2VpdmVyLCBzdGF0ZSwgdmFsdWUsIGtpbmQsIGYpIHtcclxuICAgIGlmIChraW5kID09PSBcIm1cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgbWV0aG9kIGlzIG5vdCB3cml0YWJsZVwiKTtcclxuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIHNldHRlclwiKTtcclxuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XHJcbiAgICByZXR1cm4gKGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyLCB2YWx1ZSkgOiBmID8gZi52YWx1ZSA9IHZhbHVlIDogc3RhdGUuc2V0KHJlY2VpdmVyLCB2YWx1ZSkpLCB2YWx1ZTtcclxufVxyXG4iLCJpbXBvcnQgeyBNYXJrZG93blZpZXcsIFBsdWdpbiB9IGZyb20gJ29ic2lkaWFuJztcblxuaW50ZXJmYWNlIHNvcnRNZXRob2Qge1xuXHQoeDogc3RyaW5nLCB5OiBzdHJpbmcpOiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBNeUxpbmUge1xuXHRzb3VyY2U6IHN0cmluZztcblx0Zm9ybWF0dGVkOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE15UGx1Z2luIGV4dGVuZHMgUGx1Z2luIHtcblx0Y29tcGFyZTogc29ydE1ldGhvZDtcblx0YXN5bmMgb25sb2FkKCkge1xuXHRcdGNvbnNvbGUubG9nKCdsb2FkaW5nICcgKyB0aGlzLm1hbmlmZXN0Lm5hbWUpO1xuXG5cdFx0Y29uc3QgeyBjb21wYXJlIH0gPSBuZXcgSW50bC5Db2xsYXRvcih1bmRlZmluZWQsIHtcblx0XHRcdHVzYWdlOiAnc29ydCcsXG5cdFx0XHRzZW5zaXRpdml0eTogJ2Jhc2UnLFxuXHRcdFx0bnVtZXJpYzogdHJ1ZSxcblx0XHRcdGlnbm9yZVB1bmN0dWF0aW9uOiB0cnVlLFxuXHRcdH0pO1xuXHRcdHRoaXMuY29tcGFyZSA9IGNvbXBhcmU7XG5cdFx0dGhpcy5hZGRDb21tYW5kKHtcblx0XHRcdGlkOiAnc29ydC1hbHBoYWJldGljYWxseScsXG5cdFx0XHRuYW1lOiAnU29ydCBhbHBoYWJldGljYWxseScsXG5cdFx0XHRjYWxsYmFjazogKCgpID0+IHRoaXMuc29ydEFscGhhYmV0aWNhbGx5KCkpLFxuXHRcdH0pO1xuXHRcdHRoaXMuYWRkQ29tbWFuZCh7XG5cdFx0XHRpZDogJ3NvcnQtbGVuZ3RoJyxcblx0XHRcdG5hbWU6ICdTb3J0IGJ5IGxlbmd0aCBvZiBsaW5lJyxcblx0XHRcdGNhbGxiYWNrOiAoKCkgPT4gdGhpcy5zb3J0TGVuZ3RoT2ZMaW5lKCkpLFxuXHRcdH0pO1xuXHRcdHRoaXMuYWRkQ29tbWFuZCh7XG5cdFx0XHRpZDogJ3Blcm11dGUtcmV2ZXJzZScsXG5cdFx0XHRuYW1lOiAnUmV2ZXJzZSBsaW5lcycsXG5cdFx0XHRjYWxsYmFjazogKCgpID0+IHRoaXMucGVybXV0ZVJldmVyc2UoKSksXG5cdFx0fSk7XG5cdFx0dGhpcy5hZGRDb21tYW5kKHtcblx0XHRcdGlkOiAncGVybXV0ZS1zaHVmZmxlJyxcblx0XHRcdG5hbWU6ICdTaHVmZmxlIGxpbmVzJyxcblx0XHRcdGNhbGxiYWNrOiAoKCkgPT4gdGhpcy5wZXJtdXRlU2h1ZmZsZSgpKSxcblx0XHR9KTtcblxuXHR9XG5cblx0b251bmxvYWQoKSB7XG5cdFx0Y29uc29sZS5sb2coJ3VubG9hZGluZyAnICsgdGhpcy5tYW5pZmVzdC5uYW1lKTtcblx0fVxuXG5cblx0c29ydEFscGhhYmV0aWNhbGx5KCkge1xuXHRcdGNvbnN0IGxpbmVzID0gdGhpcy5nZXRMaW5lcygpO1xuXHRcdGlmIChsaW5lcy5sZW5ndGggPT09IDApIHJldHVybjtcblx0XHRsZXQgc29ydEZ1bmMgPSAoYTogTXlMaW5lLCBiOiBNeUxpbmUpID0+IHRoaXMuY29tcGFyZShhLmZvcm1hdHRlZC50cmltKCksIGIuZm9ybWF0dGVkLnRyaW0oKSk7XG5cblx0XHRsaW5lcy5zb3J0KHNvcnRGdW5jKTtcblx0XHR0aGlzLnNldExpbmVzKGxpbmVzKTtcblx0fVxuXG5cdHNvcnRMZW5ndGhPZkxpbmUoKSB7XG5cdFx0Y29uc3QgbGluZXMgPSB0aGlzLmdldExpbmVzKCk7XG5cdFx0aWYgKGxpbmVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuXHRcdGxpbmVzLnNvcnQoKGEsIGIpID0+IGEuZm9ybWF0dGVkLmxlbmd0aCAtIGIuZm9ybWF0dGVkLmxlbmd0aCk7XG5cblx0XHR0aGlzLnNldExpbmVzKGxpbmVzKTtcblx0fVxuXG5cdHBlcm11dGVSZXZlcnNlKCkge1xuXHRcdGNvbnN0IGxpbmVzID0gdGhpcy5nZXRMaW5lcygpO1xuXHRcdGlmIChsaW5lcy5sZW5ndGggPT09IDApIHJldHVybjtcblx0XHRsaW5lcy5yZXZlcnNlKCk7XG5cdFx0dGhpcy5zZXRMaW5lcyhsaW5lcyk7XG5cdH1cblxuXHRwZXJtdXRlU2h1ZmZsZSgpIHtcblx0XHRjb25zdCBsaW5lcyA9IHRoaXMuZ2V0TGluZXMoKTtcblx0XHRpZiAobGluZXMubGVuZ3RoID09PSAwKSByZXR1cm47XG5cdFx0bGluZXMuc2h1ZmZsZSgpO1xuXHRcdHRoaXMuc2V0TGluZXMobGluZXMpO1xuXHR9XG5cblx0Z2V0TGluZXMoKTogTXlMaW5lW10ge1xuXHRcdGNvbnN0IHZpZXcgPSB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0QWN0aXZlVmlld09mVHlwZShNYXJrZG93blZpZXcpO1xuXHRcdGlmICghdmlldylcblx0XHRcdHJldHVybjtcblx0XHRjb25zdCBlZGl0b3IgPSB2aWV3LmVkaXRvcjtcblx0XHRjb25zdCBmaWxlID0gdmlldy5maWxlO1xuXHRcdGxldCBsaW5lcyA9IGVkaXRvci5nZXRWYWx1ZSgpLnNwbGl0KFwiXFxuXCIpO1xuXG5cdFx0Y29uc3Qgc3RhcnQgPSBlZGl0b3IuZ2V0Q3Vyc29yKFwiZnJvbVwiKS5saW5lO1xuXHRcdGNvbnN0IGVuZCA9IGVkaXRvci5nZXRDdXJzb3IoXCJ0b1wiKS5saW5lO1xuXHRcdGNvbnN0IGNhY2hlID0gdGhpcy5hcHAubWV0YWRhdGFDYWNoZS5nZXRGaWxlQ2FjaGUoZmlsZSk7XG5cblxuXG5cdFx0Y29uc3QgbGlua3MgPSBbLi4uY2FjaGU/LmxpbmtzID8/IFtdLCAuLi5jYWNoZT8uZW1iZWRzID8/IFtdXTtcblx0XHRjb25zdCBteUxpbmVzID0gbGluZXMubWFwKChsaW5lLCBpbmRleCkgPT4ge1xuXHRcdFx0Y29uc3QgbXlMaW5lOiBNeUxpbmUgPSB7IHNvdXJjZTogbGluZSwgZm9ybWF0dGVkOiBsaW5lIH07XG5cdFx0XHRsaW5rcy5mb3JFYWNoKGUgPT4ge1xuXHRcdFx0XHRpZiAoZS5wb3NpdGlvbi5zdGFydC5saW5lICE9IGluZGV4KSByZXR1cm47XG5cdFx0XHRcdGNvbnN0IHN0YXJ0ID0gZS5wb3NpdGlvbi5zdGFydDtcblx0XHRcdFx0Y29uc3QgZW5kID0gZS5wb3NpdGlvbi5lbmQ7XG5cdFx0XHRcdG15TGluZS5mb3JtYXR0ZWQgPSBteUxpbmUuZm9ybWF0dGVkLnJlcGxhY2UobGluZS5zdWJzdHJpbmcoc3RhcnQuY29sLCBlbmQuY29sKSwgZS5kaXNwbGF5VGV4dCk7XG5cdFx0XHR9KTtcblx0XHRcdGlmIChteUxpbmUuZm9ybWF0dGVkLnN0YXJ0c1dpdGgoXCItIFt4XVwiKSkge1xuXHRcdFx0XHRteUxpbmUuZm9ybWF0dGVkID0gbXlMaW5lLmZvcm1hdHRlZC5zdWJzdHJpbmcoNik7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBteUxpbmU7XG5cdFx0fSk7XG5cdFx0aWYgKHN0YXJ0ICE9IGVuZCkge1xuXHRcdFx0cmV0dXJuIG15TGluZXMuc2xpY2Uoc3RhcnQsIGVuZCArIDEpO1xuXHRcdH0gZWxzZSBpZiAoY2FjaGUuZnJvbnRtYXR0ZXIpIHtcblx0XHRcdHJldHVybiBteUxpbmVzLnNsaWNlKGNhY2hlLmZyb250bWF0dGVyLnBvc2l0aW9uLmVuZC5saW5lICsgMSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiBteUxpbmVzO1xuXHRcdH1cblx0fVxuXG5cdHNldExpbmVzKGxpbmVzOiBNeUxpbmVbXSkge1xuXHRcdGNvbnN0IHZpZXcgPSB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0QWN0aXZlVmlld09mVHlwZShNYXJrZG93blZpZXcpO1xuXHRcdGNvbnN0IHJlcyA9IHRoaXMuZ2V0UG9zaXRpb24odmlldyk7XG5cdFx0Y29uc3QgZWRpdG9yID0gdmlldy5lZGl0b3I7XG5cdFx0aWYgKHJlcy5zdGFydCAhPSByZXMuZW5kKSB7XG5cdFx0XHRlZGl0b3IucmVwbGFjZVJhbmdlKGxpbmVzLm1hcChlID0+IGUuc291cmNlKS5qb2luKFwiXFxuXCIpLCB7IGxpbmU6IHJlcy5zdGFydCwgY2g6IDAgfSwgeyBsaW5lOiByZXMuZW5kLCBjaDogcmVzLmVuZExpbmVMZW5ndGggfSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGVkaXRvci5zZXRWYWx1ZShsaW5lcy5tYXAoZSA9PiBlLnNvdXJjZSkuam9pbihcIlxcblwiKSk7XG5cdFx0fVxuXHR9XG5cblx0Z2V0UG9zaXRpb24odmlldzogTWFya2Rvd25WaWV3KTogeyBzdGFydDogbnVtYmVyOyBlbmQ6IG51bWJlcjsgZW5kTGluZUxlbmd0aDogbnVtYmVyOyB9IHwgdW5kZWZpbmVkIHtcblx0XHRjb25zdCBjYWNoZSA9IHRoaXMuYXBwLm1ldGFkYXRhQ2FjaGUuZ2V0RmlsZUNhY2hlKHZpZXcuZmlsZSk7XG5cdFx0Y29uc3QgZWRpdG9yID0gdmlldy5lZGl0b3I7XG5cblx0XHRjb25zdCBjdXJzb3JTdGFydCA9IGVkaXRvci5nZXRDdXJzb3IoXCJmcm9tXCIpLmxpbmU7XG5cdFx0Y29uc3QgY3Vyc29yRW5kID0gZWRpdG9yLmdldEN1cnNvcihcInRvXCIpLmxpbmU7XG5cdFx0Y29uc3QgY3Vyc2VyRW5kTGluZUxlbmd0aCA9IGVkaXRvci5nZXRMaW5lKGN1cnNvckVuZCkubGVuZ3RoO1xuXG5cdFx0bGV0IGZyb250U3RhcnQgPSBjYWNoZS5mcm9udG1hdHRlcj8ucG9zaXRpb24/LmVuZD8ubGluZSArIDE7XG5cdFx0aWYgKGlzTmFOKGZyb250U3RhcnQpKSB7XG5cdFx0XHRmcm9udFN0YXJ0ID0gMDtcblx0XHR9XG5cdFx0Y29uc3QgZnJvbnRFbmQgPSBlZGl0b3IubGFzdExpbmUoKTtcblx0XHRjb25zdCBmcm9udEVuZExpbmVMZW5ndGggPSBlZGl0b3IuZ2V0TGluZShmcm9udEVuZCkubGVuZ3RoO1xuXG5cdFx0aWYgKGN1cnNvclN0YXJ0ICE9IGN1cnNvckVuZCkge1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0c3RhcnQ6IGN1cnNvclN0YXJ0LFxuXHRcdFx0XHRlbmQ6IGN1cnNvckVuZCxcblx0XHRcdFx0ZW5kTGluZUxlbmd0aDogY3Vyc2VyRW5kTGluZUxlbmd0aCxcblx0XHRcdH07XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdHN0YXJ0OiBmcm9udFN0YXJ0LFxuXHRcdFx0XHRlbmQ6IGZyb250RW5kLFxuXHRcdFx0XHRlbmRMaW5lTGVuZ3RoOiBmcm9udEVuZExpbmVMZW5ndGgsXG5cdFx0XHR9O1xuXHRcdH1cblx0fVxufSJdLCJuYW1lcyI6WyJNYXJrZG93blZpZXciLCJQbHVnaW4iXSwibWFwcGluZ3MiOiI7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUksYUFBYSxHQUFHLFNBQVMsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUNuQyxJQUFJLGFBQWEsR0FBRyxNQUFNLENBQUMsY0FBYztBQUN6QyxTQUFTLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRSxZQUFZLEtBQUssSUFBSSxVQUFVLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUM7QUFDcEYsUUFBUSxVQUFVLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLE1BQU0sQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7QUFDMUcsSUFBSSxPQUFPLGFBQWEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDL0IsQ0FBQyxDQUFDO0FBQ0Y7QUFDTyxTQUFTLFNBQVMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ2hDLElBQUksSUFBSSxPQUFPLENBQUMsS0FBSyxVQUFVLElBQUksQ0FBQyxLQUFLLElBQUk7QUFDN0MsUUFBUSxNQUFNLElBQUksU0FBUyxDQUFDLHNCQUFzQixHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRywrQkFBK0IsQ0FBQyxDQUFDO0FBQ2xHLElBQUksYUFBYSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUN4QixJQUFJLFNBQVMsRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUMsRUFBRTtBQUMzQyxJQUFJLENBQUMsQ0FBQyxTQUFTLEdBQUcsQ0FBQyxLQUFLLElBQUksR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDekYsQ0FBQztBQXVDRDtBQUNPLFNBQVMsU0FBUyxDQUFDLE9BQU8sRUFBRSxVQUFVLEVBQUUsQ0FBQyxFQUFFLFNBQVMsRUFBRTtBQUM3RCxJQUFJLFNBQVMsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLE9BQU8sS0FBSyxZQUFZLENBQUMsR0FBRyxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsVUFBVSxPQUFPLEVBQUUsRUFBRSxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRTtBQUNoSCxJQUFJLE9BQU8sS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLE9BQU8sQ0FBQyxFQUFFLFVBQVUsT0FBTyxFQUFFLE1BQU0sRUFBRTtBQUMvRCxRQUFRLFNBQVMsU0FBUyxDQUFDLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7QUFDbkcsUUFBUSxTQUFTLFFBQVEsQ0FBQyxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7QUFDdEcsUUFBUSxTQUFTLElBQUksQ0FBQyxNQUFNLEVBQUUsRUFBRSxNQUFNLENBQUMsSUFBSSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxDQUFDLEVBQUU7QUFDdEgsUUFBUSxJQUFJLENBQUMsQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsVUFBVSxJQUFJLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7QUFDOUUsS0FBSyxDQUFDLENBQUM7QUFDUCxDQUFDO0FBQ0Q7QUFDTyxTQUFTLFdBQVcsQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFO0FBQzNDLElBQUksSUFBSSxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNySCxJQUFJLE9BQU8sQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxPQUFPLE1BQU0sS0FBSyxVQUFVLEtBQUssQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsR0FBRyxXQUFXLEVBQUUsT0FBTyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQzdKLElBQUksU0FBUyxJQUFJLENBQUMsQ0FBQyxFQUFFLEVBQUUsT0FBTyxVQUFVLENBQUMsRUFBRSxFQUFFLE9BQU8sSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDdEUsSUFBSSxTQUFTLElBQUksQ0FBQyxFQUFFLEVBQUU7QUFDdEIsUUFBUSxJQUFJLENBQUMsRUFBRSxNQUFNLElBQUksU0FBUyxDQUFDLGlDQUFpQyxDQUFDLENBQUM7QUFDdEUsUUFBUSxPQUFPLENBQUMsRUFBRSxJQUFJO0FBQ3RCLFlBQVksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDekssWUFBWSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3BELFlBQVksUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ3pCLGdCQUFnQixLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxNQUFNO0FBQzlDLGdCQUFnQixLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLENBQUM7QUFDeEUsZ0JBQWdCLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVM7QUFDakUsZ0JBQWdCLEtBQUssQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLFNBQVM7QUFDakUsZ0JBQWdCO0FBQ2hCLG9CQUFvQixJQUFJLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsU0FBUyxFQUFFO0FBQ2hJLG9CQUFvQixJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFO0FBQzFHLG9CQUFvQixJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxD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 diff --git a/.obsidian/plugins/obsidian-sort-and-permute-lines/manifest.json b/.obsidian/plugins/obsidian-sort-and-permute-lines/manifest.json deleted file mode 100644 index eb30b3a..0000000 --- a/.obsidian/plugins/obsidian-sort-and-permute-lines/manifest.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "id": "obsidian-sort-and-permute-lines", - "name": "Sort & Permute lines", - "version": "0.2.2", - "description": "", - "author": "Vinzent", - "authorUrl": "https://github.com/Vinzent03", - "isDesktopOnly": false -} \ No newline at end of file diff --git a/.obsidian/plugins/obsidian-task-archiver/main.js b/.obsidian/plugins/obsidian-task-archiver/main.js deleted file mode 100644 index 912dc23..0000000 --- a/.obsidian/plugins/obsidian-task-archiver/main.js +++ /dev/null @@ -1,294 +0,0 @@ -/* -THIS IS A GENERATED/BUNDLED FILE BY ROLLUP -if you want to view the source visit the plugins github repository -*/ - -'use strict'; - -var obsidian = require('obsidian'); - -/*! ***************************************************************************** -Copyright (c) Microsoft Corporation. - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. -***************************************************************************** */ - -function __awaiter(thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -} - -function escapeStringRegexp(string) { - if (typeof string !== 'string') { - throw new TypeError('Expected a string'); - } - - // Escape characters with special meaning either inside or outside character sets. - // Use a simple backslash escape when it’s always valid, and a `\xnn` escape when the simpler form would be disallowed by Unicode patterns’ stricter grammar. - return string - .replace(/[|\\{}()[\]^$+*?.]/g, '\\$&') - .replace(/-/g, '\\x2d'); -} - -const INDENTED_LINE_PATTERN = new RegExp("^( {2,}|\\t)\\s*\\S+"); -const COMPLETED_TASK_PATTERN = new RegExp("^(-|\\d+\\.) \\[x\\] "); -class Archiver { - constructor(settings) { - this.settings = settings; - const escapedHeading = escapeStringRegexp(settings.archiveHeading); - this.archivePattern = new RegExp(`^#+\\s+${escapedHeading}`); - this.archiveEndPattern = new RegExp(`^#+\\s+(?!${escapedHeading})`); - } - archiveTasks(lines) { - const hasArchive = lines.findIndex((line) => this.archivePattern.exec(line)) >= 0; - if (!hasArchive) { - if (lines[lines.length - 1].trim() !== "") { - lines.push(""); - } - lines.push(`# ${this.settings.archiveHeading}`); - } - const { linesWithoutArchive, archive } = this.extractArchive(lines); - const { linesWithoutCompletedTasks, newlyCompletedTasks } = this.extractCompletedTasks(linesWithoutArchive); - if (newlyCompletedTasks.length === 0) { - return { - summary: "No tasks to archive", - lines: lines, - }; - } - const linesWithInsertedArchivedTasks = this.addTasksToArchive(newlyCompletedTasks, linesWithoutCompletedTasks, archive); - return { - summary: `Archived ${newlyCompletedTasks.length} lines`, - lines: linesWithInsertedArchivedTasks, - }; - } - extractCompletedTasks(linesWithoutArchive) { - const linesWithoutCompletedTasks = []; - const newlyCompletedTasks = []; - let linesAfterTask = false; - for (const line of linesWithoutArchive) { - if (line.match(COMPLETED_TASK_PATTERN)) { - newlyCompletedTasks.push(line); - linesAfterTask = true; - } - else if (line.match(INDENTED_LINE_PATTERN) && linesAfterTask) { - newlyCompletedTasks.push(line); - } - else { - linesWithoutCompletedTasks.push(line); - linesAfterTask = false; - } - } - return { - linesWithoutCompletedTasks, - newlyCompletedTasks, - }; - } - extractArchive(lines) { - let archiveLines = []; - let linesWithoutArchive = []; - let insideArchive = false; - for (const line of lines) { - if (insideArchive) { - if (this.archiveEndPattern.exec(line)) { - insideArchive = false; - linesWithoutArchive.push(line); - } - else if (line.trim().length > 0) { - archiveLines.push(line); - } - } - else { - if (this.archivePattern.exec(line)) { - insideArchive = true; - } - linesWithoutArchive.push(line); - } - } - return { - linesWithoutArchive, - archive: new Archive(archiveLines, this.settings), - }; - } - addTasksToArchive(tasks, lines, archive) { - const archiveWithNewTasks = archive.appendToContents(tasks); - const archiveStart = lines.findIndex((l) => this.archivePattern.exec(l)); - lines.splice(archiveStart + 1, 0, ...archiveWithNewTasks); - return lines; - } -} -class Archive { - constructor(lines, settings) { - this.contents = lines; - this.settings = settings; - } - appendToContents(newLines) { - let insertionIndex; - if (this.settings.useDateTree) { - const week = window.moment().format(this.settings.weeklyNoteFormat); - const indentationSettings = this.settings.indentationSettings; - const indentation = indentationSettings.useTab - ? "\t" - : " ".repeat(indentationSettings.tabSize); - newLines = newLines.map((line) => `${indentation}${line}`); - const weekLine = `- [[${week}]]`; - const currentWeekIndexInTree = this.contents.findIndex((line) => line.startsWith(weekLine)); - if (currentWeekIndexInTree < 0) { - newLines.unshift(weekLine); - } - else { - insertionIndex = this.findBlockEnd(weekLine); - } - } - if (!insertionIndex) { - insertionIndex = this.contents.length; - } - this.contents.splice(insertionIndex, 0, ...newLines); - return ["", ...this.contents, ""]; - } - findBlockEnd(parentLine) { - let insideBlock = false; - for (const [i, line] of this.contents.entries()) { - if (line === parentLine) { - insideBlock = true; - continue; - } - const isLineIndented = INDENTED_LINE_PATTERN.exec(line); - if (insideBlock && !isLineIndented) { - return i; - } - } - return this.contents.length; - } -} - -const DEFAULT_SETTINGS = { - archiveHeading: "Archived", - weeklyNoteFormat: "YYYY-MM-[W]-w", - useDateTree: true, - indentationSettings: { - useTab: true, - tabSize: 4, - }, -}; -class ObsidianTaskArchiver extends obsidian.Plugin { - onload() { - return __awaiter(this, void 0, void 0, function* () { - this.addCommand({ - id: "archive-tasks", - name: "Archive tasks in this file", - callback: () => this.archiveTasksInCurrentFile(), - }); - yield this.loadSettings(); - this.addSettingTab(new ArchiverSettingTab(this.app, this)); - }); - } - archiveTasksInCurrentFile() { - return __awaiter(this, void 0, void 0, function* () { - const activeFile = this.app.workspace.getActiveFile(); - if (activeFile === null || activeFile.extension !== "md") { - new obsidian.Notice("The archiver works only in markdown (.md) files!"); - return; - } - const fileContents = yield this.app.vault.read(activeFile); - const lines = fileContents.split("\n"); - const archiver = new Archiver(this.settings); - const archiveResult = archiver.archiveTasks(lines); - new obsidian.Notice(archiveResult.summary); - this.app.vault.modify(activeFile, archiveResult.lines.join("\n")); - }); - } - loadSettings() { - return __awaiter(this, void 0, void 0, function* () { - const getConfig = (key) => { - return this.app.vault.getConfig(key); - }; - this.settings = Object.assign({}, DEFAULT_SETTINGS, yield this.loadData(), { - indentationSettings: { - useTab: getConfig("useTab"), - tabSize: getConfig("tabSize"), - }, - }); - }); - } - saveSettings() { - return __awaiter(this, void 0, void 0, function* () { - yield this.saveData(this.settings); - }); - } -} -class ArchiverSettingTab extends obsidian.PluginSettingTab { - constructor(app, plugin) { - super(app, plugin); - this.plugin = plugin; - } - display() { - const { containerEl } = this; - containerEl.empty(); - containerEl.createEl("h2", { text: "Obsidian Task Archiver Settings" }); - new obsidian.Setting(containerEl) - .setName("Archive heading") - .setDesc("A heading with this text will be used as an archive") - .addText((textComponent) => { - textComponent - .setPlaceholder(this.plugin.settings.archiveHeading) - .setValue(this.plugin.settings.archiveHeading) - .onChange((value) => __awaiter(this, void 0, void 0, function* () { - this.plugin.settings.archiveHeading = value; - yield this.plugin.saveSettings(); - })); - }); - new obsidian.Setting(containerEl) - .setName("Use date trees") - .setDesc("Add completed tasks under a link to the current week") - .addToggle((toggleComponent) => toggleComponent - .setValue(this.plugin.settings.useDateTree) - .onChange((value) => __awaiter(this, void 0, void 0, function* () { - this.plugin.settings.useDateTree = value; - yield this.plugin.saveSettings(); - }))); - new obsidian.Setting(containerEl) - .setDisabled(!this.plugin.settings.useDateTree) - .setName("Weekly note pattern") - .then((setting) => { - setting.addMomentFormat((momentFormat) => { - setting.descEl.appendChild(createFragment((fragment) => { - fragment.appendText("For more syntax, refer to "); - fragment.createEl("a", { - text: "format reference", - href: "https://momentjs.com/docs/#/displaying/format/", - }, (a) => { - a.setAttr("target", "_blank"); - }); - fragment.createEl("br"); - fragment.appendText("Your current syntax looks like this: "); - momentFormat.setSampleEl(fragment.createEl("b")); - fragment.createEl("br"); - })); - momentFormat - .setDefaultFormat(this.plugin.settings.weeklyNoteFormat) - .setPlaceholder(this.plugin.settings.weeklyNoteFormat) - .setValue(this.plugin.settings.weeklyNoteFormat) - .onChange((value) => __awaiter(this, void 0, void 0, function* () { - this.plugin.settings.weeklyNoteFormat = value; - yield this.plugin.saveSettings(); - })); - }); - }); - } -} - -module.exports = ObsidianTaskArchiver; diff --git a/.obsidian/plugins/obsidian-task-archiver/manifest.json b/.obsidian/plugins/obsidian-task-archiver/manifest.json deleted file mode 100644 index 9565bc2..0000000 --- a/.obsidian/plugins/obsidian-task-archiver/manifest.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "id": "obsidian-task-archiver", - "name": "Obsidian Task Archiver", - "version": "0.2.1", - "minAppVersion": "0.12.0", - "description": "Move completed tasks to an archive with a date tree", - "author": "Ivan Lednev", - "authorUrl": "https://github.com/ivan-lednev", - "isDesktopOnly": false -} diff --git a/.obsidian/plugins/quickadd/data.json b/.obsidian/plugins/quickadd/data.json deleted file mode 100644 index cbff731..0000000 --- a/.obsidian/plugins/quickadd/data.json +++ /dev/null @@ -1,610 +0,0 @@ -{ - "choices": [ - { - "id": "7e3a1676-7511-41c0-8b62-55906437052f", - "name": "Create New Project", - "type": "Macro", - "command": true, - "macroId": "b2f09e03-f268-4665-a121-7962f59b74be" - }, - { - "id": "3739ee1b-df34-4e7f-8f52-de1c1c9975e2", - "name": "Create New Discipline", - "type": "Macro", - "command": true, - "macroId": "c81df748-21e9-4bc1-ac52-48a81bb42514" - }, - { - "id": "2ba53d9e-ed12-49d4-9593-0ecaf1dc139b", - "name": "Create New Habit", - "type": "Macro", - "command": true, - "macroId": "fb71c6a7-5a51-4670-b868-d13b1e3c8f2c" - }, - { - "id": "e710c3ad-156c-4e40-92a0-dfdb138d2c67", - "name": "Task Add Here", - "type": "Macro", - "command": true, - "macroId": "8abbfb8c-8654-4837-ab59-85302db0119a" - }, - { - "id": "f186fa45-3cd8-4d96-9f9d-8708d4f0111e", - "name": "Task Archive to Archived", - "type": "Macro", - "command": true, - "macroId": "472e8d68-1bfe-4d5c-a648-4e64a7457cd1" - }, - { - "id": "7fe89f23-dc5e-436d-bb50-d9c7d74c0f53", - "name": "Task Completed Add Here", - "type": "Macro", - "command": true, - "macroId": "19466a2c-a544-45de-bcb7-a08e52ecb4df" - }, - { - "id": "5c58752f-1b0f-462e-a072-c7a9ef8c0d45", - "name": "Insert Chaotic Note Roller (5)", - "type": "Macro", - "command": true, - "macroId": "fc5423e4-7a7b-425a-a2fa-1a69a9ff29e2" - }, - { - "id": "135ba466-319d-436f-8ede-6d439a04dbe3", - "name": "Insert Chaotic Note Roller (10)", - "type": "Macro", - "command": true, - "macroId": "7c7cc6e9-3b3a-4794-92fc-5b711c130a95" - } - ], - "macros": [ - { - "name": "Task Add Here", - "id": "8abbfb8c-8654-4837-ab59-85302db0119a", - "commands": [ - { - "name": "Add Task Here", - "type": "NestedChoice", - "id": "66e1cf99-a4cb-4b9e-b0e0-9e64ae0f14db", - "choice": { - "id": "aeae736d-a75a-4454-9502-9da74b1bffd3", - "name": "Add Task Here", - "type": "Capture", - "command": false, - "appendLink": false, - "captureTo": "", - "captureToActiveFile": true, - "createFileIfItDoesntExist": { - "enabled": false, - "createWithTemplate": false, - "template": "" - }, - "format": { - "enabled": true, - "format": "#task {{VALUE:#p01 ,#p11 ,#p10 ,#p00 }}{{VALUE:#30m ,#15m ,#01h ,#02h }}{{VALUE:Task Description}} {{VALUE:,#ongoing }}{{VALUE:,#blocked/1 ,#blocked/2 ,#blocked/3 ,#blocking/1 ,#blocking/2 ,#blocking/3 }}{{VALUE:,#exclude/on-hold ,#exclude/stale }}" - }, - "insertAfter": { - "enabled": false, - "after": "", - "insertAtEnd": false, - "createIfNotFound": false, - "createIfNotFoundLocation": "top" - }, - "prepend": false, - "task": true, - "openFileInNewTab": { - "enabled": false, - "direction": "vertical", - "focus": true - }, - "openFile": false, - "openFileInMode": "default" - } - } - ], - "runOnStartup": false - }, - { - "name": "Task to Archived", - "id": "472e8d68-1bfe-4d5c-a648-4e64a7457cd1", - "commands": [ - { - "name": "Select active line", - "type": "EditorCommand", - "id": "0a577dfb-75a2-46c8-81d6-45d42c50a766", - "editorCommandType": "Select active line" - }, - { - "name": "Copy", - "type": "EditorCommand", - "id": "62a74a3a-de23-4ea4-8f44-8f873441c755", - "editorCommandType": "Copy" - }, - { - "name": "Paste Task to this Project Archived", - "type": "NestedChoice", - "id": "da1ae81f-aca0-4b45-8d0c-6174024ed3b0", - "choice": { - "id": "50d0af85-1e4b-4c3a-841a-cac635639219", - "name": "Paste Task to this Project Archived", - "type": "Capture", - "command": false, - "appendLink": false, - "captureTo": "", - "captureToActiveFile": true, - "createFileIfItDoesntExist": { - "enabled": false, - "createWithTemplate": false, - "template": "" - }, - "format": { - "enabled": true, - "format": "```js quickadd\nreturn await this.quickAddApi.utility.getClipboard();\n```" - }, - "insertAfter": { - "enabled": false, - "after": "", - "insertAtEnd": false, - "createIfNotFound": false, - "createIfNotFoundLocation": "top" - }, - "prepend": true, - "task": false, - "openFileInNewTab": { - "enabled": false, - "direction": "vertical", - "focus": true - }, - "openFile": false, - "openFileInMode": "default" - } - }, - { - "name": "Delete paragraph", - "type": "Obsidian", - "id": "04d5b6bc-d065-4a4b-9c57-8768143651ae", - "commandId": "editor:delete-paragraph" - } - ], - "runOnStartup": false - }, - { - "name": "Task Completed Add Here", - "id": "19466a2c-a544-45de-bcb7-a08e52ecb4df", - "commands": [ - { - "name": "Task Completed Add Here", - "type": "NestedChoice", - "id": "59777f88-db7c-43c3-a804-0a0424293453", - "choice": { - "id": "14fb501a-942b-4f06-ad4d-e2588708b301", - "name": "Task Completed Add Here", - "type": "Capture", - "command": false, - "appendLink": false, - "captureTo": "", - "captureToActiveFile": true, - "createFileIfItDoesntExist": { - "enabled": false, - "createWithTemplate": false, - "template": "" - }, - "format": { - "enabled": true, - "format": "- [x] #task {{VALUE:#p01 ,#p11 ,#p10 #p00 }}{{VALUE:#30m ,#15m ,#01h ,#02h }}{{VALUE:Task Description}} ✅ {{DATE}}" - }, - "insertAfter": { - "enabled": false, - "after": "", - "insertAtEnd": false, - "createIfNotFound": false, - "createIfNotFoundLocation": "top" - }, - "prepend": false, - "task": false, - "openFileInNewTab": { - "enabled": false, - "direction": "vertical", - "focus": true - }, - "openFile": false, - "openFileInMode": "default" - } - } - ], - "runOnStartup": false - }, - { - "name": "Create New Project", - "id": "b2f09e03-f268-4665-a121-7962f59b74be", - "commands": [ - { - "name": "Create New Project Dashboard", - "type": "NestedChoice", - "id": "96668efb-3d2b-4afd-826f-ec919094dbd7", - "choice": { - "id": "c8322bd8-828f-4e43-9432-6d59705dfdd3", - "name": "Create New Project Dashboard", - "type": "Template", - "command": false, - "templatePath": "800 Templates/Dashboard Project.md", - "fileNameFormat": { - "enabled": true, - "format": "00 {{VALUE:Source Emoji}} {{VALUE:Source Base Name}}" - }, - "folder": { - "enabled": true, - "folders": [], - "chooseWhenCreatingNote": true, - "createInSameFolderAsActiveFile": false - }, - "appendLink": false, - "incrementFileName": false, - "openFileInNewTab": { - "enabled": true, - "direction": "vertical", - "focus": true - }, - "openFile": true, - "openFileInMode": "default" - } - }, - { - "name": "Create New Task Catalog", - "type": "NestedChoice", - "id": "a47e75d5-b170-40bd-97f3-854f0ba3bb66", - "choice": { - "id": "4e13485d-df85-44c7-beb3-bbe6b5bb6b88", - "name": "Create New Task Catalog", - "type": "Template", - "command": false, - "templatePath": "800 Templates/Tasks (Catalog).md", - "fileNameFormat": { - "enabled": true, - "format": "01 🌊 Tasks {{VALUE:Source Base Name}}" - }, - "folder": { - "enabled": true, - "folders": [], - "chooseWhenCreatingNote": false, - "createInSameFolderAsActiveFile": true - }, - "appendLink": false, - "incrementFileName": false, - "openFileInNewTab": { - "enabled": true, - "direction": "vertical", - "focus": false - }, - "openFile": false, - "openFileInMode": "default" - } - }, - { - "name": "Create New Ramblings", - "type": "NestedChoice", - "id": "16cefa8b-d868-4d4d-afab-e88cb82ab2ce", - "choice": { - "id": "a95edb2d-e186-4ecc-8ed8-4c9721d3dc0a", - "name": "Create New Ramblings", - "type": "Template", - "command": false, - "templatePath": "800 Templates/Ramblings.md", - "fileNameFormat": { - "enabled": true, - "format": "02 💡 Ramblings {{VALUE:Source Base Name}}" - }, - "folder": { - "enabled": true, - "folders": [], - "chooseWhenCreatingNote": false, - "createInSameFolderAsActiveFile": true - }, - "appendLink": false, - "incrementFileName": false, - "openFileInNewTab": { - "enabled": true, - "direction": "vertical", - "focus": false - }, - "openFile": false, - "openFileInMode": "default" - } - } - ], - "runOnStartup": false - }, - { - "name": "Create New Discipline", - "id": "c81df748-21e9-4bc1-ac52-48a81bb42514", - "commands": [ - { - "name": "Create New Discipline Dashboard", - "type": "NestedChoice", - "id": "97449988-cd68-454d-b039-ed3e3782184c", - "choice": { - "id": "585d79bc-06b6-4676-b148-1ad8bfd4b380", - "name": "Create New Discipline Dashboard", - "type": "Template", - "command": false, - "templatePath": "800 Templates/Dashboard Discipline.md", - "fileNameFormat": { - "enabled": true, - "format": "{{VALUE:Number Prefix}}0 {{VALUE:Source Emoji}} {{VALUE:Source Base Name}}" - }, - "folder": { - "enabled": true, - "folders": [], - "chooseWhenCreatingNote": true, - "createInSameFolderAsActiveFile": false - }, - "appendLink": false, - "incrementFileName": false, - "openFileInNewTab": { - "enabled": true, - "direction": "vertical", - "focus": true - }, - "openFile": true, - "openFileInMode": "default" - } - }, - { - "name": "Create New Task Catalog", - "type": "NestedChoice", - "id": "703bbf10-4031-4b5d-82d2-60c6d2d184d7", - "choice": { - "id": "c4bf8efc-9dc7-41dc-af41-eedc273b95e6", - "name": "Create New Task Catalog", - "type": "Template", - "command": false, - "templatePath": "800 Templates/Tasks (Catalog).md", - "fileNameFormat": { - "enabled": true, - "format": "{{VALUE:Number Prefix}}1 🌊 Tasks {{VALUE:Source Base Name}}" - }, - "folder": { - "enabled": true, - "folders": [], - "chooseWhenCreatingNote": false, - "createInSameFolderAsActiveFile": true - }, - "appendLink": false, - "incrementFileName": false, - "openFileInNewTab": { - "enabled": true, - "direction": "vertical", - "focus": false - }, - "openFile": false, - "openFileInMode": "default" - } - }, - { - "name": "Create New Ramblings", - "type": "NestedChoice", - "id": "239f8e1d-335b-4f52-8e6e-912ba29b8489", - "choice": { - "id": "7b124fbd-d582-480a-b804-280fb0a2e6c7", - "name": "Create New Ramblings", - "type": "Template", - "command": false, - "templatePath": "800 Templates/Ramblings.md", - "fileNameFormat": { - "enabled": true, - "format": "{{VALUE:Number Prefix}}2 💡 Ramblings {{VALUE:Source Base Name}}" - }, - "folder": { - "enabled": true, - "folders": [], - "chooseWhenCreatingNote": false, - "createInSameFolderAsActiveFile": true - }, - "appendLink": false, - "incrementFileName": false, - "openFileInNewTab": { - "enabled": true, - "direction": "vertical", - "focus": false - }, - "openFile": false, - "openFileInMode": "default" - } - } - ], - "runOnStartup": false - }, - { - "name": "Create New Habit", - "id": "fb71c6a7-5a51-4670-b868-d13b1e3c8f2c", - "commands": [ - { - "name": "Create New Habit Dashboard", - "type": "NestedChoice", - "id": "b4f1df74-7aaa-416f-89a1-9f33610e1909", - "choice": { - "id": "2e478a03-01f1-4c6a-9198-b1edf6ea5c13", - "name": "Create New Habit Dashboard", - "type": "Template", - "command": false, - "templatePath": "800 Templates/Dashboard Habit.md", - "fileNameFormat": { - "enabled": true, - "format": "00 {{VALUE:Source Emoji}} {{VALUE:Source Base Name}}" - }, - "folder": { - "enabled": true, - "folders": [], - "chooseWhenCreatingNote": true, - "createInSameFolderAsActiveFile": false - }, - "appendLink": false, - "incrementFileName": false, - "openFileInNewTab": { - "enabled": true, - "direction": "vertical", - "focus": true - }, - "openFile": true, - "openFileInMode": "default" - } - }, - { - "name": "Create New Task Catalog", - "type": "NestedChoice", - "id": "0a31aed9-2b73-4469-aa14-54f45d0bdd54", - "choice": { - "id": "3297cb9c-23f0-46d9-84fb-93a2c27ca01c", - "name": "Create New Task Catalog", - "type": "Template", - "command": false, - "templatePath": "800 Templates/Tasks (Catalog).md", - "fileNameFormat": { - "enabled": true, - "format": "01 🌊 Tasks {{VALUE:Source Base Name}}" - }, - "folder": { - "enabled": true, - "folders": [], - "chooseWhenCreatingNote": false, - "createInSameFolderAsActiveFile": true - }, - "appendLink": false, - "incrementFileName": false, - "openFileInNewTab": { - "enabled": false, - "direction": "vertical", - "focus": false - }, - "openFile": false, - "openFileInMode": "default" - } - }, - { - "name": "Create New Ramblings", - "type": "NestedChoice", - "id": "3d04a8f7-2809-4657-8a9f-306e0f75469c", - "choice": { - "id": "c756df6d-9ce8-42d0-8c19-c865a8e2eadf", - "name": "Create New Ramblings", - "type": "Template", - "command": false, - "templatePath": "800 Templates/Ramblings.md", - "fileNameFormat": { - "enabled": true, - "format": "02 💡 Ramblings {{VALUE:Source Base Name}}" - }, - "folder": { - "enabled": true, - "folders": [], - "chooseWhenCreatingNote": false, - "createInSameFolderAsActiveFile": true - }, - "appendLink": false, - "incrementFileName": false, - "openFileInNewTab": { - "enabled": true, - "direction": "vertical", - "focus": false - }, - "openFile": false, - "openFileInMode": "default" - } - } - ], - "runOnStartup": false - }, - { - "name": "Insert Chaotic Note Roller (5)", - "id": "fc5423e4-7a7b-425a-a2fa-1a69a9ff29e2", - "commands": [ - { - "name": "Insert Chaotic Note Roller (5)", - "type": "NestedChoice", - "id": "b80448ad-4637-467c-a936-6e96c022b6b6", - "choice": { - "id": "253cdc19-3432-443e-8be2-d6e6c1772d10", - "name": "Insert Chaotic Note Roller (5)", - "type": "Capture", - "command": false, - "appendLink": false, - "captureTo": "", - "captureToActiveFile": true, - "createFileIfItDoesntExist": { - "enabled": false, - "createWithTemplate": false, - "template": "" - }, - "format": { - "enabled": true, - "format": "`dice: {{VALUE:Tag}}|link`\n`dice: {{VALUE:Tag}}|link`\n`dice: {{VALUE:Tag}}|link`\n`dice: {{VALUE:Tag}}|link`\n`dice: {{VALUE:Tag}}|link`" - }, - "insertAfter": { - "enabled": false, - "after": "", - "insertAtEnd": false, - "createIfNotFound": false, - "createIfNotFoundLocation": "top" - }, - "prepend": false, - "task": false, - "openFileInNewTab": { - "enabled": false, - "direction": "vertical", - "focus": true - }, - "openFile": false, - "openFileInMode": "default" - } - } - ], - "runOnStartup": false - }, - { - "name": "Insert Chaotic Note Roller (10)", - "id": "7c7cc6e9-3b3a-4794-92fc-5b711c130a95", - "commands": [ - { - "name": "Insert Chaotic Note Roller (10)", - "type": "NestedChoice", - "id": "bfb0aee1-c323-4559-8c7a-ca7afb538e98", - "choice": { - "id": "3cfd66e6-d096-4f0f-bdbe-d11af8e803b0", - "name": "Insert Chaotic Note Roller (10)", - "type": "Capture", - "command": false, - "appendLink": false, - "captureTo": "", - "captureToActiveFile": true, - "createFileIfItDoesntExist": { - "enabled": false, - "createWithTemplate": false, - "template": "" - }, - "format": { - "enabled": true, - "format": "`dice: {{VALUE:Tag}}|link`\n`dice: {{VALUE:Tag}}|link`\n`dice: {{VALUE:Tag}}|link`\n`dice: {{VALUE:Tag}}|link`\n`dice: {{VALUE:Tag}}|link`\n`dice: {{VALUE:Tag}}|link`\n`dice: {{VALUE:Tag}}|link`\n`dice: {{VALUE:Tag}}|link`\n`dice: {{VALUE:Tag}}|link`\n`dice: {{VALUE:Tag}}|link`" - }, - "insertAfter": { - "enabled": false, - "after": "", - "insertAtEnd": false, - "createIfNotFound": false, - "createIfNotFoundLocation": "top" - }, - "prepend": false, - "task": false, - "openFileInNewTab": { - "enabled": false, - "direction": "vertical", - "focus": true - }, - "openFile": false, - "openFileInMode": "default" - } - } - ], - "runOnStartup": false - } - ] -} \ No newline at end of file diff --git a/.obsidian/plugins/quickadd/main.js b/.obsidian/plugins/quickadd/main.js deleted file mode 100644 index fd7cf3a..0000000 --- a/.obsidian/plugins/quickadd/main.js +++ /dev/null @@ -1,15223 +0,0 @@ -'use strict'; - -var obsidian = require('obsidian'); -require('assert'); - -function _interopNamespace(e) { - if (e && e.__esModule) return e; - var n = Object.create(null); - if (e) { - Object.keys(e).forEach(function (k) { - if (k !== 'default') { - var d = Object.getOwnPropertyDescriptor(e, k); - Object.defineProperty(n, k, d.get ? d : { - enumerable: true, - get: function () { return e[k]; } - }); - } - }); - } - n["default"] = e; - return Object.freeze(n); -} - -function noop() { } -function assign(tar, src) { - // @ts-ignore - for (const k in src) - tar[k] = src[k]; - return tar; -} -function run(fn) { - return fn(); -} -function blank_object() { - return Object.create(null); -} -function run_all(fns) { - fns.forEach(run); -} -function is_function(thing) { - return typeof thing === 'function'; -} -function safe_not_equal(a, b) { - return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function'); -} -function is_empty(obj) { - return Object.keys(obj).length === 0; -} -function create_slot(definition, ctx, $$scope, fn) { - if (definition) { - const slot_ctx = get_slot_context(definition, ctx, $$scope, fn); - return definition[0](slot_ctx); - } -} -function get_slot_context(definition, ctx, $$scope, fn) { - return definition[1] && fn - ? assign($$scope.ctx.slice(), definition[1](fn(ctx))) - : $$scope.ctx; -} -function get_slot_changes(definition, $$scope, dirty, fn) { - if (definition[2] && fn) { - const lets = definition[2](fn(dirty)); - if ($$scope.dirty === undefined) { - return lets; - } - if (typeof lets === 'object') { - const merged = []; - const len = Math.max($$scope.dirty.length, lets.length); - for (let i = 0; i < len; i += 1) { - merged[i] = $$scope.dirty[i] | lets[i]; - } - return merged; - } - return $$scope.dirty | lets; - } - return $$scope.dirty; -} -function update_slot_base(slot, slot_definition, ctx, $$scope, slot_changes, get_slot_context_fn) { - if (slot_changes) { - const slot_context = get_slot_context(slot_definition, ctx, $$scope, get_slot_context_fn); - slot.p(slot_context, slot_changes); - } -} -function get_all_dirty_from_scope($$scope) { - if ($$scope.ctx.length > 32) { - const dirty = []; - const length = $$scope.ctx.length / 32; - for (let i = 0; i < length; i++) { - dirty[i] = -1; - } - return dirty; - } - return -1; -} -function action_destroyer(action_result) { - return action_result && is_function(action_result.destroy) ? action_result.destroy : noop; -} -function append(target, node) { - target.appendChild(node); -} -function append_styles(target, style_sheet_id, styles) { - const append_styles_to = get_root_for_style(target); - if (!append_styles_to.getElementById(style_sheet_id)) { - const style = element('style'); - style.id = style_sheet_id; - style.textContent = styles; - append_stylesheet(append_styles_to, style); - } -} -function get_root_for_style(node) { - if (!node) - return document; - const root = node.getRootNode ? node.getRootNode() : node.ownerDocument; - if (root && root.host) { - return root; - } - return node.ownerDocument; -} -function append_stylesheet(node, style) { - append(node.head || node, style); -} -function insert(target, node, anchor) { - target.insertBefore(node, anchor || null); -} -function detach(node) { - node.parentNode.removeChild(node); -} -function destroy_each(iterations, detaching) { - for (let i = 0; i < iterations.length; i += 1) { - if (iterations[i]) - iterations[i].d(detaching); - } -} -function element(name) { - return document.createElement(name); -} -function svg_element(name) { - return document.createElementNS('http://www.w3.org/2000/svg', name); -} -function text(data) { - return document.createTextNode(data); -} -function space() { - return text(' '); -} -function empty() { - return text(''); -} -function listen(node, event, handler, options) { - node.addEventListener(event, handler, options); - return () => node.removeEventListener(event, handler, options); -} -function attr(node, attribute, value) { - if (value == null) - node.removeAttribute(attribute); - else if (node.getAttribute(attribute) !== value) - node.setAttribute(attribute, value); -} -function set_svg_attributes(node, attributes) { - for (const key in attributes) { - attr(node, key, attributes[key]); - } -} -function to_number(value) { - return value === '' ? null : +value; -} -function children(element) { - return Array.from(element.childNodes); -} -function set_data(text, data) { - data = '' + data; - if (text.wholeText !== data) - text.data = data; -} -function set_input_value(input, value) { - input.value = value == null ? '' : value; -} -function set_style(node, key, value, important) { - node.style.setProperty(key, value, important ? 'important' : ''); -} -function select_option(select, value) { - for (let i = 0; i < select.options.length; i += 1) { - const option = select.options[i]; - if (option.__value === value) { - option.selected = true; - return; - } - } - select.selectedIndex = -1; // no option should be selected -} -function select_value(select) { - const selected_option = select.querySelector(':checked') || select.options[0]; - return selected_option && selected_option.__value; -} -function toggle_class(element, name, toggle) { - element.classList[toggle ? 'add' : 'remove'](name); -} -function custom_event(type, detail, bubbles = false) { - const e = document.createEvent('CustomEvent'); - e.initCustomEvent(type, bubbles, false, detail); - return e; -} - -let current_component; -function set_current_component(component) { - current_component = component; -} -function get_current_component() { - if (!current_component) - throw new Error('Function called outside component initialization'); - return current_component; -} -function onMount(fn) { - get_current_component().$$.on_mount.push(fn); -} -function createEventDispatcher() { - const component = get_current_component(); - return (type, detail) => { - const callbacks = component.$$.callbacks[type]; - if (callbacks) { - // TODO are there situations where events could be dispatched - // in a server (non-DOM) environment? - const event = custom_event(type, detail); - callbacks.slice().forEach(fn => { - fn.call(component, event); - }); - } - }; -} -// TODO figure out if we still want to support -// shorthand events, or if we want to implement -// a real bubbling mechanism -function bubble(component, event) { - const callbacks = component.$$.callbacks[event.type]; - if (callbacks) { - // @ts-ignore - callbacks.slice().forEach(fn => fn.call(this, event)); - } -} - -const dirty_components = []; -const binding_callbacks = []; -const render_callbacks = []; -const flush_callbacks = []; -const resolved_promise = Promise.resolve(); -let update_scheduled = false; -function schedule_update() { - if (!update_scheduled) { - update_scheduled = true; - resolved_promise.then(flush); - } -} -function add_render_callback(fn) { - render_callbacks.push(fn); -} -function add_flush_callback(fn) { - flush_callbacks.push(fn); -} -let flushing = false; -const seen_callbacks = new Set(); -function flush() { - if (flushing) - return; - flushing = true; - do { - // first, call beforeUpdate functions - // and update components - for (let i = 0; i < dirty_components.length; i += 1) { - const component = dirty_components[i]; - set_current_component(component); - update(component.$$); - } - set_current_component(null); - dirty_components.length = 0; - while (binding_callbacks.length) - binding_callbacks.pop()(); - // then, once components are updated, call - // afterUpdate functions. This may cause - // subsequent updates... - for (let i = 0; i < render_callbacks.length; i += 1) { - const callback = render_callbacks[i]; - if (!seen_callbacks.has(callback)) { - // ...so guard against infinite loops - seen_callbacks.add(callback); - callback(); - } - } - render_callbacks.length = 0; - } while (dirty_components.length); - while (flush_callbacks.length) { - flush_callbacks.pop()(); - } - update_scheduled = false; - flushing = false; - seen_callbacks.clear(); -} -function update($$) { - if ($$.fragment !== null) { - $$.update(); - run_all($$.before_update); - const dirty = $$.dirty; - $$.dirty = [-1]; - $$.fragment && $$.fragment.p($$.ctx, dirty); - $$.after_update.forEach(add_render_callback); - } -} -const outroing = new Set(); -let outros; -function group_outros() { - outros = { - r: 0, - c: [], - p: outros // parent group - }; -} -function check_outros() { - if (!outros.r) { - run_all(outros.c); - } - outros = outros.p; -} -function transition_in(block, local) { - if (block && block.i) { - outroing.delete(block); - block.i(local); - } -} -function transition_out(block, local, detach, callback) { - if (block && block.o) { - if (outroing.has(block)) - return; - outroing.add(block); - outros.c.push(() => { - outroing.delete(block); - if (callback) { - if (detach) - block.d(1); - callback(); - } - }); - block.o(local); - } -} -function outro_and_destroy_block(block, lookup) { - transition_out(block, 1, 1, () => { - lookup.delete(block.key); - }); -} -function update_keyed_each(old_blocks, dirty, get_key, dynamic, ctx, list, lookup, node, destroy, create_each_block, next, get_context) { - let o = old_blocks.length; - let n = list.length; - let i = o; - const old_indexes = {}; - while (i--) - old_indexes[old_blocks[i].key] = i; - const new_blocks = []; - const new_lookup = new Map(); - const deltas = new Map(); - i = n; - while (i--) { - const child_ctx = get_context(ctx, list, i); - const key = get_key(child_ctx); - let block = lookup.get(key); - if (!block) { - block = create_each_block(key, child_ctx); - block.c(); - } - else if (dynamic) { - block.p(child_ctx, dirty); - } - new_lookup.set(key, new_blocks[i] = block); - if (key in old_indexes) - deltas.set(key, Math.abs(i - old_indexes[key])); - } - const will_move = new Set(); - const did_move = new Set(); - function insert(block) { - transition_in(block, 1); - block.m(node, next); - lookup.set(block.key, block); - next = block.first; - n--; - } - while (o && n) { - const new_block = new_blocks[n - 1]; - const old_block = old_blocks[o - 1]; - const new_key = new_block.key; - const old_key = old_block.key; - if (new_block === old_block) { - // do nothing - next = new_block.first; - o--; - n--; - } - else if (!new_lookup.has(old_key)) { - // remove old block - destroy(old_block, lookup); - o--; - } - else if (!lookup.has(new_key) || will_move.has(new_key)) { - insert(new_block); - } - else if (did_move.has(old_key)) { - o--; - } - else if (deltas.get(new_key) > deltas.get(old_key)) { - did_move.add(new_key); - insert(new_block); - } - else { - will_move.add(old_key); - o--; - } - } - while (o--) { - const old_block = old_blocks[o]; - if (!new_lookup.has(old_block.key)) - destroy(old_block, lookup); - } - while (n) - insert(new_blocks[n - 1]); - return new_blocks; -} - -function get_spread_update(levels, updates) { - const update = {}; - const to_null_out = {}; - const accounted_for = { $$scope: 1 }; - let i = levels.length; - while (i--) { - const o = levels[i]; - const n = updates[i]; - if (n) { - for (const key in o) { - if (!(key in n)) - to_null_out[key] = 1; - } - for (const key in n) { - if (!accounted_for[key]) { - update[key] = n[key]; - accounted_for[key] = 1; - } - } - levels[i] = n; - } - else { - for (const key in o) { - accounted_for[key] = 1; - } - } - } - for (const key in to_null_out) { - if (!(key in update)) - update[key] = undefined; - } - return update; -} - -function bind(component, name, callback) { - const index = component.$$.props[name]; - if (index !== undefined) { - component.$$.bound[index] = callback; - callback(component.$$.ctx[index]); - } -} -function create_component(block) { - block && block.c(); -} -function mount_component(component, target, anchor, customElement) { - const { fragment, on_mount, on_destroy, after_update } = component.$$; - fragment && fragment.m(target, anchor); - if (!customElement) { - // onMount happens before the initial afterUpdate - add_render_callback(() => { - const new_on_destroy = on_mount.map(run).filter(is_function); - if (on_destroy) { - on_destroy.push(...new_on_destroy); - } - else { - // Edge case - component was destroyed immediately, - // most likely as a result of a binding initialising - run_all(new_on_destroy); - } - component.$$.on_mount = []; - }); - } - after_update.forEach(add_render_callback); -} -function destroy_component(component, detaching) { - const $$ = component.$$; - if ($$.fragment !== null) { - run_all($$.on_destroy); - $$.fragment && $$.fragment.d(detaching); - // TODO null out other refs, including component.$$ (but need to - // preserve final state?) - $$.on_destroy = $$.fragment = null; - $$.ctx = []; - } -} -function make_dirty(component, i) { - if (component.$$.dirty[0] === -1) { - dirty_components.push(component); - schedule_update(); - component.$$.dirty.fill(0); - } - component.$$.dirty[(i / 31) | 0] |= (1 << (i % 31)); -} -function init(component, options, instance, create_fragment, not_equal, props, append_styles, dirty = [-1]) { - const parent_component = current_component; - set_current_component(component); - const $$ = component.$$ = { - fragment: null, - ctx: null, - // state - props, - update: noop, - not_equal, - bound: blank_object(), - // lifecycle - on_mount: [], - on_destroy: [], - on_disconnect: [], - before_update: [], - after_update: [], - context: new Map(options.context || (parent_component ? parent_component.$$.context : [])), - // everything else - callbacks: blank_object(), - dirty, - skip_bound: false, - root: options.target || parent_component.$$.root - }; - append_styles && append_styles($$.root); - let ready = false; - $$.ctx = instance - ? instance(component, options.props || {}, (i, ret, ...rest) => { - const value = rest.length ? rest[0] : ret; - if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) { - if (!$$.skip_bound && $$.bound[i]) - $$.bound[i](value); - if (ready) - make_dirty(component, i); - } - return ret; - }) - : []; - $$.update(); - ready = true; - run_all($$.before_update); - // `false` as a special case of no DOM component - $$.fragment = create_fragment ? create_fragment($$.ctx) : false; - if (options.target) { - if (options.hydrate) { - const nodes = children(options.target); - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - $$.fragment && $$.fragment.l(nodes); - nodes.forEach(detach); - } - else { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - $$.fragment && $$.fragment.c(); - } - if (options.intro) - transition_in(component.$$.fragment); - mount_component(component, options.target, options.anchor, options.customElement); - flush(); - } - set_current_component(parent_component); -} -/** - * Base class for Svelte components. Used when dev=false. - */ -class SvelteComponent { - $destroy() { - destroy_component(this, 1); - this.$destroy = noop; - } - $on(type, callback) { - const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = [])); - callbacks.push(callback); - return () => { - const index = callbacks.indexOf(callback); - if (index !== -1) - callbacks.splice(index, 1); - }; - } - $set($$props) { - if (this.$$set && !is_empty($$props)) { - this.$$.skip_bound = true; - this.$$set($$props); - this.$$.skip_bound = false; - } - } -} - -var ChoiceType; -(function (ChoiceType) { - ChoiceType["Capture"] = "Capture"; - ChoiceType["Macro"] = "Macro"; - ChoiceType["Multi"] = "Multi"; - ChoiceType["Template"] = "Template"; -})(ChoiceType || (ChoiceType = {})); - -/*! - * Font Awesome Free 5.15.3 by @fontawesome - https://fontawesome.com - * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) - */ -var faBars = { - prefix: 'fas', - iconName: 'bars', - icon: [448, 512, [], "f0c9", "M16 132h416c8.837 0 16-7.163 16-16V76c0-8.837-7.163-16-16-16H16C7.163 60 0 67.163 0 76v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16zm0 160h416c8.837 0 16-7.163 16-16v-40c0-8.837-7.163-16-16-16H16c-8.837 0-16 7.163-16 16v40c0 8.837 7.163 16 16 16z"] -}; -var faBolt = { - prefix: 'fas', - iconName: 'bolt', - icon: [320, 512, [], "f0e7", "M296 160H180.6l42.6-129.8C227.2 15 215.7 0 200 0H56C44 0 33.8 8.9 32.2 20.8l-32 240C-1.7 275.2 9.5 288 24 288h118.7L96.6 482.5c-3.6 15.2 8 29.5 23.3 29.5 8.4 0 16.4-4.4 20.8-12l176-304c9.3-15.9-2.2-36-20.7-36z"] -}; -var faChevronDown = { - prefix: 'fas', - iconName: 'chevron-down', - icon: [448, 512, [], "f078", "M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z"] -}; -var faCog = { - prefix: 'fas', - iconName: 'cog', - icon: [512, 512, [], "f013", "M487.4 315.7l-42.6-24.6c4.3-23.2 4.3-47 0-70.2l42.6-24.6c4.9-2.8 7.1-8.6 5.5-14-11.1-35.6-30-67.8-54.7-94.6-3.8-4.1-10-5.1-14.8-2.3L380.8 110c-17.9-15.4-38.5-27.3-60.8-35.1V25.8c0-5.6-3.9-10.5-9.4-11.7-36.7-8.2-74.3-7.8-109.2 0-5.5 1.2-9.4 6.1-9.4 11.7V75c-22.2 7.9-42.8 19.8-60.8 35.1L88.7 85.5c-4.9-2.8-11-1.9-14.8 2.3-24.7 26.7-43.6 58.9-54.7 94.6-1.7 5.4.6 11.2 5.5 14L67.3 221c-4.3 23.2-4.3 47 0 70.2l-42.6 24.6c-4.9 2.8-7.1 8.6-5.5 14 11.1 35.6 30 67.8 54.7 94.6 3.8 4.1 10 5.1 14.8 2.3l42.6-24.6c17.9 15.4 38.5 27.3 60.8 35.1v49.2c0 5.6 3.9 10.5 9.4 11.7 36.7 8.2 74.3 7.8 109.2 0 5.5-1.2 9.4-6.1 9.4-11.7v-49.2c22.2-7.9 42.8-19.8 60.8-35.1l42.6 24.6c4.9 2.8 11 1.9 14.8-2.3 24.7-26.7 43.6-58.9 54.7-94.6 1.5-5.5-.7-11.3-5.6-14.1zM256 336c-44.1 0-80-35.9-80-80s35.9-80 80-80 80 35.9 80 80-35.9 80-80 80z"] -}; -var faTrash = { - prefix: 'fas', - iconName: 'trash', - icon: [448, 512, [], "f1f8", "M432 32H312l-9.4-18.7A24 24 0 0 0 281.1 0H166.8a23.72 23.72 0 0 0-21.4 13.3L136 32H16A16 16 0 0 0 0 48v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zM53.2 467a48 48 0 0 0 47.9 45h245.8a48 48 0 0 0 47.9-45L416 128H32z"] -}; - -/* node_modules/svelte-awesome/components/svg/Path.svelte generated by Svelte v3.43.0 */ - -function create_fragment$i(ctx) { - let path; - let path_key_value; - - let path_levels = [ - { - key: path_key_value = "path-" + /*id*/ ctx[0] - }, - /*data*/ ctx[1] - ]; - - let path_data = {}; - - for (let i = 0; i < path_levels.length; i += 1) { - path_data = assign(path_data, path_levels[i]); - } - - return { - c() { - path = svg_element("path"); - set_svg_attributes(path, path_data); - }, - m(target, anchor) { - insert(target, path, anchor); - }, - p(ctx, [dirty]) { - set_svg_attributes(path, path_data = get_spread_update(path_levels, [ - dirty & /*id*/ 1 && path_key_value !== (path_key_value = "path-" + /*id*/ ctx[0]) && { key: path_key_value }, - dirty & /*data*/ 2 && /*data*/ ctx[1] - ])); - }, - i: noop, - o: noop, - d(detaching) { - if (detaching) detach(path); - } - }; -} - -function instance$i($$self, $$props, $$invalidate) { - let { id = '' } = $$props; - let { data = {} } = $$props; - - $$self.$$set = $$props => { - if ('id' in $$props) $$invalidate(0, id = $$props.id); - if ('data' in $$props) $$invalidate(1, data = $$props.data); - }; - - return [id, data]; -} - -class Path extends SvelteComponent { - constructor(options) { - super(); - init(this, options, instance$i, create_fragment$i, safe_not_equal, { id: 0, data: 1 }); - } -} - -/* node_modules/svelte-awesome/components/svg/Polygon.svelte generated by Svelte v3.43.0 */ - -function create_fragment$h(ctx) { - let polygon; - let polygon_key_value; - - let polygon_levels = [ - { - key: polygon_key_value = "polygon-" + /*id*/ ctx[0] - }, - /*data*/ ctx[1] - ]; - - let polygon_data = {}; - - for (let i = 0; i < polygon_levels.length; i += 1) { - polygon_data = assign(polygon_data, polygon_levels[i]); - } - - return { - c() { - polygon = svg_element("polygon"); - set_svg_attributes(polygon, polygon_data); - }, - m(target, anchor) { - insert(target, polygon, anchor); - }, - p(ctx, [dirty]) { - set_svg_attributes(polygon, polygon_data = get_spread_update(polygon_levels, [ - dirty & /*id*/ 1 && polygon_key_value !== (polygon_key_value = "polygon-" + /*id*/ ctx[0]) && { key: polygon_key_value }, - dirty & /*data*/ 2 && /*data*/ ctx[1] - ])); - }, - i: noop, - o: noop, - d(detaching) { - if (detaching) detach(polygon); - } - }; -} - -function instance$h($$self, $$props, $$invalidate) { - let { id = '' } = $$props; - let { data = {} } = $$props; - - $$self.$$set = $$props => { - if ('id' in $$props) $$invalidate(0, id = $$props.id); - if ('data' in $$props) $$invalidate(1, data = $$props.data); - }; - - return [id, data]; -} - -class Polygon extends SvelteComponent { - constructor(options) { - super(); - init(this, options, instance$h, create_fragment$h, safe_not_equal, { id: 0, data: 1 }); - } -} - -/* node_modules/svelte-awesome/components/svg/Raw.svelte generated by Svelte v3.43.0 */ - -function create_fragment$g(ctx) { - let g; - - return { - c() { - g = svg_element("g"); - }, - m(target, anchor) { - insert(target, g, anchor); - g.innerHTML = /*raw*/ ctx[0]; - }, - p(ctx, [dirty]) { - if (dirty & /*raw*/ 1) g.innerHTML = /*raw*/ ctx[0]; }, - i: noop, - o: noop, - d(detaching) { - if (detaching) detach(g); - } - }; -} - -function instance$g($$self, $$props, $$invalidate) { - let cursor = 0xd4937; - - function getId() { - cursor += 1; - return `fa-${cursor.toString(16)}`; - } - - let raw; - let { data } = $$props; - - function getRaw(data) { - if (!data || !data.raw) { - return null; - } - - let rawData = data.raw; - const ids = {}; - - rawData = rawData.replace(/\s(?:xml:)?id=["']?([^"')\s]+)/g, (match, id) => { - const uniqueId = getId(); - ids[id] = uniqueId; - return ` id="${uniqueId}"`; - }); - - rawData = rawData.replace(/#(?:([^'")\s]+)|xpointer\(id\((['"]?)([^')]+)\2\)\))/g, (match, rawId, _, pointerId) => { - const id = rawId || pointerId; - - if (!id || !ids[id]) { - return match; - } - - return `#${ids[id]}`; - }); - - return rawData; - } - - $$self.$$set = $$props => { - if ('data' in $$props) $$invalidate(1, data = $$props.data); - }; - - $$self.$$.update = () => { - if ($$self.$$.dirty & /*data*/ 2) { - $$invalidate(0, raw = getRaw(data)); - } - }; - - return [raw, data]; -} - -class Raw extends SvelteComponent { - constructor(options) { - super(); - init(this, options, instance$g, create_fragment$g, safe_not_equal, { data: 1 }); - } -} - -/* node_modules/svelte-awesome/components/svg/Svg.svelte generated by Svelte v3.43.0 */ - -function add_css$a(target) { - append_styles(target, "svelte-1dof0an", ".fa-icon.svelte-1dof0an{display:inline-block;fill:currentColor}.fa-flip-horizontal.svelte-1dof0an{transform:scale(-1, 1)}.fa-flip-vertical.svelte-1dof0an{transform:scale(1, -1)}.fa-spin.svelte-1dof0an{animation:svelte-1dof0an-fa-spin 1s 0s infinite linear}.fa-inverse.svelte-1dof0an{color:#fff}.fa-pulse.svelte-1dof0an{animation:svelte-1dof0an-fa-spin 1s infinite steps(8)}@keyframes svelte-1dof0an-fa-spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}"); -} - -function create_fragment$f(ctx) { - let svg; - let svg_class_value; - let svg_role_value; - let current; - const default_slot_template = /*#slots*/ ctx[13].default; - const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[12], null); - - return { - c() { - svg = svg_element("svg"); - if (default_slot) default_slot.c(); - attr(svg, "version", "1.1"); - attr(svg, "class", svg_class_value = "fa-icon " + /*className*/ ctx[0] + " svelte-1dof0an"); - attr(svg, "x", /*x*/ ctx[8]); - attr(svg, "y", /*y*/ ctx[9]); - attr(svg, "width", /*width*/ ctx[1]); - attr(svg, "height", /*height*/ ctx[2]); - attr(svg, "aria-label", /*label*/ ctx[11]); - attr(svg, "role", svg_role_value = /*label*/ ctx[11] ? 'img' : 'presentation'); - attr(svg, "viewBox", /*box*/ ctx[3]); - attr(svg, "style", /*style*/ ctx[10]); - toggle_class(svg, "fa-spin", /*spin*/ ctx[4]); - toggle_class(svg, "fa-pulse", /*pulse*/ ctx[6]); - toggle_class(svg, "fa-inverse", /*inverse*/ ctx[5]); - toggle_class(svg, "fa-flip-horizontal", /*flip*/ ctx[7] === 'horizontal'); - toggle_class(svg, "fa-flip-vertical", /*flip*/ ctx[7] === 'vertical'); - }, - m(target, anchor) { - insert(target, svg, anchor); - - if (default_slot) { - default_slot.m(svg, null); - } - - current = true; - }, - p(ctx, [dirty]) { - if (default_slot) { - if (default_slot.p && (!current || dirty & /*$$scope*/ 4096)) { - update_slot_base( - default_slot, - default_slot_template, - ctx, - /*$$scope*/ ctx[12], - !current - ? get_all_dirty_from_scope(/*$$scope*/ ctx[12]) - : get_slot_changes(default_slot_template, /*$$scope*/ ctx[12], dirty, null), - null - ); - } - } - - if (!current || dirty & /*className*/ 1 && svg_class_value !== (svg_class_value = "fa-icon " + /*className*/ ctx[0] + " svelte-1dof0an")) { - attr(svg, "class", svg_class_value); - } - - if (!current || dirty & /*x*/ 256) { - attr(svg, "x", /*x*/ ctx[8]); - } - - if (!current || dirty & /*y*/ 512) { - attr(svg, "y", /*y*/ ctx[9]); - } - - if (!current || dirty & /*width*/ 2) { - attr(svg, "width", /*width*/ ctx[1]); - } - - if (!current || dirty & /*height*/ 4) { - attr(svg, "height", /*height*/ ctx[2]); - } - - if (!current || dirty & /*label*/ 2048) { - attr(svg, "aria-label", /*label*/ ctx[11]); - } - - if (!current || dirty & /*label*/ 2048 && svg_role_value !== (svg_role_value = /*label*/ ctx[11] ? 'img' : 'presentation')) { - attr(svg, "role", svg_role_value); - } - - if (!current || dirty & /*box*/ 8) { - attr(svg, "viewBox", /*box*/ ctx[3]); - } - - if (!current || dirty & /*style*/ 1024) { - attr(svg, "style", /*style*/ ctx[10]); - } - - if (dirty & /*className, spin*/ 17) { - toggle_class(svg, "fa-spin", /*spin*/ ctx[4]); - } - - if (dirty & /*className, pulse*/ 65) { - toggle_class(svg, "fa-pulse", /*pulse*/ ctx[6]); - } - - if (dirty & /*className, inverse*/ 33) { - toggle_class(svg, "fa-inverse", /*inverse*/ ctx[5]); - } - - if (dirty & /*className, flip*/ 129) { - toggle_class(svg, "fa-flip-horizontal", /*flip*/ ctx[7] === 'horizontal'); - } - - if (dirty & /*className, flip*/ 129) { - toggle_class(svg, "fa-flip-vertical", /*flip*/ ctx[7] === 'vertical'); - } - }, - i(local) { - if (current) return; - transition_in(default_slot, local); - current = true; - }, - o(local) { - transition_out(default_slot, local); - current = false; - }, - d(detaching) { - if (detaching) detach(svg); - if (default_slot) default_slot.d(detaching); - } - }; -} - -function instance$f($$self, $$props, $$invalidate) { - let { $$slots: slots = {}, $$scope } = $$props; - let { class: className } = $$props; - let { width } = $$props; - let { height } = $$props; - let { box } = $$props; - let { spin = false } = $$props; - let { inverse = false } = $$props; - let { pulse = false } = $$props; - let { flip = null } = $$props; - let { x = undefined } = $$props; - let { y = undefined } = $$props; - let { style = undefined } = $$props; - let { label = undefined } = $$props; - - $$self.$$set = $$props => { - if ('class' in $$props) $$invalidate(0, className = $$props.class); - if ('width' in $$props) $$invalidate(1, width = $$props.width); - if ('height' in $$props) $$invalidate(2, height = $$props.height); - if ('box' in $$props) $$invalidate(3, box = $$props.box); - if ('spin' in $$props) $$invalidate(4, spin = $$props.spin); - if ('inverse' in $$props) $$invalidate(5, inverse = $$props.inverse); - if ('pulse' in $$props) $$invalidate(6, pulse = $$props.pulse); - if ('flip' in $$props) $$invalidate(7, flip = $$props.flip); - if ('x' in $$props) $$invalidate(8, x = $$props.x); - if ('y' in $$props) $$invalidate(9, y = $$props.y); - if ('style' in $$props) $$invalidate(10, style = $$props.style); - if ('label' in $$props) $$invalidate(11, label = $$props.label); - if ('$$scope' in $$props) $$invalidate(12, $$scope = $$props.$$scope); - }; - - return [ - className, - width, - height, - box, - spin, - inverse, - pulse, - flip, - x, - y, - style, - label, - $$scope, - slots - ]; -} - -class Svg extends SvelteComponent { - constructor(options) { - super(); - - init( - this, - options, - instance$f, - create_fragment$f, - safe_not_equal, - { - class: 0, - width: 1, - height: 2, - box: 3, - spin: 4, - inverse: 5, - pulse: 6, - flip: 7, - x: 8, - y: 9, - style: 10, - label: 11 - }, - add_css$a - ); - } -} - -/* node_modules/svelte-awesome/components/Icon.svelte generated by Svelte v3.43.0 */ - -function get_each_context$3(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[24] = list[i]; - child_ctx[26] = i; - return child_ctx; -} - -function get_each_context_1(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[27] = list[i]; - child_ctx[26] = i; - return child_ctx; -} - -// (4:4) {#if self} -function create_if_block$4(ctx) { - let t0; - let t1; - let if_block2_anchor; - let current; - let if_block0 = /*self*/ ctx[0].paths && create_if_block_3(ctx); - let if_block1 = /*self*/ ctx[0].polygons && create_if_block_2$1(ctx); - let if_block2 = /*self*/ ctx[0].raw && create_if_block_1$2(ctx); - - return { - c() { - if (if_block0) if_block0.c(); - t0 = space(); - if (if_block1) if_block1.c(); - t1 = space(); - if (if_block2) if_block2.c(); - if_block2_anchor = empty(); - }, - m(target, anchor) { - if (if_block0) if_block0.m(target, anchor); - insert(target, t0, anchor); - if (if_block1) if_block1.m(target, anchor); - insert(target, t1, anchor); - if (if_block2) if_block2.m(target, anchor); - insert(target, if_block2_anchor, anchor); - current = true; - }, - p(ctx, dirty) { - if (/*self*/ ctx[0].paths) { - if (if_block0) { - if_block0.p(ctx, dirty); - - if (dirty & /*self*/ 1) { - transition_in(if_block0, 1); - } - } else { - if_block0 = create_if_block_3(ctx); - if_block0.c(); - transition_in(if_block0, 1); - if_block0.m(t0.parentNode, t0); - } - } else if (if_block0) { - group_outros(); - - transition_out(if_block0, 1, 1, () => { - if_block0 = null; - }); - - check_outros(); - } - - if (/*self*/ ctx[0].polygons) { - if (if_block1) { - if_block1.p(ctx, dirty); - - if (dirty & /*self*/ 1) { - transition_in(if_block1, 1); - } - } else { - if_block1 = create_if_block_2$1(ctx); - if_block1.c(); - transition_in(if_block1, 1); - if_block1.m(t1.parentNode, t1); - } - } else if (if_block1) { - group_outros(); - - transition_out(if_block1, 1, 1, () => { - if_block1 = null; - }); - - check_outros(); - } - - if (/*self*/ ctx[0].raw) { - if (if_block2) { - if_block2.p(ctx, dirty); - - if (dirty & /*self*/ 1) { - transition_in(if_block2, 1); - } - } else { - if_block2 = create_if_block_1$2(ctx); - if_block2.c(); - transition_in(if_block2, 1); - if_block2.m(if_block2_anchor.parentNode, if_block2_anchor); - } - } else if (if_block2) { - group_outros(); - - transition_out(if_block2, 1, 1, () => { - if_block2 = null; - }); - - check_outros(); - } - }, - i(local) { - if (current) return; - transition_in(if_block0); - transition_in(if_block1); - transition_in(if_block2); - current = true; - }, - o(local) { - transition_out(if_block0); - transition_out(if_block1); - transition_out(if_block2); - current = false; - }, - d(detaching) { - if (if_block0) if_block0.d(detaching); - if (detaching) detach(t0); - if (if_block1) if_block1.d(detaching); - if (detaching) detach(t1); - if (if_block2) if_block2.d(detaching); - if (detaching) detach(if_block2_anchor); - } - }; -} - -// (5:6) {#if self.paths} -function create_if_block_3(ctx) { - let each_1_anchor; - let current; - let each_value_1 = /*self*/ ctx[0].paths; - let each_blocks = []; - - for (let i = 0; i < each_value_1.length; i += 1) { - each_blocks[i] = create_each_block_1(get_each_context_1(ctx, each_value_1, i)); - } - - const out = i => transition_out(each_blocks[i], 1, 1, () => { - each_blocks[i] = null; - }); - - return { - c() { - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].c(); - } - - each_1_anchor = empty(); - }, - m(target, anchor) { - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].m(target, anchor); - } - - insert(target, each_1_anchor, anchor); - current = true; - }, - p(ctx, dirty) { - if (dirty & /*self*/ 1) { - each_value_1 = /*self*/ ctx[0].paths; - let i; - - for (i = 0; i < each_value_1.length; i += 1) { - const child_ctx = get_each_context_1(ctx, each_value_1, i); - - if (each_blocks[i]) { - each_blocks[i].p(child_ctx, dirty); - transition_in(each_blocks[i], 1); - } else { - each_blocks[i] = create_each_block_1(child_ctx); - each_blocks[i].c(); - transition_in(each_blocks[i], 1); - each_blocks[i].m(each_1_anchor.parentNode, each_1_anchor); - } - } - - group_outros(); - - for (i = each_value_1.length; i < each_blocks.length; i += 1) { - out(i); - } - - check_outros(); - } - }, - i(local) { - if (current) return; - - for (let i = 0; i < each_value_1.length; i += 1) { - transition_in(each_blocks[i]); - } - - current = true; - }, - o(local) { - each_blocks = each_blocks.filter(Boolean); - - for (let i = 0; i < each_blocks.length; i += 1) { - transition_out(each_blocks[i]); - } - - current = false; - }, - d(detaching) { - destroy_each(each_blocks, detaching); - if (detaching) detach(each_1_anchor); - } - }; -} - -// (6:8) {#each self.paths as path, i} -function create_each_block_1(ctx) { - let path; - let current; - - path = new Path({ - props: { - id: /*i*/ ctx[26], - data: /*path*/ ctx[27] - } - }); - - return { - c() { - create_component(path.$$.fragment); - }, - m(target, anchor) { - mount_component(path, target, anchor); - current = true; - }, - p(ctx, dirty) { - const path_changes = {}; - if (dirty & /*self*/ 1) path_changes.data = /*path*/ ctx[27]; - path.$set(path_changes); - }, - i(local) { - if (current) return; - transition_in(path.$$.fragment, local); - current = true; - }, - o(local) { - transition_out(path.$$.fragment, local); - current = false; - }, - d(detaching) { - destroy_component(path, detaching); - } - }; -} - -// (10:6) {#if self.polygons} -function create_if_block_2$1(ctx) { - let each_1_anchor; - let current; - let each_value = /*self*/ ctx[0].polygons; - let each_blocks = []; - - for (let i = 0; i < each_value.length; i += 1) { - each_blocks[i] = create_each_block$3(get_each_context$3(ctx, each_value, i)); - } - - const out = i => transition_out(each_blocks[i], 1, 1, () => { - each_blocks[i] = null; - }); - - return { - c() { - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].c(); - } - - each_1_anchor = empty(); - }, - m(target, anchor) { - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].m(target, anchor); - } - - insert(target, each_1_anchor, anchor); - current = true; - }, - p(ctx, dirty) { - if (dirty & /*self*/ 1) { - each_value = /*self*/ ctx[0].polygons; - let i; - - for (i = 0; i < each_value.length; i += 1) { - const child_ctx = get_each_context$3(ctx, each_value, i); - - if (each_blocks[i]) { - each_blocks[i].p(child_ctx, dirty); - transition_in(each_blocks[i], 1); - } else { - each_blocks[i] = create_each_block$3(child_ctx); - each_blocks[i].c(); - transition_in(each_blocks[i], 1); - each_blocks[i].m(each_1_anchor.parentNode, each_1_anchor); - } - } - - group_outros(); - - for (i = each_value.length; i < each_blocks.length; i += 1) { - out(i); - } - - check_outros(); - } - }, - i(local) { - if (current) return; - - for (let i = 0; i < each_value.length; i += 1) { - transition_in(each_blocks[i]); - } - - current = true; - }, - o(local) { - each_blocks = each_blocks.filter(Boolean); - - for (let i = 0; i < each_blocks.length; i += 1) { - transition_out(each_blocks[i]); - } - - current = false; - }, - d(detaching) { - destroy_each(each_blocks, detaching); - if (detaching) detach(each_1_anchor); - } - }; -} - -// (11:8) {#each self.polygons as polygon, i} -function create_each_block$3(ctx) { - let polygon; - let current; - - polygon = new Polygon({ - props: { - id: /*i*/ ctx[26], - data: /*polygon*/ ctx[24] - } - }); - - return { - c() { - create_component(polygon.$$.fragment); - }, - m(target, anchor) { - mount_component(polygon, target, anchor); - current = true; - }, - p(ctx, dirty) { - const polygon_changes = {}; - if (dirty & /*self*/ 1) polygon_changes.data = /*polygon*/ ctx[24]; - polygon.$set(polygon_changes); - }, - i(local) { - if (current) return; - transition_in(polygon.$$.fragment, local); - current = true; - }, - o(local) { - transition_out(polygon.$$.fragment, local); - current = false; - }, - d(detaching) { - destroy_component(polygon, detaching); - } - }; -} - -// (15:6) {#if self.raw} -function create_if_block_1$2(ctx) { - let raw; - let updating_data; - let current; - - function raw_data_binding(value) { - /*raw_data_binding*/ ctx[15](value); - } - - let raw_props = {}; - - if (/*self*/ ctx[0] !== void 0) { - raw_props.data = /*self*/ ctx[0]; - } - - raw = new Raw({ props: raw_props }); - binding_callbacks.push(() => bind(raw, 'data', raw_data_binding)); - - return { - c() { - create_component(raw.$$.fragment); - }, - m(target, anchor) { - mount_component(raw, target, anchor); - current = true; - }, - p(ctx, dirty) { - const raw_changes = {}; - - if (!updating_data && dirty & /*self*/ 1) { - updating_data = true; - raw_changes.data = /*self*/ ctx[0]; - add_flush_callback(() => updating_data = false); - } - - raw.$set(raw_changes); - }, - i(local) { - if (current) return; - transition_in(raw.$$.fragment, local); - current = true; - }, - o(local) { - transition_out(raw.$$.fragment, local); - current = false; - }, - d(detaching) { - destroy_component(raw, detaching); - } - }; -} - -// (3:8) -function fallback_block(ctx) { - let if_block_anchor; - let current; - let if_block = /*self*/ ctx[0] && create_if_block$4(ctx); - - return { - c() { - if (if_block) if_block.c(); - if_block_anchor = empty(); - }, - m(target, anchor) { - if (if_block) if_block.m(target, anchor); - insert(target, if_block_anchor, anchor); - current = true; - }, - p(ctx, dirty) { - if (/*self*/ ctx[0]) { - if (if_block) { - if_block.p(ctx, dirty); - - if (dirty & /*self*/ 1) { - transition_in(if_block, 1); - } - } else { - if_block = create_if_block$4(ctx); - if_block.c(); - transition_in(if_block, 1); - if_block.m(if_block_anchor.parentNode, if_block_anchor); - } - } else if (if_block) { - group_outros(); - - transition_out(if_block, 1, 1, () => { - if_block = null; - }); - - check_outros(); - } - }, - i(local) { - if (current) return; - transition_in(if_block); - current = true; - }, - o(local) { - transition_out(if_block); - current = false; - }, - d(detaching) { - if (if_block) if_block.d(detaching); - if (detaching) detach(if_block_anchor); - } - }; -} - -// (1:0) -function create_default_slot(ctx) { - let current; - const default_slot_template = /*#slots*/ ctx[14].default; - const default_slot = create_slot(default_slot_template, ctx, /*$$scope*/ ctx[16], null); - const default_slot_or_fallback = default_slot || fallback_block(ctx); - - return { - c() { - if (default_slot_or_fallback) default_slot_or_fallback.c(); - }, - m(target, anchor) { - if (default_slot_or_fallback) { - default_slot_or_fallback.m(target, anchor); - } - - current = true; - }, - p(ctx, dirty) { - if (default_slot) { - if (default_slot.p && (!current || dirty & /*$$scope*/ 65536)) { - update_slot_base( - default_slot, - default_slot_template, - ctx, - /*$$scope*/ ctx[16], - !current - ? get_all_dirty_from_scope(/*$$scope*/ ctx[16]) - : get_slot_changes(default_slot_template, /*$$scope*/ ctx[16], dirty, null), - null - ); - } - } else { - if (default_slot_or_fallback && default_slot_or_fallback.p && (!current || dirty & /*self*/ 1)) { - default_slot_or_fallback.p(ctx, !current ? -1 : dirty); - } - } - }, - i(local) { - if (current) return; - transition_in(default_slot_or_fallback, local); - current = true; - }, - o(local) { - transition_out(default_slot_or_fallback, local); - current = false; - }, - d(detaching) { - if (default_slot_or_fallback) default_slot_or_fallback.d(detaching); - } - }; -} - -function create_fragment$e(ctx) { - let svg; - let current; - - svg = new Svg({ - props: { - label: /*label*/ ctx[6], - width: /*width*/ ctx[7], - height: /*height*/ ctx[8], - box: /*box*/ ctx[10], - style: /*combinedStyle*/ ctx[9], - spin: /*spin*/ ctx[2], - flip: /*flip*/ ctx[5], - inverse: /*inverse*/ ctx[3], - pulse: /*pulse*/ ctx[4], - class: /*className*/ ctx[1], - $$slots: { default: [create_default_slot] }, - $$scope: { ctx } - } - }); - - return { - c() { - create_component(svg.$$.fragment); - }, - m(target, anchor) { - mount_component(svg, target, anchor); - current = true; - }, - p(ctx, [dirty]) { - const svg_changes = {}; - if (dirty & /*label*/ 64) svg_changes.label = /*label*/ ctx[6]; - if (dirty & /*width*/ 128) svg_changes.width = /*width*/ ctx[7]; - if (dirty & /*height*/ 256) svg_changes.height = /*height*/ ctx[8]; - if (dirty & /*box*/ 1024) svg_changes.box = /*box*/ ctx[10]; - if (dirty & /*combinedStyle*/ 512) svg_changes.style = /*combinedStyle*/ ctx[9]; - if (dirty & /*spin*/ 4) svg_changes.spin = /*spin*/ ctx[2]; - if (dirty & /*flip*/ 32) svg_changes.flip = /*flip*/ ctx[5]; - if (dirty & /*inverse*/ 8) svg_changes.inverse = /*inverse*/ ctx[3]; - if (dirty & /*pulse*/ 16) svg_changes.pulse = /*pulse*/ ctx[4]; - if (dirty & /*className*/ 2) svg_changes.class = /*className*/ ctx[1]; - - if (dirty & /*$$scope, self*/ 65537) { - svg_changes.$$scope = { dirty, ctx }; - } - - svg.$set(svg_changes); - }, - i(local) { - if (current) return; - transition_in(svg.$$.fragment, local); - current = true; - }, - o(local) { - transition_out(svg.$$.fragment, local); - current = false; - }, - d(detaching) { - destroy_component(svg, detaching); - } - }; -} -let outerScale = 1; - -function normaliseData(data) { - if ('iconName' in data && 'icon' in data) { - let normalisedData = {}; - let faIcon = data.icon; - let name = data.iconName; - let width = faIcon[0]; - let height = faIcon[1]; - let paths = faIcon[4]; - let iconData = { width, height, paths: [{ d: paths }] }; - normalisedData[name] = iconData; - return normalisedData; - } - - return data; -} - -function instance$e($$self, $$props, $$invalidate) { - let { $$slots: slots = {}, $$scope } = $$props; - let { class: className = "" } = $$props; - let { data } = $$props; - let { scale = 1 } = $$props; - let { spin = false } = $$props; - let { inverse = false } = $$props; - let { pulse = false } = $$props; - let { flip = null } = $$props; - let { label = null } = $$props; - let { self = null } = $$props; - let { style = null } = $$props; - let width; - let height; - let combinedStyle; - let box; - - function init() { - if (typeof data === 'undefined') { - return; - } - - const normalisedData = normaliseData(data); - const [name] = Object.keys(normalisedData); - const icon = normalisedData[name]; - - if (!icon.paths) { - icon.paths = []; - } - - if (icon.d) { - icon.paths.push({ d: icon.d }); - } - - if (!icon.polygons) { - icon.polygons = []; - } - - if (icon.points) { - icon.polygons.push({ points: icon.points }); - } - - $$invalidate(0, self = icon); - } - - function normalisedScale() { - let numScale = 1; - - if (typeof scale !== 'undefined') { - numScale = Number(scale); - } - - if (isNaN(numScale) || numScale <= 0) { - // eslint-disable-line no-restricted-globals - console.warn('Invalid prop: prop "scale" should be a number over 0.'); // eslint-disable-line no-console - - return outerScale; - } - - return numScale * outerScale; - } - - function calculateBox() { - if (self) { - return `0 0 ${self.width} ${self.height}`; - } - - return `0 0 ${width} ${height}`; - } - - function calculateRatio() { - if (!self) { - return 1; - } - - return Math.max(self.width, self.height) / 16; - } - - function calculateWidth() { - - if (self) { - return self.width / calculateRatio() * normalisedScale(); - } - - return 0; - } - - function calculateHeight() { - - if (self) { - return self.height / calculateRatio() * normalisedScale(); - } - - return 0; - } - - function calculateStyle() { - let combined = ""; - - if (style !== null) { - combined += style; - } - - let size = normalisedScale(); - - if (size === 1) { - if (combined.length === 0) { - return undefined; - } - - return combined; - } - - if (combined !== "" && !combined.endsWith(';')) { - combined += '; '; - } - - return `${combined}font-size: ${size}em`; - } - - function raw_data_binding(value) { - self = value; - $$invalidate(0, self); - } - - $$self.$$set = $$props => { - if ('class' in $$props) $$invalidate(1, className = $$props.class); - if ('data' in $$props) $$invalidate(11, data = $$props.data); - if ('scale' in $$props) $$invalidate(12, scale = $$props.scale); - if ('spin' in $$props) $$invalidate(2, spin = $$props.spin); - if ('inverse' in $$props) $$invalidate(3, inverse = $$props.inverse); - if ('pulse' in $$props) $$invalidate(4, pulse = $$props.pulse); - if ('flip' in $$props) $$invalidate(5, flip = $$props.flip); - if ('label' in $$props) $$invalidate(6, label = $$props.label); - if ('self' in $$props) $$invalidate(0, self = $$props.self); - if ('style' in $$props) $$invalidate(13, style = $$props.style); - if ('$$scope' in $$props) $$invalidate(16, $$scope = $$props.$$scope); - }; - - $$self.$$.update = () => { - if ($$self.$$.dirty & /*data, style, scale*/ 14336) { - { - init(); - $$invalidate(7, width = calculateWidth()); - $$invalidate(8, height = calculateHeight()); - $$invalidate(9, combinedStyle = calculateStyle()); - $$invalidate(10, box = calculateBox()); - } - } - }; - - return [ - self, - className, - spin, - inverse, - pulse, - flip, - label, - width, - height, - combinedStyle, - box, - data, - scale, - style, - slots, - raw_data_binding, - $$scope - ]; -} - -class Icon extends SvelteComponent { - constructor(options) { - super(); - - init(this, options, instance$e, create_fragment$e, safe_not_equal, { - class: 1, - data: 11, - scale: 12, - spin: 2, - inverse: 3, - pulse: 4, - flip: 5, - label: 6, - self: 0, - style: 13 - }); - } -} - -/* src/gui/choiceList/ChoiceItemRightButtons.svelte generated by Svelte v3.43.0 */ - -function add_css$9(target) { - append_styles(target, "svelte-a47k80", ".rightButtonsContainer.svelte-a47k80{display:flex;align-items:center;gap:8px}.clickable.svelte-a47k80:hover{cursor:pointer}.alignIconInDivInMiddle.svelte-a47k80{display:flex;align-items:center}"); -} - -// (24:4) {#if showConfigureButton} -function create_if_block$3(ctx) { - let div; - let icon; - let div_aria_label_value; - let current; - let mounted; - let dispose; - icon = new Icon({ props: { data: faCog } }); - - return { - c() { - div = element("div"); - create_component(icon.$$.fragment); - attr(div, "class", "alignIconInDivInMiddle clickable svelte-a47k80"); - attr(div, "aria-label", div_aria_label_value = `Configure${/*choiceName*/ ctx[3] ? " " + /*choiceName*/ ctx[3] : ""}`); - }, - m(target, anchor) { - insert(target, div, anchor); - mount_component(icon, div, null); - current = true; - - if (!mounted) { - dispose = listen(div, "click", /*emitConfigureChoice*/ ctx[5]); - mounted = true; - } - }, - p(ctx, dirty) { - if (!current || dirty & /*choiceName*/ 8 && div_aria_label_value !== (div_aria_label_value = `Configure${/*choiceName*/ ctx[3] ? " " + /*choiceName*/ ctx[3] : ""}`)) { - attr(div, "aria-label", div_aria_label_value); - } - }, - i(local) { - if (current) return; - transition_in(icon.$$.fragment, local); - current = true; - }, - o(local) { - transition_out(icon.$$.fragment, local); - current = false; - }, - d(detaching) { - if (detaching) detach(div); - destroy_component(icon); - mounted = false; - dispose(); - } - }; -} - -function create_fragment$d(ctx) { - let div3; - let div0; - let icon0; - let div0_aria_label_value; - let div0_style_value; - let t0; - let t1; - let div1; - let icon1; - let div1_aria_label_value; - let t2; - let div2; - let icon2; - let div2_tabindex_value; - let div2_style_value; - let current; - let mounted; - let dispose; - icon0 = new Icon({ props: { data: faBolt } }); - let if_block = /*showConfigureButton*/ ctx[1] && create_if_block$3(ctx); - icon1 = new Icon({ props: { data: faTrash } }); - icon2 = new Icon({ props: { data: faBars } }); - - return { - c() { - div3 = element("div"); - div0 = element("div"); - create_component(icon0.$$.fragment); - t0 = space(); - if (if_block) if_block.c(); - t1 = space(); - div1 = element("div"); - create_component(icon1.$$.fragment); - t2 = space(); - div2 = element("div"); - create_component(icon2.$$.fragment); - attr(div0, "class", "alignIconInDivInMiddle clickable svelte-a47k80"); - - attr(div0, "aria-label", div0_aria_label_value = `${/*commandEnabled*/ ctx[2] ? "Remove" : "Add"} command${/*choiceName*/ ctx[3] - ? " for " + /*choiceName*/ ctx[3] - : ""}`); - - attr(div0, "style", div0_style_value = /*commandEnabled*/ ctx[2] ? "color: #FDD023;" : ""); - attr(div1, "aria-label", div1_aria_label_value = `Delete${/*choiceName*/ ctx[3] ? " " + /*choiceName*/ ctx[3] : ""}`); - attr(div1, "class", "alignIconInDivInMiddle clickable svelte-a47k80"); - attr(div2, "tabindex", div2_tabindex_value = /*dragDisabled*/ ctx[0] ? 0 : -1); - attr(div2, "aria-label", "Drag-handle"); - - attr(div2, "style", div2_style_value = "" + ((/*dragDisabled*/ ctx[0] - ? 'cursor: grab' - : 'cursor: grabbing') + ";")); - - attr(div2, "class", "alignIconInDivInMiddle svelte-a47k80"); - attr(div3, "class", "rightButtonsContainer svelte-a47k80"); - }, - m(target, anchor) { - insert(target, div3, anchor); - append(div3, div0); - mount_component(icon0, div0, null); - append(div3, t0); - if (if_block) if_block.m(div3, null); - append(div3, t1); - append(div3, div1); - mount_component(icon1, div1, null); - append(div3, t2); - append(div3, div2); - mount_component(icon2, div2, null); - current = true; - - if (!mounted) { - dispose = [ - listen(div0, "click", /*emitToggleCommand*/ ctx[6]), - listen(div1, "click", /*emitDeleteChoice*/ ctx[4]), - listen(div2, "mousedown", /*mousedown_handler*/ ctx[7]), - listen(div2, "touchstart", /*touchstart_handler*/ ctx[8]) - ]; - - mounted = true; - } - }, - p(ctx, [dirty]) { - if (!current || dirty & /*commandEnabled, choiceName*/ 12 && div0_aria_label_value !== (div0_aria_label_value = `${/*commandEnabled*/ ctx[2] ? "Remove" : "Add"} command${/*choiceName*/ ctx[3] - ? " for " + /*choiceName*/ ctx[3] - : ""}`)) { - attr(div0, "aria-label", div0_aria_label_value); - } - - if (!current || dirty & /*commandEnabled*/ 4 && div0_style_value !== (div0_style_value = /*commandEnabled*/ ctx[2] ? "color: #FDD023;" : "")) { - attr(div0, "style", div0_style_value); - } - - if (/*showConfigureButton*/ ctx[1]) { - if (if_block) { - if_block.p(ctx, dirty); - - if (dirty & /*showConfigureButton*/ 2) { - transition_in(if_block, 1); - } - } else { - if_block = create_if_block$3(ctx); - if_block.c(); - transition_in(if_block, 1); - if_block.m(div3, t1); - } - } else if (if_block) { - group_outros(); - - transition_out(if_block, 1, 1, () => { - if_block = null; - }); - - check_outros(); - } - - if (!current || dirty & /*choiceName*/ 8 && div1_aria_label_value !== (div1_aria_label_value = `Delete${/*choiceName*/ ctx[3] ? " " + /*choiceName*/ ctx[3] : ""}`)) { - attr(div1, "aria-label", div1_aria_label_value); - } - - if (!current || dirty & /*dragDisabled*/ 1 && div2_tabindex_value !== (div2_tabindex_value = /*dragDisabled*/ ctx[0] ? 0 : -1)) { - attr(div2, "tabindex", div2_tabindex_value); - } - - if (!current || dirty & /*dragDisabled*/ 1 && div2_style_value !== (div2_style_value = "" + ((/*dragDisabled*/ ctx[0] - ? 'cursor: grab' - : 'cursor: grabbing') + ";"))) { - attr(div2, "style", div2_style_value); - } - }, - i(local) { - if (current) return; - transition_in(icon0.$$.fragment, local); - transition_in(if_block); - transition_in(icon1.$$.fragment, local); - transition_in(icon2.$$.fragment, local); - current = true; - }, - o(local) { - transition_out(icon0.$$.fragment, local); - transition_out(if_block); - transition_out(icon1.$$.fragment, local); - transition_out(icon2.$$.fragment, local); - current = false; - }, - d(detaching) { - if (detaching) detach(div3); - destroy_component(icon0); - if (if_block) if_block.d(); - destroy_component(icon1); - destroy_component(icon2); - mounted = false; - run_all(dispose); - } - }; -} - -function instance$d($$self, $$props, $$invalidate) { - let { dragDisabled } = $$props; - let { showConfigureButton = true } = $$props; - let { commandEnabled = false } = $$props; - let { choiceName = "" } = $$props; - const dispatcher = createEventDispatcher(); - - function emitDeleteChoice() { - dispatcher('deleteChoice'); - } - - function emitConfigureChoice() { - dispatcher('configureChoice'); - } - - function emitToggleCommand() { - dispatcher('toggleCommand'); - } - - function mousedown_handler(event) { - bubble.call(this, $$self, event); - } - - function touchstart_handler(event) { - bubble.call(this, $$self, event); - } - - $$self.$$set = $$props => { - if ('dragDisabled' in $$props) $$invalidate(0, dragDisabled = $$props.dragDisabled); - if ('showConfigureButton' in $$props) $$invalidate(1, showConfigureButton = $$props.showConfigureButton); - if ('commandEnabled' in $$props) $$invalidate(2, commandEnabled = $$props.commandEnabled); - if ('choiceName' in $$props) $$invalidate(3, choiceName = $$props.choiceName); - }; - - return [ - dragDisabled, - showConfigureButton, - commandEnabled, - choiceName, - emitDeleteChoice, - emitConfigureChoice, - emitToggleCommand, - mousedown_handler, - touchstart_handler - ]; -} - -class ChoiceItemRightButtons extends SvelteComponent { - constructor(options) { - super(); - - init( - this, - options, - instance$d, - create_fragment$d, - safe_not_equal, - { - dragDisabled: 0, - showConfigureButton: 1, - commandEnabled: 2, - choiceName: 3 - }, - add_css$9 - ); - } -} - -/* src/gui/choiceList/ChoiceListItem.svelte generated by Svelte v3.43.0 */ - -function add_css$8(target) { - append_styles(target, "svelte-1vcfikc", ".choiceListItem.svelte-1vcfikc{display:flex;font-size:16px;align-items:center;margin:12px 0 0 0;transition:1000ms ease-in-out}.choiceListItemName.svelte-1vcfikc{flex:1 0 0}"); -} - -function create_fragment$c(ctx) { - let div; - let span; - let t0_value = /*choice*/ ctx[0].name + ""; - let t0; - let t1; - let rightbuttons; - let updating_choiceName; - let updating_commandEnabled; - let updating_showConfigureButton; - let updating_dragDisabled; - let current; - - function rightbuttons_choiceName_binding(value) { - /*rightbuttons_choiceName_binding*/ ctx[6](value); - } - - function rightbuttons_commandEnabled_binding(value) { - /*rightbuttons_commandEnabled_binding*/ ctx[7](value); - } - - function rightbuttons_showConfigureButton_binding(value) { - /*rightbuttons_showConfigureButton_binding*/ ctx[8](value); - } - - function rightbuttons_dragDisabled_binding(value) { - /*rightbuttons_dragDisabled_binding*/ ctx[9](value); - } - - let rightbuttons_props = {}; - - if (/*choice*/ ctx[0].name !== void 0) { - rightbuttons_props.choiceName = /*choice*/ ctx[0].name; - } - - if (/*choice*/ ctx[0].command !== void 0) { - rightbuttons_props.commandEnabled = /*choice*/ ctx[0].command; - } - - if (/*showConfigureButton*/ ctx[2] !== void 0) { - rightbuttons_props.showConfigureButton = /*showConfigureButton*/ ctx[2]; - } - - if (/*dragDisabled*/ ctx[1] !== void 0) { - rightbuttons_props.dragDisabled = /*dragDisabled*/ ctx[1]; - } - - rightbuttons = new ChoiceItemRightButtons({ props: rightbuttons_props }); - binding_callbacks.push(() => bind(rightbuttons, 'choiceName', rightbuttons_choiceName_binding)); - binding_callbacks.push(() => bind(rightbuttons, 'commandEnabled', rightbuttons_commandEnabled_binding)); - binding_callbacks.push(() => bind(rightbuttons, 'showConfigureButton', rightbuttons_showConfigureButton_binding)); - binding_callbacks.push(() => bind(rightbuttons, 'dragDisabled', rightbuttons_dragDisabled_binding)); - rightbuttons.$on("mousedown", /*mousedown_handler*/ ctx[10]); - rightbuttons.$on("touchstart", /*touchstart_handler*/ ctx[11]); - rightbuttons.$on("deleteChoice", /*deleteChoice*/ ctx[3]); - rightbuttons.$on("configureChoice", /*configureChoice*/ ctx[4]); - rightbuttons.$on("toggleCommand", /*toggleCommandForChoice*/ ctx[5]); - - return { - c() { - div = element("div"); - span = element("span"); - t0 = text(t0_value); - t1 = space(); - create_component(rightbuttons.$$.fragment); - attr(span, "class", "choiceListItemName svelte-1vcfikc"); - attr(div, "class", "choiceListItem svelte-1vcfikc"); - }, - m(target, anchor) { - insert(target, div, anchor); - append(div, span); - append(span, t0); - append(div, t1); - mount_component(rightbuttons, div, null); - current = true; - }, - p(ctx, [dirty]) { - if ((!current || dirty & /*choice*/ 1) && t0_value !== (t0_value = /*choice*/ ctx[0].name + "")) set_data(t0, t0_value); - const rightbuttons_changes = {}; - - if (!updating_choiceName && dirty & /*choice*/ 1) { - updating_choiceName = true; - rightbuttons_changes.choiceName = /*choice*/ ctx[0].name; - add_flush_callback(() => updating_choiceName = false); - } - - if (!updating_commandEnabled && dirty & /*choice*/ 1) { - updating_commandEnabled = true; - rightbuttons_changes.commandEnabled = /*choice*/ ctx[0].command; - add_flush_callback(() => updating_commandEnabled = false); - } - - if (!updating_showConfigureButton && dirty & /*showConfigureButton*/ 4) { - updating_showConfigureButton = true; - rightbuttons_changes.showConfigureButton = /*showConfigureButton*/ ctx[2]; - add_flush_callback(() => updating_showConfigureButton = false); - } - - if (!updating_dragDisabled && dirty & /*dragDisabled*/ 2) { - updating_dragDisabled = true; - rightbuttons_changes.dragDisabled = /*dragDisabled*/ ctx[1]; - add_flush_callback(() => updating_dragDisabled = false); - } - - rightbuttons.$set(rightbuttons_changes); - }, - i(local) { - if (current) return; - transition_in(rightbuttons.$$.fragment, local); - current = true; - }, - o(local) { - transition_out(rightbuttons.$$.fragment, local); - current = false; - }, - d(detaching) { - if (detaching) detach(div); - destroy_component(rightbuttons); - } - }; -} - -function instance$c($$self, $$props, $$invalidate) { - let { choice } = $$props; - let { dragDisabled } = $$props; - let showConfigureButton = true; - const dispatcher = createEventDispatcher(); - - function deleteChoice() { - dispatcher('deleteChoice', { choice }); - } - - function configureChoice() { - dispatcher('configureChoice', { choice }); - } - - function toggleCommandForChoice() { - dispatcher('toggleCommand', { choice }); - } - - function rightbuttons_choiceName_binding(value) { - if ($$self.$$.not_equal(choice.name, value)) { - choice.name = value; - $$invalidate(0, choice); - } - } - - function rightbuttons_commandEnabled_binding(value) { - if ($$self.$$.not_equal(choice.command, value)) { - choice.command = value; - $$invalidate(0, choice); - } - } - - function rightbuttons_showConfigureButton_binding(value) { - showConfigureButton = value; - $$invalidate(2, showConfigureButton); - } - - function rightbuttons_dragDisabled_binding(value) { - dragDisabled = value; - $$invalidate(1, dragDisabled); - } - - function mousedown_handler(event) { - bubble.call(this, $$self, event); - } - - function touchstart_handler(event) { - bubble.call(this, $$self, event); - } - - $$self.$$set = $$props => { - if ('choice' in $$props) $$invalidate(0, choice = $$props.choice); - if ('dragDisabled' in $$props) $$invalidate(1, dragDisabled = $$props.dragDisabled); - }; - - return [ - choice, - dragDisabled, - showConfigureButton, - deleteChoice, - configureChoice, - toggleCommandForChoice, - rightbuttons_choiceName_binding, - rightbuttons_commandEnabled_binding, - rightbuttons_showConfigureButton_binding, - rightbuttons_dragDisabled_binding, - mousedown_handler, - touchstart_handler - ]; -} - -class ChoiceListItem extends SvelteComponent { - constructor(options) { - super(); - init(this, options, instance$c, create_fragment$c, safe_not_equal, { choice: 0, dragDisabled: 1 }, add_css$8); - } -} - -/* src/gui/choiceList/MultiChoiceListItem.svelte generated by Svelte v3.43.0 */ - -function add_css$7(target) { - append_styles(target, "svelte-na99np", ".multiChoiceListItem.svelte-na99np{display:flex;font-size:16px;align-items:center;margin:12px 0 0 0}.clickable.svelte-na99np:hover{cursor:pointer}.multiChoiceListItemName.svelte-na99np{flex:1 0 0;margin-left:5px}.nestedChoiceList.svelte-na99np{padding-left:25px}"); -} - -// (43:4) {#if !collapseId || (collapseId && choice.id !== collapseId)} -function create_if_block$2(ctx) { - let if_block_anchor; - let current; - let if_block = !/*choice*/ ctx[0].collapsed && create_if_block_1$1(ctx); - - return { - c() { - if (if_block) if_block.c(); - if_block_anchor = empty(); - }, - m(target, anchor) { - if (if_block) if_block.m(target, anchor); - insert(target, if_block_anchor, anchor); - current = true; - }, - p(ctx, dirty) { - if (!/*choice*/ ctx[0].collapsed) { - if (if_block) { - if_block.p(ctx, dirty); - - if (dirty & /*choice*/ 1) { - transition_in(if_block, 1); - } - } else { - if_block = create_if_block_1$1(ctx); - if_block.c(); - transition_in(if_block, 1); - if_block.m(if_block_anchor.parentNode, if_block_anchor); - } - } else if (if_block) { - group_outros(); - - transition_out(if_block, 1, 1, () => { - if_block = null; - }); - - check_outros(); - } - }, - i(local) { - if (current) return; - transition_in(if_block); - current = true; - }, - o(local) { - transition_out(if_block); - current = false; - }, - d(detaching) { - if (if_block) if_block.d(detaching); - if (detaching) detach(if_block_anchor); - } - }; -} - -// (44:8) {#if !choice.collapsed} -function create_if_block_1$1(ctx) { - let div; - let choicelist; - let updating_multiChoice; - let updating_choices; - let current; - - function choicelist_multiChoice_binding(value) { - /*choicelist_multiChoice_binding*/ ctx[14](value); - } - - function choicelist_choices_binding(value) { - /*choicelist_choices_binding*/ ctx[15](value); - } - - let choicelist_props = {}; - - if (/*choice*/ ctx[0] !== void 0) { - choicelist_props.multiChoice = /*choice*/ ctx[0]; - } - - if (/*choice*/ ctx[0].choices !== void 0) { - choicelist_props.choices = /*choice*/ ctx[0].choices; - } - - choicelist = new ChoiceList({ props: choicelist_props }); - binding_callbacks.push(() => bind(choicelist, 'multiChoice', choicelist_multiChoice_binding)); - binding_callbacks.push(() => bind(choicelist, 'choices', choicelist_choices_binding)); - choicelist.$on("deleteChoice", /*deleteChoice_handler*/ ctx[16]); - choicelist.$on("configureChoice", /*configureChoice_handler*/ ctx[17]); - choicelist.$on("toggleCommand", /*toggleCommand_handler*/ ctx[18]); - - return { - c() { - div = element("div"); - create_component(choicelist.$$.fragment); - attr(div, "class", "nestedChoiceList svelte-na99np"); - }, - m(target, anchor) { - insert(target, div, anchor); - mount_component(choicelist, div, null); - current = true; - }, - p(ctx, dirty) { - const choicelist_changes = {}; - - if (!updating_multiChoice && dirty & /*choice*/ 1) { - updating_multiChoice = true; - choicelist_changes.multiChoice = /*choice*/ ctx[0]; - add_flush_callback(() => updating_multiChoice = false); - } - - if (!updating_choices && dirty & /*choice*/ 1) { - updating_choices = true; - choicelist_changes.choices = /*choice*/ ctx[0].choices; - add_flush_callback(() => updating_choices = false); - } - - choicelist.$set(choicelist_changes); - }, - i(local) { - if (current) return; - transition_in(choicelist.$$.fragment, local); - current = true; - }, - o(local) { - transition_out(choicelist.$$.fragment, local); - current = false; - }, - d(detaching) { - if (detaching) detach(div); - destroy_component(choicelist); - } - }; -} - -function create_fragment$b(ctx) { - let div2; - let div1; - let div0; - let icon; - let t0; - let span; - let t1_value = /*choice*/ ctx[0].name + ""; - let t1; - let t2; - let rightbuttons; - let updating_showConfigureButton; - let updating_dragDisabled; - let updating_choiceName; - let updating_commandEnabled; - let t3; - let current; - let mounted; - let dispose; - - icon = new Icon({ - props: { - data: faChevronDown, - style: `transform:rotate(${/*choice*/ ctx[0].collapsed ? -180 : 0}deg)` - } - }); - - function rightbuttons_showConfigureButton_binding(value) { - /*rightbuttons_showConfigureButton_binding*/ ctx[8](value); - } - - function rightbuttons_dragDisabled_binding(value) { - /*rightbuttons_dragDisabled_binding*/ ctx[9](value); - } - - function rightbuttons_choiceName_binding(value) { - /*rightbuttons_choiceName_binding*/ ctx[10](value); - } - - function rightbuttons_commandEnabled_binding(value) { - /*rightbuttons_commandEnabled_binding*/ ctx[11](value); - } - - let rightbuttons_props = {}; - - if (/*showConfigureButton*/ ctx[3] !== void 0) { - rightbuttons_props.showConfigureButton = /*showConfigureButton*/ ctx[3]; - } - - if (/*dragDisabled*/ ctx[1] !== void 0) { - rightbuttons_props.dragDisabled = /*dragDisabled*/ ctx[1]; - } - - if (/*choice*/ ctx[0].name !== void 0) { - rightbuttons_props.choiceName = /*choice*/ ctx[0].name; - } - - if (/*choice*/ ctx[0].command !== void 0) { - rightbuttons_props.commandEnabled = /*choice*/ ctx[0].command; - } - - rightbuttons = new ChoiceItemRightButtons({ props: rightbuttons_props }); - binding_callbacks.push(() => bind(rightbuttons, 'showConfigureButton', rightbuttons_showConfigureButton_binding)); - binding_callbacks.push(() => bind(rightbuttons, 'dragDisabled', rightbuttons_dragDisabled_binding)); - binding_callbacks.push(() => bind(rightbuttons, 'choiceName', rightbuttons_choiceName_binding)); - binding_callbacks.push(() => bind(rightbuttons, 'commandEnabled', rightbuttons_commandEnabled_binding)); - rightbuttons.$on("mousedown", /*mousedown_handler*/ ctx[12]); - rightbuttons.$on("touchstart", /*touchstart_handler*/ ctx[13]); - rightbuttons.$on("deleteChoice", /*deleteChoice*/ ctx[4]); - rightbuttons.$on("configureChoice", /*configureChoice*/ ctx[5]); - rightbuttons.$on("toggleCommand", /*toggleCommandForChoice*/ ctx[6]); - let if_block = (!/*collapseId*/ ctx[2] || /*collapseId*/ ctx[2] && /*choice*/ ctx[0].id !== /*collapseId*/ ctx[2]) && create_if_block$2(ctx); - - return { - c() { - div2 = element("div"); - div1 = element("div"); - div0 = element("div"); - create_component(icon.$$.fragment); - t0 = space(); - span = element("span"); - t1 = text(t1_value); - t2 = space(); - create_component(rightbuttons.$$.fragment); - t3 = space(); - if (if_block) if_block.c(); - attr(div0, "class", "multiChoiceListItemName clickable svelte-na99np"); - attr(div1, "class", "multiChoiceListItem svelte-na99np"); - }, - m(target, anchor) { - insert(target, div2, anchor); - append(div2, div1); - append(div1, div0); - mount_component(icon, div0, null); - append(div0, t0); - append(div0, span); - append(span, t1); - append(div1, t2); - mount_component(rightbuttons, div1, null); - append(div2, t3); - if (if_block) if_block.m(div2, null); - current = true; - - if (!mounted) { - dispose = listen(div0, "click", /*click_handler*/ ctx[7]); - mounted = true; - } - }, - p(ctx, [dirty]) { - const icon_changes = {}; - if (dirty & /*choice*/ 1) icon_changes.style = `transform:rotate(${/*choice*/ ctx[0].collapsed ? -180 : 0}deg)`; - icon.$set(icon_changes); - if ((!current || dirty & /*choice*/ 1) && t1_value !== (t1_value = /*choice*/ ctx[0].name + "")) set_data(t1, t1_value); - const rightbuttons_changes = {}; - - if (!updating_showConfigureButton && dirty & /*showConfigureButton*/ 8) { - updating_showConfigureButton = true; - rightbuttons_changes.showConfigureButton = /*showConfigureButton*/ ctx[3]; - add_flush_callback(() => updating_showConfigureButton = false); - } - - if (!updating_dragDisabled && dirty & /*dragDisabled*/ 2) { - updating_dragDisabled = true; - rightbuttons_changes.dragDisabled = /*dragDisabled*/ ctx[1]; - add_flush_callback(() => updating_dragDisabled = false); - } - - if (!updating_choiceName && dirty & /*choice*/ 1) { - updating_choiceName = true; - rightbuttons_changes.choiceName = /*choice*/ ctx[0].name; - add_flush_callback(() => updating_choiceName = false); - } - - if (!updating_commandEnabled && dirty & /*choice*/ 1) { - updating_commandEnabled = true; - rightbuttons_changes.commandEnabled = /*choice*/ ctx[0].command; - add_flush_callback(() => updating_commandEnabled = false); - } - - rightbuttons.$set(rightbuttons_changes); - - if (!/*collapseId*/ ctx[2] || /*collapseId*/ ctx[2] && /*choice*/ ctx[0].id !== /*collapseId*/ ctx[2]) { - if (if_block) { - if_block.p(ctx, dirty); - - if (dirty & /*collapseId, choice*/ 5) { - transition_in(if_block, 1); - } - } else { - if_block = create_if_block$2(ctx); - if_block.c(); - transition_in(if_block, 1); - if_block.m(div2, null); - } - } else if (if_block) { - group_outros(); - - transition_out(if_block, 1, 1, () => { - if_block = null; - }); - - check_outros(); - } - }, - i(local) { - if (current) return; - transition_in(icon.$$.fragment, local); - transition_in(rightbuttons.$$.fragment, local); - transition_in(if_block); - current = true; - }, - o(local) { - transition_out(icon.$$.fragment, local); - transition_out(rightbuttons.$$.fragment, local); - transition_out(if_block); - current = false; - }, - d(detaching) { - if (detaching) detach(div2); - destroy_component(icon); - destroy_component(rightbuttons); - if (if_block) if_block.d(); - mounted = false; - dispose(); - } - }; -} - -function instance$b($$self, $$props, $$invalidate) { - let { choice } = $$props; - let { collapseId } = $$props; - let { dragDisabled } = $$props; - let showConfigureButton = true; - const dispatcher = createEventDispatcher(); - - function deleteChoice(e) { - dispatcher('deleteChoice', { choice }); - } - - function configureChoice() { - dispatcher('configureChoice', { choice }); - } - - function toggleCommandForChoice() { - dispatcher('toggleCommand', { choice }); - } - - const click_handler = () => $$invalidate(0, choice.collapsed = !choice.collapsed, choice); - - function rightbuttons_showConfigureButton_binding(value) { - showConfigureButton = value; - $$invalidate(3, showConfigureButton); - } - - function rightbuttons_dragDisabled_binding(value) { - dragDisabled = value; - $$invalidate(1, dragDisabled); - } - - function rightbuttons_choiceName_binding(value) { - if ($$self.$$.not_equal(choice.name, value)) { - choice.name = value; - $$invalidate(0, choice); - } - } - - function rightbuttons_commandEnabled_binding(value) { - if ($$self.$$.not_equal(choice.command, value)) { - choice.command = value; - $$invalidate(0, choice); - } - } - - function mousedown_handler(event) { - bubble.call(this, $$self, event); - } - - function touchstart_handler(event) { - bubble.call(this, $$self, event); - } - - function choicelist_multiChoice_binding(value) { - choice = value; - $$invalidate(0, choice); - } - - function choicelist_choices_binding(value) { - if ($$self.$$.not_equal(choice.choices, value)) { - choice.choices = value; - $$invalidate(0, choice); - } - } - - function deleteChoice_handler(event) { - bubble.call(this, $$self, event); - } - - function configureChoice_handler(event) { - bubble.call(this, $$self, event); - } - - function toggleCommand_handler(event) { - bubble.call(this, $$self, event); - } - - $$self.$$set = $$props => { - if ('choice' in $$props) $$invalidate(0, choice = $$props.choice); - if ('collapseId' in $$props) $$invalidate(2, collapseId = $$props.collapseId); - if ('dragDisabled' in $$props) $$invalidate(1, dragDisabled = $$props.dragDisabled); - }; - - return [ - choice, - dragDisabled, - collapseId, - showConfigureButton, - deleteChoice, - configureChoice, - toggleCommandForChoice, - click_handler, - rightbuttons_showConfigureButton_binding, - rightbuttons_dragDisabled_binding, - rightbuttons_choiceName_binding, - rightbuttons_commandEnabled_binding, - mousedown_handler, - touchstart_handler, - choicelist_multiChoice_binding, - choicelist_choices_binding, - deleteChoice_handler, - configureChoice_handler, - toggleCommand_handler - ]; -} - -class MultiChoiceListItem extends SvelteComponent { - constructor(options) { - super(); - - init( - this, - options, - instance$b, - create_fragment$b, - safe_not_equal, - { - choice: 0, - collapseId: 2, - dragDisabled: 1 - }, - add_css$7 - ); - } -} - -function _typeof(obj) { - "@babel/helpers - typeof"; - - if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { - _typeof = function (obj) { - return typeof obj; - }; - } else { - _typeof = function (obj) { - return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; - }; - } - - return _typeof(obj); -} - -function _defineProperty(obj, key, value) { - if (key in obj) { - Object.defineProperty(obj, key, { - value: value, - enumerable: true, - configurable: true, - writable: true - }); - } else { - obj[key] = value; - } - - return obj; -} - -function ownKeys(object, enumerableOnly) { - var keys = Object.keys(object); - - if (Object.getOwnPropertySymbols) { - var symbols = Object.getOwnPropertySymbols(object); - if (enumerableOnly) symbols = symbols.filter(function (sym) { - return Object.getOwnPropertyDescriptor(object, sym).enumerable; - }); - keys.push.apply(keys, symbols); - } - - return keys; -} - -function _objectSpread2(target) { - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i] != null ? arguments[i] : {}; - - if (i % 2) { - ownKeys(Object(source), true).forEach(function (key) { - _defineProperty(target, key, source[key]); - }); - } else if (Object.getOwnPropertyDescriptors) { - Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); - } else { - ownKeys(Object(source)).forEach(function (key) { - Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); - }); - } - } - - return target; -} - -function _objectWithoutPropertiesLoose(source, excluded) { - if (source == null) return {}; - var target = {}; - var sourceKeys = Object.keys(source); - var key, i; - - for (i = 0; i < sourceKeys.length; i++) { - key = sourceKeys[i]; - if (excluded.indexOf(key) >= 0) continue; - target[key] = source[key]; - } - - return target; -} - -function _objectWithoutProperties(source, excluded) { - if (source == null) return {}; - - var target = _objectWithoutPropertiesLoose(source, excluded); - - var key, i; - - if (Object.getOwnPropertySymbols) { - var sourceSymbolKeys = Object.getOwnPropertySymbols(source); - - for (i = 0; i < sourceSymbolKeys.length; i++) { - key = sourceSymbolKeys[i]; - if (excluded.indexOf(key) >= 0) continue; - if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; - target[key] = source[key]; - } - } - - return target; -} - -function _slicedToArray(arr, i) { - return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); -} - -function _toConsumableArray(arr) { - return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); -} - -function _arrayWithoutHoles(arr) { - if (Array.isArray(arr)) return _arrayLikeToArray(arr); -} - -function _arrayWithHoles(arr) { - if (Array.isArray(arr)) return arr; -} - -function _iterableToArray(iter) { - if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); -} - -function _iterableToArrayLimit(arr, i) { - if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; - var _arr = []; - var _n = true; - var _d = false; - var _e = undefined; - - try { - for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { - _arr.push(_s.value); - - if (i && _arr.length === i) break; - } - } catch (err) { - _d = true; - _e = err; - } finally { - try { - if (!_n && _i["return"] != null) _i["return"](); - } finally { - if (_d) throw _e; - } - } - - return _arr; -} - -function _unsupportedIterableToArray(o, minLen) { - if (!o) return; - if (typeof o === "string") return _arrayLikeToArray(o, minLen); - var n = Object.prototype.toString.call(o).slice(8, -1); - if (n === "Object" && o.constructor) n = o.constructor.name; - if (n === "Map" || n === "Set") return Array.from(o); - if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); -} - -function _arrayLikeToArray(arr, len) { - if (len == null || len > arr.length) len = arr.length; - - for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; - - return arr2; -} - -function _nonIterableSpread() { - throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); -} - -function _nonIterableRest() { - throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); -} - -function _createForOfIteratorHelper(o, allowArrayLike) { - var it; - - if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { - if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { - if (it) o = it; - var i = 0; - - var F = function () {}; - - return { - s: F, - n: function () { - if (i >= o.length) return { - done: true - }; - return { - done: false, - value: o[i++] - }; - }, - e: function (e) { - throw e; - }, - f: F - }; - } - - throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); - } - - var normalCompletion = true, - didErr = false, - err; - return { - s: function () { - it = o[Symbol.iterator](); - }, - n: function () { - var step = it.next(); - normalCompletion = step.done; - return step; - }, - e: function (e) { - didErr = true; - err = e; - }, - f: function () { - try { - if (!normalCompletion && it.return != null) it.return(); - } finally { - if (didErr) throw err; - } - } - }; -} - -// external events -var FINALIZE_EVENT_NAME = "finalize"; -var CONSIDER_EVENT_NAME = "consider"; -/** - * @typedef {Object} Info - * @property {string} trigger - * @property {string} id - * @property {string} source - * @param {Node} el - * @param {Array} items - * @param {Info} info - */ - -function dispatchFinalizeEvent(el, items, info) { - el.dispatchEvent(new CustomEvent(FINALIZE_EVENT_NAME, { - detail: { - items: items, - info: info - } - })); -} -/** - * Dispatches a consider event - * @param {Node} el - * @param {Array} items - * @param {Info} info - */ - -function dispatchConsiderEvent(el, items, info) { - el.dispatchEvent(new CustomEvent(CONSIDER_EVENT_NAME, { - detail: { - items: items, - info: info - } - })); -} // internal events - -var DRAGGED_ENTERED_EVENT_NAME = "draggedEntered"; -var DRAGGED_LEFT_EVENT_NAME = "draggedLeft"; -var DRAGGED_OVER_INDEX_EVENT_NAME = "draggedOverIndex"; -var DRAGGED_LEFT_DOCUMENT_EVENT_NAME = "draggedLeftDocument"; -var DRAGGED_LEFT_TYPES = { - LEFT_FOR_ANOTHER: "leftForAnother", - OUTSIDE_OF_ANY: "outsideOfAny" -}; -function dispatchDraggedElementEnteredContainer(containerEl, indexObj, draggedEl) { - containerEl.dispatchEvent(new CustomEvent(DRAGGED_ENTERED_EVENT_NAME, { - detail: { - indexObj: indexObj, - draggedEl: draggedEl - } - })); -} -/** - * @param containerEl - the dropzone the element left - * @param draggedEl - the dragged element - * @param theOtherDz - the new dropzone the element entered - */ - -function dispatchDraggedElementLeftContainerForAnother(containerEl, draggedEl, theOtherDz) { - containerEl.dispatchEvent(new CustomEvent(DRAGGED_LEFT_EVENT_NAME, { - detail: { - draggedEl: draggedEl, - type: DRAGGED_LEFT_TYPES.LEFT_FOR_ANOTHER, - theOtherDz: theOtherDz - } - })); -} -function dispatchDraggedElementLeftContainerForNone(containerEl, draggedEl) { - containerEl.dispatchEvent(new CustomEvent(DRAGGED_LEFT_EVENT_NAME, { - detail: { - draggedEl: draggedEl, - type: DRAGGED_LEFT_TYPES.OUTSIDE_OF_ANY - } - })); -} -function dispatchDraggedElementIsOverIndex(containerEl, indexObj, draggedEl) { - containerEl.dispatchEvent(new CustomEvent(DRAGGED_OVER_INDEX_EVENT_NAME, { - detail: { - indexObj: indexObj, - draggedEl: draggedEl - } - })); -} -function dispatchDraggedLeftDocument(draggedEl) { - window.dispatchEvent(new CustomEvent(DRAGGED_LEFT_DOCUMENT_EVENT_NAME, { - detail: { - draggedEl: draggedEl - } - })); -} - -var TRIGGERS = { - DRAG_STARTED: "dragStarted", - DRAGGED_ENTERED: DRAGGED_ENTERED_EVENT_NAME, - DRAGGED_ENTERED_ANOTHER: "dragEnteredAnother", - DRAGGED_OVER_INDEX: DRAGGED_OVER_INDEX_EVENT_NAME, - DRAGGED_LEFT: DRAGGED_LEFT_EVENT_NAME, - DRAGGED_LEFT_ALL: "draggedLeftAll", - DROPPED_INTO_ZONE: "droppedIntoZone", - DROPPED_INTO_ANOTHER: "droppedIntoAnother", - DROPPED_OUTSIDE_OF_ANY: "droppedOutsideOfAny", - DRAG_STOPPED: "dragStopped" -}; -var SOURCES = { - POINTER: "pointer", - KEYBOARD: "keyboard" -}; -var SHADOW_ITEM_MARKER_PROPERTY_NAME = "isDndShadowItem"; -var SHADOW_ELEMENT_ATTRIBUTE_NAME = "data-is-dnd-shadow-item"; -var SHADOW_PLACEHOLDER_ITEM_ID = "id:dnd-shadow-placeholder-0000"; -var DRAGGED_ELEMENT_ID = "dnd-action-dragged-el"; -var ITEM_ID_KEY = "id"; -var activeDndZoneCount = 0; -function incrementActiveDropZoneCount() { - activeDndZoneCount++; -} -function decrementActiveDropZoneCount() { - if (activeDndZoneCount === 0) { - throw new Error("Bug! trying to decrement when there are no dropzones"); - } - - activeDndZoneCount--; -} -var isOnServer = typeof window === "undefined"; - -// This is based off https://stackoverflow.com/questions/27745438/how-to-compute-getboundingclientrect-without-considering-transforms/57876601#57876601 -// It removes the transforms that are potentially applied by the flip animations - -/** - * Gets the bounding rect but removes transforms (ex: flip animation) - * @param {HTMLElement} el - * @return {{top: number, left: number, bottom: number, right: number}} - */ -function getBoundingRectNoTransforms(el) { - var ta; - var rect = el.getBoundingClientRect(); - var style = getComputedStyle(el); - var tx = style.transform; - - if (tx) { - var sx, sy, dx, dy; - - if (tx.startsWith("matrix3d(")) { - ta = tx.slice(9, -1).split(/, /); - sx = +ta[0]; - sy = +ta[5]; - dx = +ta[12]; - dy = +ta[13]; - } else if (tx.startsWith("matrix(")) { - ta = tx.slice(7, -1).split(/, /); - sx = +ta[0]; - sy = +ta[3]; - dx = +ta[4]; - dy = +ta[5]; - } else { - return rect; - } - - var to = style.transformOrigin; - var x = rect.x - dx - (1 - sx) * parseFloat(to); - var y = rect.y - dy - (1 - sy) * parseFloat(to.slice(to.indexOf(" ") + 1)); - var w = sx ? rect.width / sx : el.offsetWidth; - var h = sy ? rect.height / sy : el.offsetHeight; - return { - x: x, - y: y, - width: w, - height: h, - top: y, - right: x + w, - bottom: y + h, - left: x - }; - } else { - return rect; - } -} -/** - * Gets the absolute bounding rect (accounts for the window's scroll position and removes transforms) - * @param {HTMLElement} el - * @return {{top: number, left: number, bottom: number, right: number}} - */ - -function getAbsoluteRectNoTransforms(el) { - var rect = getBoundingRectNoTransforms(el); - return { - top: rect.top + window.scrollY, - bottom: rect.bottom + window.scrollY, - left: rect.left + window.scrollX, - right: rect.right + window.scrollX - }; -} -/** - * Gets the absolute bounding rect (accounts for the window's scroll position) - * @param {HTMLElement} el - * @return {{top: number, left: number, bottom: number, right: number}} - */ - -function getAbsoluteRect(el) { - var rect = el.getBoundingClientRect(); - return { - top: rect.top + window.scrollY, - bottom: rect.bottom + window.scrollY, - left: rect.left + window.scrollX, - right: rect.right + window.scrollX - }; -} -/** - * finds the center :) - * @typedef {Object} Rect - * @property {number} top - * @property {number} bottom - * @property {number} left - * @property {number} right - * @param {Rect} rect - * @return {{x: number, y: number}} - */ - -function findCenter(rect) { - return { - x: (rect.left + rect.right) / 2, - y: (rect.top + rect.bottom) / 2 - }; -} -/** - * @typedef {Object} Point - * @property {number} x - * @property {number} y - * @param {Point} pointA - * @param {Point} pointB - * @return {number} - */ - -function calcDistance(pointA, pointB) { - return Math.sqrt(Math.pow(pointA.x - pointB.x, 2) + Math.pow(pointA.y - pointB.y, 2)); -} -/** - * @param {Point} point - * @param {Rect} rect - * @return {boolean|boolean} - */ - - -function isPointInsideRect(point, rect) { - return point.y <= rect.bottom && point.y >= rect.top && point.x >= rect.left && point.x <= rect.right; -} -/** - * find the absolute coordinates of the center of a dom element - * @param el {HTMLElement} - * @returns {{x: number, y: number}} - */ - -function findCenterOfElement(el) { - return findCenter(getAbsoluteRect(el)); -} -/** - * @param {HTMLElement} elA - * @param {HTMLElement} elB - * @return {boolean} - */ - -function isCenterOfAInsideB(elA, elB) { - var centerOfA = findCenterOfElement(elA); - var rectOfB = getAbsoluteRectNoTransforms(elB); - return isPointInsideRect(centerOfA, rectOfB); -} -/** - * @param {HTMLElement|ChildNode} elA - * @param {HTMLElement|ChildNode} elB - * @return {number} - */ - -function calcDistanceBetweenCenters(elA, elB) { - var centerOfA = findCenterOfElement(elA); - var centerOfB = findCenterOfElement(elB); - return calcDistance(centerOfA, centerOfB); -} -/** - * @param {HTMLElement} el - the element to check - * @returns {boolean} - true if the element in its entirety is off screen including the scrollable area (the normal dom events look at the mouse rather than the element) - */ - -function isElementOffDocument(el) { - var rect = getAbsoluteRect(el); - return rect.right < 0 || rect.left > document.documentElement.scrollWidth || rect.bottom < 0 || rect.top > document.documentElement.scrollHeight; -} -/** - * If the point is inside the element returns its distances from the sides, otherwise returns null - * @param {Point} point - * @param {HTMLElement} el - * @return {null|{top: number, left: number, bottom: number, right: number}} - */ - -function calcInnerDistancesBetweenPointAndSidesOfElement(point, el) { - var rect = getAbsoluteRect(el); - - if (!isPointInsideRect(point, rect)) { - return null; - } - - return { - top: point.y - rect.top, - bottom: rect.bottom - point.y, - left: point.x - rect.left, - // TODO - figure out what is so special about right (why the rect is too big) - right: Math.min(rect.right, document.documentElement.clientWidth) - point.x - }; -} - -var dzToShadowIndexToRect; -/** - * Resets the cache that allows for smarter "would be index" resolution. Should be called after every drag operation - */ - -function resetIndexesCache() { - dzToShadowIndexToRect = new Map(); -} -resetIndexesCache(); -/** - * Caches the coordinates of the shadow element when it's in a certain index in a certain dropzone. - * Helpful in order to determine "would be index" more effectively - * @param {HTMLElement} dz - * @return {number} - the shadow element index - */ - -function cacheShadowRect(dz) { - var shadowElIndex = Array.from(dz.children).findIndex(function (child) { - return child.getAttribute(SHADOW_ELEMENT_ATTRIBUTE_NAME); - }); - - if (shadowElIndex >= 0) { - if (!dzToShadowIndexToRect.has(dz)) { - dzToShadowIndexToRect.set(dz, new Map()); - } - - dzToShadowIndexToRect.get(dz).set(shadowElIndex, getAbsoluteRectNoTransforms(dz.children[shadowElIndex])); - return shadowElIndex; - } - - return undefined; -} -/** - * @typedef {Object} Index - * @property {number} index - the would be index - * @property {boolean} isProximityBased - false if the element is actually over the index, true if it is not over it but this index is the closest - */ - -/** - * Find the index for the dragged element in the list it is dragged over - * @param {HTMLElement} floatingAboveEl - * @param {HTMLElement} collectionBelowEl - * @returns {Index|null} - if the element is over the container the Index object otherwise null - */ - - -function findWouldBeIndex(floatingAboveEl, collectionBelowEl) { - if (!isCenterOfAInsideB(floatingAboveEl, collectionBelowEl)) { - return null; - } - - var children = collectionBelowEl.children; // the container is empty, floating element should be the first - - if (children.length === 0) { - return { - index: 0, - isProximityBased: true - }; - } - - var shadowElIndex = cacheShadowRect(collectionBelowEl); // the search could be more efficient but keeping it simple for now - // a possible improvement: pass in the lastIndex it was found in and check there first, then expand from there - - for (var i = 0; i < children.length; i++) { - if (isCenterOfAInsideB(floatingAboveEl, children[i])) { - var cachedShadowRect = dzToShadowIndexToRect.has(collectionBelowEl) && dzToShadowIndexToRect.get(collectionBelowEl).get(i); - - if (cachedShadowRect) { - if (!isPointInsideRect(findCenterOfElement(floatingAboveEl), cachedShadowRect)) { - return { - index: shadowElIndex, - isProximityBased: false - }; - } - } - - return { - index: i, - isProximityBased: false - }; - } - } // this can happen if there is space around the children so the floating element has - //entered the container but not any of the children, in this case we will find the nearest child - - - var minDistanceSoFar = Number.MAX_VALUE; - var indexOfMin = undefined; // we are checking all of them because we don't know whether we are dealing with a horizontal or vertical container and where the floating element entered from - - for (var _i = 0; _i < children.length; _i++) { - var distance = calcDistanceBetweenCenters(floatingAboveEl, children[_i]); - - if (distance < minDistanceSoFar) { - minDistanceSoFar = distance; - indexOfMin = _i; - } - } - - return { - index: indexOfMin, - isProximityBased: true - }; -} - -var SCROLL_ZONE_PX = 25; -function makeScroller() { - var scrollingInfo; - - function resetScrolling() { - scrollingInfo = { - directionObj: undefined, - stepPx: 0 - }; - } - - resetScrolling(); // directionObj {x: 0|1|-1, y:0|1|-1} - 1 means down in y and right in x - - function scrollContainer(containerEl) { - var _scrollingInfo = scrollingInfo, - directionObj = _scrollingInfo.directionObj, - stepPx = _scrollingInfo.stepPx; - - if (directionObj) { - containerEl.scrollBy(directionObj.x * stepPx, directionObj.y * stepPx); - window.requestAnimationFrame(function () { - return scrollContainer(containerEl); - }); - } - } - - function calcScrollStepPx(distancePx) { - return SCROLL_ZONE_PX - distancePx; - } - /** - * If the pointer is next to the sides of the element to scroll, will trigger scrolling - * Can be called repeatedly with updated pointer and elementToScroll values without issues - * @return {boolean} - true if scrolling was needed - */ - - - function scrollIfNeeded(pointer, elementToScroll) { - if (!elementToScroll) { - return false; - } - - var distances = calcInnerDistancesBetweenPointAndSidesOfElement(pointer, elementToScroll); - - if (distances === null) { - resetScrolling(); - return false; - } - - var isAlreadyScrolling = !!scrollingInfo.directionObj; - var scrollingVertically = false, - scrollingHorizontally = false; // vertical - - if (elementToScroll.scrollHeight > elementToScroll.clientHeight) { - if (distances.bottom < SCROLL_ZONE_PX) { - scrollingVertically = true; - scrollingInfo.directionObj = { - x: 0, - y: 1 - }; - scrollingInfo.stepPx = calcScrollStepPx(distances.bottom); - } else if (distances.top < SCROLL_ZONE_PX) { - scrollingVertically = true; - scrollingInfo.directionObj = { - x: 0, - y: -1 - }; - scrollingInfo.stepPx = calcScrollStepPx(distances.top); - } - - if (!isAlreadyScrolling && scrollingVertically) { - scrollContainer(elementToScroll); - return true; - } - } // horizontal - - - if (elementToScroll.scrollWidth > elementToScroll.clientWidth) { - if (distances.right < SCROLL_ZONE_PX) { - scrollingHorizontally = true; - scrollingInfo.directionObj = { - x: 1, - y: 0 - }; - scrollingInfo.stepPx = calcScrollStepPx(distances.right); - } else if (distances.left < SCROLL_ZONE_PX) { - scrollingHorizontally = true; - scrollingInfo.directionObj = { - x: -1, - y: 0 - }; - scrollingInfo.stepPx = calcScrollStepPx(distances.left); - } - - if (!isAlreadyScrolling && scrollingHorizontally) { - scrollContainer(elementToScroll); - return true; - } - } - - resetScrolling(); - return false; - } - - return { - scrollIfNeeded: scrollIfNeeded, - resetScrolling: resetScrolling - }; -} - -/** - * @param {Object} object - * @return {string} - */ -function toString$1(object) { - return JSON.stringify(object, null, 2); -} -/** - * Finds the depth of the given node in the DOM tree - * @param {HTMLElement} node - * @return {number} - the depth of the node - */ - -function getDepth(node) { - if (!node) { - throw new Error("cannot get depth of a falsy node"); - } - - return _getDepth(node, 0); -} - -function _getDepth(node) { - var countSoFar = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; - - if (!node.parentElement) { - return countSoFar - 1; - } - - return _getDepth(node.parentElement, countSoFar + 1); -} -/** - * A simple util to shallow compare objects quickly, it doesn't validate the arguments so pass objects in - * @param {Object} objA - * @param {Object} objB - * @return {boolean} - true if objA and objB are shallow equal - */ - - -function areObjectsShallowEqual(objA, objB) { - if (Object.keys(objA).length !== Object.keys(objB).length) { - return false; - } - - for (var keyA in objA) { - if (!{}.hasOwnProperty.call(objB, keyA) || objB[keyA] !== objA[keyA]) { - return false; - } - } - - return true; -} -/** - * Shallow compares two arrays - * @param arrA - * @param arrB - * @return {boolean} - whether the arrays are shallow equal - */ - -function areArraysShallowEqualSameOrder(arrA, arrB) { - if (arrA.length !== arrB.length) { - return false; - } - - for (var i = 0; i < arrA.length; i++) { - if (arrA[i] !== arrB[i]) { - return false; - } - } - - return true; -} - -var INTERVAL_MS = 200; -var TOLERANCE_PX = 10; - -var _makeScroller = makeScroller(), - scrollIfNeeded = _makeScroller.scrollIfNeeded, - resetScrolling = _makeScroller.resetScrolling; - -var next; -/** - * Tracks the dragged elements and performs the side effects when it is dragged over a drop zone (basically dispatching custom-events scrolling) - * @param {Set} dropZones - * @param {HTMLElement} draggedEl - * @param {number} [intervalMs = INTERVAL_MS] - */ - -function observe(draggedEl, dropZones) { - var intervalMs = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : INTERVAL_MS; - // initialization - var lastDropZoneFound; - var lastIndexFound; - var lastIsDraggedInADropZone = false; - var lastCentrePositionOfDragged; // We are sorting to make sure that in case of nested zones of the same type the one "on top" is considered first - - var dropZonesFromDeepToShallow = Array.from(dropZones).sort(function (dz1, dz2) { - return getDepth(dz2) - getDepth(dz1); - }); - /** - * The main function in this module. Tracks where everything is/ should be a take the actions - */ - - function andNow() { - var currentCenterOfDragged = findCenterOfElement(draggedEl); - var scrolled = scrollIfNeeded(currentCenterOfDragged, lastDropZoneFound); // we only want to make a new decision after the element was moved a bit to prevent flickering - - if (!scrolled && lastCentrePositionOfDragged && Math.abs(lastCentrePositionOfDragged.x - currentCenterOfDragged.x) < TOLERANCE_PX && Math.abs(lastCentrePositionOfDragged.y - currentCenterOfDragged.y) < TOLERANCE_PX) { - next = window.setTimeout(andNow, intervalMs); - return; - } - - if (isElementOffDocument(draggedEl)) { - dispatchDraggedLeftDocument(draggedEl); - return; - } - - lastCentrePositionOfDragged = currentCenterOfDragged; // this is a simple algorithm, potential improvement: first look at lastDropZoneFound - - var isDraggedInADropZone = false; - - var _iterator = _createForOfIteratorHelper(dropZonesFromDeepToShallow), - _step; - - try { - for (_iterator.s(); !(_step = _iterator.n()).done;) { - var dz = _step.value; - var indexObj = findWouldBeIndex(draggedEl, dz); - - if (indexObj === null) { - // it is not inside - continue; - } - - var index = indexObj.index; - isDraggedInADropZone = true; // the element is over a container - - if (dz !== lastDropZoneFound) { - lastDropZoneFound && dispatchDraggedElementLeftContainerForAnother(lastDropZoneFound, draggedEl, dz); - dispatchDraggedElementEnteredContainer(dz, indexObj, draggedEl); - lastDropZoneFound = dz; - } else if (index !== lastIndexFound) { - dispatchDraggedElementIsOverIndex(dz, indexObj, draggedEl); - lastIndexFound = index; - } // we handle looping with the 'continue' statement above - - - break; - } // the first time the dragged element is not in any dropzone we need to notify the last dropzone it was in - - } catch (err) { - _iterator.e(err); - } finally { - _iterator.f(); - } - - if (!isDraggedInADropZone && lastIsDraggedInADropZone && lastDropZoneFound) { - dispatchDraggedElementLeftContainerForNone(lastDropZoneFound, draggedEl); - lastDropZoneFound = undefined; - lastIndexFound = undefined; - lastIsDraggedInADropZone = false; - } else { - lastIsDraggedInADropZone = true; - } - - next = window.setTimeout(andNow, intervalMs); - } - - andNow(); -} // assumption - we can only observe one dragged element at a time, this could be changed in the future - -function unobserve() { - clearTimeout(next); - resetScrolling(); - resetIndexesCache(); -} - -var INTERVAL_MS$1 = 300; -var mousePosition; -/** - * Do not use this! it is visible for testing only until we get over the issue Cypress not triggering the mousemove listeners - * // TODO - make private (remove export) - * @param {{clientX: number, clientY: number}} e - */ - -function updateMousePosition(e) { - var c = e.touches ? e.touches[0] : e; - mousePosition = { - x: c.clientX, - y: c.clientY - }; -} - -var _makeScroller$1 = makeScroller(), - scrollIfNeeded$1 = _makeScroller$1.scrollIfNeeded, - resetScrolling$1 = _makeScroller$1.resetScrolling; - -var next$1; - -function loop() { - if (mousePosition) { - scrollIfNeeded$1(mousePosition, document.documentElement); - } - - next$1 = window.setTimeout(loop, INTERVAL_MS$1); -} -/** - * will start watching the mouse pointer and scroll the window if it goes next to the edges - */ - - -function armWindowScroller() { - window.addEventListener("mousemove", updateMousePosition); - window.addEventListener("touchmove", updateMousePosition); - loop(); -} -/** - * will stop watching the mouse pointer and won't scroll the window anymore - */ - -function disarmWindowScroller() { - window.removeEventListener("mousemove", updateMousePosition); - window.removeEventListener("touchmove", updateMousePosition); - mousePosition = undefined; - window.clearTimeout(next$1); - resetScrolling$1(); -} - -var TRANSITION_DURATION_SECONDS = 0.2; -/** - * private helper function - creates a transition string for a property - * @param {string} property - * @return {string} - the transition string - */ - -function trs(property) { - return "".concat(property, " ").concat(TRANSITION_DURATION_SECONDS, "s ease"); -} -/** - * clones the given element and applies proper styles and transitions to the dragged element - * @param {HTMLElement} originalElement - * @param {Point} [positionCenterOnXY] - * @return {Node} - the cloned, styled element - */ - - -function createDraggedElementFrom(originalElement, positionCenterOnXY) { - var rect = originalElement.getBoundingClientRect(); - var draggedEl = originalElement.cloneNode(true); - copyStylesFromTo(originalElement, draggedEl); - draggedEl.id = DRAGGED_ELEMENT_ID; - draggedEl.style.position = "fixed"; - var elTopPx = rect.top; - var elLeftPx = rect.left; - draggedEl.style.top = "".concat(elTopPx, "px"); - draggedEl.style.left = "".concat(elLeftPx, "px"); - - if (positionCenterOnXY) { - var center = findCenter(rect); - elTopPx -= center.y - positionCenterOnXY.y; - elLeftPx -= center.x - positionCenterOnXY.x; - window.setTimeout(function () { - draggedEl.style.top = "".concat(elTopPx, "px"); - draggedEl.style.left = "".concat(elLeftPx, "px"); - }, 0); - } - - draggedEl.style.margin = "0"; // we can't have relative or automatic height and width or it will break the illusion - - draggedEl.style.boxSizing = "border-box"; - draggedEl.style.height = "".concat(rect.height, "px"); - draggedEl.style.width = "".concat(rect.width, "px"); - draggedEl.style.transition = "".concat(trs("top"), ", ").concat(trs("left"), ", ").concat(trs("background-color"), ", ").concat(trs("opacity"), ", ").concat(trs("color"), " "); // this is a workaround for a strange browser bug that causes the right border to disappear when all the transitions are added at the same time - - window.setTimeout(function () { - return draggedEl.style.transition += ", ".concat(trs("width"), ", ").concat(trs("height")); - }, 0); - draggedEl.style.zIndex = "9999"; - draggedEl.style.cursor = "grabbing"; - return draggedEl; -} -/** - * styles the dragged element to a 'dropped' state - * @param {HTMLElement} draggedEl - */ - -function moveDraggedElementToWasDroppedState(draggedEl) { - draggedEl.style.cursor = "grab"; -} -/** - * Morphs the dragged element style, maintains the mouse pointer within the element - * @param {HTMLElement} draggedEl - * @param {HTMLElement} copyFromEl - the element the dragged element should look like, typically the shadow element - * @param {number} currentMouseX - * @param {number} currentMouseY - * @param {function} transformDraggedElement - function to transform the dragged element, does nothing by default. - */ - -function morphDraggedElementToBeLike(draggedEl, copyFromEl, currentMouseX, currentMouseY, transformDraggedElement) { - var newRect = copyFromEl.getBoundingClientRect(); - var draggedElRect = draggedEl.getBoundingClientRect(); - var widthChange = newRect.width - draggedElRect.width; - var heightChange = newRect.height - draggedElRect.height; - - if (widthChange || heightChange) { - var relativeDistanceOfMousePointerFromDraggedSides = { - left: (currentMouseX - draggedElRect.left) / draggedElRect.width, - top: (currentMouseY - draggedElRect.top) / draggedElRect.height - }; - draggedEl.style.height = "".concat(newRect.height, "px"); - draggedEl.style.width = "".concat(newRect.width, "px"); - draggedEl.style.left = "".concat(parseFloat(draggedEl.style.left) - relativeDistanceOfMousePointerFromDraggedSides.left * widthChange, "px"); - draggedEl.style.top = "".concat(parseFloat(draggedEl.style.top) - relativeDistanceOfMousePointerFromDraggedSides.top * heightChange, "px"); - } /// other properties - - - copyStylesFromTo(copyFromEl, draggedEl); - transformDraggedElement(); -} -/** - * @param {HTMLElement} copyFromEl - * @param {HTMLElement} copyToEl - */ - -function copyStylesFromTo(copyFromEl, copyToEl) { - var computedStyle = window.getComputedStyle(copyFromEl); - Array.from(computedStyle).filter(function (s) { - return s.startsWith("background") || s.startsWith("padding") || s.startsWith("font") || s.startsWith("text") || s.startsWith("align") || s.startsWith("justify") || s.startsWith("display") || s.startsWith("flex") || s.startsWith("border") || s === "opacity" || s === "color" || s === "list-style-type"; - }).forEach(function (s) { - return copyToEl.style.setProperty(s, computedStyle.getPropertyValue(s), computedStyle.getPropertyPriority(s)); - }); -} -/** - * makes the element compatible with being draggable - * @param {HTMLElement} draggableEl - * @param {boolean} dragDisabled - */ - - -function styleDraggable(draggableEl, dragDisabled) { - draggableEl.draggable = false; - - draggableEl.ondragstart = function () { - return false; - }; - - if (!dragDisabled) { - draggableEl.style.userSelect = "none"; - draggableEl.style.WebkitUserSelect = "none"; - draggableEl.style.cursor = "grab"; - } else { - draggableEl.style.userSelect = ""; - draggableEl.style.WebkitUserSelect = ""; - draggableEl.style.cursor = ""; - } -} -/** - * Hides the provided element so that it can stay in the dom without interrupting - * @param {HTMLElement} dragTarget - */ - -function hideOriginalDragTarget(dragTarget) { - dragTarget.style.display = "none"; - dragTarget.style.position = "fixed"; - dragTarget.style.zIndex = "-5"; -} -/** - * styles the shadow element - * @param {HTMLElement} shadowEl - */ - -function decorateShadowEl(shadowEl) { - shadowEl.style.visibility = "hidden"; - shadowEl.setAttribute(SHADOW_ELEMENT_ATTRIBUTE_NAME, "true"); -} -/** - * undo the styles the shadow element - * @param {HTMLElement} shadowEl - */ - -function unDecorateShadowElement(shadowEl) { - shadowEl.style.visibility = ""; - shadowEl.removeAttribute(SHADOW_ELEMENT_ATTRIBUTE_NAME); -} -/** - * will mark the given dropzones as visually active - * @param {Array} dropZones - * @param {Function} getStyles - maps a dropzone to a styles object (so the styles can be removed) - * @param {Function} getClasses - maps a dropzone to a classList - */ - -function styleActiveDropZones(dropZones) { - var getStyles = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {}; - var getClasses = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function () { - return []; - }; - dropZones.forEach(function (dz) { - var styles = getStyles(dz); - Object.keys(styles).forEach(function (style) { - dz.style[style] = styles[style]; - }); - getClasses(dz).forEach(function (c) { - return dz.classList.add(c); - }); - }); -} -/** - * will remove the 'active' styling from given dropzones - * @param {Array} dropZones - * @param {Function} getStyles - maps a dropzone to a styles object - * @param {Function} getClasses - maps a dropzone to a classList - */ - -function styleInactiveDropZones(dropZones) { - var getStyles = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {}; - var getClasses = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function () { - return []; - }; - dropZones.forEach(function (dz) { - var styles = getStyles(dz); - Object.keys(styles).forEach(function (style) { - dz.style[style] = ""; - }); - getClasses(dz).forEach(function (c) { - return dz.classList.contains(c) && dz.classList.remove(c); - }); - }); -} -/** - * will prevent the provided element from shrinking by setting its minWidth and minHeight to the current width and height values - * @param {HTMLElement} el - * @return {function(): void} - run this function to undo the operation and restore the original values - */ - -function preventShrinking(el) { - var originalMinHeight = el.style.minHeight; - el.style.minHeight = window.getComputedStyle(el).getPropertyValue("height"); - var originalMinWidth = el.style.minWidth; - el.style.minWidth = window.getComputedStyle(el).getPropertyValue("width"); - return function undo() { - el.style.minHeight = originalMinHeight; - el.style.minWidth = originalMinWidth; - }; -} - -var DEFAULT_DROP_ZONE_TYPE = "--any--"; -var MIN_OBSERVATION_INTERVAL_MS = 100; -var MIN_MOVEMENT_BEFORE_DRAG_START_PX = 3; -var DEFAULT_DROP_TARGET_STYLE = { - outline: "rgba(255, 255, 102, 0.7) solid 2px" -}; -var originalDragTarget; -var draggedEl; -var draggedElData; -var draggedElType; -var originDropZone; -var originIndex; -var shadowElData; -var shadowElDropZone; -var dragStartMousePosition; -var currentMousePosition; -var isWorkingOnPreviousDrag = false; -var finalizingPreviousDrag = false; -var unlockOriginDzMinDimensions; -var isDraggedOutsideOfAnyDz = false; // a map from type to a set of drop-zones - -var typeToDropZones = new Map(); // important - this is needed because otherwise the config that would be used for everyone is the config of the element that created the event listeners - -var dzToConfig = new Map(); // this is needed in order to be able to cleanup old listeners and avoid stale closures issues (as the listener is defined within each zone) - -var elToMouseDownListener = new WeakMap(); -/* drop-zones registration management */ - -function registerDropZone(dropZoneEl, type) { - - if (!typeToDropZones.has(type)) { - typeToDropZones.set(type, new Set()); - } - - if (!typeToDropZones.get(type).has(dropZoneEl)) { - typeToDropZones.get(type).add(dropZoneEl); - incrementActiveDropZoneCount(); - } -} - -function unregisterDropZone(dropZoneEl, type) { - typeToDropZones.get(type)["delete"](dropZoneEl); - decrementActiveDropZoneCount(); - - if (typeToDropZones.get(type).size === 0) { - typeToDropZones["delete"](type); - } -} -/* functions to manage observing the dragged element and trigger custom drag-events */ - - -function watchDraggedElement() { - armWindowScroller(); - var dropZones = typeToDropZones.get(draggedElType); - - var _iterator = _createForOfIteratorHelper(dropZones), - _step; - - try { - for (_iterator.s(); !(_step = _iterator.n()).done;) { - var dz = _step.value; - dz.addEventListener(DRAGGED_ENTERED_EVENT_NAME, handleDraggedEntered); - dz.addEventListener(DRAGGED_LEFT_EVENT_NAME, handleDraggedLeft); - dz.addEventListener(DRAGGED_OVER_INDEX_EVENT_NAME, handleDraggedIsOverIndex); - } - } catch (err) { - _iterator.e(err); - } finally { - _iterator.f(); - } - - window.addEventListener(DRAGGED_LEFT_DOCUMENT_EVENT_NAME, handleDrop); // it is important that we don't have an interval that is faster than the flip duration because it can cause elements to jump bach and forth - - var observationIntervalMs = Math.max.apply(Math, [MIN_OBSERVATION_INTERVAL_MS].concat(_toConsumableArray(Array.from(dropZones.keys()).map(function (dz) { - return dzToConfig.get(dz).dropAnimationDurationMs; - })))); - observe(draggedEl, dropZones, observationIntervalMs * 1.07); -} - -function unWatchDraggedElement() { - disarmWindowScroller(); - var dropZones = typeToDropZones.get(draggedElType); - - var _iterator2 = _createForOfIteratorHelper(dropZones), - _step2; - - try { - for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { - var dz = _step2.value; - dz.removeEventListener(DRAGGED_ENTERED_EVENT_NAME, handleDraggedEntered); - dz.removeEventListener(DRAGGED_LEFT_EVENT_NAME, handleDraggedLeft); - dz.removeEventListener(DRAGGED_OVER_INDEX_EVENT_NAME, handleDraggedIsOverIndex); - } - } catch (err) { - _iterator2.e(err); - } finally { - _iterator2.f(); - } - - window.removeEventListener(DRAGGED_LEFT_DOCUMENT_EVENT_NAME, handleDrop); - unobserve(); -} // finds the initial placeholder that is placed there on drag start - - -function findShadowPlaceHolderIdx(items) { - return items.findIndex(function (item) { - return item[ITEM_ID_KEY] === SHADOW_PLACEHOLDER_ITEM_ID; - }); -} - -function findShadowElementIdx(items) { - // checking that the id is not the placeholder's for Dragula like usecases - return items.findIndex(function (item) { - return !!item[SHADOW_ITEM_MARKER_PROPERTY_NAME] && item[ITEM_ID_KEY] !== SHADOW_PLACEHOLDER_ITEM_ID; - }); -} -/* custom drag-events handlers */ - - -function handleDraggedEntered(e) { - - var _dzToConfig$get = dzToConfig.get(e.currentTarget), - items = _dzToConfig$get.items, - dropFromOthersDisabled = _dzToConfig$get.dropFromOthersDisabled; - - if (dropFromOthersDisabled && e.currentTarget !== originDropZone) { - return; - } - - isDraggedOutsideOfAnyDz = false; // this deals with another race condition. in rare occasions (super rapid operations) the list hasn't updated yet - - items = items.filter(function (item) { - return item[ITEM_ID_KEY] !== shadowElData[ITEM_ID_KEY]; - }); - - if (originDropZone !== e.currentTarget) { - var originZoneItems = dzToConfig.get(originDropZone).items; - var newOriginZoneItems = originZoneItems.filter(function (item) { - return !item[SHADOW_ITEM_MARKER_PROPERTY_NAME]; - }); - dispatchConsiderEvent(originDropZone, newOriginZoneItems, { - trigger: TRIGGERS.DRAGGED_ENTERED_ANOTHER, - id: draggedElData[ITEM_ID_KEY], - source: SOURCES.POINTER - }); - } else { - var shadowPlaceHolderIdx = findShadowPlaceHolderIdx(items); - - if (shadowPlaceHolderIdx !== -1) { - items.splice(shadowPlaceHolderIdx, 1); - } - } - - var _e$detail$indexObj = e.detail.indexObj, - index = _e$detail$indexObj.index, - isProximityBased = _e$detail$indexObj.isProximityBased; - var shadowElIdx = isProximityBased && index === e.currentTarget.children.length - 1 ? index + 1 : index; - shadowElDropZone = e.currentTarget; - items.splice(shadowElIdx, 0, shadowElData); - dispatchConsiderEvent(e.currentTarget, items, { - trigger: TRIGGERS.DRAGGED_ENTERED, - id: draggedElData[ITEM_ID_KEY], - source: SOURCES.POINTER - }); -} - -function handleDraggedLeft(e) { - // dealing with a rare race condition on extremely rapid clicking and dropping - if (!isWorkingOnPreviousDrag) return; - - var _dzToConfig$get2 = dzToConfig.get(e.currentTarget), - items = _dzToConfig$get2.items, - dropFromOthersDisabled = _dzToConfig$get2.dropFromOthersDisabled; - - if (dropFromOthersDisabled && e.currentTarget !== originDropZone && e.currentTarget !== shadowElDropZone) { - return; - } - - var shadowElIdx = findShadowElementIdx(items); - var shadowItem = items.splice(shadowElIdx, 1)[0]; - shadowElDropZone = undefined; - var _e$detail = e.detail, - type = _e$detail.type, - theOtherDz = _e$detail.theOtherDz; - - if (type === DRAGGED_LEFT_TYPES.OUTSIDE_OF_ANY || type === DRAGGED_LEFT_TYPES.LEFT_FOR_ANOTHER && theOtherDz !== originDropZone && dzToConfig.get(theOtherDz).dropFromOthersDisabled) { - isDraggedOutsideOfAnyDz = true; - shadowElDropZone = originDropZone; - var originZoneItems = dzToConfig.get(originDropZone).items; - originZoneItems.splice(originIndex, 0, shadowItem); - dispatchConsiderEvent(originDropZone, originZoneItems, { - trigger: TRIGGERS.DRAGGED_LEFT_ALL, - id: draggedElData[ITEM_ID_KEY], - source: SOURCES.POINTER - }); - } // for the origin dz, when the dragged is outside of any, this will be fired in addition to the previous. this is for simplicity - - - dispatchConsiderEvent(e.currentTarget, items, { - trigger: TRIGGERS.DRAGGED_LEFT, - id: draggedElData[ITEM_ID_KEY], - source: SOURCES.POINTER - }); -} - -function handleDraggedIsOverIndex(e) { - - var _dzToConfig$get3 = dzToConfig.get(e.currentTarget), - items = _dzToConfig$get3.items, - dropFromOthersDisabled = _dzToConfig$get3.dropFromOthersDisabled; - - if (dropFromOthersDisabled && e.currentTarget !== originDropZone) { - return; - } - - isDraggedOutsideOfAnyDz = false; - var index = e.detail.indexObj.index; - var shadowElIdx = findShadowElementIdx(items); - items.splice(shadowElIdx, 1); - items.splice(index, 0, shadowElData); - dispatchConsiderEvent(e.currentTarget, items, { - trigger: TRIGGERS.DRAGGED_OVER_INDEX, - id: draggedElData[ITEM_ID_KEY], - source: SOURCES.POINTER - }); -} // Global mouse/touch-events handlers - - -function handleMouseMove(e) { - e.preventDefault(); - var c = e.touches ? e.touches[0] : e; - currentMousePosition = { - x: c.clientX, - y: c.clientY - }; - draggedEl.style.transform = "translate3d(".concat(currentMousePosition.x - dragStartMousePosition.x, "px, ").concat(currentMousePosition.y - dragStartMousePosition.y, "px, 0)"); -} - -function handleDrop() { - finalizingPreviousDrag = true; // cleanup - - window.removeEventListener("mousemove", handleMouseMove); - window.removeEventListener("touchmove", handleMouseMove); - window.removeEventListener("mouseup", handleDrop); - window.removeEventListener("touchend", handleDrop); - unWatchDraggedElement(); - moveDraggedElementToWasDroppedState(draggedEl); - - if (!shadowElDropZone) { - shadowElDropZone = originDropZone; - } - - var _dzToConfig$get4 = dzToConfig.get(shadowElDropZone), - items = _dzToConfig$get4.items, - type = _dzToConfig$get4.type; - - styleInactiveDropZones(typeToDropZones.get(type), function (dz) { - return dzToConfig.get(dz).dropTargetStyle; - }, function (dz) { - return dzToConfig.get(dz).dropTargetClasses; - }); - var shadowElIdx = findShadowElementIdx(items); // the handler might remove the shadow element, ex: dragula like copy on drag - - if (shadowElIdx === -1) shadowElIdx = originIndex; - items = items.map(function (item) { - return item[SHADOW_ITEM_MARKER_PROPERTY_NAME] ? draggedElData : item; - }); - - function finalizeWithinZone() { - unlockOriginDzMinDimensions(); - dispatchFinalizeEvent(shadowElDropZone, items, { - trigger: isDraggedOutsideOfAnyDz ? TRIGGERS.DROPPED_OUTSIDE_OF_ANY : TRIGGERS.DROPPED_INTO_ZONE, - id: draggedElData[ITEM_ID_KEY], - source: SOURCES.POINTER - }); - - if (shadowElDropZone !== originDropZone) { - // letting the origin drop zone know the element was permanently taken away - dispatchFinalizeEvent(originDropZone, dzToConfig.get(originDropZone).items, { - trigger: TRIGGERS.DROPPED_INTO_ANOTHER, - id: draggedElData[ITEM_ID_KEY], - source: SOURCES.POINTER - }); - } - - unDecorateShadowElement(shadowElDropZone.children[shadowElIdx]); - cleanupPostDrop(); - } - - animateDraggedToFinalPosition(shadowElIdx, finalizeWithinZone); -} // helper function for handleDrop - - -function animateDraggedToFinalPosition(shadowElIdx, callback) { - var shadowElRect = getBoundingRectNoTransforms(shadowElDropZone.children[shadowElIdx]); - var newTransform = { - x: shadowElRect.left - parseFloat(draggedEl.style.left), - y: shadowElRect.top - parseFloat(draggedEl.style.top) - }; - - var _dzToConfig$get5 = dzToConfig.get(shadowElDropZone), - dropAnimationDurationMs = _dzToConfig$get5.dropAnimationDurationMs; - - var transition = "transform ".concat(dropAnimationDurationMs, "ms ease"); - draggedEl.style.transition = draggedEl.style.transition ? draggedEl.style.transition + "," + transition : transition; - draggedEl.style.transform = "translate3d(".concat(newTransform.x, "px, ").concat(newTransform.y, "px, 0)"); - window.setTimeout(callback, dropAnimationDurationMs); -} -/* cleanup */ - - -function cleanupPostDrop() { - draggedEl.remove(); - originalDragTarget.remove(); - draggedEl = undefined; - originalDragTarget = undefined; - draggedElData = undefined; - draggedElType = undefined; - originDropZone = undefined; - originIndex = undefined; - shadowElData = undefined; - shadowElDropZone = undefined; - dragStartMousePosition = undefined; - currentMousePosition = undefined; - isWorkingOnPreviousDrag = false; - finalizingPreviousDrag = false; - unlockOriginDzMinDimensions = undefined; - isDraggedOutsideOfAnyDz = false; -} - -function dndzone(node, options) { - var config = { - items: undefined, - type: undefined, - flipDurationMs: 0, - dragDisabled: false, - morphDisabled: false, - dropFromOthersDisabled: false, - dropTargetStyle: DEFAULT_DROP_TARGET_STYLE, - dropTargetClasses: [], - transformDraggedElement: function transformDraggedElement() {}, - centreDraggedOnCursor: false - }; - var elToIdx = new Map(); - - function addMaybeListeners() { - window.addEventListener("mousemove", handleMouseMoveMaybeDragStart, { - passive: false - }); - window.addEventListener("touchmove", handleMouseMoveMaybeDragStart, { - passive: false, - capture: false - }); - window.addEventListener("mouseup", handleFalseAlarm, { - passive: false - }); - window.addEventListener("touchend", handleFalseAlarm, { - passive: false - }); - } - - function removeMaybeListeners() { - window.removeEventListener("mousemove", handleMouseMoveMaybeDragStart); - window.removeEventListener("touchmove", handleMouseMoveMaybeDragStart); - window.removeEventListener("mouseup", handleFalseAlarm); - window.removeEventListener("touchend", handleFalseAlarm); - } - - function handleFalseAlarm() { - removeMaybeListeners(); - originalDragTarget = undefined; - dragStartMousePosition = undefined; - currentMousePosition = undefined; - } - - function handleMouseMoveMaybeDragStart(e) { - e.preventDefault(); - var c = e.touches ? e.touches[0] : e; - currentMousePosition = { - x: c.clientX, - y: c.clientY - }; - - if (Math.abs(currentMousePosition.x - dragStartMousePosition.x) >= MIN_MOVEMENT_BEFORE_DRAG_START_PX || Math.abs(currentMousePosition.y - dragStartMousePosition.y) >= MIN_MOVEMENT_BEFORE_DRAG_START_PX) { - removeMaybeListeners(); - handleDragStart(); - } - } - - function handleMouseDown(e) { - // on safari clicking on a select element doesn't fire mouseup at the end of the click and in general this makes more sense - if (e.target !== e.currentTarget && (e.target.value !== undefined || e.target.isContentEditable)) { - return; - } // prevents responding to any button but left click which equals 0 (which is falsy) - - - if (e.button) { - return; - } - - if (isWorkingOnPreviousDrag) { - return; - } - - e.stopPropagation(); - var c = e.touches ? e.touches[0] : e; - dragStartMousePosition = { - x: c.clientX, - y: c.clientY - }; - currentMousePosition = _objectSpread2({}, dragStartMousePosition); - originalDragTarget = e.currentTarget; - addMaybeListeners(); - } - - function handleDragStart() { - isWorkingOnPreviousDrag = true; // initialising globals - - var currentIdx = elToIdx.get(originalDragTarget); - originIndex = currentIdx; - originDropZone = originalDragTarget.parentElement; - var items = config.items, - type = config.type, - centreDraggedOnCursor = config.centreDraggedOnCursor; - draggedElData = _objectSpread2({}, items[currentIdx]); - draggedElType = type; - shadowElData = _objectSpread2(_objectSpread2({}, draggedElData), {}, _defineProperty({}, SHADOW_ITEM_MARKER_PROPERTY_NAME, true)); // The initial shadow element. We need a different id at first in order to avoid conflicts and timing issues - - var placeHolderElData = _objectSpread2(_objectSpread2({}, shadowElData), {}, _defineProperty({}, ITEM_ID_KEY, SHADOW_PLACEHOLDER_ITEM_ID)); // creating the draggable element - - - draggedEl = createDraggedElementFrom(originalDragTarget, centreDraggedOnCursor && currentMousePosition); // We will keep the original dom node in the dom because touch events keep firing on it, we want to re-add it after the framework removes it - - function keepOriginalElementInDom() { - if (!draggedEl.parentElement) { - document.body.appendChild(draggedEl); // to prevent the outline from disappearing - - draggedEl.focus(); - watchDraggedElement(); - hideOriginalDragTarget(originalDragTarget); - document.body.appendChild(originalDragTarget); - } else { - window.requestAnimationFrame(keepOriginalElementInDom); - } - } - - window.requestAnimationFrame(keepOriginalElementInDom); - styleActiveDropZones(Array.from(typeToDropZones.get(config.type)).filter(function (dz) { - return dz === originDropZone || !dzToConfig.get(dz).dropFromOthersDisabled; - }), function (dz) { - return dzToConfig.get(dz).dropTargetStyle; - }, function (dz) { - return dzToConfig.get(dz).dropTargetClasses; - }); // removing the original element by removing its data entry - - items.splice(currentIdx, 1, placeHolderElData); - unlockOriginDzMinDimensions = preventShrinking(originDropZone); - dispatchConsiderEvent(originDropZone, items, { - trigger: TRIGGERS.DRAG_STARTED, - id: draggedElData[ITEM_ID_KEY], - source: SOURCES.POINTER - }); // handing over to global handlers - starting to watch the element - - window.addEventListener("mousemove", handleMouseMove, { - passive: false - }); - window.addEventListener("touchmove", handleMouseMove, { - passive: false, - capture: false - }); - window.addEventListener("mouseup", handleDrop, { - passive: false - }); - window.addEventListener("touchend", handleDrop, { - passive: false - }); - } - - function configure(_ref) { - var _ref$items = _ref.items, - items = _ref$items === void 0 ? undefined : _ref$items, - _ref$flipDurationMs = _ref.flipDurationMs, - dropAnimationDurationMs = _ref$flipDurationMs === void 0 ? 0 : _ref$flipDurationMs, - _ref$type = _ref.type, - newType = _ref$type === void 0 ? DEFAULT_DROP_ZONE_TYPE : _ref$type, - _ref$dragDisabled = _ref.dragDisabled, - dragDisabled = _ref$dragDisabled === void 0 ? false : _ref$dragDisabled, - _ref$morphDisabled = _ref.morphDisabled, - morphDisabled = _ref$morphDisabled === void 0 ? false : _ref$morphDisabled, - _ref$dropFromOthersDi = _ref.dropFromOthersDisabled, - dropFromOthersDisabled = _ref$dropFromOthersDi === void 0 ? false : _ref$dropFromOthersDi, - _ref$dropTargetStyle = _ref.dropTargetStyle, - dropTargetStyle = _ref$dropTargetStyle === void 0 ? DEFAULT_DROP_TARGET_STYLE : _ref$dropTargetStyle, - _ref$dropTargetClasse = _ref.dropTargetClasses, - dropTargetClasses = _ref$dropTargetClasse === void 0 ? [] : _ref$dropTargetClasse, - _ref$transformDragged = _ref.transformDraggedElement, - transformDraggedElement = _ref$transformDragged === void 0 ? function () {} : _ref$transformDragged, - _ref$centreDraggedOnC = _ref.centreDraggedOnCursor, - centreDraggedOnCursor = _ref$centreDraggedOnC === void 0 ? false : _ref$centreDraggedOnC; - config.dropAnimationDurationMs = dropAnimationDurationMs; - - if (config.type && newType !== config.type) { - unregisterDropZone(node, config.type); - } - - config.type = newType; - registerDropZone(node, newType); - config.items = _toConsumableArray(items); - config.dragDisabled = dragDisabled; - config.morphDisabled = morphDisabled; - config.transformDraggedElement = transformDraggedElement; - config.centreDraggedOnCursor = centreDraggedOnCursor; // realtime update for dropTargetStyle - - if (isWorkingOnPreviousDrag && !finalizingPreviousDrag && (!areObjectsShallowEqual(dropTargetStyle, config.dropTargetStyle) || !areArraysShallowEqualSameOrder(dropTargetClasses, config.dropTargetClasses))) { - styleInactiveDropZones([node], function () { - return config.dropTargetStyle; - }, function () { - return dropTargetClasses; - }); - styleActiveDropZones([node], function () { - return dropTargetStyle; - }, function () { - return dropTargetClasses; - }); - } - - config.dropTargetStyle = dropTargetStyle; - config.dropTargetClasses = _toConsumableArray(dropTargetClasses); // realtime update for dropFromOthersDisabled - - function getConfigProp(dz, propName) { - return dzToConfig.get(dz) ? dzToConfig.get(dz)[propName] : config[propName]; - } - - if (isWorkingOnPreviousDrag && config.dropFromOthersDisabled !== dropFromOthersDisabled) { - if (dropFromOthersDisabled) { - styleInactiveDropZones([node], function (dz) { - return getConfigProp(dz, "dropTargetStyle"); - }, function (dz) { - return getConfigProp(dz, "dropTargetClasses"); - }); - } else { - styleActiveDropZones([node], function (dz) { - return getConfigProp(dz, "dropTargetStyle"); - }, function (dz) { - return getConfigProp(dz, "dropTargetClasses"); - }); - } - } - - config.dropFromOthersDisabled = dropFromOthersDisabled; - dzToConfig.set(node, config); - var shadowElIdx = findShadowElementIdx(config.items); - - var _loop = function _loop(idx) { - var draggableEl = node.children[idx]; - styleDraggable(draggableEl, dragDisabled); - - if (idx === shadowElIdx) { - if (!morphDisabled) { - morphDraggedElementToBeLike(draggedEl, draggableEl, currentMousePosition.x, currentMousePosition.y, function () { - return config.transformDraggedElement(draggedEl, draggedElData, idx); - }); - } - - decorateShadowEl(draggableEl); - return "continue"; - } - - draggableEl.removeEventListener("mousedown", elToMouseDownListener.get(draggableEl)); - draggableEl.removeEventListener("touchstart", elToMouseDownListener.get(draggableEl)); - - if (!dragDisabled) { - draggableEl.addEventListener("mousedown", handleMouseDown); - draggableEl.addEventListener("touchstart", handleMouseDown); - elToMouseDownListener.set(draggableEl, handleMouseDown); - } // updating the idx - - - elToIdx.set(draggableEl, idx); - }; - - for (var idx = 0; idx < node.children.length; idx++) { - var _ret = _loop(idx); - - if (_ret === "continue") continue; - } - } - - configure(options); - return { - update: function update(newOptions) { - configure(newOptions); - }, - destroy: function destroy() { - unregisterDropZone(node, config.type); - dzToConfig["delete"](node); - } - }; -} - -var _ID_TO_INSTRUCTION; -var INSTRUCTION_IDs = { - DND_ZONE_ACTIVE: "dnd-zone-active", - DND_ZONE_DRAG_DISABLED: "dnd-zone-drag-disabled" -}; -var ID_TO_INSTRUCTION = (_ID_TO_INSTRUCTION = {}, _defineProperty(_ID_TO_INSTRUCTION, INSTRUCTION_IDs.DND_ZONE_ACTIVE, "Tab to one the items and press space-bar or enter to start dragging it"), _defineProperty(_ID_TO_INSTRUCTION, INSTRUCTION_IDs.DND_ZONE_DRAG_DISABLED, "This is a disabled drag and drop list"), _ID_TO_INSTRUCTION); -var ALERT_DIV_ID = "dnd-action-aria-alert"; -var alertsDiv; - -function initAriaOnBrowser() { - // setting the dynamic alerts - alertsDiv = document.createElement("div"); - - (function initAlertsDiv() { - alertsDiv.id = ALERT_DIV_ID; // tab index -1 makes the alert be read twice on chrome for some reason - //alertsDiv.tabIndex = -1; - - alertsDiv.style.position = "fixed"; - alertsDiv.style.bottom = "0"; - alertsDiv.style.left = "0"; - alertsDiv.style.zIndex = "-5"; - alertsDiv.style.opacity = "0"; - alertsDiv.style.height = "0"; - alertsDiv.style.width = "0"; - alertsDiv.setAttribute("role", "alert"); - })(); - - document.body.prepend(alertsDiv); // setting the instructions - - Object.entries(ID_TO_INSTRUCTION).forEach(function (_ref) { - var _ref2 = _slicedToArray(_ref, 2), - id = _ref2[0], - txt = _ref2[1]; - - return document.body.prepend(instructionToHiddenDiv(id, txt)); - }); -} -/** - * Initializes the static aria instructions so they can be attached to zones - * @return {{DND_ZONE_ACTIVE: string, DND_ZONE_DRAG_DISABLED: string} | null} - the IDs for static aria instruction (to be used via aria-describedby) or null on the server - */ - - -function initAria() { - if (isOnServer) return null; - - if (document.readyState === "complete") { - initAriaOnBrowser(); - } else { - window.addEventListener("DOMContentLoaded", initAriaOnBrowser); - } - - return _objectSpread2({}, INSTRUCTION_IDs); -} - -function instructionToHiddenDiv(id, txt) { - var div = document.createElement("div"); - div.id = id; - div.innerHTML = "

".concat(txt, "

"); - div.style.display = "none"; - div.style.position = "fixed"; - div.style.zIndex = "-5"; - return div; -} -/** - * Will make the screen reader alert the provided text to the user - * @param {string} txt - */ - - -function alertToScreenReader(txt) { - alertsDiv.innerHTML = ""; - var alertText = document.createTextNode(txt); - alertsDiv.appendChild(alertText); // this is needed for Safari - - alertsDiv.style.display = "none"; - alertsDiv.style.display = "inline"; -} - -var DEFAULT_DROP_ZONE_TYPE$1 = "--any--"; -var DEFAULT_DROP_TARGET_STYLE$1 = { - outline: "rgba(255, 255, 102, 0.7) solid 2px" -}; -var isDragging = false; -var draggedItemType; -var focusedDz; -var focusedDzLabel = ""; -var focusedItem; -var focusedItemId; -var focusedItemLabel = ""; -var allDragTargets = new WeakSet(); -var elToKeyDownListeners = new WeakMap(); -var elToFocusListeners = new WeakMap(); -var dzToHandles = new Map(); -var dzToConfig$1 = new Map(); -var typeToDropZones$1 = new Map(); -/* TODO (potentially) - * what's the deal with the black border of voice-reader not following focus? - * maybe keep focus on the last dragged item upon drop? - */ - -var INSTRUCTION_IDs$1 = initAria(); -/* drop-zones registration management */ - -function registerDropZone$1(dropZoneEl, type) { - - if (typeToDropZones$1.size === 0) { - window.addEventListener("keydown", globalKeyDownHandler); - window.addEventListener("click", globalClickHandler); - } - - if (!typeToDropZones$1.has(type)) { - typeToDropZones$1.set(type, new Set()); - } - - if (!typeToDropZones$1.get(type).has(dropZoneEl)) { - typeToDropZones$1.get(type).add(dropZoneEl); - incrementActiveDropZoneCount(); - } -} - -function unregisterDropZone$1(dropZoneEl, type) { - - if (focusedDz === dropZoneEl) { - handleDrop$1(); - } - - typeToDropZones$1.get(type)["delete"](dropZoneEl); - decrementActiveDropZoneCount(); - - if (typeToDropZones$1.get(type).size === 0) { - typeToDropZones$1["delete"](type); - } - - if (typeToDropZones$1.size === 0) { - window.removeEventListener("keydown", globalKeyDownHandler); - window.removeEventListener("click", globalClickHandler); - } -} - -function globalKeyDownHandler(e) { - if (!isDragging) return; - - switch (e.key) { - case "Escape": - { - handleDrop$1(); - break; - } - } -} - -function globalClickHandler() { - if (!isDragging) return; - - if (!allDragTargets.has(document.activeElement)) { - handleDrop$1(); - } -} - -function handleZoneFocus(e) { - if (!isDragging) return; - var newlyFocusedDz = e.currentTarget; - if (newlyFocusedDz === focusedDz) return; - focusedDzLabel = newlyFocusedDz.getAttribute("aria-label") || ""; - - var _dzToConfig$get = dzToConfig$1.get(focusedDz), - originItems = _dzToConfig$get.items; - - var originItem = originItems.find(function (item) { - return item[ITEM_ID_KEY] === focusedItemId; - }); - var originIdx = originItems.indexOf(originItem); - var itemToMove = originItems.splice(originIdx, 1)[0]; - - var _dzToConfig$get2 = dzToConfig$1.get(newlyFocusedDz), - targetItems = _dzToConfig$get2.items, - autoAriaDisabled = _dzToConfig$get2.autoAriaDisabled; - - if (newlyFocusedDz.getBoundingClientRect().top < focusedDz.getBoundingClientRect().top || newlyFocusedDz.getBoundingClientRect().left < focusedDz.getBoundingClientRect().left) { - targetItems.push(itemToMove); - - if (!autoAriaDisabled) { - alertToScreenReader("Moved item ".concat(focusedItemLabel, " to the end of the list ").concat(focusedDzLabel)); - } - } else { - targetItems.unshift(itemToMove); - - if (!autoAriaDisabled) { - alertToScreenReader("Moved item ".concat(focusedItemLabel, " to the beginning of the list ").concat(focusedDzLabel)); - } - } - - var dzFrom = focusedDz; - dispatchFinalizeEvent(dzFrom, originItems, { - trigger: TRIGGERS.DROPPED_INTO_ANOTHER, - id: focusedItemId, - source: SOURCES.KEYBOARD - }); - dispatchFinalizeEvent(newlyFocusedDz, targetItems, { - trigger: TRIGGERS.DROPPED_INTO_ZONE, - id: focusedItemId, - source: SOURCES.KEYBOARD - }); - focusedDz = newlyFocusedDz; -} - -function triggerAllDzsUpdate() { - dzToHandles.forEach(function (_ref, dz) { - var update = _ref.update; - return update(dzToConfig$1.get(dz)); - }); -} - -function handleDrop$1() { - var dispatchConsider = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; - - if (!dzToConfig$1.get(focusedDz).autoAriaDisabled) { - alertToScreenReader("Stopped dragging item ".concat(focusedItemLabel)); - } - - if (allDragTargets.has(document.activeElement)) { - document.activeElement.blur(); - } - - if (dispatchConsider) { - dispatchConsiderEvent(focusedDz, dzToConfig$1.get(focusedDz).items, { - trigger: TRIGGERS.DRAG_STOPPED, - id: focusedItemId, - source: SOURCES.KEYBOARD - }); - } - - styleInactiveDropZones(typeToDropZones$1.get(draggedItemType), function (dz) { - return dzToConfig$1.get(dz).dropTargetStyle; - }, function (dz) { - return dzToConfig$1.get(dz).dropTargetClasses; - }); - focusedItem = null; - focusedItemId = null; - focusedItemLabel = ""; - draggedItemType = null; - focusedDz = null; - focusedDzLabel = ""; - isDragging = false; - triggerAllDzsUpdate(); -} ////// - - -function dndzone$1(node, options) { - var config = { - items: undefined, - type: undefined, - dragDisabled: false, - dropFromOthersDisabled: false, - dropTargetStyle: DEFAULT_DROP_TARGET_STYLE$1, - dropTargetClasses: [], - autoAriaDisabled: false - }; - - function swap(arr, i, j) { - if (arr.length <= 1) return; - arr.splice(j, 1, arr.splice(i, 1, arr[j])[0]); - } - - function handleKeyDown(e) { - - switch (e.key) { - case "Enter": - case " ": - { - // we don't want to affect nested input elements or clickable elements - if ((e.target.disabled !== undefined || e.target.href || e.target.isContentEditable) && !allDragTargets.has(e.target)) { - return; - } - - e.preventDefault(); // preventing scrolling on spacebar - - e.stopPropagation(); - - if (isDragging) { - // TODO - should this trigger a drop? only here or in general (as in when hitting space or enter outside of any zone)? - handleDrop$1(); - } else { - // drag start - handleDragStart(e); - } - - break; - } - - case "ArrowDown": - case "ArrowRight": - { - if (!isDragging) return; - e.preventDefault(); // prevent scrolling - - e.stopPropagation(); - - var _dzToConfig$get3 = dzToConfig$1.get(node), - items = _dzToConfig$get3.items; - - var children = Array.from(node.children); - var idx = children.indexOf(e.currentTarget); - - if (idx < children.length - 1) { - if (!config.autoAriaDisabled) { - alertToScreenReader("Moved item ".concat(focusedItemLabel, " to position ").concat(idx + 2, " in the list ").concat(focusedDzLabel)); - } - - swap(items, idx, idx + 1); - dispatchFinalizeEvent(node, items, { - trigger: TRIGGERS.DROPPED_INTO_ZONE, - id: focusedItemId, - source: SOURCES.KEYBOARD - }); - } - - break; - } - - case "ArrowUp": - case "ArrowLeft": - { - if (!isDragging) return; - e.preventDefault(); // prevent scrolling - - e.stopPropagation(); - - var _dzToConfig$get4 = dzToConfig$1.get(node), - _items = _dzToConfig$get4.items; - - var _children = Array.from(node.children); - - var _idx = _children.indexOf(e.currentTarget); - - if (_idx > 0) { - if (!config.autoAriaDisabled) { - alertToScreenReader("Moved item ".concat(focusedItemLabel, " to position ").concat(_idx, " in the list ").concat(focusedDzLabel)); - } - - swap(_items, _idx, _idx - 1); - dispatchFinalizeEvent(node, _items, { - trigger: TRIGGERS.DROPPED_INTO_ZONE, - id: focusedItemId, - source: SOURCES.KEYBOARD - }); - } - - break; - } - } - } - - function handleDragStart(e) { - setCurrentFocusedItem(e.currentTarget); - focusedDz = node; - draggedItemType = config.type; - isDragging = true; - var dropTargets = Array.from(typeToDropZones$1.get(config.type)).filter(function (dz) { - return dz === focusedDz || !dzToConfig$1.get(dz).dropFromOthersDisabled; - }); - styleActiveDropZones(dropTargets, function (dz) { - return dzToConfig$1.get(dz).dropTargetStyle; - }, function (dz) { - return dzToConfig$1.get(dz).dropTargetClasses; - }); - - if (!config.autoAriaDisabled) { - var msg = "Started dragging item ".concat(focusedItemLabel, ". Use the arrow keys to move it within its list ").concat(focusedDzLabel); - - if (dropTargets.length > 1) { - msg += ", or tab to another list in order to move the item into it"; - } - - alertToScreenReader(msg); - } - - dispatchConsiderEvent(node, dzToConfig$1.get(node).items, { - trigger: TRIGGERS.DRAG_STARTED, - id: focusedItemId, - source: SOURCES.KEYBOARD - }); - triggerAllDzsUpdate(); - } - - function handleClick(e) { - if (!isDragging) return; - if (e.currentTarget === focusedItem) return; - e.stopPropagation(); - handleDrop$1(false); - handleDragStart(e); - } - - function setCurrentFocusedItem(draggableEl) { - var _dzToConfig$get5 = dzToConfig$1.get(node), - items = _dzToConfig$get5.items; - - var children = Array.from(node.children); - var focusedItemIdx = children.indexOf(draggableEl); - focusedItem = draggableEl; - focusedItem.tabIndex = 0; - focusedItemId = items[focusedItemIdx][ITEM_ID_KEY]; - focusedItemLabel = children[focusedItemIdx].getAttribute("aria-label") || ""; - } - - function configure(_ref2) { - var _ref2$items = _ref2.items, - items = _ref2$items === void 0 ? [] : _ref2$items, - _ref2$type = _ref2.type, - newType = _ref2$type === void 0 ? DEFAULT_DROP_ZONE_TYPE$1 : _ref2$type, - _ref2$dragDisabled = _ref2.dragDisabled, - dragDisabled = _ref2$dragDisabled === void 0 ? false : _ref2$dragDisabled, - _ref2$dropFromOthersD = _ref2.dropFromOthersDisabled, - dropFromOthersDisabled = _ref2$dropFromOthersD === void 0 ? false : _ref2$dropFromOthersD, - _ref2$dropTargetStyle = _ref2.dropTargetStyle, - dropTargetStyle = _ref2$dropTargetStyle === void 0 ? DEFAULT_DROP_TARGET_STYLE$1 : _ref2$dropTargetStyle, - _ref2$dropTargetClass = _ref2.dropTargetClasses, - dropTargetClasses = _ref2$dropTargetClass === void 0 ? [] : _ref2$dropTargetClass, - _ref2$autoAriaDisable = _ref2.autoAriaDisabled, - autoAriaDisabled = _ref2$autoAriaDisable === void 0 ? false : _ref2$autoAriaDisable; - config.items = _toConsumableArray(items); - config.dragDisabled = dragDisabled; - config.dropFromOthersDisabled = dropFromOthersDisabled; - config.dropTargetStyle = dropTargetStyle; - config.dropTargetClasses = dropTargetClasses; - config.autoAriaDisabled = autoAriaDisabled; - - if (!autoAriaDisabled) { - node.setAttribute("aria-disabled", dragDisabled); - node.setAttribute("role", "list"); - node.setAttribute("aria-describedby", dragDisabled ? INSTRUCTION_IDs$1.DND_ZONE_DRAG_DISABLED : INSTRUCTION_IDs$1.DND_ZONE_ACTIVE); - } - - if (config.type && newType !== config.type) { - unregisterDropZone$1(node, config.type); - } - - config.type = newType; - registerDropZone$1(node, newType); - dzToConfig$1.set(node, config); - node.tabIndex = isDragging && (node === focusedDz || focusedItem.contains(node) || config.dropFromOthersDisabled || focusedDz && config.type !== dzToConfig$1.get(focusedDz).type) ? -1 : 0; - node.addEventListener("focus", handleZoneFocus); - - var _loop = function _loop(i) { - var draggableEl = node.children[i]; - allDragTargets.add(draggableEl); - draggableEl.tabIndex = isDragging ? -1 : 0; - - if (!autoAriaDisabled) { - draggableEl.setAttribute("role", "listitem"); - } - - draggableEl.removeEventListener("keydown", elToKeyDownListeners.get(draggableEl)); - draggableEl.removeEventListener("click", elToFocusListeners.get(draggableEl)); - - if (!dragDisabled) { - draggableEl.addEventListener("keydown", handleKeyDown); - elToKeyDownListeners.set(draggableEl, handleKeyDown); - draggableEl.addEventListener("click", handleClick); - elToFocusListeners.set(draggableEl, handleClick); - } - - if (isDragging && config.items[i][ITEM_ID_KEY] === focusedItemId) { - - focusedItem = draggableEl; - focusedItem.tabIndex = 0; // without this the element loses focus if it moves backwards in the list - - draggableEl.focus(); - } - }; - - for (var i = 0; i < node.children.length; i++) { - _loop(i); - } - } - - configure(options); - var handles = { - update: function update(newOptions) { - configure(newOptions); - }, - destroy: function destroy() { - unregisterDropZone$1(node, config.type); - dzToConfig$1["delete"](node); - dzToHandles["delete"](node); - } - }; - dzToHandles.set(node, handles); - return handles; -} - -/** - * A custom action to turn any container to a dnd zone and all of its direct children to draggables - * Supports mouse, touch and keyboard interactions. - * Dispatches two events that the container is expected to react to by modifying its list of items, - * which will then feed back in to this action via the update function - * - * @typedef {object} Options - * @property {array} items - the list of items that was used to generate the children of the given node (the list used in the #each block - * @property {string} [type] - the type of the dnd zone. children dragged from here can only be dropped in other zones of the same type, default to a base type - * @property {number} [flipDurationMs] - if the list animated using flip (recommended), specifies the flip duration such that everything syncs with it without conflict, defaults to zero - * @property {boolean} [dragDisabled] - * @property {boolean} [morphDisabled] - whether dragged element should morph to zone dimensions - * @property {boolean} [dropFromOthersDisabled] - * @property {object} [dropTargetStyle] - * @property {string[]} [dropTargetClasses] - * @property {function} [transformDraggedElement] - * @param {HTMLElement} node - the element to enhance - * @param {Options} options - * @return {{update: function, destroy: function}} - */ - -function dndzone$2(node, options) { - validateOptions(options); - var pointerZone = dndzone(node, options); - var keyboardZone = dndzone$1(node, options); - return { - update: function update(newOptions) { - validateOptions(newOptions); - pointerZone.update(newOptions); - keyboardZone.update(newOptions); - }, - destroy: function destroy() { - pointerZone.destroy(); - keyboardZone.destroy(); - } - }; -} - -function validateOptions(options) { - /*eslint-disable*/ - var items = options.items; - options.flipDurationMs; - options.type; - options.dragDisabled; - options.morphDisabled; - options.dropFromOthersDisabled; - options.dropTargetStyle; - var dropTargetClasses = options.dropTargetClasses; - options.transformDraggedElement; - options.autoAriaDisabled; - options.centreDraggedOnCursor; - var rest = _objectWithoutProperties(options, ["items", "flipDurationMs", "type", "dragDisabled", "morphDisabled", "dropFromOthersDisabled", "dropTargetStyle", "dropTargetClasses", "transformDraggedElement", "autoAriaDisabled", "centreDraggedOnCursor"]); - /*eslint-enable*/ - - - if (Object.keys(rest).length > 0) { - console.warn("dndzone will ignore unknown options", rest); - } - - if (!items) { - throw new Error("no 'items' key provided to dndzone"); - } - - var itemWithMissingId = items.find(function (item) { - return !{}.hasOwnProperty.call(item, ITEM_ID_KEY); - }); - - if (itemWithMissingId) { - throw new Error("missing '".concat(ITEM_ID_KEY, "' property for item ").concat(toString$1(itemWithMissingId))); - } - - if (dropTargetClasses && !Array.isArray(dropTargetClasses)) { - throw new Error("dropTargetClasses should be an array but instead it is a ".concat(_typeof(dropTargetClasses), ", ").concat(toString$1(dropTargetClasses))); - } -} - -/* src/gui/choiceList/ChoiceList.svelte generated by Svelte v3.43.0 */ - -function add_css$6(target) { - append_styles(target, "svelte-jb273g", ".choiceList.svelte-jb273g{width:auto;border:0 solid black;overflow-y:auto;height:auto}"); -} - -function get_each_context$2(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[21] = list[i]; - child_ctx[22] = list; - child_ctx[23] = i; - return child_ctx; -} - -// (51:8) {:else} -function create_else_block$1(ctx) { - let multichoicelistitem; - let updating_dragDisabled; - let updating_collapseId; - let updating_choice; - let current; - - function multichoicelistitem_dragDisabled_binding(value) { - /*multichoicelistitem_dragDisabled_binding*/ ctx[13](value); - } - - function multichoicelistitem_collapseId_binding(value) { - /*multichoicelistitem_collapseId_binding*/ ctx[14](value); - } - - function multichoicelistitem_choice_binding(value) { - /*multichoicelistitem_choice_binding*/ ctx[15](value, /*choice*/ ctx[21], /*each_value*/ ctx[22], /*choice_index*/ ctx[23]); - } - - let multichoicelistitem_props = {}; - - if (/*dragDisabled*/ ctx[3] !== void 0) { - multichoicelistitem_props.dragDisabled = /*dragDisabled*/ ctx[3]; - } - - if (/*collapseId*/ ctx[2] !== void 0) { - multichoicelistitem_props.collapseId = /*collapseId*/ ctx[2]; - } - - if (/*choice*/ ctx[21] !== void 0) { - multichoicelistitem_props.choice = /*choice*/ ctx[21]; - } - - multichoicelistitem = new MultiChoiceListItem({ props: multichoicelistitem_props }); - binding_callbacks.push(() => bind(multichoicelistitem, 'dragDisabled', multichoicelistitem_dragDisabled_binding)); - binding_callbacks.push(() => bind(multichoicelistitem, 'collapseId', multichoicelistitem_collapseId_binding)); - binding_callbacks.push(() => bind(multichoicelistitem, 'choice', multichoicelistitem_choice_binding)); - multichoicelistitem.$on("mousedown", /*startDrag*/ ctx[6]); - multichoicelistitem.$on("touchstart", /*startDrag*/ ctx[6]); - multichoicelistitem.$on("deleteChoice", /*deleteChoice_handler_1*/ ctx[16]); - multichoicelistitem.$on("configureChoice", /*configureChoice_handler_1*/ ctx[17]); - multichoicelistitem.$on("toggleCommand", /*toggleCommand_handler_1*/ ctx[18]); - - return { - c() { - create_component(multichoicelistitem.$$.fragment); - }, - m(target, anchor) { - mount_component(multichoicelistitem, target, anchor); - current = true; - }, - p(new_ctx, dirty) { - ctx = new_ctx; - const multichoicelistitem_changes = {}; - - if (!updating_dragDisabled && dirty & /*dragDisabled*/ 8) { - updating_dragDisabled = true; - multichoicelistitem_changes.dragDisabled = /*dragDisabled*/ ctx[3]; - add_flush_callback(() => updating_dragDisabled = false); - } - - if (!updating_collapseId && dirty & /*collapseId*/ 4) { - updating_collapseId = true; - multichoicelistitem_changes.collapseId = /*collapseId*/ ctx[2]; - add_flush_callback(() => updating_collapseId = false); - } - - if (!updating_choice && dirty & /*choices, SHADOW_PLACEHOLDER_ITEM_ID*/ 3) { - updating_choice = true; - multichoicelistitem_changes.choice = /*choice*/ ctx[21]; - add_flush_callback(() => updating_choice = false); - } - - multichoicelistitem.$set(multichoicelistitem_changes); - }, - i(local) { - if (current) return; - transition_in(multichoicelistitem.$$.fragment, local); - current = true; - }, - o(local) { - transition_out(multichoicelistitem.$$.fragment, local); - current = false; - }, - d(detaching) { - destroy_component(multichoicelistitem, detaching); - } - }; -} - -// (41:8) {#if choice.type !== ChoiceType.Multi} -function create_if_block$1(ctx) { - let choicelistitem; - let updating_dragDisabled; - let updating_choice; - let current; - - function choicelistitem_dragDisabled_binding(value) { - /*choicelistitem_dragDisabled_binding*/ ctx[8](value); - } - - function choicelistitem_choice_binding(value) { - /*choicelistitem_choice_binding*/ ctx[9](value, /*choice*/ ctx[21], /*each_value*/ ctx[22], /*choice_index*/ ctx[23]); - } - - let choicelistitem_props = {}; - - if (/*dragDisabled*/ ctx[3] !== void 0) { - choicelistitem_props.dragDisabled = /*dragDisabled*/ ctx[3]; - } - - if (/*choice*/ ctx[21] !== void 0) { - choicelistitem_props.choice = /*choice*/ ctx[21]; - } - - choicelistitem = new ChoiceListItem({ props: choicelistitem_props }); - binding_callbacks.push(() => bind(choicelistitem, 'dragDisabled', choicelistitem_dragDisabled_binding)); - binding_callbacks.push(() => bind(choicelistitem, 'choice', choicelistitem_choice_binding)); - choicelistitem.$on("mousedown", /*startDrag*/ ctx[6]); - choicelistitem.$on("touchstart", /*startDrag*/ ctx[6]); - choicelistitem.$on("deleteChoice", /*deleteChoice_handler*/ ctx[10]); - choicelistitem.$on("configureChoice", /*configureChoice_handler*/ ctx[11]); - choicelistitem.$on("toggleCommand", /*toggleCommand_handler*/ ctx[12]); - - return { - c() { - create_component(choicelistitem.$$.fragment); - }, - m(target, anchor) { - mount_component(choicelistitem, target, anchor); - current = true; - }, - p(new_ctx, dirty) { - ctx = new_ctx; - const choicelistitem_changes = {}; - - if (!updating_dragDisabled && dirty & /*dragDisabled*/ 8) { - updating_dragDisabled = true; - choicelistitem_changes.dragDisabled = /*dragDisabled*/ ctx[3]; - add_flush_callback(() => updating_dragDisabled = false); - } - - if (!updating_choice && dirty & /*choices, SHADOW_PLACEHOLDER_ITEM_ID*/ 3) { - updating_choice = true; - choicelistitem_changes.choice = /*choice*/ ctx[21]; - add_flush_callback(() => updating_choice = false); - } - - choicelistitem.$set(choicelistitem_changes); - }, - i(local) { - if (current) return; - transition_in(choicelistitem.$$.fragment, local); - current = true; - }, - o(local) { - transition_out(choicelistitem.$$.fragment, local); - current = false; - }, - d(detaching) { - destroy_component(choicelistitem, detaching); - } - }; -} - -// (40:4) {#each choices.filter(c => c.id !== SHADOW_PLACEHOLDER_ITEM_ID) as choice(choice.id)} -function create_each_block$2(key_1, ctx) { - let first; - let current_block_type_index; - let if_block; - let if_block_anchor; - let current; - const if_block_creators = [create_if_block$1, create_else_block$1]; - const if_blocks = []; - - function select_block_type(ctx, dirty) { - if (/*choice*/ ctx[21].type !== ChoiceType.Multi) return 0; - return 1; - } - - current_block_type_index = select_block_type(ctx); - if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx); - - return { - key: key_1, - first: null, - c() { - first = empty(); - if_block.c(); - if_block_anchor = empty(); - this.first = first; - }, - m(target, anchor) { - insert(target, first, anchor); - if_blocks[current_block_type_index].m(target, anchor); - insert(target, if_block_anchor, anchor); - current = true; - }, - p(new_ctx, dirty) { - ctx = new_ctx; - let previous_block_index = current_block_type_index; - current_block_type_index = select_block_type(ctx); - - if (current_block_type_index === previous_block_index) { - if_blocks[current_block_type_index].p(ctx, dirty); - } else { - group_outros(); - - transition_out(if_blocks[previous_block_index], 1, 1, () => { - if_blocks[previous_block_index] = null; - }); - - check_outros(); - if_block = if_blocks[current_block_type_index]; - - if (!if_block) { - if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx); - if_block.c(); - } else { - if_block.p(ctx, dirty); - } - - transition_in(if_block, 1); - if_block.m(if_block_anchor.parentNode, if_block_anchor); - } - }, - i(local) { - if (current) return; - transition_in(if_block); - current = true; - }, - o(local) { - transition_out(if_block); - current = false; - }, - d(detaching) { - if (detaching) detach(first); - if_blocks[current_block_type_index].d(detaching); - if (detaching) detach(if_block_anchor); - } - }; -} - -function create_fragment$a(ctx) { - let div; - let each_blocks = []; - let each_1_lookup = new Map(); - let div_style_value; - let dndzone_action; - let current; - let mounted; - let dispose; - let each_value = /*choices*/ ctx[0].filter(/*func*/ ctx[7]); - const get_key = ctx => /*choice*/ ctx[21].id; - - for (let i = 0; i < each_value.length; i += 1) { - let child_ctx = get_each_context$2(ctx, each_value, i); - let key = get_key(child_ctx); - each_1_lookup.set(key, each_blocks[i] = create_each_block$2(key, child_ctx)); - } - - return { - c() { - div = element("div"); - - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].c(); - } - - attr(div, "class", "choiceList svelte-jb273g"); - - attr(div, "style", div_style_value = /*choices*/ ctx[0].length === 0 - ? 'padding-bottom: 0.5rem' - : ''); - }, - m(target, anchor) { - insert(target, div, anchor); - - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].m(div, null); - } - - current = true; - - if (!mounted) { - dispose = [ - action_destroyer(dndzone_action = dndzone$2.call(null, div, { - items: /*choices*/ ctx[0], - dragDisabled: /*dragDisabled*/ ctx[3], - dropTargetStyle: {} - })), - listen(div, "consider", /*handleConsider*/ ctx[4]), - listen(div, "finalize", /*handleSort*/ ctx[5]) - ]; - - mounted = true; - } - }, - p(ctx, [dirty]) { - if (dirty & /*dragDisabled, choices, SHADOW_PLACEHOLDER_ITEM_ID, startDrag, ChoiceType, collapseId*/ 79) { - each_value = /*choices*/ ctx[0].filter(/*func*/ ctx[7]); - group_outros(); - each_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, div, outro_and_destroy_block, create_each_block$2, null, get_each_context$2); - check_outros(); - } - - if (!current || dirty & /*choices*/ 1 && div_style_value !== (div_style_value = /*choices*/ ctx[0].length === 0 - ? 'padding-bottom: 0.5rem' - : '')) { - attr(div, "style", div_style_value); - } - - if (dndzone_action && is_function(dndzone_action.update) && dirty & /*choices, dragDisabled*/ 9) dndzone_action.update.call(null, { - items: /*choices*/ ctx[0], - dragDisabled: /*dragDisabled*/ ctx[3], - dropTargetStyle: {} - }); - }, - i(local) { - if (current) return; - - for (let i = 0; i < each_value.length; i += 1) { - transition_in(each_blocks[i]); - } - - current = true; - }, - o(local) { - for (let i = 0; i < each_blocks.length; i += 1) { - transition_out(each_blocks[i]); - } - - current = false; - }, - d(detaching) { - if (detaching) detach(div); - - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].d(); - } - - mounted = false; - run_all(dispose); - } - }; -} - -function instance$a($$self, $$props, $$invalidate) { - let { choices = [] } = $$props; - let collapseId; - let dragDisabled = true; - const dispatcher = createEventDispatcher(); - - function emitChoicesReordered() { - dispatcher('reorderChoices', { choices }); - } - - function handleConsider(e) { - let { items: newItems, info: { id } } = e.detail; - $$invalidate(2, collapseId = id); - $$invalidate(0, choices = newItems); - } - - function handleSort(e) { - let { items: newItems, info: { source } } = e.detail; - $$invalidate(2, collapseId = ""); - $$invalidate(0, choices = newItems); - - if (source === SOURCES.POINTER) { - $$invalidate(3, dragDisabled = true); - } - - emitChoicesReordered(); - } - - function startDrag(e) { - e.preventDefault(); - $$invalidate(3, dragDisabled = false); - } - - const func = c => c.id !== SHADOW_PLACEHOLDER_ITEM_ID; - - function choicelistitem_dragDisabled_binding(value) { - dragDisabled = value; - $$invalidate(3, dragDisabled); - } - - function choicelistitem_choice_binding(value, choice, each_value, choice_index) { - each_value[choice_index] = value; - $$invalidate(0, choices); - } - - function deleteChoice_handler(event) { - bubble.call(this, $$self, event); - } - - function configureChoice_handler(event) { - bubble.call(this, $$self, event); - } - - function toggleCommand_handler(event) { - bubble.call(this, $$self, event); - } - - function multichoicelistitem_dragDisabled_binding(value) { - dragDisabled = value; - $$invalidate(3, dragDisabled); - } - - function multichoicelistitem_collapseId_binding(value) { - collapseId = value; - $$invalidate(2, collapseId); - } - - function multichoicelistitem_choice_binding(value, choice, each_value, choice_index) { - each_value[choice_index] = value; - $$invalidate(0, choices); - } - - function deleteChoice_handler_1(event) { - bubble.call(this, $$self, event); - } - - function configureChoice_handler_1(event) { - bubble.call(this, $$self, event); - } - - function toggleCommand_handler_1(event) { - bubble.call(this, $$self, event); - } - - $$self.$$set = $$props => { - if ('choices' in $$props) $$invalidate(0, choices = $$props.choices); - }; - - return [ - choices, - SHADOW_PLACEHOLDER_ITEM_ID, - collapseId, - dragDisabled, - handleConsider, - handleSort, - startDrag, - func, - choicelistitem_dragDisabled_binding, - choicelistitem_choice_binding, - deleteChoice_handler, - configureChoice_handler, - toggleCommand_handler, - multichoicelistitem_dragDisabled_binding, - multichoicelistitem_collapseId_binding, - multichoicelistitem_choice_binding, - deleteChoice_handler_1, - configureChoice_handler_1, - toggleCommand_handler_1 - ]; -} - -class ChoiceList extends SvelteComponent { - constructor(options) { - super(); - init(this, options, instance$a, create_fragment$a, safe_not_equal, { choices: 0 }, add_css$6); - } -} - -/* src/gui/choiceList/AddChoiceBox.svelte generated by Svelte v3.43.0 */ - -function add_css$5(target) { - append_styles(target, "svelte-1newuee", ".addChoiceBox.svelte-1newuee{margin-top:1em;display:flex;flex-direction:row;align-items:center;gap:10px;justify-content:center}@media(max-width: 800px){.addChoiceBox.svelte-1newuee{flex-direction:column}}#addChoiceTypeSelector.svelte-1newuee{font-size:16px;padding:3px;border-radius:3px}"); -} - -function create_fragment$9(ctx) { - let div; - let input; - let t0; - let select; - let option0; - let t1_value = ChoiceType.Template + ""; - let t1; - let option1; - let t2_value = ChoiceType.Capture + ""; - let t2; - let option2; - let t3_value = ChoiceType.Macro + ""; - let t3; - let option3; - let t4_value = ChoiceType.Multi + ""; - let t4; - let t5; - let button; - let mounted; - let dispose; - - return { - c() { - div = element("div"); - input = element("input"); - t0 = space(); - select = element("select"); - option0 = element("option"); - t1 = text(t1_value); - option1 = element("option"); - t2 = text(t2_value); - option2 = element("option"); - t3 = text(t3_value); - option3 = element("option"); - t4 = text(t4_value); - t5 = space(); - button = element("button"); - button.textContent = "Add Choice"; - attr(input, "type", "text"); - attr(input, "placeholder", "Name"); - option0.__value = ChoiceType.Template; - option0.value = option0.__value; - option1.__value = ChoiceType.Capture; - option1.value = option1.__value; - option2.__value = ChoiceType.Macro; - option2.value = option2.__value; - option3.__value = ChoiceType.Multi; - option3.value = option3.__value; - attr(select, "id", "addChoiceTypeSelector"); - attr(select, "class", "svelte-1newuee"); - if (/*type*/ ctx[1] === void 0) add_render_callback(() => /*select_change_handler*/ ctx[4].call(select)); - attr(button, "class", "mod-cta"); - attr(div, "class", "addChoiceBox svelte-1newuee"); - }, - m(target, anchor) { - insert(target, div, anchor); - append(div, input); - set_input_value(input, /*name*/ ctx[0]); - append(div, t0); - append(div, select); - append(select, option0); - append(option0, t1); - append(select, option1); - append(option1, t2); - append(select, option2); - append(option2, t3); - append(select, option3); - append(option3, t4); - select_option(select, /*type*/ ctx[1]); - append(div, t5); - append(div, button); - - if (!mounted) { - dispose = [ - listen(input, "input", /*input_input_handler*/ ctx[3]), - listen(select, "change", /*select_change_handler*/ ctx[4]), - listen(button, "click", /*addChoice*/ ctx[2]) - ]; - - mounted = true; - } - }, - p(ctx, [dirty]) { - if (dirty & /*name*/ 1 && input.value !== /*name*/ ctx[0]) { - set_input_value(input, /*name*/ ctx[0]); - } - - if (dirty & /*type, ChoiceType*/ 2) { - select_option(select, /*type*/ ctx[1]); - } - }, - i: noop, - o: noop, - d(detaching) { - if (detaching) detach(div); - mounted = false; - run_all(dispose); - } - }; -} - -function instance$9($$self, $$props, $$invalidate) { - let name; - let type; - const dispatch = createEventDispatcher(); - - function addChoice() { - if (!name) { - new obsidian.Notice("Choice name is invalid."); - return; - } - - dispatch('addChoice', { name, type }); - $$invalidate(0, name = ""); - } - - function input_input_handler() { - name = this.value; - $$invalidate(0, name); - } - - function select_change_handler() { - type = select_value(this); - $$invalidate(1, type); - } - - return [name, type, addChoice, input_input_handler, select_change_handler]; -} - -class AddChoiceBox extends SvelteComponent { - constructor(options) { - super(); - init(this, options, instance$9, create_fragment$9, safe_not_equal, {}, add_css$5); - } -} - -// Unique ID creation requires a high quality random # generator. In the browser we therefore -// require the crypto API and do not support built-in fallback to lower quality random number -// generators (like Math.random()). -var getRandomValues; -var rnds8 = new Uint8Array(16); -function rng() { - // lazy load so that environments that need to polyfill have a chance to do so - if (!getRandomValues) { - // getRandomValues needs to be invoked in a context where "this" is a Crypto implementation. Also, - // find the complete implementation of crypto (msCrypto) on IE11. - getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto !== 'undefined' && typeof msCrypto.getRandomValues === 'function' && msCrypto.getRandomValues.bind(msCrypto); - - if (!getRandomValues) { - throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported'); - } - } - - return getRandomValues(rnds8); -} - -var REGEX = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i; - -function validate(uuid) { - return typeof uuid === 'string' && REGEX.test(uuid); -} - -/** - * Convert array of 16 byte values to UUID string format of the form: - * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX - */ - -var byteToHex = []; - -for (var i = 0; i < 256; ++i) { - byteToHex.push((i + 0x100).toString(16).substr(1)); -} - -function stringify(arr) { - var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; - // Note: Be careful editing this code! It's been tuned for performance - // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 - var uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one - // of the following: - // - One or more input array values don't map to a hex octet (leading to - // "undefined" in the uuid) - // - Invalid input values for the RFC `version` or `variant` fields - - if (!validate(uuid)) { - throw TypeError('Stringified UUID is invalid'); - } - - return uuid; -} - -function v4(options, buf, offset) { - options = options || {}; - var rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` - - rnds[6] = rnds[6] & 0x0f | 0x40; - rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided - - if (buf) { - offset = offset || 0; - - for (var i = 0; i < 16; ++i) { - buf[offset + i] = rnds[i]; - } - - return buf; - } - - return stringify(rnds); -} - -class Choice { - constructor(name, type) { - this.id = v4(); - this.name = name; - this.type = type; - this.command = false; - } -} - -var NewTabDirection; -(function (NewTabDirection) { - NewTabDirection["vertical"] = "vertical"; - NewTabDirection["horizontal"] = "horizontal"; -})(NewTabDirection || (NewTabDirection = {})); - -class TemplateChoice extends Choice { - constructor(name) { - super(name, ChoiceType.Template); - this.templatePath = ""; - this.fileNameFormat = { enabled: false, format: "" }; - this.folder = { enabled: false, folders: [], chooseWhenCreatingNote: false, createInSameFolderAsActiveFile: false }; - this.appendLink = false; - this.incrementFileName = false; - this.openFileInNewTab = { enabled: false, direction: NewTabDirection.vertical, focus: true }; - this.openFile = false; - this.openFileInMode = 'default'; - } - static Load(choice) { - return choice; - } -} - -class MacroChoice extends Choice { - constructor(name) { - super(name, ChoiceType.Macro); - this.macroId = null; - } -} - -class CaptureChoice extends Choice { - constructor(name) { - super(name, ChoiceType.Capture); - this.appendLink = false; - this.captureTo = ""; - this.captureToActiveFile = false; - this.createFileIfItDoesntExist = { enabled: false, createWithTemplate: false, template: "" }; - this.format = { enabled: false, format: "" }; - this.insertAfter = { enabled: false, after: "", insertAtEnd: false, createIfNotFound: false, createIfNotFoundLocation: "top" }; - this.prepend = false; - this.task = false; - this.openFileInNewTab = { enabled: false, direction: NewTabDirection.vertical, focus: true }; - this.openFile = false; - this.openFileInMode = 'default'; - } - static Load(choice) { - return choice; - } -} - -class MultiChoice extends Choice { - constructor(name) { - super(name, ChoiceType.Multi); - this.choices = []; - } - addChoice(choice) { - this.choices.push(choice); - return this; - } - addChoices(choices) { - this.choices.push(...choices); - return this; - } -} - -/* src/gui/GenericYesNoPrompt/GenericYesNoPromptContent.svelte generated by Svelte v3.43.0 */ - -function add_css$4(target) { - append_styles(target, "svelte-1qg9c18", ".yesNoPromptButtonContainer.svelte-1qg9c18{display:flex;align-items:center;justify-content:space-around;margin-top:2rem}p.svelte-1qg9c18{text-align:center}button.svelte-1qg9c18{font-size:18px}"); -} - -function create_fragment$8(ctx) { - let div1; - let h1; - let t0; - let t1; - let p; - let t2; - let t3; - let div0; - let button0; - let t5; - let button1; - let mounted; - let dispose; - - return { - c() { - div1 = element("div"); - h1 = element("h1"); - t0 = text(/*header*/ ctx[0]); - t1 = space(); - p = element("p"); - t2 = text(/*text*/ ctx[1]); - t3 = space(); - div0 = element("div"); - button0 = element("button"); - button0.textContent = "No"; - t5 = space(); - button1 = element("button"); - button1.textContent = "Yes"; - set_style(h1, "text-align", "center"); - attr(p, "class", "svelte-1qg9c18"); - attr(button0, "class", "mod-warning svelte-1qg9c18"); - attr(button1, "class", "mod-cta svelte-1qg9c18"); - attr(div0, "class", "yesNoPromptButtonContainer svelte-1qg9c18"); - attr(div1, "class", "quickAddYesNoPrompt"); - }, - m(target, anchor) { - insert(target, div1, anchor); - append(div1, h1); - append(h1, t0); - append(div1, t1); - append(div1, p); - append(p, t2); - append(div1, t3); - append(div1, div0); - append(div0, button0); - append(div0, t5); - append(div0, button1); - - if (!mounted) { - dispose = [ - listen(button0, "click", /*click_handler*/ ctx[5]), - listen(button1, "click", /*click_handler_1*/ ctx[6]) - ]; - - mounted = true; - } - }, - p(ctx, [dirty]) { - if (dirty & /*header*/ 1) set_data(t0, /*header*/ ctx[0]); - if (dirty & /*text*/ 2) set_data(t2, /*text*/ ctx[1]); - }, - i: noop, - o: noop, - d(detaching) { - if (detaching) detach(div1); - mounted = false; - run_all(dispose); - } - }; -} - -function instance$8($$self, $$props, $$invalidate) { - let { header = "" } = $$props; - let { value = "" } = $$props; - let { text = "" } = $$props; - let { onSubmit } = $$props; - - function submit(answer) { - onSubmit(answer); - } - - const click_handler = () => submit(false); - const click_handler_1 = () => submit(true); - - $$self.$$set = $$props => { - if ('header' in $$props) $$invalidate(0, header = $$props.header); - if ('value' in $$props) $$invalidate(3, value = $$props.value); - if ('text' in $$props) $$invalidate(1, text = $$props.text); - if ('onSubmit' in $$props) $$invalidate(4, onSubmit = $$props.onSubmit); - }; - - return [header, text, submit, value, onSubmit, click_handler, click_handler_1]; -} - -class GenericYesNoPromptContent extends SvelteComponent { - constructor(options) { - super(); - - init( - this, - options, - instance$8, - create_fragment$8, - safe_not_equal, - { - header: 0, - value: 3, - text: 1, - onSubmit: 4 - }, - add_css$4 - ); - } -} - -class GenericYesNoPrompt extends obsidian.Modal { - constructor(app, header, text) { - super(app); - this.didSubmit = false; - this.modalContent = new GenericYesNoPromptContent({ - target: this.contentEl, - props: { - app, - header, - text, - onSubmit: (input) => { - this.input = input; - this.didSubmit = true; - this.close(); - } - } - }); - this.waitForClose = new Promise((resolve, reject) => { - this.resolvePromise = resolve; - this.rejectPromise = reject; - }); - this.open(); - } - static Prompt(app, header, text) { - const newPromptModal = new GenericYesNoPrompt(app, header, text); - return newPromptModal.waitForClose; - } - onClose() { - super.onClose(); - this.modalContent.$destroy(); - if (!this.didSubmit) - this.rejectPromise("No answer given."); - else - this.resolvePromise(this.input); - } -} - -var top = 'top'; -var bottom = 'bottom'; -var right = 'right'; -var left = 'left'; -var auto = 'auto'; -var basePlacements = [top, bottom, right, left]; -var start = 'start'; -var end = 'end'; -var clippingParents = 'clippingParents'; -var viewport = 'viewport'; -var popper = 'popper'; -var reference = 'reference'; -var variationPlacements = /*#__PURE__*/basePlacements.reduce(function (acc, placement) { - return acc.concat([placement + "-" + start, placement + "-" + end]); -}, []); -var placements = /*#__PURE__*/[].concat(basePlacements, [auto]).reduce(function (acc, placement) { - return acc.concat([placement, placement + "-" + start, placement + "-" + end]); -}, []); // modifiers that need to read the DOM - -var beforeRead = 'beforeRead'; -var read = 'read'; -var afterRead = 'afterRead'; // pure-logic modifiers - -var beforeMain = 'beforeMain'; -var main = 'main'; -var afterMain = 'afterMain'; // modifier with the purpose to write to the DOM (or write into a framework state) - -var beforeWrite = 'beforeWrite'; -var write = 'write'; -var afterWrite = 'afterWrite'; -var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite]; - -function getNodeName(element) { - return element ? (element.nodeName || '').toLowerCase() : null; -} - -function getWindow(node) { - if (node == null) { - return window; - } - - if (node.toString() !== '[object Window]') { - var ownerDocument = node.ownerDocument; - return ownerDocument ? ownerDocument.defaultView || window : window; - } - - return node; -} - -function isElement(node) { - var OwnElement = getWindow(node).Element; - return node instanceof OwnElement || node instanceof Element; -} - -function isHTMLElement(node) { - var OwnElement = getWindow(node).HTMLElement; - return node instanceof OwnElement || node instanceof HTMLElement; -} - -function isShadowRoot(node) { - // IE 11 has no ShadowRoot - if (typeof ShadowRoot === 'undefined') { - return false; - } - - var OwnElement = getWindow(node).ShadowRoot; - return node instanceof OwnElement || node instanceof ShadowRoot; -} - -// and applies them to the HTMLElements such as popper and arrow - -function applyStyles(_ref) { - var state = _ref.state; - Object.keys(state.elements).forEach(function (name) { - var style = state.styles[name] || {}; - var attributes = state.attributes[name] || {}; - var element = state.elements[name]; // arrow is optional + virtual elements - - if (!isHTMLElement(element) || !getNodeName(element)) { - return; - } // Flow doesn't support to extend this property, but it's the most - // effective way to apply styles to an HTMLElement - // $FlowFixMe[cannot-write] - - - Object.assign(element.style, style); - Object.keys(attributes).forEach(function (name) { - var value = attributes[name]; - - if (value === false) { - element.removeAttribute(name); - } else { - element.setAttribute(name, value === true ? '' : value); - } - }); - }); -} - -function effect$2(_ref2) { - var state = _ref2.state; - var initialStyles = { - popper: { - position: state.options.strategy, - left: '0', - top: '0', - margin: '0' - }, - arrow: { - position: 'absolute' - }, - reference: {} - }; - Object.assign(state.elements.popper.style, initialStyles.popper); - state.styles = initialStyles; - - if (state.elements.arrow) { - Object.assign(state.elements.arrow.style, initialStyles.arrow); - } - - return function () { - Object.keys(state.elements).forEach(function (name) { - var element = state.elements[name]; - var attributes = state.attributes[name] || {}; - var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); // Set all values to an empty string to unset them - - var style = styleProperties.reduce(function (style, property) { - style[property] = ''; - return style; - }, {}); // arrow is optional + virtual elements - - if (!isHTMLElement(element) || !getNodeName(element)) { - return; - } - - Object.assign(element.style, style); - Object.keys(attributes).forEach(function (attribute) { - element.removeAttribute(attribute); - }); - }); - }; -} // eslint-disable-next-line import/no-unused-modules - - -var applyStyles$1 = { - name: 'applyStyles', - enabled: true, - phase: 'write', - fn: applyStyles, - effect: effect$2, - requires: ['computeStyles'] -}; - -function getBasePlacement(placement) { - return placement.split('-')[0]; -} - -var round$1 = Math.round; -function getBoundingClientRect(element, includeScale) { - if (includeScale === void 0) { - includeScale = false; - } - - var rect = element.getBoundingClientRect(); - var scaleX = 1; - var scaleY = 1; - - if (isHTMLElement(element) && includeScale) { - var offsetHeight = element.offsetHeight; - var offsetWidth = element.offsetWidth; // Do not attempt to divide by 0, otherwise we get `Infinity` as scale - // Fallback to 1 in case both values are `0` - - if (offsetWidth > 0) { - scaleX = rect.width / offsetWidth || 1; - } - - if (offsetHeight > 0) { - scaleY = rect.height / offsetHeight || 1; - } - } - - return { - width: round$1(rect.width / scaleX), - height: round$1(rect.height / scaleY), - top: round$1(rect.top / scaleY), - right: round$1(rect.right / scaleX), - bottom: round$1(rect.bottom / scaleY), - left: round$1(rect.left / scaleX), - x: round$1(rect.left / scaleX), - y: round$1(rect.top / scaleY) - }; -} - -// means it doesn't take into account transforms. - -function getLayoutRect(element) { - var clientRect = getBoundingClientRect(element); // Use the clientRect sizes if it's not been transformed. - // Fixes https://github.com/popperjs/popper-core/issues/1223 - - var width = element.offsetWidth; - var height = element.offsetHeight; - - if (Math.abs(clientRect.width - width) <= 1) { - width = clientRect.width; - } - - if (Math.abs(clientRect.height - height) <= 1) { - height = clientRect.height; - } - - return { - x: element.offsetLeft, - y: element.offsetTop, - width: width, - height: height - }; -} - -function contains(parent, child) { - var rootNode = child.getRootNode && child.getRootNode(); // First, attempt with faster native method - - if (parent.contains(child)) { - return true; - } // then fallback to custom implementation with Shadow DOM support - else if (rootNode && isShadowRoot(rootNode)) { - var next = child; - - do { - if (next && parent.isSameNode(next)) { - return true; - } // $FlowFixMe[prop-missing]: need a better way to handle this... - - - next = next.parentNode || next.host; - } while (next); - } // Give up, the result is false - - - return false; -} - -function getComputedStyle$1(element) { - return getWindow(element).getComputedStyle(element); -} - -function isTableElement(element) { - return ['table', 'td', 'th'].indexOf(getNodeName(element)) >= 0; -} - -function getDocumentElement(element) { - // $FlowFixMe[incompatible-return]: assume body is always available - return ((isElement(element) ? element.ownerDocument : // $FlowFixMe[prop-missing] - element.document) || window.document).documentElement; -} - -function getParentNode(element) { - if (getNodeName(element) === 'html') { - return element; - } - - return (// this is a quicker (but less type safe) way to save quite some bytes from the bundle - // $FlowFixMe[incompatible-return] - // $FlowFixMe[prop-missing] - element.assignedSlot || // step into the shadow DOM of the parent of a slotted node - element.parentNode || ( // DOM Element detected - isShadowRoot(element) ? element.host : null) || // ShadowRoot detected - // $FlowFixMe[incompatible-call]: HTMLElement is a Node - getDocumentElement(element) // fallback - - ); -} - -function getTrueOffsetParent(element) { - if (!isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837 - getComputedStyle$1(element).position === 'fixed') { - return null; - } - - return element.offsetParent; -} // `.offsetParent` reports `null` for fixed elements, while absolute elements -// return the containing block - - -function getContainingBlock(element) { - var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') !== -1; - var isIE = navigator.userAgent.indexOf('Trident') !== -1; - - if (isIE && isHTMLElement(element)) { - // In IE 9, 10 and 11 fixed elements containing block is always established by the viewport - var elementCss = getComputedStyle$1(element); - - if (elementCss.position === 'fixed') { - return null; - } - } - - var currentNode = getParentNode(element); - - while (isHTMLElement(currentNode) && ['html', 'body'].indexOf(getNodeName(currentNode)) < 0) { - var css = getComputedStyle$1(currentNode); // This is non-exhaustive but covers the most common CSS properties that - // create a containing block. - // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block - - if (css.transform !== 'none' || css.perspective !== 'none' || css.contain === 'paint' || ['transform', 'perspective'].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === 'filter' || isFirefox && css.filter && css.filter !== 'none') { - return currentNode; - } else { - currentNode = currentNode.parentNode; - } - } - - return null; -} // Gets the closest ancestor positioned element. Handles some edge cases, -// such as table ancestors and cross browser bugs. - - -function getOffsetParent(element) { - var window = getWindow(element); - var offsetParent = getTrueOffsetParent(element); - - while (offsetParent && isTableElement(offsetParent) && getComputedStyle$1(offsetParent).position === 'static') { - offsetParent = getTrueOffsetParent(offsetParent); - } - - if (offsetParent && (getNodeName(offsetParent) === 'html' || getNodeName(offsetParent) === 'body' && getComputedStyle$1(offsetParent).position === 'static')) { - return window; - } - - return offsetParent || getContainingBlock(element) || window; -} - -function getMainAxisFromPlacement(placement) { - return ['top', 'bottom'].indexOf(placement) >= 0 ? 'x' : 'y'; -} - -var max = Math.max; -var min = Math.min; -var round = Math.round; - -function within(min$1, value, max$1) { - return max(min$1, min(value, max$1)); -} - -function getFreshSideObject() { - return { - top: 0, - right: 0, - bottom: 0, - left: 0 - }; -} - -function mergePaddingObject(paddingObject) { - return Object.assign({}, getFreshSideObject(), paddingObject); -} - -function expandToHashMap(value, keys) { - return keys.reduce(function (hashMap, key) { - hashMap[key] = value; - return hashMap; - }, {}); -} - -var toPaddingObject = function toPaddingObject(padding, state) { - padding = typeof padding === 'function' ? padding(Object.assign({}, state.rects, { - placement: state.placement - })) : padding; - return mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements)); -}; - -function arrow(_ref) { - var _state$modifiersData$; - - var state = _ref.state, - name = _ref.name, - options = _ref.options; - var arrowElement = state.elements.arrow; - var popperOffsets = state.modifiersData.popperOffsets; - var basePlacement = getBasePlacement(state.placement); - var axis = getMainAxisFromPlacement(basePlacement); - var isVertical = [left, right].indexOf(basePlacement) >= 0; - var len = isVertical ? 'height' : 'width'; - - if (!arrowElement || !popperOffsets) { - return; - } - - var paddingObject = toPaddingObject(options.padding, state); - var arrowRect = getLayoutRect(arrowElement); - var minProp = axis === 'y' ? top : left; - var maxProp = axis === 'y' ? bottom : right; - var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets[axis] - state.rects.popper[len]; - var startDiff = popperOffsets[axis] - state.rects.reference[axis]; - var arrowOffsetParent = getOffsetParent(arrowElement); - var clientSize = arrowOffsetParent ? axis === 'y' ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0; - var centerToReference = endDiff / 2 - startDiff / 2; // Make sure the arrow doesn't overflow the popper if the center point is - // outside of the popper bounds - - var min = paddingObject[minProp]; - var max = clientSize - arrowRect[len] - paddingObject[maxProp]; - var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference; - var offset = within(min, center, max); // Prevents breaking syntax highlighting... - - var axisProp = axis; - state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset, _state$modifiersData$.centerOffset = offset - center, _state$modifiersData$); -} - -function effect$1(_ref2) { - var state = _ref2.state, - options = _ref2.options; - var _options$element = options.element, - arrowElement = _options$element === void 0 ? '[data-popper-arrow]' : _options$element; - - if (arrowElement == null) { - return; - } // CSS selector - - - if (typeof arrowElement === 'string') { - arrowElement = state.elements.popper.querySelector(arrowElement); - - if (!arrowElement) { - return; - } - } - - if (process.env.NODE_ENV !== "production") { - if (!isHTMLElement(arrowElement)) { - console.error(['Popper: "arrow" element must be an HTMLElement (not an SVGElement).', 'To use an SVG arrow, wrap it in an HTMLElement that will be used as', 'the arrow.'].join(' ')); - } - } - - if (!contains(state.elements.popper, arrowElement)) { - if (process.env.NODE_ENV !== "production") { - console.error(['Popper: "arrow" modifier\'s `element` must be a child of the popper', 'element.'].join(' ')); - } - - return; - } - - state.elements.arrow = arrowElement; -} // eslint-disable-next-line import/no-unused-modules - - -var arrow$1 = { - name: 'arrow', - enabled: true, - phase: 'main', - fn: arrow, - effect: effect$1, - requires: ['popperOffsets'], - requiresIfExists: ['preventOverflow'] -}; - -function getVariation(placement) { - return placement.split('-')[1]; -} - -var unsetSides = { - top: 'auto', - right: 'auto', - bottom: 'auto', - left: 'auto' -}; // Round the offsets to the nearest suitable subpixel based on the DPR. -// Zooming can change the DPR, but it seems to report a value that will -// cleanly divide the values into the appropriate subpixels. - -function roundOffsetsByDPR(_ref) { - var x = _ref.x, - y = _ref.y; - var win = window; - var dpr = win.devicePixelRatio || 1; - return { - x: round(round(x * dpr) / dpr) || 0, - y: round(round(y * dpr) / dpr) || 0 - }; -} - -function mapToStyles(_ref2) { - var _Object$assign2; - - var popper = _ref2.popper, - popperRect = _ref2.popperRect, - placement = _ref2.placement, - variation = _ref2.variation, - offsets = _ref2.offsets, - position = _ref2.position, - gpuAcceleration = _ref2.gpuAcceleration, - adaptive = _ref2.adaptive, - roundOffsets = _ref2.roundOffsets; - - var _ref3 = roundOffsets === true ? roundOffsetsByDPR(offsets) : typeof roundOffsets === 'function' ? roundOffsets(offsets) : offsets, - _ref3$x = _ref3.x, - x = _ref3$x === void 0 ? 0 : _ref3$x, - _ref3$y = _ref3.y, - y = _ref3$y === void 0 ? 0 : _ref3$y; - - var hasX = offsets.hasOwnProperty('x'); - var hasY = offsets.hasOwnProperty('y'); - var sideX = left; - var sideY = top; - var win = window; - - if (adaptive) { - var offsetParent = getOffsetParent(popper); - var heightProp = 'clientHeight'; - var widthProp = 'clientWidth'; - - if (offsetParent === getWindow(popper)) { - offsetParent = getDocumentElement(popper); - - if (getComputedStyle$1(offsetParent).position !== 'static' && position === 'absolute') { - heightProp = 'scrollHeight'; - widthProp = 'scrollWidth'; - } - } // $FlowFixMe[incompatible-cast]: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it - - - offsetParent = offsetParent; - - if (placement === top || (placement === left || placement === right) && variation === end) { - sideY = bottom; // $FlowFixMe[prop-missing] - - y -= offsetParent[heightProp] - popperRect.height; - y *= gpuAcceleration ? 1 : -1; - } - - if (placement === left || (placement === top || placement === bottom) && variation === end) { - sideX = right; // $FlowFixMe[prop-missing] - - x -= offsetParent[widthProp] - popperRect.width; - x *= gpuAcceleration ? 1 : -1; - } - } - - var commonStyles = Object.assign({ - position: position - }, adaptive && unsetSides); - - if (gpuAcceleration) { - var _Object$assign; - - return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? '0' : '', _Object$assign[sideX] = hasX ? '0' : '', _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? "translate(" + x + "px, " + y + "px)" : "translate3d(" + x + "px, " + y + "px, 0)", _Object$assign)); - } - - return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + "px" : '', _Object$assign2[sideX] = hasX ? x + "px" : '', _Object$assign2.transform = '', _Object$assign2)); -} - -function computeStyles(_ref4) { - var state = _ref4.state, - options = _ref4.options; - var _options$gpuAccelerat = options.gpuAcceleration, - gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat, - _options$adaptive = options.adaptive, - adaptive = _options$adaptive === void 0 ? true : _options$adaptive, - _options$roundOffsets = options.roundOffsets, - roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets; - - if (process.env.NODE_ENV !== "production") { - var transitionProperty = getComputedStyle$1(state.elements.popper).transitionProperty || ''; - - if (adaptive && ['transform', 'top', 'right', 'bottom', 'left'].some(function (property) { - return transitionProperty.indexOf(property) >= 0; - })) { - console.warn(['Popper: Detected CSS transitions on at least one of the following', 'CSS properties: "transform", "top", "right", "bottom", "left".', '\n\n', 'Disable the "computeStyles" modifier\'s `adaptive` option to allow', 'for smooth transitions, or remove these properties from the CSS', 'transition declaration on the popper element if only transitioning', 'opacity or background-color for example.', '\n\n', 'We recommend using the popper element as a wrapper around an inner', 'element that can have any CSS property transitioned for animations.'].join(' ')); - } - } - - var commonStyles = { - placement: getBasePlacement(state.placement), - variation: getVariation(state.placement), - popper: state.elements.popper, - popperRect: state.rects.popper, - gpuAcceleration: gpuAcceleration - }; - - if (state.modifiersData.popperOffsets != null) { - state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, { - offsets: state.modifiersData.popperOffsets, - position: state.options.strategy, - adaptive: adaptive, - roundOffsets: roundOffsets - }))); - } - - if (state.modifiersData.arrow != null) { - state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, { - offsets: state.modifiersData.arrow, - position: 'absolute', - adaptive: false, - roundOffsets: roundOffsets - }))); - } - - state.attributes.popper = Object.assign({}, state.attributes.popper, { - 'data-popper-placement': state.placement - }); -} // eslint-disable-next-line import/no-unused-modules - - -var computeStyles$1 = { - name: 'computeStyles', - enabled: true, - phase: 'beforeWrite', - fn: computeStyles, - data: {} -}; - -var passive = { - passive: true -}; - -function effect(_ref) { - var state = _ref.state, - instance = _ref.instance, - options = _ref.options; - var _options$scroll = options.scroll, - scroll = _options$scroll === void 0 ? true : _options$scroll, - _options$resize = options.resize, - resize = _options$resize === void 0 ? true : _options$resize; - var window = getWindow(state.elements.popper); - var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper); - - if (scroll) { - scrollParents.forEach(function (scrollParent) { - scrollParent.addEventListener('scroll', instance.update, passive); - }); - } - - if (resize) { - window.addEventListener('resize', instance.update, passive); - } - - return function () { - if (scroll) { - scrollParents.forEach(function (scrollParent) { - scrollParent.removeEventListener('scroll', instance.update, passive); - }); - } - - if (resize) { - window.removeEventListener('resize', instance.update, passive); - } - }; -} // eslint-disable-next-line import/no-unused-modules - - -var eventListeners = { - name: 'eventListeners', - enabled: true, - phase: 'write', - fn: function fn() {}, - effect: effect, - data: {} -}; - -var hash$1 = { - left: 'right', - right: 'left', - bottom: 'top', - top: 'bottom' -}; -function getOppositePlacement(placement) { - return placement.replace(/left|right|bottom|top/g, function (matched) { - return hash$1[matched]; - }); -} - -var hash = { - start: 'end', - end: 'start' -}; -function getOppositeVariationPlacement(placement) { - return placement.replace(/start|end/g, function (matched) { - return hash[matched]; - }); -} - -function getWindowScroll(node) { - var win = getWindow(node); - var scrollLeft = win.pageXOffset; - var scrollTop = win.pageYOffset; - return { - scrollLeft: scrollLeft, - scrollTop: scrollTop - }; -} - -function getWindowScrollBarX(element) { - // If has a CSS width greater than the viewport, then this will be - // incorrect for RTL. - // Popper 1 is broken in this case and never had a bug report so let's assume - // it's not an issue. I don't think anyone ever specifies width on - // anyway. - // Browsers where the left scrollbar doesn't cause an issue report `0` for - // this (e.g. Edge 2019, IE11, Safari) - return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft; -} - -function getViewportRect(element) { - var win = getWindow(element); - var html = getDocumentElement(element); - var visualViewport = win.visualViewport; - var width = html.clientWidth; - var height = html.clientHeight; - var x = 0; - var y = 0; // NB: This isn't supported on iOS <= 12. If the keyboard is open, the popper - // can be obscured underneath it. - // Also, `html.clientHeight` adds the bottom bar height in Safari iOS, even - // if it isn't open, so if this isn't available, the popper will be detected - // to overflow the bottom of the screen too early. - - if (visualViewport) { - width = visualViewport.width; - height = visualViewport.height; // Uses Layout Viewport (like Chrome; Safari does not currently) - // In Chrome, it returns a value very close to 0 (+/-) but contains rounding - // errors due to floating point numbers, so we need to check precision. - // Safari returns a number <= 0, usually < -1 when pinch-zoomed - // Feature detection fails in mobile emulation mode in Chrome. - // Math.abs(win.innerWidth / visualViewport.scale - visualViewport.width) < - // 0.001 - // Fallback here: "Not Safari" userAgent - - if (!/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) { - x = visualViewport.offsetLeft; - y = visualViewport.offsetTop; - } - } - - return { - width: width, - height: height, - x: x + getWindowScrollBarX(element), - y: y - }; -} - -// of the `` and `` rect bounds if horizontally scrollable - -function getDocumentRect(element) { - var _element$ownerDocumen; - - var html = getDocumentElement(element); - var winScroll = getWindowScroll(element); - var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body; - var width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0); - var height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0); - var x = -winScroll.scrollLeft + getWindowScrollBarX(element); - var y = -winScroll.scrollTop; - - if (getComputedStyle$1(body || html).direction === 'rtl') { - x += max(html.clientWidth, body ? body.clientWidth : 0) - width; - } - - return { - width: width, - height: height, - x: x, - y: y - }; -} - -function isScrollParent(element) { - // Firefox wants us to check `-x` and `-y` variations as well - var _getComputedStyle = getComputedStyle$1(element), - overflow = _getComputedStyle.overflow, - overflowX = _getComputedStyle.overflowX, - overflowY = _getComputedStyle.overflowY; - - return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX); -} - -function getScrollParent(node) { - if (['html', 'body', '#document'].indexOf(getNodeName(node)) >= 0) { - // $FlowFixMe[incompatible-return]: assume body is always available - return node.ownerDocument.body; - } - - if (isHTMLElement(node) && isScrollParent(node)) { - return node; - } - - return getScrollParent(getParentNode(node)); -} - -/* -given a DOM element, return the list of all scroll parents, up the list of ancesors -until we get to the top window object. This list is what we attach scroll listeners -to, because if any of these parent elements scroll, we'll need to re-calculate the -reference element's position. -*/ - -function listScrollParents(element, list) { - var _element$ownerDocumen; - - if (list === void 0) { - list = []; - } - - var scrollParent = getScrollParent(element); - var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body); - var win = getWindow(scrollParent); - var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent; - var updatedList = list.concat(target); - return isBody ? updatedList : // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here - updatedList.concat(listScrollParents(getParentNode(target))); -} - -function rectToClientRect(rect) { - return Object.assign({}, rect, { - left: rect.x, - top: rect.y, - right: rect.x + rect.width, - bottom: rect.y + rect.height - }); -} - -function getInnerBoundingClientRect(element) { - var rect = getBoundingClientRect(element); - rect.top = rect.top + element.clientTop; - rect.left = rect.left + element.clientLeft; - rect.bottom = rect.top + element.clientHeight; - rect.right = rect.left + element.clientWidth; - rect.width = element.clientWidth; - rect.height = element.clientHeight; - rect.x = rect.left; - rect.y = rect.top; - return rect; -} - -function getClientRectFromMixedType(element, clippingParent) { - return clippingParent === viewport ? rectToClientRect(getViewportRect(element)) : isHTMLElement(clippingParent) ? getInnerBoundingClientRect(clippingParent) : rectToClientRect(getDocumentRect(getDocumentElement(element))); -} // A "clipping parent" is an overflowable container with the characteristic of -// clipping (or hiding) overflowing elements with a position different from -// `initial` - - -function getClippingParents(element) { - var clippingParents = listScrollParents(getParentNode(element)); - var canEscapeClipping = ['absolute', 'fixed'].indexOf(getComputedStyle$1(element).position) >= 0; - var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element; - - if (!isElement(clipperElement)) { - return []; - } // $FlowFixMe[incompatible-return]: https://github.com/facebook/flow/issues/1414 - - - return clippingParents.filter(function (clippingParent) { - return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== 'body'; - }); -} // Gets the maximum area that the element is visible in due to any number of -// clipping parents - - -function getClippingRect(element, boundary, rootBoundary) { - var mainClippingParents = boundary === 'clippingParents' ? getClippingParents(element) : [].concat(boundary); - var clippingParents = [].concat(mainClippingParents, [rootBoundary]); - var firstClippingParent = clippingParents[0]; - var clippingRect = clippingParents.reduce(function (accRect, clippingParent) { - var rect = getClientRectFromMixedType(element, clippingParent); - accRect.top = max(rect.top, accRect.top); - accRect.right = min(rect.right, accRect.right); - accRect.bottom = min(rect.bottom, accRect.bottom); - accRect.left = max(rect.left, accRect.left); - return accRect; - }, getClientRectFromMixedType(element, firstClippingParent)); - clippingRect.width = clippingRect.right - clippingRect.left; - clippingRect.height = clippingRect.bottom - clippingRect.top; - clippingRect.x = clippingRect.left; - clippingRect.y = clippingRect.top; - return clippingRect; -} - -function computeOffsets(_ref) { - var reference = _ref.reference, - element = _ref.element, - placement = _ref.placement; - var basePlacement = placement ? getBasePlacement(placement) : null; - var variation = placement ? getVariation(placement) : null; - var commonX = reference.x + reference.width / 2 - element.width / 2; - var commonY = reference.y + reference.height / 2 - element.height / 2; - var offsets; - - switch (basePlacement) { - case top: - offsets = { - x: commonX, - y: reference.y - element.height - }; - break; - - case bottom: - offsets = { - x: commonX, - y: reference.y + reference.height - }; - break; - - case right: - offsets = { - x: reference.x + reference.width, - y: commonY - }; - break; - - case left: - offsets = { - x: reference.x - element.width, - y: commonY - }; - break; - - default: - offsets = { - x: reference.x, - y: reference.y - }; - } - - var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null; - - if (mainAxis != null) { - var len = mainAxis === 'y' ? 'height' : 'width'; - - switch (variation) { - case start: - offsets[mainAxis] = offsets[mainAxis] - (reference[len] / 2 - element[len] / 2); - break; - - case end: - offsets[mainAxis] = offsets[mainAxis] + (reference[len] / 2 - element[len] / 2); - break; - } - } - - return offsets; -} - -function detectOverflow(state, options) { - if (options === void 0) { - options = {}; - } - - var _options = options, - _options$placement = _options.placement, - placement = _options$placement === void 0 ? state.placement : _options$placement, - _options$boundary = _options.boundary, - boundary = _options$boundary === void 0 ? clippingParents : _options$boundary, - _options$rootBoundary = _options.rootBoundary, - rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary, - _options$elementConte = _options.elementContext, - elementContext = _options$elementConte === void 0 ? popper : _options$elementConte, - _options$altBoundary = _options.altBoundary, - altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary, - _options$padding = _options.padding, - padding = _options$padding === void 0 ? 0 : _options$padding; - var paddingObject = mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements)); - var altContext = elementContext === popper ? reference : popper; - var popperRect = state.rects.popper; - var element = state.elements[altBoundary ? altContext : elementContext]; - var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary); - var referenceClientRect = getBoundingClientRect(state.elements.reference); - var popperOffsets = computeOffsets({ - reference: referenceClientRect, - element: popperRect, - strategy: 'absolute', - placement: placement - }); - var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets)); - var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; // positive = overflowing the clipping rect - // 0 or negative = within the clipping rect - - var overflowOffsets = { - top: clippingClientRect.top - elementClientRect.top + paddingObject.top, - bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom, - left: clippingClientRect.left - elementClientRect.left + paddingObject.left, - right: elementClientRect.right - clippingClientRect.right + paddingObject.right - }; - var offsetData = state.modifiersData.offset; // Offsets can be applied only to the popper element - - if (elementContext === popper && offsetData) { - var offset = offsetData[placement]; - Object.keys(overflowOffsets).forEach(function (key) { - var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1; - var axis = [top, bottom].indexOf(key) >= 0 ? 'y' : 'x'; - overflowOffsets[key] += offset[axis] * multiply; - }); - } - - return overflowOffsets; -} - -function computeAutoPlacement(state, options) { - if (options === void 0) { - options = {}; - } - - var _options = options, - placement = _options.placement, - boundary = _options.boundary, - rootBoundary = _options.rootBoundary, - padding = _options.padding, - flipVariations = _options.flipVariations, - _options$allowedAutoP = _options.allowedAutoPlacements, - allowedAutoPlacements = _options$allowedAutoP === void 0 ? placements : _options$allowedAutoP; - var variation = getVariation(placement); - var placements$1 = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function (placement) { - return getVariation(placement) === variation; - }) : basePlacements; - var allowedPlacements = placements$1.filter(function (placement) { - return allowedAutoPlacements.indexOf(placement) >= 0; - }); - - if (allowedPlacements.length === 0) { - allowedPlacements = placements$1; - - if (process.env.NODE_ENV !== "production") { - console.error(['Popper: The `allowedAutoPlacements` option did not allow any', 'placements. Ensure the `placement` option matches the variation', 'of the allowed placements.', 'For example, "auto" cannot be used to allow "bottom-start".', 'Use "auto-start" instead.'].join(' ')); - } - } // $FlowFixMe[incompatible-type]: Flow seems to have problems with two array unions... - - - var overflows = allowedPlacements.reduce(function (acc, placement) { - acc[placement] = detectOverflow(state, { - placement: placement, - boundary: boundary, - rootBoundary: rootBoundary, - padding: padding - })[getBasePlacement(placement)]; - return acc; - }, {}); - return Object.keys(overflows).sort(function (a, b) { - return overflows[a] - overflows[b]; - }); -} - -function getExpandedFallbackPlacements(placement) { - if (getBasePlacement(placement) === auto) { - return []; - } - - var oppositePlacement = getOppositePlacement(placement); - return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)]; -} - -function flip(_ref) { - var state = _ref.state, - options = _ref.options, - name = _ref.name; - - if (state.modifiersData[name]._skip) { - return; - } - - var _options$mainAxis = options.mainAxis, - checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, - _options$altAxis = options.altAxis, - checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis, - specifiedFallbackPlacements = options.fallbackPlacements, - padding = options.padding, - boundary = options.boundary, - rootBoundary = options.rootBoundary, - altBoundary = options.altBoundary, - _options$flipVariatio = options.flipVariations, - flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio, - allowedAutoPlacements = options.allowedAutoPlacements; - var preferredPlacement = state.options.placement; - var basePlacement = getBasePlacement(preferredPlacement); - var isBasePlacement = basePlacement === preferredPlacement; - var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement)); - var placements = [preferredPlacement].concat(fallbackPlacements).reduce(function (acc, placement) { - return acc.concat(getBasePlacement(placement) === auto ? computeAutoPlacement(state, { - placement: placement, - boundary: boundary, - rootBoundary: rootBoundary, - padding: padding, - flipVariations: flipVariations, - allowedAutoPlacements: allowedAutoPlacements - }) : placement); - }, []); - var referenceRect = state.rects.reference; - var popperRect = state.rects.popper; - var checksMap = new Map(); - var makeFallbackChecks = true; - var firstFittingPlacement = placements[0]; - - for (var i = 0; i < placements.length; i++) { - var placement = placements[i]; - - var _basePlacement = getBasePlacement(placement); - - var isStartVariation = getVariation(placement) === start; - var isVertical = [top, bottom].indexOf(_basePlacement) >= 0; - var len = isVertical ? 'width' : 'height'; - var overflow = detectOverflow(state, { - placement: placement, - boundary: boundary, - rootBoundary: rootBoundary, - altBoundary: altBoundary, - padding: padding - }); - var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top; - - if (referenceRect[len] > popperRect[len]) { - mainVariationSide = getOppositePlacement(mainVariationSide); - } - - var altVariationSide = getOppositePlacement(mainVariationSide); - var checks = []; - - if (checkMainAxis) { - checks.push(overflow[_basePlacement] <= 0); - } - - if (checkAltAxis) { - checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0); - } - - if (checks.every(function (check) { - return check; - })) { - firstFittingPlacement = placement; - makeFallbackChecks = false; - break; - } - - checksMap.set(placement, checks); - } - - if (makeFallbackChecks) { - // `2` may be desired in some cases – research later - var numberOfChecks = flipVariations ? 3 : 1; - - var _loop = function _loop(_i) { - var fittingPlacement = placements.find(function (placement) { - var checks = checksMap.get(placement); - - if (checks) { - return checks.slice(0, _i).every(function (check) { - return check; - }); - } - }); - - if (fittingPlacement) { - firstFittingPlacement = fittingPlacement; - return "break"; - } - }; - - for (var _i = numberOfChecks; _i > 0; _i--) { - var _ret = _loop(_i); - - if (_ret === "break") break; - } - } - - if (state.placement !== firstFittingPlacement) { - state.modifiersData[name]._skip = true; - state.placement = firstFittingPlacement; - state.reset = true; - } -} // eslint-disable-next-line import/no-unused-modules - - -var flip$1 = { - name: 'flip', - enabled: true, - phase: 'main', - fn: flip, - requiresIfExists: ['offset'], - data: { - _skip: false - } -}; - -function getSideOffsets(overflow, rect, preventedOffsets) { - if (preventedOffsets === void 0) { - preventedOffsets = { - x: 0, - y: 0 - }; - } - - return { - top: overflow.top - rect.height - preventedOffsets.y, - right: overflow.right - rect.width + preventedOffsets.x, - bottom: overflow.bottom - rect.height + preventedOffsets.y, - left: overflow.left - rect.width - preventedOffsets.x - }; -} - -function isAnySideFullyClipped(overflow) { - return [top, right, bottom, left].some(function (side) { - return overflow[side] >= 0; - }); -} - -function hide(_ref) { - var state = _ref.state, - name = _ref.name; - var referenceRect = state.rects.reference; - var popperRect = state.rects.popper; - var preventedOffsets = state.modifiersData.preventOverflow; - var referenceOverflow = detectOverflow(state, { - elementContext: 'reference' - }); - var popperAltOverflow = detectOverflow(state, { - altBoundary: true - }); - var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect); - var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets); - var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets); - var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets); - state.modifiersData[name] = { - referenceClippingOffsets: referenceClippingOffsets, - popperEscapeOffsets: popperEscapeOffsets, - isReferenceHidden: isReferenceHidden, - hasPopperEscaped: hasPopperEscaped - }; - state.attributes.popper = Object.assign({}, state.attributes.popper, { - 'data-popper-reference-hidden': isReferenceHidden, - 'data-popper-escaped': hasPopperEscaped - }); -} // eslint-disable-next-line import/no-unused-modules - - -var hide$1 = { - name: 'hide', - enabled: true, - phase: 'main', - requiresIfExists: ['preventOverflow'], - fn: hide -}; - -function distanceAndSkiddingToXY(placement, rects, offset) { - var basePlacement = getBasePlacement(placement); - var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1; - - var _ref = typeof offset === 'function' ? offset(Object.assign({}, rects, { - placement: placement - })) : offset, - skidding = _ref[0], - distance = _ref[1]; - - skidding = skidding || 0; - distance = (distance || 0) * invertDistance; - return [left, right].indexOf(basePlacement) >= 0 ? { - x: distance, - y: skidding - } : { - x: skidding, - y: distance - }; -} - -function offset(_ref2) { - var state = _ref2.state, - options = _ref2.options, - name = _ref2.name; - var _options$offset = options.offset, - offset = _options$offset === void 0 ? [0, 0] : _options$offset; - var data = placements.reduce(function (acc, placement) { - acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset); - return acc; - }, {}); - var _data$state$placement = data[state.placement], - x = _data$state$placement.x, - y = _data$state$placement.y; - - if (state.modifiersData.popperOffsets != null) { - state.modifiersData.popperOffsets.x += x; - state.modifiersData.popperOffsets.y += y; - } - - state.modifiersData[name] = data; -} // eslint-disable-next-line import/no-unused-modules - - -var offset$1 = { - name: 'offset', - enabled: true, - phase: 'main', - requires: ['popperOffsets'], - fn: offset -}; - -function popperOffsets(_ref) { - var state = _ref.state, - name = _ref.name; - // Offsets are the actual position the popper needs to have to be - // properly positioned near its reference element - // This is the most basic placement, and will be adjusted by - // the modifiers in the next step - state.modifiersData[name] = computeOffsets({ - reference: state.rects.reference, - element: state.rects.popper, - strategy: 'absolute', - placement: state.placement - }); -} // eslint-disable-next-line import/no-unused-modules - - -var popperOffsets$1 = { - name: 'popperOffsets', - enabled: true, - phase: 'read', - fn: popperOffsets, - data: {} -}; - -function getAltAxis(axis) { - return axis === 'x' ? 'y' : 'x'; -} - -function preventOverflow(_ref) { - var state = _ref.state, - options = _ref.options, - name = _ref.name; - var _options$mainAxis = options.mainAxis, - checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, - _options$altAxis = options.altAxis, - checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis, - boundary = options.boundary, - rootBoundary = options.rootBoundary, - altBoundary = options.altBoundary, - padding = options.padding, - _options$tether = options.tether, - tether = _options$tether === void 0 ? true : _options$tether, - _options$tetherOffset = options.tetherOffset, - tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset; - var overflow = detectOverflow(state, { - boundary: boundary, - rootBoundary: rootBoundary, - padding: padding, - altBoundary: altBoundary - }); - var basePlacement = getBasePlacement(state.placement); - var variation = getVariation(state.placement); - var isBasePlacement = !variation; - var mainAxis = getMainAxisFromPlacement(basePlacement); - var altAxis = getAltAxis(mainAxis); - var popperOffsets = state.modifiersData.popperOffsets; - var referenceRect = state.rects.reference; - var popperRect = state.rects.popper; - var tetherOffsetValue = typeof tetherOffset === 'function' ? tetherOffset(Object.assign({}, state.rects, { - placement: state.placement - })) : tetherOffset; - var data = { - x: 0, - y: 0 - }; - - if (!popperOffsets) { - return; - } - - if (checkMainAxis || checkAltAxis) { - var mainSide = mainAxis === 'y' ? top : left; - var altSide = mainAxis === 'y' ? bottom : right; - var len = mainAxis === 'y' ? 'height' : 'width'; - var offset = popperOffsets[mainAxis]; - var min$1 = popperOffsets[mainAxis] + overflow[mainSide]; - var max$1 = popperOffsets[mainAxis] - overflow[altSide]; - var additive = tether ? -popperRect[len] / 2 : 0; - var minLen = variation === start ? referenceRect[len] : popperRect[len]; - var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; // We need to include the arrow in the calculation so the arrow doesn't go - // outside the reference bounds - - var arrowElement = state.elements.arrow; - var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : { - width: 0, - height: 0 - }; - var arrowPaddingObject = state.modifiersData['arrow#persistent'] ? state.modifiersData['arrow#persistent'].padding : getFreshSideObject(); - var arrowPaddingMin = arrowPaddingObject[mainSide]; - var arrowPaddingMax = arrowPaddingObject[altSide]; // If the reference length is smaller than the arrow length, we don't want - // to include its full size in the calculation. If the reference is small - // and near the edge of a boundary, the popper can overflow even if the - // reference is not overflowing as well (e.g. virtual elements with no - // width or height) - - var arrowLen = within(0, referenceRect[len], arrowRect[len]); - var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - tetherOffsetValue : minLen - arrowLen - arrowPaddingMin - tetherOffsetValue; - var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + tetherOffsetValue : maxLen + arrowLen + arrowPaddingMax + tetherOffsetValue; - var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow); - var clientOffset = arrowOffsetParent ? mainAxis === 'y' ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0; - var offsetModifierValue = state.modifiersData.offset ? state.modifiersData.offset[state.placement][mainAxis] : 0; - var tetherMin = popperOffsets[mainAxis] + minOffset - offsetModifierValue - clientOffset; - var tetherMax = popperOffsets[mainAxis] + maxOffset - offsetModifierValue; - - if (checkMainAxis) { - var preventedOffset = within(tether ? min(min$1, tetherMin) : min$1, offset, tether ? max(max$1, tetherMax) : max$1); - popperOffsets[mainAxis] = preventedOffset; - data[mainAxis] = preventedOffset - offset; - } - - if (checkAltAxis) { - var _mainSide = mainAxis === 'x' ? top : left; - - var _altSide = mainAxis === 'x' ? bottom : right; - - var _offset = popperOffsets[altAxis]; - - var _min = _offset + overflow[_mainSide]; - - var _max = _offset - overflow[_altSide]; - - var _preventedOffset = within(tether ? min(_min, tetherMin) : _min, _offset, tether ? max(_max, tetherMax) : _max); - - popperOffsets[altAxis] = _preventedOffset; - data[altAxis] = _preventedOffset - _offset; - } - } - - state.modifiersData[name] = data; -} // eslint-disable-next-line import/no-unused-modules - - -var preventOverflow$1 = { - name: 'preventOverflow', - enabled: true, - phase: 'main', - fn: preventOverflow, - requiresIfExists: ['offset'] -}; - -function getHTMLElementScroll(element) { - return { - scrollLeft: element.scrollLeft, - scrollTop: element.scrollTop - }; -} - -function getNodeScroll(node) { - if (node === getWindow(node) || !isHTMLElement(node)) { - return getWindowScroll(node); - } else { - return getHTMLElementScroll(node); - } -} - -function isElementScaled(element) { - var rect = element.getBoundingClientRect(); - var scaleX = rect.width / element.offsetWidth || 1; - var scaleY = rect.height / element.offsetHeight || 1; - return scaleX !== 1 || scaleY !== 1; -} // Returns the composite rect of an element relative to its offsetParent. -// Composite means it takes into account transforms as well as layout. - - -function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) { - if (isFixed === void 0) { - isFixed = false; - } - - var isOffsetParentAnElement = isHTMLElement(offsetParent); - var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent); - var documentElement = getDocumentElement(offsetParent); - var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled); - var scroll = { - scrollLeft: 0, - scrollTop: 0 - }; - var offsets = { - x: 0, - y: 0 - }; - - if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) { - if (getNodeName(offsetParent) !== 'body' || // https://github.com/popperjs/popper-core/issues/1078 - isScrollParent(documentElement)) { - scroll = getNodeScroll(offsetParent); - } - - if (isHTMLElement(offsetParent)) { - offsets = getBoundingClientRect(offsetParent, true); - offsets.x += offsetParent.clientLeft; - offsets.y += offsetParent.clientTop; - } else if (documentElement) { - offsets.x = getWindowScrollBarX(documentElement); - } - } - - return { - x: rect.left + scroll.scrollLeft - offsets.x, - y: rect.top + scroll.scrollTop - offsets.y, - width: rect.width, - height: rect.height - }; -} - -function order(modifiers) { - var map = new Map(); - var visited = new Set(); - var result = []; - modifiers.forEach(function (modifier) { - map.set(modifier.name, modifier); - }); // On visiting object, check for its dependencies and visit them recursively - - function sort(modifier) { - visited.add(modifier.name); - var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []); - requires.forEach(function (dep) { - if (!visited.has(dep)) { - var depModifier = map.get(dep); - - if (depModifier) { - sort(depModifier); - } - } - }); - result.push(modifier); - } - - modifiers.forEach(function (modifier) { - if (!visited.has(modifier.name)) { - // check for visited object - sort(modifier); - } - }); - return result; -} - -function orderModifiers(modifiers) { - // order based on dependencies - var orderedModifiers = order(modifiers); // order based on phase - - return modifierPhases.reduce(function (acc, phase) { - return acc.concat(orderedModifiers.filter(function (modifier) { - return modifier.phase === phase; - })); - }, []); -} - -function debounce(fn) { - var pending; - return function () { - if (!pending) { - pending = new Promise(function (resolve) { - Promise.resolve().then(function () { - pending = undefined; - resolve(fn()); - }); - }); - } - - return pending; - }; -} - -function format$1(str) { - for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - args[_key - 1] = arguments[_key]; - } - - return [].concat(args).reduce(function (p, c) { - return p.replace(/%s/, c); - }, str); -} - -var INVALID_MODIFIER_ERROR = 'Popper: modifier "%s" provided an invalid %s property, expected %s but got %s'; -var MISSING_DEPENDENCY_ERROR = 'Popper: modifier "%s" requires "%s", but "%s" modifier is not available'; -var VALID_PROPERTIES = ['name', 'enabled', 'phase', 'fn', 'effect', 'requires', 'options']; -function validateModifiers(modifiers) { - modifiers.forEach(function (modifier) { - [].concat(Object.keys(modifier), VALID_PROPERTIES) // IE11-compatible replacement for `new Set(iterable)` - .filter(function (value, index, self) { - return self.indexOf(value) === index; - }).forEach(function (key) { - switch (key) { - case 'name': - if (typeof modifier.name !== 'string') { - console.error(format$1(INVALID_MODIFIER_ERROR, String(modifier.name), '"name"', '"string"', "\"" + String(modifier.name) + "\"")); - } - - break; - - case 'enabled': - if (typeof modifier.enabled !== 'boolean') { - console.error(format$1(INVALID_MODIFIER_ERROR, modifier.name, '"enabled"', '"boolean"', "\"" + String(modifier.enabled) + "\"")); - } - - break; - - case 'phase': - if (modifierPhases.indexOf(modifier.phase) < 0) { - console.error(format$1(INVALID_MODIFIER_ERROR, modifier.name, '"phase"', "either " + modifierPhases.join(', '), "\"" + String(modifier.phase) + "\"")); - } - - break; - - case 'fn': - if (typeof modifier.fn !== 'function') { - console.error(format$1(INVALID_MODIFIER_ERROR, modifier.name, '"fn"', '"function"', "\"" + String(modifier.fn) + "\"")); - } - - break; - - case 'effect': - if (modifier.effect != null && typeof modifier.effect !== 'function') { - console.error(format$1(INVALID_MODIFIER_ERROR, modifier.name, '"effect"', '"function"', "\"" + String(modifier.fn) + "\"")); - } - - break; - - case 'requires': - if (modifier.requires != null && !Array.isArray(modifier.requires)) { - console.error(format$1(INVALID_MODIFIER_ERROR, modifier.name, '"requires"', '"array"', "\"" + String(modifier.requires) + "\"")); - } - - break; - - case 'requiresIfExists': - if (!Array.isArray(modifier.requiresIfExists)) { - console.error(format$1(INVALID_MODIFIER_ERROR, modifier.name, '"requiresIfExists"', '"array"', "\"" + String(modifier.requiresIfExists) + "\"")); - } - - break; - - case 'options': - case 'data': - break; - - default: - console.error("PopperJS: an invalid property has been provided to the \"" + modifier.name + "\" modifier, valid properties are " + VALID_PROPERTIES.map(function (s) { - return "\"" + s + "\""; - }).join(', ') + "; but \"" + key + "\" was provided."); - } - - modifier.requires && modifier.requires.forEach(function (requirement) { - if (modifiers.find(function (mod) { - return mod.name === requirement; - }) == null) { - console.error(format$1(MISSING_DEPENDENCY_ERROR, String(modifier.name), requirement, requirement)); - } - }); - }); - }); -} - -function uniqueBy(arr, fn) { - var identifiers = new Set(); - return arr.filter(function (item) { - var identifier = fn(item); - - if (!identifiers.has(identifier)) { - identifiers.add(identifier); - return true; - } - }); -} - -function mergeByName(modifiers) { - var merged = modifiers.reduce(function (merged, current) { - var existing = merged[current.name]; - merged[current.name] = existing ? Object.assign({}, existing, current, { - options: Object.assign({}, existing.options, current.options), - data: Object.assign({}, existing.data, current.data) - }) : current; - return merged; - }, {}); // IE11 does not support Object.values - - return Object.keys(merged).map(function (key) { - return merged[key]; - }); -} - -var INVALID_ELEMENT_ERROR = 'Popper: Invalid reference or popper argument provided. They must be either a DOM element or virtual element.'; -var INFINITE_LOOP_ERROR = 'Popper: An infinite loop in the modifiers cycle has been detected! The cycle has been interrupted to prevent a browser crash.'; -var DEFAULT_OPTIONS = { - placement: 'bottom', - modifiers: [], - strategy: 'absolute' -}; - -function areValidElements() { - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } - - return !args.some(function (element) { - return !(element && typeof element.getBoundingClientRect === 'function'); - }); -} - -function popperGenerator(generatorOptions) { - if (generatorOptions === void 0) { - generatorOptions = {}; - } - - var _generatorOptions = generatorOptions, - _generatorOptions$def = _generatorOptions.defaultModifiers, - defaultModifiers = _generatorOptions$def === void 0 ? [] : _generatorOptions$def, - _generatorOptions$def2 = _generatorOptions.defaultOptions, - defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2; - return function createPopper(reference, popper, options) { - if (options === void 0) { - options = defaultOptions; - } - - var state = { - placement: 'bottom', - orderedModifiers: [], - options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions), - modifiersData: {}, - elements: { - reference: reference, - popper: popper - }, - attributes: {}, - styles: {} - }; - var effectCleanupFns = []; - var isDestroyed = false; - var instance = { - state: state, - setOptions: function setOptions(setOptionsAction) { - var options = typeof setOptionsAction === 'function' ? setOptionsAction(state.options) : setOptionsAction; - cleanupModifierEffects(); - state.options = Object.assign({}, defaultOptions, state.options, options); - state.scrollParents = { - reference: isElement(reference) ? listScrollParents(reference) : reference.contextElement ? listScrollParents(reference.contextElement) : [], - popper: listScrollParents(popper) - }; // Orders the modifiers based on their dependencies and `phase` - // properties - - var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers, state.options.modifiers))); // Strip out disabled modifiers - - state.orderedModifiers = orderedModifiers.filter(function (m) { - return m.enabled; - }); // Validate the provided modifiers so that the consumer will get warned - // if one of the modifiers is invalid for any reason - - if (process.env.NODE_ENV !== "production") { - var modifiers = uniqueBy([].concat(orderedModifiers, state.options.modifiers), function (_ref) { - var name = _ref.name; - return name; - }); - validateModifiers(modifiers); - - if (getBasePlacement(state.options.placement) === auto) { - var flipModifier = state.orderedModifiers.find(function (_ref2) { - var name = _ref2.name; - return name === 'flip'; - }); - - if (!flipModifier) { - console.error(['Popper: "auto" placements require the "flip" modifier be', 'present and enabled to work.'].join(' ')); - } - } - - var _getComputedStyle = getComputedStyle$1(popper), - marginTop = _getComputedStyle.marginTop, - marginRight = _getComputedStyle.marginRight, - marginBottom = _getComputedStyle.marginBottom, - marginLeft = _getComputedStyle.marginLeft; // We no longer take into account `margins` on the popper, and it can - // cause bugs with positioning, so we'll warn the consumer - - - if ([marginTop, marginRight, marginBottom, marginLeft].some(function (margin) { - return parseFloat(margin); - })) { - console.warn(['Popper: CSS "margin" styles cannot be used to apply padding', 'between the popper and its reference element or boundary.', 'To replicate margin, use the `offset` modifier, as well as', 'the `padding` option in the `preventOverflow` and `flip`', 'modifiers.'].join(' ')); - } - } - - runModifierEffects(); - return instance.update(); - }, - // Sync update – it will always be executed, even if not necessary. This - // is useful for low frequency updates where sync behavior simplifies the - // logic. - // For high frequency updates (e.g. `resize` and `scroll` events), always - // prefer the async Popper#update method - forceUpdate: function forceUpdate() { - if (isDestroyed) { - return; - } - - var _state$elements = state.elements, - reference = _state$elements.reference, - popper = _state$elements.popper; // Don't proceed if `reference` or `popper` are not valid elements - // anymore - - if (!areValidElements(reference, popper)) { - if (process.env.NODE_ENV !== "production") { - console.error(INVALID_ELEMENT_ERROR); - } - - return; - } // Store the reference and popper rects to be read by modifiers - - - state.rects = { - reference: getCompositeRect(reference, getOffsetParent(popper), state.options.strategy === 'fixed'), - popper: getLayoutRect(popper) - }; // Modifiers have the ability to reset the current update cycle. The - // most common use case for this is the `flip` modifier changing the - // placement, which then needs to re-run all the modifiers, because the - // logic was previously ran for the previous placement and is therefore - // stale/incorrect - - state.reset = false; - state.placement = state.options.placement; // On each update cycle, the `modifiersData` property for each modifier - // is filled with the initial data specified by the modifier. This means - // it doesn't persist and is fresh on each update. - // To ensure persistent data, use `${name}#persistent` - - state.orderedModifiers.forEach(function (modifier) { - return state.modifiersData[modifier.name] = Object.assign({}, modifier.data); - }); - var __debug_loops__ = 0; - - for (var index = 0; index < state.orderedModifiers.length; index++) { - if (process.env.NODE_ENV !== "production") { - __debug_loops__ += 1; - - if (__debug_loops__ > 100) { - console.error(INFINITE_LOOP_ERROR); - break; - } - } - - if (state.reset === true) { - state.reset = false; - index = -1; - continue; - } - - var _state$orderedModifie = state.orderedModifiers[index], - fn = _state$orderedModifie.fn, - _state$orderedModifie2 = _state$orderedModifie.options, - _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2, - name = _state$orderedModifie.name; - - if (typeof fn === 'function') { - state = fn({ - state: state, - options: _options, - name: name, - instance: instance - }) || state; - } - } - }, - // Async and optimistically optimized update – it will not be executed if - // not necessary (debounced to run at most once-per-tick) - update: debounce(function () { - return new Promise(function (resolve) { - instance.forceUpdate(); - resolve(state); - }); - }), - destroy: function destroy() { - cleanupModifierEffects(); - isDestroyed = true; - } - }; - - if (!areValidElements(reference, popper)) { - if (process.env.NODE_ENV !== "production") { - console.error(INVALID_ELEMENT_ERROR); - } - - return instance; - } - - instance.setOptions(options).then(function (state) { - if (!isDestroyed && options.onFirstUpdate) { - options.onFirstUpdate(state); - } - }); // Modifiers have the ability to execute arbitrary code before the first - // update cycle runs. They will be executed in the same order as the update - // cycle. This is useful when a modifier adds some persistent data that - // other modifiers need to use, but the modifier is run after the dependent - // one. - - function runModifierEffects() { - state.orderedModifiers.forEach(function (_ref3) { - var name = _ref3.name, - _ref3$options = _ref3.options, - options = _ref3$options === void 0 ? {} : _ref3$options, - effect = _ref3.effect; - - if (typeof effect === 'function') { - var cleanupFn = effect({ - state: state, - name: name, - instance: instance, - options: options - }); - - var noopFn = function noopFn() {}; - - effectCleanupFns.push(cleanupFn || noopFn); - } - }); - } - - function cleanupModifierEffects() { - effectCleanupFns.forEach(function (fn) { - return fn(); - }); - effectCleanupFns = []; - } - - return instance; - }; -} - -var defaultModifiers = [eventListeners, popperOffsets$1, computeStyles$1, applyStyles$1, offset$1, flip$1, preventOverflow$1, arrow$1, hide$1]; -var createPopper = /*#__PURE__*/popperGenerator({ - defaultModifiers: defaultModifiers -}); // eslint-disable-next-line import/no-unused-modules - -// Credits go to Liam's Periodic Notes Plugin: https://github.com/liamcain/obsidian-periodic-notes -const wrapAround = (value, size) => { - return ((value % size) + size) % size; -}; -class Suggest { - constructor(owner, containerEl, scope) { - this.owner = owner; - this.containerEl = containerEl; - containerEl.on("click", ".suggestion-item", this.onSuggestionClick.bind(this)); - containerEl.on("mousemove", ".suggestion-item", this.onSuggestionMouseover.bind(this)); - scope.register([], "ArrowUp", (event) => { - if (!event.isComposing) { - this.setSelectedItem(this.selectedItem - 1, true); - return false; - } - }); - scope.register([], "ArrowDown", (event) => { - if (!event.isComposing) { - this.setSelectedItem(this.selectedItem + 1, true); - return false; - } - }); - scope.register([], "Enter", (event) => { - if (!event.isComposing) { - this.useSelectedItem(event); - return false; - } - }); - } - onSuggestionClick(event, el) { - event.preventDefault(); - const item = this.suggestions.indexOf(el); - this.setSelectedItem(item, false); - this.useSelectedItem(event); - } - onSuggestionMouseover(_event, el) { - const item = this.suggestions.indexOf(el); - this.setSelectedItem(item, false); - } - setSuggestions(values) { - this.containerEl.empty(); - const suggestionEls = []; - values.forEach((value) => { - const suggestionEl = this.containerEl.createDiv("suggestion-item"); - this.owner.renderSuggestion(value, suggestionEl); - suggestionEls.push(suggestionEl); - }); - this.values = values; - this.suggestions = suggestionEls; - this.setSelectedItem(0, false); - } - useSelectedItem(event) { - const currentValue = this.values[this.selectedItem]; - if (currentValue) { - this.owner.selectSuggestion(currentValue, event); - } - } - setSelectedItem(selectedIndex, scrollIntoView) { - const normalizedIndex = wrapAround(selectedIndex, this.suggestions.length); - const prevSelectedSuggestion = this.suggestions[this.selectedItem]; - const selectedSuggestion = this.suggestions[normalizedIndex]; - prevSelectedSuggestion === null || prevSelectedSuggestion === void 0 ? void 0 : prevSelectedSuggestion.removeClass("is-selected"); - selectedSuggestion === null || selectedSuggestion === void 0 ? void 0 : selectedSuggestion.addClass("is-selected"); - this.selectedItem = normalizedIndex; - if (scrollIntoView) { - selectedSuggestion.scrollIntoView(false); - } - } -} -class TextInputSuggest { - constructor(app, inputEl) { - this.app = app; - this.inputEl = inputEl; - this.scope = new obsidian.Scope(); - this.suggestEl = createDiv("suggestion-container"); - const suggestion = this.suggestEl.createDiv("suggestion"); - this.suggest = new Suggest(this, suggestion, this.scope); - this.scope.register([], "Escape", this.close.bind(this)); - this.inputEl.addEventListener("input", this.onInputChanged.bind(this)); - this.inputEl.addEventListener("focus", this.onInputChanged.bind(this)); - this.inputEl.addEventListener("blur", this.close.bind(this)); - this.suggestEl.on("mousedown", ".suggestion-container", (event) => { - event.preventDefault(); - }); - } - onInputChanged() { - const inputStr = this.inputEl.value; - const suggestions = this.getSuggestions(inputStr); - if (!suggestions) { - this.close(); - return; - } - if (suggestions.length > 0) { - this.suggest.setSuggestions(suggestions); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - this.open(this.app.dom.appContainerEl, this.inputEl); - } - else { - this.close(); - } - } - open(container, inputEl) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - this.app.keymap.pushScope(this.scope); - container.appendChild(this.suggestEl); - this.popper = createPopper(inputEl, this.suggestEl, { - placement: "bottom-start", - modifiers: [ - { - name: "sameWidth", - enabled: true, - fn: ({ state, instance }) => { - // Note: positioning needs to be calculated twice - - // first pass - positioning it according to the width of the popper - // second pass - position it with the width bound to the reference element - // we need to early exit to avoid an infinite loop - const targetWidth = `${state.rects.reference.width}px`; - if (state.styles.popper.width === targetWidth) { - return; - } - state.styles.popper.width = targetWidth; - instance.update(); - }, - phase: "beforeWrite", - requires: ["computeStyles"], - }, - ], - }); - } - close() { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - this.app.keymap.popScope(this.scope); - this.suggest.setSuggestions([]); - if (this.popper) - this.popper.destroy(); - this.suggestEl.detach(); - } -} - -class GenericTextSuggester extends TextInputSuggest { - constructor(app, inputEl, items) { - super(app, inputEl); - this.app = app; - this.inputEl = inputEl; - this.items = items; - } - getSuggestions(inputStr) { - const inputLowerCase = inputStr.toLowerCase(); - const filtered = this.items.filter(item => { - if (item.toLowerCase().contains(inputLowerCase)) - return item; - }); - if (!filtered) - this.close(); - if ((filtered === null || filtered === void 0 ? void 0 : filtered.length) > 0) - return filtered; - } - selectSuggestion(item) { - this.inputEl.value = item; - this.inputEl.trigger("input"); - this.close(); - } - renderSuggestion(value, el) { - if (value) - el.setText(value); - } -} - -const VALUE_SYNTAX = "{{VALUE}}"; -const DATE_SYNTAX = "{{DATE}}"; -const NAME_SYNTAX = "{{NAME}}"; -const VARIABLE_SYNTAX = "{{VALUE:}}"; -const LINKCURRENT_SYNTAX = "{{LINKCURRENT}}"; -const FILE_NAME_FORMAT_SYNTAX = [ - DATE_SYNTAX, "{{DATE:}}", "{{VDATE:, }}", - VALUE_SYNTAX, NAME_SYNTAX, VARIABLE_SYNTAX, -]; -const FILE_NUMBER_REGEX = new RegExp(/([0-9]*)\.md$/); -const NUMBER_REGEX = new RegExp(/^-?[0-9]*$/); -const CREATE_IF_NOT_FOUND_TOP = "top"; -const CREATE_IF_NOT_FOUND_BOTTOM = "bottom"; -// == Format Syntax == // -const DATE_REGEX = new RegExp(/{{DATE(\+-?[0-9]+)?}}/); -const DATE_REGEX_FORMATTED = new RegExp(/{{DATE:([^}\n\r+]*)(\+-?[0-9]+)?}}/); -const NAME_VALUE_REGEX = new RegExp(/{{NAME}}|{{VALUE}}/); -const VARIABLE_REGEX = new RegExp(/{{VALUE:([^\n\r}]*)}}/); -const DATE_VARIABLE_REGEX = new RegExp(/{{VDATE:([^\n\r},]*),\s*([^\n\r},]*)}}/); -const LINK_TO_CURRENT_FILE_REGEX = new RegExp(/{{LINKCURRENT}}/); -const MARKDOWN_FILE_EXTENSION_REGEX = new RegExp(/\.md$/); -const JAVASCRIPT_FILE_EXTENSION_REGEX = new RegExp(/\.js$/); -const MACRO_REGEX = new RegExp(/{{MACRO:([^\n\r}]*)}}/); -const TEMPLATE_REGEX = new RegExp(/{{TEMPLATE:([^\n\r}]*.md)}}/); -const LINEBREAK_REGEX = new RegExp(/\\n/); -const INLINE_JAVASCRIPT_REGEX = new RegExp(/`{3,}js quickadd([\s\S]*?)`{3,}/); -// This is not an accurate wikilink regex - but works for its intended purpose. -const FILE_LINK_REGEX = new RegExp(/\[\[([^\]]*)$/); -const TAG_REGEX = new RegExp(/#([^ ]*)$/); -// == Format Syntax Suggestion == // -const DATE_SYNTAX_SUGGEST_REGEX = new RegExp(/{{[D]?[A]?[T]?[E]?[}]?[}]?$/i); -const DATE_FORMAT_SYNTAX_SUGGEST_REGEX = new RegExp(/{{[D]?[A]?[T]?[E]?[:]?$|{{DATE:[^\n\r}]*}}$/i); -const NAME_SYNTAX_SUGGEST_REGEX = new RegExp(/{{[N]?[A]?[M]?[E]?[}]?[}]?$/i); -const VALUE_SYNTAX_SUGGEST_REGEX = new RegExp(/{{[V]?[A]?[L]?[U]?[E]?[}]?[}]?$/i); -const VARIABLE_SYNTAX_SUGGEST_REGEX = new RegExp(/{{[V]?[A]?[L]?[U]?[E]?[:]?$|{{VALUE:[^\n\r}]*}}$/i); -const VARIABLE_DATE_SYNTAX_SUGGEST_REGEX = new RegExp(/{{[V]?[D]?[A]?[T]?[E]?[:]?$|{{VDATE:[^\n\r}]*}}$/i); -const LINKCURRENT_SYNTAX_SUGGEST_REGEX = new RegExp(/{{[L]?[I]?[N]?[K]?[C]?[U]?[R]?[R]?[E]?[N]?[T]?[}]?[}]?$/i); -const TEMPLATE_SYNTAX_SUGGEST_REGEX = new RegExp(/{{[T]?[E]?[M]?[P]?[L]?[A]?[T]?[E]?[:]?$|{{TEMPLATE:[^\n\r}]*[}]?[}]?$/i); -const MACRO_SYNTAX_SUGGEST_REGEX = new RegExp(/{{[M]?[A]?[C]?[R]?[O]?[:]?$|{{MACRO:[^\n\r}]*}}$/i); -// == File Exists (Template Choice) == // -const fileExistsAppendToBottom = "Append to the bottom of the file"; -const fileExistsAppendToTop = "Append to the top of the file"; -const fileExistsOverwriteFile = "Overwrite the file"; -const fileExistsDoNothing = "Nothing"; -const fileExistsChoices = [fileExistsAppendToBottom, fileExistsAppendToTop, fileExistsOverwriteFile, fileExistsDoNothing]; -// == MISC == // -const WIKI_LINK_REGEX = new RegExp(/\[\[([^\]]*)\]\]/); - -/** - * Fuse.js v6.4.6 - Lightweight fuzzy-search (http://fusejs.io) - * - * Copyright (c) 2021 Kiro Risk (http://kiro.me) - * All Rights Reserved. Apache Software License 2.0 - * - * http://www.apache.org/licenses/LICENSE-2.0 - */ - -function isArray(value) { - return !Array.isArray - ? getTag(value) === '[object Array]' - : Array.isArray(value) -} - -// Adapted from: https://github.com/lodash/lodash/blob/master/.internal/baseToString.js -const INFINITY = 1 / 0; -function baseToString(value) { - // Exit early for strings to avoid a performance hit in some environments. - if (typeof value == 'string') { - return value - } - let result = value + ''; - return result == '0' && 1 / value == -INFINITY ? '-0' : result -} - -function toString(value) { - return value == null ? '' : baseToString(value) -} - -function isString(value) { - return typeof value === 'string' -} - -function isNumber(value) { - return typeof value === 'number' -} - -// Adapted from: https://github.com/lodash/lodash/blob/master/isBoolean.js -function isBoolean(value) { - return ( - value === true || - value === false || - (isObjectLike(value) && getTag(value) == '[object Boolean]') - ) -} - -function isObject(value) { - return typeof value === 'object' -} - -// Checks if `value` is object-like. -function isObjectLike(value) { - return isObject(value) && value !== null -} - -function isDefined(value) { - return value !== undefined && value !== null -} - -function isBlank(value) { - return !value.trim().length -} - -// Gets the `toStringTag` of `value`. -// Adapted from: https://github.com/lodash/lodash/blob/master/.internal/getTag.js -function getTag(value) { - return value == null - ? value === undefined - ? '[object Undefined]' - : '[object Null]' - : Object.prototype.toString.call(value) -} - -const EXTENDED_SEARCH_UNAVAILABLE = 'Extended search is not available'; - -const INCORRECT_INDEX_TYPE = "Incorrect 'index' type"; - -const LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY = (key) => - `Invalid value for key ${key}`; - -const PATTERN_LENGTH_TOO_LARGE = (max) => - `Pattern length exceeds max of ${max}.`; - -const MISSING_KEY_PROPERTY = (name) => `Missing ${name} property in key`; - -const INVALID_KEY_WEIGHT_VALUE = (key) => - `Property 'weight' in key '${key}' must be a positive integer`; - -const hasOwn = Object.prototype.hasOwnProperty; - -class KeyStore { - constructor(keys) { - this._keys = []; - this._keyMap = {}; - - let totalWeight = 0; - - keys.forEach((key) => { - let obj = createKey(key); - - totalWeight += obj.weight; - - this._keys.push(obj); - this._keyMap[obj.id] = obj; - - totalWeight += obj.weight; - }); - - // Normalize weights so that their sum is equal to 1 - this._keys.forEach((key) => { - key.weight /= totalWeight; - }); - } - get(keyId) { - return this._keyMap[keyId] - } - keys() { - return this._keys - } - toJSON() { - return JSON.stringify(this._keys) - } -} - -function createKey(key) { - let path = null; - let id = null; - let src = null; - let weight = 1; - - if (isString(key) || isArray(key)) { - src = key; - path = createKeyPath(key); - id = createKeyId(key); - } else { - if (!hasOwn.call(key, 'name')) { - throw new Error(MISSING_KEY_PROPERTY('name')) - } - - const name = key.name; - src = name; - - if (hasOwn.call(key, 'weight')) { - weight = key.weight; - - if (weight <= 0) { - throw new Error(INVALID_KEY_WEIGHT_VALUE(name)) - } - } - - path = createKeyPath(name); - id = createKeyId(name); - } - - return { path, id, weight, src } -} - -function createKeyPath(key) { - return isArray(key) ? key : key.split('.') -} - -function createKeyId(key) { - return isArray(key) ? key.join('.') : key -} - -function get(obj, path) { - let list = []; - let arr = false; - - const deepGet = (obj, path, index) => { - if (!isDefined(obj)) { - return - } - if (!path[index]) { - // If there's no path left, we've arrived at the object we care about. - list.push(obj); - } else { - let key = path[index]; - - const value = obj[key]; - - if (!isDefined(value)) { - return - } - - // If we're at the last value in the path, and if it's a string/number/bool, - // add it to the list - if ( - index === path.length - 1 && - (isString(value) || isNumber(value) || isBoolean(value)) - ) { - list.push(toString(value)); - } else if (isArray(value)) { - arr = true; - // Search each item in the array. - for (let i = 0, len = value.length; i < len; i += 1) { - deepGet(value[i], path, index + 1); - } - } else if (path.length) { - // An object. Recurse further. - deepGet(value, path, index + 1); - } - } - }; - - // Backwards compatibility (since path used to be a string) - deepGet(obj, isString(path) ? path.split('.') : path, 0); - - return arr ? list : list[0] -} - -const MatchOptions = { - // Whether the matches should be included in the result set. When `true`, each record in the result - // set will include the indices of the matched characters. - // These can consequently be used for highlighting purposes. - includeMatches: false, - // When `true`, the matching function will continue to the end of a search pattern even if - // a perfect match has already been located in the string. - findAllMatches: false, - // Minimum number of characters that must be matched before a result is considered a match - minMatchCharLength: 1 -}; - -const BasicOptions = { - // When `true`, the algorithm continues searching to the end of the input even if a perfect - // match is found before the end of the same input. - isCaseSensitive: false, - // When true, the matching function will continue to the end of a search pattern even if - includeScore: false, - // List of properties that will be searched. This also supports nested properties. - keys: [], - // Whether to sort the result list, by score - shouldSort: true, - // Default sort function: sort by ascending score, ascending index - sortFn: (a, b) => - a.score === b.score ? (a.idx < b.idx ? -1 : 1) : a.score < b.score ? -1 : 1 -}; - -const FuzzyOptions = { - // Approximately where in the text is the pattern expected to be found? - location: 0, - // At what point does the match algorithm give up. A threshold of '0.0' requires a perfect match - // (of both letters and location), a threshold of '1.0' would match anything. - threshold: 0.6, - // Determines how close the match must be to the fuzzy location (specified above). - // An exact letter match which is 'distance' characters away from the fuzzy location - // would score as a complete mismatch. A distance of '0' requires the match be at - // the exact location specified, a threshold of '1000' would require a perfect match - // to be within 800 characters of the fuzzy location to be found using a 0.8 threshold. - distance: 100 -}; - -const AdvancedOptions = { - // When `true`, it enables the use of unix-like search commands - useExtendedSearch: false, - // The get function to use when fetching an object's properties. - // The default will search nested paths *ie foo.bar.baz* - getFn: get, - // When `true`, search will ignore `location` and `distance`, so it won't matter - // where in the string the pattern appears. - // More info: https://fusejs.io/concepts/scoring-theory.html#fuzziness-score - ignoreLocation: false, - // When `true`, the calculation for the relevance score (used for sorting) will - // ignore the field-length norm. - // More info: https://fusejs.io/concepts/scoring-theory.html#field-length-norm - ignoreFieldNorm: false -}; - -var Config = { - ...BasicOptions, - ...MatchOptions, - ...FuzzyOptions, - ...AdvancedOptions -}; - -const SPACE = /[^ ]+/g; - -// Field-length norm: the shorter the field, the higher the weight. -// Set to 3 decimals to reduce index size. -function norm(mantissa = 3) { - const cache = new Map(); - const m = Math.pow(10, mantissa); - - return { - get(value) { - const numTokens = value.match(SPACE).length; - - if (cache.has(numTokens)) { - return cache.get(numTokens) - } - - const norm = 1 / Math.sqrt(numTokens); - - // In place of `toFixed(mantissa)`, for faster computation - const n = parseFloat(Math.round(norm * m) / m); - - cache.set(numTokens, n); - - return n - }, - clear() { - cache.clear(); - } - } -} - -class FuseIndex { - constructor({ getFn = Config.getFn } = {}) { - this.norm = norm(3); - this.getFn = getFn; - this.isCreated = false; - - this.setIndexRecords(); - } - setSources(docs = []) { - this.docs = docs; - } - setIndexRecords(records = []) { - this.records = records; - } - setKeys(keys = []) { - this.keys = keys; - this._keysMap = {}; - keys.forEach((key, idx) => { - this._keysMap[key.id] = idx; - }); - } - create() { - if (this.isCreated || !this.docs.length) { - return - } - - this.isCreated = true; - - // List is Array - if (isString(this.docs[0])) { - this.docs.forEach((doc, docIndex) => { - this._addString(doc, docIndex); - }); - } else { - // List is Array - this.docs.forEach((doc, docIndex) => { - this._addObject(doc, docIndex); - }); - } - - this.norm.clear(); - } - // Adds a doc to the end of the index - add(doc) { - const idx = this.size(); - - if (isString(doc)) { - this._addString(doc, idx); - } else { - this._addObject(doc, idx); - } - } - // Removes the doc at the specified index of the index - removeAt(idx) { - this.records.splice(idx, 1); - - // Change ref index of every subsquent doc - for (let i = idx, len = this.size(); i < len; i += 1) { - this.records[i].i -= 1; - } - } - getValueForItemAtKeyId(item, keyId) { - return item[this._keysMap[keyId]] - } - size() { - return this.records.length - } - _addString(doc, docIndex) { - if (!isDefined(doc) || isBlank(doc)) { - return - } - - let record = { - v: doc, - i: docIndex, - n: this.norm.get(doc) - }; - - this.records.push(record); - } - _addObject(doc, docIndex) { - let record = { i: docIndex, $: {} }; - - // Iterate over every key (i.e, path), and fetch the value at that key - this.keys.forEach((key, keyIndex) => { - // console.log(key) - let value = this.getFn(doc, key.path); - - if (!isDefined(value)) { - return - } - - if (isArray(value)) { - let subRecords = []; - const stack = [{ nestedArrIndex: -1, value }]; - - while (stack.length) { - const { nestedArrIndex, value } = stack.pop(); - - if (!isDefined(value)) { - continue - } - - if (isString(value) && !isBlank(value)) { - let subRecord = { - v: value, - i: nestedArrIndex, - n: this.norm.get(value) - }; - - subRecords.push(subRecord); - } else if (isArray(value)) { - value.forEach((item, k) => { - stack.push({ - nestedArrIndex: k, - value: item - }); - }); - } - } - record.$[keyIndex] = subRecords; - } else if (!isBlank(value)) { - let subRecord = { - v: value, - n: this.norm.get(value) - }; - - record.$[keyIndex] = subRecord; - } - }); - - this.records.push(record); - } - toJSON() { - return { - keys: this.keys, - records: this.records - } - } -} - -function createIndex(keys, docs, { getFn = Config.getFn } = {}) { - const myIndex = new FuseIndex({ getFn }); - myIndex.setKeys(keys.map(createKey)); - myIndex.setSources(docs); - myIndex.create(); - return myIndex -} - -function parseIndex(data, { getFn = Config.getFn } = {}) { - const { keys, records } = data; - const myIndex = new FuseIndex({ getFn }); - myIndex.setKeys(keys); - myIndex.setIndexRecords(records); - return myIndex -} - -function computeScore( - pattern, - { - errors = 0, - currentLocation = 0, - expectedLocation = 0, - distance = Config.distance, - ignoreLocation = Config.ignoreLocation - } = {} -) { - const accuracy = errors / pattern.length; - - if (ignoreLocation) { - return accuracy - } - - const proximity = Math.abs(expectedLocation - currentLocation); - - if (!distance) { - // Dodge divide by zero error. - return proximity ? 1.0 : accuracy - } - - return accuracy + proximity / distance -} - -function convertMaskToIndices( - matchmask = [], - minMatchCharLength = Config.minMatchCharLength -) { - let indices = []; - let start = -1; - let end = -1; - let i = 0; - - for (let len = matchmask.length; i < len; i += 1) { - let match = matchmask[i]; - if (match && start === -1) { - start = i; - } else if (!match && start !== -1) { - end = i - 1; - if (end - start + 1 >= minMatchCharLength) { - indices.push([start, end]); - } - start = -1; - } - } - - // (i-1 - start) + 1 => i - start - if (matchmask[i - 1] && i - start >= minMatchCharLength) { - indices.push([start, i - 1]); - } - - return indices -} - -// Machine word size -const MAX_BITS = 32; - -function search( - text, - pattern, - patternAlphabet, - { - location = Config.location, - distance = Config.distance, - threshold = Config.threshold, - findAllMatches = Config.findAllMatches, - minMatchCharLength = Config.minMatchCharLength, - includeMatches = Config.includeMatches, - ignoreLocation = Config.ignoreLocation - } = {} -) { - if (pattern.length > MAX_BITS) { - throw new Error(PATTERN_LENGTH_TOO_LARGE(MAX_BITS)) - } - - const patternLen = pattern.length; - // Set starting location at beginning text and initialize the alphabet. - const textLen = text.length; - // Handle the case when location > text.length - const expectedLocation = Math.max(0, Math.min(location, textLen)); - // Highest score beyond which we give up. - let currentThreshold = threshold; - // Is there a nearby exact match? (speedup) - let bestLocation = expectedLocation; - - // Performance: only computer matches when the minMatchCharLength > 1 - // OR if `includeMatches` is true. - const computeMatches = minMatchCharLength > 1 || includeMatches; - // A mask of the matches, used for building the indices - const matchMask = computeMatches ? Array(textLen) : []; - - let index; - - // Get all exact matches, here for speed up - while ((index = text.indexOf(pattern, bestLocation)) > -1) { - let score = computeScore(pattern, { - currentLocation: index, - expectedLocation, - distance, - ignoreLocation - }); - - currentThreshold = Math.min(score, currentThreshold); - bestLocation = index + patternLen; - - if (computeMatches) { - let i = 0; - while (i < patternLen) { - matchMask[index + i] = 1; - i += 1; - } - } - } - - // Reset the best location - bestLocation = -1; - - let lastBitArr = []; - let finalScore = 1; - let binMax = patternLen + textLen; - - const mask = 1 << (patternLen - 1); - - for (let i = 0; i < patternLen; i += 1) { - // Scan for the best match; each iteration allows for one more error. - // Run a binary search to determine how far from the match location we can stray - // at this error level. - let binMin = 0; - let binMid = binMax; - - while (binMin < binMid) { - const score = computeScore(pattern, { - errors: i, - currentLocation: expectedLocation + binMid, - expectedLocation, - distance, - ignoreLocation - }); - - if (score <= currentThreshold) { - binMin = binMid; - } else { - binMax = binMid; - } - - binMid = Math.floor((binMax - binMin) / 2 + binMin); - } - - // Use the result from this iteration as the maximum for the next. - binMax = binMid; - - let start = Math.max(1, expectedLocation - binMid + 1); - let finish = findAllMatches - ? textLen - : Math.min(expectedLocation + binMid, textLen) + patternLen; - - // Initialize the bit array - let bitArr = Array(finish + 2); - - bitArr[finish + 1] = (1 << i) - 1; - - for (let j = finish; j >= start; j -= 1) { - let currentLocation = j - 1; - let charMatch = patternAlphabet[text.charAt(currentLocation)]; - - if (computeMatches) { - // Speed up: quick bool to int conversion (i.e, `charMatch ? 1 : 0`) - matchMask[currentLocation] = +!!charMatch; - } - - // First pass: exact match - bitArr[j] = ((bitArr[j + 1] << 1) | 1) & charMatch; - - // Subsequent passes: fuzzy match - if (i) { - bitArr[j] |= - ((lastBitArr[j + 1] | lastBitArr[j]) << 1) | 1 | lastBitArr[j + 1]; - } - - if (bitArr[j] & mask) { - finalScore = computeScore(pattern, { - errors: i, - currentLocation, - expectedLocation, - distance, - ignoreLocation - }); - - // This match will almost certainly be better than any existing match. - // But check anyway. - if (finalScore <= currentThreshold) { - // Indeed it is - currentThreshold = finalScore; - bestLocation = currentLocation; - - // Already passed `loc`, downhill from here on in. - if (bestLocation <= expectedLocation) { - break - } - - // When passing `bestLocation`, don't exceed our current distance from `expectedLocation`. - start = Math.max(1, 2 * expectedLocation - bestLocation); - } - } - } - - // No hope for a (better) match at greater error levels. - const score = computeScore(pattern, { - errors: i + 1, - currentLocation: expectedLocation, - expectedLocation, - distance, - ignoreLocation - }); - - if (score > currentThreshold) { - break - } - - lastBitArr = bitArr; - } - - const result = { - isMatch: bestLocation >= 0, - // Count exact matches (those with a score of 0) to be "almost" exact - score: Math.max(0.001, finalScore) - }; - - if (computeMatches) { - const indices = convertMaskToIndices(matchMask, minMatchCharLength); - if (!indices.length) { - result.isMatch = false; - } else if (includeMatches) { - result.indices = indices; - } - } - - return result -} - -function createPatternAlphabet(pattern) { - let mask = {}; - - for (let i = 0, len = pattern.length; i < len; i += 1) { - const char = pattern.charAt(i); - mask[char] = (mask[char] || 0) | (1 << (len - i - 1)); - } - - return mask -} - -class BitapSearch { - constructor( - pattern, - { - location = Config.location, - threshold = Config.threshold, - distance = Config.distance, - includeMatches = Config.includeMatches, - findAllMatches = Config.findAllMatches, - minMatchCharLength = Config.minMatchCharLength, - isCaseSensitive = Config.isCaseSensitive, - ignoreLocation = Config.ignoreLocation - } = {} - ) { - this.options = { - location, - threshold, - distance, - includeMatches, - findAllMatches, - minMatchCharLength, - isCaseSensitive, - ignoreLocation - }; - - this.pattern = isCaseSensitive ? pattern : pattern.toLowerCase(); - - this.chunks = []; - - if (!this.pattern.length) { - return - } - - const addChunk = (pattern, startIndex) => { - this.chunks.push({ - pattern, - alphabet: createPatternAlphabet(pattern), - startIndex - }); - }; - - const len = this.pattern.length; - - if (len > MAX_BITS) { - let i = 0; - const remainder = len % MAX_BITS; - const end = len - remainder; - - while (i < end) { - addChunk(this.pattern.substr(i, MAX_BITS), i); - i += MAX_BITS; - } - - if (remainder) { - const startIndex = len - MAX_BITS; - addChunk(this.pattern.substr(startIndex), startIndex); - } - } else { - addChunk(this.pattern, 0); - } - } - - searchIn(text) { - const { isCaseSensitive, includeMatches } = this.options; - - if (!isCaseSensitive) { - text = text.toLowerCase(); - } - - // Exact match - if (this.pattern === text) { - let result = { - isMatch: true, - score: 0 - }; - - if (includeMatches) { - result.indices = [[0, text.length - 1]]; - } - - return result - } - - // Otherwise, use Bitap algorithm - const { - location, - distance, - threshold, - findAllMatches, - minMatchCharLength, - ignoreLocation - } = this.options; - - let allIndices = []; - let totalScore = 0; - let hasMatches = false; - - this.chunks.forEach(({ pattern, alphabet, startIndex }) => { - const { isMatch, score, indices } = search(text, pattern, alphabet, { - location: location + startIndex, - distance, - threshold, - findAllMatches, - minMatchCharLength, - includeMatches, - ignoreLocation - }); - - if (isMatch) { - hasMatches = true; - } - - totalScore += score; - - if (isMatch && indices) { - allIndices = [...allIndices, ...indices]; - } - }); - - let result = { - isMatch: hasMatches, - score: hasMatches ? totalScore / this.chunks.length : 1 - }; - - if (hasMatches && includeMatches) { - result.indices = allIndices; - } - - return result - } -} - -class BaseMatch { - constructor(pattern) { - this.pattern = pattern; - } - static isMultiMatch(pattern) { - return getMatch(pattern, this.multiRegex) - } - static isSingleMatch(pattern) { - return getMatch(pattern, this.singleRegex) - } - search(/*text*/) {} -} - -function getMatch(pattern, exp) { - const matches = pattern.match(exp); - return matches ? matches[1] : null -} - -// Token: 'file - -class ExactMatch extends BaseMatch { - constructor(pattern) { - super(pattern); - } - static get type() { - return 'exact' - } - static get multiRegex() { - return /^="(.*)"$/ - } - static get singleRegex() { - return /^=(.*)$/ - } - search(text) { - const isMatch = text === this.pattern; - - return { - isMatch, - score: isMatch ? 0 : 1, - indices: [0, this.pattern.length - 1] - } - } -} - -// Token: !fire - -class InverseExactMatch extends BaseMatch { - constructor(pattern) { - super(pattern); - } - static get type() { - return 'inverse-exact' - } - static get multiRegex() { - return /^!"(.*)"$/ - } - static get singleRegex() { - return /^!(.*)$/ - } - search(text) { - const index = text.indexOf(this.pattern); - const isMatch = index === -1; - - return { - isMatch, - score: isMatch ? 0 : 1, - indices: [0, text.length - 1] - } - } -} - -// Token: ^file - -class PrefixExactMatch extends BaseMatch { - constructor(pattern) { - super(pattern); - } - static get type() { - return 'prefix-exact' - } - static get multiRegex() { - return /^\^"(.*)"$/ - } - static get singleRegex() { - return /^\^(.*)$/ - } - search(text) { - const isMatch = text.startsWith(this.pattern); - - return { - isMatch, - score: isMatch ? 0 : 1, - indices: [0, this.pattern.length - 1] - } - } -} - -// Token: !^fire - -class InversePrefixExactMatch extends BaseMatch { - constructor(pattern) { - super(pattern); - } - static get type() { - return 'inverse-prefix-exact' - } - static get multiRegex() { - return /^!\^"(.*)"$/ - } - static get singleRegex() { - return /^!\^(.*)$/ - } - search(text) { - const isMatch = !text.startsWith(this.pattern); - - return { - isMatch, - score: isMatch ? 0 : 1, - indices: [0, text.length - 1] - } - } -} - -// Token: .file$ - -class SuffixExactMatch extends BaseMatch { - constructor(pattern) { - super(pattern); - } - static get type() { - return 'suffix-exact' - } - static get multiRegex() { - return /^"(.*)"\$$/ - } - static get singleRegex() { - return /^(.*)\$$/ - } - search(text) { - const isMatch = text.endsWith(this.pattern); - - return { - isMatch, - score: isMatch ? 0 : 1, - indices: [text.length - this.pattern.length, text.length - 1] - } - } -} - -// Token: !.file$ - -class InverseSuffixExactMatch extends BaseMatch { - constructor(pattern) { - super(pattern); - } - static get type() { - return 'inverse-suffix-exact' - } - static get multiRegex() { - return /^!"(.*)"\$$/ - } - static get singleRegex() { - return /^!(.*)\$$/ - } - search(text) { - const isMatch = !text.endsWith(this.pattern); - return { - isMatch, - score: isMatch ? 0 : 1, - indices: [0, text.length - 1] - } - } -} - -class FuzzyMatch extends BaseMatch { - constructor( - pattern, - { - location = Config.location, - threshold = Config.threshold, - distance = Config.distance, - includeMatches = Config.includeMatches, - findAllMatches = Config.findAllMatches, - minMatchCharLength = Config.minMatchCharLength, - isCaseSensitive = Config.isCaseSensitive, - ignoreLocation = Config.ignoreLocation - } = {} - ) { - super(pattern); - this._bitapSearch = new BitapSearch(pattern, { - location, - threshold, - distance, - includeMatches, - findAllMatches, - minMatchCharLength, - isCaseSensitive, - ignoreLocation - }); - } - static get type() { - return 'fuzzy' - } - static get multiRegex() { - return /^"(.*)"$/ - } - static get singleRegex() { - return /^(.*)$/ - } - search(text) { - return this._bitapSearch.searchIn(text) - } -} - -// Token: 'file - -class IncludeMatch extends BaseMatch { - constructor(pattern) { - super(pattern); - } - static get type() { - return 'include' - } - static get multiRegex() { - return /^'"(.*)"$/ - } - static get singleRegex() { - return /^'(.*)$/ - } - search(text) { - let location = 0; - let index; - - const indices = []; - const patternLen = this.pattern.length; - - // Get all exact matches - while ((index = text.indexOf(this.pattern, location)) > -1) { - location = index + patternLen; - indices.push([index, location - 1]); - } - - const isMatch = !!indices.length; - - return { - isMatch, - score: isMatch ? 0 : 1, - indices - } - } -} - -// ❗Order is important. DO NOT CHANGE. -const searchers = [ - ExactMatch, - IncludeMatch, - PrefixExactMatch, - InversePrefixExactMatch, - InverseSuffixExactMatch, - SuffixExactMatch, - InverseExactMatch, - FuzzyMatch -]; - -const searchersLen = searchers.length; - -// Regex to split by spaces, but keep anything in quotes together -const SPACE_RE = / +(?=([^\"]*\"[^\"]*\")*[^\"]*$)/; -const OR_TOKEN = '|'; - -// Return a 2D array representation of the query, for simpler parsing. -// Example: -// "^core go$ | rb$ | py$ xy$" => [["^core", "go$"], ["rb$"], ["py$", "xy$"]] -function parseQuery(pattern, options = {}) { - return pattern.split(OR_TOKEN).map((item) => { - let query = item - .trim() - .split(SPACE_RE) - .filter((item) => item && !!item.trim()); - - let results = []; - for (let i = 0, len = query.length; i < len; i += 1) { - const queryItem = query[i]; - - // 1. Handle multiple query match (i.e, once that are quoted, like `"hello world"`) - let found = false; - let idx = -1; - while (!found && ++idx < searchersLen) { - const searcher = searchers[idx]; - let token = searcher.isMultiMatch(queryItem); - if (token) { - results.push(new searcher(token, options)); - found = true; - } - } - - if (found) { - continue - } - - // 2. Handle single query matches (i.e, once that are *not* quoted) - idx = -1; - while (++idx < searchersLen) { - const searcher = searchers[idx]; - let token = searcher.isSingleMatch(queryItem); - if (token) { - results.push(new searcher(token, options)); - break - } - } - } - - return results - }) -} - -// These extended matchers can return an array of matches, as opposed -// to a singl match -const MultiMatchSet = new Set([FuzzyMatch.type, IncludeMatch.type]); - -/** - * Command-like searching - * ====================== - * - * Given multiple search terms delimited by spaces.e.g. `^jscript .python$ ruby !java`, - * search in a given text. - * - * Search syntax: - * - * | Token | Match type | Description | - * | ----------- | -------------------------- | -------------------------------------- | - * | `jscript` | fuzzy-match | Items that fuzzy match `jscript` | - * | `=scheme` | exact-match | Items that are `scheme` | - * | `'python` | include-match | Items that include `python` | - * | `!ruby` | inverse-exact-match | Items that do not include `ruby` | - * | `^java` | prefix-exact-match | Items that start with `java` | - * | `!^earlang` | inverse-prefix-exact-match | Items that do not start with `earlang` | - * | `.js$` | suffix-exact-match | Items that end with `.js` | - * | `!.go$` | inverse-suffix-exact-match | Items that do not end with `.go` | - * - * A single pipe character acts as an OR operator. For example, the following - * query matches entries that start with `core` and end with either`go`, `rb`, - * or`py`. - * - * ``` - * ^core go$ | rb$ | py$ - * ``` - */ -class ExtendedSearch { - constructor( - pattern, - { - isCaseSensitive = Config.isCaseSensitive, - includeMatches = Config.includeMatches, - minMatchCharLength = Config.minMatchCharLength, - ignoreLocation = Config.ignoreLocation, - findAllMatches = Config.findAllMatches, - location = Config.location, - threshold = Config.threshold, - distance = Config.distance - } = {} - ) { - this.query = null; - this.options = { - isCaseSensitive, - includeMatches, - minMatchCharLength, - findAllMatches, - ignoreLocation, - location, - threshold, - distance - }; - - this.pattern = isCaseSensitive ? pattern : pattern.toLowerCase(); - this.query = parseQuery(this.pattern, this.options); - } - - static condition(_, options) { - return options.useExtendedSearch - } - - searchIn(text) { - const query = this.query; - - if (!query) { - return { - isMatch: false, - score: 1 - } - } - - const { includeMatches, isCaseSensitive } = this.options; - - text = isCaseSensitive ? text : text.toLowerCase(); - - let numMatches = 0; - let allIndices = []; - let totalScore = 0; - - // ORs - for (let i = 0, qLen = query.length; i < qLen; i += 1) { - const searchers = query[i]; - - // Reset indices - allIndices.length = 0; - numMatches = 0; - - // ANDs - for (let j = 0, pLen = searchers.length; j < pLen; j += 1) { - const searcher = searchers[j]; - const { isMatch, indices, score } = searcher.search(text); - - if (isMatch) { - numMatches += 1; - totalScore += score; - if (includeMatches) { - const type = searcher.constructor.type; - if (MultiMatchSet.has(type)) { - allIndices = [...allIndices, ...indices]; - } else { - allIndices.push(indices); - } - } - } else { - totalScore = 0; - numMatches = 0; - allIndices.length = 0; - break - } - } - - // OR condition, so if TRUE, return - if (numMatches) { - let result = { - isMatch: true, - score: totalScore / numMatches - }; - - if (includeMatches) { - result.indices = allIndices; - } - - return result - } - } - - // Nothing was matched - return { - isMatch: false, - score: 1 - } - } -} - -const registeredSearchers = []; - -function register(...args) { - registeredSearchers.push(...args); -} - -function createSearcher(pattern, options) { - for (let i = 0, len = registeredSearchers.length; i < len; i += 1) { - let searcherClass = registeredSearchers[i]; - if (searcherClass.condition(pattern, options)) { - return new searcherClass(pattern, options) - } - } - - return new BitapSearch(pattern, options) -} - -const LogicalOperator = { - AND: '$and', - OR: '$or' -}; - -const KeyType = { - PATH: '$path', - PATTERN: '$val' -}; - -const isExpression = (query) => - !!(query[LogicalOperator.AND] || query[LogicalOperator.OR]); - -const isPath = (query) => !!query[KeyType.PATH]; - -const isLeaf = (query) => - !isArray(query) && isObject(query) && !isExpression(query); - -const convertToExplicit = (query) => ({ - [LogicalOperator.AND]: Object.keys(query).map((key) => ({ - [key]: query[key] - })) -}); - -// When `auto` is `true`, the parse function will infer and initialize and add -// the appropriate `Searcher` instance -function parse(query, options, { auto = true } = {}) { - const next = (query) => { - let keys = Object.keys(query); - - const isQueryPath = isPath(query); - - if (!isQueryPath && keys.length > 1 && !isExpression(query)) { - return next(convertToExplicit(query)) - } - - if (isLeaf(query)) { - const key = isQueryPath ? query[KeyType.PATH] : keys[0]; - - const pattern = isQueryPath ? query[KeyType.PATTERN] : query[key]; - - if (!isString(pattern)) { - throw new Error(LOGICAL_SEARCH_INVALID_QUERY_FOR_KEY(key)) - } - - const obj = { - keyId: createKeyId(key), - pattern - }; - - if (auto) { - obj.searcher = createSearcher(pattern, options); - } - - return obj - } - - let node = { - children: [], - operator: keys[0] - }; - - keys.forEach((key) => { - const value = query[key]; - - if (isArray(value)) { - value.forEach((item) => { - node.children.push(next(item)); - }); - } - }); - - return node - }; - - if (!isExpression(query)) { - query = convertToExplicit(query); - } - - return next(query) -} - -// Practical scoring function -function computeScore$1( - results, - { ignoreFieldNorm = Config.ignoreFieldNorm } -) { - results.forEach((result) => { - let totalScore = 1; - - result.matches.forEach(({ key, norm, score }) => { - const weight = key ? key.weight : null; - - totalScore *= Math.pow( - score === 0 && weight ? Number.EPSILON : score, - (weight || 1) * (ignoreFieldNorm ? 1 : norm) - ); - }); - - result.score = totalScore; - }); -} - -function transformMatches(result, data) { - const matches = result.matches; - data.matches = []; - - if (!isDefined(matches)) { - return - } - - matches.forEach((match) => { - if (!isDefined(match.indices) || !match.indices.length) { - return - } - - const { indices, value } = match; - - let obj = { - indices, - value - }; - - if (match.key) { - obj.key = match.key.src; - } - - if (match.idx > -1) { - obj.refIndex = match.idx; - } - - data.matches.push(obj); - }); -} - -function transformScore(result, data) { - data.score = result.score; -} - -function format( - results, - docs, - { - includeMatches = Config.includeMatches, - includeScore = Config.includeScore - } = {} -) { - const transformers = []; - - if (includeMatches) transformers.push(transformMatches); - if (includeScore) transformers.push(transformScore); - - return results.map((result) => { - const { idx } = result; - - const data = { - item: docs[idx], - refIndex: idx - }; - - if (transformers.length) { - transformers.forEach((transformer) => { - transformer(result, data); - }); - } - - return data - }) -} - -class Fuse { - constructor(docs, options = {}, index) { - this.options = { ...Config, ...options }; - - if ( - this.options.useExtendedSearch && - !true - ) { - throw new Error(EXTENDED_SEARCH_UNAVAILABLE) - } - - this._keyStore = new KeyStore(this.options.keys); - - this.setCollection(docs, index); - } - - setCollection(docs, index) { - this._docs = docs; - - if (index && !(index instanceof FuseIndex)) { - throw new Error(INCORRECT_INDEX_TYPE) - } - - this._myIndex = - index || - createIndex(this.options.keys, this._docs, { - getFn: this.options.getFn - }); - } - - add(doc) { - if (!isDefined(doc)) { - return - } - - this._docs.push(doc); - this._myIndex.add(doc); - } - - remove(predicate = (/* doc, idx */) => false) { - const results = []; - - for (let i = 0, len = this._docs.length; i < len; i += 1) { - const doc = this._docs[i]; - if (predicate(doc, i)) { - this.removeAt(i); - i -= 1; - len -= 1; - - results.push(doc); - } - } - - return results - } - - removeAt(idx) { - this._docs.splice(idx, 1); - this._myIndex.removeAt(idx); - } - - getIndex() { - return this._myIndex - } - - search(query, { limit = -1 } = {}) { - const { - includeMatches, - includeScore, - shouldSort, - sortFn, - ignoreFieldNorm - } = this.options; - - let results = isString(query) - ? isString(this._docs[0]) - ? this._searchStringList(query) - : this._searchObjectList(query) - : this._searchLogical(query); - - computeScore$1(results, { ignoreFieldNorm }); - - if (shouldSort) { - results.sort(sortFn); - } - - if (isNumber(limit) && limit > -1) { - results = results.slice(0, limit); - } - - return format(results, this._docs, { - includeMatches, - includeScore - }) - } - - _searchStringList(query) { - const searcher = createSearcher(query, this.options); - const { records } = this._myIndex; - const results = []; - - // Iterate over every string in the index - records.forEach(({ v: text, i: idx, n: norm }) => { - if (!isDefined(text)) { - return - } - - const { isMatch, score, indices } = searcher.searchIn(text); - - if (isMatch) { - results.push({ - item: text, - idx, - matches: [{ score, value: text, norm, indices }] - }); - } - }); - - return results - } - - _searchLogical(query) { - - const expression = parse(query, this.options); - - const evaluate = (node, item, idx) => { - if (!node.children) { - const { keyId, searcher } = node; - - const matches = this._findMatches({ - key: this._keyStore.get(keyId), - value: this._myIndex.getValueForItemAtKeyId(item, keyId), - searcher - }); - - if (matches && matches.length) { - return [ - { - idx, - item, - matches - } - ] - } - - return [] - } - - /*eslint indent: [2, 2, {"SwitchCase": 1}]*/ - switch (node.operator) { - case LogicalOperator.AND: { - const res = []; - for (let i = 0, len = node.children.length; i < len; i += 1) { - const child = node.children[i]; - const result = evaluate(child, item, idx); - if (result.length) { - res.push(...result); - } else { - return [] - } - } - return res - } - case LogicalOperator.OR: { - const res = []; - for (let i = 0, len = node.children.length; i < len; i += 1) { - const child = node.children[i]; - const result = evaluate(child, item, idx); - if (result.length) { - res.push(...result); - break - } - } - return res - } - } - }; - - const records = this._myIndex.records; - const resultMap = {}; - const results = []; - - records.forEach(({ $: item, i: idx }) => { - if (isDefined(item)) { - let expResults = evaluate(expression, item, idx); - - if (expResults.length) { - // Dedupe when adding - if (!resultMap[idx]) { - resultMap[idx] = { idx, item, matches: [] }; - results.push(resultMap[idx]); - } - expResults.forEach(({ matches }) => { - resultMap[idx].matches.push(...matches); - }); - } - } - }); - - return results - } - - _searchObjectList(query) { - const searcher = createSearcher(query, this.options); - const { keys, records } = this._myIndex; - const results = []; - - // List is Array - records.forEach(({ $: item, i: idx }) => { - if (!isDefined(item)) { - return - } - - let matches = []; - - // Iterate over every key (i.e, path), and fetch the value at that key - keys.forEach((key, keyIndex) => { - matches.push( - ...this._findMatches({ - key, - value: item[keyIndex], - searcher - }) - ); - }); - - if (matches.length) { - results.push({ - idx, - item, - matches - }); - } - }); - - return results - } - _findMatches({ key, value, searcher }) { - if (!isDefined(value)) { - return [] - } - - let matches = []; - - if (isArray(value)) { - value.forEach(({ v: text, i: idx, n: norm }) => { - if (!isDefined(text)) { - return - } - - const { isMatch, score, indices } = searcher.searchIn(text); - - if (isMatch) { - matches.push({ - score, - key, - value: text, - idx, - norm, - indices - }); - } - }); - } else { - const { v: text, n: norm } = value; - - const { isMatch, score, indices } = searcher.searchIn(text); - - if (isMatch) { - matches.push({ score, key, value: text, norm, indices }); - } - } - - return matches - } -} - -Fuse.version = '6.4.6'; -Fuse.createIndex = createIndex; -Fuse.parseIndex = parseIndex; -Fuse.config = Config; - -{ - Fuse.parseQuery = parse; -} - -{ - register(ExtendedSearch); -} - -var TagOrFile; -(function (TagOrFile) { - TagOrFile[TagOrFile["Tag"] = 0] = "Tag"; - TagOrFile[TagOrFile["File"] = 1] = "File"; -})(TagOrFile || (TagOrFile = {})); -class SilentFileAndTagSuggester extends TextInputSuggest { - constructor(app, inputEl) { - super(app, inputEl); - this.app = app; - this.inputEl = inputEl; - this.lastInput = ""; - this.files = app.vault.getMarkdownFiles(); - this.unresolvedLinkNames = this.getUnresolvedLinkNames(app); - // @ts-ignore - this.tags = Object.keys(app.metadataCache.getTags()); - } - getSuggestions(inputStr) { - const cursorPosition = this.inputEl.selectionStart; - const inputBeforeCursor = inputStr.substr(0, cursorPosition); - const fileLinkMatch = FILE_LINK_REGEX.exec(inputBeforeCursor); - const tagMatch = TAG_REGEX.exec(inputBeforeCursor); - let suggestions = []; - if (tagMatch) { - const tagInput = tagMatch[1]; - this.lastInput = tagInput; - this.lastInputType = TagOrFile.Tag; - suggestions = this.tags.filter(tag => tag.toLowerCase().contains(tagInput.toLowerCase())); - } - if (fileLinkMatch) { - const fileNameInput = fileLinkMatch[1]; - this.lastInput = fileNameInput; - this.lastInputType = TagOrFile.File; - suggestions = this.files - .filter(file => file.path.toLowerCase().contains(fileNameInput.toLowerCase())) - .map(file => file.path); - suggestions.push(...this.unresolvedLinkNames.filter(name => name.toLowerCase().contains(fileNameInput.toLowerCase()))); - } - const fuse = new Fuse(suggestions, { findAllMatches: true, threshold: 0.8 }); - return fuse.search(this.lastInput).map(value => value.item); - } - renderSuggestion(item, el) { - if (item) - el.setText(item); - } - selectSuggestion(item) { - const cursorPosition = this.inputEl.selectionStart; - const lastInputLength = this.lastInput.length; - const currentInputValue = this.inputEl.value; - let insertedEndPosition = 0; - if (this.lastInputType === TagOrFile.File) { - const linkFile = this.app.vault.getAbstractFileByPath(item); - if (linkFile instanceof obsidian.TFile) { - insertedEndPosition = this.makeLinkObsidianMethod(linkFile, currentInputValue, cursorPosition, lastInputLength); - } - else { - insertedEndPosition = this.makeLinkManually(currentInputValue, item.replace(/.md$/, ''), cursorPosition, lastInputLength); - } - } - if (this.lastInputType === TagOrFile.Tag) { - this.inputEl.value = this.getNewInputValueForTag(currentInputValue, item, cursorPosition, lastInputLength); - insertedEndPosition = cursorPosition - lastInputLength + item.length - 1; - } - this.inputEl.trigger("input"); - this.close(); - this.inputEl.setSelectionRange(insertedEndPosition, insertedEndPosition); - } - makeLinkObsidianMethod(linkFile, currentInputValue, cursorPosition, lastInputLength) { - const link = this.app.fileManager.generateMarkdownLink(linkFile, ''); - this.inputEl.value = this.getNewInputValueForFileLink(currentInputValue, link, cursorPosition, lastInputLength); - return cursorPosition - lastInputLength + link.length + 2; - } - makeLinkManually(currentInputValue, item, cursorPosition, lastInputLength) { - this.inputEl.value = this.getNewInputValueForFileName(currentInputValue, item, cursorPosition, lastInputLength); - return cursorPosition - lastInputLength + item.length + 2; - } - getNewInputValueForFileLink(currentInputElValue, selectedItem, cursorPosition, lastInputLength) { - return `${currentInputElValue.substr(0, cursorPosition - lastInputLength - 2)}${selectedItem}${currentInputElValue.substr(cursorPosition)}`; - } - getNewInputValueForFileName(currentInputElValue, selectedItem, cursorPosition, lastInputLength) { - return `${currentInputElValue.substr(0, cursorPosition - lastInputLength)}${selectedItem}]]${currentInputElValue.substr(cursorPosition)}`; - } - getNewInputValueForTag(currentInputElValue, selectedItem, cursorPosition, lastInputLength) { - return `${currentInputElValue.substr(0, cursorPosition - lastInputLength - 1)}${selectedItem}${currentInputElValue.substr(cursorPosition)}`; - } - getUnresolvedLinkNames(app) { - const unresolvedLinks = app.metadataCache.unresolvedLinks; - const unresolvedLinkNames = new Set(); - for (const sourceFileName in unresolvedLinks) { - for (const unresolvedLink in unresolvedLinks[sourceFileName]) { - unresolvedLinkNames.add(unresolvedLink); - } - } - return Array.from(unresolvedLinkNames); - } -} - -/* src/gui/GenericInputPrompt/GenericInputPromptContent.svelte generated by Svelte v3.43.0 */ - -function create_fragment$7(ctx) { - let div; - let h1; - let t0; - let t1; - let input; - let mounted; - let dispose; - - return { - c() { - div = element("div"); - h1 = element("h1"); - t0 = text(/*header*/ ctx[1]); - t1 = space(); - input = element("input"); - set_style(h1, "text-align", "center"); - attr(input, "class", "quickAddPromptInput"); - attr(input, "placeholder", /*placeholder*/ ctx[2]); - set_style(input, "width", "100%"); - attr(input, "type", "text"); - attr(div, "class", "quickAddPrompt"); - }, - m(target, anchor) { - insert(target, div, anchor); - append(div, h1); - append(h1, t0); - append(div, t1); - append(div, input); - /*input_binding*/ ctx[7](input); - set_input_value(input, /*value*/ ctx[0]); - - if (!mounted) { - dispose = [ - listen(input, "input", /*input_input_handler*/ ctx[8]), - listen(input, "keydown", /*submit*/ ctx[4]) - ]; - - mounted = true; - } - }, - p(ctx, [dirty]) { - if (dirty & /*header*/ 2) set_data(t0, /*header*/ ctx[1]); - - if (dirty & /*placeholder*/ 4) { - attr(input, "placeholder", /*placeholder*/ ctx[2]); - } - - if (dirty & /*value*/ 1 && input.value !== /*value*/ ctx[0]) { - set_input_value(input, /*value*/ ctx[0]); - } - }, - i: noop, - o: noop, - d(detaching) { - if (detaching) detach(div); - /*input_binding*/ ctx[7](null); - mounted = false; - run_all(dispose); - } - }; -} - -function instance$7($$self, $$props, $$invalidate) { - let { header = "" } = $$props; - let { placeholder = "" } = $$props; - let { value = "" } = $$props; - let { onSubmit } = $$props; - let { app } = $$props; - let inputEl; - - onMount(() => { - new SilentFileAndTagSuggester(app, inputEl); - }); - - function submit(evt) { - if (evt.key === "Enter") { - evt.preventDefault(); - onSubmit(value); - } - } - - function input_binding($$value) { - binding_callbacks[$$value ? 'unshift' : 'push'](() => { - inputEl = $$value; - $$invalidate(3, inputEl); - }); - } - - function input_input_handler() { - value = this.value; - $$invalidate(0, value); - } - - $$self.$$set = $$props => { - if ('header' in $$props) $$invalidate(1, header = $$props.header); - if ('placeholder' in $$props) $$invalidate(2, placeholder = $$props.placeholder); - if ('value' in $$props) $$invalidate(0, value = $$props.value); - if ('onSubmit' in $$props) $$invalidate(5, onSubmit = $$props.onSubmit); - if ('app' in $$props) $$invalidate(6, app = $$props.app); - }; - - return [ - value, - header, - placeholder, - inputEl, - submit, - onSubmit, - app, - input_binding, - input_input_handler - ]; -} - -class GenericInputPromptContent extends SvelteComponent { - constructor(options) { - super(); - - init(this, options, instance$7, create_fragment$7, safe_not_equal, { - header: 1, - placeholder: 2, - value: 0, - onSubmit: 5, - app: 6 - }); - } -} - -class GenericInputPrompt extends obsidian.Modal { - constructor(app, header, placeholder, value) { - super(app); - this.didSubmit = false; - this.modalContent = new GenericInputPromptContent({ - target: this.contentEl, - props: { - header, - placeholder, - value, - app, - onSubmit: (input) => { - this.input = input; - this.didSubmit = true; - this.close(); - } - } - }); - this.waitForClose = new Promise((resolve, reject) => { - this.resolvePromise = resolve; - this.rejectPromise = reject; - }); - this.open(); - } - static Prompt(app, header, placeholder, value) { - const newPromptModal = new GenericInputPrompt(app, header, placeholder, value); - return newPromptModal.waitForClose; - } - onOpen() { - super.onOpen(); - const modalPrompt = document.querySelector('.quickAddPrompt'); - const modalInput = modalPrompt.querySelector('.quickAddPromptInput'); - modalInput.focus(); - modalInput.select(); - } - onClose() { - super.onClose(); - this.modalContent.$destroy(); - if (!this.didSubmit) - this.rejectPromise("No input given."); - else - this.resolvePromise(this.input); - } -} - -class LogManager { - register(logger) { - LogManager.loggers.push(logger); - return this; - } - logError(message) { - LogManager.loggers.forEach(logger => logger.logError(message)); - throw new Error(); - } - logWarning(message) { - LogManager.loggers.forEach(logger => logger.logError(message)); - } - logMessage(message) { - LogManager.loggers.forEach(logger => logger.logMessage(message)); - } -} -LogManager.loggers = []; -const log = new LogManager(); - -class ChoiceBuilder extends obsidian.Modal { - constructor(app) { - super(app); - this.didSubmit = false; - this.svelteElements = []; - this.waitForClose = new Promise((resolve, reject) => { - this.resolvePromise = resolve; - this.rejectPromise = reject; - }); - this.containerEl.addClass('quickAddModal'); - this.open(); - } - reload() { - this.contentEl.empty(); - this.display(); - } - addFileSearchInputToSetting(setting, value, onChangeCallback) { - let component; - setting.addSearch(searchComponent => { - component = searchComponent; - searchComponent.setValue(value); - searchComponent.setPlaceholder("File path"); - const markdownFiles = this.app.vault.getMarkdownFiles().map(f => f.path); - new GenericTextSuggester(this.app, searchComponent.inputEl, markdownFiles); - searchComponent.onChange(onChangeCallback); - }); - return component; - } - addCenteredChoiceNameHeader(choice) { - const headerEl = this.contentEl.createEl('h2', { cls: "choiceNameHeader" }); - headerEl.setText(choice.name); - headerEl.addEventListener('click', async (ev) => { - try { - const newName = await GenericInputPrompt.Prompt(this.app, choice.name, "Choice name", choice.name); - if (newName !== choice.name) { - choice.name = newName; - headerEl.setText(newName); - } - } - catch (e) { - log.logMessage(`No new name given for ${choice.name}`); - } - }); - } - onClose() { - super.onClose(); - this.resolvePromise(this.choice); - this.svelteElements.forEach(el => { - if (el && el.$destroy) - el.$destroy(); - }); - if (!this.didSubmit) - this.rejectPromise("No answer given."); - else - this.resolvePromise(this.input); - } -} - -function getTemplater(app) { - // @ts-ignore - return app.plugins.plugins["templater-obsidian"]; -} -async function replaceTemplaterTemplatesInCreatedFile(app, file, force = false) { - const templater = getTemplater(app); - if (templater && (force || !(templater === null || templater === void 0 ? void 0 : templater.settings["trigger_on_file_creation"]))) { - app.workspace.getActiveFile(); - await templater.templater.overwrite_file_commands(file); - } -} -async function templaterParseTemplate(app, templateContent, targetFile) { - const templater = getTemplater(app); - if (!templater) - return templateContent; - return await templater.templater.parse_template({ target_file: targetFile, run_mode: 4 }, templateContent); -} -function getCoreTemplatesPath(app) { - // @ts-ignore - const internalTemplatePlugin = app.internalPlugins.plugins.templates; - if (internalTemplatePlugin) { - const templateFolderPath = internalTemplatePlugin.instance.options.folder; - if (templateFolderPath) - return templateFolderPath; - } -} -function getTemplaterTemplatesPath(app) { - const templater = getTemplater(app); - if (templater) { - const templateFolderPath = templater.settings["template_folder"]; - if (templateFolderPath) - return templateFolderPath; - } -} -function getTemplateFiles(app) { - let templateFiles = new Set(); - const markdownFiles = app.vault.getMarkdownFiles(); - const coreTemplatesPath = getCoreTemplatesPath(app); - const templaterTemplatesPath = getTemplaterTemplatesPath(app); - markdownFiles.forEach(file => { - if (file.path.contains(coreTemplatesPath) || file.path.contains(templaterTemplatesPath)) - templateFiles.add(file); - }); - return [...templateFiles]; -} -function getTemplatePaths(app) { - return getTemplateFiles(app).map(file => file.path); -} -function getNaturalLanguageDates(app) { - // @ts-ignore - return app.plugins.plugins["nldates-obsidian"]; -} -function getDate(input) { - let duration; - if (input.offset !== null && input.offset !== undefined && typeof input.offset === "number") { - duration = window.moment.duration(input.offset, "days"); - } - return input.format ? window.moment().add(duration).format(input.format) - : window.moment().add(duration).format("YYYY-MM-DD"); -} -function appendToCurrentLine(toAppend, app) { - try { - const activeView = app.workspace.getActiveViewOfType(obsidian.MarkdownView); - if (!activeView) { - log.logError(`unable to append '${toAppend}' to current line.`); - return; - } - activeView.editor.replaceSelection(toAppend); - } - catch (_a) { - log.logError(`unable to append '${toAppend}' to current line.`); - } -} -function findObsidianCommand(app, commandId) { - // @ts-ignore - return app.commands.findCommand(commandId); -} -function deleteObsidianCommand(app, commandId) { - if (findObsidianCommand(app, commandId)) { - // @ts-ignore - delete app.commands.commands[commandId]; - // @ts-ignore - delete app.commands.editorCommands[commandId]; - } -} -function getAllFolderPathsInVault(app) { - return app.vault.getAllLoadedFiles() - .filter(f => f instanceof obsidian.TFolder) - .map(folder => folder.path); -} -function getUserScriptMemberAccess(fullMemberPath) { - const fullMemberArray = fullMemberPath.split("::"); - return { - basename: fullMemberArray[0], - memberAccess: fullMemberArray.slice(1) - }; -} -function waitFor(ms) { - return new Promise(res => setTimeout(res, ms)); -} -function getLinesInString(input) { - let lines = []; - let tempString = input; - while (tempString.contains("\n")) { - const lineEndIndex = tempString.indexOf("\n"); - lines.push(tempString.slice(0, lineEndIndex)); - tempString = tempString.slice(lineEndIndex + 1); - } - lines.push(tempString); - return lines; -} -// https://stackoverflow.com/questions/3115150/how-to-escape-regular-expression-special-characters-using-javascript -function escapeRegExp(text) { - return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&'); -} -async function openFile(app, file, optional) { - let leaf; - if ((optional === null || optional === void 0 ? void 0 : optional.openInNewTab) && (optional === null || optional === void 0 ? void 0 : optional.direction)) { - leaf = app.workspace.splitActiveLeaf(optional.direction); - } - else { - leaf = app.workspace.activeLeaf; - } - await leaf.openFile(file); - if ((optional === null || optional === void 0 ? void 0 : optional.mode) || (optional === null || optional === void 0 ? void 0 : optional.focus)) { - await leaf.setViewState(Object.assign(Object.assign({}, leaf.getViewState()), { state: optional.mode && optional.mode !== 'default' ? Object.assign(Object.assign({}, leaf.view.getState()), { mode: optional.mode }) : leaf.view.getState(), popstate: true }), { focus: optional === null || optional === void 0 ? void 0 : optional.focus }); - } -} -async function getUserScript(command, app) { - // @ts-ignore - const vaultPath = app.vault.adapter.getBasePath(); - const file = app.vault.getAbstractFileByPath(command.path); - if (!file) { - log.logError(`failed to load file ${command.path}.`); - return; - } - if (file instanceof obsidian.TFile) { - const filePath = `${vaultPath}/${file.path}`; - if (window.require.cache[window.require.resolve(filePath)]) { - delete window.require.cache[window.require.resolve(filePath)]; - } - // @ts-ignore - const userScript = await (function (t) { return Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require(t)); }); })(filePath); - if (!userScript || !userScript.default) - return; - let script = userScript.default; - const { memberAccess } = getUserScriptMemberAccess(command.name); - if (memberAccess && memberAccess.length > 0) { - let member; - while (member = memberAccess.shift()) { - script = script[member]; - } - } - return script; - } -} - -var FormatSyntaxToken; -(function (FormatSyntaxToken) { - FormatSyntaxToken[FormatSyntaxToken["Date"] = 0] = "Date"; - FormatSyntaxToken[FormatSyntaxToken["DateFormat"] = 1] = "DateFormat"; - FormatSyntaxToken[FormatSyntaxToken["VariableDate"] = 2] = "VariableDate"; - FormatSyntaxToken[FormatSyntaxToken["Value"] = 3] = "Value"; - FormatSyntaxToken[FormatSyntaxToken["Name"] = 4] = "Name"; - FormatSyntaxToken[FormatSyntaxToken["Variable"] = 5] = "Variable"; - FormatSyntaxToken[FormatSyntaxToken["LinkCurrent"] = 6] = "LinkCurrent"; - FormatSyntaxToken[FormatSyntaxToken["Macro"] = 7] = "Macro"; - FormatSyntaxToken[FormatSyntaxToken["Template"] = 8] = "Template"; -})(FormatSyntaxToken || (FormatSyntaxToken = {})); -class FormatSyntaxSuggester extends TextInputSuggest { - constructor(app, inputEl, plugin, suggestForFileNames = false) { - super(app, inputEl); - this.app = app; - this.inputEl = inputEl; - this.plugin = plugin; - this.suggestForFileNames = suggestForFileNames; - this.lastInput = ""; - this.macroNames = this.plugin.settings.macros.map(macro => macro.name); - this.templatePaths = getTemplatePaths(this.app); - } - getSuggestions(inputStr) { - const cursorPosition = this.inputEl.selectionStart; - const lookbehind = 15; - const inputBeforeCursor = inputStr.substr(cursorPosition - lookbehind, lookbehind); - let suggestions = []; - this.processToken(inputBeforeCursor, (match, type, suggestion) => { - this.lastInput = match[0]; - this.lastInputType = type; - suggestions.push(suggestion); - if (this.lastInputType === FormatSyntaxToken.Template) { - suggestions.push(...this.templatePaths.map(templatePath => `{{TEMPLATE:${templatePath}}}`)); - } - if (this.lastInputType === FormatSyntaxToken.Macro) { - suggestions.push(...this.macroNames.map(macroName => `{{MACRO:${macroName}}}`)); - } - }); - return suggestions; - } - selectSuggestion(item) { - const cursorPosition = this.inputEl.selectionStart; - const lastInputLength = this.lastInput.length; - const currentInputValue = this.inputEl.value; - let insertedEndPosition = 0; - const insert = (text, offset = 0) => { - return `${currentInputValue.substr(0, cursorPosition - lastInputLength + offset)}${text}${currentInputValue.substr(cursorPosition)}`; - }; - this.processToken(item, ((match, type, suggestion) => { - if (item.contains(suggestion)) { - this.inputEl.value = insert(item); - this.lastInputType = type; - insertedEndPosition = cursorPosition - lastInputLength + item.length; - if (this.lastInputType === FormatSyntaxToken.VariableDate || - this.lastInputType === FormatSyntaxToken.Variable || - this.lastInputType === FormatSyntaxToken.DateFormat) { - insertedEndPosition -= 2; - } - } - })); - this.inputEl.trigger("input"); - this.close(); - this.inputEl.setSelectionRange(insertedEndPosition, insertedEndPosition); - } - renderSuggestion(value, el) { - if (value) - el.setText(value); - } - processToken(input, callback) { - const dateFormatMatch = DATE_FORMAT_SYNTAX_SUGGEST_REGEX.exec(input); - if (dateFormatMatch) - callback(dateFormatMatch, FormatSyntaxToken.DateFormat, "{{DATE:}}"); - const dateMatch = DATE_SYNTAX_SUGGEST_REGEX.exec(input); - if (dateMatch) - callback(dateMatch, FormatSyntaxToken.Date, DATE_SYNTAX); - const nameMatch = NAME_SYNTAX_SUGGEST_REGEX.exec(input); - if (nameMatch) - callback(nameMatch, FormatSyntaxToken.Name, NAME_SYNTAX); - const valueMatch = VALUE_SYNTAX_SUGGEST_REGEX.exec(input); - if (valueMatch) - callback(valueMatch, FormatSyntaxToken.Value, VALUE_SYNTAX); - const variableMatch = VARIABLE_SYNTAX_SUGGEST_REGEX.exec(input); - if (variableMatch) - callback(variableMatch, FormatSyntaxToken.Variable, "{{VALUE:}}"); - const variableDateMatch = VARIABLE_DATE_SYNTAX_SUGGEST_REGEX.exec(input); - if (variableDateMatch) - callback(variableDateMatch, FormatSyntaxToken.VariableDate, "{{VDATE:}}"); - if (!this.suggestForFileNames) { - const linkCurrentMatch = LINKCURRENT_SYNTAX_SUGGEST_REGEX.exec(input); - if (linkCurrentMatch) - callback(linkCurrentMatch, FormatSyntaxToken.LinkCurrent, LINKCURRENT_SYNTAX); - const templateMatch = TEMPLATE_SYNTAX_SUGGEST_REGEX.exec(input); - if (templateMatch) - callback(templateMatch, FormatSyntaxToken.Template, "{{TEMPLATE:"); - const macroMatch = MACRO_SYNTAX_SUGGEST_REGEX.exec(input); - if (macroMatch) - callback(macroMatch, FormatSyntaxToken.Macro, "{{MACRO:"); - } - } -} - -/* src/gui/ChoiceBuilder/FolderList.svelte generated by Svelte v3.43.0 */ - -function add_css$3(target) { - append_styles(target, "svelte-tuapcq", ".quickAddCommandListItem.svelte-tuapcq{display:flex;align-items:center;justify-content:space-between}@media(min-width: 768px){.quickAddFolderListGrid.svelte-tuapcq{display:grid;grid-template-columns:repeat(2, 1fr);column-gap:20px}}.quickAddCommandList.svelte-tuapcq{max-width:50%;margin:12px auto}.clickable.svelte-tuapcq{cursor:pointer}"); -} - -function get_each_context$1(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[4] = list[i]; - child_ctx[6] = i; - return child_ctx; -} - -// (11:4) {#each folders as folder, i} -function create_each_block$1(ctx) { - let div; - let span0; - let t0_value = /*folder*/ ctx[4] + ""; - let t0; - let t1; - let span1; - let icon; - let t2; - let current; - let mounted; - let dispose; - icon = new Icon({ props: { data: faTrash } }); - - function click_handler() { - return /*click_handler*/ ctx[3](/*folder*/ ctx[4]); - } - - return { - c() { - div = element("div"); - span0 = element("span"); - t0 = text(t0_value); - t1 = space(); - span1 = element("span"); - create_component(icon.$$.fragment); - t2 = space(); - attr(span1, "class", "clickable svelte-tuapcq"); - attr(div, "class", "quickAddCommandListItem svelte-tuapcq"); - }, - m(target, anchor) { - insert(target, div, anchor); - append(div, span0); - append(span0, t0); - append(div, t1); - append(div, span1); - mount_component(icon, span1, null); - append(div, t2); - current = true; - - if (!mounted) { - dispose = listen(span1, "click", click_handler); - mounted = true; - } - }, - p(new_ctx, dirty) { - ctx = new_ctx; - if ((!current || dirty & /*folders*/ 1) && t0_value !== (t0_value = /*folder*/ ctx[4] + "")) set_data(t0, t0_value); - }, - i(local) { - if (current) return; - transition_in(icon.$$.fragment, local); - current = true; - }, - o(local) { - transition_out(icon.$$.fragment, local); - current = false; - }, - d(detaching) { - if (detaching) detach(div); - destroy_component(icon); - mounted = false; - dispose(); - } - }; -} - -function create_fragment$6(ctx) { - let div; - let current; - let each_value = /*folders*/ ctx[0]; - let each_blocks = []; - - for (let i = 0; i < each_value.length; i += 1) { - each_blocks[i] = create_each_block$1(get_each_context$1(ctx, each_value, i)); - } - - const out = i => transition_out(each_blocks[i], 1, 1, () => { - each_blocks[i] = null; - }); - - return { - c() { - div = element("div"); - - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].c(); - } - - attr(div, "class", "quickAddFolderListGrid quickAddCommandList svelte-tuapcq"); - }, - m(target, anchor) { - insert(target, div, anchor); - - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].m(div, null); - } - - current = true; - }, - p(ctx, [dirty]) { - if (dirty & /*deleteFolder, folders, faTrash*/ 3) { - each_value = /*folders*/ ctx[0]; - let i; - - for (i = 0; i < each_value.length; i += 1) { - const child_ctx = get_each_context$1(ctx, each_value, i); - - if (each_blocks[i]) { - each_blocks[i].p(child_ctx, dirty); - transition_in(each_blocks[i], 1); - } else { - each_blocks[i] = create_each_block$1(child_ctx); - each_blocks[i].c(); - transition_in(each_blocks[i], 1); - each_blocks[i].m(div, null); - } - } - - group_outros(); - - for (i = each_value.length; i < each_blocks.length; i += 1) { - out(i); - } - - check_outros(); - } - }, - i(local) { - if (current) return; - - for (let i = 0; i < each_value.length; i += 1) { - transition_in(each_blocks[i]); - } - - current = true; - }, - o(local) { - each_blocks = each_blocks.filter(Boolean); - - for (let i = 0; i < each_blocks.length; i += 1) { - transition_out(each_blocks[i]); - } - - current = false; - }, - d(detaching) { - if (detaching) detach(div); - destroy_each(each_blocks, detaching); - } - }; -} - -function instance$6($$self, $$props, $$invalidate) { - let { folders } = $$props; - let { deleteFolder } = $$props; - - const updateFolders = newFolders => { - $$invalidate(0, folders = newFolders); - }; - - const click_handler = folder => deleteFolder(folder); - - $$self.$$set = $$props => { - if ('folders' in $$props) $$invalidate(0, folders = $$props.folders); - if ('deleteFolder' in $$props) $$invalidate(1, deleteFolder = $$props.deleteFolder); - }; - - return [folders, deleteFolder, updateFolders, click_handler]; -} - -class FolderList extends SvelteComponent { - constructor(options) { - super(); - - init( - this, - options, - instance$6, - create_fragment$6, - safe_not_equal, - { - folders: 0, - deleteFolder: 1, - updateFolders: 2 - }, - add_css$3 - ); - } - - get updateFolders() { - return this.$$.ctx[2]; - } -} - -class Formatter { - constructor() { - this.variables = new Map(); - } - replacer(str, reg, replaceValue) { - return str.replace(reg, function () { return replaceValue; }); - } - replaceDateInString(input) { - let output = input; - while (DATE_REGEX.test(output)) { - const dateMatch = DATE_REGEX.exec(output); - let offset; - if (dateMatch[1]) { - const offsetString = dateMatch[1].replace('+', '').trim(); - const offsetIsInt = NUMBER_REGEX.test(offsetString); - if (offsetIsInt) - offset = parseInt(offsetString); - } - output = this.replacer(output, DATE_REGEX, getDate({ offset: offset })); - } - while (DATE_REGEX_FORMATTED.test(output)) { - const dateMatch = DATE_REGEX_FORMATTED.exec(output); - const format = dateMatch[1]; - let offset; - if (dateMatch[2]) { - const offsetString = dateMatch[2].replace('+', '').trim(); - const offsetIsInt = NUMBER_REGEX.test(offsetString); - if (offsetIsInt) - offset = parseInt(offsetString); - } - output = this.replacer(output, DATE_REGEX_FORMATTED, getDate({ format, offset })); - } - return output; - } - async replaceValueInString(input) { - let output = input; - while (NAME_VALUE_REGEX.test(output)) { - if (!this.value) - this.value = await this.promptForValue(); - output = this.replacer(output, NAME_VALUE_REGEX, this.value); - } - return output; - } - async replaceLinkToCurrentFileInString(input) { - const currentFilePathLink = this.getCurrentFileLink(); - let output = input; - while (LINK_TO_CURRENT_FILE_REGEX.test(output)) - output = this.replacer(output, LINK_TO_CURRENT_FILE_REGEX, currentFilePathLink); - return output; - } - async replaceVariableInString(input) { - let output = input; - while (VARIABLE_REGEX.test(output)) { - const match = VARIABLE_REGEX.exec(output); - const variableName = match[1]; - if (variableName) { - if (!this.getVariableValue(variableName)) { - const suggestedValues = variableName.split(","); - if (suggestedValues.length === 1) - this.variables.set(variableName, await this.promptForVariable(variableName)); - else - this.variables.set(variableName, await this.suggestForValue(suggestedValues)); - } - output = this.replacer(output, VARIABLE_REGEX, this.getVariableValue(variableName)); - } - else { - break; - } - } - return output; - } - async replaceMacrosInString(input) { - let output = input; - while (MACRO_REGEX.test(output)) { - const macroName = MACRO_REGEX.exec(output)[1]; - const macroOutput = await this.getMacroValue(macroName); - output = this.replacer(output, MACRO_REGEX, macroOutput ? macroOutput.toString() : ""); - } - return output; - } - async replaceDateVariableInString(input) { - let output = input; - while (DATE_VARIABLE_REGEX.test(output)) { - const match = DATE_VARIABLE_REGEX.exec(output); - const variableName = match[1]; - const dateFormat = match[2]; - if (variableName && dateFormat) { - if (!this.variables[variableName]) { - this.variables[variableName] = await this.promptForVariable(variableName); - const parseAttempt = this.getNaturalLanguageDates().parseDate(this.variables[variableName]); - if (parseAttempt) - this.variables[variableName] = parseAttempt.moment.format(dateFormat); - else - throw new Error(`unable to parse date variable ${this.variables[variableName]}`); - } - output = this.replacer(output, DATE_VARIABLE_REGEX, this.variables[variableName]); - } - else { - break; - } - } - return output; - } - async replaceTemplateInString(input) { - let output = input; - while (TEMPLATE_REGEX.test(output)) { - const templatePath = TEMPLATE_REGEX.exec(output)[1]; - const templateContent = await this.getTemplateContent(templatePath); - output = this.replacer(output, TEMPLATE_REGEX, templateContent); - } - return output; - } - replaceLinebreakInString(input) { - let output = input; - while (LINEBREAK_REGEX.test(output)) { - output = this.replacer(output, LINEBREAK_REGEX, `\n`); - } - return output; - } -} - -class FileNameDisplayFormatter extends Formatter { - constructor(app) { - super(); - this.app = app; - } - async format(input) { - let output = input; - output = await this.replaceMacrosInString(output); - output = this.replaceDateInString(output); - output = await this.replaceValueInString(output); - output = await this.replaceDateVariableInString(output); - output = await this.replaceVariableInString(output); - return `File Name: ${output}`; - } - promptForValue(header) { - return `FileName`; - } - getVariableValue(variableName) { - return variableName; - } - getCurrentFileLink() { - var _a; - return (_a = this.app.workspace.getActiveFile().path) !== null && _a !== void 0 ? _a : ""; - } - getNaturalLanguageDates() { - return getNaturalLanguageDates(this.app); - } - suggestForValue(suggestedValues) { - return "_suggest_"; - } - getMacroValue(macroName) { - return `_macro: ${macroName}`; - } - async promptForVariable(variableName) { - return `_${variableName}_`; - } - async getTemplateContent(templatePath) { - return `/${templatePath}/`; - } - async getSelectedText() { - return "_selected_"; - } -} - -class ExclusiveSuggester extends TextInputSuggest { - constructor(app, inputEl, suggestItems, currentItems) { - super(app, inputEl); - this.app = app; - this.inputEl = inputEl; - this.suggestItems = suggestItems; - this.currentItems = currentItems; - } - updateCurrentItems(currentItems) { - this.currentItems = currentItems; - } - getSuggestions(inputStr) { - return this.suggestItems.filter(item => item.contains(inputStr)); - } - selectSuggestion(item) { - this.inputEl.value = item; - this.inputEl.trigger("input"); - this.close(); - } - renderSuggestion(value, el) { - if (value) - el.setText(value); - } -} - -class TemplateChoiceBuilder extends ChoiceBuilder { - constructor(app, choice, plugin) { - super(app); - this.plugin = plugin; - this.choice = choice; - this.display(); - } - display() { - this.addCenteredChoiceNameHeader(this.choice); - this.addTemplatePathSetting(); - this.addFileNameFormatSetting(); - this.addFolderSetting(); - this.addAppendLinkSetting(); - this.addIncrementFileNameSetting(); - this.addOpenFileSetting(); - if (this.choice.openFile) - this.addOpenFileInNewTabSetting(); - } - addTemplatePathSetting() { - new obsidian.Setting(this.contentEl) - .setName('Template Path') - .setDesc('Path to the Template.') - .addSearch(search => { - const templates = getTemplatePaths(this.app); - search.setValue(this.choice.templatePath); - search.setPlaceholder("Template path"); - new GenericTextSuggester(this.app, search.inputEl, templates); - search.onChange(value => { - this.choice.templatePath = value; - }); - }); - } - addFileNameFormatSetting() { - let textField; - const enableSetting = new obsidian.Setting(this.contentEl); - enableSetting.setName("File Name Format") - .setDesc("Set the file name format.") - .addToggle(toggleComponent => { - toggleComponent.setValue(this.choice.fileNameFormat.enabled) - .onChange(value => { - this.choice.fileNameFormat.enabled = value; - textField.setDisabled(!value); - }); - }); - const formatDisplay = this.contentEl.createEl('span'); - const displayFormatter = new FileNameDisplayFormatter(this.app); - (async () => formatDisplay.textContent = await displayFormatter.format(this.choice.fileNameFormat.format))(); - const formatInput = new obsidian.TextComponent(this.contentEl); - formatInput.setPlaceholder("File name format"); - textField = formatInput; - formatInput.inputEl.style.width = "100%"; - formatInput.inputEl.style.marginBottom = "8px"; - formatInput.setValue(this.choice.fileNameFormat.format) - .setDisabled(!this.choice.fileNameFormat.enabled) - .onChange(async (value) => { - this.choice.fileNameFormat.format = value; - formatDisplay.textContent = await displayFormatter.format(value); - }); - new FormatSyntaxSuggester(this.app, textField.inputEl, this.plugin, true); - } - addFolderSetting() { - var _a, _b, _c, _d; - const folderSetting = new obsidian.Setting(this.contentEl); - folderSetting.setName("Create in folder") - .setDesc("Create the file in the specified folder. If multiple folders are specified, you will be prompted for which folder to create the file in.") - .addToggle(toggle => { - toggle.setValue(this.choice.folder.enabled); - toggle.onChange(value => { - this.choice.folder.enabled = value; - this.reload(); - }); - }); - if (this.choice.folder.enabled) { - if (!((_a = this.choice.folder) === null || _a === void 0 ? void 0 : _a.createInSameFolderAsActiveFile)) { - const chooseFolderWhenCreatingNoteContainer = this.contentEl.createDiv('chooseFolderWhenCreatingNoteContainer'); - chooseFolderWhenCreatingNoteContainer.createEl('span', { text: "Choose folder when creating a new note" }); - const chooseFolderWhenCreatingNote = new obsidian.ToggleComponent(chooseFolderWhenCreatingNoteContainer); - chooseFolderWhenCreatingNote.setValue((_b = this.choice.folder) === null || _b === void 0 ? void 0 : _b.chooseWhenCreatingNote) - .onChange(value => { - this.choice.folder.chooseWhenCreatingNote = value; - this.reload(); - }); - if (!((_c = this.choice.folder) === null || _c === void 0 ? void 0 : _c.chooseWhenCreatingNote)) { - this.addFolderSelector(); - } - } - if (!((_d = this.choice.folder) === null || _d === void 0 ? void 0 : _d.chooseWhenCreatingNote)) { - const createInSameFolderAsActiveFileSetting = new obsidian.Setting(this.contentEl); - createInSameFolderAsActiveFileSetting.setName("Create in same folder as active file") - .setDesc("Creates the file in the same folder as the currently active file. Will not create the file if there is no active file.") - .addToggle(toggle => { - var _a; - return toggle - .setValue((_a = this.choice.folder) === null || _a === void 0 ? void 0 : _a.createInSameFolderAsActiveFile) - .onChange(value => { - this.choice.folder.createInSameFolderAsActiveFile = value; - this.reload(); - }); - }); - } - } - } - addFolderSelector() { - const folderSelectionContainer = this.contentEl.createDiv('folderSelectionContainer'); - const folderList = folderSelectionContainer.createDiv('folderList'); - const folderListEl = new FolderList({ - target: folderList, - props: { - folders: this.choice.folder.folders, - deleteFolder: (folder) => { - this.choice.folder.folders = this.choice.folder.folders.filter(f => f !== folder); - folderListEl.updateFolders(this.choice.folder.folders); - suggester.updateCurrentItems(this.choice.folder.folders); - } - } - }); - this.svelteElements.push(folderListEl); - const inputContainer = folderSelectionContainer.createDiv('folderInputContainer'); - const folderInput = new obsidian.TextComponent(inputContainer); - folderInput.inputEl.style.width = "100%"; - folderInput.setPlaceholder("Folder path"); - const allFolders = getAllFolderPathsInVault(this.app); - const suggester = new ExclusiveSuggester(this.app, folderInput.inputEl, allFolders, this.choice.folder.folders); - const addFolder = () => { - const input = folderInput.inputEl.value.trim(); - if (this.choice.folder.folders.some(folder => folder === input)) { - log.logWarning("cannot add same folder twice."); - return; - } - this.choice.folder.folders.push(input); - folderListEl.updateFolders(this.choice.folder.folders); - folderInput.inputEl.value = ""; - suggester.updateCurrentItems(this.choice.folder.folders); - }; - folderInput.inputEl.addEventListener('keypress', (e) => { - if (e.key === 'Enter') { - addFolder(); - } - }); - const addButton = new obsidian.ButtonComponent(inputContainer); - addButton.setCta().setButtonText("Add").onClick(evt => { - addFolder(); - }); - } - addAppendLinkSetting() { - const appendLinkSetting = new obsidian.Setting(this.contentEl); - appendLinkSetting.setName("Append link") - .setDesc("Append link to created file to current file.") - .addToggle(toggle => { - toggle.setValue(this.choice.appendLink); - toggle.onChange(value => this.choice.appendLink = value); - }); - } - addIncrementFileNameSetting() { - const incrementFileNameSetting = new obsidian.Setting(this.contentEl); - incrementFileNameSetting.setName("Increment file name") - .setDesc("If the file already exists, increment the file name.") - .addToggle(toggle => { - toggle.setValue(this.choice.incrementFileName); - toggle.onChange(value => this.choice.incrementFileName = value); - }); - } - addOpenFileSetting() { - const noOpenSetting = new obsidian.Setting(this.contentEl); - noOpenSetting.setName("Open") - .setDesc("Open the created file.") - .addToggle(toggle => { - toggle.setValue(this.choice.openFile); - toggle.onChange(value => { - this.choice.openFile = value; - this.reload(); - }); - }) - .addDropdown(dropdown => { - dropdown.selectEl.style.marginLeft = "10px"; - if (!this.choice.openFileInMode) - this.choice.openFileInMode = 'default'; - dropdown - .addOption('source', 'Source') - .addOption('preview', 'Preview') - .addOption('default', 'Default') - .setValue(this.choice.openFileInMode) - .onChange(value => this.choice.openFileInMode = value); - }); - } - addOpenFileInNewTabSetting() { - const newTabSetting = new obsidian.Setting(this.contentEl); - newTabSetting.setName("New Tab") - .setDesc("Open created file in a new tab.") - .addToggle(toggle => { - toggle.setValue(this.choice.openFileInNewTab.enabled); - toggle.onChange(value => this.choice.openFileInNewTab.enabled = value); - }) - .addDropdown(dropdown => { - dropdown.selectEl.style.marginLeft = "10px"; - dropdown.addOption(NewTabDirection.vertical, "Vertical"); - dropdown.addOption(NewTabDirection.horizontal, "Horizontal"); - dropdown.setValue(this.choice.openFileInNewTab.direction); - dropdown.onChange(value => this.choice.openFileInNewTab.direction = value); - }); - new obsidian.Setting(this.contentEl) - .setName("Focus new pane") - .setDesc("Focus the opened tab immediately") - .addToggle(toggle => toggle - .setValue(this.choice.openFileInNewTab.focus) - .onChange(value => this.choice.openFileInNewTab.focus = value)); - } -} - -class QuickAddEngine { - constructor(app) { - this.app = app; - } - async createFolder(folder) { - const folderExists = await this.app.vault.adapter.exists(folder); - if (!folderExists) { - await this.app.vault.createFolder(folder); - } - } - formatFilePath(folderPath, fileName) { - const actualFolderPath = folderPath ? `${folderPath}/` : ""; - const formattedFileName = fileName.replace(MARKDOWN_FILE_EXTENSION_REGEX, ''); - return `${actualFolderPath}${formattedFileName}.md`; - } - async fileExists(filePath) { - return await this.app.vault.adapter.exists(filePath); - } - async getFileByPath(filePath) { - const file = await this.app.vault.getAbstractFileByPath(filePath); - if (!file) { - log.logError(`${filePath} not found`); - return null; - } - if (file instanceof obsidian.TFolder) { - log.logError(`${filePath} found but it's a folder`); - return null; - } - if (file instanceof obsidian.TFile) - return file; - } - async createFileWithInput(filePath, fileContent) { - const dirMatch = filePath.match(/(.*)[\/\\]/); - let dirName = ""; - if (dirMatch) - dirName = dirMatch[1]; - if (await this.app.vault.adapter.exists(dirName)) { - return await this.app.vault.create(filePath, fileContent); - } - else { - await this.createFolder(dirName); - return await this.app.vault.create(filePath, fileContent); - } - } -} - -class GenericSuggester extends obsidian.FuzzySuggestModal { - constructor(app, displayItems, items) { - super(app); - this.displayItems = displayItems; - this.items = items; - this.promise = new Promise((resolve, reject) => { (this.resolvePromise = resolve); (this.rejectPromise = reject); }); - this.open(); - } - static Suggest(app, displayItems, items) { - const newSuggester = new GenericSuggester(app, displayItems, items); - return newSuggester.promise; - } - getItemText(item) { - return this.displayItems[this.items.indexOf(item)]; - } - getItems() { - return this.items; - } - selectSuggestion(value, evt) { - this.resolved = true; - super.selectSuggestion(value, evt); - } - onChooseItem(item, evt) { - this.resolved = true; - this.resolvePromise(item); - } - onClose() { - super.onClose(); - if (!this.resolved) - this.rejectPromise("no input given."); - } -} - -var CommandType; -(function (CommandType) { - CommandType["Obsidian"] = "Obsidian"; - CommandType["UserScript"] = "UserScript"; - CommandType["Choice"] = "Choice"; - CommandType["Wait"] = "Wait"; - CommandType["NestedChoice"] = "NestedChoice"; - CommandType["EditorCommand"] = "EditorCommand"; -})(CommandType || (CommandType = {})); - -class GenericCheckboxPrompt extends obsidian.Modal { - constructor(app, items, selectedItems = []) { - super(app); - this.items = items; - this.selectedItems = selectedItems; - // This clones the item so that we don't get any unexpected modifications of the - // arguments - this._selectedItems = [...selectedItems]; - this.promise = new Promise((resolve, reject) => { (this.resolvePromise = resolve); (this.rejectPromise = reject); }); - this.display(); - this.open(); - } - static Open(app, items, selectedItems) { - const newSuggester = new GenericCheckboxPrompt(app, items, selectedItems); - return newSuggester.promise; - } - display() { - this.contentEl.empty(); - this.containerEl.addClass('quickAddModal'); - this.addCheckboxRows(); - this.addSubmitButton(); - } - onClose() { - super.onClose(); - if (!this.resolved) - this.rejectPromise("no input given."); - } - addCheckboxRows() { - const rowContainer = this.contentEl.createDiv('checkboxRowContainer'); - this.items.forEach(item => this.addCheckboxRow(item, rowContainer)); - } - addCheckboxRow(item, container) { - const checkboxRow = container.createDiv('checkboxRow'); - checkboxRow.createEl('span', { text: item }); - const checkbox = new obsidian.ToggleComponent(checkboxRow); - checkbox - .setTooltip(`Toggle ${item}`) - .setValue(this._selectedItems.contains(item)) - .onChange(value => { - if (value) - this._selectedItems.push(item); - else { - const index = this._selectedItems.findIndex(value => item === value); - this._selectedItems.splice(index, 1); - } - }); - } - addSubmitButton() { - const submitButtonContainer = this.contentEl.createDiv('submitButtonContainer'); - const submitButton = new obsidian.ButtonComponent(submitButtonContainer); - submitButton.setButtonText("Submit").setCta().onClick(evt => { - this.resolved = true; - this.resolvePromise(this._selectedItems); - this.close(); - }); - } -} - -class QuickAddApi { - static GetApi(app, plugin, choiceExecutor) { - return { - inputPrompt: (header, placeholder, value) => { return this.inputPrompt(app, header, placeholder, value); }, - yesNoPrompt: (header, text) => { return this.yesNoPrompt(app, header, text); }, - suggester: (displayItems, actualItems) => { return this.suggester(app, displayItems, actualItems); }, - checkboxPrompt: (items, selectedItems) => { return this.checkboxPrompt(app, items, selectedItems); }, - executeChoice: async (choiceName, variables) => { - const choice = plugin.getChoiceByName(choiceName); - if (!choice) - log.logError(`choice named '${choiceName}' not found`); - if (variables) { - Object.keys(variables).forEach(key => { - choiceExecutor.variables.set(key, variables[key]); - }); - } - await choiceExecutor.execute(choice); - choiceExecutor.variables.clear(); - }, - format: async (input) => { - return new CompleteFormatter(app, plugin, choiceExecutor).formatFileContent(input); - }, - utility: { - getClipboard: async () => { return await navigator.clipboard.readText(); }, - setClipboard: async (text) => { return await navigator.clipboard.writeText(text); }, - getSelectedText: () => { - const activeView = app.workspace.getActiveViewOfType(obsidian.MarkdownView); - if (!activeView) { - log.logError("no active view - could not get selected text."); - return; - } - if (!activeView.editor.somethingSelected()) { - log.logError("no text selected."); - return; - } - return activeView.editor.getSelection(); - } - }, - date: { - now: (format, offset) => { - return getDate({ format, offset }); - }, - tomorrow: (format) => { - return getDate({ format, offset: 1 }); - }, - yesterday: (format) => { - return getDate({ format, offset: -1 }); - } - } - }; - } - static async inputPrompt(app, header, placeholder, value) { - try { - return await GenericInputPrompt.Prompt(app, header, placeholder, value); - } - catch (_a) { - return undefined; - } - } - static async yesNoPrompt(app, header, text) { - try { - return await GenericYesNoPrompt.Prompt(app, header, text); - } - catch (_a) { - return undefined; - } - } - static async suggester(app, displayItems, actualItems) { - try { - let displayedItems; - if (typeof displayItems === "function") { - displayedItems = actualItems.map(displayItems); - } - else { - displayedItems = displayItems; - } - return await GenericSuggester.Suggest(app, displayedItems, actualItems); - } - catch (_a) { - return undefined; - } - } - static async checkboxPrompt(app, items, selectedItems) { - try { - return await GenericCheckboxPrompt.Open(app, items, selectedItems); - } - catch (_a) { - return undefined; - } - } -} - -class QuickAddChoiceEngine extends QuickAddEngine { -} - -var EditorCommandType; -(function (EditorCommandType) { - EditorCommandType["Cut"] = "Cut"; - EditorCommandType["Copy"] = "Copy"; - EditorCommandType["Paste"] = "Paste"; - EditorCommandType["SelectActiveLine"] = "Select active line"; - EditorCommandType["SelectLinkOnActiveLine"] = "Select link on active line"; -})(EditorCommandType || (EditorCommandType = {})); - -class Command { - constructor(name, type) { - this.name = name; - this.type = type; - this.id = v4(); - } -} - -class EditorCommand extends Command { - constructor(type) { - super(type, CommandType.EditorCommand); - this.editorCommandType = type; - } - static getSelectedText(app) { - return this.getActiveMarkdownView(app).editor.getSelection(); - } - static getActiveMarkdownView(app) { - const activeView = app.workspace.getActiveViewOfType(obsidian.MarkdownView); - if (!activeView) { - log.logError("no active markdown view."); - return; - } - return activeView; - } -} - -class CutCommand extends EditorCommand { - constructor() { - super(EditorCommandType.Cut); - } - static async run(app) { - const selectedText = EditorCommand.getSelectedText(app); - const activeView = EditorCommand.getActiveMarkdownView(app); - if (!selectedText) { - log.logError("nothing selected."); - return; - } - await navigator.clipboard.writeText(selectedText); - activeView.editor.replaceSelection(""); - } -} - -class CopyCommand extends EditorCommand { - constructor() { - super(EditorCommandType.Copy); - } - static async run(app) { - const selectedText = EditorCommand.getSelectedText(app); - await navigator.clipboard.writeText(selectedText); - } -} - -class PasteCommand extends EditorCommand { - constructor() { - super(EditorCommandType.Paste); - } - static async run(app) { - const clipboard = await navigator.clipboard.readText(); - const activeView = EditorCommand.getActiveMarkdownView(app); - if (!activeView) { - log.logError("no active markdown view."); - return; - } - activeView.editor.replaceSelection(clipboard); - } -} - -class SelectActiveLineCommand extends EditorCommand { - constructor() { - super(EditorCommandType.SelectActiveLine); - } - static run(app) { - const activeView = EditorCommand.getActiveMarkdownView(app); - const { line: lineNumber } = activeView.editor.getCursor(); - const line = activeView.editor.getLine(lineNumber); - const lineLength = line.length; - activeView.editor.setSelection({ line: lineNumber, ch: 0 }, { line: lineNumber, ch: lineLength }); - } -} - -class SelectLinkOnActiveLineCommand extends EditorCommand { - constructor() { - super(EditorCommandType.SelectLinkOnActiveLine); - } - static async run(app) { - const activeView = EditorCommand.getActiveMarkdownView(app); - const { line: lineNumber } = activeView.editor.getCursor(); - const line = activeView.editor.getLine(lineNumber); - const match = WIKI_LINK_REGEX.exec(line); - if (!match) { - log.logError(`no internal link found on line ${lineNumber}.`); - return; - } - const matchStart = match.index; - const matchEnd = match[0].length + matchStart; - activeView.editor.setSelection({ line: lineNumber, ch: matchStart }, { line: lineNumber, ch: matchEnd }); - } -} - -class MacroChoiceEngine extends QuickAddChoiceEngine { - constructor(app, plugin, choice, macros, choiceExecutor, variables) { - super(app); - this.choice = choice; - this.plugin = plugin; - this.macros = macros; - this.choiceExecutor = choiceExecutor; - this.params = { app: this.app, quickAddApi: QuickAddApi.GetApi(app, plugin, choiceExecutor), variables: {} }; - variables === null || variables === void 0 ? void 0 : variables.forEach(((value, key) => { - this.params.variables[key] = value; - })); - } - async run() { - var _a, _b, _c; - const macroId = (_a = this.choice.macroId) !== null && _a !== void 0 ? _a : (_c = (_b = this.choice) === null || _b === void 0 ? void 0 : _b.macro) === null || _c === void 0 ? void 0 : _c.id; - const macro = this.macros.find(m => m.id === macroId); - if (!macro || !(macro === null || macro === void 0 ? void 0 : macro.commands)) { - log.logError(`No commands in the selected macro. Did you select a macro for '${this.choice.name}'?`); - } - await this.executeCommands(macro.commands); - } - async executeCommands(commands) { - for (const command of commands) { - if ((command === null || command === void 0 ? void 0 : command.type) === CommandType.Obsidian) - await this.executeObsidianCommand(command); - if ((command === null || command === void 0 ? void 0 : command.type) === CommandType.UserScript) - await this.executeUserScript(command); - if ((command === null || command === void 0 ? void 0 : command.type) === CommandType.Choice) - await this.executeChoice(command); - if ((command === null || command === void 0 ? void 0 : command.type) === CommandType.Wait) { - const waitCommand = command; - await waitFor(waitCommand.time); - } - if ((command === null || command === void 0 ? void 0 : command.type) === CommandType.NestedChoice) { - await this.executeNestedChoice(command); - } - if ((command === null || command === void 0 ? void 0 : command.type) === CommandType.EditorCommand) { - await this.executeEditorCommand(command); - } - Object.keys(this.params.variables).forEach(key => { - this.choiceExecutor.variables.set(key, this.params.variables[key]); - }); - } - } - // Slightly modified from Templater's user script engine: - // https://github.com/SilentVoid13/Templater/blob/master/src/UserTemplates/UserTemplateParser.ts - async executeUserScript(command) { - const userScript = await getUserScript(command, this.app); - if (!userScript) { - log.logError(`failed to load user script ${command.path}.`); - return; - } - if (userScript.settings) { - this.userScriptCommand = command; - } - await this.userScriptDelegator(userScript); - if (this.userScriptCommand) - this.userScriptCommand = null; - } - async runScriptWithSettings(userScript, command) { - if (userScript.entry) { - await this.onExportIsFunction(userScript.entry, command.settings); - } - else { - await this.onExportIsFunction(userScript, command.settings); - } - } - async userScriptDelegator(userScript) { - switch (typeof userScript) { - case "function": - if (this.userScriptCommand) { - await this.runScriptWithSettings(userScript, this.userScriptCommand); - } - else { - await this.onExportIsFunction(userScript); - } - break; - case "object": - await this.onExportIsObject(userScript); - break; - case "bigint": - case "boolean": - case "number": - case "string": - this.output = userScript.toString(); - break; - default: - log.logError(`user script in macro for '${this.choice.name}' is invalid`); - } - } - async onExportIsFunction(userScript, settings) { - this.output = await userScript(this.params, settings); - } - async onExportIsObject(obj) { - if (this.userScriptCommand && obj.entry !== null) { - await this.runScriptWithSettings(obj, this.userScriptCommand); - return; - } - try { - const keys = Object.keys(obj); - const selected = await GenericSuggester.Suggest(this.app, keys, keys); - await this.userScriptDelegator(obj[selected]); - } - catch (e) { - log.logMessage(e); - } - } - executeObsidianCommand(command) { - // @ts-ignore - this.app.commands.executeCommandById(command.commandId); - } - async executeChoice(command) { - const targetChoice = this.plugin.getChoiceById(command.choiceId); - if (!targetChoice) { - log.logError("choice could not be found."); - return; - } - await this.choiceExecutor.execute(targetChoice); - } - async executeNestedChoice(command) { - const choice = command.choice; - if (!choice) { - log.logError(`choice in ${command.name} is invalid`); - return; - } - await this.choiceExecutor.execute(choice); - } - async executeEditorCommand(command) { - switch (command.editorCommandType) { - case EditorCommandType.Cut: - await CutCommand.run(this.app); - break; - case EditorCommandType.Copy: - await CopyCommand.run(this.app); - break; - case EditorCommandType.Paste: - await PasteCommand.run(this.app); - break; - case EditorCommandType.SelectActiveLine: - await SelectActiveLineCommand.run(this.app); - break; - case EditorCommandType.SelectLinkOnActiveLine: - await SelectLinkOnActiveLineCommand.run(this.app); - break; - } - } -} - -class SingleMacroEngine extends MacroChoiceEngine { - constructor(app, plugin, macros, choiceExecutor, variables) { - super(app, plugin, null, macros, choiceExecutor, variables); - } - async runAndGetOutput(macroName) { - const { basename, memberAccess } = getUserScriptMemberAccess(macroName); - const macro = this.macros.find(macro => macro.name === basename); - if (!macro) { - log.logError(`macro '${macroName}' does not exist.`); - return; - } - if (memberAccess && memberAccess.length > 0) { - this.memberAccess = memberAccess; - } - await this.executeCommands(macro.commands); - return this.output; - } - async onExportIsObject(obj) { - if (!this.memberAccess) - return await super.onExportIsObject(obj); - let newObj = obj; - this.memberAccess.forEach(key => { - newObj = newObj[key]; - }); - await this.userScriptDelegator(newObj); - } -} - -class SingleInlineScriptEngine extends MacroChoiceEngine { - constructor(app, plugin, choiceExecutor, variables) { - super(app, plugin, null, null, choiceExecutor, variables); - } - async runAndGetOutput(code) { - const AsyncFunction = Object.getPrototypeOf(async function () { }).constructor; - const userCode = new AsyncFunction(code); - return await userCode.bind(this.params, this).call(); - } -} - -class CompleteFormatter extends Formatter { - constructor(app, plugin, choiceExecutor) { - super(); - this.app = app; - this.plugin = plugin; - this.choiceExecutor = choiceExecutor; - this.variables = choiceExecutor === null || choiceExecutor === void 0 ? void 0 : choiceExecutor.variables; - } - async format(input) { - let output = input; - output = await this.replaceInlineJavascriptInString(output); - output = await this.replaceMacrosInString(output); - output = await this.replaceTemplateInString(output); - output = this.replaceDateInString(output); - output = await this.replaceValueInString(output); - output = await this.replaceDateVariableInString(output); - output = await this.replaceVariableInString(output); - return output; - } - async formatFileName(input, valueHeader) { - this.valueHeader = valueHeader; - return await this.format(input); - } - async formatFileContent(input) { - let output = input; - output = await this.format(output); - output = await this.replaceLinkToCurrentFileInString(output); - return output; - } - getCurrentFileLink() { - const currentFile = this.app.workspace.getActiveFile(); - if (!currentFile) - return null; - return this.app.fileManager.generateMarkdownLink(currentFile, ''); - } - getNaturalLanguageDates() { - return getNaturalLanguageDates(this.app); - } - getVariableValue(variableName) { - return this.variables.get(variableName); - } - async promptForValue(header) { - var _a; - if (!this.value) { - const selectedText = await this.getSelectedText(); - this.value = selectedText ? selectedText : - await GenericInputPrompt.Prompt(this.app, (_a = this.valueHeader) !== null && _a !== void 0 ? _a : `Enter value`); - } - return this.value; - } - async promptForVariable(header) { - return await GenericInputPrompt.Prompt(this.app, header); - } - async suggestForValue(suggestedValues) { - return await GenericSuggester.Suggest(this.app, suggestedValues, suggestedValues); - } - async getMacroValue(macroName) { - var _a; - const macroEngine = new SingleMacroEngine(this.app, this.plugin, this.plugin.settings.macros, this.choiceExecutor, this.variables); - const macroOutput = (_a = await macroEngine.runAndGetOutput(macroName)) !== null && _a !== void 0 ? _a : ""; - Object.keys(macroEngine.params.variables).forEach(key => { - this.variables.set(key, macroEngine.params.variables[key]); - }); - return macroOutput; - } - async getTemplateContent(templatePath) { - return await new SingleTemplateEngine(this.app, this.plugin, templatePath, this.choiceExecutor).run(); - } - async getSelectedText() { - const activeView = this.app.workspace.getActiveViewOfType(obsidian.MarkdownView); - if (!activeView) - return; - return activeView.editor.getSelection(); - } - async replaceInlineJavascriptInString(input) { - var _a; - let output = input; - while (INLINE_JAVASCRIPT_REGEX.test(output)) { - const match = INLINE_JAVASCRIPT_REGEX.exec(output); - const code = (_a = match[1]) === null || _a === void 0 ? void 0 : _a.trim(); - if (code) { - const executor = new SingleInlineScriptEngine(this.app, this.plugin, this.choiceExecutor, this.variables); - const outVal = await executor.runAndGetOutput(code); - for (let key in executor.params.variables) { - this.variables.set(key, executor.params.variables[key]); - } - output = typeof outVal === "string" ? - this.replacer(output, INLINE_JAVASCRIPT_REGEX, outVal) : - this.replacer(output, INLINE_JAVASCRIPT_REGEX, ""); - } - } - return output; - } -} - -class TemplateEngine extends QuickAddEngine { - constructor(app, plugin, choiceFormatter) { - super(app); - this.plugin = plugin; - this.templater = getTemplater(app); - this.formatter = new CompleteFormatter(app, plugin, choiceFormatter); - } - async getOrCreateFolder(folders) { - let folderPath; - if (folders.length > 1) { - folderPath = await GenericSuggester.Suggest(this.app, folders, folders); - if (!folderPath) - return null; - } - else { - folderPath = folders[0]; - } - if (folderPath) - await this.createFolder(folderPath); - else - folderPath = ""; - return folderPath; - } - async getFormattedFilePath(folderPath, format, promptHeader) { - const formattedName = await this.formatter.formatFileName(format, promptHeader); - return this.formatFilePath(folderPath, formattedName); - } - async incrementFileName(fileName) { - const numStr = FILE_NUMBER_REGEX.exec(fileName)[1]; - const fileExists = await this.app.vault.adapter.exists(fileName); - let newFileName = fileName; - if (fileExists && numStr) { - const number = parseInt(numStr); - if (!number) - throw new Error("detected numbers but couldn't get them."); - newFileName = newFileName.replace(FILE_NUMBER_REGEX, `${number + 1}.md`); - } - else if (fileExists) { - newFileName = newFileName.replace(FILE_NUMBER_REGEX, `${1}.md`); - } - const newFileExists = await this.app.vault.adapter.exists(newFileName); - if (newFileExists) - newFileName = await this.incrementFileName(newFileName); - return newFileName; - } - async createFileWithTemplate(filePath, templatePath) { - try { - const templateContent = await this.getTemplateContent(templatePath); - const formattedTemplateContent = await this.formatter.formatFileContent(templateContent); - const createdFile = await this.app.vault.create(filePath, formattedTemplateContent); - await replaceTemplaterTemplatesInCreatedFile(this.app, createdFile); - return createdFile; - } - catch (e) { - log.logError(`Could not create file with template. Maybe '${templatePath}' is an invalid template path?`); - return null; - } - } - async overwriteFileWithTemplate(file, templatePath) { - try { - const templateContent = await this.getTemplateContent(templatePath); - const formattedTemplateContent = await this.formatter.formatFileContent(templateContent); - await this.app.vault.modify(file, formattedTemplateContent); - await replaceTemplaterTemplatesInCreatedFile(this.app, file, true); - return file; - } - catch (e) { - log.logError(e); - return null; - } - } - async appendToFileWithTemplate(file, templatePath, section) { - try { - const templateContent = await this.getTemplateContent(templatePath); - const formattedTemplateContent = await this.formatter.formatFileContent(templateContent); - const fileContent = await this.app.vault.cachedRead(file); - const newFileContent = section === "top" ? - `${formattedTemplateContent}\n${fileContent}` : - `${fileContent}\n${formattedTemplateContent}`; - await this.app.vault.modify(file, newFileContent); - await replaceTemplaterTemplatesInCreatedFile(this.app, file, true); - return file; - } - catch (e) { - log.logError(e); - return null; - } - } - async getTemplateContent(templatePath) { - let correctTemplatePath = templatePath; - if (!MARKDOWN_FILE_EXTENSION_REGEX.test(templatePath)) - correctTemplatePath += ".md"; - const templateFile = this.app.vault.getAbstractFileByPath(correctTemplatePath); - if (!(templateFile instanceof obsidian.TFile)) - return; - return await this.app.vault.cachedRead(templateFile); - } -} - -class SingleTemplateEngine extends TemplateEngine { - constructor(app, plugin, templatePath, choiceExecutor) { - super(app, plugin, choiceExecutor); - this.templatePath = templatePath; - } - async run() { - let templateContent = await this.getTemplateContent(this.templatePath); - if (!templateContent) { - log.logError(`Template ${this.templatePath} not found.`); - } - templateContent = await this.formatter.formatFileContent(templateContent); - return templateContent; - } -} - -class FormatDisplayFormatter extends Formatter { - constructor(app, plugin) { - super(); - this.app = app; - this.plugin = plugin; - } - async format(input) { - let output = input; - output = this.replaceDateInString(output); - output = await this.replaceValueInString(output); - output = await this.replaceDateVariableInString(output); - output = await this.replaceVariableInString(output); - output = await this.replaceLinkToCurrentFileInString(output); - output = await this.replaceMacrosInString(output); - output = await this.replaceTemplateInString(output); - output = this.replaceLinebreakInString(output); - return output; - } - promptForValue(header) { - return "_value_"; - } - getVariableValue(variableName) { - return variableName; - } - getCurrentFileLink() { - var _a, _b; - return (_b = (_a = this.app.workspace.getActiveFile()) === null || _a === void 0 ? void 0 : _a.path) !== null && _b !== void 0 ? _b : "_noPageOpen_"; - } - getNaturalLanguageDates() { - return getNaturalLanguageDates(this.app); - } - suggestForValue(suggestedValues) { - return "_suggest_"; - } - getMacroValue(macroName) { - return `_macro: ${macroName}_`; - } - promptForVariable(variableName) { - return Promise.resolve(`${variableName}_`); - } - async getTemplateContent(templatePath) { - try { - return await new SingleTemplateEngine(this.app, this.plugin, templatePath, null).run(); - } - catch (e) { - return `Template (not found): ${templatePath}`; - } - } - async getSelectedText() { - return "_selected_"; - } -} - -class CaptureChoiceBuilder extends ChoiceBuilder { - constructor(app, choice, plugin) { - super(app); - this.plugin = plugin; - this.choice = choice; - this.display(); - } - display() { - var _a, _b, _c; - this.contentEl.empty(); - this.addCenteredChoiceNameHeader(this.choice); - this.addCapturedToSetting(); - if (!((_a = this.choice) === null || _a === void 0 ? void 0 : _a.captureToActiveFile)) { - this.addCreateIfNotExistsSetting(); - if ((_c = (_b = this.choice) === null || _b === void 0 ? void 0 : _b.createFileIfItDoesntExist) === null || _c === void 0 ? void 0 : _c.enabled) - this.addCreateWithTemplateSetting(); - } - this.addTaskSetting(); - this.addPrependSetting(); - if (!this.choice.captureToActiveFile) { - this.addAppendLinkSetting(); - this.addInsertAfterSetting(); - this.addOpenFileSetting(); - if (this.choice.openFile) - this.addOpenFileInNewTabSetting(); - } - this.addFormatSetting(); - } - addCapturedToSetting() { - var _a, _b, _c; - let textField; - new obsidian.Setting(this.contentEl) - .setName('Capture To') - .setDesc('File to capture to. Supports some format syntax.'); - const captureToContainer = this.contentEl.createDiv('captureToContainer'); - const captureToActiveFileContainer = captureToContainer.createDiv('captureToActiveFileContainer'); - const captureToActiveFileText = captureToActiveFileContainer.createEl('span'); - captureToActiveFileText.textContent = "Capture to active file"; - const captureToActiveFileToggle = new obsidian.ToggleComponent(captureToActiveFileContainer); - captureToActiveFileToggle.setValue((_a = this.choice) === null || _a === void 0 ? void 0 : _a.captureToActiveFile); - captureToActiveFileToggle.onChange(value => { - this.choice.captureToActiveFile = value; - this.reload(); - }); - if (!((_b = this.choice) === null || _b === void 0 ? void 0 : _b.captureToActiveFile)) { - const captureToFileContainer = captureToContainer.createDiv('captureToFileContainer'); - const formatDisplay = captureToFileContainer.createEl('span'); - const displayFormatter = new FileNameDisplayFormatter(this.app); - (async () => formatDisplay.textContent = await displayFormatter.format(this.choice.captureTo))(); - const formatInput = new obsidian.TextComponent(captureToFileContainer); - formatInput.setPlaceholder("File name format"); - textField = formatInput; - formatInput.inputEl.style.width = "100%"; - formatInput.inputEl.style.marginBottom = "8px"; - formatInput.setValue(this.choice.captureTo) - .setDisabled((_c = this.choice) === null || _c === void 0 ? void 0 : _c.captureToActiveFile) - .onChange(async (value) => { - this.choice.captureTo = value; - formatDisplay.textContent = await displayFormatter.format(value); - }); - const markdownFilesAndFormatSyntax = [...this.app.vault.getMarkdownFiles().map(f => f.path), ...FILE_NAME_FORMAT_SYNTAX]; - new GenericTextSuggester(this.app, textField.inputEl, markdownFilesAndFormatSyntax); - } - } - addPrependSetting() { - var _a; - const prependSetting = new obsidian.Setting(this.contentEl); - prependSetting.setName("Write to bottom of file") - .setDesc(`Put value at the bottom of the file - otherwise at the ${((_a = this.choice) === null || _a === void 0 ? void 0 : _a.captureToActiveFile) ? "active cursor location" : "top"}.`) - .addToggle(toggle => { - toggle.setValue(this.choice.prepend); - toggle.onChange(value => this.choice.prepend = value); - }); - } - addTaskSetting() { - const taskSetting = new obsidian.Setting(this.contentEl); - taskSetting.setName("Task") - .setDesc("Formats the value as a task.") - .addToggle(toggle => { - toggle.setValue(this.choice.task); - toggle.onChange(value => this.choice.task = value); - }); - } - addAppendLinkSetting() { - const appendLinkSetting = new obsidian.Setting(this.contentEl); - appendLinkSetting.setName("Append link") - .setDesc("Add a link on your current cursor position, linking to the file you're capturing to.") - .addToggle(toggle => { - toggle.setValue(this.choice.appendLink); - toggle.onChange(value => this.choice.appendLink = value); - }); - } - addInsertAfterSetting() { - let insertAfterInput; - const insertAfterSetting = new obsidian.Setting(this.contentEl); - insertAfterSetting.setName("Insert after") - .setDesc("Insert capture after specified line. Accepts format syntax.") - .addToggle(toggle => { - toggle.setValue(this.choice.insertAfter.enabled); - toggle.onChange(value => { - this.choice.insertAfter.enabled = value; - insertAfterInput.setDisabled(!value); - this.reload(); - }); - }); - const insertAfterFormatDisplay = this.contentEl.createEl('span'); - const displayFormatter = new FormatDisplayFormatter(this.app, this.plugin); - (async () => insertAfterFormatDisplay.innerText = await displayFormatter.format(this.choice.insertAfter.after))(); - insertAfterInput = new obsidian.TextComponent(this.contentEl); - insertAfterInput.setPlaceholder("Insert after"); - insertAfterInput.inputEl.style.width = "100%"; - insertAfterInput.inputEl.style.marginBottom = "8px"; - insertAfterInput.setValue(this.choice.insertAfter.after) - .setDisabled(!this.choice.insertAfter.enabled) - .onChange(async (value) => { - this.choice.insertAfter.after = value; - insertAfterFormatDisplay.innerText = await displayFormatter.format(value); - }); - new FormatSyntaxSuggester(this.app, insertAfterInput.inputEl, this.plugin); - if (this.choice.insertAfter.enabled) { - const insertAtEndSetting = new obsidian.Setting(this.contentEl); - insertAtEndSetting.setName("Insert at end of section") - .setDesc("Insert the text at the end of the section, rather than at the top.") - .addToggle(toggle => { - var _a; - return toggle - .setValue((_a = this.choice.insertAfter) === null || _a === void 0 ? void 0 : _a.insertAtEnd) - .onChange(value => this.choice.insertAfter.insertAtEnd = value); - }); - const createLineIfNotFound = new obsidian.Setting(this.contentEl); - createLineIfNotFound.setName("Create line if not found") - .setDesc("Creates the 'insert after' line if it is not found.") - .addToggle(toggle => { - var _a, _b; - if (!((_a = this.choice.insertAfter) === null || _a === void 0 ? void 0 : _a.createIfNotFound)) - this.choice.insertAfter.createIfNotFound = false; // Set to default - toggle - .setValue((_b = this.choice.insertAfter) === null || _b === void 0 ? void 0 : _b.createIfNotFound) - .onChange(value => this.choice.insertAfter.createIfNotFound = value) - .toggleEl.style.marginRight = "1em"; - }) - .addDropdown(dropdown => { - var _a, _b; - if (!((_a = this.choice.insertAfter) === null || _a === void 0 ? void 0 : _a.createIfNotFoundLocation)) - this.choice.insertAfter.createIfNotFoundLocation = CREATE_IF_NOT_FOUND_TOP; // Set to default - dropdown - .addOption(CREATE_IF_NOT_FOUND_TOP, "Top") - .addOption(CREATE_IF_NOT_FOUND_BOTTOM, "Bottom") - .setValue((_b = this.choice.insertAfter) === null || _b === void 0 ? void 0 : _b.createIfNotFoundLocation) - .onChange(value => this.choice.insertAfter.createIfNotFoundLocation = value); - }); - } - } - addFormatSetting() { - let textField; - const enableSetting = new obsidian.Setting(this.contentEl); - enableSetting.setName("Capture format") - .setDesc("Set the format of the capture.") - .addToggle(toggleComponent => { - toggleComponent.setValue(this.choice.format.enabled) - .onChange(value => { - this.choice.format.enabled = value; - textField.setDisabled(!value); - }); - }); - const formatInput = new obsidian.TextAreaComponent(this.contentEl); - formatInput.setPlaceholder("Format"); - textField = formatInput; - formatInput.inputEl.style.width = "100%"; - formatInput.inputEl.style.marginBottom = "8px"; - formatInput.inputEl.style.height = "10rem"; - formatInput.setValue(this.choice.format.format) - .setDisabled(!this.choice.format.enabled) - .onChange(async (value) => { - this.choice.format.format = value; - formatDisplay.innerText = await displayFormatter.format(value); - }); - new FormatSyntaxSuggester(this.app, textField.inputEl, this.plugin); - const formatDisplay = this.contentEl.createEl('span'); - const displayFormatter = new FormatDisplayFormatter(this.app, this.plugin); - (async () => formatDisplay.innerText = await displayFormatter.format(this.choice.format.format))(); - } - addCreateIfNotExistsSetting() { - if (!this.choice.createFileIfItDoesntExist) - this.choice.createFileIfItDoesntExist = { enabled: false, createWithTemplate: false, template: "" }; - const createFileIfItDoesntExist = new obsidian.Setting(this.contentEl); - createFileIfItDoesntExist - .setName("Create file if it doesn't exist") - .addToggle(toggle => { - var _a, _b; - return toggle - .setValue((_b = (_a = this.choice) === null || _a === void 0 ? void 0 : _a.createFileIfItDoesntExist) === null || _b === void 0 ? void 0 : _b.enabled) - .setTooltip("Create file if it doesn't exist") - .onChange(value => { - this.choice.createFileIfItDoesntExist.enabled = value; - this.reload(); - }); - }); - } - addCreateWithTemplateSetting() { - var _a, _b, _c, _d, _e; - let templateSelector; - const createWithTemplateSetting = new obsidian.Setting(this.contentEl); - createWithTemplateSetting.setName("Create file with given template.") - .addToggle(toggle => { - var _a; - return toggle.setValue((_a = this.choice.createFileIfItDoesntExist) === null || _a === void 0 ? void 0 : _a.createWithTemplate) - .onChange(value => { - this.choice.createFileIfItDoesntExist.createWithTemplate = value; - templateSelector.setDisabled(!value); - }); - }); - templateSelector = new obsidian.TextComponent(this.contentEl); - templateSelector.setValue((_c = (_b = (_a = this.choice) === null || _a === void 0 ? void 0 : _a.createFileIfItDoesntExist) === null || _b === void 0 ? void 0 : _b.template) !== null && _c !== void 0 ? _c : "") - .setPlaceholder("Template path") - .setDisabled(!((_e = (_d = this.choice) === null || _d === void 0 ? void 0 : _d.createFileIfItDoesntExist) === null || _e === void 0 ? void 0 : _e.createWithTemplate)); - templateSelector.inputEl.style.width = "100%"; - templateSelector.inputEl.style.marginBottom = "8px"; - const markdownFiles = getTemplatePaths(this.app); - new GenericTextSuggester(this.app, templateSelector.inputEl, markdownFiles); - templateSelector.onChange(value => { - this.choice.createFileIfItDoesntExist.template = value; - }); - } - addOpenFileSetting() { - const noOpenSetting = new obsidian.Setting(this.contentEl); - noOpenSetting.setName("Open") - .setDesc("Open the file that is captured to.") - .addToggle(toggle => { - toggle.setValue(this.choice.openFile); - toggle.onChange(value => { - this.choice.openFile = value; - this.reload(); - }); - }) - .addDropdown(dropdown => { - dropdown.selectEl.style.marginLeft = "10px"; - if (!this.choice.openFileInMode) - this.choice.openFileInMode = 'default'; - dropdown - .addOption('source', 'Source') - .addOption('preview', 'Preview') - .addOption('default', 'Default') - .setValue(this.choice.openFileInMode) - .onChange(value => this.choice.openFileInMode = value); - }); - } - addOpenFileInNewTabSetting() { - const newTabSetting = new obsidian.Setting(this.contentEl); - newTabSetting.setName("New Tab") - .setDesc("Open the file that is captured to in a new tab.") - .addToggle(toggle => { - var _a, _b; - toggle.setValue((_b = (_a = this.choice) === null || _a === void 0 ? void 0 : _a.openFileInNewTab) === null || _b === void 0 ? void 0 : _b.enabled); - toggle.onChange(value => this.choice.openFileInNewTab.enabled = value); - }) - .addDropdown(dropdown => { - var _a, _b, _c; - if (!((_a = this.choice) === null || _a === void 0 ? void 0 : _a.openFileInNewTab)) { - this.choice.openFileInNewTab = { enabled: false, direction: NewTabDirection.vertical, focus: true }; - } - dropdown.selectEl.style.marginLeft = "10px"; - dropdown.addOption(NewTabDirection.vertical, "Vertical"); - dropdown.addOption(NewTabDirection.horizontal, "Horizontal"); - dropdown.setValue((_c = (_b = this.choice) === null || _b === void 0 ? void 0 : _b.openFileInNewTab) === null || _c === void 0 ? void 0 : _c.direction); - dropdown.onChange(value => this.choice.openFileInNewTab.direction = value); - }); - new obsidian.Setting(this.contentEl) - .setName("Focus new pane") - .setDesc("Focus the opened tab immediately") - .addToggle(toggle => toggle - .setValue(this.choice.openFileInNewTab.focus) - .onChange(value => this.choice.openFileInNewTab.focus = value)); - } -} - -class MacroChoiceBuilder extends ChoiceBuilder { - constructor(app, choice, macros) { - super(app); - this.macros = macros; - this.choice = choice; - this.display(); - } - display() { - this.addCenteredChoiceNameHeader(this.choice); - this.addSelectMacroSearch(); - } - addSelectMacroSearch() { - const selectMacroDropdownContainer = this.contentEl.createDiv('selectMacroDropdownContainer'); - const dropdown = new obsidian.DropdownComponent(selectMacroDropdownContainer); - let macroOptions = {}; - this.macros.forEach(macro => { - macroOptions[macro.name] = macro.name; - }); - dropdown.addOptions(macroOptions); - dropdown.onChange(value => { - this.selectMacro(value); - }); - const selectedMacro = this.macros.find(m => m.id === this.choice.macroId); - if (selectedMacro) { - dropdown.setValue(selectedMacro.name); - } - else { - const value = dropdown.getValue(); - if (value) { - this.selectMacro(value); - } - } - } - selectMacro(value) { - const targetMacro = this.macros.find(m => m.name === value); - if (!targetMacro) - return; - this.choice.macroId = targetMacro.id; - } -} - -class UserScript extends Command { - constructor(name, path) { - super(name, CommandType.UserScript); - this.path = path; - this.settings = {}; - } -} - -class ObsidianCommand extends Command { - constructor(name, commandId) { - super(name, CommandType.Obsidian); - this.generateId = () => this.id = v4(); - this.commandId = commandId; - } -} - -/* src/gui/MacroGUIs/Components/StandardCommand.svelte generated by Svelte v3.43.0 */ - -function create_fragment$5(ctx) { - let div1; - let li; - let t0_value = /*command*/ ctx[0].name + ""; - let t0; - let t1; - let div0; - let span0; - let icon0; - let t2; - let span1; - let icon1; - let span1_style_value; - let span1_tabindex_value; - let current; - let mounted; - let dispose; - icon0 = new Icon({ props: { data: faTrash } }); - icon1 = new Icon({ props: { data: faBars } }); - - return { - c() { - div1 = element("div"); - li = element("li"); - t0 = text(t0_value); - t1 = space(); - div0 = element("div"); - span0 = element("span"); - create_component(icon0.$$.fragment); - t2 = space(); - span1 = element("span"); - create_component(icon1.$$.fragment); - attr(span0, "class", "clickable"); - attr(span1, "aria-label", "Drag-handle"); - - attr(span1, "style", span1_style_value = "" + ((/*dragDisabled*/ ctx[2] - ? 'cursor: grab' - : 'cursor: grabbing') + ";")); - - attr(span1, "tabindex", span1_tabindex_value = /*dragDisabled*/ ctx[2] ? 0 : -1); - attr(div1, "class", "quickAddCommandListItem"); - }, - m(target, anchor) { - insert(target, div1, anchor); - append(div1, li); - append(li, t0); - append(div1, t1); - append(div1, div0); - append(div0, span0); - mount_component(icon0, span0, null); - append(div0, t2); - append(div0, span1); - mount_component(icon1, span1, null); - current = true; - - if (!mounted) { - dispose = [ - listen(span0, "click", /*click_handler*/ ctx[4]), - listen(span1, "mousedown", function () { - if (is_function(/*startDrag*/ ctx[1])) /*startDrag*/ ctx[1].apply(this, arguments); - }), - listen(span1, "touchstart", function () { - if (is_function(/*startDrag*/ ctx[1])) /*startDrag*/ ctx[1].apply(this, arguments); - }) - ]; - - mounted = true; - } - }, - p(new_ctx, [dirty]) { - ctx = new_ctx; - if ((!current || dirty & /*command*/ 1) && t0_value !== (t0_value = /*command*/ ctx[0].name + "")) set_data(t0, t0_value); - - if (!current || dirty & /*dragDisabled*/ 4 && span1_style_value !== (span1_style_value = "" + ((/*dragDisabled*/ ctx[2] - ? 'cursor: grab' - : 'cursor: grabbing') + ";"))) { - attr(span1, "style", span1_style_value); - } - - if (!current || dirty & /*dragDisabled*/ 4 && span1_tabindex_value !== (span1_tabindex_value = /*dragDisabled*/ ctx[2] ? 0 : -1)) { - attr(span1, "tabindex", span1_tabindex_value); - } - }, - i(local) { - if (current) return; - transition_in(icon0.$$.fragment, local); - transition_in(icon1.$$.fragment, local); - current = true; - }, - o(local) { - transition_out(icon0.$$.fragment, local); - transition_out(icon1.$$.fragment, local); - current = false; - }, - d(detaching) { - if (detaching) detach(div1); - destroy_component(icon0); - destroy_component(icon1); - mounted = false; - run_all(dispose); - } - }; -} - -function instance$5($$self, $$props, $$invalidate) { - let { command } = $$props; - let { startDrag } = $$props; - let { dragDisabled } = $$props; - const dispatch = createEventDispatcher(); - - function deleteCommand(commandId) { - dispatch('deleteCommand', commandId); - } - - const click_handler = () => deleteCommand(command.id); - - $$self.$$set = $$props => { - if ('command' in $$props) $$invalidate(0, command = $$props.command); - if ('startDrag' in $$props) $$invalidate(1, startDrag = $$props.startDrag); - if ('dragDisabled' in $$props) $$invalidate(2, dragDisabled = $$props.dragDisabled); - }; - - return [command, startDrag, dragDisabled, deleteCommand, click_handler]; -} - -class StandardCommand extends SvelteComponent { - constructor(options) { - super(); - - init(this, options, instance$5, create_fragment$5, safe_not_equal, { - command: 0, - startDrag: 1, - dragDisabled: 2 - }); - } -} - -/* src/gui/MacroGUIs/Components/WaitCommand.svelte generated by Svelte v3.43.0 */ - -function add_css$2(target) { - append_styles(target, "svelte-1196d9p", ".dotInput.svelte-1196d9p{border:none;display:inline;font-family:inherit;font-size:inherit;padding:0;width:0;text-decoration:underline dotted;background-color:transparent}.dotInput.svelte-1196d9p:hover{background-color:transparent}"); -} - -function create_fragment$4(ctx) { - let div1; - let li; - let t0_value = /*command*/ ctx[0].name + ""; - let t0; - let t1; - let input; - let t2; - let t3; - let div0; - let span0; - let icon0; - let t4; - let span1; - let icon1; - let span1_style_value; - let span1_tabindex_value; - let current; - let mounted; - let dispose; - icon0 = new Icon({ props: { data: faTrash } }); - icon1 = new Icon({ props: { data: faBars } }); - - return { - c() { - div1 = element("div"); - li = element("li"); - t0 = text(t0_value); - t1 = text(" for "); - input = element("input"); - t2 = text("ms"); - t3 = space(); - div0 = element("div"); - span0 = element("span"); - create_component(icon0.$$.fragment); - t4 = space(); - span1 = element("span"); - create_component(icon1.$$.fragment); - attr(input, "type", "number"); - attr(input, "placeholder", " "); - attr(input, "class", "dotInput svelte-1196d9p"); - attr(span0, "class", "clickable"); - attr(span1, "aria-label", "Drag-handle"); - - attr(span1, "style", span1_style_value = "" + ((/*dragDisabled*/ ctx[2] - ? 'cursor: grab' - : 'cursor: grabbing') + ";")); - - attr(span1, "tabindex", span1_tabindex_value = /*dragDisabled*/ ctx[2] ? 0 : -1); - attr(div1, "class", "quickAddCommandListItem"); - }, - m(target, anchor) { - insert(target, div1, anchor); - append(div1, li); - append(li, t0); - append(li, t1); - append(li, input); - /*input_binding*/ ctx[6](input); - set_input_value(input, /*command*/ ctx[0].time); - append(li, t2); - append(div1, t3); - append(div1, div0); - append(div0, span0); - mount_component(icon0, span0, null); - append(div0, t4); - append(div0, span1); - mount_component(icon1, span1, null); - current = true; - - if (!mounted) { - dispose = [ - listen(input, "keyup", /*resizeInput*/ ctx[5]), - listen(input, "input", /*input_input_handler*/ ctx[7]), - listen(span0, "click", /*click_handler*/ ctx[8]), - listen(span1, "mousedown", function () { - if (is_function(/*startDrag*/ ctx[1])) /*startDrag*/ ctx[1].apply(this, arguments); - }), - listen(span1, "touchstart", function () { - if (is_function(/*startDrag*/ ctx[1])) /*startDrag*/ ctx[1].apply(this, arguments); - }) - ]; - - mounted = true; - } - }, - p(new_ctx, [dirty]) { - ctx = new_ctx; - if ((!current || dirty & /*command*/ 1) && t0_value !== (t0_value = /*command*/ ctx[0].name + "")) set_data(t0, t0_value); - - if (dirty & /*command*/ 1 && to_number(input.value) !== /*command*/ ctx[0].time) { - set_input_value(input, /*command*/ ctx[0].time); - } - - if (!current || dirty & /*dragDisabled*/ 4 && span1_style_value !== (span1_style_value = "" + ((/*dragDisabled*/ ctx[2] - ? 'cursor: grab' - : 'cursor: grabbing') + ";"))) { - attr(span1, "style", span1_style_value); - } - - if (!current || dirty & /*dragDisabled*/ 4 && span1_tabindex_value !== (span1_tabindex_value = /*dragDisabled*/ ctx[2] ? 0 : -1)) { - attr(span1, "tabindex", span1_tabindex_value); - } - }, - i(local) { - if (current) return; - transition_in(icon0.$$.fragment, local); - transition_in(icon1.$$.fragment, local); - current = true; - }, - o(local) { - transition_out(icon0.$$.fragment, local); - transition_out(icon1.$$.fragment, local); - current = false; - }, - d(detaching) { - if (detaching) detach(div1); - /*input_binding*/ ctx[6](null); - destroy_component(icon0); - destroy_component(icon1); - mounted = false; - run_all(dispose); - } - }; -} - -function instance$4($$self, $$props, $$invalidate) { - let { command } = $$props; - let { startDrag } = $$props; - let { dragDisabled } = $$props; - const dispatch = createEventDispatcher(); - let inputEl; - - function deleteCommand(commandId) { - dispatch('deleteCommand', commandId); - } - - function resizeInput() { - const length = inputEl.value.length; - $$invalidate(3, inputEl.style.width = (length === 0 ? 2 : length) + 'ch', inputEl); - } - - onMount(resizeInput); - - function input_binding($$value) { - binding_callbacks[$$value ? 'unshift' : 'push'](() => { - inputEl = $$value; - $$invalidate(3, inputEl); - }); - } - - function input_input_handler() { - command.time = to_number(this.value); - $$invalidate(0, command); - } - - const click_handler = () => deleteCommand(command.id); - - $$self.$$set = $$props => { - if ('command' in $$props) $$invalidate(0, command = $$props.command); - if ('startDrag' in $$props) $$invalidate(1, startDrag = $$props.startDrag); - if ('dragDisabled' in $$props) $$invalidate(2, dragDisabled = $$props.dragDisabled); - }; - - return [ - command, - startDrag, - dragDisabled, - inputEl, - deleteCommand, - resizeInput, - input_binding, - input_input_handler, - click_handler - ]; -} - -class WaitCommand$1 extends SvelteComponent { - constructor(options) { - super(); - - init( - this, - options, - instance$4, - create_fragment$4, - safe_not_equal, - { - command: 0, - startDrag: 1, - dragDisabled: 2 - }, - add_css$2 - ); - } -} - -/* src/gui/MacroGUIs/Components/NestedChoiceCommand.svelte generated by Svelte v3.43.0 */ - -function create_fragment$3(ctx) { - let div1; - let li; - let t0_value = /*command*/ ctx[0].name + ""; - let t0; - let t1; - let div0; - let span0; - let icon0; - let t2; - let span1; - let icon1; - let t3; - let span2; - let icon2; - let span2_style_value; - let span2_tabindex_value; - let current; - let mounted; - let dispose; - icon0 = new Icon({ props: { data: faCog } }); - icon1 = new Icon({ props: { data: faTrash } }); - icon2 = new Icon({ props: { data: faBars } }); - - return { - c() { - div1 = element("div"); - li = element("li"); - t0 = text(t0_value); - t1 = space(); - div0 = element("div"); - span0 = element("span"); - create_component(icon0.$$.fragment); - t2 = space(); - span1 = element("span"); - create_component(icon1.$$.fragment); - t3 = space(); - span2 = element("span"); - create_component(icon2.$$.fragment); - attr(span0, "class", "clickable"); - attr(span1, "class", "clickable"); - attr(span2, "aria-label", "Drag-handle"); - - attr(span2, "style", span2_style_value = "" + ((/*dragDisabled*/ ctx[2] - ? 'cursor: grab' - : 'cursor: grabbing') + ";")); - - attr(span2, "tabindex", span2_tabindex_value = /*dragDisabled*/ ctx[2] ? 0 : -1); - attr(div1, "class", "quickAddCommandListItem"); - }, - m(target, anchor) { - insert(target, div1, anchor); - append(div1, li); - append(li, t0); - append(div1, t1); - append(div1, div0); - append(div0, span0); - mount_component(icon0, span0, null); - append(div0, t2); - append(div0, span1); - mount_component(icon1, span1, null); - append(div0, t3); - append(div0, span2); - mount_component(icon2, span2, null); - current = true; - - if (!mounted) { - dispose = [ - listen(span0, "click", /*click_handler*/ ctx[5]), - listen(span1, "click", /*click_handler_1*/ ctx[6]), - listen(span2, "mousedown", function () { - if (is_function(/*startDrag*/ ctx[1])) /*startDrag*/ ctx[1].apply(this, arguments); - }), - listen(span2, "touchstart", function () { - if (is_function(/*startDrag*/ ctx[1])) /*startDrag*/ ctx[1].apply(this, arguments); - }) - ]; - - mounted = true; - } - }, - p(new_ctx, [dirty]) { - ctx = new_ctx; - if ((!current || dirty & /*command*/ 1) && t0_value !== (t0_value = /*command*/ ctx[0].name + "")) set_data(t0, t0_value); - - if (!current || dirty & /*dragDisabled*/ 4 && span2_style_value !== (span2_style_value = "" + ((/*dragDisabled*/ ctx[2] - ? 'cursor: grab' - : 'cursor: grabbing') + ";"))) { - attr(span2, "style", span2_style_value); - } - - if (!current || dirty & /*dragDisabled*/ 4 && span2_tabindex_value !== (span2_tabindex_value = /*dragDisabled*/ ctx[2] ? 0 : -1)) { - attr(span2, "tabindex", span2_tabindex_value); - } - }, - i(local) { - if (current) return; - transition_in(icon0.$$.fragment, local); - transition_in(icon1.$$.fragment, local); - transition_in(icon2.$$.fragment, local); - current = true; - }, - o(local) { - transition_out(icon0.$$.fragment, local); - transition_out(icon1.$$.fragment, local); - transition_out(icon2.$$.fragment, local); - current = false; - }, - d(detaching) { - if (detaching) detach(div1); - destroy_component(icon0); - destroy_component(icon1); - destroy_component(icon2); - mounted = false; - run_all(dispose); - } - }; -} - -function instance$3($$self, $$props, $$invalidate) { - let { command } = $$props; - let { startDrag } = $$props; - let { dragDisabled } = $$props; - const dispatch = createEventDispatcher(); - - function deleteCommand() { - dispatch('deleteCommand', command.id); - } - - function configureChoice() { - dispatch('configureChoice', command); - } - - const click_handler = () => configureChoice(); - const click_handler_1 = () => deleteCommand(); - - $$self.$$set = $$props => { - if ('command' in $$props) $$invalidate(0, command = $$props.command); - if ('startDrag' in $$props) $$invalidate(1, startDrag = $$props.startDrag); - if ('dragDisabled' in $$props) $$invalidate(2, dragDisabled = $$props.dragDisabled); - }; - - return [ - command, - startDrag, - dragDisabled, - deleteCommand, - configureChoice, - click_handler, - click_handler_1 - ]; -} - -class NestedChoiceCommand$1 extends SvelteComponent { - constructor(options) { - super(); - - init(this, options, instance$3, create_fragment$3, safe_not_equal, { - command: 0, - startDrag: 1, - dragDisabled: 2 - }); - } -} - -/* src/gui/MacroGUIs/Components/UserScriptCommand.svelte generated by Svelte v3.43.0 */ - -function create_fragment$2(ctx) { - let div1; - let li; - let t0_value = /*command*/ ctx[0].name + ""; - let t0; - let t1; - let div0; - let span0; - let icon0; - let t2; - let span1; - let icon1; - let t3; - let span2; - let icon2; - let span2_style_value; - let span2_tabindex_value; - let current; - let mounted; - let dispose; - icon0 = new Icon({ props: { data: faCog } }); - icon1 = new Icon({ props: { data: faTrash } }); - icon2 = new Icon({ props: { data: faBars } }); - - return { - c() { - div1 = element("div"); - li = element("li"); - t0 = text(t0_value); - t1 = space(); - div0 = element("div"); - span0 = element("span"); - create_component(icon0.$$.fragment); - t2 = space(); - span1 = element("span"); - create_component(icon1.$$.fragment); - t3 = space(); - span2 = element("span"); - create_component(icon2.$$.fragment); - attr(span0, "class", "clickable"); - attr(span1, "class", "clickable"); - attr(span2, "aria-label", "Drag-handle"); - - attr(span2, "style", span2_style_value = "" + ((/*dragDisabled*/ ctx[2] - ? 'cursor: grab' - : 'cursor: grabbing') + ";")); - - attr(span2, "tabindex", span2_tabindex_value = /*dragDisabled*/ ctx[2] ? 0 : -1); - attr(div1, "class", "quickAddCommandListItem"); - }, - m(target, anchor) { - insert(target, div1, anchor); - append(div1, li); - append(li, t0); - append(div1, t1); - append(div1, div0); - append(div0, span0); - mount_component(icon0, span0, null); - append(div0, t2); - append(div0, span1); - mount_component(icon1, span1, null); - append(div0, t3); - append(div0, span2); - mount_component(icon2, span2, null); - current = true; - - if (!mounted) { - dispose = [ - listen(span0, "click", /*click_handler*/ ctx[5]), - listen(span1, "click", /*click_handler_1*/ ctx[6]), - listen(span2, "mousedown", function () { - if (is_function(/*startDrag*/ ctx[1])) /*startDrag*/ ctx[1].apply(this, arguments); - }), - listen(span2, "touchstart", function () { - if (is_function(/*startDrag*/ ctx[1])) /*startDrag*/ ctx[1].apply(this, arguments); - }) - ]; - - mounted = true; - } - }, - p(new_ctx, [dirty]) { - ctx = new_ctx; - if ((!current || dirty & /*command*/ 1) && t0_value !== (t0_value = /*command*/ ctx[0].name + "")) set_data(t0, t0_value); - - if (!current || dirty & /*dragDisabled*/ 4 && span2_style_value !== (span2_style_value = "" + ((/*dragDisabled*/ ctx[2] - ? 'cursor: grab' - : 'cursor: grabbing') + ";"))) { - attr(span2, "style", span2_style_value); - } - - if (!current || dirty & /*dragDisabled*/ 4 && span2_tabindex_value !== (span2_tabindex_value = /*dragDisabled*/ ctx[2] ? 0 : -1)) { - attr(span2, "tabindex", span2_tabindex_value); - } - }, - i(local) { - if (current) return; - transition_in(icon0.$$.fragment, local); - transition_in(icon1.$$.fragment, local); - transition_in(icon2.$$.fragment, local); - current = true; - }, - o(local) { - transition_out(icon0.$$.fragment, local); - transition_out(icon1.$$.fragment, local); - transition_out(icon2.$$.fragment, local); - current = false; - }, - d(detaching) { - if (detaching) detach(div1); - destroy_component(icon0); - destroy_component(icon1); - destroy_component(icon2); - mounted = false; - run_all(dispose); - } - }; -} - -function instance$2($$self, $$props, $$invalidate) { - let { command } = $$props; - let { startDrag } = $$props; - let { dragDisabled } = $$props; - const dispatch = createEventDispatcher(); - - function deleteCommand() { - dispatch('deleteCommand', command.id); - } - - function configureChoice() { - dispatch('configureScript', command); - } - - const click_handler = () => configureChoice(); - const click_handler_1 = () => deleteCommand(); - - $$self.$$set = $$props => { - if ('command' in $$props) $$invalidate(0, command = $$props.command); - if ('startDrag' in $$props) $$invalidate(1, startDrag = $$props.startDrag); - if ('dragDisabled' in $$props) $$invalidate(2, dragDisabled = $$props.dragDisabled); - }; - - return [ - command, - startDrag, - dragDisabled, - deleteCommand, - configureChoice, - click_handler, - click_handler_1 - ]; -} - -class UserScriptCommand extends SvelteComponent { - constructor(options) { - super(); - - init(this, options, instance$2, create_fragment$2, safe_not_equal, { - command: 0, - startDrag: 1, - dragDisabled: 2 - }); - } -} - -class UserScriptSettingsModal extends obsidian.Modal { - constructor(app, command, settings) { - super(app); - this.command = command; - this.settings = settings; - this.display(); - if (!this.command.settings) - this.command.settings = {}; - Object.keys(this.settings.options).forEach(setting => { - var _a; - if (this.command.settings[setting] === undefined) { - this.command.settings[setting] = (_a = this.settings.options[setting]) === null || _a === void 0 ? void 0 : _a.defaultValue; - } - }); - } - display() { - var _a, _b, _c; - this.contentEl.empty(); - this.titleEl.innerText = `${(_a = this.settings) === null || _a === void 0 ? void 0 : _a.name}${((_b = this.settings) === null || _b === void 0 ? void 0 : _b.author) ? " by " + ((_c = this.settings) === null || _c === void 0 ? void 0 : _c.author) : ""}`; - const options = this.settings.options; - Object.keys(options).forEach(option => { - var _a, _b; - const entry = options[option]; - let value = entry.defaultValue; - if (this.command.settings[option] !== undefined) { - value = this.command.settings[option]; - } - switch ((_b = (_a = options[option]) === null || _a === void 0 ? void 0 : _a.type) === null || _b === void 0 ? void 0 : _b.toLowerCase()) { - case "text": - case "input": - this.addInputBox(option, value, entry === null || entry === void 0 ? void 0 : entry.placeholder, entry === null || entry === void 0 ? void 0 : entry.secret); - break; - case "checkbox": - case "toggle": - this.addToggle(option, value); - break; - case "dropdown": - case "select": - this.addDropdown(option, entry.options, value); - break; - case "format": - this.addFormatInput(option, value, entry === null || entry === void 0 ? void 0 : entry.placeholder); - break; - } - }); - } - setPasswordOnBlur(el) { - el.addEventListener('focus', () => { - el.type = "text"; - }); - el.addEventListener('blur', () => { - el.type = "password"; - }); - el.type = "password"; - } - addInputBox(name, value, placeholder, passwordOnBlur) { - new obsidian.Setting(this.contentEl) - .setName(name) - .addText(input => { - input.setValue(value) - .onChange(value => this.command.settings[name] = value) - .setPlaceholder(placeholder !== null && placeholder !== void 0 ? placeholder : ""); - if (passwordOnBlur) { - this.setPasswordOnBlur(input.inputEl); - } - }); - } - addToggle(name, value) { - new obsidian.Setting(this.contentEl) - .setName(name) - .addToggle(toggle => toggle.setValue(value) - .onChange(value => this.command.settings[name] = value)); - } - addDropdown(name, options, value) { - new obsidian.Setting(this.contentEl) - .setName(name) - .addDropdown(dropdown => { - options.forEach(item => dropdown.addOption(item, item)); - dropdown.setValue(value); - dropdown.onChange(value => this.command.settings[name] = value); - }); - } - addFormatInput(name, value, placeholder) { - new obsidian.Setting(this.contentEl).setName(name); - const formatDisplay = this.contentEl.createEl("span"); - const input = new obsidian.TextComponent(this.contentEl); - new FormatSyntaxSuggester(this.app, input.inputEl, QuickAdd.instance); - const displayFormatter = new FormatDisplayFormatter(this.app, QuickAdd.instance); - input.setValue(value) - .onChange(async (value) => { - this.command.settings[name] = value; - formatDisplay.innerText = await displayFormatter.format(value); - }) - .setPlaceholder(placeholder !== null && placeholder !== void 0 ? placeholder : ""); - input.inputEl.style.width = "100%"; - input.inputEl.style.marginBottom = "1em"; - (async () => formatDisplay.innerText = await displayFormatter.format(value))(); - } -} - -/* src/gui/MacroGUIs/CommandList.svelte generated by Svelte v3.43.0 */ - -function add_css$1(target) { - append_styles(target, "svelte-1ukgrgp", ".quickAddCommandList.svelte-1ukgrgp{display:grid;grid-template-columns:auto;width:auto;border:0 solid black;overflow-y:auto;height:auto;margin-bottom:8px;padding:20px}"); -} - -function get_each_context(ctx, list, i) { - const child_ctx = ctx.slice(); - child_ctx[34] = list[i]; - child_ctx[35] = list; - child_ctx[36] = i; - return child_ctx; -} - -// (106:8) {:else} -function create_else_block(ctx) { - let standardcommand; - let updating_command; - let updating_dragDisabled; - let updating_startDrag; - let current; - - function standardcommand_command_binding(value) { - /*standardcommand_command_binding*/ ctx[27](value, /*command*/ ctx[34], /*each_value*/ ctx[35], /*command_index*/ ctx[36]); - } - - function standardcommand_dragDisabled_binding(value) { - /*standardcommand_dragDisabled_binding*/ ctx[28](value); - } - - function standardcommand_startDrag_binding(value) { - /*standardcommand_startDrag_binding*/ ctx[29](value); - } - - let standardcommand_props = {}; - - if (/*command*/ ctx[34] !== void 0) { - standardcommand_props.command = /*command*/ ctx[34]; - } - - if (/*dragDisabled*/ ctx[3] !== void 0) { - standardcommand_props.dragDisabled = /*dragDisabled*/ ctx[3]; - } - - if (/*startDrag*/ ctx[4] !== void 0) { - standardcommand_props.startDrag = /*startDrag*/ ctx[4]; - } - - standardcommand = new StandardCommand({ props: standardcommand_props }); - binding_callbacks.push(() => bind(standardcommand, 'command', standardcommand_command_binding)); - binding_callbacks.push(() => bind(standardcommand, 'dragDisabled', standardcommand_dragDisabled_binding)); - binding_callbacks.push(() => bind(standardcommand, 'startDrag', standardcommand_startDrag_binding)); - standardcommand.$on("deleteCommand", /*deleteCommand_handler_3*/ ctx[30]); - standardcommand.$on("updateCommand", /*updateCommandFromEvent*/ ctx[7]); - - return { - c() { - create_component(standardcommand.$$.fragment); - }, - m(target, anchor) { - mount_component(standardcommand, target, anchor); - current = true; - }, - p(new_ctx, dirty) { - ctx = new_ctx; - const standardcommand_changes = {}; - - if (!updating_command && dirty[0] & /*commands, SHADOW_PLACEHOLDER_ITEM_ID*/ 5) { - updating_command = true; - standardcommand_changes.command = /*command*/ ctx[34]; - add_flush_callback(() => updating_command = false); - } - - if (!updating_dragDisabled && dirty[0] & /*dragDisabled*/ 8) { - updating_dragDisabled = true; - standardcommand_changes.dragDisabled = /*dragDisabled*/ ctx[3]; - add_flush_callback(() => updating_dragDisabled = false); - } - - if (!updating_startDrag && dirty[0] & /*startDrag*/ 16) { - updating_startDrag = true; - standardcommand_changes.startDrag = /*startDrag*/ ctx[4]; - add_flush_callback(() => updating_startDrag = false); - } - - standardcommand.$set(standardcommand_changes); - }, - i(local) { - if (current) return; - transition_in(standardcommand.$$.fragment, local); - current = true; - }, - o(local) { - transition_out(standardcommand.$$.fragment, local); - current = false; - }, - d(detaching) { - destroy_component(standardcommand, detaching); - } - }; -} - -// (104:58) -function create_if_block_2(ctx) { - let userscriptcommand; - let updating_command; - let updating_dragDisabled; - let updating_startDrag; - let current; - - function userscriptcommand_command_binding(value) { - /*userscriptcommand_command_binding*/ ctx[23](value, /*command*/ ctx[34], /*each_value*/ ctx[35], /*command_index*/ ctx[36]); - } - - function userscriptcommand_dragDisabled_binding(value) { - /*userscriptcommand_dragDisabled_binding*/ ctx[24](value); - } - - function userscriptcommand_startDrag_binding(value) { - /*userscriptcommand_startDrag_binding*/ ctx[25](value); - } - - let userscriptcommand_props = {}; - - if (/*command*/ ctx[34] !== void 0) { - userscriptcommand_props.command = /*command*/ ctx[34]; - } - - if (/*dragDisabled*/ ctx[3] !== void 0) { - userscriptcommand_props.dragDisabled = /*dragDisabled*/ ctx[3]; - } - - if (/*startDrag*/ ctx[4] !== void 0) { - userscriptcommand_props.startDrag = /*startDrag*/ ctx[4]; - } - - userscriptcommand = new UserScriptCommand({ props: userscriptcommand_props }); - binding_callbacks.push(() => bind(userscriptcommand, 'command', userscriptcommand_command_binding)); - binding_callbacks.push(() => bind(userscriptcommand, 'dragDisabled', userscriptcommand_dragDisabled_binding)); - binding_callbacks.push(() => bind(userscriptcommand, 'startDrag', userscriptcommand_startDrag_binding)); - userscriptcommand.$on("deleteCommand", /*deleteCommand_handler_2*/ ctx[26]); - userscriptcommand.$on("updateCommand", /*updateCommandFromEvent*/ ctx[7]); - userscriptcommand.$on("configureScript", /*configureScript*/ ctx[9]); - - return { - c() { - create_component(userscriptcommand.$$.fragment); - }, - m(target, anchor) { - mount_component(userscriptcommand, target, anchor); - current = true; - }, - p(new_ctx, dirty) { - ctx = new_ctx; - const userscriptcommand_changes = {}; - - if (!updating_command && dirty[0] & /*commands, SHADOW_PLACEHOLDER_ITEM_ID*/ 5) { - updating_command = true; - userscriptcommand_changes.command = /*command*/ ctx[34]; - add_flush_callback(() => updating_command = false); - } - - if (!updating_dragDisabled && dirty[0] & /*dragDisabled*/ 8) { - updating_dragDisabled = true; - userscriptcommand_changes.dragDisabled = /*dragDisabled*/ ctx[3]; - add_flush_callback(() => updating_dragDisabled = false); - } - - if (!updating_startDrag && dirty[0] & /*startDrag*/ 16) { - updating_startDrag = true; - userscriptcommand_changes.startDrag = /*startDrag*/ ctx[4]; - add_flush_callback(() => updating_startDrag = false); - } - - userscriptcommand.$set(userscriptcommand_changes); - }, - i(local) { - if (current) return; - transition_in(userscriptcommand.$$.fragment, local); - current = true; - }, - o(local) { - transition_out(userscriptcommand.$$.fragment, local); - current = false; - }, - d(detaching) { - destroy_component(userscriptcommand, detaching); - } - }; -} - -// (102:60) -function create_if_block_1(ctx) { - let nestedchoicecommand; - let updating_command; - let updating_dragDisabled; - let updating_startDrag; - let current; - - function nestedchoicecommand_command_binding(value) { - /*nestedchoicecommand_command_binding*/ ctx[19](value, /*command*/ ctx[34], /*each_value*/ ctx[35], /*command_index*/ ctx[36]); - } - - function nestedchoicecommand_dragDisabled_binding(value) { - /*nestedchoicecommand_dragDisabled_binding*/ ctx[20](value); - } - - function nestedchoicecommand_startDrag_binding(value) { - /*nestedchoicecommand_startDrag_binding*/ ctx[21](value); - } - - let nestedchoicecommand_props = {}; - - if (/*command*/ ctx[34] !== void 0) { - nestedchoicecommand_props.command = /*command*/ ctx[34]; - } - - if (/*dragDisabled*/ ctx[3] !== void 0) { - nestedchoicecommand_props.dragDisabled = /*dragDisabled*/ ctx[3]; - } - - if (/*startDrag*/ ctx[4] !== void 0) { - nestedchoicecommand_props.startDrag = /*startDrag*/ ctx[4]; - } - - nestedchoicecommand = new NestedChoiceCommand$1({ props: nestedchoicecommand_props }); - binding_callbacks.push(() => bind(nestedchoicecommand, 'command', nestedchoicecommand_command_binding)); - binding_callbacks.push(() => bind(nestedchoicecommand, 'dragDisabled', nestedchoicecommand_dragDisabled_binding)); - binding_callbacks.push(() => bind(nestedchoicecommand, 'startDrag', nestedchoicecommand_startDrag_binding)); - nestedchoicecommand.$on("deleteCommand", /*deleteCommand_handler_1*/ ctx[22]); - nestedchoicecommand.$on("updateCommand", /*updateCommandFromEvent*/ ctx[7]); - nestedchoicecommand.$on("configureChoice", /*configureChoice*/ ctx[8]); - - return { - c() { - create_component(nestedchoicecommand.$$.fragment); - }, - m(target, anchor) { - mount_component(nestedchoicecommand, target, anchor); - current = true; - }, - p(new_ctx, dirty) { - ctx = new_ctx; - const nestedchoicecommand_changes = {}; - - if (!updating_command && dirty[0] & /*commands, SHADOW_PLACEHOLDER_ITEM_ID*/ 5) { - updating_command = true; - nestedchoicecommand_changes.command = /*command*/ ctx[34]; - add_flush_callback(() => updating_command = false); - } - - if (!updating_dragDisabled && dirty[0] & /*dragDisabled*/ 8) { - updating_dragDisabled = true; - nestedchoicecommand_changes.dragDisabled = /*dragDisabled*/ ctx[3]; - add_flush_callback(() => updating_dragDisabled = false); - } - - if (!updating_startDrag && dirty[0] & /*startDrag*/ 16) { - updating_startDrag = true; - nestedchoicecommand_changes.startDrag = /*startDrag*/ ctx[4]; - add_flush_callback(() => updating_startDrag = false); - } - - nestedchoicecommand.$set(nestedchoicecommand_changes); - }, - i(local) { - if (current) return; - transition_in(nestedchoicecommand.$$.fragment, local); - current = true; - }, - o(local) { - transition_out(nestedchoicecommand.$$.fragment, local); - current = false; - }, - d(detaching) { - destroy_component(nestedchoicecommand, detaching); - } - }; -} - -// (100:8) {#if command.type === CommandType.Wait} -function create_if_block(ctx) { - let waitcommand; - let updating_command; - let updating_dragDisabled; - let updating_startDrag; - let current; - - function waitcommand_command_binding(value) { - /*waitcommand_command_binding*/ ctx[15](value, /*command*/ ctx[34], /*each_value*/ ctx[35], /*command_index*/ ctx[36]); - } - - function waitcommand_dragDisabled_binding(value) { - /*waitcommand_dragDisabled_binding*/ ctx[16](value); - } - - function waitcommand_startDrag_binding(value) { - /*waitcommand_startDrag_binding*/ ctx[17](value); - } - - let waitcommand_props = {}; - - if (/*command*/ ctx[34] !== void 0) { - waitcommand_props.command = /*command*/ ctx[34]; - } - - if (/*dragDisabled*/ ctx[3] !== void 0) { - waitcommand_props.dragDisabled = /*dragDisabled*/ ctx[3]; - } - - if (/*startDrag*/ ctx[4] !== void 0) { - waitcommand_props.startDrag = /*startDrag*/ ctx[4]; - } - - waitcommand = new WaitCommand$1({ props: waitcommand_props }); - binding_callbacks.push(() => bind(waitcommand, 'command', waitcommand_command_binding)); - binding_callbacks.push(() => bind(waitcommand, 'dragDisabled', waitcommand_dragDisabled_binding)); - binding_callbacks.push(() => bind(waitcommand, 'startDrag', waitcommand_startDrag_binding)); - waitcommand.$on("deleteCommand", /*deleteCommand_handler*/ ctx[18]); - waitcommand.$on("updateCommand", /*updateCommandFromEvent*/ ctx[7]); - - return { - c() { - create_component(waitcommand.$$.fragment); - }, - m(target, anchor) { - mount_component(waitcommand, target, anchor); - current = true; - }, - p(new_ctx, dirty) { - ctx = new_ctx; - const waitcommand_changes = {}; - - if (!updating_command && dirty[0] & /*commands, SHADOW_PLACEHOLDER_ITEM_ID*/ 5) { - updating_command = true; - waitcommand_changes.command = /*command*/ ctx[34]; - add_flush_callback(() => updating_command = false); - } - - if (!updating_dragDisabled && dirty[0] & /*dragDisabled*/ 8) { - updating_dragDisabled = true; - waitcommand_changes.dragDisabled = /*dragDisabled*/ ctx[3]; - add_flush_callback(() => updating_dragDisabled = false); - } - - if (!updating_startDrag && dirty[0] & /*startDrag*/ 16) { - updating_startDrag = true; - waitcommand_changes.startDrag = /*startDrag*/ ctx[4]; - add_flush_callback(() => updating_startDrag = false); - } - - waitcommand.$set(waitcommand_changes); - }, - i(local) { - if (current) return; - transition_in(waitcommand.$$.fragment, local); - current = true; - }, - o(local) { - transition_out(waitcommand.$$.fragment, local); - current = false; - }, - d(detaching) { - destroy_component(waitcommand, detaching); - } - }; -} - -// (99:4) {#each commands.filter(c => c.id !== SHADOW_PLACEHOLDER_ITEM_ID) as command(command.id)} -function create_each_block(key_1, ctx) { - let first; - let current_block_type_index; - let if_block; - let if_block_anchor; - let current; - const if_block_creators = [create_if_block, create_if_block_1, create_if_block_2, create_else_block]; - const if_blocks = []; - - function select_block_type(ctx, dirty) { - if (/*command*/ ctx[34].type === CommandType.Wait) return 0; - if (/*command*/ ctx[34].type === CommandType.NestedChoice) return 1; - if (/*command*/ ctx[34].type === CommandType.UserScript) return 2; - return 3; - } - - current_block_type_index = select_block_type(ctx); - if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx); - - return { - key: key_1, - first: null, - c() { - first = empty(); - if_block.c(); - if_block_anchor = empty(); - this.first = first; - }, - m(target, anchor) { - insert(target, first, anchor); - if_blocks[current_block_type_index].m(target, anchor); - insert(target, if_block_anchor, anchor); - current = true; - }, - p(new_ctx, dirty) { - ctx = new_ctx; - let previous_block_index = current_block_type_index; - current_block_type_index = select_block_type(ctx); - - if (current_block_type_index === previous_block_index) { - if_blocks[current_block_type_index].p(ctx, dirty); - } else { - group_outros(); - - transition_out(if_blocks[previous_block_index], 1, 1, () => { - if_blocks[previous_block_index] = null; - }); - - check_outros(); - if_block = if_blocks[current_block_type_index]; - - if (!if_block) { - if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx); - if_block.c(); - } else { - if_block.p(ctx, dirty); - } - - transition_in(if_block, 1); - if_block.m(if_block_anchor.parentNode, if_block_anchor); - } - }, - i(local) { - if (current) return; - transition_in(if_block); - current = true; - }, - o(local) { - transition_out(if_block); - current = false; - }, - d(detaching) { - if (detaching) detach(first); - if_blocks[current_block_type_index].d(detaching); - if (detaching) detach(if_block_anchor); - } - }; -} - -function create_fragment$1(ctx) { - let ol; - let each_blocks = []; - let each_1_lookup = new Map(); - let dndzone_action; - let current; - let mounted; - let dispose; - let each_value = /*commands*/ ctx[0].filter(/*func*/ ctx[14]); - const get_key = ctx => /*command*/ ctx[34].id; - - for (let i = 0; i < each_value.length; i += 1) { - let child_ctx = get_each_context(ctx, each_value, i); - let key = get_key(child_ctx); - each_1_lookup.set(key, each_blocks[i] = create_each_block(key, child_ctx)); - } - - return { - c() { - ol = element("ol"); - - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].c(); - } - - attr(ol, "class", "quickAddCommandList svelte-1ukgrgp"); - }, - m(target, anchor) { - insert(target, ol, anchor); - - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].m(ol, null); - } - - current = true; - - if (!mounted) { - dispose = [ - action_destroyer(dndzone_action = dndzone$2.call(null, ol, { - items: /*commands*/ ctx[0], - dragDisabled: /*dragDisabled*/ ctx[3], - dropTargetStyle: {}, - type: "command" - })), - listen(ol, "consider", /*handleConsider*/ ctx[5]), - listen(ol, "finalize", /*handleSort*/ ctx[6]) - ]; - - mounted = true; - } - }, - p(ctx, dirty) { - if (dirty[0] & /*commands, SHADOW_PLACEHOLDER_ITEM_ID, dragDisabled, startDrag, deleteCommand, updateCommandFromEvent, configureChoice, configureScript*/ 927) { - each_value = /*commands*/ ctx[0].filter(/*func*/ ctx[14]); - group_outros(); - each_blocks = update_keyed_each(each_blocks, dirty, get_key, 1, ctx, each_value, each_1_lookup, ol, outro_and_destroy_block, create_each_block, null, get_each_context); - check_outros(); - } - - if (dndzone_action && is_function(dndzone_action.update) && dirty[0] & /*commands, dragDisabled*/ 9) dndzone_action.update.call(null, { - items: /*commands*/ ctx[0], - dragDisabled: /*dragDisabled*/ ctx[3], - dropTargetStyle: {}, - type: "command" - }); - }, - i(local) { - if (current) return; - - for (let i = 0; i < each_value.length; i += 1) { - transition_in(each_blocks[i]); - } - - current = true; - }, - o(local) { - for (let i = 0; i < each_blocks.length; i += 1) { - transition_out(each_blocks[i]); - } - - current = false; - }, - d(detaching) { - if (detaching) detach(ol); - - for (let i = 0; i < each_blocks.length; i += 1) { - each_blocks[i].d(); - } - - mounted = false; - run_all(dispose); - } - }; -} - -function instance$1($$self, $$props, $$invalidate) { - var __awaiter = this && this.__awaiter || function (thisArg, _arguments, P, generator) { - function adopt(value) { - return value instanceof P - ? value - : new P(function (resolve) { - resolve(value); - }); - } - - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { - try { - step(generator.next(value)); - } catch(e) { - reject(e); - } - } - - function rejected(value) { - try { - step(generator["throw"](value)); - } catch(e) { - reject(e); - } - } - - function step(result) { - result.done - ? resolve(result.value) - : adopt(result.value).then(fulfilled, rejected); - } - - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); - }; - - let { commands } = $$props; - let { deleteCommand } = $$props; - let { saveCommands } = $$props; - let { app } = $$props; - let { plugin } = $$props; - let dragDisabled = true; - - const updateCommandList = newCommands => { - $$invalidate(0, commands = newCommands); - }; - - function handleConsider(e) { - let { items: newItems } = e.detail; - $$invalidate(0, commands = newItems); - } - - function handleSort(e) { - let { items: newItems, info: { source } } = e.detail; - $$invalidate(0, commands = newItems); - - if (source === SOURCES.POINTER) { - $$invalidate(3, dragDisabled = true); - } - - saveCommands(commands); - } - - let startDrag = e => { - e.preventDefault(); - $$invalidate(3, dragDisabled = false); - }; - - function updateCommandFromEvent(e) { - const command = e.detail; - updateCommand(command); - } - - function updateCommand(command) { - const index = commands.findIndex(c => c.id === command.id); - $$invalidate(0, commands[index] = command, commands); - saveCommands(commands); - } - - function configureChoice(e) { - return __awaiter(this, void 0, void 0, function* () { - const command = e.detail; - const newChoice = yield getChoiceBuilder(command.choice).waitForClose; - if (!newChoice) return; - command.choice = newChoice; - command.name = newChoice.name; - updateCommand(command); - }); - } - - function getChoiceBuilder(choice) { - switch (choice.type) { - case ChoiceType.Template: - return new TemplateChoiceBuilder(app, choice, plugin); - case ChoiceType.Capture: - return new CaptureChoiceBuilder(app, choice, plugin); - case ChoiceType.Macro: - case ChoiceType.Multi: - } - } - - function configureScript(e) { - return __awaiter(this, void 0, void 0, function* () { - const command = e.detail; - const userScript = yield getUserScript(command, app); - - if (!userScript.settings) { - log.logWarning(`${command.name} has no settings.`); - return; - } - - new UserScriptSettingsModal(app, command, userScript.settings).open(); - }); - } - - const func = c => c.id !== SHADOW_PLACEHOLDER_ITEM_ID; - - function waitcommand_command_binding(value, command, each_value, command_index) { - each_value[command_index] = value; - $$invalidate(0, commands); - } - - function waitcommand_dragDisabled_binding(value) { - dragDisabled = value; - $$invalidate(3, dragDisabled); - } - - function waitcommand_startDrag_binding(value) { - startDrag = value; - $$invalidate(4, startDrag); - } - - const deleteCommand_handler = async e => await deleteCommand(e.detail); - - function nestedchoicecommand_command_binding(value, command, each_value, command_index) { - each_value[command_index] = value; - $$invalidate(0, commands); - } - - function nestedchoicecommand_dragDisabled_binding(value) { - dragDisabled = value; - $$invalidate(3, dragDisabled); - } - - function nestedchoicecommand_startDrag_binding(value) { - startDrag = value; - $$invalidate(4, startDrag); - } - - const deleteCommand_handler_1 = async e => await deleteCommand(e.detail); - - function userscriptcommand_command_binding(value, command, each_value, command_index) { - each_value[command_index] = value; - $$invalidate(0, commands); - } - - function userscriptcommand_dragDisabled_binding(value) { - dragDisabled = value; - $$invalidate(3, dragDisabled); - } - - function userscriptcommand_startDrag_binding(value) { - startDrag = value; - $$invalidate(4, startDrag); - } - - const deleteCommand_handler_2 = async e => await deleteCommand(e.detail); - - function standardcommand_command_binding(value, command, each_value, command_index) { - each_value[command_index] = value; - $$invalidate(0, commands); - } - - function standardcommand_dragDisabled_binding(value) { - dragDisabled = value; - $$invalidate(3, dragDisabled); - } - - function standardcommand_startDrag_binding(value) { - startDrag = value; - $$invalidate(4, startDrag); - } - - const deleteCommand_handler_3 = async e => await deleteCommand(e.detail); - - $$self.$$set = $$props => { - if ('commands' in $$props) $$invalidate(0, commands = $$props.commands); - if ('deleteCommand' in $$props) $$invalidate(1, deleteCommand = $$props.deleteCommand); - if ('saveCommands' in $$props) $$invalidate(10, saveCommands = $$props.saveCommands); - if ('app' in $$props) $$invalidate(11, app = $$props.app); - if ('plugin' in $$props) $$invalidate(12, plugin = $$props.plugin); - }; - - return [ - commands, - deleteCommand, - SHADOW_PLACEHOLDER_ITEM_ID, - dragDisabled, - startDrag, - handleConsider, - handleSort, - updateCommandFromEvent, - configureChoice, - configureScript, - saveCommands, - app, - plugin, - updateCommandList, - func, - waitcommand_command_binding, - waitcommand_dragDisabled_binding, - waitcommand_startDrag_binding, - deleteCommand_handler, - nestedchoicecommand_command_binding, - nestedchoicecommand_dragDisabled_binding, - nestedchoicecommand_startDrag_binding, - deleteCommand_handler_1, - userscriptcommand_command_binding, - userscriptcommand_dragDisabled_binding, - userscriptcommand_startDrag_binding, - deleteCommand_handler_2, - standardcommand_command_binding, - standardcommand_dragDisabled_binding, - standardcommand_startDrag_binding, - deleteCommand_handler_3 - ]; -} - -class CommandList extends SvelteComponent { - constructor(options) { - super(); - - init( - this, - options, - instance$1, - create_fragment$1, - safe_not_equal, - { - commands: 0, - deleteCommand: 1, - saveCommands: 10, - app: 11, - plugin: 12, - updateCommandList: 13 - }, - add_css$1, - [-1, -1] - ); - } - - get updateCommandList() { - return this.$$.ctx[13]; - } -} - -class ChoiceCommand extends Command { - constructor(name, choiceId) { - super(name, CommandType.Choice); - this.choiceId = choiceId; - } -} - -class WaitCommand extends Command { - constructor(time) { - super("Wait", CommandType.Wait); - this.time = time; - } -} - -class NestedChoiceCommand extends Command { - constructor(choice) { - super(choice.name, CommandType.NestedChoice); - this.choice = choice; - } -} - -class MacroBuilder extends obsidian.Modal { - constructor(app, plugin, macro, choices) { - super(app); - this.commands = []; - this.javascriptFiles = []; - this.choices = []; - this.macro = macro; - this.svelteElements = []; - this.choices = choices; - this.plugin = plugin; - this.waitForClose = new Promise(resolve => (this.resolvePromise = resolve)); - this.getObsidianCommands(); - this.getJavascriptFiles(); - this.display(); - this.open(); - } - onClose() { - super.onClose(); - this.resolvePromise(this.macro); - this.svelteElements.forEach(el => { - if (el && el.$destroy) - el.$destroy(); - }); - } - display() { - this.contentEl.empty(); - this.addCenteredHeader(this.macro.name); - this.addCommandList(); - this.addCommandBar(); - this.addAddObsidianCommandSetting(); - this.addAddEditorCommandsSetting(); - this.addAddUserScriptSetting(); - this.addAddChoiceSetting(); - } - addCenteredHeader(header) { - const headerEl = this.contentEl.createEl('h2'); - headerEl.style.textAlign = "center"; - headerEl.setText(header); - headerEl.addClass('clickable'); - headerEl.addEventListener('click', async () => { - const newMacroName = await GenericInputPrompt.Prompt(this.app, `Update name for ${this.macro.name}`, this.macro.name); - if (!newMacroName) - return; - this.macro.name = newMacroName; - this.reload(); - }); - } - reload() { - this.display(); - } - addAddObsidianCommandSetting() { - let input; - const addObsidianCommandFromInput = () => { - const value = input.getValue(); - const obsidianCommand = this.commands.find(v => v.name === value); - const command = new ObsidianCommand(obsidianCommand.name, obsidianCommand.commandId); - command.generateId(); - this.addCommandToMacro(command); - input.setValue(""); - }; - new obsidian.Setting(this.contentEl) - .setName("Obsidian command") - .setDesc("Add an Obsidian command") - .addText(textComponent => { - input = textComponent; - textComponent.inputEl.style.marginRight = "1em"; - textComponent.setPlaceholder("Obsidian command"); - new GenericTextSuggester(this.app, textComponent.inputEl, this.commands.map(c => c.name)); - textComponent.inputEl.addEventListener('keypress', (e) => { - if (e.key === 'Enter') { - addObsidianCommandFromInput(); - } - }); - }) - .addButton(button => button.setCta().setButtonText("Add").onClick(addObsidianCommandFromInput)); - } - addAddEditorCommandsSetting() { - let dropdownComponent; - const addEditorCommandFromDropdown = () => { - const type = dropdownComponent.getValue(); - let command; - switch (type) { - case EditorCommandType.Copy: - command = new CopyCommand(); - break; - case EditorCommandType.Cut: - command = new CutCommand(); - break; - case EditorCommandType.Paste: - command = new PasteCommand(); - break; - case EditorCommandType.SelectActiveLine: - command = new SelectActiveLineCommand(); - break; - case EditorCommandType.SelectLinkOnActiveLine: - command = new SelectLinkOnActiveLineCommand(); - break; - default: - log.logError("invalid editor command type"); - } - this.addCommandToMacro(command); - }; - new obsidian.Setting(this.contentEl) - .setName("Editor commands") - .setDesc("Add editor command") - .addDropdown(dropdown => { - dropdownComponent = dropdown; - dropdown.selectEl.style.marginRight = "1em"; - dropdown.addOption(EditorCommandType.Copy, EditorCommandType.Copy) - .addOption(EditorCommandType.Cut, EditorCommandType.Cut) - .addOption(EditorCommandType.Paste, EditorCommandType.Paste) - .addOption(EditorCommandType.SelectActiveLine, EditorCommandType.SelectActiveLine) - .addOption(EditorCommandType.SelectLinkOnActiveLine, EditorCommandType.SelectLinkOnActiveLine); - }) - .addButton(button => button.setCta().setButtonText("Add").onClick(addEditorCommandFromDropdown)); - } - addAddUserScriptSetting() { - let input; - const addUserScriptFromInput = () => { - const value = input.getValue(); - const scriptBasename = getUserScriptMemberAccess(value).basename; - const file = this.javascriptFiles.find(f => f.basename === scriptBasename); - if (!file) - return; - this.addCommandToMacro(new UserScript(value, file.path)); - input.setValue(""); - }; - new obsidian.Setting(this.contentEl) - .setName("User Scripts") - .setDesc("Add user script") - .addText(textComponent => { - input = textComponent; - textComponent.inputEl.style.marginRight = "1em"; - textComponent.setPlaceholder("User script"); - new GenericTextSuggester(this.app, textComponent.inputEl, this.javascriptFiles.map(f => f.basename)); - textComponent.inputEl.addEventListener('keypress', (e) => { - if (e.key === 'Enter') { - addUserScriptFromInput(); - } - }); - }) - .addButton(button => button - .setButtonText("Add") - .setCta() - .onClick(addUserScriptFromInput)); - } - addAddChoiceSetting() { - let input; - const addChoiceFromInput = () => { - const value = input.getValue(); - const choice = this.choices.find(c => c.name === value); - if (!choice) - return; - this.addCommandToMacro(new ChoiceCommand(choice.name, choice.id)); - input.setValue(""); - }; - new obsidian.Setting(this.contentEl) - .setName("Choices") - .setDesc("Add existing choice") - .addText(textComponent => { - input = textComponent; - textComponent.inputEl.style.marginRight = "1em"; - textComponent.setPlaceholder("Choice"); - new GenericTextSuggester(this.app, textComponent.inputEl, this.choices.map(c => c.name)); - textComponent.inputEl.addEventListener('keypress', (e) => { - if (e.key === 'Enter') { - addChoiceFromInput(); - } - }); - }) - .addButton(button => button.setCta() - .setButtonText("Add") - .onClick(addChoiceFromInput)); - } - getObsidianCommands() { - // @ts-ignore - Object.keys(this.app.commands.commands).forEach(key => { - // @ts-ignore - const command = this.app.commands.commands[key]; - this.commands.push(new ObsidianCommand(command.name, command.id)); - }); - } - getJavascriptFiles() { - this.javascriptFiles = this.app.vault.getFiles() - .filter(file => JAVASCRIPT_FILE_EXTENSION_REGEX.test(file.path)); - } - addCommandList() { - const commandList = this.contentEl.createDiv('commandList'); - console.log(this.macro.commands); - this.commandListEl = new CommandList({ - target: commandList, - props: { - app: this.app, - plugin: this.plugin, - commands: this.macro.commands, - deleteCommand: async (commandId) => { - const command = this.macro.commands.find(c => c.id === commandId); - const promptAnswer = await GenericYesNoPrompt.Prompt(this.app, "Are you sure you wish to delete this command?", `If you click yes, you will delete '${command.name}'.`); - if (!promptAnswer) - return; - this.macro.commands = this.macro.commands.filter(c => c.id !== commandId); - this.commandListEl.updateCommandList(this.macro.commands); - }, - saveCommands: (commands) => { - this.macro.commands = commands; - }, - } - }); - this.svelteElements.push(this.commandListEl); - } - addCommandBar() { - const quickCommandContainer = this.contentEl.createDiv('quickCommandContainer'); - this.newChoiceButton(quickCommandContainer, "Capture", CaptureChoice); - this.newChoiceButton(quickCommandContainer, "Template", TemplateChoice); - this.addAddWaitCommandButton(quickCommandContainer); - } - addAddWaitCommandButton(quickCommandContainer) { - const button = new obsidian.ButtonComponent(quickCommandContainer); - button.setIcon('clock').setTooltip("Add wait command").onClick(() => { - this.addCommandToMacro(new WaitCommand(100)); - }); - } - newChoiceButton(container, typeName, type) { - const button = new obsidian.ButtonComponent(container); - button.setButtonText(typeName).setTooltip(`Add ${typeName} Choice`).onClick(() => { - const captureChoice = new type(`Untitled ${typeName} Choice`); - this.addCommandToMacro(new NestedChoiceCommand(captureChoice)); - }); - } - addCommandToMacro(command) { - this.macro.commands.push(command); - this.commandListEl.updateCommandList(this.macro.commands); - } -} - -class QuickAddMacro { - constructor(name) { - this.name = name; - this.id = v4(); - this.commands = []; - this.runOnStartup = false; - } -} - -class MacrosManager extends obsidian.Modal { - constructor(app, plugin, macros, choices) { - super(app); - this.app = app; - this.macros = macros; - this.choices = choices; - this.plugin = plugin; - this.waitForClose = new Promise(((resolve, reject) => { - this.rejectPromise = reject; - this.resolvePromise = resolve; - })); - this.open(); - this.display(); - } - display() { - this.contentEl.createEl('h2', { text: 'Macro Manager' }).style.textAlign = "center"; - this.addMacroSettings(); - this.addAddMacroBar(); - } - addMacroSettings() { - this.macroContainer = this.contentEl.createDiv(); - this.updateMacroContainer = () => { - if (this.macros.length <= 1) - this.macroContainer.className = "macroContainer macroContainer1"; - if (this.macros.length === 2) - this.macroContainer.className = "macroContainer macroContainer2"; - if (this.macros.length > 2) - this.macroContainer.className = "macroContainer macroContainer3"; - }; - this.macros.forEach(macro => this.addMacroSetting(macro, this.macroContainer)); - this.updateMacroContainer(); - } - addMacroSetting(macro, container) { - const configureMacroContainer = container.createDiv(); - const macroSetting = new obsidian.Setting(configureMacroContainer); - macroSetting.setName(macro.name); - macroSetting.infoEl.style.fontWeight = "bold"; - this.addMacroConfigurationItem(configureMacroContainer, itemContainerEl => { - this.addSpanWithText(itemContainerEl, "Run on plugin load"); - const toggle = new obsidian.ToggleComponent(itemContainerEl); - toggle.setValue(macro.runOnStartup); - toggle.onChange(value => { - macro.runOnStartup = value; - this.updateMacro(macro); - }); - }); - configureMacroContainer.addClass("configureMacroDiv"); - this.addMacroConfigurationItem(configureMacroContainer, itemContainerEl => { - const deleteButton = new obsidian.ButtonComponent(itemContainerEl); - deleteButton.setClass('mod-warning'); - deleteButton.buttonEl.style.marginRight = "0"; - deleteButton.setButtonText("Delete").onClick(evt => { - this.macros = this.macros.filter(m => m.id !== macro.id); - const scroll = this.macroContainer.scrollTop; - this.reload(); - this.macroContainer.scrollTop = scroll; - }); - const configureButton = new obsidian.ButtonComponent(itemContainerEl); - configureButton.setClass('mod-cta'); - configureButton.buttonEl.style.marginRight = "0"; - configureButton.setButtonText("Configure").onClick(async (evt) => { - const getReachableChoices = (choices) => { - let reachableChoices = []; - choices.forEach(choice => { - if (choice.type === ChoiceType.Multi) - reachableChoices.push(...getReachableChoices(choice.choices)); - if (choice.type !== ChoiceType.Multi) - reachableChoices.push(choice); - }); - return reachableChoices; - }; - const reachableChoices = getReachableChoices(this.choices); - const newMacro = await new MacroBuilder(this.app, this.plugin, macro, reachableChoices).waitForClose; - if (newMacro) { - this.updateMacro(newMacro); - this.reload(); - } - }); - }); - } - addMacroConfigurationItem(container, callback, classString = "configureMacroDivItem") { - const item = container.createDiv(); - item.addClass(classString); - callback(item); - } - addSpanWithText(container, text) { - const configureText = container.createEl('span'); - configureText.setText(text); - } - updateMacro(macro) { - const index = this.macros.findIndex(v => v.id === macro.id); - this.macros[index] = macro; - if (this.updateMacroContainer) - this.updateMacroContainer(); - this.reload(); - } - reload() { - this.contentEl.empty(); - this.display(); - } - addAddMacroBar() { - const addMacroBarContainer = this.contentEl.createDiv(); - addMacroBarContainer.addClass("addMacroBarContainer"); - const nameInput = new obsidian.TextComponent(addMacroBarContainer); - nameInput.setPlaceholder("Macro name"); - const addMacroButton = new obsidian.ButtonComponent(addMacroBarContainer); - addMacroButton.setButtonText("Add macro") - .setClass("mod-cta") - .onClick(() => { - const inputValue = nameInput.getValue(); - if (inputValue !== "" && !this.macros.find(m => m.name === inputValue)) { - const macro = new QuickAddMacro(inputValue); - if (!macro) { - log.logError("macro invalid - will not be added"); - return; - } - this.macros.push(macro); - this.reload(); - this.macroContainer.scrollTo(0, this.macroContainer.scrollHeight); - } - }); - } - onClose() { - super.onClose(); - this.resolvePromise(this.macros); - } -} - -/* src/gui/choiceList/ChoiceView.svelte generated by Svelte v3.43.0 */ - -function add_css(target) { - append_styles(target, "svelte-wcmtyt", ".choiceViewBottomBar.svelte-wcmtyt{display:flex;flex-direction:row;align-items:center;justify-content:space-between;margin-top:1rem}@media(max-width: 800px){.choiceViewBottomBar.svelte-wcmtyt{flex-direction:column}}"); -} - -function create_fragment(ctx) { - let div1; - let choicelist; - let updating_choices; - let t0; - let div0; - let button; - let t2; - let addchoicebox; - let current; - let mounted; - let dispose; - - function choicelist_choices_binding(value) { - /*choicelist_choices_binding*/ ctx[11](value); - } - - let choicelist_props = { type: "main" }; - - if (/*choices*/ ctx[0] !== void 0) { - choicelist_props.choices = /*choices*/ ctx[0]; - } - - choicelist = new ChoiceList({ props: choicelist_props }); - binding_callbacks.push(() => bind(choicelist, 'choices', choicelist_choices_binding)); - choicelist.$on("deleteChoice", /*deleteChoice*/ ctx[3]); - choicelist.$on("configureChoice", /*configureChoice*/ ctx[4]); - choicelist.$on("toggleCommand", /*toggleCommandForChoice*/ ctx[5]); - choicelist.$on("reorderChoices", /*reorderChoices_handler*/ ctx[12]); - addchoicebox = new AddChoiceBox({}); - addchoicebox.$on("addChoice", /*addChoiceToList*/ ctx[2]); - - return { - c() { - div1 = element("div"); - create_component(choicelist.$$.fragment); - t0 = space(); - div0 = element("div"); - button = element("button"); - button.textContent = "Manage Macros"; - t2 = space(); - create_component(addchoicebox.$$.fragment); - attr(button, "class", "mod-cta"); - attr(div0, "class", "choiceViewBottomBar svelte-wcmtyt"); - }, - m(target, anchor) { - insert(target, div1, anchor); - mount_component(choicelist, div1, null); - append(div1, t0); - append(div1, div0); - append(div0, button); - append(div0, t2); - mount_component(addchoicebox, div0, null); - current = true; - - if (!mounted) { - dispose = listen(button, "click", /*openMacroManager*/ ctx[6]); - mounted = true; - } - }, - p(ctx, [dirty]) { - const choicelist_changes = {}; - - if (!updating_choices && dirty & /*choices*/ 1) { - updating_choices = true; - choicelist_changes.choices = /*choices*/ ctx[0]; - add_flush_callback(() => updating_choices = false); - } - - choicelist.$set(choicelist_changes); - }, - i(local) { - if (current) return; - transition_in(choicelist.$$.fragment, local); - transition_in(addchoicebox.$$.fragment, local); - current = true; - }, - o(local) { - transition_out(choicelist.$$.fragment, local); - transition_out(addchoicebox.$$.fragment, local); - current = false; - }, - d(detaching) { - if (detaching) detach(div1); - destroy_component(choicelist); - destroy_component(addchoicebox); - mounted = false; - dispose(); - } - }; -} - -function instance($$self, $$props, $$invalidate) { - var __awaiter = this && this.__awaiter || function (thisArg, _arguments, P, generator) { - function adopt(value) { - return value instanceof P - ? value - : new P(function (resolve) { - resolve(value); - }); - } - - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { - try { - step(generator.next(value)); - } catch(e) { - reject(e); - } - } - - function rejected(value) { - try { - step(generator["throw"](value)); - } catch(e) { - reject(e); - } - } - - function step(result) { - result.done - ? resolve(result.value) - : adopt(result.value).then(fulfilled, rejected); - } - - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); - }; - - let { choices = [] } = $$props; - let { macros = [] } = $$props; - let { saveChoices } = $$props; - let { saveMacros } = $$props; - let { app } = $$props; - let { plugin } = $$props; - - function addChoiceToList(event) { - const { name, type } = event.detail; - - switch (type) { - case ChoiceType.Template: - const templateChoice = new TemplateChoice(name); - $$invalidate(0, choices = [...choices, templateChoice]); - break; - case ChoiceType.Capture: - const captureChoice = new CaptureChoice(name); - $$invalidate(0, choices = [...choices, captureChoice]); - break; - case ChoiceType.Macro: - const macroChoice = new MacroChoice(name); - $$invalidate(0, choices = [...choices, macroChoice]); - break; - case ChoiceType.Multi: - const multiChoice = new MultiChoice(name); - $$invalidate(0, choices = [...choices, multiChoice]); - break; - } - - saveChoices(choices); - } - - function deleteChoice(e) { - return __awaiter(this, void 0, void 0, function* () { - const choice = e.detail.choice; - - const userConfirmed = yield GenericYesNoPrompt.Prompt(app, `Confirm deletion of choice`, `Please confirm that you wish to delete '${choice.name}'. - ${choice.type === ChoiceType.Multi - ? "Deleting this choice will delete all (" + choice.choices.length + ") choices inside it!" - : ""} - `); - - if (userConfirmed) { - $$invalidate(0, choices = choices.filter(value => deleteChoiceHelper(choice.id, value))); - plugin.removeCommandForChoice(choice); - saveChoices(choices); - } - }); - } - - function deleteChoiceHelper(id, value) { - if (value.type === ChoiceType.Multi) { - value.choices = value.choices.filter(v => deleteChoiceHelper(id, v)); - } - - return value.id !== id; - } - - function configureChoice(e) { - return __awaiter(this, void 0, void 0, function* () { - const { choice: oldChoice } = e.detail; - let updatedChoice; - - if (oldChoice.type === ChoiceType.Multi) { - updatedChoice = oldChoice; - const name = yield GenericInputPrompt.Prompt(app, `Rename ${oldChoice.name}`, '', oldChoice.name); - if (!name) return; - updatedChoice.name = name; - } else { - updatedChoice = yield getChoiceBuilder(oldChoice).waitForClose; - } - - if (!updatedChoice) return; - $$invalidate(0, choices = choices.map(choice => updateChoiceHelper(choice, updatedChoice))); - saveChoices(choices); - }); - } - - function toggleCommandForChoice(e) { - return __awaiter(this, void 0, void 0, function* () { - const { choice: oldChoice } = e.detail; - const updatedChoice = Object.assign(Object.assign({}, oldChoice), { command: !oldChoice.command }); - - updatedChoice.command - ? plugin.addCommandForChoice(updatedChoice) - : plugin.removeCommandForChoice(updatedChoice); - - $$invalidate(0, choices = choices.map(choice => updateChoiceHelper(choice, updatedChoice))); - saveChoices(choices); - }); - } - - function updateChoiceHelper(oldChoice, newChoice) { - if (oldChoice.id === newChoice.id) { - oldChoice = Object.assign(Object.assign({}, oldChoice), newChoice); - return oldChoice; - } - - if (oldChoice.type === ChoiceType.Multi) { - const multiChoice = oldChoice; - const multiChoiceChoices = multiChoice.choices.map(c => updateChoiceHelper(c, newChoice)); - return Object.assign(Object.assign({}, multiChoice), { choices: multiChoiceChoices }); - } - - return oldChoice; - } - - function getChoiceBuilder(choice) { - switch (choice.type) { - case ChoiceType.Template: - return new TemplateChoiceBuilder(app, choice, plugin); - case ChoiceType.Capture: - return new CaptureChoiceBuilder(app, choice, plugin); - case ChoiceType.Macro: - return new MacroChoiceBuilder(app, choice, macros); - case ChoiceType.Multi: - } - } - - function openMacroManager() { - return __awaiter(this, void 0, void 0, function* () { - const newMacros = yield new MacrosManager(app, plugin, macros, choices).waitForClose; - - if (newMacros) { - saveMacros(newMacros); - $$invalidate(7, macros = newMacros); - } - }); - } - - function choicelist_choices_binding(value) { - choices = value; - $$invalidate(0, choices); - } - - const reorderChoices_handler = e => saveChoices(e.detail.choices); - - $$self.$$set = $$props => { - if ('choices' in $$props) $$invalidate(0, choices = $$props.choices); - if ('macros' in $$props) $$invalidate(7, macros = $$props.macros); - if ('saveChoices' in $$props) $$invalidate(1, saveChoices = $$props.saveChoices); - if ('saveMacros' in $$props) $$invalidate(8, saveMacros = $$props.saveMacros); - if ('app' in $$props) $$invalidate(9, app = $$props.app); - if ('plugin' in $$props) $$invalidate(10, plugin = $$props.plugin); - }; - - return [ - choices, - saveChoices, - addChoiceToList, - deleteChoice, - configureChoice, - toggleCommandForChoice, - openMacroManager, - macros, - saveMacros, - app, - plugin, - choicelist_choices_binding, - reorderChoices_handler - ]; -} - -class ChoiceView extends SvelteComponent { - constructor(options) { - super(); - - init( - this, - options, - instance, - create_fragment, - safe_not_equal, - { - choices: 0, - macros: 7, - saveChoices: 1, - saveMacros: 8, - app: 9, - plugin: 10 - }, - add_css - ); - } -} - -const DEFAULT_SETTINGS = { - choices: [], - macros: [] -}; -class QuickAddSettingsTab extends obsidian.PluginSettingTab { - constructor(app, plugin) { - super(app, plugin); - this.plugin = plugin; - } - display() { - let { containerEl } = this; - containerEl.empty(); - containerEl.createEl('h2', { text: 'QuickAdd Settings' }); - this.addChoicesSetting(); - } - hide() { - if (this.choiceView) - this.choiceView.$destroy(); - } - addChoicesSetting() { - const setting = new obsidian.Setting(this.containerEl); - setting.infoEl.remove(); - setting.settingEl.style.display = "block"; - this.choiceView = new ChoiceView({ - target: setting.settingEl, - props: { - app: this.app, - plugin: this.plugin, - choices: this.plugin.settings.choices, - saveChoices: async (choices) => { - this.plugin.settings.choices = choices; - await this.plugin.saveSettings(); - }, - macros: this.plugin.settings.macros, - saveMacros: async (macros) => { - this.plugin.settings.macros = macros; - await this.plugin.saveSettings(); - } - } - }); - } -} - -class TemplateChoiceEngine extends TemplateEngine { - constructor(app, plugin, choice, choiceExecutor) { - super(app, plugin, choiceExecutor); - this.choice = choice; - } - async run() { - let folderPath = ""; - if (this.choice.folder.enabled) { - folderPath = await this.getFolderPath(); - } - let filePath; - if (this.choice.fileNameFormat.enabled) { - filePath = await this.getFormattedFilePath(folderPath, this.choice.fileNameFormat.format, this.choice.name); - } - else { - filePath = await this.getFormattedFilePath(folderPath, VALUE_SYNTAX, this.choice.name); - } - if (this.choice.incrementFileName) - filePath = await this.incrementFileName(filePath); - let createdFile; - if (await this.app.vault.adapter.exists(filePath)) { - const file = this.app.vault.getAbstractFileByPath(filePath); - if (!(file instanceof obsidian.TFile) || file.extension !== 'md') { - log.logError(`'${filePath}' already exists and is not a valid markdown file.`); - return; - } - await this.app.workspace.splitActiveLeaf('vertical').openFile(file); - const userChoice = await GenericSuggester.Suggest(this.app, fileExistsChoices, fileExistsChoices); - switch (userChoice) { - case fileExistsAppendToTop: - createdFile = await this.appendToFileWithTemplate(file, this.choice.templatePath, 'top'); - break; - case fileExistsAppendToBottom: - createdFile = await this.appendToFileWithTemplate(file, this.choice.templatePath, 'bottom'); - break; - case fileExistsOverwriteFile: - createdFile = await this.overwriteFileWithTemplate(file, this.choice.templatePath); - break; - case fileExistsDoNothing: - default: - log.logWarning("File not written to."); - return; - } - } - else { - createdFile = await this.createFileWithTemplate(filePath, this.choice.templatePath); - if (!createdFile) { - log.logWarning(`Could not create file '${filePath}'.`); - return; - } - } - if (this.choice.appendLink) { - appendToCurrentLine(this.app.fileManager.generateMarkdownLink(createdFile, ''), this.app); - } - if (this.choice.openFile) { - await openFile(this.app, createdFile, { - openInNewTab: this.choice.openFileInNewTab.enabled, - direction: this.choice.openFileInNewTab.direction, - focus: this.choice.openFileInNewTab.focus, - mode: this.choice.openFileInMode - }); - } - } - async getFolderPath() { - var _a, _b; - let folders = [...this.choice.folder.folders]; - if ((_a = this.choice.folder) === null || _a === void 0 ? void 0 : _a.chooseWhenCreatingNote) { - const allFoldersInVault = getAllFolderPathsInVault(this.app); - return await this.getOrCreateFolder(allFoldersInVault); - } - if ((_b = this.choice.folder) === null || _b === void 0 ? void 0 : _b.createInSameFolderAsActiveFile) { - const activeFile = this.app.workspace.getActiveFile(); - if (!activeFile) - log.logError("No active file. Cannot create new file."); - return this.getOrCreateFolder([activeFile.parent.path]); - } - return await this.getOrCreateFolder(folders); - } -} - -class CaptureChoiceFormatter extends CompleteFormatter { - constructor(app, plugin, choiceExecutor) { - super(app, plugin, choiceExecutor); - this.file = null; - this.fileContent = ""; - } - async formatContentWithFile(input, choice, fileContent, file) { - this.choice = choice; - this.file = file; - this.fileContent = fileContent; - if (!choice || !file || fileContent === null) - return input; - const formatted = await this.formatFileContent(input); - const templaterFormatted = templaterParseTemplate(this.app, formatted, this.file); - if (!templaterFormatted) - return formatted; - return templaterFormatted; - } - async formatContent(input, choice) { - this.choice = choice; - if (!choice) - return input; - return await this.formatFileContent(input); - } - async formatFileContent(input) { - let formatted = await super.formatFileContent(input); - formatted = this.replaceLinebreakInString(formatted); - const formattedContentIsEmpty = formatted.trim() === ""; - if (formattedContentIsEmpty) - return this.fileContent; - if (this.choice.prepend) { - const shouldInsertLinebreak = !this.choice.task; - return `${this.fileContent}${shouldInsertLinebreak ? "\n" : ""}${formatted}`; - } - if (this.choice.insertAfter.enabled) { - return await this.insertAfterHandler(formatted); - } - const frontmatterEndPosition = this.file ? await this.getFrontmatterEndPosition(this.file) : null; - if (!frontmatterEndPosition) - return `${formatted}${this.fileContent}`; - return this.insertTextAfterPositionInBody(formatted, this.fileContent, frontmatterEndPosition); - } - async insertAfterHandler(formatted) { - var _a, _b; - const targetString = await this.format(this.choice.insertAfter.after); - const targetRegex = new RegExp(`\s*${escapeRegExp(targetString.replace('\\n', ''))}\s*`); - let fileContentLines = getLinesInString(this.fileContent); - const targetPosition = fileContentLines.findIndex(line => targetRegex.test(line)); - const targetNotFound = targetPosition === -1; - if (targetNotFound) { - if ((_a = this.choice.insertAfter) === null || _a === void 0 ? void 0 : _a.createIfNotFound) { - return await this.createInsertAfterIfNotFound(formatted); - } - log.logError("unable to find insert after line in file."); - } - if ((_b = this.choice.insertAfter) === null || _b === void 0 ? void 0 : _b.insertAtEnd) { - const nextHeaderPositionAfterTargetPosition = fileContentLines - .slice(targetPosition + 1) - .findIndex(line => (/^#+ |---/).test(line)); - const foundNextHeader = nextHeaderPositionAfterTargetPosition !== -1; - if (foundNextHeader) { - let endOfSectionIndex; - for (let i = nextHeaderPositionAfterTargetPosition + targetPosition; i > targetPosition; i--) { - const lineIsNewline = (/^[\s\n ]*$/).test(fileContentLines[i]); - if (!lineIsNewline) { - endOfSectionIndex = i; - break; - } - } - if (!endOfSectionIndex) - endOfSectionIndex = targetPosition; - return this.insertTextAfterPositionInBody(formatted, this.fileContent, endOfSectionIndex); - } - else { - return this.insertTextAfterPositionInBody(formatted, this.fileContent, fileContentLines.length - 1); - } - } - return this.insertTextAfterPositionInBody(formatted, this.fileContent, targetPosition); - } - async createInsertAfterIfNotFound(formatted) { - var _a, _b; - const insertAfterLine = this.replaceLinebreakInString(await this.format(this.choice.insertAfter.after)); - const insertAfterLineAndFormatted = `${insertAfterLine}\n${formatted}`; - if (((_a = this.choice.insertAfter) === null || _a === void 0 ? void 0 : _a.createIfNotFoundLocation) === CREATE_IF_NOT_FOUND_TOP) { - const frontmatterEndPosition = this.file ? await this.getFrontmatterEndPosition(this.file) : -1; - return this.insertTextAfterPositionInBody(insertAfterLineAndFormatted, this.fileContent, frontmatterEndPosition); - } - if (((_b = this.choice.insertAfter) === null || _b === void 0 ? void 0 : _b.createIfNotFoundLocation) === CREATE_IF_NOT_FOUND_BOTTOM) { - return `${this.fileContent}\n${insertAfterLineAndFormatted}`; - } - } - async getFrontmatterEndPosition(file) { - const fileCache = await this.app.metadataCache.getFileCache(file); - if (!fileCache || !fileCache.frontmatter) { - log.logMessage("could not get frontmatter. Maybe there isn't any."); - return -1; - } - if (fileCache.frontmatter.position) - return fileCache.frontmatter.position.end.line; - return -1; - } - insertTextAfterPositionInBody(text, body, pos) { - if (pos === -1) { - return `${text}\n${body}`; - } - const splitContent = body.split("\n"); - const pre = splitContent.slice(0, pos + 1).join("\n"); - const post = splitContent.slice(pos + 1).join("\n"); - return `${pre}\n${text}${post}`; - } -} - -class CaptureChoiceEngine extends QuickAddChoiceEngine { - constructor(app, plugin, choice, choiceExecutor) { - super(app); - this.choiceExecutor = choiceExecutor; - this.choice = choice; - this.plugin = plugin; - this.formatter = new CaptureChoiceFormatter(app, plugin, choiceExecutor); - } - async run() { - var _a, _b, _c, _d; - try { - if ((_a = this.choice) === null || _a === void 0 ? void 0 : _a.captureToActiveFile) { - await this.captureToActiveFile(); - return; - } - const captureTo = this.choice.captureTo; - if (!captureTo) { - log.logError(`Invalid capture to for ${this.choice.name}`); - return; - } - const filePath = await this.getFilePath(captureTo); - let content = await this.getCaptureContent(); - let file; - if (await this.fileExists(filePath)) { - file = await this.getFileByPath(filePath); - if (!file) - return; - const fileContent = await this.app.vault.read(file); - const newFileContent = await this.formatter.formatContentWithFile(content, this.choice, fileContent, file); - await this.app.vault.modify(file, newFileContent); - } - else if ((_c = (_b = this.choice) === null || _b === void 0 ? void 0 : _b.createFileIfItDoesntExist) === null || _c === void 0 ? void 0 : _c.enabled) { - let fileContent = ""; - if (this.choice.createFileIfItDoesntExist.createWithTemplate) { - const singleTemplateEngine = new SingleTemplateEngine(this.app, this.plugin, this.choice.createFileIfItDoesntExist.template, this.choiceExecutor); - fileContent = await singleTemplateEngine.run(); - } - file = await this.createFileWithInput(filePath, fileContent); - await replaceTemplaterTemplatesInCreatedFile(this.app, file); - const updatedFileContent = await this.app.vault.cachedRead(file); - const newFileContent = await this.formatter.formatContentWithFile(content, this.choice, updatedFileContent, file); - await this.app.vault.modify(file, newFileContent); - } - else { - log.logWarning(`The file ${filePath} does not exist and "Create file if it doesn't exist" is disabled.`); - return; - } - if (this.choice.appendLink) - appendToCurrentLine(this.app.fileManager.generateMarkdownLink(file, ''), this.app); - if ((_d = this.choice) === null || _d === void 0 ? void 0 : _d.openFile) { - await openFile(this.app, file, { - openInNewTab: this.choice.openFileInNewTab.enabled, - direction: this.choice.openFileInNewTab.direction, - focus: this.choice.openFileInNewTab.focus, - mode: this.choice.openFileInMode - }); - } - } - catch (e) { - log.logMessage(e); - } - } - async getCaptureContent() { - let content; - if (!this.choice.format.enabled) - content = VALUE_SYNTAX; - else - content = this.choice.format.format; - if (this.choice.task) - content = `- [ ] ${content}\n`; - return content; - } - async getFilePath(captureTo) { - const formattedCaptureTo = await this.formatter.formatFileName(captureTo, this.choice.name); - return this.formatFilePath("", formattedCaptureTo); - } - async captureToActiveFile() { - const activeFile = this.app.workspace.getActiveFile(); - if (!activeFile) { - log.logError("Cannot capture to active file - no active file."); - } - let content = await this.getCaptureContent(); - content = await this.formatter.formatContent(content, this.choice); - if (this.choice.format.enabled) { - content = await templaterParseTemplate(this.app, content, activeFile); - } - if (!content) - return; - if (this.choice.prepend) { - const fileContent = await this.app.vault.cachedRead(activeFile); - const newFileContent = `${fileContent}${content}`; - await this.app.vault.modify(activeFile, newFileContent); - } - else { - appendToCurrentLine(content, this.app); - } - } -} - -class ChoiceExecutor { - constructor(app, plugin) { - this.app = app; - this.plugin = plugin; - this.variables = new Map(); - } - async execute(choice) { - switch (choice.type) { - case ChoiceType.Template: - const templateChoice = choice; - await this.onChooseTemplateType(templateChoice); - break; - case ChoiceType.Capture: - const captureChoice = choice; - await this.onChooseCaptureType(captureChoice); - break; - case ChoiceType.Macro: - const macroChoice = choice; - await this.onChooseMacroType(macroChoice); - break; - case ChoiceType.Multi: - const multiChoice = choice; - await this.onChooseMultiType(multiChoice); - break; - } - } - async onChooseTemplateType(templateChoice) { - if (!templateChoice.templatePath) { - log.logError(`please provide a template path for ${templateChoice.name}`); - return; - } - await new TemplateChoiceEngine(this.app, this.plugin, templateChoice, this).run(); - } - async onChooseCaptureType(captureChoice) { - if (!captureChoice.captureTo && !(captureChoice === null || captureChoice === void 0 ? void 0 : captureChoice.captureToActiveFile)) { - log.logError(`please provide a capture path for ${captureChoice.name}`); - return; - } - await new CaptureChoiceEngine(this.app, this.plugin, captureChoice, this).run(); - } - async onChooseMacroType(macroChoice) { - const macroEngine = await new MacroChoiceEngine(this.app, this.plugin, macroChoice, this.plugin.settings.macros, this, this.variables); - await macroEngine.run(); - Object.keys(macroEngine.params.variables).forEach(key => { - this.variables.set(key, macroEngine.params.variables[key]); - }); - } - async onChooseMultiType(multiChoice) { - ChoiceSuggester.Open(this.plugin, multiChoice.choices, this); - } -} - -class ChoiceSuggester extends obsidian.FuzzySuggestModal { - constructor(plugin, choices, choiceExecutor) { - super(plugin.app); - this.plugin = plugin; - this.choices = choices; - this.choiceExecutor = new ChoiceExecutor(this.app, this.plugin); - if (choiceExecutor) - this.choiceExecutor = choiceExecutor; - } - static Open(plugin, choices, choiceExecutor) { - new ChoiceSuggester(plugin, choices, choiceExecutor).open(); - } - getItemText(item) { - return item.name; - } - getItems() { - return this.choices; - } - async onChooseItem(item, evt) { - if (item.type === ChoiceType.Multi) - this.onChooseMultiType(item); - else - await this.choiceExecutor.execute(item); - } - onChooseMultiType(multi) { - const choices = [...multi.choices]; - if (multi.name != "← Back") - choices.push(new MultiChoice("← Back").addChoices(this.choices)); - ChoiceSuggester.Open(this.plugin, choices); - } -} - -var ErrorLevel; -(function (ErrorLevel) { - ErrorLevel["Error"] = "ERROR"; - ErrorLevel["Warning"] = "WARNING"; - ErrorLevel["Log"] = "LOG"; -})(ErrorLevel || (ErrorLevel = {})); - -class QuickAddLogger { - formatOutputString(error) { - return `QuickAdd: (${error.level}) ${error.message}`; - } - getQuickAddError(message, level) { - return { message, level, time: Date.now() }; - } -} - -class ConsoleErrorLogger extends QuickAddLogger { - constructor() { - super(...arguments); - this.ErrorLog = []; - } - logError(errorMsg) { - const error = this.getQuickAddError(errorMsg, ErrorLevel.Error); - this.addMessageToErrorLog(error); - console.error(this.formatOutputString(error)); - } - logWarning(warningMsg) { - const warning = this.getQuickAddError(warningMsg, ErrorLevel.Warning); - this.addMessageToErrorLog(warning); - console.warn(this.formatOutputString(warning)); - } - logMessage(logMsg) { - const log = this.getQuickAddError(logMsg, ErrorLevel.Log); - this.addMessageToErrorLog(log); - console.log(this.formatOutputString(log)); - } - addMessageToErrorLog(error) { - this.ErrorLog.push(error); - } -} - -class GuiLogger extends QuickAddLogger { - constructor(plugin) { - super(); - this.plugin = plugin; - } - logError(msg) { - const error = this.getQuickAddError(msg, ErrorLevel.Error); - new obsidian.Notice(this.formatOutputString(error)); - } - logWarning(msg) { - const warning = this.getQuickAddError(msg, ErrorLevel.Warning); - new obsidian.Notice(this.formatOutputString(warning)); - } - logMessage(msg) { } -} - -class StartupMacroEngine extends MacroChoiceEngine { - constructor(app, plugin, macros, choiceExecutor) { - super(app, plugin, null, macros, choiceExecutor, null); - } - async run() { - this.macros.forEach(macro => { - if (macro.runOnStartup) { - this.executeCommands(macro.commands); - } - }); - } -} - -class QuickAdd extends obsidian.Plugin { - async onload() { - console.log('Loading QuickAdd'); - QuickAdd.instance = this; - await this.loadSettings(); - this.addCommand({ - id: 'runQuickAdd', - name: 'Run QuickAdd', - callback: () => { - ChoiceSuggester.Open(this, this.settings.choices); - } - }); - log.register(new ConsoleErrorLogger()) - .register(new GuiLogger(this)); - this.addSettingTab(new QuickAddSettingsTab(this.app, this)); - this.app.workspace.onLayoutReady(() => new StartupMacroEngine(this.app, this, this.settings.macros, new ChoiceExecutor(this.app, this)).run()); - this.addCommandsForChoices(this.settings.choices); - await this.convertMacroChoicesMacroToId(); - } - onunload() { - console.log('Unloading QuickAdd'); - } - async loadSettings() { - this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); - } - async saveSettings() { - await this.saveData(this.settings); - } - addCommandsForChoices(choices) { - choices.forEach(choice => this.addCommandForChoice(choice)); - } - addCommandForChoice(choice) { - if (choice.type === ChoiceType.Multi) { - this.addCommandsForChoices(choice.choices); - } - if (choice.command) { - this.addCommand({ - id: `choice:${choice.id}`, - name: choice.name, - callback: async () => { - await new ChoiceExecutor(this.app, this).execute(choice); - } - }); - } - } - getChoiceById(choiceId) { - return this.getChoice("id", choiceId); - } - getChoiceByName(choiceName) { - return this.getChoice("name", choiceName); - } - getChoice(by, targetPropertyValue) { - let tempChoice; - const findChoice = (choice) => { - if (choice[by] === targetPropertyValue) { - tempChoice = choice; - return tempChoice; - } - if (choice.type === ChoiceType.Multi) - choice.choices.forEach(findChoice); - }; - this.settings.choices.forEach(findChoice); - return tempChoice; - } - removeCommandForChoice(choice) { - deleteObsidianCommand(this.app, `quickadd:choice:${choice.id}`); - } - // Did not make sense to have copies of macros in the choices when they are maintained for themselves. - // Instead we reference by id now. Have to port this over for all users. - async convertMacroChoicesMacroToId() { - function convertMacroChoiceMacroToIdHelper(choice) { - if (choice.type === ChoiceType.Multi) { - let multiChoice = choice; - const multiChoices = multiChoice.choices.map(convertMacroChoiceMacroToIdHelper); - multiChoice = Object.assign(Object.assign({}, multiChoice), { choices: multiChoices }); - return multiChoice; - } - if (choice.type !== ChoiceType.Macro) - return choice; - const macroChoice = choice; - if (macroChoice.macro) { - macroChoice.macroId = macroChoice.macro.id; - delete macroChoice.macro; - } - return macroChoice; - } - this.settings.choices = this.settings.choices.map(convertMacroChoiceMacroToIdHelper); - await this.saveSettings(); - } -} - -module.exports = QuickAdd; diff --git a/.obsidian/plugins/quickadd/manifest.json b/.obsidian/plugins/quickadd/manifest.json deleted file mode 100644 index 9d9322f..0000000 --- a/.obsidian/plugins/quickadd/manifest.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "id": "quickadd", - "name": "QuickAdd", - "version": "0.4.8", - "minAppVersion": "0.12.5", - "description": "Quickly add new pages or content to your vault.", - "author": "Christian B. B. Houmann", - "authorUrl": "https://bagerbach.com", - "isDesktopOnly": false -} diff --git a/.obsidian/plugins/quickadd/styles.css b/.obsidian/plugins/quickadd/styles.css deleted file mode 100644 index 248d31e..0000000 --- a/.obsidian/plugins/quickadd/styles.css +++ /dev/null @@ -1,168 +0,0 @@ -.configureMacroDiv { - display: grid; - grid-template-rows: 1fr; - min-width: 12rem; -} - -.configureMacroDivItem { - display: flex; - align-content: center; - justify-content: space-between; - margin-bottom: 10px; -} - -.configureMacroDivItemButton { - display: flex; - align-content: center; - justify-content: center; - margin-bottom: 10px; -} - -.macroContainer { - display: grid; - grid-template-rows: repeat(auto-fill, 120px); - grid-gap: 40px; - - overflow-y: auto; - max-height: 30em; - padding: 2em; -} - -/* Mobile */ -@media screen and (max-width: 540px){ - .macroContainer1 { - grid-template-columns: repeat(1, 1fr); - } - - .macroContainer2 { - grid-template-columns: repeat(1, 1fr); - } - - .macroContainer3 { - grid-template-columns: repeat(1, 1fr); - } -} - -/* Tablet */ -@media screen and (max-width: 540px) and (max-width: 780px) { - .macroContainer1 { - grid-template-columns: repeat(1, 1fr); - } - - .macroContainer2 { - grid-template-columns: repeat(2, 1fr); - } - - .macroContainer3 { - grid-template-columns: repeat(2, 1fr); - } -} - -/* Everything else */ -@media screen and (min-width: 781px){ - .macroContainer1 { - grid-template-columns: repeat(1, 1fr); - } - - .macroContainer2 { - grid-template-columns: repeat(2, 1fr); - } - - .macroContainer3 { - grid-template-columns: repeat(3, 1fr); - } -} - -.addMacroBarContainer { - display: flex; - align-content: center; - justify-content: space-around; - margin-top: 20px; -} - -.captureToActiveFileContainer { - display: flex; - align-content: center; - justify-content: space-between; - margin-bottom: 10px; -} - -.choiceNameHeader { - text-align: center; -} - -.choiceNameHeader:hover { - cursor: pointer; -} - -.folderInputContainer { - display: flex; - align-content: center; - justify-content: space-between; - margin-bottom: 8px; - gap: 4px; -} - -.selectMacroDropdownContainer { - display: flex; - align-content: center; - justify-content: center; -} - -.quickAddModal .modal { - min-width: 35%; - overflow-y: auto; - max-height: 70%; -} - -.checkboxRowContainer { - display: grid; - grid-template-rows: auto; - align-content: center; -} - -.checkboxRow { - display: flex; - justify-content: space-between; - align-content: center; -} - -.checkboxRow .checkbox-container { - flex-shrink: 0; -} - -.checkboxRow span { - font-size: 16px; - word-break: break-all; -} - -.submitButtonContainer { - display: flex; - align-content: center; - justify-content: center; -} - -.chooseFolderWhenCreatingNoteContainer { - display: flex; - align-content: center; - justify-content: space-between; - margin-bottom: 10px; -} - -.clickable:hover { - cursor: pointer; -} - -.quickAddCommandListItem { - display: flex; - flex: 1 1 auto; - align-items: center; - justify-content: space-between; -} - -.quickCommandContainer { - display: flex; - justify-content: flex-end; - align-content: center; - margin-bottom: 1em; -} \ No newline at end of file diff --git a/.obsidian/plugins/tag-wrangler/main.js b/.obsidian/plugins/tag-wrangler/main.js new file mode 100644 index 0000000..e2cc2fa --- /dev/null +++ b/.obsidian/plugins/tag-wrangler/main.js @@ -0,0 +1,7381 @@ +'use strict'; + +var obsidian = require('obsidian'); + +const f = (fn) => [ + /*eslint no-unused-vars: 0*/ + function (a) {return fn(...arguments);}, + function (a, b) {return fn(...arguments);}, + function (a, b, c) {return fn(...arguments);}, + function (a, b, c, d) {return fn(...arguments);}, + function (a, b, c, d, e) {return fn(...arguments);}, +]; + +const currify = (fn, ...args) => { + check(fn); + + if (args.length >= fn.length) + return fn(...args); + + const again = (...args2) => { + return currify(fn, ...[...args, ...args2]); + }; + + const count = fn.length - args.length - 1; + const func = f(again)[count]; + + return func || again; +}; + +var currify_1 = currify; + +function check(fn) { + if (typeof fn !== 'function') + throw Error('fn should be function!'); +} + +var fullstore = (value) => { + const data = { + value, + }; + + return (...args) => { + const [value] = args; + + if (!args.length) + return data.value; + + data.value = value; + + return value; + }; +}; + +const query = (a) => document.querySelector(`[data-name="${a}"]`); + +const setAttribute = currify_1((el, obj, name) => el.setAttribute(name, obj[name])); +const set = currify_1((el, obj, name) => el[name] = obj[name]); +const not = currify_1((f, a) => !f(a)); +const isCamelCase = (a) => a != a.toLowerCase(); + +var createElement = (name, options = {}) => { + const { + dataName, + notAppend, + parent = document.body, + uniq = true, + ...restOptions + } = options; + + const elFound = isElementPresent(dataName); + + if (uniq && elFound) + return elFound; + + const el = document.createElement(name); + + if (dataName) + el.dataset.name = dataName; + + Object.keys(restOptions) + .filter(isCamelCase) + .map(set(el, options)); + + Object.keys(restOptions) + .filter(not(isCamelCase)) + .map(setAttribute(el, options)); + + if (!notAppend) + parent.appendChild(el); + + return el; +}; + +var isElementPresent_1 = isElementPresent; + +function isElementPresent(dataName) { + if (!dataName) + return; + + return query(dataName); +} +createElement.isElementPresent = isElementPresent_1; + +const keyDown = currify_1(keyDown_); + +const BUTTON_OK_CANCEL = { + ok: 'OK', + cancel: 'Cancel', +}; + +const zIndex = fullstore(100); + +var prompt = (title, msg, value = '', options) => { + const type = getType(options); + const val = String(value) + .replace(/"/g, '"'); + + const valueStr = ``; + const buttons = getButtons(options) || BUTTON_OK_CANCEL; + + return showDialog(title, msg, valueStr, buttons, options); +}; + +var confirm = (title, msg, options) => { + const buttons = getButtons(options) || BUTTON_OK_CANCEL; + + return showDialog(title, msg, '', buttons, options); +}; + +var progress = (title, message, options) => { + const valueStr = ` + + 0% + `; + + const buttons = { + cancel: 'Abort', + }; + + const promise = showDialog(title, message, valueStr, buttons, options); + const {ok, dialog} = promise; + const resolve = ok(); + + find(dialog, ['cancel']).map((el) => { + el.focus(); + }); + + Object.assign(promise, { + setProgress(count) { + const [elProgress] = find(dialog, ['progress']); + const [elCounter] = find(dialog, ['counter']); + + elProgress.value = count; + elCounter.textContent = `${count}%`; + + if (count === 100) { + remove(dialog); + resolve(); + } + }, + + remove() { + remove(dialog); + }, + }); + + return promise; +}; + +function getButtons(options = {}) { + const {buttons} = options; + + if (!buttons) + return null; + + return buttons; +} + +function getType(options = {}) { + const {type} = options; + + if (type === 'password') + return 'password'; + + return 'text'; +} + +function getTemplate(title, msg, value, buttons) { + const encodedMsg = msg.replace(/\n/g, '
'); + + return `
+
+
${ title }
+
${ encodedMsg }${ value }
+
+
+ ${parseButtons(buttons)} +
+
+
`; +} + +function parseButtons(buttons) { + const names = Object.keys(buttons); + const parse = currify_1((buttons, name, i) => ``); + + return names + .map(parse(buttons)) + .join(''); +} + +function showDialog(title, msg, value, buttons, options) { + const ok = fullstore(); + const cancel = fullstore(); + + const closeButtons = [ + 'cancel', + 'close', + 'ok', + ]; + + const promise = new Promise((resolve, reject) => { + const noCancel = options && options.cancel === false; + const empty = () => {}; + const rejectError = () => reject(Error()); + + ok(resolve); + cancel(noCancel ? empty : rejectError); + }); + + const innerHTML = getTemplate(title, msg, value, buttons); + + const dialog = createElement('div', { + innerHTML, + className: 'smalltalk', + style: `z-index: ${zIndex(zIndex() + 1)}`, + }); + + for (const el of find(dialog, ['ok', 'input'])) + el.focus(); + + for (const el of find(dialog, ['input'])) { + el.setSelectionRange(0, value.length); + } + + addListenerAll('click', dialog, closeButtons, (event) => { + closeDialog(event.target, dialog, ok(), cancel()); + }); + + for (const event of ['click', 'contextmenu']) + dialog.addEventListener(event, (e) => { + e.stopPropagation(); + for (const el of find(dialog, ['ok', 'input'])) + el.focus(); + }); + + dialog.addEventListener('keydown', keyDown(dialog, ok(), cancel())); + + return Object.assign(promise, { + dialog, + ok, + }); +} + +function keyDown_(dialog, ok, cancel, event) { + const KEY = { + ENTER : 13, + ESC : 27, + TAB : 9, + LEFT : 37, + UP : 38, + RIGHT : 39, + DOWN : 40, + }; + + const {keyCode} = event; + const el = event.target; + + const namesAll = ['ok', 'cancel', 'input']; + const names = find(dialog, namesAll) + .map(getDataName); + + switch(keyCode) { + case KEY.ENTER: + closeDialog(el, dialog, ok, cancel); + event.preventDefault(); + break; + + case KEY.ESC: + remove(dialog); + cancel(); + break; + + case KEY.TAB: + if (event.shiftKey) + tab(dialog, names); + + tab(dialog, names); + event.preventDefault(); + break; + + default: + ['left', 'right', 'up', 'down'].filter((name) => { + return keyCode === KEY[name.toUpperCase()]; + }).forEach(() => { + changeButtonFocus(dialog, names); + }); + + break; + } + + event.stopPropagation(); +} + +function getDataName(el) { + return el + .getAttribute('data-name') + .replace('js-', ''); +} + +const getName = (activeName) => { + if (activeName === 'cancel') + return 'ok'; + + return 'cancel'; +}; + +function changeButtonFocus(dialog, names) { + const active = document.activeElement; + const activeName = getDataName(active); + const isButton = /ok|cancel/.test(activeName); + const count = names.length - 1; + + if (activeName === 'input' || !count || !isButton) + return; + + const name = getName(activeName); + + for (const el of find(dialog, [name])) { + el.focus(); + } +} + +const getIndex = (count, index) => { + if (index === count) + return 0; + + return index + 1; +}; + +function tab(dialog, names) { + const active = document.activeElement; + const activeName = getDataName(active); + const count = names.length - 1; + + const activeIndex = names.indexOf(activeName); + const index = getIndex(count, activeIndex); + + const name = names[index]; + + for (const el of find(dialog, [name])) + el.focus(); +} + +function closeDialog(el, dialog, ok, cancel) { + const name = el + .getAttribute('data-name') + .replace('js-', ''); + + if (/close|cancel/.test(name)) { + cancel(); + remove(dialog); + return; + } + + const value = find(dialog, ['input']) + .reduce((value, el) => el.value, null); + + ok(value); + remove(dialog); +} + +const query$1 = currify_1((element, name) => element.querySelector(`[data-name="js-${ name }"]`)); + +function find(element, names) { + const elements = names + .map(query$1(element)) + .filter(Boolean); + + return elements; +} + +function addListenerAll(event, parent, elements, fn) { + for (const el of find(parent, elements)) { + el.addEventListener(event, fn); + } +} + +function remove(dialog) { + const {parentElement} = dialog; + + if (parentElement) + parentElement.removeChild(dialog); +} + +class Progress { + + constructor(title, message) { + this.progress = progress(title, message); + this.progress.catch(e => { + this.aborted = true; + if (e && (e.constructor !== Error || e.message !== "")) console.error(e); + }); + this.dialog = this.progress.dialog; + this.aborted = false; + } + + async forEach(collection, func) { + try { + if (this.aborted) + return; + let processed = 0, range = collection.length, accum = 0, pct = 0; + for (const item of collection) { + await func(item, processed++, collection, this); + if (this.aborted) + return; + accum += 100; + if (accum > range) { + const remainder = accum % range, step = (accum - remainder) / range; + this.progress.setProgress(pct += step); + accum = remainder; + } + } + if (pct < 100) + this.progress.setProgress(100); + return this; + } finally { + this.progress.remove(); + } + } + + set title(text) { this.dialog.querySelector("header").textContent = text; } + get title() { return this.dialog.querySelector("header").textContent; } + + set message(text) { + this.dialog.querySelector(".content-area").childNodes[0].textContent = text; + } + + get message() { + return this.dialog.querySelector(".content-area").childNodes[0].textContent; + } +} + +async function validatedInput(title, message, value = "", regex = ".*", what = "entry") { + while (true) { + const input = prompt(title, message, value); + const inputField = input.dialog.find("input"); + const isValid = (t) => new RegExp(`^${regex}$`).test(t); + + inputField.setSelectionRange(value.length, value.length); + inputField.pattern = regex; + inputField.oninput = () => inputField.setAttribute("aria-invalid", !isValid(inputField.value)); + + const result = await input; + if (isValid(result)) return result; + + new obsidian.Notice(`"${result}" is not a valid ${what}`); + } +} + +class Tag { + constructor(name) { + while (name.startsWith("#")) name = name.slice(1); + this.name = name; + const + hashed = this.tag = "#" + name, + canonical = this.canonical = hashed.toLowerCase(), + canonical_prefix = this.canonical_prefix = canonical + "/"; + this.matches = function (text) { + text = text.toLowerCase(); + return text == canonical || text.startsWith(canonical_prefix); + }; + } + toString() { return this.tag; } +} + +class Replacement { + + constructor(fromTag, toTag) { + const cache = Object.assign( + Object.create(null), { + [fromTag.tag]: toTag.tag, + [fromTag.name]: toTag.name, + } + ); + + this.inString = function(text, pos = 0) { + return text.slice(0, pos) + toTag.tag + text.slice(pos + fromTag.tag.length); + }; + + this.inArray = (tags, skipOdd) => { + return tags.map((t, i) => { + if (skipOdd && (i & 1)) return t; // leave odd entries (separators) alone + // Obsidian allows spaces as separators within array elements + if (t.contains(" ")) return this.inArray(t.split(/( +)/), true).join(""); + if (!t) return t; + if (cache[t]) return cache[t]; + const lc = t.toLowerCase(); + if (cache[lc]) { + return cache[t] = cache[lc]; + } else if (lc.startsWith(fromTag.canonical_prefix)) { + return cache[t] = cache[lc] = this.inString(t); + } else if (("#" + lc).startsWith(fromTag.canonical_prefix)) { + return cache[t] = cache[lc] = this.inString("#" + t).slice(1); + } + return cache[t] = cache[lc] = t; + }); + }; + + this.willMergeTags = function (tagNames) { + // Renaming to change case doesn't lose info, so ignore it + if (fromTag.canonical === toTag.canonical) return; + + const existing = new Set(tagNames.map(s => s.toLowerCase())); + + for (const tagName of tagNames.filter(fromTag.matches)) { + const changed = this.inString(tagName); + if (existing.has(changed.toLowerCase())) + return [new Tag(tagName), new Tag(changed)]; + } + + }; + } +} + +const Char = { + ANCHOR: '&', + COMMENT: '#', + TAG: '!', + DIRECTIVES_END: '-', + DOCUMENT_END: '.' +}; +const LogLevel = Object.assign(['silent', 'error', 'warn', 'debug'], { + SILENT: 0, + ERROR: 1, + WARN: 2, + DEBUG: 3 +}); +const Type = { + ALIAS: 'ALIAS', + BLANK_LINE: 'BLANK_LINE', + BLOCK_FOLDED: 'BLOCK_FOLDED', + BLOCK_LITERAL: 'BLOCK_LITERAL', + COMMENT: 'COMMENT', + DIRECTIVE: 'DIRECTIVE', + DOCUMENT: 'DOCUMENT', + FLOW_MAP: 'FLOW_MAP', + FLOW_SEQ: 'FLOW_SEQ', + MAP: 'MAP', + MAP_KEY: 'MAP_KEY', + MAP_VALUE: 'MAP_VALUE', + PLAIN: 'PLAIN', + QUOTE_DOUBLE: 'QUOTE_DOUBLE', + QUOTE_SINGLE: 'QUOTE_SINGLE', + SEQ: 'SEQ', + SEQ_ITEM: 'SEQ_ITEM' +}; +const defaultTagPrefix = 'tag:yaml.org,2002:'; +const defaultTags = { + MAP: 'tag:yaml.org,2002:map', + SEQ: 'tag:yaml.org,2002:seq', + STR: 'tag:yaml.org,2002:str' +}; + +function findLineStarts(src) { + const ls = [0]; + let offset = src.indexOf('\n'); + + while (offset !== -1) { + offset += 1; + ls.push(offset); + offset = src.indexOf('\n', offset); + } + + return ls; +} + +function getSrcInfo(cst) { + let lineStarts, src; + + if (typeof cst === 'string') { + lineStarts = findLineStarts(cst); + src = cst; + } else { + if (Array.isArray(cst)) cst = cst[0]; + + if (cst && cst.context) { + if (!cst.lineStarts) cst.lineStarts = findLineStarts(cst.context.src); + lineStarts = cst.lineStarts; + src = cst.context.src; + } + } + + return { + lineStarts, + src + }; +} +/** + * @typedef {Object} LinePos - One-indexed position in the source + * @property {number} line + * @property {number} col + */ + +/** + * Determine the line/col position matching a character offset. + * + * Accepts a source string or a CST document as the second parameter. With + * the latter, starting indices for lines are cached in the document as + * `lineStarts: number[]`. + * + * Returns a one-indexed `{ line, col }` location if found, or + * `undefined` otherwise. + * + * @param {number} offset + * @param {string|Document|Document[]} cst + * @returns {?LinePos} + */ + + +function getLinePos(offset, cst) { + if (typeof offset !== 'number' || offset < 0) return null; + const { + lineStarts, + src + } = getSrcInfo(cst); + if (!lineStarts || !src || offset > src.length) return null; + + for (let i = 0; i < lineStarts.length; ++i) { + const start = lineStarts[i]; + + if (offset < start) { + return { + line: i, + col: offset - lineStarts[i - 1] + 1 + }; + } + + if (offset === start) return { + line: i + 1, + col: 1 + }; + } + + const line = lineStarts.length; + return { + line, + col: offset - lineStarts[line - 1] + 1 + }; +} +/** + * Get a specified line from the source. + * + * Accepts a source string or a CST document as the second parameter. With + * the latter, starting indices for lines are cached in the document as + * `lineStarts: number[]`. + * + * Returns the line as a string if found, or `null` otherwise. + * + * @param {number} line One-indexed line number + * @param {string|Document|Document[]} cst + * @returns {?string} + */ + +function getLine(line, cst) { + const { + lineStarts, + src + } = getSrcInfo(cst); + if (!lineStarts || !(line >= 1) || line > lineStarts.length) return null; + const start = lineStarts[line - 1]; + let end = lineStarts[line]; // undefined for last line; that's ok for slice() + + while (end && end > start && src[end - 1] === '\n') --end; + + return src.slice(start, end); +} +/** + * Pretty-print the starting line from the source indicated by the range `pos` + * + * Trims output to `maxWidth` chars while keeping the starting column visible, + * using `…` at either end to indicate dropped characters. + * + * Returns a two-line string (or `null`) with `\n` as separator; the second line + * will hold appropriately indented `^` marks indicating the column range. + * + * @param {Object} pos + * @param {LinePos} pos.start + * @param {LinePos} [pos.end] + * @param {string|Document|Document[]*} cst + * @param {number} [maxWidth=80] + * @returns {?string} + */ + +function getPrettyContext({ + start, + end +}, cst, maxWidth = 80) { + let src = getLine(start.line, cst); + if (!src) return null; + let { + col + } = start; + + if (src.length > maxWidth) { + if (col <= maxWidth - 10) { + src = src.substr(0, maxWidth - 1) + '…'; + } else { + const halfWidth = Math.round(maxWidth / 2); + if (src.length > col + halfWidth) src = src.substr(0, col + halfWidth - 1) + '…'; + col -= src.length - maxWidth; + src = '…' + src.substr(1 - maxWidth); + } + } + + let errLen = 1; + let errEnd = ''; + + if (end) { + if (end.line === start.line && col + (end.col - start.col) <= maxWidth + 1) { + errLen = end.col - start.col; + } else { + errLen = Math.min(src.length + 1, maxWidth) - col; + errEnd = '…'; + } + } + + const offset = col > 1 ? ' '.repeat(col - 1) : ''; + const err = '^'.repeat(errLen); + return "".concat(src, "\n").concat(offset).concat(err).concat(errEnd); +} + +class Range { + static copy(orig) { + return new Range(orig.start, orig.end); + } + + constructor(start, end) { + this.start = start; + this.end = end || start; + } + + isEmpty() { + return typeof this.start !== 'number' || !this.end || this.end <= this.start; + } + /** + * Set `origStart` and `origEnd` to point to the original source range for + * this node, which may differ due to dropped CR characters. + * + * @param {number[]} cr - Positions of dropped CR characters + * @param {number} offset - Starting index of `cr` from the last call + * @returns {number} - The next offset, matching the one found for `origStart` + */ + + + setOrigRange(cr, offset) { + const { + start, + end + } = this; + + if (cr.length === 0 || end <= cr[0]) { + this.origStart = start; + this.origEnd = end; + return offset; + } + + let i = offset; + + while (i < cr.length) { + if (cr[i] > start) break;else ++i; + } + + this.origStart = start + i; + const nextOffset = i; + + while (i < cr.length) { + // if end was at \n, it should now be at \r + if (cr[i] >= end) break;else ++i; + } + + this.origEnd = end + i; + return nextOffset; + } + +} + +/** Root class of all nodes */ + +class Node { + static addStringTerminator(src, offset, str) { + if (str[str.length - 1] === '\n') return str; + const next = Node.endOfWhiteSpace(src, offset); + return next >= src.length || src[next] === '\n' ? str + '\n' : str; + } // ^(---|...) + + + static atDocumentBoundary(src, offset, sep) { + const ch0 = src[offset]; + if (!ch0) return true; + const prev = src[offset - 1]; + if (prev && prev !== '\n') return false; + + if (sep) { + if (ch0 !== sep) return false; + } else { + if (ch0 !== Char.DIRECTIVES_END && ch0 !== Char.DOCUMENT_END) return false; + } + + const ch1 = src[offset + 1]; + const ch2 = src[offset + 2]; + if (ch1 !== ch0 || ch2 !== ch0) return false; + const ch3 = src[offset + 3]; + return !ch3 || ch3 === '\n' || ch3 === '\t' || ch3 === ' '; + } + + static endOfIdentifier(src, offset) { + let ch = src[offset]; + const isVerbatim = ch === '<'; + const notOk = isVerbatim ? ['\n', '\t', ' ', '>'] : ['\n', '\t', ' ', '[', ']', '{', '}', ',']; + + while (ch && notOk.indexOf(ch) === -1) ch = src[offset += 1]; + + if (isVerbatim && ch === '>') offset += 1; + return offset; + } + + static endOfIndent(src, offset) { + let ch = src[offset]; + + while (ch === ' ') ch = src[offset += 1]; + + return offset; + } + + static endOfLine(src, offset) { + let ch = src[offset]; + + while (ch && ch !== '\n') ch = src[offset += 1]; + + return offset; + } + + static endOfWhiteSpace(src, offset) { + let ch = src[offset]; + + while (ch === '\t' || ch === ' ') ch = src[offset += 1]; + + return offset; + } + + static startOfLine(src, offset) { + let ch = src[offset - 1]; + if (ch === '\n') return offset; + + while (ch && ch !== '\n') ch = src[offset -= 1]; + + return offset + 1; + } + /** + * End of indentation, or null if the line's indent level is not more + * than `indent` + * + * @param {string} src + * @param {number} indent + * @param {number} lineStart + * @returns {?number} + */ + + + static endOfBlockIndent(src, indent, lineStart) { + const inEnd = Node.endOfIndent(src, lineStart); + + if (inEnd > lineStart + indent) { + return inEnd; + } else { + const wsEnd = Node.endOfWhiteSpace(src, inEnd); + const ch = src[wsEnd]; + if (!ch || ch === '\n') return wsEnd; + } + + return null; + } + + static atBlank(src, offset, endAsBlank) { + const ch = src[offset]; + return ch === '\n' || ch === '\t' || ch === ' ' || endAsBlank && !ch; + } + + static nextNodeIsIndented(ch, indentDiff, indicatorAsIndent) { + if (!ch || indentDiff < 0) return false; + if (indentDiff > 0) return true; + return indicatorAsIndent && ch === '-'; + } // should be at line or string end, or at next non-whitespace char + + + static normalizeOffset(src, offset) { + const ch = src[offset]; + return !ch ? offset : ch !== '\n' && src[offset - 1] === '\n' ? offset - 1 : Node.endOfWhiteSpace(src, offset); + } // fold single newline into space, multiple newlines to N - 1 newlines + // presumes src[offset] === '\n' + + + static foldNewline(src, offset, indent) { + let inCount = 0; + let error = false; + let fold = ''; + let ch = src[offset + 1]; + + while (ch === ' ' || ch === '\t' || ch === '\n') { + switch (ch) { + case '\n': + inCount = 0; + offset += 1; + fold += '\n'; + break; + + case '\t': + if (inCount <= indent) error = true; + offset = Node.endOfWhiteSpace(src, offset + 2) - 1; + break; + + case ' ': + inCount += 1; + offset += 1; + break; + } + + ch = src[offset + 1]; + } + + if (!fold) fold = ' '; + if (ch && inCount <= indent) error = true; + return { + fold, + offset, + error + }; + } + + constructor(type, props, context) { + Object.defineProperty(this, 'context', { + value: context || null, + writable: true + }); + this.error = null; + this.range = null; + this.valueRange = null; + this.props = props || []; + this.type = type; + this.value = null; + } + + getPropValue(idx, key, skipKey) { + if (!this.context) return null; + const { + src + } = this.context; + const prop = this.props[idx]; + return prop && src[prop.start] === key ? src.slice(prop.start + (skipKey ? 1 : 0), prop.end) : null; + } + + get anchor() { + for (let i = 0; i < this.props.length; ++i) { + const anchor = this.getPropValue(i, Char.ANCHOR, true); + if (anchor != null) return anchor; + } + + return null; + } + + get comment() { + const comments = []; + + for (let i = 0; i < this.props.length; ++i) { + const comment = this.getPropValue(i, Char.COMMENT, true); + if (comment != null) comments.push(comment); + } + + return comments.length > 0 ? comments.join('\n') : null; + } + + commentHasRequiredWhitespace(start) { + const { + src + } = this.context; + if (this.header && start === this.header.end) return false; + if (!this.valueRange) return false; + const { + end + } = this.valueRange; + return start !== end || Node.atBlank(src, end - 1); + } + + get hasComment() { + if (this.context) { + const { + src + } = this.context; + + for (let i = 0; i < this.props.length; ++i) { + if (src[this.props[i].start] === Char.COMMENT) return true; + } + } + + return false; + } + + get hasProps() { + if (this.context) { + const { + src + } = this.context; + + for (let i = 0; i < this.props.length; ++i) { + if (src[this.props[i].start] !== Char.COMMENT) return true; + } + } + + return false; + } + + get includesTrailingLines() { + return false; + } + + get jsonLike() { + const jsonLikeTypes = [Type.FLOW_MAP, Type.FLOW_SEQ, Type.QUOTE_DOUBLE, Type.QUOTE_SINGLE]; + return jsonLikeTypes.indexOf(this.type) !== -1; + } + + get rangeAsLinePos() { + if (!this.range || !this.context) return undefined; + const start = getLinePos(this.range.start, this.context.root); + if (!start) return undefined; + const end = getLinePos(this.range.end, this.context.root); + return { + start, + end + }; + } + + get rawValue() { + if (!this.valueRange || !this.context) return null; + const { + start, + end + } = this.valueRange; + return this.context.src.slice(start, end); + } + + get tag() { + for (let i = 0; i < this.props.length; ++i) { + const tag = this.getPropValue(i, Char.TAG, false); + + if (tag != null) { + if (tag[1] === '<') { + return { + verbatim: tag.slice(2, -1) + }; + } else { + // eslint-disable-next-line no-unused-vars + const [_, handle, suffix] = tag.match(/^(.*!)([^!]*)$/); + return { + handle, + suffix + }; + } + } + } + + return null; + } + + get valueRangeContainsNewline() { + if (!this.valueRange || !this.context) return false; + const { + start, + end + } = this.valueRange; + const { + src + } = this.context; + + for (let i = start; i < end; ++i) { + if (src[i] === '\n') return true; + } + + return false; + } + + parseComment(start) { + const { + src + } = this.context; + + if (src[start] === Char.COMMENT) { + const end = Node.endOfLine(src, start + 1); + const commentRange = new Range(start, end); + this.props.push(commentRange); + return end; + } + + return start; + } + /** + * Populates the `origStart` and `origEnd` values of all ranges for this + * node. Extended by child classes to handle descendant nodes. + * + * @param {number[]} cr - Positions of dropped CR characters + * @param {number} offset - Starting index of `cr` from the last call + * @returns {number} - The next offset, matching the one found for `origStart` + */ + + + setOrigRanges(cr, offset) { + if (this.range) offset = this.range.setOrigRange(cr, offset); + if (this.valueRange) this.valueRange.setOrigRange(cr, offset); + this.props.forEach(prop => prop.setOrigRange(cr, offset)); + return offset; + } + + toString() { + const { + context: { + src + }, + range, + value + } = this; + if (value != null) return value; + const str = src.slice(range.start, range.end); + return Node.addStringTerminator(src, range.end, str); + } + +} + +class YAMLError extends Error { + constructor(name, source, message) { + if (!message || !(source instanceof Node)) throw new Error("Invalid arguments for new ".concat(name)); + super(); + this.name = name; + this.message = message; + this.source = source; + } + + makePretty() { + if (!this.source) return; + this.nodeType = this.source.type; + const cst = this.source.context && this.source.context.root; + + if (typeof this.offset === 'number') { + this.range = new Range(this.offset, this.offset + 1); + const start = cst && getLinePos(this.offset, cst); + + if (start) { + const end = { + line: start.line, + col: start.col + 1 + }; + this.linePos = { + start, + end + }; + } + + delete this.offset; + } else { + this.range = this.source.range; + this.linePos = this.source.rangeAsLinePos; + } + + if (this.linePos) { + const { + line, + col + } = this.linePos.start; + this.message += " at line ".concat(line, ", column ").concat(col); + const ctx = cst && getPrettyContext(this.linePos, cst); + if (ctx) this.message += ":\n\n".concat(ctx, "\n"); + } + + delete this.source; + } + +} +class YAMLReferenceError extends YAMLError { + constructor(source, message) { + super('YAMLReferenceError', source, message); + } + +} +class YAMLSemanticError extends YAMLError { + constructor(source, message) { + super('YAMLSemanticError', source, message); + } + +} +class YAMLSyntaxError extends YAMLError { + constructor(source, message) { + super('YAMLSyntaxError', source, message); + } + +} +class YAMLWarning extends YAMLError { + constructor(source, message) { + super('YAMLWarning', source, message); + } + +} + +class BlankLine extends Node { + constructor() { + super(Type.BLANK_LINE); + } + /* istanbul ignore next */ + + + get includesTrailingLines() { + // This is never called from anywhere, but if it were, + // this is the value it should return. + return true; + } + /** + * Parses a blank line from the source + * + * @param {ParseContext} context + * @param {number} start - Index of first \n character + * @returns {number} - Index of the character after this + */ + + + parse(context, start) { + this.context = context; + this.range = new Range(start, start + 1); + return start + 1; + } + +} + +class CollectionItem extends Node { + constructor(type, props) { + super(type, props); + this.node = null; + } + + get includesTrailingLines() { + return !!this.node && this.node.includesTrailingLines; + } + /** + * @param {ParseContext} context + * @param {number} start - Index of first character + * @returns {number} - Index of the character after this + */ + + + parse(context, start) { + this.context = context; + const { + parseNode, + src + } = context; + let { + atLineStart, + lineStart + } = context; + if (!atLineStart && this.type === Type.SEQ_ITEM) this.error = new YAMLSemanticError(this, 'Sequence items must not have preceding content on the same line'); + const indent = atLineStart ? start - lineStart : context.indent; + let offset = Node.endOfWhiteSpace(src, start + 1); + let ch = src[offset]; + const inlineComment = ch === '#'; + const comments = []; + let blankLine = null; + + while (ch === '\n' || ch === '#') { + if (ch === '#') { + const end = Node.endOfLine(src, offset + 1); + comments.push(new Range(offset, end)); + offset = end; + } else { + atLineStart = true; + lineStart = offset + 1; + const wsEnd = Node.endOfWhiteSpace(src, lineStart); + + if (src[wsEnd] === '\n' && comments.length === 0) { + blankLine = new BlankLine(); + lineStart = blankLine.parse({ + src + }, lineStart); + } + + offset = Node.endOfIndent(src, lineStart); + } + + ch = src[offset]; + } + + if (Node.nextNodeIsIndented(ch, offset - (lineStart + indent), this.type !== Type.SEQ_ITEM)) { + this.node = parseNode({ + atLineStart, + inCollection: false, + indent, + lineStart, + parent: this + }, offset); + } else if (ch && lineStart > start + 1) { + offset = lineStart - 1; + } + + if (this.node) { + if (blankLine) { + // Only blank lines preceding non-empty nodes are captured. Note that + // this means that collection item range start indices do not always + // increase monotonically. -- eemeli/yaml#126 + const items = context.parent.items || context.parent.contents; + if (items) items.push(blankLine); + } + + if (comments.length) Array.prototype.push.apply(this.props, comments); + offset = this.node.range.end; + } else { + if (inlineComment) { + const c = comments[0]; + this.props.push(c); + offset = c.end; + } else { + offset = Node.endOfLine(src, start + 1); + } + } + + const end = this.node ? this.node.valueRange.end : offset; + this.valueRange = new Range(start, end); + return offset; + } + + setOrigRanges(cr, offset) { + offset = super.setOrigRanges(cr, offset); + return this.node ? this.node.setOrigRanges(cr, offset) : offset; + } + + toString() { + const { + context: { + src + }, + node, + range, + value + } = this; + if (value != null) return value; + const str = node ? src.slice(range.start, node.range.start) + String(node) : src.slice(range.start, range.end); + return Node.addStringTerminator(src, range.end, str); + } + +} + +class Comment extends Node { + constructor() { + super(Type.COMMENT); + } + /** + * Parses a comment line from the source + * + * @param {ParseContext} context + * @param {number} start - Index of first character + * @returns {number} - Index of the character after this scalar + */ + + + parse(context, start) { + this.context = context; + const offset = this.parseComment(start); + this.range = new Range(start, offset); + return offset; + } + +} + +function grabCollectionEndComments(node) { + let cnode = node; + + while (cnode instanceof CollectionItem) cnode = cnode.node; + + if (!(cnode instanceof Collection)) return null; + const len = cnode.items.length; + let ci = -1; + + for (let i = len - 1; i >= 0; --i) { + const n = cnode.items[i]; + + if (n.type === Type.COMMENT) { + // Keep sufficiently indented comments with preceding node + const { + indent, + lineStart + } = n.context; + if (indent > 0 && n.range.start >= lineStart + indent) break; + ci = i; + } else if (n.type === Type.BLANK_LINE) ci = i;else break; + } + + if (ci === -1) return null; + const ca = cnode.items.splice(ci, len - ci); + const prevEnd = ca[0].range.start; + + while (true) { + cnode.range.end = prevEnd; + if (cnode.valueRange && cnode.valueRange.end > prevEnd) cnode.valueRange.end = prevEnd; + if (cnode === node) break; + cnode = cnode.context.parent; + } + + return ca; +} +class Collection extends Node { + static nextContentHasIndent(src, offset, indent) { + const lineStart = Node.endOfLine(src, offset) + 1; + offset = Node.endOfWhiteSpace(src, lineStart); + const ch = src[offset]; + if (!ch) return false; + if (offset >= lineStart + indent) return true; + if (ch !== '#' && ch !== '\n') return false; + return Collection.nextContentHasIndent(src, offset, indent); + } + + constructor(firstItem) { + super(firstItem.type === Type.SEQ_ITEM ? Type.SEQ : Type.MAP); + + for (let i = firstItem.props.length - 1; i >= 0; --i) { + if (firstItem.props[i].start < firstItem.context.lineStart) { + // props on previous line are assumed by the collection + this.props = firstItem.props.slice(0, i + 1); + firstItem.props = firstItem.props.slice(i + 1); + const itemRange = firstItem.props[0] || firstItem.valueRange; + firstItem.range.start = itemRange.start; + break; + } + } + + this.items = [firstItem]; + const ec = grabCollectionEndComments(firstItem); + if (ec) Array.prototype.push.apply(this.items, ec); + } + + get includesTrailingLines() { + return this.items.length > 0; + } + /** + * @param {ParseContext} context + * @param {number} start - Index of first character + * @returns {number} - Index of the character after this + */ + + + parse(context, start) { + this.context = context; + const { + parseNode, + src + } = context; // It's easier to recalculate lineStart here rather than tracking down the + // last context from which to read it -- eemeli/yaml#2 + + let lineStart = Node.startOfLine(src, start); + const firstItem = this.items[0]; // First-item context needs to be correct for later comment handling + // -- eemeli/yaml#17 + + firstItem.context.parent = this; + this.valueRange = Range.copy(firstItem.valueRange); + const indent = firstItem.range.start - firstItem.context.lineStart; + let offset = start; + offset = Node.normalizeOffset(src, offset); + let ch = src[offset]; + let atLineStart = Node.endOfWhiteSpace(src, lineStart) === offset; + let prevIncludesTrailingLines = false; + + while (ch) { + while (ch === '\n' || ch === '#') { + if (atLineStart && ch === '\n' && !prevIncludesTrailingLines) { + const blankLine = new BlankLine(); + offset = blankLine.parse({ + src + }, offset); + this.valueRange.end = offset; + + if (offset >= src.length) { + ch = null; + break; + } + + this.items.push(blankLine); + offset -= 1; // blankLine.parse() consumes terminal newline + } else if (ch === '#') { + if (offset < lineStart + indent && !Collection.nextContentHasIndent(src, offset, indent)) { + return offset; + } + + const comment = new Comment(); + offset = comment.parse({ + indent, + lineStart, + src + }, offset); + this.items.push(comment); + this.valueRange.end = offset; + + if (offset >= src.length) { + ch = null; + break; + } + } + + lineStart = offset + 1; + offset = Node.endOfIndent(src, lineStart); + + if (Node.atBlank(src, offset)) { + const wsEnd = Node.endOfWhiteSpace(src, offset); + const next = src[wsEnd]; + + if (!next || next === '\n' || next === '#') { + offset = wsEnd; + } + } + + ch = src[offset]; + atLineStart = true; + } + + if (!ch) { + break; + } + + if (offset !== lineStart + indent && (atLineStart || ch !== ':')) { + if (offset < lineStart + indent) { + if (lineStart > start) offset = lineStart; + break; + } else if (!this.error) { + const msg = 'All collection items must start at the same column'; + this.error = new YAMLSyntaxError(this, msg); + } + } + + if (firstItem.type === Type.SEQ_ITEM) { + if (ch !== '-') { + if (lineStart > start) offset = lineStart; + break; + } + } else if (ch === '-' && !this.error) { + // map key may start with -, as long as it's followed by a non-whitespace char + const next = src[offset + 1]; + + if (!next || next === '\n' || next === '\t' || next === ' ') { + const msg = 'A collection cannot be both a mapping and a sequence'; + this.error = new YAMLSyntaxError(this, msg); + } + } + + const node = parseNode({ + atLineStart, + inCollection: true, + indent, + lineStart, + parent: this + }, offset); + if (!node) return offset; // at next document start + + this.items.push(node); + this.valueRange.end = node.valueRange.end; + offset = Node.normalizeOffset(src, node.range.end); + ch = src[offset]; + atLineStart = false; + prevIncludesTrailingLines = node.includesTrailingLines; // Need to reset lineStart and atLineStart here if preceding node's range + // has advanced to check the current line's indentation level + // -- eemeli/yaml#10 & eemeli/yaml#38 + + if (ch) { + let ls = offset - 1; + let prev = src[ls]; + + while (prev === ' ' || prev === '\t') prev = src[--ls]; + + if (prev === '\n') { + lineStart = ls + 1; + atLineStart = true; + } + } + + const ec = grabCollectionEndComments(node); + if (ec) Array.prototype.push.apply(this.items, ec); + } + + return offset; + } + + setOrigRanges(cr, offset) { + offset = super.setOrigRanges(cr, offset); + this.items.forEach(node => { + offset = node.setOrigRanges(cr, offset); + }); + return offset; + } + + toString() { + const { + context: { + src + }, + items, + range, + value + } = this; + if (value != null) return value; + let str = src.slice(range.start, items[0].range.start) + String(items[0]); + + for (let i = 1; i < items.length; ++i) { + const item = items[i]; + const { + atLineStart, + indent + } = item.context; + if (atLineStart) for (let i = 0; i < indent; ++i) str += ' '; + str += String(item); + } + + return Node.addStringTerminator(src, range.end, str); + } + +} + +class Directive extends Node { + constructor() { + super(Type.DIRECTIVE); + this.name = null; + } + + get parameters() { + const raw = this.rawValue; + return raw ? raw.trim().split(/[ \t]+/) : []; + } + + parseName(start) { + const { + src + } = this.context; + let offset = start; + let ch = src[offset]; + + while (ch && ch !== '\n' && ch !== '\t' && ch !== ' ') ch = src[offset += 1]; + + this.name = src.slice(start, offset); + return offset; + } + + parseParameters(start) { + const { + src + } = this.context; + let offset = start; + let ch = src[offset]; + + while (ch && ch !== '\n' && ch !== '#') ch = src[offset += 1]; + + this.valueRange = new Range(start, offset); + return offset; + } + + parse(context, start) { + this.context = context; + let offset = this.parseName(start + 1); + offset = this.parseParameters(offset); + offset = this.parseComment(offset); + this.range = new Range(start, offset); + return offset; + } + +} + +class Document extends Node { + static startCommentOrEndBlankLine(src, start) { + const offset = Node.endOfWhiteSpace(src, start); + const ch = src[offset]; + return ch === '#' || ch === '\n' ? offset : start; + } + + constructor() { + super(Type.DOCUMENT); + this.directives = null; + this.contents = null; + this.directivesEndMarker = null; + this.documentEndMarker = null; + } + + parseDirectives(start) { + const { + src + } = this.context; + this.directives = []; + let atLineStart = true; + let hasDirectives = false; + let offset = start; + + while (!Node.atDocumentBoundary(src, offset, Char.DIRECTIVES_END)) { + offset = Document.startCommentOrEndBlankLine(src, offset); + + switch (src[offset]) { + case '\n': + if (atLineStart) { + const blankLine = new BlankLine(); + offset = blankLine.parse({ + src + }, offset); + + if (offset < src.length) { + this.directives.push(blankLine); + } + } else { + offset += 1; + atLineStart = true; + } + + break; + + case '#': + { + const comment = new Comment(); + offset = comment.parse({ + src + }, offset); + this.directives.push(comment); + atLineStart = false; + } + break; + + case '%': + { + const directive = new Directive(); + offset = directive.parse({ + parent: this, + src + }, offset); + this.directives.push(directive); + hasDirectives = true; + atLineStart = false; + } + break; + + default: + if (hasDirectives) { + this.error = new YAMLSemanticError(this, 'Missing directives-end indicator line'); + } else if (this.directives.length > 0) { + this.contents = this.directives; + this.directives = []; + } + + return offset; + } + } + + if (src[offset]) { + this.directivesEndMarker = new Range(offset, offset + 3); + return offset + 3; + } + + if (hasDirectives) { + this.error = new YAMLSemanticError(this, 'Missing directives-end indicator line'); + } else if (this.directives.length > 0) { + this.contents = this.directives; + this.directives = []; + } + + return offset; + } + + parseContents(start) { + const { + parseNode, + src + } = this.context; + if (!this.contents) this.contents = []; + let lineStart = start; + + while (src[lineStart - 1] === '-') lineStart -= 1; + + let offset = Node.endOfWhiteSpace(src, start); + let atLineStart = lineStart === start; + this.valueRange = new Range(offset); + + while (!Node.atDocumentBoundary(src, offset, Char.DOCUMENT_END)) { + switch (src[offset]) { + case '\n': + if (atLineStart) { + const blankLine = new BlankLine(); + offset = blankLine.parse({ + src + }, offset); + + if (offset < src.length) { + this.contents.push(blankLine); + } + } else { + offset += 1; + atLineStart = true; + } + + lineStart = offset; + break; + + case '#': + { + const comment = new Comment(); + offset = comment.parse({ + src + }, offset); + this.contents.push(comment); + atLineStart = false; + } + break; + + default: + { + const iEnd = Node.endOfIndent(src, offset); + const context = { + atLineStart, + indent: -1, + inFlow: false, + inCollection: false, + lineStart, + parent: this + }; + const node = parseNode(context, iEnd); + if (!node) return this.valueRange.end = iEnd; // at next document start + + this.contents.push(node); + offset = node.range.end; + atLineStart = false; + const ec = grabCollectionEndComments(node); + if (ec) Array.prototype.push.apply(this.contents, ec); + } + } + + offset = Document.startCommentOrEndBlankLine(src, offset); + } + + this.valueRange.end = offset; + + if (src[offset]) { + this.documentEndMarker = new Range(offset, offset + 3); + offset += 3; + + if (src[offset]) { + offset = Node.endOfWhiteSpace(src, offset); + + if (src[offset] === '#') { + const comment = new Comment(); + offset = comment.parse({ + src + }, offset); + this.contents.push(comment); + } + + switch (src[offset]) { + case '\n': + offset += 1; + break; + + case undefined: + break; + + default: + this.error = new YAMLSyntaxError(this, 'Document end marker line cannot have a non-comment suffix'); + } + } + } + + return offset; + } + /** + * @param {ParseContext} context + * @param {number} start - Index of first character + * @returns {number} - Index of the character after this + */ + + + parse(context, start) { + context.root = this; + this.context = context; + const { + src + } = context; + let offset = src.charCodeAt(start) === 0xfeff ? start + 1 : start; // skip BOM + + offset = this.parseDirectives(offset); + offset = this.parseContents(offset); + return offset; + } + + setOrigRanges(cr, offset) { + offset = super.setOrigRanges(cr, offset); + this.directives.forEach(node => { + offset = node.setOrigRanges(cr, offset); + }); + if (this.directivesEndMarker) offset = this.directivesEndMarker.setOrigRange(cr, offset); + this.contents.forEach(node => { + offset = node.setOrigRanges(cr, offset); + }); + if (this.documentEndMarker) offset = this.documentEndMarker.setOrigRange(cr, offset); + return offset; + } + + toString() { + const { + contents, + directives, + value + } = this; + if (value != null) return value; + let str = directives.join(''); + + if (contents.length > 0) { + if (directives.length > 0 || contents[0].type === Type.COMMENT) str += '---\n'; + str += contents.join(''); + } + + if (str[str.length - 1] !== '\n') str += '\n'; + return str; + } + +} + +function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + + return obj; +} + +class Alias extends Node { + /** + * Parses an *alias from the source + * + * @param {ParseContext} context + * @param {number} start - Index of first character + * @returns {number} - Index of the character after this scalar + */ + parse(context, start) { + this.context = context; + const { + src + } = context; + let offset = Node.endOfIdentifier(src, start + 1); + this.valueRange = new Range(start + 1, offset); + offset = Node.endOfWhiteSpace(src, offset); + offset = this.parseComment(offset); + return offset; + } + +} + +const Chomp = { + CLIP: 'CLIP', + KEEP: 'KEEP', + STRIP: 'STRIP' +}; +class BlockValue extends Node { + constructor(type, props) { + super(type, props); + this.blockIndent = null; + this.chomping = Chomp.CLIP; + this.header = null; + } + + get includesTrailingLines() { + return this.chomping === Chomp.KEEP; + } + + get strValue() { + if (!this.valueRange || !this.context) return null; + let { + start, + end + } = this.valueRange; + const { + indent, + src + } = this.context; + if (this.valueRange.isEmpty()) return ''; + let lastNewLine = null; + let ch = src[end - 1]; + + while (ch === '\n' || ch === '\t' || ch === ' ') { + end -= 1; + + if (end <= start) { + if (this.chomping === Chomp.KEEP) break;else return ''; // probably never happens + } + + if (ch === '\n') lastNewLine = end; + ch = src[end - 1]; + } + + let keepStart = end + 1; + + if (lastNewLine) { + if (this.chomping === Chomp.KEEP) { + keepStart = lastNewLine; + end = this.valueRange.end; + } else { + end = lastNewLine; + } + } + + const bi = indent + this.blockIndent; + const folded = this.type === Type.BLOCK_FOLDED; + let atStart = true; + let str = ''; + let sep = ''; + let prevMoreIndented = false; + + for (let i = start; i < end; ++i) { + for (let j = 0; j < bi; ++j) { + if (src[i] !== ' ') break; + i += 1; + } + + const ch = src[i]; + + if (ch === '\n') { + if (sep === '\n') str += '\n';else sep = '\n'; + } else { + const lineEnd = Node.endOfLine(src, i); + const line = src.slice(i, lineEnd); + i = lineEnd; + + if (folded && (ch === ' ' || ch === '\t') && i < keepStart) { + if (sep === ' ') sep = '\n';else if (!prevMoreIndented && !atStart && sep === '\n') sep = '\n\n'; + str += sep + line; //+ ((lineEnd < end && src[lineEnd]) || '') + + sep = lineEnd < end && src[lineEnd] || ''; + prevMoreIndented = true; + } else { + str += sep + line; + sep = folded && i < keepStart ? ' ' : '\n'; + prevMoreIndented = false; + } + + if (atStart && line !== '') atStart = false; + } + } + + return this.chomping === Chomp.STRIP ? str : str + '\n'; + } + + parseBlockHeader(start) { + const { + src + } = this.context; + let offset = start + 1; + let bi = ''; + + while (true) { + const ch = src[offset]; + + switch (ch) { + case '-': + this.chomping = Chomp.STRIP; + break; + + case '+': + this.chomping = Chomp.KEEP; + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + bi += ch; + break; + + default: + this.blockIndent = Number(bi) || null; + this.header = new Range(start, offset); + return offset; + } + + offset += 1; + } + } + + parseBlockValue(start) { + const { + indent, + src + } = this.context; + const explicit = !!this.blockIndent; + let offset = start; + let valueEnd = start; + let minBlockIndent = 1; + + for (let ch = src[offset]; ch === '\n'; ch = src[offset]) { + offset += 1; + if (Node.atDocumentBoundary(src, offset)) break; + const end = Node.endOfBlockIndent(src, indent, offset); // should not include tab? + + if (end === null) break; + const ch = src[end]; + const lineIndent = end - (offset + indent); + + if (!this.blockIndent) { + // no explicit block indent, none yet detected + if (src[end] !== '\n') { + // first line with non-whitespace content + if (lineIndent < minBlockIndent) { + const msg = 'Block scalars with more-indented leading empty lines must use an explicit indentation indicator'; + this.error = new YAMLSemanticError(this, msg); + } + + this.blockIndent = lineIndent; + } else if (lineIndent > minBlockIndent) { + // empty line with more whitespace + minBlockIndent = lineIndent; + } + } else if (ch && ch !== '\n' && lineIndent < this.blockIndent) { + if (src[end] === '#') break; + + if (!this.error) { + const src = explicit ? 'explicit indentation indicator' : 'first line'; + const msg = "Block scalars must not be less indented than their ".concat(src); + this.error = new YAMLSemanticError(this, msg); + } + } + + if (src[end] === '\n') { + offset = end; + } else { + offset = valueEnd = Node.endOfLine(src, end); + } + } + + if (this.chomping !== Chomp.KEEP) { + offset = src[valueEnd] ? valueEnd + 1 : valueEnd; + } + + this.valueRange = new Range(start + 1, offset); + return offset; + } + /** + * Parses a block value from the source + * + * Accepted forms are: + * ``` + * BS + * block + * lines + * + * BS #comment + * block + * lines + * ``` + * where the block style BS matches the regexp `[|>][-+1-9]*` and block lines + * are empty or have an indent level greater than `indent`. + * + * @param {ParseContext} context + * @param {number} start - Index of first character + * @returns {number} - Index of the character after this block + */ + + + parse(context, start) { + this.context = context; + const { + src + } = context; + let offset = this.parseBlockHeader(start); + offset = Node.endOfWhiteSpace(src, offset); + offset = this.parseComment(offset); + offset = this.parseBlockValue(offset); + return offset; + } + + setOrigRanges(cr, offset) { + offset = super.setOrigRanges(cr, offset); + return this.header ? this.header.setOrigRange(cr, offset) : offset; + } + +} + +class FlowCollection extends Node { + constructor(type, props) { + super(type, props); + this.items = null; + } + + prevNodeIsJsonLike(idx = this.items.length) { + const node = this.items[idx - 1]; + return !!node && (node.jsonLike || node.type === Type.COMMENT && this.prevNodeIsJsonLike(idx - 1)); + } + /** + * @param {ParseContext} context + * @param {number} start - Index of first character + * @returns {number} - Index of the character after this + */ + + + parse(context, start) { + this.context = context; + const { + parseNode, + src + } = context; + let { + indent, + lineStart + } = context; + let char = src[start]; // { or [ + + this.items = [{ + char, + offset: start + }]; + let offset = Node.endOfWhiteSpace(src, start + 1); + char = src[offset]; + + while (char && char !== ']' && char !== '}') { + switch (char) { + case '\n': + { + lineStart = offset + 1; + const wsEnd = Node.endOfWhiteSpace(src, lineStart); + + if (src[wsEnd] === '\n') { + const blankLine = new BlankLine(); + lineStart = blankLine.parse({ + src + }, lineStart); + this.items.push(blankLine); + } + + offset = Node.endOfIndent(src, lineStart); + + if (offset <= lineStart + indent) { + char = src[offset]; + + if (offset < lineStart + indent || char !== ']' && char !== '}') { + const msg = 'Insufficient indentation in flow collection'; + this.error = new YAMLSemanticError(this, msg); + } + } + } + break; + + case ',': + { + this.items.push({ + char, + offset + }); + offset += 1; + } + break; + + case '#': + { + const comment = new Comment(); + offset = comment.parse({ + src + }, offset); + this.items.push(comment); + } + break; + + case '?': + case ':': + { + const next = src[offset + 1]; + + if (next === '\n' || next === '\t' || next === ' ' || next === ',' || // in-flow : after JSON-like key does not need to be followed by whitespace + char === ':' && this.prevNodeIsJsonLike()) { + this.items.push({ + char, + offset + }); + offset += 1; + break; + } + } + // fallthrough + + default: + { + const node = parseNode({ + atLineStart: false, + inCollection: false, + inFlow: true, + indent: -1, + lineStart, + parent: this + }, offset); + + if (!node) { + // at next document start + this.valueRange = new Range(start, offset); + return offset; + } + + this.items.push(node); + offset = Node.normalizeOffset(src, node.range.end); + } + } + + offset = Node.endOfWhiteSpace(src, offset); + char = src[offset]; + } + + this.valueRange = new Range(start, offset + 1); + + if (char) { + this.items.push({ + char, + offset + }); + offset = Node.endOfWhiteSpace(src, offset + 1); + offset = this.parseComment(offset); + } + + return offset; + } + + setOrigRanges(cr, offset) { + offset = super.setOrigRanges(cr, offset); + this.items.forEach(node => { + if (node instanceof Node) { + offset = node.setOrigRanges(cr, offset); + } else if (cr.length === 0) { + node.origOffset = node.offset; + } else { + let i = offset; + + while (i < cr.length) { + if (cr[i] > node.offset) break;else ++i; + } + + node.origOffset = node.offset + i; + offset = i; + } + }); + return offset; + } + + toString() { + const { + context: { + src + }, + items, + range, + value + } = this; + if (value != null) return value; + const nodes = items.filter(item => item instanceof Node); + let str = ''; + let prevEnd = range.start; + nodes.forEach(node => { + const prefix = src.slice(prevEnd, node.range.start); + prevEnd = node.range.end; + str += prefix + String(node); + + if (str[str.length - 1] === '\n' && src[prevEnd - 1] !== '\n' && src[prevEnd] === '\n') { + // Comment range does not include the terminal newline, but its + // stringified value does. Without this fix, newlines at comment ends + // get duplicated. + prevEnd += 1; + } + }); + str += src.slice(prevEnd, range.end); + return Node.addStringTerminator(src, range.end, str); + } + +} + +class PlainValue extends Node { + static endOfLine(src, start, inFlow) { + let ch = src[start]; + let offset = start; + + while (ch && ch !== '\n') { + if (inFlow && (ch === '[' || ch === ']' || ch === '{' || ch === '}' || ch === ',')) break; + const next = src[offset + 1]; + if (ch === ':' && (!next || next === '\n' || next === '\t' || next === ' ' || inFlow && next === ',')) break; + if ((ch === ' ' || ch === '\t') && next === '#') break; + offset += 1; + ch = next; + } + + return offset; + } + + get strValue() { + if (!this.valueRange || !this.context) return null; + let { + start, + end + } = this.valueRange; + const { + src + } = this.context; + let ch = src[end - 1]; + + while (start < end && (ch === '\n' || ch === '\t' || ch === ' ')) ch = src[--end - 1]; + + let str = ''; + + for (let i = start; i < end; ++i) { + const ch = src[i]; + + if (ch === '\n') { + const { + fold, + offset + } = Node.foldNewline(src, i, -1); + str += fold; + i = offset; + } else if (ch === ' ' || ch === '\t') { + // trim trailing whitespace + const wsStart = i; + let next = src[i + 1]; + + while (i < end && (next === ' ' || next === '\t')) { + i += 1; + next = src[i + 1]; + } + + if (next !== '\n') str += i > wsStart ? src.slice(wsStart, i + 1) : ch; + } else { + str += ch; + } + } + + const ch0 = src[start]; + + switch (ch0) { + case '\t': + { + const msg = 'Plain value cannot start with a tab character'; + const errors = [new YAMLSemanticError(this, msg)]; + return { + errors, + str + }; + } + + case '@': + case '`': + { + const msg = "Plain value cannot start with reserved character ".concat(ch0); + const errors = [new YAMLSemanticError(this, msg)]; + return { + errors, + str + }; + } + + default: + return str; + } + } + + parseBlockValue(start) { + const { + indent, + inFlow, + src + } = this.context; + let offset = start; + let valueEnd = start; + + for (let ch = src[offset]; ch === '\n'; ch = src[offset]) { + if (Node.atDocumentBoundary(src, offset + 1)) break; + const end = Node.endOfBlockIndent(src, indent, offset + 1); + if (end === null || src[end] === '#') break; + + if (src[end] === '\n') { + offset = end; + } else { + valueEnd = PlainValue.endOfLine(src, end, inFlow); + offset = valueEnd; + } + } + + if (this.valueRange.isEmpty()) this.valueRange.start = start; + this.valueRange.end = valueEnd; + return valueEnd; + } + /** + * Parses a plain value from the source + * + * Accepted forms are: + * ``` + * #comment + * + * first line + * + * first line #comment + * + * first line + * block + * lines + * + * #comment + * block + * lines + * ``` + * where block lines are empty or have an indent level greater than `indent`. + * + * @param {ParseContext} context + * @param {number} start - Index of first character + * @returns {number} - Index of the character after this scalar, may be `\n` + */ + + + parse(context, start) { + this.context = context; + const { + inFlow, + src + } = context; + let offset = start; + const ch = src[offset]; + + if (ch && ch !== '#' && ch !== '\n') { + offset = PlainValue.endOfLine(src, start, inFlow); + } + + this.valueRange = new Range(start, offset); + offset = Node.endOfWhiteSpace(src, offset); + offset = this.parseComment(offset); + + if (!this.hasComment || this.valueRange.isEmpty()) { + offset = this.parseBlockValue(offset); + } + + return offset; + } + +} + +class QuoteDouble extends Node { + static endOfQuote(src, offset) { + let ch = src[offset]; + + while (ch && ch !== '"') { + offset += ch === '\\' ? 2 : 1; + ch = src[offset]; + } + + return offset + 1; + } + /** + * @returns {string | { str: string, errors: YAMLSyntaxError[] }} + */ + + + get strValue() { + if (!this.valueRange || !this.context) return null; + const errors = []; + const { + start, + end + } = this.valueRange; + const { + indent, + src + } = this.context; + if (src[end - 1] !== '"') errors.push(new YAMLSyntaxError(this, 'Missing closing "quote')); // Using String#replace is too painful with escaped newlines preceded by + // escaped backslashes; also, this should be faster. + + let str = ''; + + for (let i = start + 1; i < end - 1; ++i) { + const ch = src[i]; + + if (ch === '\n') { + if (Node.atDocumentBoundary(src, i + 1)) errors.push(new YAMLSemanticError(this, 'Document boundary indicators are not allowed within string values')); + const { + fold, + offset, + error + } = Node.foldNewline(src, i, indent); + str += fold; + i = offset; + if (error) errors.push(new YAMLSemanticError(this, 'Multi-line double-quoted string needs to be sufficiently indented')); + } else if (ch === '\\') { + i += 1; + + switch (src[i]) { + case '0': + str += '\0'; + break; + // null character + + case 'a': + str += '\x07'; + break; + // bell character + + case 'b': + str += '\b'; + break; + // backspace + + case 'e': + str += '\x1b'; + break; + // escape character + + case 'f': + str += '\f'; + break; + // form feed + + case 'n': + str += '\n'; + break; + // line feed + + case 'r': + str += '\r'; + break; + // carriage return + + case 't': + str += '\t'; + break; + // horizontal tab + + case 'v': + str += '\v'; + break; + // vertical tab + + case 'N': + str += '\u0085'; + break; + // Unicode next line + + case '_': + str += '\u00a0'; + break; + // Unicode non-breaking space + + case 'L': + str += '\u2028'; + break; + // Unicode line separator + + case 'P': + str += '\u2029'; + break; + // Unicode paragraph separator + + case ' ': + str += ' '; + break; + + case '"': + str += '"'; + break; + + case '/': + str += '/'; + break; + + case '\\': + str += '\\'; + break; + + case '\t': + str += '\t'; + break; + + case 'x': + str += this.parseCharCode(i + 1, 2, errors); + i += 2; + break; + + case 'u': + str += this.parseCharCode(i + 1, 4, errors); + i += 4; + break; + + case 'U': + str += this.parseCharCode(i + 1, 8, errors); + i += 8; + break; + + case '\n': + // skip escaped newlines, but still trim the following line + while (src[i + 1] === ' ' || src[i + 1] === '\t') i += 1; + + break; + + default: + errors.push(new YAMLSyntaxError(this, "Invalid escape sequence ".concat(src.substr(i - 1, 2)))); + str += '\\' + src[i]; + } + } else if (ch === ' ' || ch === '\t') { + // trim trailing whitespace + const wsStart = i; + let next = src[i + 1]; + + while (next === ' ' || next === '\t') { + i += 1; + next = src[i + 1]; + } + + if (next !== '\n') str += i > wsStart ? src.slice(wsStart, i + 1) : ch; + } else { + str += ch; + } + } + + return errors.length > 0 ? { + errors, + str + } : str; + } + + parseCharCode(offset, length, errors) { + const { + src + } = this.context; + const cc = src.substr(offset, length); + const ok = cc.length === length && /^[0-9a-fA-F]+$/.test(cc); + const code = ok ? parseInt(cc, 16) : NaN; + + if (isNaN(code)) { + errors.push(new YAMLSyntaxError(this, "Invalid escape sequence ".concat(src.substr(offset - 2, length + 2)))); + return src.substr(offset - 2, length + 2); + } + + return String.fromCodePoint(code); + } + /** + * Parses a "double quoted" value from the source + * + * @param {ParseContext} context + * @param {number} start - Index of first character + * @returns {number} - Index of the character after this scalar + */ + + + parse(context, start) { + this.context = context; + const { + src + } = context; + let offset = QuoteDouble.endOfQuote(src, start + 1); + this.valueRange = new Range(start, offset); + offset = Node.endOfWhiteSpace(src, offset); + offset = this.parseComment(offset); + return offset; + } + +} + +class QuoteSingle extends Node { + static endOfQuote(src, offset) { + let ch = src[offset]; + + while (ch) { + if (ch === "'") { + if (src[offset + 1] !== "'") break; + ch = src[offset += 2]; + } else { + ch = src[offset += 1]; + } + } + + return offset + 1; + } + /** + * @returns {string | { str: string, errors: YAMLSyntaxError[] }} + */ + + + get strValue() { + if (!this.valueRange || !this.context) return null; + const errors = []; + const { + start, + end + } = this.valueRange; + const { + indent, + src + } = this.context; + if (src[end - 1] !== "'") errors.push(new YAMLSyntaxError(this, "Missing closing 'quote")); + let str = ''; + + for (let i = start + 1; i < end - 1; ++i) { + const ch = src[i]; + + if (ch === '\n') { + if (Node.atDocumentBoundary(src, i + 1)) errors.push(new YAMLSemanticError(this, 'Document boundary indicators are not allowed within string values')); + const { + fold, + offset, + error + } = Node.foldNewline(src, i, indent); + str += fold; + i = offset; + if (error) errors.push(new YAMLSemanticError(this, 'Multi-line single-quoted string needs to be sufficiently indented')); + } else if (ch === "'") { + str += ch; + i += 1; + if (src[i] !== "'") errors.push(new YAMLSyntaxError(this, 'Unescaped single quote? This should not happen.')); + } else if (ch === ' ' || ch === '\t') { + // trim trailing whitespace + const wsStart = i; + let next = src[i + 1]; + + while (next === ' ' || next === '\t') { + i += 1; + next = src[i + 1]; + } + + if (next !== '\n') str += i > wsStart ? src.slice(wsStart, i + 1) : ch; + } else { + str += ch; + } + } + + return errors.length > 0 ? { + errors, + str + } : str; + } + /** + * Parses a 'single quoted' value from the source + * + * @param {ParseContext} context + * @param {number} start - Index of first character + * @returns {number} - Index of the character after this scalar + */ + + + parse(context, start) { + this.context = context; + const { + src + } = context; + let offset = QuoteSingle.endOfQuote(src, start + 1); + this.valueRange = new Range(start, offset); + offset = Node.endOfWhiteSpace(src, offset); + offset = this.parseComment(offset); + return offset; + } + +} + +function createNewNode(type, props) { + switch (type) { + case Type.ALIAS: + return new Alias(type, props); + + case Type.BLOCK_FOLDED: + case Type.BLOCK_LITERAL: + return new BlockValue(type, props); + + case Type.FLOW_MAP: + case Type.FLOW_SEQ: + return new FlowCollection(type, props); + + case Type.MAP_KEY: + case Type.MAP_VALUE: + case Type.SEQ_ITEM: + return new CollectionItem(type, props); + + case Type.COMMENT: + case Type.PLAIN: + return new PlainValue(type, props); + + case Type.QUOTE_DOUBLE: + return new QuoteDouble(type, props); + + case Type.QUOTE_SINGLE: + return new QuoteSingle(type, props); + + /* istanbul ignore next */ + + default: + return null; + // should never happen + } +} +/** + * @param {boolean} atLineStart - Node starts at beginning of line + * @param {boolean} inFlow - true if currently in a flow context + * @param {boolean} inCollection - true if currently in a collection context + * @param {number} indent - Current level of indentation + * @param {number} lineStart - Start of the current line + * @param {Node} parent - The parent of the node + * @param {string} src - Source of the YAML document + */ + + +class ParseContext { + static parseType(src, offset, inFlow) { + switch (src[offset]) { + case '*': + return Type.ALIAS; + + case '>': + return Type.BLOCK_FOLDED; + + case '|': + return Type.BLOCK_LITERAL; + + case '{': + return Type.FLOW_MAP; + + case '[': + return Type.FLOW_SEQ; + + case '?': + return !inFlow && Node.atBlank(src, offset + 1, true) ? Type.MAP_KEY : Type.PLAIN; + + case ':': + return !inFlow && Node.atBlank(src, offset + 1, true) ? Type.MAP_VALUE : Type.PLAIN; + + case '-': + return !inFlow && Node.atBlank(src, offset + 1, true) ? Type.SEQ_ITEM : Type.PLAIN; + + case '"': + return Type.QUOTE_DOUBLE; + + case "'": + return Type.QUOTE_SINGLE; + + default: + return Type.PLAIN; + } + } + + constructor(orig = {}, { + atLineStart, + inCollection, + inFlow, + indent, + lineStart, + parent + } = {}) { + _defineProperty(this, "parseNode", (overlay, start) => { + if (Node.atDocumentBoundary(this.src, start)) return null; + const context = new ParseContext(this, overlay); + const { + props, + type, + valueStart + } = context.parseProps(start); + const node = createNewNode(type, props); + let offset = node.parse(context, valueStart); + node.range = new Range(start, offset); + /* istanbul ignore if */ + + if (offset <= start) { + // This should never happen, but if it does, let's make sure to at least + // step one character forward to avoid a busy loop. + node.error = new Error("Node#parse consumed no characters"); + node.error.parseEnd = offset; + node.error.source = node; + node.range.end = start + 1; + } + + if (context.nodeStartsCollection(node)) { + if (!node.error && !context.atLineStart && context.parent.type === Type.DOCUMENT) { + node.error = new YAMLSyntaxError(node, 'Block collection must not have preceding content here (e.g. directives-end indicator)'); + } + + const collection = new Collection(node); + offset = collection.parse(new ParseContext(context), offset); + collection.range = new Range(start, offset); + return collection; + } + + return node; + }); + + this.atLineStart = atLineStart != null ? atLineStart : orig.atLineStart || false; + this.inCollection = inCollection != null ? inCollection : orig.inCollection || false; + this.inFlow = inFlow != null ? inFlow : orig.inFlow || false; + this.indent = indent != null ? indent : orig.indent; + this.lineStart = lineStart != null ? lineStart : orig.lineStart; + this.parent = parent != null ? parent : orig.parent || {}; + this.root = orig.root; + this.src = orig.src; + } + + nodeStartsCollection(node) { + const { + inCollection, + inFlow, + src + } = this; + if (inCollection || inFlow) return false; + if (node instanceof CollectionItem) return true; // check for implicit key + + let offset = node.range.end; + if (src[offset] === '\n' || src[offset - 1] === '\n') return false; + offset = Node.endOfWhiteSpace(src, offset); + return src[offset] === ':'; + } // Anchor and tag are before type, which determines the node implementation + // class; hence this intermediate step. + + + parseProps(offset) { + const { + inFlow, + parent, + src + } = this; + const props = []; + let lineHasProps = false; + offset = this.atLineStart ? Node.endOfIndent(src, offset) : Node.endOfWhiteSpace(src, offset); + let ch = src[offset]; + + while (ch === Char.ANCHOR || ch === Char.COMMENT || ch === Char.TAG || ch === '\n') { + if (ch === '\n') { + const lineStart = offset + 1; + const inEnd = Node.endOfIndent(src, lineStart); + const indentDiff = inEnd - (lineStart + this.indent); + const noIndicatorAsIndent = parent.type === Type.SEQ_ITEM && parent.context.atLineStart; + if (!Node.nextNodeIsIndented(src[inEnd], indentDiff, !noIndicatorAsIndent)) break; + this.atLineStart = true; + this.lineStart = lineStart; + lineHasProps = false; + offset = inEnd; + } else if (ch === Char.COMMENT) { + const end = Node.endOfLine(src, offset + 1); + props.push(new Range(offset, end)); + offset = end; + } else { + let end = Node.endOfIdentifier(src, offset + 1); + + if (ch === Char.TAG && src[end] === ',' && /^[a-zA-Z0-9-]+\.[a-zA-Z0-9-]+,\d\d\d\d(-\d\d){0,2}\/\S/.test(src.slice(offset + 1, end + 13))) { + // Let's presume we're dealing with a YAML 1.0 domain tag here, rather + // than an empty but 'foo.bar' private-tagged node in a flow collection + // followed without whitespace by a plain string starting with a year + // or date divided by something. + end = Node.endOfIdentifier(src, end + 5); + } + + props.push(new Range(offset, end)); + lineHasProps = true; + offset = Node.endOfWhiteSpace(src, end); + } + + ch = src[offset]; + } // '- &a : b' has an anchor on an empty node + + + if (lineHasProps && ch === ':' && Node.atBlank(src, offset + 1, true)) offset -= 1; + const type = ParseContext.parseType(src, offset, inFlow); + return { + props, + type, + valueStart: offset + }; + } + /** + * Parses a node from the source + * @param {ParseContext} overlay + * @param {number} start - Index of first non-whitespace character for the node + * @returns {?Node} - null if at a document boundary + */ + + +} + +function parse(src) { + const cr = []; + + if (src.indexOf('\r') !== -1) { + src = src.replace(/\r\n?/g, (match, offset) => { + if (match.length > 1) cr.push(offset); + return '\n'; + }); + } + + const documents = []; + let offset = 0; + + do { + const doc = new Document(); + const context = new ParseContext({ + src + }); + offset = doc.parse(context, offset); + documents.push(doc); + } while (offset < src.length); + + documents.setOrigRanges = () => { + if (cr.length === 0) return false; + + for (let i = 1; i < cr.length; ++i) cr[i] -= i; + + let crOffset = 0; + + for (let i = 0; i < documents.length; ++i) { + crOffset = documents[i].setOrigRanges(cr, crOffset); + } + + cr.splice(0, cr.length); + return true; + }; + + documents.toString = () => documents.join('...\n'); + + return documents; +} + +const binaryOptions = { + defaultType: Type.BLOCK_LITERAL, + lineWidth: 76 +}; +const boolOptions = { + trueStr: 'true', + falseStr: 'false' +}; +const intOptions = { + asBigInt: false +}; +const nullOptions = { + nullStr: 'null' +}; +const strOptions = { + defaultType: Type.PLAIN, + defaultKeyType: Type.PLAIN, + defaultQuoteSingle: false, + doubleQuoted: { + jsonEncoding: false, + minMultiLineLength: 40 + }, + fold: { + lineWidth: 80, + minContentWidth: 20 + } +}; + +const defaultOptions = { + anchorPrefix: 'a', + customTags: null, + indent: 2, + indentSeq: true, + keepCstNodes: false, + keepNodeTypes: true, + keepUndefined: false, + logLevel: 'warn', + mapAsMap: false, + maxAliasCount: 100, + prettyErrors: true, + simpleKeys: false, + version: '1.2' +}; +const documentOptions = { + '1.0': { + schema: 'yaml-1.1', + merge: true, + tagPrefixes: [{ + handle: '!', + prefix: defaultTagPrefix + }, { + handle: '!!', + prefix: 'tag:private.yaml.org,2002:' + }] + }, + 1.1: { + schema: 'yaml-1.1', + merge: true, + tagPrefixes: [{ + handle: '!', + prefix: '!' + }, { + handle: '!!', + prefix: defaultTagPrefix + }] + }, + 1.2: { + schema: 'core', + merge: false, + resolveKnownTags: true, + tagPrefixes: [{ + handle: '!', + prefix: '!' + }, { + handle: '!!', + prefix: defaultTagPrefix + }] + } +}; + +function addCommentBefore(str, indent, comment) { + if (!comment) return str; + const cc = comment.replace(/[\s\S]^/gm, "$&".concat(indent, "#")); + return "#".concat(cc, "\n").concat(indent).concat(str); +} +function addComment(str, indent, comment) { + return !comment ? str : comment.indexOf('\n') === -1 ? "".concat(str, " #").concat(comment) : "".concat(str, "\n") + comment.replace(/^/gm, "".concat(indent || '', "#")); +} + +class Node$1 {} + +/** + * Recursively convert any node or its contents to native JavaScript + * + * @param value - The input value + * @param {string|null} arg - If `value` defines a `toJSON()` method, use this + * as its first argument + * @param ctx - Conversion context, originally set in Document#toJS(). If + * `{ keep: true }` is not set, output should be suitable for JSON + * stringification. + */ +function toJS(value, arg, ctx) { + if (Array.isArray(value)) return value.map((v, i) => toJS(v, String(i), ctx)); + + if (value && typeof value.toJSON === 'function') { + const anchor = ctx && ctx.anchors && ctx.anchors.get(value); + if (anchor) ctx.onCreate = res => { + anchor.res = res; + delete ctx.onCreate; + }; + const res = value.toJSON(arg, ctx); + if (anchor && ctx.onCreate) ctx.onCreate(res); + return res; + } + + if (!(ctx && ctx.keep) && typeof value === 'bigint') return Number(value); + return value; +} + +const isScalarValue = value => !value || typeof value !== 'function' && typeof value !== 'object'; +class Scalar extends Node$1 { + constructor(value) { + super(); + this.value = value; + } + + toJSON(arg, ctx) { + return ctx && ctx.keep ? this.value : toJS(this.value, arg, ctx); + } + + toString() { + return String(this.value); + } + +} + +function findTagObject(value, tagName, tags) { + if (tagName) { + const match = tags.filter(t => t.tag === tagName); + const tagObj = match.find(t => !t.format) || match[0]; + if (!tagObj) throw new Error("Tag ".concat(tagName, " not found")); + return tagObj; + } + + return tags.find(t => t.identify && t.identify(value) && !t.format); +} + +function createNode(value, tagName, ctx) { + if (value instanceof Node$1) return value; + const { + onAlias, + onTagObj, + prevObjects, + wrapScalars + } = ctx; + const { + map, + seq, + tags + } = ctx.schema; + if (tagName && tagName.startsWith('!!')) tagName = defaultTagPrefix + tagName.slice(2); + let tagObj = findTagObject(value, tagName, tags); + + if (!tagObj) { + if (typeof value.toJSON === 'function') value = value.toJSON(); + if (!value || typeof value !== 'object') return wrapScalars ? new Scalar(value) : value; + tagObj = value instanceof Map ? map : value[Symbol.iterator] ? seq : map; + } + + if (onTagObj) { + onTagObj(tagObj); + delete ctx.onTagObj; + } // Detect duplicate references to the same object & use Alias nodes for all + // after first. The `obj` wrapper allows for circular references to resolve. + + + const obj = { + value: undefined, + node: undefined + }; + + if (value && typeof value === 'object') { + const prev = prevObjects.get(value); + if (prev) return onAlias(prev); + obj.value = value; + prevObjects.set(value, obj); + } + + obj.node = tagObj.createNode ? tagObj.createNode(ctx.schema, value, ctx) : wrapScalars ? new Scalar(value) : value; + if (tagName && obj.node instanceof Node$1) obj.node.tag = tagName; + return obj.node; +} + +function collectionFromPath(schema, path, value) { + let v = value; + + for (let i = path.length - 1; i >= 0; --i) { + const k = path[i]; + + if (Number.isInteger(k) && k >= 0) { + const a = []; + a[k] = v; + v = a; + } else { + const o = {}; + Object.defineProperty(o, k, { + value: v, + writable: true, + enumerable: true, + configurable: true + }); + v = o; + } + } + + return createNode(v, null, { + onAlias() { + throw new Error('Repeated objects are not supported here'); + }, + + prevObjects: new Map(), + schema, + wrapScalars: false + }); +} // null, undefined, or an empty non-string iterable (e.g. []) + +const isEmptyPath = path => path == null || typeof path === 'object' && path[Symbol.iterator]().next().done; +class Collection$1 extends Node$1 { + constructor(schema) { + super(); + + _defineProperty(this, "items", []); + + this.schema = schema; + } + + addIn(path, value) { + if (isEmptyPath(path)) this.add(value);else { + const [key, ...rest] = path; + const node = this.get(key, true); + if (node instanceof Collection$1) node.addIn(rest, value);else if (node === undefined && this.schema) this.set(key, collectionFromPath(this.schema, rest, value));else throw new Error("Expected YAML collection at ".concat(key, ". Remaining path: ").concat(rest)); + } + } + + deleteIn([key, ...rest]) { + if (rest.length === 0) return this.delete(key); + const node = this.get(key, true); + if (node instanceof Collection$1) return node.deleteIn(rest);else throw new Error("Expected YAML collection at ".concat(key, ". Remaining path: ").concat(rest)); + } + + getIn([key, ...rest], keepScalar) { + const node = this.get(key, true); + if (rest.length === 0) return !keepScalar && node instanceof Scalar ? node.value : node;else return node instanceof Collection$1 ? node.getIn(rest, keepScalar) : undefined; + } + + hasAllNullValues() { + return this.items.every(node => { + if (!node || node.type !== 'PAIR') return false; + const n = node.value; + return n == null || n instanceof Scalar && n.value == null && !n.commentBefore && !n.comment && !n.tag; + }); + } + + hasIn([key, ...rest]) { + if (rest.length === 0) return this.has(key); + const node = this.get(key, true); + return node instanceof Collection$1 ? node.hasIn(rest) : false; + } + + setIn([key, ...rest], value) { + if (rest.length === 0) { + this.set(key, value); + } else { + const node = this.get(key, true); + if (node instanceof Collection$1) node.setIn(rest, value);else if (node === undefined && this.schema) this.set(key, collectionFromPath(this.schema, rest, value));else throw new Error("Expected YAML collection at ".concat(key, ". Remaining path: ").concat(rest)); + } + } + /* istanbul ignore next: overridden in implementations */ + + + toJSON() { + return null; + } + + toString(ctx, { + blockItem, + flowChars, + isMap, + itemIndent + }, onComment, onChompKeep) { + const { + indent, + indentStep, + stringify + } = ctx; + const inFlow = this.type === Type.FLOW_MAP || this.type === Type.FLOW_SEQ || ctx.inFlow; + if (inFlow) itemIndent += indentStep; + const allNullValues = isMap && this.hasAllNullValues(); + ctx = Object.assign({}, ctx, { + allNullValues, + indent: itemIndent, + inFlow, + type: null + }); + let chompKeep = false; + let hasItemWithNewLine = false; + const nodes = this.items.reduce((nodes, item, i) => { + let comment; + + if (item) { + if (!chompKeep && item.spaceBefore) nodes.push({ + type: 'comment', + str: '' + }); + if (item.commentBefore) item.commentBefore.match(/^.*$/gm).forEach(line => { + nodes.push({ + type: 'comment', + str: "#".concat(line) + }); + }); + if (item.comment) comment = item.comment; + if (inFlow && (!chompKeep && item.spaceBefore || item.commentBefore || item.comment || item.key && (item.key.commentBefore || item.key.comment) || item.value && (item.value.commentBefore || item.value.comment))) hasItemWithNewLine = true; + } + + chompKeep = false; + let str = stringify(item, ctx, () => comment = null, () => chompKeep = true); + if (inFlow && !hasItemWithNewLine && str.includes('\n')) hasItemWithNewLine = true; + if (inFlow && i < this.items.length - 1) str += ','; + str = addComment(str, itemIndent, comment); + if (chompKeep && (comment || inFlow)) chompKeep = false; + nodes.push({ + type: 'item', + str + }); + return nodes; + }, []); + let str; + + if (nodes.length === 0) { + str = flowChars.start + flowChars.end; + } else if (inFlow) { + const { + start, + end + } = flowChars; + const strings = nodes.map(n => n.str); + + if (hasItemWithNewLine || strings.reduce((sum, str) => sum + str.length + 2, 2) > Collection$1.maxFlowStringSingleLineLength) { + str = start; + + for (const s of strings) { + str += s ? "\n".concat(indentStep).concat(indent).concat(s) : '\n'; + } + + str += "\n".concat(indent).concat(end); + } else { + str = "".concat(start, " ").concat(strings.join(' '), " ").concat(end); + } + } else { + const strings = nodes.map(blockItem); + str = strings.shift(); + + for (const s of strings) str += s ? "\n".concat(indent).concat(s) : '\n'; + } + + if (this.comment) { + str += '\n' + this.comment.replace(/^/gm, "".concat(indent, "#")); + if (onComment) onComment(); + } else if (chompKeep && onChompKeep) onChompKeep(); + + return str; + } + +} + +_defineProperty(Collection$1, "maxFlowStringSingleLineLength", 60); + +/* global console, process */ +function warn(logLevel, warning) { + if (LogLevel.indexOf(logLevel) >= LogLevel.WARN) { + if (typeof process !== 'undefined' && process.emitWarning) process.emitWarning(warning);else console.warn(warning); + } +} + +function asItemIndex(key) { + let idx = key instanceof Scalar ? key.value : key; + if (idx && typeof idx === 'string') idx = Number(idx); + return Number.isInteger(idx) && idx >= 0 ? idx : null; +} + +class YAMLSeq extends Collection$1 { + add(value) { + this.items.push(value); + } + + delete(key) { + const idx = asItemIndex(key); + if (typeof idx !== 'number') return false; + const del = this.items.splice(idx, 1); + return del.length > 0; + } + + get(key, keepScalar) { + const idx = asItemIndex(key); + if (typeof idx !== 'number') return undefined; + const it = this.items[idx]; + return !keepScalar && it instanceof Scalar ? it.value : it; + } + + has(key) { + const idx = asItemIndex(key); + return typeof idx === 'number' && idx < this.items.length; + } + + set(key, value) { + const idx = asItemIndex(key); + if (typeof idx !== 'number') throw new Error("Expected a valid index, not ".concat(key, ".")); + const prev = this.items[idx]; + if (prev instanceof Scalar && isScalarValue(value)) prev.value = value;else this.items[idx] = value; + } + + toJSON(_, ctx) { + const seq = []; + if (ctx && ctx.onCreate) ctx.onCreate(seq); + let i = 0; + + for (const item of this.items) seq.push(toJS(item, String(i++), ctx)); + + return seq; + } + + toString(ctx, onComment, onChompKeep) { + if (!ctx) return JSON.stringify(this); + return super.toString(ctx, { + blockItem: n => n.type === 'comment' ? n.str : "- ".concat(n.str), + flowChars: { + start: '[', + end: ']' + }, + isMap: false, + itemIndent: (ctx.indent || '') + ' ' + }, onComment, onChompKeep); + } + +} + +function stringifyKey(key, jsKey, ctx) { + if (jsKey === null) return ''; + if (typeof jsKey !== 'object') return String(jsKey); + + if (key instanceof Node$1 && ctx && ctx.doc) { + const strKey = key.toString({ + anchors: Object.create(null), + doc: ctx.doc, + indent: '', + indentStep: ctx.indentStep, + inFlow: true, + inStringifyKey: true, + stringify: ctx.stringify + }); + + if (!ctx.mapKeyWarned) { + let jsonStr = JSON.stringify(strKey); + if (jsonStr.length > 40) jsonStr = jsonStr.split('').splice(36, '..."').join(''); + warn(ctx.doc.options.logLevel, "Keys with collection values will be stringified due to JS Object restrictions: ".concat(jsonStr, ". Set mapAsMap: true to use object keys.")); + ctx.mapKeyWarned = true; + } + + return strKey; + } + + return JSON.stringify(jsKey); +} + +function createPair(key, value, ctx) { + const k = createNode(key, null, ctx); + const v = createNode(value, null, ctx); + return new Pair(k, v); +} +class Pair extends Node$1 { + constructor(key, value = null) { + super(); + this.key = key; + this.value = value; + this.type = Pair.Type.PAIR; + } + + get commentBefore() { + return this.key instanceof Node$1 ? this.key.commentBefore : undefined; + } + + set commentBefore(cb) { + if (this.key == null) this.key = new Scalar(null); + if (this.key instanceof Node$1) this.key.commentBefore = cb;else { + const msg = 'Pair.commentBefore is an alias for Pair.key.commentBefore. To set it, the key must be a Node.'; + throw new Error(msg); + } + } + + addToJSMap(ctx, map) { + const key = toJS(this.key, '', ctx); + + if (map instanceof Map) { + const value = toJS(this.value, key, ctx); + map.set(key, value); + } else if (map instanceof Set) { + map.add(key); + } else { + const stringKey = stringifyKey(this.key, key, ctx); + const value = toJS(this.value, stringKey, ctx); + if (stringKey in map) Object.defineProperty(map, stringKey, { + value, + writable: true, + enumerable: true, + configurable: true + });else map[stringKey] = value; + } + + return map; + } + + toJSON(_, ctx) { + const pair = ctx && ctx.mapAsMap ? new Map() : {}; + return this.addToJSMap(ctx, pair); + } + + toString(ctx, onComment, onChompKeep) { + if (!ctx || !ctx.doc) return JSON.stringify(this); + const { + indent: indentSize, + indentSeq, + simpleKeys + } = ctx.doc.options; + let { + key, + value + } = this; + let keyComment = key instanceof Node$1 && key.comment; + + if (simpleKeys) { + if (keyComment) { + throw new Error('With simple keys, key nodes cannot have comments'); + } + + if (key instanceof Collection$1) { + const msg = 'With simple keys, collection cannot be used as a key value'; + throw new Error(msg); + } + } + + let explicitKey = !simpleKeys && (!key || keyComment || (key instanceof Node$1 ? key instanceof Collection$1 || key.type === Type.BLOCK_FOLDED || key.type === Type.BLOCK_LITERAL : typeof key === 'object')); + const { + allNullValues, + doc, + indent, + indentStep, + stringify + } = ctx; + ctx = Object.assign({}, ctx, { + implicitKey: !explicitKey && (simpleKeys || !allNullValues), + indent: indent + indentStep + }); + let chompKeep = false; + let str = stringify(key, ctx, () => keyComment = null, () => chompKeep = true); + str = addComment(str, ctx.indent, keyComment); + + if (!explicitKey && str.length > 1024) { + if (simpleKeys) throw new Error('With simple keys, single line scalar must not span more than 1024 characters'); + explicitKey = true; + } + + if (allNullValues && !simpleKeys) { + if (this.comment) { + str = addComment(str, ctx.indent, this.comment); + if (onComment) onComment(); + } else if (chompKeep && !keyComment && onChompKeep) onChompKeep(); + + return ctx.inFlow && !explicitKey ? str : "? ".concat(str); + } + + str = explicitKey ? "? ".concat(str, "\n").concat(indent, ":") : "".concat(str, ":"); + + if (this.comment) { + // expected (but not strictly required) to be a single-line comment + str = addComment(str, ctx.indent, this.comment); + if (onComment) onComment(); + } + + let vcb = ''; + let valueComment = null; + + if (value instanceof Node$1) { + if (value.spaceBefore) vcb = '\n'; + + if (value.commentBefore) { + const cs = value.commentBefore.replace(/^/gm, "".concat(ctx.indent, "#")); + vcb += "\n".concat(cs); + } + + valueComment = value.comment; + } else if (value && typeof value === 'object') { + value = doc.createNode(value); + } + + ctx.implicitKey = false; + if (!explicitKey && !this.comment && value instanceof Scalar) ctx.indentAtStart = str.length + 1; + chompKeep = false; + + if (!indentSeq && indentSize >= 2 && !ctx.inFlow && !explicitKey && value instanceof YAMLSeq && value.type !== Type.FLOW_SEQ && !value.tag && !doc.anchors.getName(value)) { + // If indentSeq === false, consider '- ' as part of indentation where possible + ctx.indent = ctx.indent.substr(2); + } + + const valueStr = stringify(value, ctx, () => valueComment = null, () => chompKeep = true); + let ws = ' '; + + if (vcb || this.comment) { + ws = "".concat(vcb, "\n").concat(ctx.indent); + } else if (!explicitKey && value instanceof Collection$1) { + const flow = valueStr[0] === '[' || valueStr[0] === '{'; + if (!flow || valueStr.includes('\n')) ws = "\n".concat(ctx.indent); + } else if (valueStr[0] === '\n') ws = ''; + + if (chompKeep && !valueComment && onChompKeep) onChompKeep(); + return addComment(str + ws + valueStr, ctx.indent, valueComment); + } + +} + +_defineProperty(Pair, "Type", { + PAIR: 'PAIR', + MERGE_PAIR: 'MERGE_PAIR' +}); + +const getAliasCount = (node, anchors) => { + if (node instanceof Alias$1) { + const anchor = anchors.get(node.source); + return anchor.count * anchor.aliasCount; + } else if (node instanceof Collection$1) { + let count = 0; + + for (const item of node.items) { + const c = getAliasCount(item, anchors); + if (c > count) count = c; + } + + return count; + } else if (node instanceof Pair) { + const kc = getAliasCount(node.key, anchors); + const vc = getAliasCount(node.value, anchors); + return Math.max(kc, vc); + } + + return 1; +}; + +class Alias$1 extends Node$1 { + static stringify({ + range, + source + }, { + anchors, + doc, + implicitKey, + inStringifyKey + }) { + let anchor = Object.keys(anchors).find(a => anchors[a] === source); + if (!anchor && inStringifyKey) anchor = doc.anchors.getName(source) || doc.anchors.newName(); + if (anchor) return "*".concat(anchor).concat(implicitKey ? ' ' : ''); + const msg = doc.anchors.getName(source) ? 'Alias node must be after source node' : 'Source node not found for alias node'; + throw new Error("".concat(msg, " [").concat(range, "]")); + } + + constructor(source) { + super(); + this.source = source; + this.type = Type.ALIAS; + } + + set tag(t) { + throw new Error('Alias nodes cannot have tags'); + } + + toJSON(arg, ctx) { + if (!ctx) return toJS(this.source, arg, ctx); + const { + anchors, + maxAliasCount + } = ctx; + const anchor = anchors.get(this.source); + /* istanbul ignore if */ + + if (!anchor || anchor.res === undefined) { + const msg = 'This should not happen: Alias anchor was not resolved?'; + if (this.cstNode) throw new YAMLReferenceError(this.cstNode, msg);else throw new ReferenceError(msg); + } + + if (maxAliasCount >= 0) { + anchor.count += 1; + if (anchor.aliasCount === 0) anchor.aliasCount = getAliasCount(this.source, anchors); + + if (anchor.count * anchor.aliasCount > maxAliasCount) { + const msg = 'Excessive alias count indicates a resource exhaustion attack'; + if (this.cstNode) throw new YAMLReferenceError(this.cstNode, msg);else throw new ReferenceError(msg); + } + } + + return anchor.res; + } // Only called when stringifying an alias mapping key while constructing + // Object output. + + + toString(ctx) { + return Alias$1.stringify(this, ctx); + } + +} + +_defineProperty(Alias$1, "default", true); + +function resolveScalar(str, tags) { + for (const { + format, + test, + resolve + } of tags) { + if (test && test.test(str)) { + let res = resolve(str); + if (!(res instanceof Scalar)) res = new Scalar(res); + if (format) res.format = format; + return res; + } + } + + return new Scalar(str); // fallback to string +} + +const FOLD_FLOW = 'flow'; +const FOLD_BLOCK = 'block'; +const FOLD_QUOTED = 'quoted'; // presumes i+1 is at the start of a line +// returns index of last newline in more-indented block + +const consumeMoreIndentedLines = (text, i) => { + let ch = text[i + 1]; + + while (ch === ' ' || ch === '\t') { + do { + ch = text[i += 1]; + } while (ch && ch !== '\n'); + + ch = text[i + 1]; + } + + return i; +}; +/** + * Tries to keep input at up to `lineWidth` characters, splitting only on spaces + * not followed by newlines or spaces unless `mode` is `'quoted'`. Lines are + * terminated with `\n` and started with `indent`. + * + * @param {string} text + * @param {string} indent + * @param {string} [mode='flow'] `'block'` prevents more-indented lines + * from being folded; `'quoted'` allows for `\` escapes, including escaped + * newlines + * @param {Object} options + * @param {number} [options.indentAtStart] Accounts for leading contents on + * the first line, defaulting to `indent.length` + * @param {number} [options.lineWidth=80] + * @param {number} [options.minContentWidth=20] Allow highly indented lines to + * stretch the line width or indent content from the start + * @param {function} options.onFold Called once if the text is folded + * @param {function} options.onFold Called once if any line of text exceeds + * lineWidth characters + */ + + +function foldFlowLines(text, indent, mode, { + indentAtStart, + lineWidth = 80, + minContentWidth = 20, + onFold, + onOverflow +}) { + if (!lineWidth || lineWidth < 0) return text; + const endStep = Math.max(1 + minContentWidth, 1 + lineWidth - indent.length); + if (text.length <= endStep) return text; + const folds = []; + const escapedFolds = {}; + let end = lineWidth - indent.length; + + if (typeof indentAtStart === 'number') { + if (indentAtStart > lineWidth - Math.max(2, minContentWidth)) folds.push(0);else end = lineWidth - indentAtStart; + } + + let split = undefined; + let prev = undefined; + let overflow = false; + let i = -1; + let escStart = -1; + let escEnd = -1; + + if (mode === FOLD_BLOCK) { + i = consumeMoreIndentedLines(text, i); + if (i !== -1) end = i + endStep; + } + + for (let ch; ch = text[i += 1];) { + if (mode === FOLD_QUOTED && ch === '\\') { + escStart = i; + + switch (text[i + 1]) { + case 'x': + i += 3; + break; + + case 'u': + i += 5; + break; + + case 'U': + i += 9; + break; + + default: + i += 1; + } + + escEnd = i; + } + + if (ch === '\n') { + if (mode === FOLD_BLOCK) i = consumeMoreIndentedLines(text, i); + end = i + endStep; + split = undefined; + } else { + if (ch === ' ' && prev && prev !== ' ' && prev !== '\n' && prev !== '\t') { + // space surrounded by non-space can be replaced with newline + indent + const next = text[i + 1]; + if (next && next !== ' ' && next !== '\n' && next !== '\t') split = i; + } + + if (i >= end) { + if (split) { + folds.push(split); + end = split + endStep; + split = undefined; + } else if (mode === FOLD_QUOTED) { + // white-space collected at end may stretch past lineWidth + while (prev === ' ' || prev === '\t') { + prev = ch; + ch = text[i += 1]; + overflow = true; + } // Account for newline escape, but don't break preceding escape + + + const j = i > escEnd + 1 ? i - 2 : escStart - 1; // Bail out if lineWidth & minContentWidth are shorter than an escape string + + if (escapedFolds[j]) return text; + folds.push(j); + escapedFolds[j] = true; + end = j + endStep; + split = undefined; + } else { + overflow = true; + } + } + } + + prev = ch; + } + + if (overflow && onOverflow) onOverflow(); + if (folds.length === 0) return text; + if (onFold) onFold(); + let res = text.slice(0, folds[0]); + + for (let i = 0; i < folds.length; ++i) { + const fold = folds[i]; + const end = folds[i + 1] || text.length; + if (fold === 0) res = "\n".concat(indent).concat(text.slice(0, end));else { + if (mode === FOLD_QUOTED && escapedFolds[fold]) res += "".concat(text[fold], "\\"); + res += "\n".concat(indent).concat(text.slice(fold + 1, end)); + } + } + + return res; +} + +const getFoldOptions = ({ + indentAtStart +}) => indentAtStart ? Object.assign({ + indentAtStart +}, strOptions.fold) : strOptions.fold; // Also checks for lines starting with %, as parsing the output as YAML 1.1 will +// presume that's starting a new document. + + +const containsDocumentMarker = str => /^(%|---|\.\.\.)/m.test(str); + +function lineLengthOverLimit(str, limit) { + const strLen = str.length; + if (strLen <= limit) return false; + + for (let i = 0, start = 0; i < strLen; ++i) { + if (str[i] === '\n') { + if (i - start > limit) return true; + start = i + 1; + if (strLen - start <= limit) return false; + } + } + + return true; +} + +function doubleQuotedString(value, ctx) { + const { + implicitKey + } = ctx; + const { + jsonEncoding, + minMultiLineLength + } = strOptions.doubleQuoted; + const json = JSON.stringify(value); + if (jsonEncoding) return json; + const indent = ctx.indent || (containsDocumentMarker(value) ? ' ' : ''); + let str = ''; + let start = 0; + + for (let i = 0, ch = json[i]; ch; ch = json[++i]) { + if (ch === ' ' && json[i + 1] === '\\' && json[i + 2] === 'n') { + // space before newline needs to be escaped to not be folded + str += json.slice(start, i) + '\\ '; + i += 1; + start = i; + ch = '\\'; + } + + if (ch === '\\') switch (json[i + 1]) { + case 'u': + { + str += json.slice(start, i); + const code = json.substr(i + 2, 4); + + switch (code) { + case '0000': + str += '\\0'; + break; + + case '0007': + str += '\\a'; + break; + + case '000b': + str += '\\v'; + break; + + case '001b': + str += '\\e'; + break; + + case '0085': + str += '\\N'; + break; + + case '00a0': + str += '\\_'; + break; + + case '2028': + str += '\\L'; + break; + + case '2029': + str += '\\P'; + break; + + default: + if (code.substr(0, 2) === '00') str += '\\x' + code.substr(2);else str += json.substr(i, 6); + } + + i += 5; + start = i + 1; + } + break; + + case 'n': + if (implicitKey || json[i + 2] === '"' || json.length < minMultiLineLength) { + i += 1; + } else { + // folding will eat first newline + str += json.slice(start, i) + '\n\n'; + + while (json[i + 2] === '\\' && json[i + 3] === 'n' && json[i + 4] !== '"') { + str += '\n'; + i += 2; + } + + str += indent; // space after newline needs to be escaped to not be folded + + if (json[i + 2] === ' ') str += '\\'; + i += 1; + start = i + 1; + } + + break; + + default: + i += 1; + } + } + + str = start ? str + json.slice(start) : json; + return implicitKey ? str : foldFlowLines(str, indent, FOLD_QUOTED, getFoldOptions(ctx)); +} + +function singleQuotedString(value, ctx) { + if (ctx.implicitKey) { + if (/\n/.test(value)) return doubleQuotedString(value, ctx); + } else { + // single quoted string can't have leading or trailing whitespace around newline + if (/[ \t]\n|\n[ \t]/.test(value)) return doubleQuotedString(value, ctx); + } + + const indent = ctx.indent || (containsDocumentMarker(value) ? ' ' : ''); + const res = "'" + value.replace(/'/g, "''").replace(/\n+/g, "$&\n".concat(indent)) + "'"; + return ctx.implicitKey ? res : foldFlowLines(res, indent, FOLD_FLOW, getFoldOptions(ctx)); +} + +function blockString({ + comment, + type, + value +}, ctx, onComment, onChompKeep) { + // 1. Block can't end in whitespace unless the last line is non-empty. + // 2. Strings consisting of only whitespace are best rendered explicitly. + if (/\n[\t ]+$/.test(value) || /^\s*$/.test(value)) { + return doubleQuotedString(value, ctx); + } + + const indent = ctx.indent || (ctx.forceBlockIndent || containsDocumentMarker(value) ? ' ' : ''); + const indentSize = indent ? '2' : '1'; // root is at -1 + + const literal = type === Type.BLOCK_FOLDED ? false : type === Type.BLOCK_LITERAL ? true : !lineLengthOverLimit(value, strOptions.fold.lineWidth - indent.length); + let header = literal ? '|' : '>'; + if (!value) return header + '\n'; + let wsStart = ''; + let wsEnd = ''; + value = value.replace(/[\n\t ]*$/, ws => { + const n = ws.indexOf('\n'); + + if (n === -1) { + header += '-'; // strip + } else if (value === ws || n !== ws.length - 1) { + header += '+'; // keep + + if (onChompKeep) onChompKeep(); + } + + wsEnd = ws.replace(/\n$/, ''); + return ''; + }).replace(/^[\n ]*/, ws => { + if (ws.indexOf(' ') !== -1) header += indentSize; + const m = ws.match(/ +$/); + + if (m) { + wsStart = ws.slice(0, -m[0].length); + return m[0]; + } else { + wsStart = ws; + return ''; + } + }); + if (wsEnd) wsEnd = wsEnd.replace(/\n+(?!\n|$)/g, "$&".concat(indent)); + if (wsStart) wsStart = wsStart.replace(/\n+/g, "$&".concat(indent)); + + if (comment) { + header += ' #' + comment.replace(/ ?[\r\n]+/g, ' '); + if (onComment) onComment(); + } + + if (!value) return "".concat(header).concat(indentSize, "\n").concat(indent).concat(wsEnd); + + if (literal) { + value = value.replace(/\n+/g, "$&".concat(indent)); + return "".concat(header, "\n").concat(indent).concat(wsStart).concat(value).concat(wsEnd); + } + + value = value.replace(/\n+/g, '\n$&').replace(/(?:^|\n)([\t ].*)(?:([\n\t ]*)\n(?![\n\t ]))?/g, '$1$2') // more-indented lines aren't folded + // ^ ind.line ^ empty ^ capture next empty lines only at end of indent + .replace(/\n+/g, "$&".concat(indent)); + const body = foldFlowLines("".concat(wsStart).concat(value).concat(wsEnd), indent, FOLD_BLOCK, strOptions.fold); + return "".concat(header, "\n").concat(indent).concat(body); +} + +function plainString(item, ctx, onComment, onChompKeep) { + const { + comment, + type, + value + } = item; + const { + actualString, + implicitKey, + indent, + inFlow + } = ctx; + + if (implicitKey && /[\n[\]{},]/.test(value) || inFlow && /[[\]{},]/.test(value)) { + return doubleQuotedString(value, ctx); + } + + if (!value || /^[\n\t ,[\]{}#&*!|>'"%@`]|^[?-]$|^[?-][ \t]|[\n:][ \t]|[ \t]\n|[\n\t ]#|[\n\t :]$/.test(value)) { + const hasDouble = value.indexOf('"') !== -1; + const hasSingle = value.indexOf("'") !== -1; + let quotedString; + + if (hasDouble && !hasSingle) { + quotedString = singleQuotedString; + } else if (hasSingle && !hasDouble) { + quotedString = doubleQuotedString; + } else if (strOptions.defaultQuoteSingle) { + quotedString = singleQuotedString; + } else { + quotedString = doubleQuotedString; + } // not allowed: + // - empty string, '-' or '?' + // - start with an indicator character (except [?:-]) or /[?-] / + // - '\n ', ': ' or ' \n' anywhere + // - '#' not preceded by a non-space char + // - end with ' ' or ':' + + + return implicitKey || inFlow || value.indexOf('\n') === -1 ? quotedString(value, ctx) : blockString(item, ctx, onComment, onChompKeep); + } + + if (!implicitKey && !inFlow && type !== Type.PLAIN && value.indexOf('\n') !== -1) { + // Where allowed & type not set explicitly, prefer block style for multiline strings + return blockString(item, ctx, onComment, onChompKeep); + } + + if (indent === '' && containsDocumentMarker(value)) { + ctx.forceBlockIndent = true; + return blockString(item, ctx, onComment, onChompKeep); + } + + const str = value.replace(/\n+/g, "$&\n".concat(indent)); // Verify that output will be parsed as a string, as e.g. plain numbers and + // booleans get parsed with those types in v1.2 (e.g. '42', 'true' & '0.9e-3'), + // and others in v1.1. + + if (actualString) { + const { + tags + } = ctx.doc.schema; + const resolved = resolveScalar(str, tags).value; + if (typeof resolved !== 'string') return doubleQuotedString(value, ctx); + } + + const body = implicitKey ? str : foldFlowLines(str, indent, FOLD_FLOW, getFoldOptions(ctx)); + + if (comment && !inFlow && (body.indexOf('\n') !== -1 || comment.indexOf('\n') !== -1)) { + if (onComment) onComment(); + return addCommentBefore(body, indent, comment); + } + + return body; +} + +function stringifyString(item, ctx, onComment, onChompKeep) { + const { + defaultKeyType, + defaultType + } = strOptions; + const { + implicitKey, + inFlow + } = ctx; + let { + type, + value + } = item; + + if (typeof value !== 'string') { + value = String(value); + item = Object.assign({}, item, { + value + }); + } + + if (type !== Type.QUOTE_DOUBLE) { + // force double quotes on control characters & unpaired surrogates + if (/[\x00-\x08\x0b-\x1f\x7f-\x9f\u{D800}-\u{DFFF}]/u.test(value)) type = Type.QUOTE_DOUBLE; + } + + const _stringify = _type => { + switch (_type) { + case Type.BLOCK_FOLDED: + case Type.BLOCK_LITERAL: + return implicitKey || inFlow ? doubleQuotedString(value, ctx) // blocks are not valid inside flow containers + : blockString(item, ctx, onComment, onChompKeep); + + case Type.QUOTE_DOUBLE: + return doubleQuotedString(value, ctx); + + case Type.QUOTE_SINGLE: + return singleQuotedString(value, ctx); + + case Type.PLAIN: + return plainString(item, ctx, onComment, onChompKeep); + + default: + return null; + } + }; + + let res = _stringify(type); + + if (res === null) { + const t = implicitKey ? defaultKeyType : defaultType; + res = _stringify(t); + if (res === null) throw new Error("Unsupported default string type ".concat(t)); + } + + return res; +} + +function stringifyTag(doc, tag) { + if ((doc.version || doc.options.version) === '1.0') { + const priv = tag.match(/^tag:private\.yaml\.org,2002:([^:/]+)$/); + if (priv) return '!' + priv[1]; + const vocab = tag.match(/^tag:([a-zA-Z0-9-]+)\.yaml\.org,2002:(.*)/); + return vocab ? "!".concat(vocab[1], "/").concat(vocab[2]) : "!".concat(tag.replace(/^tag:/, '')); + } + + let p = doc.tagPrefixes.find(p => tag.indexOf(p.prefix) === 0); + + if (!p) { + const dtp = doc.getDefaults().tagPrefixes; + p = dtp && dtp.find(p => tag.indexOf(p.prefix) === 0); + } + + if (!p) return tag[0] === '!' ? tag : "!<".concat(tag, ">"); + const suffix = tag.substr(p.prefix.length).replace(/[!,[\]{}]/g, ch => ({ + '!': '%21', + ',': '%2C', + '[': '%5B', + ']': '%5D', + '{': '%7B', + '}': '%7D' + })[ch]); + return p.handle + suffix; +} + +function getTagObject(tags, item) { + if (item instanceof Alias$1) return Alias$1; + + if (item.tag) { + const match = tags.filter(t => t.tag === item.tag); + if (match.length > 0) return match.find(t => t.format === item.format) || match[0]; + } + + let tagObj, obj; + + if (item instanceof Scalar) { + obj = item.value; + const match = tags.filter(t => t.identify && t.identify(obj)); + tagObj = match.find(t => t.format === item.format) || match.find(t => !t.format); + } else { + obj = item; + tagObj = tags.find(t => t.nodeClass && obj instanceof t.nodeClass); + } + + if (!tagObj) { + const name = obj && obj.constructor ? obj.constructor.name : typeof obj; + throw new Error("Tag not resolved for ".concat(name, " value")); + } + + return tagObj; +} // needs to be called before value stringifier to allow for circular anchor refs + + +function stringifyProps(node, tagObj, { + anchors, + doc +}) { + const props = []; + const anchor = doc.anchors.getName(node); + + if (anchor) { + anchors[anchor] = node; + props.push("&".concat(anchor)); + } + + if (node.tag) { + props.push(stringifyTag(doc, node.tag)); + } else if (!tagObj.default) { + props.push(stringifyTag(doc, tagObj.tag)); + } + + return props.join(' '); +} + +function stringify(item, ctx, onComment, onChompKeep) { + const { + schema + } = ctx.doc; + let tagObj; + + if (!(item instanceof Node$1)) { + item = ctx.doc.createNode(item, { + onTagObj: o => tagObj = o, + wrapScalars: true + }); + } + + if (item instanceof Pair) return item.toString(ctx, onComment, onChompKeep); + if (!tagObj) tagObj = getTagObject(schema.tags, item); + const props = stringifyProps(item, tagObj, ctx); + if (props.length > 0) ctx.indentAtStart = (ctx.indentAtStart || 0) + props.length + 1; + const str = typeof tagObj.stringify === 'function' ? tagObj.stringify(item, ctx, onComment, onChompKeep) : item instanceof Scalar ? stringifyString(item, ctx, onComment, onChompKeep) : item.toString(ctx, onComment, onChompKeep); + if (!props) return str; + return item instanceof Scalar || str[0] === '{' || str[0] === '[' ? "".concat(props, " ").concat(str) : "".concat(props, "\n").concat(ctx.indent).concat(str); +} + +function findPair(items, key) { + const k = key instanceof Scalar ? key.value : key; + + for (const it of items) { + if (it instanceof Pair) { + if (it.key === key || it.key === k) return it; + if (it.key && it.key.value === k) return it; + } + } + + return undefined; +} +class YAMLMap extends Collection$1 { + add(pair, overwrite) { + if (!pair) pair = new Pair(pair);else if (!(pair instanceof Pair)) pair = new Pair(pair.key || pair, pair.value); + const prev = findPair(this.items, pair.key); + const sortEntries = this.schema && this.schema.sortMapEntries; + + if (prev) { + if (!overwrite) throw new Error("Key ".concat(pair.key, " already set")); // For scalars, keep the old node & its comments and anchors + + if (prev.value instanceof Scalar && isScalarValue(pair.value)) prev.value.value = pair.value;else prev.value = pair.value; + } else if (sortEntries) { + const i = this.items.findIndex(item => sortEntries(pair, item) < 0); + if (i === -1) this.items.push(pair);else this.items.splice(i, 0, pair); + } else { + this.items.push(pair); + } + } + + delete(key) { + const it = findPair(this.items, key); + if (!it) return false; + const del = this.items.splice(this.items.indexOf(it), 1); + return del.length > 0; + } + + get(key, keepScalar) { + const it = findPair(this.items, key); + const node = it && it.value; + return !keepScalar && node instanceof Scalar ? node.value : node; + } + + has(key) { + return !!findPair(this.items, key); + } + + set(key, value) { + this.add(new Pair(key, value), true); + } + /** + * @param ctx - Conversion context, originally set in Document#toJS() + * @param {Class} Type - If set, forces the returned collection type + * @returns Instance of Type, Map, or Object + */ + + + toJSON(_, ctx, Type) { + const map = Type ? new Type() : ctx && ctx.mapAsMap ? new Map() : {}; + if (ctx && ctx.onCreate) ctx.onCreate(map); + + for (const item of this.items) item.addToJSMap(ctx, map); + + return map; + } + + toString(ctx, onComment, onChompKeep) { + if (!ctx) return JSON.stringify(this); + + for (const item of this.items) { + if (!(item instanceof Pair)) throw new Error("Map items must all be pairs; found ".concat(JSON.stringify(item), " instead")); + } + + return super.toString(ctx, { + blockItem: n => n.str, + flowChars: { + start: '{', + end: '}' + }, + isMap: true, + itemIndent: ctx.indent || '' + }, onComment, onChompKeep); + } + +} + +const MERGE_KEY = '<<'; +class Merge extends Pair { + constructor(pair) { + if (pair instanceof Pair) { + let seq = pair.value; + + if (!(seq instanceof YAMLSeq)) { + seq = new YAMLSeq(); + seq.items.push(pair.value); + seq.range = pair.value.range; + } + + super(pair.key, seq); + this.range = pair.range; + } else { + super(new Scalar(MERGE_KEY), new YAMLSeq()); + } + + this.type = Pair.Type.MERGE_PAIR; + } // If the value associated with a merge key is a single mapping node, each of + // its key/value pairs is inserted into the current mapping, unless the key + // already exists in it. If the value associated with the merge key is a + // sequence, then this sequence is expected to contain mapping nodes and each + // of these nodes is merged in turn according to its order in the sequence. + // Keys in mapping nodes earlier in the sequence override keys specified in + // later mapping nodes. -- http://yaml.org/type/merge.html + + + addToJSMap(ctx, map) { + for (const { + source + } of this.value.items) { + if (!(source instanceof YAMLMap)) throw new Error('Merge sources must be maps'); + const srcMap = source.toJSON(null, ctx, Map); + + for (const [key, value] of srcMap) { + if (map instanceof Map) { + if (!map.has(key)) map.set(key, value); + } else if (map instanceof Set) { + map.add(key); + } else if (!Object.prototype.hasOwnProperty.call(map, key)) { + Object.defineProperty(map, key, { + value, + writable: true, + enumerable: true, + configurable: true + }); + } + } + } + + return map; + } + + toString(ctx, onComment) { + const seq = this.value; + if (seq.items.length > 1) return super.toString(ctx, onComment); + this.value = seq.items[0]; + const str = super.toString(ctx, onComment); + this.value = seq; + return str; + } + +} + +class Anchors { + static validAnchorNode(node) { + return node instanceof Scalar || node instanceof YAMLSeq || node instanceof YAMLMap; + } + + constructor(prefix) { + _defineProperty(this, "map", Object.create(null)); + + this.prefix = prefix; + } + + createAlias(node, name) { + this.setAnchor(node, name); + return new Alias$1(node); + } + + createMergePair(...sources) { + const merge = new Merge(); + merge.value.items = sources.map(s => { + if (s instanceof Alias$1) { + if (s.source instanceof YAMLMap) return s; + } else if (s instanceof YAMLMap) { + return this.createAlias(s); + } + + throw new Error('Merge sources must be Map nodes or their Aliases'); + }); + return merge; + } + + getName(node) { + const { + map + } = this; + return Object.keys(map).find(a => map[a] === node); + } + + getNames() { + return Object.keys(this.map); + } + + getNode(name) { + return this.map[name]; + } + + newName(prefix) { + if (!prefix) prefix = this.prefix; + const names = Object.keys(this.map); + + for (let i = 1; true; ++i) { + const name = "".concat(prefix).concat(i); + if (!names.includes(name)) return name; + } + } // During parsing, map & aliases contain CST nodes + + + resolveNodes() { + const { + map, + _cstAliases + } = this; + Object.keys(map).forEach(a => { + map[a] = map[a].resolved; + }); + + _cstAliases.forEach(a => { + a.source = a.source.resolved; + }); + + delete this._cstAliases; + } + + setAnchor(node, name) { + if (node != null && !Anchors.validAnchorNode(node)) { + throw new Error('Anchors may only be set for Scalar, Seq and Map nodes'); + } + + if (name && /[\x00-\x19\s,[\]{}]/.test(name)) { + throw new Error('Anchor names must not contain whitespace or control characters'); + } + + const { + map + } = this; + const prev = node && Object.keys(map).find(a => map[a] === node); + + if (prev) { + if (!name) { + return prev; + } else if (prev !== name) { + delete map[prev]; + map[name] = node; + } + } else { + if (!name) { + if (!node) return null; + name = this.newName(); + } + + map[name] = node; + } + + return name; + } + +} + +function stringifyNumber({ + format, + minFractionDigits, + tag, + value +}) { + if (typeof value === 'bigint') return String(value); + if (!isFinite(value)) return isNaN(value) ? '.nan' : value < 0 ? '-.inf' : '.inf'; + let n = JSON.stringify(value); + + if (!format && minFractionDigits && (!tag || tag === 'tag:yaml.org,2002:float') && /^\d/.test(n)) { + let i = n.indexOf('.'); + + if (i < 0) { + i = n.length; + n += '.'; + } + + let d = minFractionDigits - (n.length - i - 1); + + while (d-- > 0) n += '0'; + } + + return n; +} + +function createMap(schema, obj, ctx) { + const { + keepUndefined, + replacer + } = ctx; + const map = new YAMLMap(schema); + + const add = (key, value) => { + if (typeof replacer === 'function') value = replacer.call(obj, key, value);else if (Array.isArray(replacer) && !replacer.includes(key)) return; + if (value !== undefined || keepUndefined) map.items.push(createPair(key, value, ctx)); + }; + + if (obj instanceof Map) { + for (const [key, value] of obj) add(key, value); + } else if (obj && typeof obj === 'object') { + for (const key of Object.keys(obj)) add(key, obj[key]); + } + + if (typeof schema.sortMapEntries === 'function') { + map.items.sort(schema.sortMapEntries); + } + + return map; +} + +const map = { + createNode: createMap, + default: true, + nodeClass: YAMLMap, + tag: 'tag:yaml.org,2002:map', + resolve: map => map +}; + +function createSeq(schema, obj, ctx) { + const { + replacer + } = ctx; + const seq = new YAMLSeq(schema); + + if (obj && obj[Symbol.iterator]) { + let i = 0; + + for (let it of obj) { + if (typeof replacer === 'function') { + const key = obj instanceof Set ? it : String(i++); + it = replacer.call(obj, key, it); + } + + seq.items.push(createNode(it, null, ctx)); + } + } + + return seq; +} + +const seq = { + createNode: createSeq, + default: true, + nodeClass: YAMLSeq, + tag: 'tag:yaml.org,2002:seq', + resolve: seq => seq +}; + +const string = { + identify: value => typeof value === 'string', + default: true, + tag: 'tag:yaml.org,2002:str', + resolve: str => str, + + stringify(item, ctx, onComment, onChompKeep) { + ctx = Object.assign({ + actualString: true + }, ctx); + return stringifyString(item, ctx, onComment, onChompKeep); + }, + + options: strOptions +}; + +const failsafe = [map, seq, string]; + +/* global BigInt */ + +const intIdentify = value => typeof value === 'bigint' || Number.isInteger(value); + +const intResolve = (src, offset, radix) => intOptions.asBigInt ? BigInt(src) : parseInt(src.substring(offset), radix); + +function intStringify(node, radix, prefix) { + const { + value + } = node; + if (intIdentify(value) && value >= 0) return prefix + value.toString(radix); + return stringifyNumber(node); +} + +function stringifyBool(node) { + const { + value, + sourceStr + } = node; + + if (sourceStr) { + const match = boolObj.test.test(sourceStr); + if (match && value === (sourceStr[0] === 't' || sourceStr[0] === 'T')) return sourceStr; + } + + return value ? boolOptions.trueStr : boolOptions.falseStr; +} + +const nullObj = { + identify: value => value == null, + createNode: (schema, value, ctx) => ctx.wrapScalars ? new Scalar(null) : null, + default: true, + tag: 'tag:yaml.org,2002:null', + test: /^(?:~|[Nn]ull|NULL)?$/, + resolve: str => { + const node = new Scalar(null); + node.sourceStr = str; + return node; + }, + options: nullOptions, + stringify: ({ + sourceStr + }) => sourceStr !== null && sourceStr !== void 0 ? sourceStr : nullOptions.nullStr +}; +const boolObj = { + identify: value => typeof value === 'boolean', + default: true, + tag: 'tag:yaml.org,2002:bool', + test: /^(?:[Tt]rue|TRUE|[Ff]alse|FALSE)$/, + resolve: str => { + const node = new Scalar(str[0] === 't' || str[0] === 'T'); + node.sourceStr = str; + return node; + }, + options: boolOptions, + stringify: stringifyBool +}; +const octObj = { + identify: value => intIdentify(value) && value >= 0, + default: true, + tag: 'tag:yaml.org,2002:int', + format: 'OCT', + test: /^0o[0-7]+$/, + resolve: str => intResolve(str, 2, 8), + options: intOptions, + stringify: node => intStringify(node, 8, '0o') +}; +const intObj = { + identify: intIdentify, + default: true, + tag: 'tag:yaml.org,2002:int', + test: /^[-+]?[0-9]+$/, + resolve: str => intResolve(str, 0, 10), + options: intOptions, + stringify: stringifyNumber +}; +const hexObj = { + identify: value => intIdentify(value) && value >= 0, + default: true, + tag: 'tag:yaml.org,2002:int', + format: 'HEX', + test: /^0x[0-9a-fA-F]+$/, + resolve: str => intResolve(str, 2, 16), + options: intOptions, + stringify: node => intStringify(node, 16, '0x') +}; +const nanObj = { + identify: value => typeof value === 'number', + default: true, + tag: 'tag:yaml.org,2002:float', + test: /^(?:[-+]?\.(?:inf|Inf|INF|nan|NaN|NAN))$/, + resolve: str => str.slice(-3).toLowerCase() === 'nan' ? NaN : str[0] === '-' ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY, + stringify: stringifyNumber +}; +const expObj = { + identify: value => typeof value === 'number', + default: true, + tag: 'tag:yaml.org,2002:float', + format: 'EXP', + test: /^[-+]?(?:\.[0-9]+|[0-9]+(?:\.[0-9]*)?)[eE][-+]?[0-9]+$/, + resolve: str => parseFloat(str), + stringify: ({ + value + }) => Number(value).toExponential() +}; +const floatObj = { + identify: value => typeof value === 'number', + default: true, + tag: 'tag:yaml.org,2002:float', + test: /^[-+]?(?:\.[0-9]+|[0-9]+\.[0-9]*)$/, + + resolve(str) { + const node = new Scalar(parseFloat(str)); + const dot = str.indexOf('.'); + if (dot !== -1 && str[str.length - 1] === '0') node.minFractionDigits = str.length - dot - 1; + return node; + }, + + stringify: stringifyNumber +}; +const core = failsafe.concat([nullObj, boolObj, octObj, intObj, hexObj, nanObj, expObj, floatObj]); + +/* global BigInt */ + +const intIdentify$1 = value => typeof value === 'bigint' || Number.isInteger(value); + +const stringifyJSON = ({ + value +}) => JSON.stringify(value); + +const json = [map, seq, { + identify: value => typeof value === 'string', + default: true, + tag: 'tag:yaml.org,2002:str', + resolve: str => str, + stringify: stringifyJSON +}, { + identify: value => value == null, + createNode: (schema, value, ctx) => ctx.wrapScalars ? new Scalar(null) : null, + default: true, + tag: 'tag:yaml.org,2002:null', + test: /^null$/, + resolve: () => null, + stringify: stringifyJSON +}, { + identify: value => typeof value === 'boolean', + default: true, + tag: 'tag:yaml.org,2002:bool', + test: /^true|false$/, + resolve: str => str === 'true', + stringify: stringifyJSON +}, { + identify: intIdentify$1, + default: true, + tag: 'tag:yaml.org,2002:int', + test: /^-?(?:0|[1-9][0-9]*)$/, + resolve: str => intOptions.asBigInt ? BigInt(str) : parseInt(str, 10), + stringify: ({ + value + }) => intIdentify$1(value) ? value.toString() : JSON.stringify(value) +}, { + identify: value => typeof value === 'number', + default: true, + tag: 'tag:yaml.org,2002:float', + test: /^-?(?:0|[1-9][0-9]*)(?:\.[0-9]*)?(?:[eE][-+]?[0-9]+)?$/, + resolve: str => parseFloat(str), + stringify: stringifyJSON +}, { + default: true, + test: /^/, + + resolve(str, onError) { + onError("Unresolved plain scalar ".concat(JSON.stringify(str))); + return str; + } + +}]; + +/* global atob, btoa, Buffer */ +const binary = { + identify: value => value instanceof Uint8Array, + // Buffer inherits from Uint8Array + default: false, + tag: 'tag:yaml.org,2002:binary', + + /** + * Returns a Buffer in node and an Uint8Array in browsers + * + * To use the resulting buffer as an image, you'll want to do something like: + * + * const blob = new Blob([buffer], { type: 'image/jpeg' }) + * document.querySelector('#photo').src = URL.createObjectURL(blob) + */ + resolve(src, onError) { + if (typeof Buffer === 'function') { + return Buffer.from(src, 'base64'); + } else if (typeof atob === 'function') { + // On IE 11, atob() can't handle newlines + const str = atob(src.replace(/[\n\r]/g, '')); + const buffer = new Uint8Array(str.length); + + for (let i = 0; i < str.length; ++i) buffer[i] = str.charCodeAt(i); + + return buffer; + } else { + onError('This environment does not support reading binary tags; either Buffer or atob is required'); + return src; + } + }, + + options: binaryOptions, + stringify: ({ + comment, + type, + value + }, ctx, onComment, onChompKeep) => { + let src; + + if (typeof Buffer === 'function') { + src = value instanceof Buffer ? value.toString('base64') : Buffer.from(value.buffer).toString('base64'); + } else if (typeof btoa === 'function') { + let s = ''; + + for (let i = 0; i < value.length; ++i) s += String.fromCharCode(value[i]); + + src = btoa(s); + } else { + throw new Error('This environment does not support writing binary tags; either Buffer or btoa is required'); + } + + if (!type) type = binaryOptions.defaultType; + + if (type === Type.QUOTE_DOUBLE) { + value = src; + } else { + const { + lineWidth + } = binaryOptions; + const n = Math.ceil(src.length / lineWidth); + const lines = new Array(n); + + for (let i = 0, o = 0; i < n; ++i, o += lineWidth) { + lines[i] = src.substr(o, lineWidth); + } + + value = lines.join(type === Type.BLOCK_LITERAL ? '\n' : ' '); + } + + return stringifyString({ + comment, + type, + value + }, ctx, onComment, onChompKeep); + } +}; + +function parsePairs(seq, onError) { + if (seq instanceof YAMLSeq) { + for (let i = 0; i < seq.items.length; ++i) { + let item = seq.items[i]; + if (item instanceof Pair) continue;else if (item instanceof YAMLMap) { + if (item.items.length > 1) onError('Each pair must have its own sequence indicator'); + const pair = item.items[0] || new Pair(); + if (item.commentBefore) pair.commentBefore = pair.commentBefore ? "".concat(item.commentBefore, "\n").concat(pair.commentBefore) : item.commentBefore; + if (item.comment) pair.comment = pair.comment ? "".concat(item.comment, "\n").concat(pair.comment) : item.comment; + item = pair; + } + seq.items[i] = item instanceof Pair ? item : new Pair(item); + } + } else onError('Expected a sequence for this tag'); + + return seq; +} +function createPairs(schema, iterable, ctx) { + const { + replacer + } = ctx; + const pairs = new YAMLSeq(schema); + pairs.tag = 'tag:yaml.org,2002:pairs'; + let i = 0; + + for (let it of iterable) { + if (typeof replacer === 'function') it = replacer.call(iterable, String(i++), it); + let key, value; + + if (Array.isArray(it)) { + if (it.length === 2) { + key = it[0]; + value = it[1]; + } else throw new TypeError("Expected [key, value] tuple: ".concat(it)); + } else if (it && it instanceof Object) { + const keys = Object.keys(it); + + if (keys.length === 1) { + key = keys[0]; + value = it[key]; + } else throw new TypeError("Expected { key: value } tuple: ".concat(it)); + } else { + key = it; + } + + pairs.items.push(createPair(key, value, ctx)); + } + + return pairs; +} +const pairs = { + default: false, + tag: 'tag:yaml.org,2002:pairs', + resolve: parsePairs, + createNode: createPairs +}; + +class YAMLOMap extends YAMLSeq { + constructor() { + super(); + + _defineProperty(this, "add", YAMLMap.prototype.add.bind(this)); + + _defineProperty(this, "delete", YAMLMap.prototype.delete.bind(this)); + + _defineProperty(this, "get", YAMLMap.prototype.get.bind(this)); + + _defineProperty(this, "has", YAMLMap.prototype.has.bind(this)); + + _defineProperty(this, "set", YAMLMap.prototype.set.bind(this)); + + this.tag = YAMLOMap.tag; + } + + toJSON(_, ctx) { + const map = new Map(); + if (ctx && ctx.onCreate) ctx.onCreate(map); + + for (const pair of this.items) { + let key, value; + + if (pair instanceof Pair) { + key = toJS(pair.key, '', ctx); + value = toJS(pair.value, key, ctx); + } else { + key = toJS(pair, '', ctx); + } + + if (map.has(key)) throw new Error('Ordered maps must not include duplicate keys'); + map.set(key, value); + } + + return map; + } + +} + +_defineProperty(YAMLOMap, "tag", 'tag:yaml.org,2002:omap'); + +function parseOMap(seq, onError) { + const pairs = parsePairs(seq, onError); + const seenKeys = []; + + for (const { + key + } of pairs.items) { + if (key instanceof Scalar) { + if (seenKeys.includes(key.value)) { + onError("Ordered maps must not include duplicate keys: ".concat(key.value)); + } else { + seenKeys.push(key.value); + } + } + } + + return Object.assign(new YAMLOMap(), pairs); +} + +function createOMap(schema, iterable, ctx) { + const pairs = createPairs(schema, iterable, ctx); + const omap = new YAMLOMap(); + omap.items = pairs.items; + return omap; +} + +const omap = { + identify: value => value instanceof Map, + nodeClass: YAMLOMap, + default: false, + tag: 'tag:yaml.org,2002:omap', + resolve: parseOMap, + createNode: createOMap +}; + +class YAMLSet extends YAMLMap { + constructor(schema) { + super(schema); + this.tag = YAMLSet.tag; + } + + add(key) { + const pair = key instanceof Pair ? key : new Pair(key); + const prev = findPair(this.items, pair.key); + if (!prev) this.items.push(pair); + } + + get(key, keepPair) { + const pair = findPair(this.items, key); + return !keepPair && pair instanceof Pair ? pair.key instanceof Scalar ? pair.key.value : pair.key : pair; + } + + set(key, value) { + if (typeof value !== 'boolean') throw new Error("Expected boolean value for set(key, value) in a YAML set, not ".concat(typeof value)); + const prev = findPair(this.items, key); + + if (prev && !value) { + this.items.splice(this.items.indexOf(prev), 1); + } else if (!prev && value) { + this.items.push(new Pair(key)); + } + } + + toJSON(_, ctx) { + return super.toJSON(_, ctx, Set); + } + + toString(ctx, onComment, onChompKeep) { + if (!ctx) return JSON.stringify(this); + if (this.hasAllNullValues()) return super.toString(ctx, onComment, onChompKeep);else throw new Error('Set items must all have null values'); + } + +} + +_defineProperty(YAMLSet, "tag", 'tag:yaml.org,2002:set'); + +function parseSet(map, onError) { + if (map instanceof YAMLMap) { + if (map.hasAllNullValues()) return Object.assign(new YAMLSet(), map);else onError('Set items must all have null values'); + } else onError('Expected a mapping for this tag'); + + return map; +} + +function createSet(schema, iterable, ctx) { + const { + replacer + } = ctx; + const set = new YAMLSet(schema); + + for (let value of iterable) { + if (typeof replacer === 'function') value = replacer.call(iterable, value, value); + set.items.push(createPair(value, null, ctx)); + } + + return set; +} + +const set$1 = { + identify: value => value instanceof Set, + nodeClass: YAMLSet, + default: false, + tag: 'tag:yaml.org,2002:set', + resolve: parseSet, + createNode: createSet +}; + +/* global BigInt */ + +const parseSexagesimal = (str, isInt) => { + const sign = str[0]; + const parts = sign === '-' || sign === '+' ? str.substring(1) : str; + + const num = n => isInt && intOptions.asBigInt ? BigInt(n) : Number(n); + + const res = parts.replace(/_/g, '').split(':').reduce((res, p) => res * num(60) + num(p), num(0)); + return sign === '-' ? num(-1) * res : res; +}; // hhhh:mm:ss.sss + + +const stringifySexagesimal = ({ + value +}) => { + let num = n => n; + + if (typeof value === 'bigint') num = n => BigInt(n);else if (isNaN(value) || !isFinite(value)) return stringifyNumber(value); + let sign = ''; + + if (value < 0) { + sign = '-'; + value *= num(-1); + } + + const _60 = num(60); + + const parts = [value % _60]; // seconds, including ms + + if (value < 60) { + parts.unshift(0); // at least one : is required + } else { + value = (value - parts[0]) / _60; + parts.unshift(value % _60); // minutes + + if (value >= 60) { + value = (value - parts[0]) / _60; + parts.unshift(value); // hours + } + } + + return sign + parts.map(n => n < 10 ? '0' + String(n) : String(n)).join(':').replace(/000000\d*$/, '') // % 60 may introduce error + ; +}; + +const intTime = { + identify: value => typeof value === 'bigint' || Number.isInteger(value), + default: true, + tag: 'tag:yaml.org,2002:int', + format: 'TIME', + test: /^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+$/, + resolve: str => parseSexagesimal(str, true), + stringify: stringifySexagesimal +}; +const floatTime = { + identify: value => typeof value === 'number', + default: true, + tag: 'tag:yaml.org,2002:float', + format: 'TIME', + test: /^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\.[0-9_]*$/, + resolve: str => parseSexagesimal(str, false), + stringify: stringifySexagesimal +}; +const timestamp = { + identify: value => value instanceof Date, + default: true, + tag: 'tag:yaml.org,2002:timestamp', + // If the time zone is omitted, the timestamp is assumed to be specified in UTC. The time part + // may be omitted altogether, resulting in a date format. In such a case, the time part is + // assumed to be 00:00:00Z (start of day, UTC). + test: RegExp('^([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})' + // YYYY-Mm-Dd + '(?:' + // time is optional + '(?:t|T|[ \\t]+)' + // t | T | whitespace + '([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2}(\\.[0-9]+)?)' + // Hh:Mm:Ss(.ss)? + '(?:[ \\t]*(Z|[-+][012]?[0-9](?::[0-9]{2})?))?' + // Z | +5 | -03:30 + ')?$'), + + resolve(str) { + let [, year, month, day, hour, minute, second, millisec, tz] = str.match(timestamp.test); + if (millisec) millisec = (millisec + '00').substr(1, 3); + let date = Date.UTC(year, month - 1, day, hour || 0, minute || 0, second || 0, millisec || 0); + + if (tz && tz !== 'Z') { + let d = parseSexagesimal(tz, false); + if (Math.abs(d) < 30) d *= 60; + date -= 60000 * d; + } + + return new Date(date); + }, + + stringify: ({ + value + }) => value.toISOString().replace(/((T00:00)?:00)?\.000Z$/, '') +}; + +/* global BigInt */ + +const boolStringify = ({ + value, + sourceStr +}) => { + const boolObj = value ? trueObj : falseObj; + if (sourceStr && boolObj.test.test(sourceStr)) return sourceStr; + return value ? boolOptions.trueStr : boolOptions.falseStr; +}; + +const boolResolve = (value, str) => { + const node = new Scalar(value); + node.sourceStr = str; + return node; +}; + +const trueObj = { + identify: value => value === true, + default: true, + tag: 'tag:yaml.org,2002:bool', + test: /^(?:Y|y|[Yy]es|YES|[Tt]rue|TRUE|[Oo]n|ON)$/, + resolve: str => boolResolve(true, str), + options: boolOptions, + stringify: boolStringify +}; +const falseObj = { + identify: value => value === false, + default: true, + tag: 'tag:yaml.org,2002:bool', + test: /^(?:N|n|[Nn]o|NO|[Ff]alse|FALSE|[Oo]ff|OFF)$/i, + resolve: str => boolResolve(false, str), + options: boolOptions, + stringify: boolStringify +}; + +const intIdentify$2 = value => typeof value === 'bigint' || Number.isInteger(value); + +function intResolve$1(str, offset, radix) { + const sign = str[0]; + if (sign === '-' || sign === '+') offset += 1; + str = str.substring(offset).replace(/_/g, ''); + + if (intOptions.asBigInt) { + switch (radix) { + case 2: + str = "0b".concat(str); + break; + + case 8: + str = "0o".concat(str); + break; + + case 16: + str = "0x".concat(str); + break; + } + + const n = BigInt(str); + return sign === '-' ? BigInt(-1) * n : n; + } + + const n = parseInt(str, radix); + return sign === '-' ? -1 * n : n; +} + +function intStringify$1(node, radix, prefix) { + const { + value + } = node; + + if (intIdentify$2(value)) { + const str = value.toString(radix); + return value < 0 ? '-' + prefix + str.substr(1) : prefix + str; + } + + return stringifyNumber(node); +} + +const yaml11 = failsafe.concat([{ + identify: value => value == null, + createNode: (schema, value, ctx) => ctx.wrapScalars ? new Scalar(null) : null, + default: true, + tag: 'tag:yaml.org,2002:null', + test: /^(?:~|[Nn]ull|NULL)?$/, + resolve: str => { + const node = new Scalar(null); + node.sourceStr = str; + return node; + }, + options: nullOptions, + stringify: ({ + sourceStr + }) => sourceStr !== null && sourceStr !== void 0 ? sourceStr : nullOptions.nullStr +}, trueObj, falseObj, { + identify: intIdentify$2, + default: true, + tag: 'tag:yaml.org,2002:int', + format: 'BIN', + test: /^[-+]?0b[0-1_]+$/, + resolve: str => intResolve$1(str, 2, 2), + stringify: node => intStringify$1(node, 2, '0b') +}, { + identify: intIdentify$2, + default: true, + tag: 'tag:yaml.org,2002:int', + format: 'OCT', + test: /^[-+]?0[0-7_]+$/, + resolve: str => intResolve$1(str, 1, 8), + stringify: node => intStringify$1(node, 8, '0') +}, { + identify: intIdentify$2, + default: true, + tag: 'tag:yaml.org,2002:int', + test: /^[-+]?[0-9][0-9_]*$/, + resolve: str => intResolve$1(str, 0, 10), + stringify: stringifyNumber +}, { + identify: intIdentify$2, + default: true, + tag: 'tag:yaml.org,2002:int', + format: 'HEX', + test: /^[-+]?0x[0-9a-fA-F_]+$/, + resolve: str => intResolve$1(str, 2, 16), + stringify: node => intStringify$1(node, 16, '0x') +}, { + identify: value => typeof value === 'number', + default: true, + tag: 'tag:yaml.org,2002:float', + test: /^[-+]?\.(?:inf|Inf|INF|nan|NaN|NAN)$/, + resolve: str => str.slice(-3).toLowerCase() === 'nan' ? NaN : str[0] === '-' ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY, + stringify: stringifyNumber +}, { + identify: value => typeof value === 'number', + default: true, + tag: 'tag:yaml.org,2002:float', + format: 'EXP', + test: /^[-+]?(?:[0-9][0-9_]*)?(?:\.[0-9_]*)?[eE][-+]?[0-9]+$/, + resolve: str => parseFloat(str.replace(/_/g, '')), + stringify: ({ + value + }) => Number(value).toExponential() +}, { + identify: value => typeof value === 'number', + default: true, + tag: 'tag:yaml.org,2002:float', + test: /^[-+]?(?:[0-9][0-9_]*)?\.[0-9_]*$/, + + resolve(str) { + const node = new Scalar(parseFloat(str.replace(/_/g, ''))); + const dot = str.indexOf('.'); + + if (dot !== -1) { + const f = str.substring(dot + 1).replace(/_/g, ''); + if (f[f.length - 1] === '0') node.minFractionDigits = f.length; + } + + return node; + }, + + stringify: stringifyNumber +}], binary, omap, pairs, set$1, intTime, floatTime, timestamp); + +const schemas = { + core, + failsafe, + json, + yaml11 +}; +const tags = { + binary, + bool: boolObj, + float: floatObj, + floatExp: expObj, + floatNaN: nanObj, + floatTime, + int: intObj, + intHex: hexObj, + intOct: octObj, + intTime, + map, + null: nullObj, + omap, + pairs, + seq, + set: set$1, + timestamp +}; + +function getSchemaTags(schemas, knownTags, customTags, schemaId) { + let tags = schemas[schemaId.replace(/\W/g, '')]; // 'yaml-1.1' -> 'yaml11' + + if (!tags) { + const keys = Object.keys(schemas).map(key => JSON.stringify(key)).join(', '); + throw new Error("Unknown schema \"".concat(schemaId, "\"; use one of ").concat(keys)); + } + + if (Array.isArray(customTags)) { + for (const tag of customTags) tags = tags.concat(tag); + } else if (typeof customTags === 'function') { + tags = customTags(tags.slice()); + } + + for (let i = 0; i < tags.length; ++i) { + const tag = tags[i]; + + if (typeof tag === 'string') { + const tagObj = knownTags[tag]; + + if (!tagObj) { + const keys = Object.keys(knownTags).map(key => JSON.stringify(key)).join(', '); + throw new Error("Unknown custom tag \"".concat(tag, "\"; use one of ").concat(keys)); + } + + tags[i] = tagObj; + } + } + + return tags; +} + +const sortMapEntriesByKey = (a, b) => a.key < b.key ? -1 : a.key > b.key ? 1 : 0; + +const coreKnownTags = { + 'tag:yaml.org,2002:binary': tags.binary, + 'tag:yaml.org,2002:omap': tags.omap, + 'tag:yaml.org,2002:pairs': tags.pairs, + 'tag:yaml.org,2002:set': tags.set, + 'tag:yaml.org,2002:timestamp': tags.timestamp +}; +class Schema { + constructor({ + customTags, + merge, + resolveKnownTags, + schema, + sortMapEntries + }) { + this.merge = !!merge; + this.name = schema; + this.knownTags = resolveKnownTags ? coreKnownTags : {}; + this.tags = getSchemaTags(schemas, tags, customTags, schema); // Used by createNode(), to avoid circular dependencies + + this.map = tags.map; + this.seq = tags.seq; // Used by createMap() + + this.sortMapEntries = sortMapEntries === true ? sortMapEntriesByKey : sortMapEntries || null; + } + +} + +/** + * Applies the JSON.parse reviver algorithm as defined in the ECMA-262 spec, + * in section 24.5.1.1 "Runtime Semantics: InternalizeJSONProperty" of the + * 2021 edition: https://tc39.es/ecma262/#sec-json.parse + * + * Includes extensions for handling Map and Set objects. + */ +function applyReviver(reviver, obj, key, val) { + if (val && typeof val === 'object') { + if (Array.isArray(val)) { + for (let i = 0, len = val.length; i < len; ++i) { + const v0 = val[i]; + const v1 = applyReviver(reviver, val, String(i), v0); + if (v1 === undefined) delete val[i];else if (v1 !== v0) val[i] = v1; + } + } else if (val instanceof Map) { + for (const k of Array.from(val.keys())) { + const v0 = val.get(k); + const v1 = applyReviver(reviver, val, k, v0); + if (v1 === undefined) val.delete(k);else if (v1 !== v0) val.set(k, v1); + } + } else if (val instanceof Set) { + for (const v0 of Array.from(val)) { + const v1 = applyReviver(reviver, val, v0, v0); + if (v1 === undefined) val.delete(v0);else if (v1 !== v0) { + val.delete(v0); + val.add(v1); + } + } + } else { + for (const [k, v0] of Object.entries(val)) { + const v1 = applyReviver(reviver, val, k, v0); + if (v1 === undefined) delete val[k];else if (v1 !== v0) val[k] = v1; + } + } + } + + return reviver.call(obj, key, val); +} + +const visit = (node, tags) => { + if (node && typeof node === 'object') { + const { + tag + } = node; + + if (node instanceof Collection$1) { + if (tag) tags[tag] = true; + node.items.forEach(n => visit(n, tags)); + } else if (node instanceof Pair) { + visit(node.key, tags); + visit(node.value, tags); + } else if (node instanceof Scalar) { + if (tag) tags[tag] = true; + } + } + + return tags; +}; + +const listTagNames = node => Object.keys(visit(node, {})); + +function resolveTagHandle(doc, node) { + const { + handle, + suffix + } = node.tag; + let prefix = doc.tagPrefixes.find(p => p.handle === handle); + + if (!prefix) { + const dtp = doc.getDefaults().tagPrefixes; + if (dtp) prefix = dtp.find(p => p.handle === handle); + if (!prefix) throw new YAMLSemanticError(node, "The ".concat(handle, " tag handle is non-default and was not declared.")); + } + + if (!suffix) throw new YAMLSemanticError(node, "The ".concat(handle, " tag has no suffix.")); + + if (handle === '!' && (doc.version || doc.options.version) === '1.0') { + if (suffix[0] === '^') { + doc.warnings.push(new YAMLWarning(node, 'YAML 1.0 ^ tag expansion is not supported')); + return suffix; + } + + if (/[:/]/.test(suffix)) { + // word/foo -> tag:word.yaml.org,2002:foo + const vocab = suffix.match(/^([a-z0-9-]+)\/(.*)/i); + return vocab ? "tag:".concat(vocab[1], ".yaml.org,2002:").concat(vocab[2]) : "tag:".concat(suffix); + } + } + + return prefix.prefix + decodeURIComponent(suffix); +} + +function resolveTagName(doc, node) { + const { + tag, + type + } = node; + let nonSpecific = false; + + if (tag) { + const { + handle, + suffix, + verbatim + } = tag; + + if (verbatim) { + if (verbatim !== '!' && verbatim !== '!!') return verbatim; + const msg = "Verbatim tags aren't resolved, so ".concat(verbatim, " is invalid."); + doc.errors.push(new YAMLSemanticError(node, msg)); + } else if (handle === '!' && !suffix) { + nonSpecific = true; + } else { + try { + return resolveTagHandle(doc, node); + } catch (error) { + doc.errors.push(error); + } + } + } + + switch (type) { + case Type.BLOCK_FOLDED: + case Type.BLOCK_LITERAL: + case Type.QUOTE_DOUBLE: + case Type.QUOTE_SINGLE: + return defaultTags.STR; + + case Type.FLOW_MAP: + case Type.MAP: + return defaultTags.MAP; + + case Type.FLOW_SEQ: + case Type.SEQ: + return defaultTags.SEQ; + + case Type.PLAIN: + return nonSpecific ? defaultTags.STR : null; + + default: + return null; + } +} + +function checkFlowCollectionEnd(errors, cst) { + let char, name; + + switch (cst.type) { + case Type.FLOW_MAP: + char = '}'; + name = 'flow map'; + break; + + case Type.FLOW_SEQ: + char = ']'; + name = 'flow sequence'; + break; + + default: + errors.push(new YAMLSemanticError(cst, 'Not a flow collection!?')); + return; + } + + let lastItem; + + for (let i = cst.items.length - 1; i >= 0; --i) { + const item = cst.items[i]; + + if (!item || item.type !== Type.COMMENT) { + lastItem = item; + break; + } + } + + if (lastItem && lastItem.char !== char) { + const msg = "Expected ".concat(name, " to end with ").concat(char); + let err; + + if (typeof lastItem.offset === 'number') { + err = new YAMLSemanticError(cst, msg); + err.offset = lastItem.offset + 1; + } else { + err = new YAMLSemanticError(lastItem, msg); + if (lastItem.range && lastItem.range.end) err.offset = lastItem.range.end - lastItem.range.start; + } + + errors.push(err); + } +} +function checkFlowCommentSpace(errors, comment) { + const prev = comment.context.src[comment.range.start - 1]; + + if (prev !== '\n' && prev !== '\t' && prev !== ' ') { + const msg = 'Comments must be separated from other tokens by white space characters'; + errors.push(new YAMLSemanticError(comment, msg)); + } +} +function getLongKeyError(source, key) { + const sk = String(key); + const k = sk.substr(0, 8) + '...' + sk.substr(-8); + return new YAMLSemanticError(source, "The \"".concat(k, "\" key is too long")); +} +function resolveComments(collection, comments) { + for (const { + afterKey, + before, + comment + } of comments) { + let item = collection.items[before]; + + if (!item) { + if (comment !== undefined) { + if (collection.comment) collection.comment += '\n' + comment;else collection.comment = comment; + } + } else { + if (afterKey && item.value) item = item.value; + + if (comment === undefined) { + if (afterKey || !item.commentBefore) item.spaceBefore = true; + } else { + if (item.commentBefore) item.commentBefore += '\n' + comment;else item.commentBefore = comment; + } + } + } +} + +function resolveMap(doc, cst) { + const { + comments, + items + } = cst.type === Type.FLOW_MAP ? resolveFlowMapItems(doc, cst) : resolveBlockMapItems(doc, cst); + const map = new YAMLMap(doc.schema); + map.items = items; + resolveComments(map, comments); + + for (let i = 0; i < items.length; ++i) { + const { + key: iKey + } = items[i]; + + if (doc.schema.merge && iKey && iKey.value === MERGE_KEY) { + items[i] = new Merge(items[i]); + const sources = items[i].value.items; + let error = null; + sources.some(node => { + if (node instanceof Alias$1) { + // During parsing, alias sources are CST nodes; to account for + // circular references their resolved values can't be used here. + const { + type + } = node.source; + if (type === Type.MAP || type === Type.FLOW_MAP) return false; + return error = 'Merge nodes aliases can only point to maps'; + } + + return error = 'Merge nodes can only have Alias nodes as values'; + }); + if (error) doc.errors.push(new YAMLSemanticError(cst, error)); + } else { + for (let j = i + 1; j < items.length; ++j) { + const { + key: jKey + } = items[j]; + + if (iKey === jKey || iKey && jKey && Object.prototype.hasOwnProperty.call(iKey, 'value') && iKey.value === jKey.value) { + const msg = "Map keys must be unique; \"".concat(iKey, "\" is repeated"); + doc.errors.push(new YAMLSemanticError(cst, msg)); + break; + } + } + } + } + + cst.resolved = map; + return map; +} + +const valueHasPairComment = ({ + context: { + lineStart, + node, + src + }, + props +}) => { + if (props.length === 0) return false; + const { + start + } = props[0]; + if (node && start > node.valueRange.start) return false; + if (src[start] !== Char.COMMENT) return false; + + for (let i = lineStart; i < start; ++i) if (src[i] === '\n') return false; + + return true; +}; + +function resolvePairComment(item, pair) { + if (!valueHasPairComment(item)) return; + const comment = item.getPropValue(0, Char.COMMENT, true); + let found = false; + const cb = pair.value.commentBefore; + + if (cb && cb.startsWith(comment)) { + pair.value.commentBefore = cb.substr(comment.length + 1); + found = true; + } else { + const cc = pair.value.comment; + + if (!item.node && cc && cc.startsWith(comment)) { + pair.value.comment = cc.substr(comment.length + 1); + found = true; + } + } + + if (found) pair.comment = comment; +} + +function resolveBlockMapItems(doc, cst) { + const comments = []; + const items = []; + let key = undefined; + let keyStart = null; + + for (let i = 0; i < cst.items.length; ++i) { + const item = cst.items[i]; + + switch (item.type) { + case Type.BLANK_LINE: + comments.push({ + afterKey: !!key, + before: items.length + }); + break; + + case Type.COMMENT: + comments.push({ + afterKey: !!key, + before: items.length, + comment: item.comment + }); + break; + + case Type.MAP_KEY: + if (key !== undefined) items.push(new Pair(key)); + if (item.error) doc.errors.push(item.error); + key = resolveNode(doc, item.node); + keyStart = null; + break; + + case Type.MAP_VALUE: + { + if (key === undefined) key = null; + if (item.error) doc.errors.push(item.error); + + if (!item.context.atLineStart && item.node && item.node.type === Type.MAP && !item.node.context.atLineStart) { + const msg = 'Nested mappings are not allowed in compact mappings'; + doc.errors.push(new YAMLSemanticError(item.node, msg)); + } + + let valueNode = item.node; + + if (!valueNode && item.props.length > 0) { + // Comments on an empty mapping value need to be preserved, so we + // need to construct a minimal empty node here to use instead of the + // missing `item.node`. -- eemeli/yaml#19 + valueNode = new PlainValue(Type.PLAIN, []); + valueNode.context = { + parent: item, + src: item.context.src + }; + const pos = item.range.start + 1; + valueNode.range = { + start: pos, + end: pos + }; + valueNode.valueRange = { + start: pos, + end: pos + }; + + if (typeof item.range.origStart === 'number') { + const origPos = item.range.origStart + 1; + valueNode.range.origStart = valueNode.range.origEnd = origPos; + valueNode.valueRange.origStart = valueNode.valueRange.origEnd = origPos; + } + } + + const pair = new Pair(key, resolveNode(doc, valueNode)); + resolvePairComment(item, pair); + items.push(pair); + + if (key && typeof keyStart === 'number') { + if (item.range.start > keyStart + 1024) doc.errors.push(getLongKeyError(cst, key)); + } + + key = undefined; + keyStart = null; + } + break; + + default: + if (key !== undefined) items.push(new Pair(key)); + key = resolveNode(doc, item); + keyStart = item.range.start; + if (item.error) doc.errors.push(item.error); + + next: for (let j = i + 1;; ++j) { + const nextItem = cst.items[j]; + + switch (nextItem && nextItem.type) { + case Type.BLANK_LINE: + case Type.COMMENT: + continue next; + + case Type.MAP_VALUE: + break next; + + default: + { + const msg = 'Implicit map keys need to be followed by map values'; + doc.errors.push(new YAMLSemanticError(item, msg)); + break next; + } + } + } + + if (item.valueRangeContainsNewline) { + const msg = 'Implicit map keys need to be on a single line'; + doc.errors.push(new YAMLSemanticError(item, msg)); + } + + } + } + + if (key !== undefined) items.push(new Pair(key)); + return { + comments, + items + }; +} + +function resolveFlowMapItems(doc, cst) { + const comments = []; + const items = []; + let key = undefined; + let explicitKey = false; + let next = '{'; + + for (let i = 0; i < cst.items.length; ++i) { + const item = cst.items[i]; + + if (typeof item.char === 'string') { + const { + char, + offset + } = item; + + if (char === '?' && key === undefined && !explicitKey) { + explicitKey = true; + next = ':'; + continue; + } + + if (char === ':') { + if (key === undefined) key = null; + + if (next === ':') { + next = ','; + continue; + } + } else { + if (explicitKey) { + if (key === undefined && char !== ',') key = null; + explicitKey = false; + } + + if (key !== undefined) { + items.push(new Pair(key)); + key = undefined; + + if (char === ',') { + next = ':'; + continue; + } + } + } + + if (char === '}') { + if (i === cst.items.length - 1) continue; + } else if (char === next) { + next = ':'; + continue; + } + + const msg = "Flow map contains an unexpected ".concat(char); + const err = new YAMLSyntaxError(cst, msg); + err.offset = offset; + doc.errors.push(err); + } else if (item.type === Type.BLANK_LINE) { + comments.push({ + afterKey: !!key, + before: items.length + }); + } else if (item.type === Type.COMMENT) { + checkFlowCommentSpace(doc.errors, item); + comments.push({ + afterKey: !!key, + before: items.length, + comment: item.comment + }); + } else if (key === undefined) { + if (next === ',') doc.errors.push(new YAMLSemanticError(item, 'Separator , missing in flow map')); + key = resolveNode(doc, item); + } else { + if (next !== ',') doc.errors.push(new YAMLSemanticError(item, 'Indicator : missing in flow map entry')); + items.push(new Pair(key, resolveNode(doc, item))); + key = undefined; + explicitKey = false; + } + } + + checkFlowCollectionEnd(doc.errors, cst); + if (key !== undefined) items.push(new Pair(key)); + return { + comments, + items + }; +} + +function resolveSeq(doc, cst) { + const { + comments, + items + } = cst.type === Type.FLOW_SEQ ? resolveFlowSeqItems(doc, cst) : resolveBlockSeqItems(doc, cst); + const seq = new YAMLSeq(doc.schema); + seq.items = items; + resolveComments(seq, comments); + cst.resolved = seq; + return seq; +} + +function resolveBlockSeqItems(doc, cst) { + const comments = []; + const items = []; + + for (let i = 0; i < cst.items.length; ++i) { + const item = cst.items[i]; + + switch (item.type) { + case Type.BLANK_LINE: + comments.push({ + before: items.length + }); + break; + + case Type.COMMENT: + comments.push({ + comment: item.comment, + before: items.length + }); + break; + + case Type.SEQ_ITEM: + if (item.error) doc.errors.push(item.error); + items.push(resolveNode(doc, item.node)); + + if (item.hasProps) { + const msg = 'Sequence items cannot have tags or anchors before the - indicator'; + doc.errors.push(new YAMLSemanticError(item, msg)); + } + + break; + + default: + if (item.error) doc.errors.push(item.error); + doc.errors.push(new YAMLSyntaxError(item, "Unexpected ".concat(item.type, " node in sequence"))); + } + } + + return { + comments, + items + }; +} + +function resolveFlowSeqItems(doc, cst) { + const comments = []; + const items = []; + let explicitKey = false; + let key = undefined; + let keyStart = null; + let next = '['; + let prevItem = null; + + for (let i = 0; i < cst.items.length; ++i) { + const item = cst.items[i]; + + if (typeof item.char === 'string') { + const { + char, + offset + } = item; + + if (char !== ':' && (explicitKey || key !== undefined)) { + if (explicitKey && key === undefined) key = next ? items.pop() : null; + items.push(new Pair(key)); + explicitKey = false; + key = undefined; + keyStart = null; + } + + if (char === next) { + next = null; + } else if (!next && char === '?') { + explicitKey = true; + } else if (next !== '[' && char === ':' && key === undefined) { + if (next === ',') { + key = items.pop(); + + if (key instanceof Pair) { + const msg = 'Chaining flow sequence pairs is invalid'; + const err = new YAMLSemanticError(cst, msg); + err.offset = offset; + doc.errors.push(err); + } + + if (!explicitKey && typeof keyStart === 'number') { + const keyEnd = item.range ? item.range.start : item.offset; + if (keyEnd > keyStart + 1024) doc.errors.push(getLongKeyError(cst, key)); + const { + src + } = prevItem.context; + + for (let i = keyStart; i < keyEnd; ++i) if (src[i] === '\n') { + const msg = 'Implicit keys of flow sequence pairs need to be on a single line'; + doc.errors.push(new YAMLSemanticError(prevItem, msg)); + break; + } + } + } else { + key = null; + } + + keyStart = null; + explicitKey = false; + next = null; + } else if (next === '[' || char !== ']' || i < cst.items.length - 1) { + const msg = "Flow sequence contains an unexpected ".concat(char); + const err = new YAMLSyntaxError(cst, msg); + err.offset = offset; + doc.errors.push(err); + } + } else if (item.type === Type.BLANK_LINE) { + comments.push({ + before: items.length + }); + } else if (item.type === Type.COMMENT) { + checkFlowCommentSpace(doc.errors, item); + comments.push({ + comment: item.comment, + before: items.length + }); + } else { + if (next) { + const msg = "Expected a ".concat(next, " in flow sequence"); + doc.errors.push(new YAMLSemanticError(item, msg)); + } + + const value = resolveNode(doc, item); + + if (key === undefined) { + items.push(value); + prevItem = item; + } else { + items.push(new Pair(key, value)); + key = undefined; + } + + keyStart = item.range.start; + next = ','; + } + } + + checkFlowCollectionEnd(doc.errors, cst); + if (key !== undefined) items.push(new Pair(key)); + return { + comments, + items + }; +} + +function resolveByTagName({ + knownTags, + tags +}, tagName, value, onError) { + const matchWithTest = []; + + for (const tag of tags) { + if (tag.tag === tagName) { + if (tag.test) { + if (typeof value === 'string') matchWithTest.push(tag);else onError("The tag ".concat(tagName, " cannot be applied to a collection")); + } else { + const res = tag.resolve(value, onError); + return res instanceof Collection$1 ? res : new Scalar(res); + } + } + } + + if (matchWithTest.length > 0) return resolveScalar(value, matchWithTest); + const kt = knownTags[tagName]; + + if (kt) { + tags.push(Object.assign({}, kt, { + default: false, + test: undefined + })); + const res = kt.resolve(value, onError); + return res instanceof Collection$1 ? res : new Scalar(res); + } + + return null; +} + +function resolveTag(doc, node, tagName) { + const { + MAP, + SEQ, + STR + } = defaultTags; + let value, fallback; + + const onError = message => doc.errors.push(new YAMLSemanticError(node, message)); + + try { + switch (node.type) { + case Type.FLOW_MAP: + case Type.MAP: + value = resolveMap(doc, node); + fallback = MAP; + if (tagName === SEQ || tagName === STR) onError("The tag ".concat(tagName, " cannot be applied to a mapping")); + break; + + case Type.FLOW_SEQ: + case Type.SEQ: + value = resolveSeq(doc, node); + fallback = SEQ; + if (tagName === MAP || tagName === STR) onError("The tag ".concat(tagName, " cannot be applied to a sequence")); + break; + + default: + value = node.strValue || ''; + + if (typeof value !== 'string') { + value.errors.forEach(error => doc.errors.push(error)); + value = value.str; + } + + if (tagName === MAP || tagName === SEQ) onError("The tag ".concat(tagName, " cannot be applied to a scalar")); + fallback = STR; + } + + const res = resolveByTagName(doc.schema, tagName, value, onError); + + if (res) { + if (tagName && node.tag) res.tag = tagName; + return res; + } + } catch (error) { + /* istanbul ignore if */ + if (!error.source) error.source = node; + doc.errors.push(error); + return null; + } + + try { + if (!fallback) throw new Error("The tag ".concat(tagName, " is unavailable")); + const msg = "The tag ".concat(tagName, " is unavailable, falling back to ").concat(fallback); + doc.warnings.push(new YAMLWarning(node, msg)); + const res = resolveByTagName(doc.schema, fallback, value, onError); + res.tag = tagName; + return res; + } catch (error) { + const refError = new YAMLReferenceError(node, error.message); + refError.stack = error.stack; + doc.errors.push(refError); + return null; + } +} + +const isCollectionItem = node => { + if (!node) return false; + const { + type + } = node; + return type === Type.MAP_KEY || type === Type.MAP_VALUE || type === Type.SEQ_ITEM; +}; + +function resolveNodeProps(errors, node) { + const comments = { + before: [], + after: [] + }; + let hasAnchor = false; + let hasTag = false; + const props = isCollectionItem(node.context.parent) ? node.context.parent.props.concat(node.props) : node.props; + + for (const { + start, + end + } of props) { + switch (node.context.src[start]) { + case Char.COMMENT: + { + if (!node.commentHasRequiredWhitespace(start)) { + const msg = 'Comments must be separated from other tokens by white space characters'; + errors.push(new YAMLSemanticError(node, msg)); + } + + const { + header, + valueRange + } = node; + const cc = valueRange && (start > valueRange.start || header && start > header.start) ? comments.after : comments.before; + cc.push(node.context.src.slice(start + 1, end)); + break; + } + // Actual anchor & tag resolution is handled by schema, here we just complain + + case Char.ANCHOR: + if (hasAnchor) { + const msg = 'A node can have at most one anchor'; + errors.push(new YAMLSemanticError(node, msg)); + } + + hasAnchor = true; + break; + + case Char.TAG: + if (hasTag) { + const msg = 'A node can have at most one tag'; + errors.push(new YAMLSemanticError(node, msg)); + } + + hasTag = true; + break; + } + } + + return { + comments, + hasAnchor, + hasTag + }; +} + +function resolveNodeValue(doc, node) { + const { + anchors, + errors, + schema + } = doc; + + if (node.type === Type.ALIAS) { + const name = node.rawValue; + const src = anchors.getNode(name); + + if (!src) { + const msg = "Aliased anchor not found: ".concat(name); + errors.push(new YAMLReferenceError(node, msg)); + return null; + } // Lazy resolution for circular references + + + const res = new Alias$1(src); + + anchors._cstAliases.push(res); + + return res; + } + + const tagName = resolveTagName(doc, node); + if (tagName) return resolveTag(doc, node, tagName); + + if (node.type !== Type.PLAIN) { + const msg = "Failed to resolve ".concat(node.type, " node here"); + errors.push(new YAMLSyntaxError(node, msg)); + return null; + } + + try { + let str = node.strValue || ''; + + if (typeof str !== 'string') { + str.errors.forEach(error => doc.errors.push(error)); + str = str.str; + } + + return resolveScalar(str, schema.tags); + } catch (error) { + if (!error.source) error.source = node; + errors.push(error); + return null; + } +} // sets node.resolved on success + + +function resolveNode(doc, node) { + if (!node) return null; + if (node.error) doc.errors.push(node.error); + const { + comments, + hasAnchor, + hasTag + } = resolveNodeProps(doc.errors, node); + + if (hasAnchor) { + const { + anchors + } = doc; + const name = node.anchor; + const prev = anchors.getNode(name); // At this point, aliases for any preceding node with the same anchor + // name have already been resolved, so it may safely be renamed. + + if (prev) anchors.map[anchors.newName(name)] = prev; // During parsing, we need to store the CST node in anchors.map as + // anchors need to be available during resolution to allow for + // circular references. + + anchors.map[name] = node; + } + + if (node.type === Type.ALIAS && (hasAnchor || hasTag)) { + const msg = 'An alias node must not specify any properties'; + doc.errors.push(new YAMLSemanticError(node, msg)); + } + + const res = resolveNodeValue(doc, node); + + if (res) { + res.range = [node.range.start, node.range.end]; + if (doc.options.keepCstNodes) res.cstNode = node; + if (doc.options.keepNodeTypes) res.type = node.type; + const cb = comments.before.join('\n'); + + if (cb) { + res.commentBefore = res.commentBefore ? "".concat(res.commentBefore, "\n").concat(cb) : cb; + } + + const ca = comments.after.join('\n'); + if (ca) res.comment = res.comment ? "".concat(res.comment, "\n").concat(ca) : ca; + } + + return node.resolved = res; +} + +function parseContents(doc, contents) { + const comments = { + before: [], + after: [] + }; + let body = undefined; + let spaceBefore = false; + + for (const node of contents) { + if (node.valueRange) { + if (body !== undefined) { + const msg = 'Document contains trailing content not separated by a ... or --- line'; + doc.errors.push(new YAMLSyntaxError(node, msg)); + break; + } + + const res = resolveNode(doc, node); + + if (spaceBefore) { + res.spaceBefore = true; + spaceBefore = false; + } + + body = res; + } else if (node.comment !== null) { + const cc = body === undefined ? comments.before : comments.after; + cc.push(node.comment); + } else if (node.type === Type.BLANK_LINE) { + spaceBefore = true; + + if (body === undefined && comments.before.length > 0 && !doc.commentBefore) { + // space-separated comments at start are parsed as document comments + doc.commentBefore = comments.before.join('\n'); + comments.before = []; + } + } + } + + doc.contents = body || null; + + if (!body) { + doc.comment = comments.before.concat(comments.after).join('\n') || null; + } else { + const cb = comments.before.join('\n'); + + if (cb) { + const cbNode = body instanceof Collection$1 && body.items[0] ? body.items[0] : body; + cbNode.commentBefore = cbNode.commentBefore ? "".concat(cb, "\n").concat(cbNode.commentBefore) : cb; + } + + doc.comment = comments.after.join('\n') || null; + } +} + +function resolveTagDirective({ + tagPrefixes +}, directive) { + const [handle, prefix] = directive.parameters; + + if (!handle || !prefix) { + const msg = 'Insufficient parameters given for %TAG directive'; + throw new YAMLSemanticError(directive, msg); + } + + if (tagPrefixes.some(p => p.handle === handle)) { + const msg = 'The %TAG directive must only be given at most once per handle in the same document.'; + throw new YAMLSemanticError(directive, msg); + } + + return { + handle, + prefix + }; +} + +function resolveYamlDirective(doc, directive) { + let [version] = directive.parameters; + if (directive.name === 'YAML:1.0') version = '1.0'; + + if (!version) { + const msg = 'Insufficient parameters given for %YAML directive'; + throw new YAMLSemanticError(directive, msg); + } + + if (!documentOptions[version]) { + const v0 = doc.version || doc.options.version; + const msg = "Document will be parsed as YAML ".concat(v0, " rather than YAML ").concat(version); + doc.warnings.push(new YAMLWarning(directive, msg)); + } + + return version; +} + +function parseDirectives(doc, directives, prevDoc) { + const directiveComments = []; + let hasDirectives = false; + + for (const directive of directives) { + const { + comment, + name + } = directive; + + switch (name) { + case 'TAG': + try { + doc.tagPrefixes.push(resolveTagDirective(doc, directive)); + } catch (error) { + doc.errors.push(error); + } + + hasDirectives = true; + break; + + case 'YAML': + case 'YAML:1.0': + if (doc.version) { + const msg = 'The %YAML directive must only be given at most once per document.'; + doc.errors.push(new YAMLSemanticError(directive, msg)); + } + + try { + doc.version = resolveYamlDirective(doc, directive); + } catch (error) { + doc.errors.push(error); + } + + hasDirectives = true; + break; + + default: + if (name) { + const msg = "YAML only supports %TAG and %YAML directives, and not %".concat(name); + doc.warnings.push(new YAMLWarning(directive, msg)); + } + + } + + if (comment) directiveComments.push(comment); + } + + if (prevDoc && !hasDirectives && '1.1' === (doc.version || prevDoc.version || doc.options.version)) { + const copyTagPrefix = ({ + handle, + prefix + }) => ({ + handle, + prefix + }); + + doc.tagPrefixes = prevDoc.tagPrefixes.map(copyTagPrefix); + doc.version = prevDoc.version; + } + + doc.commentBefore = directiveComments.join('\n') || null; +} + +function assertCollection(contents) { + if (contents instanceof Collection$1) return true; + throw new Error('Expected a YAML collection as document contents'); +} + +class Document$1 { + constructor(value, replacer, options) { + if (options === undefined && replacer && typeof replacer === 'object' && !Array.isArray(replacer)) { + options = replacer; + replacer = undefined; + } + + this.options = Object.assign({}, defaultOptions, options); + this.anchors = new Anchors(this.options.anchorPrefix); + this.commentBefore = null; + this.comment = null; + this.directivesEndMarker = null; + this.errors = []; + this.schema = null; + this.tagPrefixes = []; + this.version = null; + this.warnings = []; + + if (value === undefined) { + // note that this.schema is left as null here + this.contents = null; + } else if (value instanceof Document) { + this.parse(value); + } else { + this.contents = this.createNode(value, { + replacer + }); + } + } + + add(value) { + assertCollection(this.contents); + return this.contents.add(value); + } + + addIn(path, value) { + assertCollection(this.contents); + this.contents.addIn(path, value); + } + + createNode(value, { + keepUndefined, + onTagObj, + replacer, + tag, + wrapScalars + } = {}) { + this.setSchema(); + if (typeof replacer === 'function') value = replacer.call({ + '': value + }, '', value);else if (Array.isArray(replacer)) { + const keyToStr = v => typeof v === 'number' || v instanceof String || v instanceof Number; + + const asStr = replacer.filter(keyToStr).map(String); + if (asStr.length > 0) replacer = replacer.concat(asStr); + } + if (typeof keepUndefined !== 'boolean') keepUndefined = !!this.options.keepUndefined; + const aliasNodes = []; + const ctx = { + keepUndefined, + + onAlias(source) { + const alias = new Alias$1(source); + aliasNodes.push(alias); + return alias; + }, + + onTagObj, + prevObjects: new Map(), + replacer, + schema: this.schema, + wrapScalars: wrapScalars !== false + }; + const node = createNode(value, tag, ctx); + + for (const alias of aliasNodes) { + // With circular references, the source node is only resolved after all of + // its child nodes are. This is why anchors are set only after all of the + // nodes have been created. + alias.source = alias.source.node; + let name = this.anchors.getName(alias.source); + + if (!name) { + name = this.anchors.newName(); + this.anchors.map[name] = alias.source; + } + } + + return node; + } + + createPair(key, value, options = {}) { + const k = this.createNode(key, options); + const v = this.createNode(value, options); + return new Pair(k, v); + } + + delete(key) { + assertCollection(this.contents); + return this.contents.delete(key); + } + + deleteIn(path) { + if (isEmptyPath(path)) { + if (this.contents == null) return false; + this.contents = null; + return true; + } + + assertCollection(this.contents); + return this.contents.deleteIn(path); + } + + getDefaults() { + return Document$1.defaults[this.version] || Document$1.defaults[this.options.version] || {}; + } + + get(key, keepScalar) { + return this.contents instanceof Collection$1 ? this.contents.get(key, keepScalar) : undefined; + } + + getIn(path, keepScalar) { + if (isEmptyPath(path)) return !keepScalar && this.contents instanceof Scalar ? this.contents.value : this.contents; + return this.contents instanceof Collection$1 ? this.contents.getIn(path, keepScalar) : undefined; + } + + has(key) { + return this.contents instanceof Collection$1 ? this.contents.has(key) : false; + } + + hasIn(path) { + if (isEmptyPath(path)) return this.contents !== undefined; + return this.contents instanceof Collection$1 ? this.contents.hasIn(path) : false; + } + + set(key, value) { + if (this.contents == null) { + this.setSchema(); + this.contents = collectionFromPath(this.schema, [key], value); + } else { + assertCollection(this.contents); + this.contents.set(key, value); + } + } + + setIn(path, value) { + if (isEmptyPath(path)) this.contents = value;else if (this.contents == null) { + this.setSchema(); + this.contents = collectionFromPath(this.schema, path, value); + } else { + assertCollection(this.contents); + this.contents.setIn(path, value); + } + } + + setSchema(id, customTags) { + if (!id && !customTags && this.schema) return; + if (typeof id === 'number') id = id.toFixed(1); + + if (id === '1.0' || id === '1.1' || id === '1.2') { + if (this.version) this.version = id;else this.options.version = id; + delete this.options.schema; + } else if (id && typeof id === 'string') { + this.options.schema = id; + } + + if (Array.isArray(customTags)) this.options.customTags = customTags; + const opt = Object.assign({}, this.getDefaults(), this.options); + this.schema = new Schema(opt); + } + + parse(node, prevDoc) { + if (this.options.keepCstNodes) this.cstNode = node; + if (this.options.keepNodeTypes) this.type = 'DOCUMENT'; + const { + directives = [], + contents = [], + directivesEndMarker, + error, + valueRange + } = node; + + if (error) { + if (!error.source) error.source = this; + this.errors.push(error); + } + + parseDirectives(this, directives, prevDoc); + if (directivesEndMarker) this.directivesEndMarker = true; + this.range = valueRange ? [valueRange.start, valueRange.end] : null; + this.setSchema(); + this.anchors._cstAliases = []; + parseContents(this, contents); + this.anchors.resolveNodes(); + + if (this.options.prettyErrors) { + for (const error of this.errors) if (error instanceof YAMLError) error.makePretty(); + + for (const warn of this.warnings) if (warn instanceof YAMLError) warn.makePretty(); + } + + return this; + } + + listNonDefaultTags() { + return listTagNames(this.contents).filter(t => t.indexOf(defaultTagPrefix) !== 0); + } + + setTagPrefix(handle, prefix) { + if (handle[0] !== '!' || handle[handle.length - 1] !== '!') throw new Error('Handle must start and end with !'); + + if (prefix) { + const prev = this.tagPrefixes.find(p => p.handle === handle); + if (prev) prev.prefix = prefix;else this.tagPrefixes.push({ + handle, + prefix + }); + } else { + this.tagPrefixes = this.tagPrefixes.filter(p => p.handle !== handle); + } + } + + toJS({ + json, + jsonArg, + mapAsMap, + onAnchor, + reviver + } = {}) { + const anchorNodes = Object.values(this.anchors.map).map(node => [node, { + alias: [], + aliasCount: 0, + count: 1 + }]); + const anchors = anchorNodes.length > 0 ? new Map(anchorNodes) : null; + const ctx = { + anchors, + doc: this, + indentStep: ' ', + keep: !json, + mapAsMap: typeof mapAsMap === 'boolean' ? mapAsMap : !!this.options.mapAsMap, + mapKeyWarned: false, + maxAliasCount: this.options.maxAliasCount, + stringify // Requiring directly in Pair would create circular dependencies + + }; + const res = toJS(this.contents, jsonArg || '', ctx); + if (typeof onAnchor === 'function' && anchors) for (const { + count, + res + } of anchors.values()) onAnchor(res, count); + return typeof reviver === 'function' ? applyReviver(reviver, { + '': res + }, '', res) : res; + } + + toJSON(jsonArg, onAnchor) { + return this.toJS({ + json: true, + jsonArg, + mapAsMap: false, + onAnchor + }); + } + + toString() { + if (this.errors.length > 0) throw new Error('Document with errors cannot be stringified'); + const indentSize = this.options.indent; + + if (!Number.isInteger(indentSize) || indentSize <= 0) { + const s = JSON.stringify(indentSize); + throw new Error("\"indent\" option must be a positive integer, not ".concat(s)); + } + + this.setSchema(); + const lines = []; + let hasDirectives = false; + + if (this.version) { + let vd = '%YAML 1.2'; + + if (this.schema.name === 'yaml-1.1') { + if (this.version === '1.0') vd = '%YAML:1.0';else if (this.version === '1.1') vd = '%YAML 1.1'; + } + + lines.push(vd); + hasDirectives = true; + } + + const tagNames = this.listNonDefaultTags(); + this.tagPrefixes.forEach(({ + handle, + prefix + }) => { + if (tagNames.some(t => t.indexOf(prefix) === 0)) { + lines.push("%TAG ".concat(handle, " ").concat(prefix)); + hasDirectives = true; + } + }); + if (hasDirectives || this.directivesEndMarker) lines.push('---'); + + if (this.commentBefore) { + if (hasDirectives || !this.directivesEndMarker) lines.unshift(''); + lines.unshift(this.commentBefore.replace(/^/gm, '#')); + } + + const ctx = { + anchors: Object.create(null), + doc: this, + indent: '', + indentStep: ' '.repeat(indentSize), + stringify // Requiring directly in nodes would create circular dependencies + + }; + let chompKeep = false; + let contentComment = null; + + if (this.contents) { + if (this.contents instanceof Node$1) { + if (this.contents.spaceBefore && (hasDirectives || this.directivesEndMarker)) lines.push(''); + if (this.contents.commentBefore) lines.push(this.contents.commentBefore.replace(/^/gm, '#')); // top-level block scalars need to be indented if followed by a comment + + ctx.forceBlockIndent = !!this.comment; + contentComment = this.contents.comment; + } + + const onChompKeep = contentComment ? null : () => chompKeep = true; + const body = stringify(this.contents, ctx, () => contentComment = null, onChompKeep); + lines.push(addComment(body, '', contentComment)); + } else { + lines.push(stringify(this.contents, ctx)); + } + + if (this.comment) { + if ((!chompKeep || contentComment) && lines[lines.length - 1] !== '') lines.push(''); + lines.push(this.comment.replace(/^/gm, '#')); + } + + return lines.join('\n') + '\n'; + } + +} + +_defineProperty(Document$1, "defaults", documentOptions); + +function parseDocument(src, options) { + const cst = parse(src); + const doc = new Document$1(cst[0], null, options); + + if (cst.length > 1 && LogLevel.indexOf(doc.options.logLevel) >= LogLevel.ERROR) { + const errMsg = 'Source contains multiple documents; please use YAML.parseAllDocuments()'; + doc.errors.unshift(new YAMLSemanticError(cst[1], errMsg)); + } + + return doc; +} + +class File { + + constructor(app, filename, tagPositions, hasFrontMatter) { + this.app = app; + this.filename = filename; + this.basename = filename.split("/").pop(); + this.tagPositions = tagPositions; + this.hasFrontMatter = !!hasFrontMatter; + } + + /** @param {Replacement} replace */ + async renamed(replace) { + const file = this.app.vault.getAbstractFileByPath(this.filename); + const original = await this.app.vault.read(file); + let text = original; + + for (const { position: { start, end }, tag } of this.tagPositions) { + if (text.slice(start.offset, end.offset) !== tag) { + const msg = `File ${this.filename} has changed; skipping`; + new obsidian.Notice(msg); + console.error(msg); + console.debug(text.slice(start.offset, end.offset), tag); + return; + } + text = replace.inString(text, start.offset); + } + + if (this.hasFrontMatter) + text = this.replaceInFrontMatter(text, replace); + + if (text !== original) { + await this.app.vault.modify(file, text); + return true; + } + } + + /** @param {Replacement} replace */ + replaceInFrontMatter(text, replace) { + const [empty, frontMatter] = text.split(/^---\r?$\n?/m, 2); + + // Check for valid, non-empty, properly terminated front matter + if (empty.trim() !== "" || !frontMatter.trim() || !frontMatter.endsWith("\n")) + return text; + + const parsed = parseDocument(frontMatter); + if (parsed.errors.length) { + const error = `YAML issue with ${this.filename}: ${parsed.errors[0]}`; + console.error(error); new obsidian.Notice(error + "; skipping frontmatter"); + return; + } + + let changed = false; + for (const {key: {value:prop}} of parsed.contents.items) { + if (!/^tags?$/i.test(prop)) continue; + const node = parsed.get(prop, true); + if (!node) continue; + const field = node.toJSON(); + if (!field || !field.length) continue; + if (typeof field === "string") { + const parts = field.split(/([\s,]+)/); + const after = replace.inArray(parts, true).join(""); + if (field != after) { parsed.set(prop, after); changed = true; } + } else if (Array.isArray(field)) { + replace.inArray(field).forEach((v, i) => { + if (field[i] !== v) + node.set(i, v); changed = true; + }); + } + } + return changed ? text.replace(frontMatter, parsed.toString()) : text; + } +} + +async function renameTag(app, tagName) { + const newName = await promptForNewName(tagName); + if (newName === false) return; // aborted + + if (!newName || newName === tagName) { + return new obsidian.Notice("Unchanged or empty tag: No changes made."); + } + + const + oldTag = new Tag(tagName), + newTag = new Tag(newName), + replace = new Replacement(oldTag, newTag), + clashing = replace.willMergeTags( + allTags(app).reverse() // find longest clash first + ), + shouldAbort = clashing && + await shouldAbortDueToClash(clashing, oldTag, newTag) + ; + + if (shouldAbort) return; + + const targets = await findTargets(app, oldTag); + if (!targets) return; + + const progress = new Progress(`Renaming to #${newName}/*`, "Processing files..."); + let renamed = 0; + await progress.forEach(targets, async (target) => { + progress.message = "Processing " + target.basename; + if (await target.renamed(replace)) renamed++; + }); + + return new obsidian.Notice(`Operation ${progress.aborted ? "cancelled" : "complete"}: ${renamed} file(s) updated`); +} + +function allTags(app) { + return Object.keys(app.metadataCache.getTags()); +} + +async function findTargets(app, tag) { + const targets = []; + const progress = new Progress(`Searching for ${tag}/*`, "Matching files..."); + await progress.forEach( + app.metadataCache.getCachedFiles(), + filename => { + let { frontmatter, tags } = app.metadataCache.getCache(filename) || {}; + tags = (tags || []).filter(t => t.tag && tag.matches(t.tag)).reverse(); // last positions first + const fmtags = (obsidian.parseFrontMatterTags(frontmatter) || []).filter(tag.matches); + if (tags.length || fmtags.length) + targets.push(new File(app, filename, tags, fmtags.length)); + } + ); + if (!progress.aborted) + return targets; +} + +async function promptForNewName(tagName) { + try { + return await validatedInput( + `Renaming #${tagName} (and any sub-tags)`, "Enter new name (must be a valid Obsidian tag):\n", + tagName, + "[^\u2000-\u206F\u2E00-\u2E7F'!\"#$%&()*+,.:;<=>?@^`{|}~\\[\\]\\\\\\s]+", + "Obsidian tag name" + ); + } catch(e) { + return false; // user cancelled + } +} + +async function shouldAbortDueToClash([origin, clash], oldTag, newTag) { + try { + await confirm( + "WARNING: No Undo!", + `Renaming ${oldTag} to ${newTag} will merge ${ + (origin.canonical === oldTag.canonical) ? + `these tags` : `multiple tags + into existing tags (such as ${origin} + merging with ${clash})` + }. + + This cannot be undone. Do you wish to proceed?` + ); + } catch(e) { + return true; + } +} + +function onElement(el, event, selector, callback, options) { + el.on(event, selector, callback, options); + return () => el.off(event, selector, callback, options); +} + +class TagWrangler extends obsidian.Plugin { + onload(){ + this.register( + onElement(document, "contextmenu", ".tag-pane-tag", this.onMenu.bind(this), {capture: true}) + ); + } + + onMenu(e, tagEl) { + if (!e.obsidian_contextmenu) { + e.obsidian_contextmenu = new obsidian.Menu(this.app); + setImmediate(() => menu.showAtPosition({x: e.pageX, y: e.pageY})); + } + + const + tagName = tagEl.find(".tag-pane-tag-text").textContent, + isHierarchy = tagEl.parentElement.parentElement.find(".collapse-icon"), + searchPlugin = this.app.internalPlugins.getPluginById("global-search"), + search = searchPlugin && searchPlugin.instance, + query = search && search.getGlobalSearchQuery(), + random = this.app.plugins.plugins["smart-random-note"], + menu = e.obsidian_contextmenu.addItem(item("pencil", "Rename #"+tagName, () => this.rename(tagName))); + + menu.register( + onElement(document, "keydown", "*", e => { + if (e.key==="Escape") { + e.preventDefault(); + e.stopPropagation(); + menu.hide(); + } + }, {capture: true}) + ); + + if (search) { + menu.addSeparator().addItem( + item("magnifying-glass", "New search for #"+tagName, () => search.openGlobalSearch("tag:" + tagName)) + ); + if (query) { + menu.addItem( + item("sheets-in-box", "Require #"+tagName+" in search" , () => search.openGlobalSearch(query+" tag:" + tagName)) + ); + } + menu.addItem( + item("crossed-star" , "Exclude #"+tagName+" from search", () => search.openGlobalSearch(query+" -tag:" + tagName)) + ); + } + + if (random) { + menu.addSeparator().addItem( + item("dice", "Open random note", async () => { + const targets = await findTargets(this.app, new Tag(tagName)); + random.openRandomNote(targets.map(f=>f.filename)); + }) + ); + } + + this.app.workspace.trigger("tag-wrangler:contextmenu", menu, tagName, {search, query, isHierarchy}); + + if (isHierarchy) { + const + tagParent = tagName.split("/").slice(0, -1).join("/"), + tagView = this.leafView(tagEl.matchParent(".workspace-leaf")), + tagContainer = tagParent ? tagView.tagDoms["#" + tagParent.toLowerCase()]: tagView.root + ; + function toggle(collapse) { + for(const tag of tagContainer.children) tag.setCollapsed(collapse); + } + menu.addSeparator() + .addItem(item("vertical-three-dots", "Collapse tags at this level", () => toggle(true ))) + .addItem(item("expand-vertically" , "Expand tags at this level" , () => toggle(false))); + } + } + + leafView(containerEl) { + let view; + this.app.workspace.iterateAllLeaves((leaf) => { + if (leaf.containerEl === containerEl) { view = leaf.view; return true; } + }); + return view; + } + + + async rename(tagName) { + const scope = new obsidian.Scope; + this.app.keymap.pushScope(scope); + try { await renameTag(this.app, tagName); } + catch (e) { console.error(e); new obsidian.Notice("error: " + e); } + this.app.keymap.popScope(scope); + } + +} + +function item(icon, title, click) { + return i => i.setIcon(icon).setTitle(title).onClick(click); +} + +module.exports = TagWrangler; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZXMiOlsiLnlhcm4vY2FjaGUvY3VycmlmeS1ucG0tNC4wLjAtYjkyZWUzYTRlYi04MjViNjgxODQxLnppcC9ub2RlX21vZHVsZXMvY3VycmlmeS9saWIvY3VycmlmeS5qcyIsIi55YXJuL2NhY2hlL2Z1bGxzdG9yZS1ucG0tMy4wLjAtYzQ4NTY0NGE2NS02ZDM5OTNjN2JmLnppcC9ub2RlX21vZHVsZXMvZnVsbHN0b3JlL2xpYi9mdWxsc3RvcmUuanMiLCIueWFybi9jYWNoZS9AY2xvdWRjbWQtY3JlYXRlLWVsZW1lbnQtbnBtLTIuMC4yLTE5NzY5NTlhNmMtMTk2ZDA5YjJkMi56aXAvbm9kZV9tb2R1bGVzL0BjbG91ZGNtZC9jcmVhdGUtZWxlbWVudC9saWIvY3JlYXRlLWVsZW1lbnQuanMiLCIueWFybi9jYWNoZS9zbWFsbHRhbGstbnBtLTQuMC43LTgyMzM5ZjY2NzItZDY3MzZmMzI0Yy56aXAvbm9kZV9tb2R1bGVzL3NtYWxsdGFsay9saWIvc21hbGx0YWxrLmpzIiwic3JjL3Byb2dyZXNzLmpzIiwic3JjL3ZhbGlkYXRpb24uanMiLCJzcmMvVGFnLmpzIiwiLnlhcm4vY2FjaGUveWFtbC1ucG0tMi4wLjAtMy0zMTc2OGU4MjdkLWZjMTQyMjcwNzkuemlwL25vZGVfbW9kdWxlcy95YW1sL2Jyb3dzZXIvZGlzdC9jb25zdGFudHMuanMiLCIueWFybi9jYWNoZS95YW1sLW5wbS0yLjAuMC0zLTMxNzY4ZTgyN2QtZmMxNDIyNzA3OS56aXAvbm9kZV9tb2R1bGVzL3lhbWwvYnJvd3Nlci9kaXN0L2NzdC9zb3VyY2UtdXRpbHMuanMiLCIueWFybi9jYWNoZS95YW1sLW5wbS0yLjAuMC0zLTMxNzY4ZTgyN2QtZmMxNDIyNzA3OS56aXAvbm9kZV9tb2R1bGVzL3lhbWwvYnJvd3Nlci9kaXN0L2NzdC9SYW5nZS5qcyIsIi55YXJuL2NhY2hlL3lhbWwtbnBtLTIuMC4wLTMtMzE3NjhlODI3ZC1mYzE0MjI3MDc5LnppcC9ub2RlX21vZHVsZXMveWFtbC9icm93c2VyL2Rpc3QvY3N0L05vZGUuanMiLCIueWFybi9jYWNoZS95YW1sLW5wbS0yLjAuMC0zLTMxNzY4ZTgyN2QtZmMxNDIyNzA3OS56aXAvbm9kZV9tb2R1bGVzL3lhbWwvYnJvd3Nlci9kaXN0L2Vycm9ycy5qcyIsIi55YXJuL2NhY2hlL3lhbWwtbnBtLTIuMC4wLTMtMzE3NjhlODI3ZC1mYzE0MjI3MDc5LnppcC9ub2RlX21vZHVsZXMveWFtbC9icm93c2VyL2Rpc3QvY3N0L0JsYW5rTGluZS5qcyIsIi55YXJuL2NhY2hlL3lhbWwtbnBtLTIuMC4wLTMtMzE3NjhlODI3ZC1mYzE0MjI3MDc5LnppcC9ub2RlX21vZHVsZXMveWFtbC9icm93c2VyL2Rpc3QvY3N0L0NvbGxlY3Rpb25JdGVtLmpzIiwiLnlhcm4vY2FjaGUveWFtbC1ucG0tMi4wLjAtMy0zMTc2OGU4MjdkLWZjMTQyMjcwNzkuemlwL25vZGVfbW9kdWxlcy95YW1sL2Jyb3dzZXIvZGlzdC9jc3QvQ29tbWVudC5qcyIsIi55YXJuL2NhY2hlL3lhbWwtbnBtLTIuMC4wLTMtMzE3NjhlODI3ZC1mYzE0MjI3MDc5LnppcC9ub2RlX21vZHVsZXMveWFtbC9icm93c2VyL2Rpc3QvY3N0L0NvbGxlY3Rpb24uanMiLCIueWFybi9jYWNoZS95YW1sLW5wbS0yLjAuMC0zLTMxNzY4ZTgyN2QtZmMxNDIyNzA3OS56aXAvbm9kZV9tb2R1bGVzL3lhbWwvYnJvd3Nlci9kaXN0L2NzdC9EaXJlY3RpdmUuanMiLCIueWFybi9jYWNoZS95YW1sLW5wbS0yLjAuMC0zLTMxNzY4ZTgyN2QtZmMxNDIyNzA3OS56aXAvbm9kZV9tb2R1bGVzL3lhbWwvYnJvd3Nlci9kaXN0L2NzdC9Eb2N1bWVudC5qcyIsIi55YXJuL2NhY2hlL3lhbWwtbnBtLTIuMC4wLTMtMzE3NjhlODI3ZC1mYzE0MjI3MDc5LnppcC9ub2RlX21vZHVsZXMveWFtbC9icm93c2VyL2Rpc3QvX3ZpcnR1YWwvX3JvbGx1cFBsdWdpbkJhYmVsSGVscGVycy5qcyIsIi55YXJuL2NhY2hlL3lhbWwtbnBtLTIuMC4wLTMtMzE3NjhlODI3ZC1mYzE0MjI3MDc5LnppcC9ub2RlX21vZHVsZXMveWFtbC9icm93c2VyL2Rpc3QvY3N0L0FsaWFzLmpzIiwiLnlhcm4vY2FjaGUveWFtbC1ucG0tMi4wLjAtMy0zMTc2OGU4MjdkLWZjMTQyMjcwNzkuemlwL25vZGVfbW9kdWxlcy95YW1sL2Jyb3dzZXIvZGlzdC9jc3QvQmxvY2tWYWx1ZS5qcyIsIi55YXJuL2NhY2hlL3lhbWwtbnBtLTIuMC4wLTMtMzE3NjhlODI3ZC1mYzE0MjI3MDc5LnppcC9ub2RlX21vZHVsZXMveWFtbC9icm93c2VyL2Rpc3QvY3N0L0Zsb3dDb2xsZWN0aW9uLmpzIiwiLnlhcm4vY2FjaGUveWFtbC1ucG0tMi4wLjAtMy0zMTc2OGU4MjdkLWZjMTQyMjcwNzkuemlwL25vZGVfbW9kdWxlcy95YW1sL2Jyb3dzZXIvZGlzdC9jc3QvUGxhaW5WYWx1ZS5qcyIsIi55YXJuL2NhY2hlL3lhbWwtbnBtLTIuMC4wLTMtMzE3NjhlODI3ZC1mYzE0MjI3MDc5LnppcC9ub2RlX21vZHVsZXMveWFtbC9icm93c2VyL2Rpc3QvY3N0L1F1b3RlRG91YmxlLmpzIiwiLnlhcm4vY2FjaGUveWFtbC1ucG0tMi4wLjAtMy0zMTc2OGU4MjdkLWZjMTQyMjcwNzkuemlwL25vZGVfbW9kdWxlcy95YW1sL2Jyb3dzZXIvZGlzdC9jc3QvUXVvdGVTaW5nbGUuanMiLCIueWFybi9jYWNoZS95YW1sLW5wbS0yLjAuMC0zLTMxNzY4ZTgyN2QtZmMxNDIyNzA3OS56aXAvbm9kZV9tb2R1bGVzL3lhbWwvYnJvd3Nlci9kaXN0L2NzdC9QYXJzZUNvbnRleHQuanMiLCIueWFybi9jYWNoZS95YW1sLW5wbS0yLjAuMC0zLTMxNzY4ZTgyN2QtZmMxNDIyNzA3OS56aXAvbm9kZV9tb2R1bGVzL3lhbWwvYnJvd3Nlci9kaXN0L2NzdC9wYXJzZS5qcyIsIi55YXJuL2NhY2hlL3lhbWwtbnBtLTIuMC4wLTMtMzE3NjhlODI3ZC1mYzE0MjI3MDc5LnppcC9ub2RlX21vZHVsZXMveWFtbC9icm93c2VyL2Rpc3QvdGFncy9vcHRpb25zLmpzIiwiLnlhcm4vY2FjaGUveWFtbC1ucG0tMi4wLjAtMy0zMTc2OGU4MjdkLWZjMTQyMjcwNzkuemlwL25vZGVfbW9kdWxlcy95YW1sL2Jyb3dzZXIvZGlzdC9vcHRpb25zLmpzIiwiLnlhcm4vY2FjaGUveWFtbC1ucG0tMi4wLjAtMy0zMTc2OGU4MjdkLWZjMTQyMjcwNzkuemlwL25vZGVfbW9kdWxlcy95YW1sL2Jyb3dzZXIvZGlzdC9zdHJpbmdpZnkvYWRkQ29tbWVudC5qcyIsIi55YXJuL2NhY2hlL3lhbWwtbnBtLTIuMC4wLTMtMzE3NjhlODI3ZC1mYzE0MjI3MDc5LnppcC9ub2RlX21vZHVsZXMveWFtbC9icm93c2VyL2Rpc3QvYXN0L05vZGUuanMiLCIueWFybi9jYWNoZS95YW1sLW5wbS0yLjAuMC0zLTMxNzY4ZTgyN2QtZmMxNDIyNzA3OS56aXAvbm9kZV9tb2R1bGVzL3lhbWwvYnJvd3Nlci9kaXN0L2FzdC90b0pTLmpzIiwiLnlhcm4vY2FjaGUveWFtbC1ucG0tMi4wLjAtMy0zMTc2OGU4MjdkLWZjMTQyMjcwNzkuemlwL25vZGVfbW9kdWxlcy95YW1sL2Jyb3dzZXIvZGlzdC9hc3QvU2NhbGFyLmpzIiwiLnlhcm4vY2FjaGUveWFtbC1ucG0tMi4wLjAtMy0zMTc2OGU4MjdkLWZjMTQyMjcwNzkuemlwL25vZGVfbW9kdWxlcy95YW1sL2Jyb3dzZXIvZGlzdC9kb2MvY3JlYXRlTm9kZS5qcyIsIi55YXJuL2NhY2hlL3lhbWwtbnBtLTIuMC4wLTMtMzE3NjhlODI3ZC1mYzE0MjI3MDc5LnppcC9ub2RlX21vZHVsZXMveWFtbC9icm93c2VyL2Rpc3QvYXN0L0NvbGxlY3Rpb24uanMiLCIueWFybi9jYWNoZS95YW1sLW5wbS0yLjAuMC0zLTMxNzY4ZTgyN2QtZmMxNDIyNzA3OS56aXAvbm9kZV9tb2R1bGVzL3lhbWwvYnJvd3Nlci9kaXN0L2xvZy5qcyIsIi55YXJuL2NhY2hlL3lhbWwtbnBtLTIuMC4wLTMtMzE3NjhlODI3ZC1mYzE0MjI3MDc5LnppcC9ub2RlX21vZHVsZXMveWFtbC9icm93c2VyL2Rpc3QvYXN0L1lBTUxTZXEuanMiLCIueWFybi9jYWNoZS95YW1sLW5wbS0yLjAuMC0zLTMxNzY4ZTgyN2QtZmMxNDIyNzA3OS56aXAvbm9kZV9tb2R1bGVzL3lhbWwvYnJvd3Nlci9kaXN0L2FzdC9QYWlyLmpzIiwiLnlhcm4vY2FjaGUveWFtbC1ucG0tMi4wLjAtMy0zMTc2OGU4MjdkLWZjMTQyMjcwNzkuemlwL25vZGVfbW9kdWxlcy95YW1sL2Jyb3dzZXIvZGlzdC9hc3QvQWxpYXMuanMiLCIueWFybi9jYWNoZS95YW1sLW5wbS0yLjAuMC0zLTMxNzY4ZTgyN2QtZmMxNDIyNzA3OS56aXAvbm9kZV9tb2R1bGVzL3lhbWwvYnJvd3Nlci9kaXN0L3Jlc29sdmUvcmVzb2x2ZVNjYWxhci5qcyIsIi55YXJuL2NhY2hlL3lhbWwtbnBtLTIuMC4wLTMtMzE3NjhlODI3ZC1mYzE0MjI3MDc5LnppcC9ub2RlX21vZHVsZXMveWFtbC9icm93c2VyL2Rpc3Qvc3RyaW5naWZ5L2ZvbGRGbG93TGluZXMuanMiLCIueWFybi9jYWNoZS95YW1sLW5wbS0yLjAuMC0zLTMxNzY4ZTgyN2QtZmMxNDIyNzA3OS56aXAvbm9kZV9tb2R1bGVzL3lhbWwvYnJvd3Nlci9kaXN0L3N0cmluZ2lmeS9zdHJpbmdpZnlTdHJpbmcuanMiLCIueWFybi9jYWNoZS95YW1sLW5wbS0yLjAuMC0zLTMxNzY4ZTgyN2QtZmMxNDIyNzA3OS56aXAvbm9kZV9tb2R1bGVzL3lhbWwvYnJvd3Nlci9kaXN0L3N0cmluZ2lmeS9zdHJpbmdpZnlUYWcuanMiLCIueWFybi9jYWNoZS95YW1sLW5wbS0yLjAuMC0zLTMxNzY4ZTgyN2QtZmMxNDIyNzA3OS56aXAvbm9kZV9tb2R1bGVzL3lhbWwvYnJvd3Nlci9kaXN0L3N0cmluZ2lmeS9zdHJpbmdpZnkuanMiLCIueWFybi9jYWNoZS95YW1sLW5wbS0yLjAuMC0zLTMxNzY4ZTgyN2QtZmMxNDIyNzA3OS56aXAvbm9kZV9tb2R1bGVzL3lhbWwvYnJvd3Nlci9kaXN0L2FzdC9ZQU1MTWFwLmpzIiwiLnlhcm4vY2FjaGUveWFtbC1ucG0tMi4wLjAtMy0zMTc2OGU4MjdkLWZjMTQyMjcwNzkuemlwL25vZGVfbW9kdWxlcy95YW1sL2Jyb3dzZXIvZGlzdC9hc3QvTWVyZ2UuanMiLCIueWFybi9jYWNoZS95YW1sLW5wbS0yLjAuMC0zLTMxNzY4ZTgyN2QtZmMxNDIyNzA3OS56aXAvbm9kZV9tb2R1bGVzL3lhbWwvYnJvd3Nlci9kaXN0L2RvYy9BbmNob3JzLmpzIiwiLnlhcm4vY2FjaGUveWFtbC1ucG0tMi4wLjAtMy0zMTc2OGU4MjdkLWZjMTQyMjcwNzkuemlwL25vZGVfbW9kdWxlcy95YW1sL2Jyb3dzZXIvZGlzdC9zdHJpbmdpZnkvc3RyaW5naWZ5TnVtYmVyLmpzIiwiLnlhcm4vY2FjaGUveWFtbC1ucG0tMi4wLjAtMy0zMTc2OGU4MjdkLWZjMTQyMjcwNzkuemlwL25vZGVfbW9kdWxlcy95YW1sL2Jyb3dzZXIvZGlzdC90YWdzL2ZhaWxzYWZlL21hcC5qcyIsIi55YXJuL2NhY2hlL3lhbWwtbnBtLTIuMC4wLTMtMzE3NjhlODI3ZC1mYzE0MjI3MDc5LnppcC9ub2RlX21vZHVsZXMveWFtbC9icm93c2VyL2Rpc3QvdGFncy9mYWlsc2FmZS9zZXEuanMiLCIueWFybi9jYWNoZS95YW1sLW5wbS0yLjAuMC0zLTMxNzY4ZTgyN2QtZmMxNDIyNzA3OS56aXAvbm9kZV9tb2R1bGVzL3lhbWwvYnJvd3Nlci9kaXN0L3RhZ3MvZmFpbHNhZmUvc3RyaW5nLmpzIiwiLnlhcm4vY2FjaGUveWFtbC1ucG0tMi4wLjAtMy0zMTc2OGU4MjdkLWZjMTQyMjcwNzkuemlwL25vZGVfbW9kdWxlcy95YW1sL2Jyb3dzZXIvZGlzdC90YWdzL2ZhaWxzYWZlL2luZGV4LmpzIiwiLnlhcm4vY2FjaGUveWFtbC1ucG0tMi4wLjAtMy0zMTc2OGU4MjdkLWZjMTQyMjcwNzkuemlwL25vZGVfbW9kdWxlcy95YW1sL2Jyb3dzZXIvZGlzdC90YWdzL2NvcmUuanMiLCIueWFybi9jYWNoZS95YW1sLW5wbS0yLjAuMC0zLTMxNzY4ZTgyN2QtZmMxNDIyNzA3OS56aXAvbm9kZV9tb2R1bGVzL3lhbWwvYnJvd3Nlci9kaXN0L3RhZ3MvanNvbi5qcyIsIi55YXJuL2NhY2hlL3lhbWwtbnBtLTIuMC4wLTMtMzE3NjhlODI3ZC1mYzE0MjI3MDc5LnppcC9ub2RlX21vZHVsZXMveWFtbC9icm93c2VyL2Rpc3QvdGFncy95YW1sLTEuMS9iaW5hcnkuanMiLCIueWFybi9jYWNoZS95YW1sLW5wbS0yLjAuMC0zLTMxNzY4ZTgyN2QtZmMxNDIyNzA3OS56aXAvbm9kZV9tb2R1bGVzL3lhbWwvYnJvd3Nlci9kaXN0L3RhZ3MveWFtbC0xLjEvcGFpcnMuanMiLCIueWFybi9jYWNoZS95YW1sLW5wbS0yLjAuMC0zLTMxNzY4ZTgyN2QtZmMxNDIyNzA3OS56aXAvbm9kZV9tb2R1bGVzL3lhbWwvYnJvd3Nlci9kaXN0L3RhZ3MveWFtbC0xLjEvb21hcC5qcyIsIi55YXJuL2NhY2hlL3lhbWwtbnBtLTIuMC4wLTMtMzE3NjhlODI3ZC1mYzE0MjI3MDc5LnppcC9ub2RlX21vZHVsZXMveWFtbC9icm93c2VyL2Rpc3QvdGFncy95YW1sLTEuMS9zZXQuanMiLCIueWFybi9jYWNoZS95YW1sLW5wbS0yLjAuMC0zLTMxNzY4ZTgyN2QtZmMxNDIyNzA3OS56aXAvbm9kZV9tb2R1bGVzL3lhbWwvYnJvd3Nlci9kaXN0L3RhZ3MveWFtbC0xLjEvdGltZXN0YW1wLmpzIiwiLnlhcm4vY2FjaGUveWFtbC1ucG0tMi4wLjAtMy0zMTc2OGU4MjdkLWZjMTQyMjcwNzkuemlwL25vZGVfbW9kdWxlcy95YW1sL2Jyb3dzZXIvZGlzdC90YWdzL3lhbWwtMS4xL2luZGV4LmpzIiwiLnlhcm4vY2FjaGUveWFtbC1ucG0tMi4wLjAtMy0zMTc2OGU4MjdkLWZjMTQyMjcwNzkuemlwL25vZGVfbW9kdWxlcy95YW1sL2Jyb3dzZXIvZGlzdC90YWdzL2luZGV4LmpzIiwiLnlhcm4vY2FjaGUveWFtbC1ucG0tMi4wLjAtMy0zMTc2OGU4MjdkLWZjMTQyMjcwNzkuemlwL25vZGVfbW9kdWxlcy95YW1sL2Jyb3dzZXIvZGlzdC9kb2MvZ2V0U2NoZW1hVGFncy5qcyIsIi55YXJuL2NhY2hlL3lhbWwtbnBtLTIuMC4wLTMtMzE3NjhlODI3ZC1mYzE0MjI3MDc5LnppcC9ub2RlX21vZHVsZXMveWFtbC9icm93c2VyL2Rpc3QvZG9jL1NjaGVtYS5qcyIsIi55YXJuL2NhY2hlL3lhbWwtbnBtLTIuMC4wLTMtMzE3NjhlODI3ZC1mYzE0MjI3MDc5LnppcC9ub2RlX21vZHVsZXMveWFtbC9icm93c2VyL2Rpc3QvZG9jL2FwcGx5UmV2aXZlci5qcyIsIi55YXJuL2NhY2hlL3lhbWwtbnBtLTIuMC4wLTMtMzE3NjhlODI3ZC1mYzE0MjI3MDc5LnppcC9ub2RlX21vZHVsZXMveWFtbC9icm93c2VyL2Rpc3QvZG9jL2xpc3RUYWdOYW1lcy5qcyIsIi55YXJuL2NhY2hlL3lhbWwtbnBtLTIuMC4wLTMtMzE3NjhlODI3ZC1mYzE0MjI3MDc5LnppcC9ub2RlX21vZHVsZXMveWFtbC9icm93c2VyL2Rpc3QvcmVzb2x2ZS9yZXNvbHZlVGFnTmFtZS5qcyIsIi55YXJuL2NhY2hlL3lhbWwtbnBtLTIuMC4wLTMtMzE3NjhlODI3ZC1mYzE0MjI3MDc5LnppcC9ub2RlX21vZHVsZXMveWFtbC9icm93c2VyL2Rpc3QvcmVzb2x2ZS9jb2xsZWN0aW9uLXV0aWxzLmpzIiwiLnlhcm4vY2FjaGUveWFtbC1ucG0tMi4wLjAtMy0zMTc2OGU4MjdkLWZjMTQyMjcwNzkuemlwL25vZGVfbW9kdWxlcy95YW1sL2Jyb3dzZXIvZGlzdC9yZXNvbHZlL3Jlc29sdmVNYXAuanMiLCIueWFybi9jYWNoZS95YW1sLW5wbS0yLjAuMC0zLTMxNzY4ZTgyN2QtZmMxNDIyNzA3OS56aXAvbm9kZV9tb2R1bGVzL3lhbWwvYnJvd3Nlci9kaXN0L3Jlc29sdmUvcmVzb2x2ZVNlcS5qcyIsIi55YXJuL2NhY2hlL3lhbWwtbnBtLTIuMC4wLTMtMzE3NjhlODI3ZC1mYzE0MjI3MDc5LnppcC9ub2RlX21vZHVsZXMveWFtbC9icm93c2VyL2Rpc3QvcmVzb2x2ZS9yZXNvbHZlVGFnLmpzIiwiLnlhcm4vY2FjaGUveWFtbC1ucG0tMi4wLjAtMy0zMTc2OGU4MjdkLWZjMTQyMjcwNzkuemlwL25vZGVfbW9kdWxlcy95YW1sL2Jyb3dzZXIvZGlzdC9yZXNvbHZlL3Jlc29sdmVOb2RlLmpzIiwiLnlhcm4vY2FjaGUveWFtbC1ucG0tMi4wLjAtMy0zMTc2OGU4MjdkLWZjMTQyMjcwNzkuemlwL25vZGVfbW9kdWxlcy95YW1sL2Jyb3dzZXIvZGlzdC9kb2MvcGFyc2VDb250ZW50cy5qcyIsIi55YXJuL2NhY2hlL3lhbWwtbnBtLTIuMC4wLTMtMzE3NjhlODI3ZC1mYzE0MjI3MDc5LnppcC9ub2RlX21vZHVsZXMveWFtbC9icm93c2VyL2Rpc3QvZG9jL3BhcnNlRGlyZWN0aXZlcy5qcyIsIi55YXJuL2NhY2hlL3lhbWwtbnBtLTIuMC4wLTMtMzE3NjhlODI3ZC1mYzE0MjI3MDc5LnppcC9ub2RlX21vZHVsZXMveWFtbC9icm93c2VyL2Rpc3QvZG9jL0RvY3VtZW50LmpzIiwiLnlhcm4vY2FjaGUveWFtbC1ucG0tMi4wLjAtMy0zMTc2OGU4MjdkLWZjMTQyMjcwNzkuemlwL25vZGVfbW9kdWxlcy95YW1sL2Jyb3dzZXIvZGlzdC9pbmRleC5qcyIsInNyYy9GaWxlLmpzIiwic3JjL3JlbmFtaW5nLmpzIiwic3JjL3BsdWdpbi5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbmNvbnN0IGYgPSAoZm4pID0+IFtcbiAgICAvKmVzbGludCBuby11bnVzZWQtdmFyczogMCovXG4gICAgZnVuY3Rpb24gKGEpIHtyZXR1cm4gZm4oLi4uYXJndW1lbnRzKTt9LFxuICAgIGZ1bmN0aW9uIChhLCBiKSB7cmV0dXJuIGZuKC4uLmFyZ3VtZW50cyk7fSxcbiAgICBmdW5jdGlvbiAoYSwgYiwgYykge3JldHVybiBmbiguLi5hcmd1bWVudHMpO30sXG4gICAgZnVuY3Rpb24gKGEsIGIsIGMsIGQpIHtyZXR1cm4gZm4oLi4uYXJndW1lbnRzKTt9LFxuICAgIGZ1bmN0aW9uIChhLCBiLCBjLCBkLCBlKSB7cmV0dXJuIGZuKC4uLmFyZ3VtZW50cyk7fSxcbl07XG5cbmNvbnN0IGN1cnJpZnkgPSAoZm4sIC4uLmFyZ3MpID0+IHtcbiAgICBjaGVjayhmbik7XG4gICAgXG4gICAgaWYgKGFyZ3MubGVuZ3RoID49IGZuLmxlbmd0aClcbiAgICAgICAgcmV0dXJuIGZuKC4uLmFyZ3MpO1xuICAgIFxuICAgIGNvbnN0IGFnYWluID0gKC4uLmFyZ3MyKSA9PiB7XG4gICAgICAgIHJldHVybiBjdXJyaWZ5KGZuLCAuLi5bLi4uYXJncywgLi4uYXJnczJdKTtcbiAgICB9O1xuICAgIFxuICAgIGNvbnN0IGNvdW50ID0gZm4ubGVuZ3RoIC0gYXJncy5sZW5ndGggLSAxO1xuICAgIGNvbnN0IGZ1bmMgPSBmKGFnYWluKVtjb3VudF07XG4gICAgXG4gICAgcmV0dXJuIGZ1bmMgfHwgYWdhaW47XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGN1cnJpZnk7XG5cbmZ1bmN0aW9uIGNoZWNrKGZuKSB7XG4gICAgaWYgKHR5cGVvZiBmbiAhPT0gJ2Z1bmN0aW9uJylcbiAgICAgICAgdGhyb3cgRXJyb3IoJ2ZuIHNob3VsZCBiZSBmdW5jdGlvbiEnKTtcbn1cblxuIiwiJ3VzZSBzdHJpY3QnO1xuXG5tb2R1bGUuZXhwb3J0cyA9ICh2YWx1ZSkgPT4ge1xuICAgIGNvbnN0IGRhdGEgPSB7XG4gICAgICAgIHZhbHVlLFxuICAgIH07XG4gICAgXG4gICAgcmV0dXJuICguLi5hcmdzKSA9PiB7XG4gICAgICAgIGNvbnN0IFt2YWx1ZV0gPSBhcmdzO1xuICAgICAgICBcbiAgICAgICAgaWYgKCFhcmdzLmxlbmd0aClcbiAgICAgICAgICAgIHJldHVybiBkYXRhLnZhbHVlO1xuICAgICAgICBcbiAgICAgICAgZGF0YS52YWx1ZSA9IHZhbHVlO1xuICAgICAgICBcbiAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH07XG59O1xuXG4iLCIndXNlIHN0cmljdCc7XG5cbmNvbnN0IGN1cnJpZnkgPSByZXF1aXJlKCdjdXJyaWZ5Jyk7XG5jb25zdCBxdWVyeSA9IChhKSA9PiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGBbZGF0YS1uYW1lPVwiJHthfVwiXWApO1xuXG5jb25zdCBzZXRBdHRyaWJ1dGUgPSBjdXJyaWZ5KChlbCwgb2JqLCBuYW1lKSA9PiBlbC5zZXRBdHRyaWJ1dGUobmFtZSwgb2JqW25hbWVdKSk7XG5jb25zdCBzZXQgPSBjdXJyaWZ5KChlbCwgb2JqLCBuYW1lKSA9PiBlbFtuYW1lXSA9IG9ialtuYW1lXSk7XG5jb25zdCBub3QgPSBjdXJyaWZ5KChmLCBhKSA9PiAhZihhKSk7XG5jb25zdCBpc0NhbWVsQ2FzZSA9IChhKSA9PiBhICE9IGEudG9Mb3dlckNhc2UoKTtcblxubW9kdWxlLmV4cG9ydHMgPSAobmFtZSwgb3B0aW9ucyA9IHt9KSA9PiB7XG4gICAgY29uc3Qge1xuICAgICAgICBkYXRhTmFtZSxcbiAgICAgICAgbm90QXBwZW5kLFxuICAgICAgICBwYXJlbnQgPSBkb2N1bWVudC5ib2R5LFxuICAgICAgICB1bmlxID0gdHJ1ZSxcbiAgICAgICAgLi4ucmVzdE9wdGlvbnNcbiAgICB9ID0gb3B0aW9ucztcbiAgICBcbiAgICBjb25zdCBlbEZvdW5kID0gaXNFbGVtZW50UHJlc2VudChkYXRhTmFtZSk7XG4gICAgXG4gICAgaWYgKHVuaXEgJiYgZWxGb3VuZClcbiAgICAgICAgcmV0dXJuIGVsRm91bmQ7XG4gICAgXG4gICAgY29uc3QgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KG5hbWUpO1xuICAgIFxuICAgIGlmIChkYXRhTmFtZSlcbiAgICAgICAgZWwuZGF0YXNldC5uYW1lID0gZGF0YU5hbWU7XG4gICAgXG4gICAgT2JqZWN0LmtleXMocmVzdE9wdGlvbnMpXG4gICAgICAgIC5maWx0ZXIoaXNDYW1lbENhc2UpXG4gICAgICAgIC5tYXAoc2V0KGVsLCBvcHRpb25zKSk7XG4gICAgXG4gICAgT2JqZWN0LmtleXMocmVzdE9wdGlvbnMpXG4gICAgICAgIC5maWx0ZXIobm90KGlzQ2FtZWxDYXNlKSlcbiAgICAgICAgLm1hcChzZXRBdHRyaWJ1dGUoZWwsIG9wdGlvbnMpKTtcbiAgICBcbiAgICBpZiAoIW5vdEFwcGVuZClcbiAgICAgICAgcGFyZW50LmFwcGVuZENoaWxkKGVsKTtcbiAgICBcbiAgICByZXR1cm4gZWw7XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5pc0VsZW1lbnRQcmVzZW50ID0gaXNFbGVtZW50UHJlc2VudDtcblxuZnVuY3Rpb24gaXNFbGVtZW50UHJlc2VudChkYXRhTmFtZSkge1xuICAgIGlmICghZGF0YU5hbWUpXG4gICAgICAgIHJldHVybjtcbiAgICBcbiAgICByZXR1cm4gcXVlcnkoZGF0YU5hbWUpO1xufVxuXG4iLCIndXNlIHN0cmljdCc7XG5cbnJlcXVpcmUoJy4uL2Nzcy9zbWFsbHRhbGsuY3NzJyk7XG5cbmNvbnN0IGN1cnJpZnkgPSByZXF1aXJlKCdjdXJyaWZ5Jyk7XG5jb25zdCBzdG9yZSA9IHJlcXVpcmUoJ2Z1bGxzdG9yZScpO1xuY29uc3QgY3JlYXRlRWxlbWVudCA9IHJlcXVpcmUoJ0BjbG91ZGNtZC9jcmVhdGUtZWxlbWVudCcpO1xuXG5jb25zdCBrZXlEb3duID0gY3VycmlmeShrZXlEb3duXyk7XG5cbmNvbnN0IEJVVFRPTl9PSyA9IHtcbiAgICBvazogJ09LJyxcbn07XG5cbmNvbnN0IEJVVFRPTl9PS19DQU5DRUwgPSB7XG4gICAgb2s6ICdPSycsXG4gICAgY2FuY2VsOiAnQ2FuY2VsJyxcbn07XG5cbmNvbnN0IHpJbmRleCA9IHN0b3JlKDEwMCk7XG5cbmV4cG9ydHMuYWxlcnQgPSAodGl0bGUsIG1zZywgb3B0aW9ucykgPT4ge1xuICAgIGNvbnN0IGJ1dHRvbnMgPSBnZXRCdXR0b25zKG9wdGlvbnMpIHx8IEJVVFRPTl9PSztcbiAgICByZXR1cm4gc2hvd0RpYWxvZyh0aXRsZSwgbXNnLCAnJywgYnV0dG9ucywgb3B0aW9ucyk7XG59O1xuXG5leHBvcnRzLnByb21wdCA9ICh0aXRsZSwgbXNnLCB2YWx1ZSA9ICcnLCBvcHRpb25zKSA9PiB7XG4gICAgY29uc3QgdHlwZSA9IGdldFR5cGUob3B0aW9ucyk7XG4gICAgY29uc3QgdmFsID0gU3RyaW5nKHZhbHVlKVxuICAgICAgICAucmVwbGFjZSgvXCIvZywgJyZxdW90OycpO1xuICAgIFxuICAgIGNvbnN0IHZhbHVlU3RyID0gYDxpbnB1dCB0eXBlPVwiJHsgdHlwZSB9XCIgdmFsdWU9XCIkeyB2YWwgfVwiIGRhdGEtbmFtZT1cImpzLWlucHV0XCI+YDtcbiAgICBjb25zdCBidXR0b25zID0gZ2V0QnV0dG9ucyhvcHRpb25zKSB8fCBCVVRUT05fT0tfQ0FOQ0VMO1xuICAgIFxuICAgIHJldHVybiBzaG93RGlhbG9nKHRpdGxlLCBtc2csIHZhbHVlU3RyLCBidXR0b25zLCBvcHRpb25zKTtcbn07XG5cbmV4cG9ydHMuY29uZmlybSA9ICh0aXRsZSwgbXNnLCBvcHRpb25zKSA9PiB7XG4gICAgY29uc3QgYnV0dG9ucyA9IGdldEJ1dHRvbnMob3B0aW9ucykgfHwgQlVUVE9OX09LX0NBTkNFTDtcbiAgICBcbiAgICByZXR1cm4gc2hvd0RpYWxvZyh0aXRsZSwgbXNnLCAnJywgYnV0dG9ucywgb3B0aW9ucyk7XG59O1xuXG5leHBvcnRzLnByb2dyZXNzID0gKHRpdGxlLCBtZXNzYWdlLCBvcHRpb25zKSA9PiB7XG4gICAgY29uc3QgdmFsdWVTdHIgPSBgXG4gICAgICAgIDxwcm9ncmVzcyB2YWx1ZT1cIjBcIiBkYXRhLW5hbWU9XCJqcy1wcm9ncmVzc1wiIGNsYXNzPVwicHJvZ3Jlc3NcIiBtYXg9XCIxMDBcIj48L3Byb2dyZXNzPlxuICAgICAgICA8c3BhbiBkYXRhLW5hbWU9XCJqcy1jb3VudGVyXCI+MCU8L3NwYW4+XG4gICAgYDtcbiAgICBcbiAgICBjb25zdCBidXR0b25zID0ge1xuICAgICAgICBjYW5jZWw6ICdBYm9ydCcsXG4gICAgfTtcbiAgICBcbiAgICBjb25zdCBwcm9taXNlID0gc2hvd0RpYWxvZyh0aXRsZSwgbWVzc2FnZSwgdmFsdWVTdHIsIGJ1dHRvbnMsIG9wdGlvbnMpO1xuICAgIGNvbnN0IHtvaywgZGlhbG9nfSA9IHByb21pc2U7XG4gICAgY29uc3QgcmVzb2x2ZSA9IG9rKCk7XG4gICAgXG4gICAgZmluZChkaWFsb2csIFsnY2FuY2VsJ10pLm1hcCgoZWwpID0+IHtcbiAgICAgICAgZWwuZm9jdXMoKTtcbiAgICB9KTtcbiAgICBcbiAgICBPYmplY3QuYXNzaWduKHByb21pc2UsIHtcbiAgICAgICAgc2V0UHJvZ3Jlc3MoY291bnQpIHtcbiAgICAgICAgICAgIGNvbnN0IFtlbFByb2dyZXNzXSA9IGZpbmQoZGlhbG9nLCBbJ3Byb2dyZXNzJ10pO1xuICAgICAgICAgICAgY29uc3QgW2VsQ291bnRlcl0gPSBmaW5kKGRpYWxvZywgWydjb3VudGVyJ10pO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICBlbFByb2dyZXNzLnZhbHVlID0gY291bnQ7XG4gICAgICAgICAgICBlbENvdW50ZXIudGV4dENvbnRlbnQgPSBgJHtjb3VudH0lYDtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgaWYgKGNvdW50ID09PSAxMDApIHtcbiAgICAgICAgICAgICAgICByZW1vdmUoZGlhbG9nKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIFxuICAgICAgICByZW1vdmUoKSB7XG4gICAgICAgICAgICByZW1vdmUoZGlhbG9nKTtcbiAgICAgICAgfSxcbiAgICB9KTtcbiAgICBcbiAgICByZXR1cm4gcHJvbWlzZTtcbn07XG5cbmZ1bmN0aW9uIGdldEJ1dHRvbnMob3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3Qge2J1dHRvbnN9ID0gb3B0aW9ucztcbiAgICBcbiAgICBpZiAoIWJ1dHRvbnMpXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIFxuICAgIHJldHVybiBidXR0b25zO1xufVxuXG5mdW5jdGlvbiBnZXRUeXBlKG9wdGlvbnMgPSB7fSkge1xuICAgIGNvbnN0IHt0eXBlfSA9IG9wdGlvbnM7XG4gICAgXG4gICAgaWYgKHR5cGUgPT09ICdwYXNzd29yZCcpXG4gICAgICAgIHJldHVybiAncGFzc3dvcmQnO1xuICAgIFxuICAgIHJldHVybiAndGV4dCc7XG59XG5cbmZ1bmN0aW9uIGdldFRlbXBsYXRlKHRpdGxlLCBtc2csIHZhbHVlLCBidXR0b25zKSB7XG4gICAgY29uc3QgZW5jb2RlZE1zZyA9IG1zZy5yZXBsYWNlKC9cXG4vZywgJzxicj4nKTtcbiAgICBcbiAgICByZXR1cm4gYDxkaXYgY2xhc3M9XCJwYWdlXCI+XG4gICAgICAgIDxkaXYgZGF0YS1uYW1lPVwianMtY2xvc2VcIiBjbGFzcz1cImNsb3NlLWJ1dHRvblwiPjwvZGl2PlxuICAgICAgICA8aGVhZGVyPiR7IHRpdGxlIH08L2hlYWRlcj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNvbnRlbnQtYXJlYVwiPiR7IGVuY29kZWRNc2cgfSR7IHZhbHVlIH08L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImFjdGlvbi1hcmVhXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnV0dG9uLXN0cmlwXCI+XG4gICAgICAgICAgICAgICAgJHtwYXJzZUJ1dHRvbnMoYnV0dG9ucyl9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+YDtcbn1cblxuZnVuY3Rpb24gcGFyc2VCdXR0b25zKGJ1dHRvbnMpIHtcbiAgICBjb25zdCBuYW1lcyA9IE9iamVjdC5rZXlzKGJ1dHRvbnMpO1xuICAgIGNvbnN0IHBhcnNlID0gY3VycmlmeSgoYnV0dG9ucywgbmFtZSwgaSkgPT4gYDxidXR0b25cbiAgICAgICAgICAgIHRhYmluZGV4PSR7aX1cbiAgICAgICAgICAgIGRhdGEtbmFtZT1cImpzLSR7bmFtZS50b0xvd2VyQ2FzZSgpfVwiPlxuICAgICAgICAgICAgJHtidXR0b25zW25hbWVdfVxuICAgICAgICA8L2J1dHRvbj5gKTtcbiAgICBcbiAgICByZXR1cm4gbmFtZXNcbiAgICAgICAgLm1hcChwYXJzZShidXR0b25zKSlcbiAgICAgICAgLmpvaW4oJycpO1xufVxuXG5mdW5jdGlvbiBzaG93RGlhbG9nKHRpdGxlLCBtc2csIHZhbHVlLCBidXR0b25zLCBvcHRpb25zKSB7XG4gICAgY29uc3Qgb2sgPSBzdG9yZSgpO1xuICAgIGNvbnN0IGNhbmNlbCA9IHN0b3JlKCk7XG4gICAgXG4gICAgY29uc3QgY2xvc2VCdXR0b25zID0gW1xuICAgICAgICAnY2FuY2VsJyxcbiAgICAgICAgJ2Nsb3NlJyxcbiAgICAgICAgJ29rJyxcbiAgICBdO1xuICAgIFxuICAgIGNvbnN0IHByb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIGNvbnN0IG5vQ2FuY2VsID0gb3B0aW9ucyAmJiBvcHRpb25zLmNhbmNlbCA9PT0gZmFsc2U7XG4gICAgICAgIGNvbnN0IGVtcHR5ID0gKCkgPT4ge307XG4gICAgICAgIGNvbnN0IHJlamVjdEVycm9yID0gKCkgPT4gcmVqZWN0KEVycm9yKCkpO1xuICAgICAgICBcbiAgICAgICAgb2socmVzb2x2ZSk7XG4gICAgICAgIGNhbmNlbChub0NhbmNlbCA/IGVtcHR5IDogcmVqZWN0RXJyb3IpO1xuICAgIH0pO1xuICAgIFxuICAgIGNvbnN0IGlubmVySFRNTCA9IGdldFRlbXBsYXRlKHRpdGxlLCBtc2csIHZhbHVlLCBidXR0b25zKTtcbiAgICBcbiAgICBjb25zdCBkaWFsb2cgPSBjcmVhdGVFbGVtZW50KCdkaXYnLCB7XG4gICAgICAgIGlubmVySFRNTCxcbiAgICAgICAgY2xhc3NOYW1lOiAnc21hbGx0YWxrJyxcbiAgICAgICAgc3R5bGU6IGB6LWluZGV4OiAke3pJbmRleCh6SW5kZXgoKSArIDEpfWAsXG4gICAgfSk7XG4gICAgXG4gICAgZm9yIChjb25zdCBlbCBvZiBmaW5kKGRpYWxvZywgWydvaycsICdpbnB1dCddKSlcbiAgICAgICAgZWwuZm9jdXMoKTtcbiAgICBcbiAgICBmb3IgKGNvbnN0IGVsIG9mIGZpbmQoZGlhbG9nLCBbJ2lucHV0J10pKSB7XG4gICAgICAgIGVsLnNldFNlbGVjdGlvblJhbmdlKDAsIHZhbHVlLmxlbmd0aCk7XG4gICAgfVxuICAgIFxuICAgIGFkZExpc3RlbmVyQWxsKCdjbGljaycsIGRpYWxvZywgY2xvc2VCdXR0b25zLCAoZXZlbnQpID0+IHtcbiAgICAgICAgY2xvc2VEaWFsb2coZXZlbnQudGFyZ2V0LCBkaWFsb2csIG9rKCksIGNhbmNlbCgpKTtcbiAgICB9KTtcbiAgICBcbiAgICBmb3IgKGNvbnN0IGV2ZW50IG9mIFsnY2xpY2snLCAnY29udGV4dG1lbnUnXSlcbiAgICAgICAgZGlhbG9nLmFkZEV2ZW50TGlzdGVuZXIoZXZlbnQsIChlKSA9PiB7XG4gICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgZm9yIChjb25zdCBlbCBvZiBmaW5kKGRpYWxvZywgWydvaycsICdpbnB1dCddKSlcbiAgICAgICAgICAgICAgICBlbC5mb2N1cygpO1xuICAgICAgICB9KTtcbiAgICBcbiAgICBkaWFsb2cuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIGtleURvd24oZGlhbG9nLCBvaygpLCBjYW5jZWwoKSkpO1xuICAgIFxuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHByb21pc2UsIHtcbiAgICAgICAgZGlhbG9nLFxuICAgICAgICBvayxcbiAgICB9KTtcbn1cblxuZnVuY3Rpb24ga2V5RG93bl8oZGlhbG9nLCBvaywgY2FuY2VsLCBldmVudCkge1xuICAgIGNvbnN0IEtFWSA9IHtcbiAgICAgICAgRU5URVIgOiAxMyxcbiAgICAgICAgRVNDICAgOiAyNyxcbiAgICAgICAgVEFCICAgOiA5LFxuICAgICAgICBMRUZUICA6IDM3LFxuICAgICAgICBVUCAgICA6IDM4LFxuICAgICAgICBSSUdIVCA6IDM5LFxuICAgICAgICBET1dOICA6IDQwLFxuICAgIH07XG4gICAgXG4gICAgY29uc3Qge2tleUNvZGV9ID0gZXZlbnQ7XG4gICAgY29uc3QgZWwgPSBldmVudC50YXJnZXQ7XG4gICAgXG4gICAgY29uc3QgbmFtZXNBbGwgPSBbJ29rJywgJ2NhbmNlbCcsICdpbnB1dCddO1xuICAgIGNvbnN0IG5hbWVzID0gZmluZChkaWFsb2csIG5hbWVzQWxsKVxuICAgICAgICAubWFwKGdldERhdGFOYW1lKTtcbiAgICBcbiAgICBzd2l0Y2goa2V5Q29kZSkge1xuICAgIGNhc2UgS0VZLkVOVEVSOlxuICAgICAgICBjbG9zZURpYWxvZyhlbCwgZGlhbG9nLCBvaywgY2FuY2VsKTtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgXG4gICAgY2FzZSBLRVkuRVNDOlxuICAgICAgICByZW1vdmUoZGlhbG9nKTtcbiAgICAgICAgY2FuY2VsKCk7XG4gICAgICAgIGJyZWFrO1xuICAgIFxuICAgIGNhc2UgS0VZLlRBQjpcbiAgICAgICAgaWYgKGV2ZW50LnNoaWZ0S2V5KVxuICAgICAgICAgICAgdGFiKGRpYWxvZywgbmFtZXMpO1xuICAgICAgICBcbiAgICAgICAgdGFiKGRpYWxvZywgbmFtZXMpO1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBicmVhaztcbiAgICBcbiAgICBkZWZhdWx0OlxuICAgICAgICBbJ2xlZnQnLCAncmlnaHQnLCAndXAnLCAnZG93biddLmZpbHRlcigobmFtZSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGtleUNvZGUgPT09IEtFWVtuYW1lLnRvVXBwZXJDYXNlKCldO1xuICAgICAgICB9KS5mb3JFYWNoKCgpID0+IHtcbiAgICAgICAgICAgIGNoYW5nZUJ1dHRvbkZvY3VzKGRpYWxvZywgbmFtZXMpO1xuICAgICAgICB9KTtcbiAgICAgICAgXG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbn1cblxuZnVuY3Rpb24gZ2V0RGF0YU5hbWUoZWwpIHtcbiAgICByZXR1cm4gZWxcbiAgICAgICAgLmdldEF0dHJpYnV0ZSgnZGF0YS1uYW1lJylcbiAgICAgICAgLnJlcGxhY2UoJ2pzLScsICcnKTtcbn1cblxuY29uc3QgZ2V0TmFtZSA9IChhY3RpdmVOYW1lKSA9PiB7XG4gICAgaWYgKGFjdGl2ZU5hbWUgPT09ICdjYW5jZWwnKVxuICAgICAgICByZXR1cm4gJ29rJztcbiAgICBcbiAgICByZXR1cm4gJ2NhbmNlbCc7XG59O1xuXG5mdW5jdGlvbiBjaGFuZ2VCdXR0b25Gb2N1cyhkaWFsb2csIG5hbWVzKSB7XG4gICAgY29uc3QgYWN0aXZlID0gZG9jdW1lbnQuYWN0aXZlRWxlbWVudDtcbiAgICBjb25zdCBhY3RpdmVOYW1lID0gZ2V0RGF0YU5hbWUoYWN0aXZlKTtcbiAgICBjb25zdCBpc0J1dHRvbiA9IC9va3xjYW5jZWwvLnRlc3QoYWN0aXZlTmFtZSk7XG4gICAgY29uc3QgY291bnQgPSBuYW1lcy5sZW5ndGggLSAxO1xuICAgIFxuICAgIGlmIChhY3RpdmVOYW1lID09PSAnaW5wdXQnIHx8ICFjb3VudCB8fCAhaXNCdXR0b24pXG4gICAgICAgIHJldHVybjtcbiAgICBcbiAgICBjb25zdCBuYW1lID0gZ2V0TmFtZShhY3RpdmVOYW1lKTtcbiAgICBcbiAgICBmb3IgKGNvbnN0IGVsIG9mIGZpbmQoZGlhbG9nLCBbbmFtZV0pKSB7XG4gICAgICAgIGVsLmZvY3VzKCk7XG4gICAgfVxufVxuXG5jb25zdCBnZXRJbmRleCA9IChjb3VudCwgaW5kZXgpID0+IHtcbiAgICBpZiAoaW5kZXggPT09IGNvdW50KVxuICAgICAgICByZXR1cm4gMDtcbiAgICBcbiAgICByZXR1cm4gaW5kZXggKyAxO1xufTtcblxuZnVuY3Rpb24gdGFiKGRpYWxvZywgbmFtZXMpIHtcbiAgICBjb25zdCBhY3RpdmUgPSBkb2N1bWVudC5hY3RpdmVFbGVtZW50O1xuICAgIGNvbnN0IGFjdGl2ZU5hbWUgPSBnZXREYXRhTmFtZShhY3RpdmUpO1xuICAgIGNvbnN0IGNvdW50ID0gbmFtZXMubGVuZ3RoIC0gMTtcbiAgICBcbiAgICBjb25zdCBhY3RpdmVJbmRleCA9IG5hbWVzLmluZGV4T2YoYWN0aXZlTmFtZSk7XG4gICAgY29uc3QgaW5kZXggPSBnZXRJbmRleChjb3VudCwgYWN0aXZlSW5kZXgpO1xuICAgIFxuICAgIGNvbnN0IG5hbWUgPSBuYW1lc1tpbmRleF07XG4gICAgXG4gICAgZm9yIChjb25zdCBlbCBvZiBmaW5kKGRpYWxvZywgW25hbWVdKSlcbiAgICAgICAgZWwuZm9jdXMoKTtcbn1cblxuZnVuY3Rpb24gY2xvc2VEaWFsb2coZWwsIGRpYWxvZywgb2ssIGNhbmNlbCkge1xuICAgIGNvbnN0IG5hbWUgPSBlbFxuICAgICAgICAuZ2V0QXR0cmlidXRlKCdkYXRhLW5hbWUnKVxuICAgICAgICAucmVwbGFjZSgnanMtJywgJycpO1xuICAgIFxuICAgIGlmICgvY2xvc2V8Y2FuY2VsLy50ZXN0KG5hbWUpKSB7XG4gICAgICAgIGNhbmNlbCgpO1xuICAgICAgICByZW1vdmUoZGlhbG9nKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBcbiAgICBjb25zdCB2YWx1ZSA9IGZpbmQoZGlhbG9nLCBbJ2lucHV0J10pXG4gICAgICAgIC5yZWR1Y2UoKHZhbHVlLCBlbCkgPT4gZWwudmFsdWUsIG51bGwpO1xuICAgIFxuICAgIG9rKHZhbHVlKTtcbiAgICByZW1vdmUoZGlhbG9nKTtcbn1cblxuY29uc3QgcXVlcnkgPSBjdXJyaWZ5KChlbGVtZW50LCBuYW1lKSA9PiBlbGVtZW50LnF1ZXJ5U2VsZWN0b3IoYFtkYXRhLW5hbWU9XCJqcy0keyBuYW1lIH1cIl1gKSk7XG5cbmZ1bmN0aW9uIGZpbmQoZWxlbWVudCwgbmFtZXMpIHtcbiAgICBjb25zdCBlbGVtZW50cyA9IG5hbWVzXG4gICAgICAgIC5tYXAocXVlcnkoZWxlbWVudCkpXG4gICAgICAgIC5maWx0ZXIoQm9vbGVhbik7XG4gICAgXG4gICAgcmV0dXJuIGVsZW1lbnRzO1xufVxuXG5mdW5jdGlvbiBhZGRMaXN0ZW5lckFsbChldmVudCwgcGFyZW50LCBlbGVtZW50cywgZm4pIHtcbiAgICBmb3IgKGNvbnN0IGVsIG9mIGZpbmQocGFyZW50LCBlbGVtZW50cykpIHtcbiAgICAgICAgZWwuYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgZm4pO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gcmVtb3ZlKGRpYWxvZykge1xuICAgIGNvbnN0IHtwYXJlbnRFbGVtZW50fSA9IGRpYWxvZztcbiAgICBcbiAgICBpZiAocGFyZW50RWxlbWVudClcbiAgICAgICAgcGFyZW50RWxlbWVudC5yZW1vdmVDaGlsZChkaWFsb2cpO1xufVxuXG4iLCJpbXBvcnQgeyBwcm9ncmVzcyB9IGZyb20gXCJzbWFsbHRhbGtcIjtcblxuZXhwb3J0IGNsYXNzIFByb2dyZXNzIHtcblxuICAgIGNvbnN0cnVjdG9yKHRpdGxlLCBtZXNzYWdlKSB7XG4gICAgICAgIHRoaXMucHJvZ3Jlc3MgPSBwcm9ncmVzcyh0aXRsZSwgbWVzc2FnZSk7XG4gICAgICAgIHRoaXMucHJvZ3Jlc3MuY2F0Y2goZSA9PiB7XG4gICAgICAgICAgICB0aGlzLmFib3J0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgaWYgKGUgJiYgKGUuY29uc3RydWN0b3IgIT09IEVycm9yIHx8IGUubWVzc2FnZSAhPT0gXCJcIikpIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRpYWxvZyA9IHRoaXMucHJvZ3Jlc3MuZGlhbG9nO1xuICAgICAgICB0aGlzLmFib3J0ZWQgPSBmYWxzZTtcbiAgICB9XG5cbiAgICBhc3luYyBmb3JFYWNoKGNvbGxlY3Rpb24sIGZ1bmMpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmFib3J0ZWQpXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgbGV0IHByb2Nlc3NlZCA9IDAsIHJhbmdlID0gY29sbGVjdGlvbi5sZW5ndGgsIGFjY3VtID0gMCwgcGN0ID0gMDtcbiAgICAgICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBjb2xsZWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgZnVuYyhpdGVtLCBwcm9jZXNzZWQrKywgY29sbGVjdGlvbiwgdGhpcyk7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuYWJvcnRlZClcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIGFjY3VtICs9IDEwMDtcbiAgICAgICAgICAgICAgICBpZiAoYWNjdW0gPiByYW5nZSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByZW1haW5kZXIgPSBhY2N1bSAlIHJhbmdlLCBzdGVwID0gKGFjY3VtIC0gcmVtYWluZGVyKSAvIHJhbmdlO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnByb2dyZXNzLnNldFByb2dyZXNzKHBjdCArPSBzdGVwKTtcbiAgICAgICAgICAgICAgICAgICAgYWNjdW0gPSByZW1haW5kZXI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHBjdCA8IDEwMClcbiAgICAgICAgICAgICAgICB0aGlzLnByb2dyZXNzLnNldFByb2dyZXNzKDEwMCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIHRoaXMucHJvZ3Jlc3MucmVtb3ZlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZXQgdGl0bGUodGV4dCkgeyB0aGlzLmRpYWxvZy5xdWVyeVNlbGVjdG9yKFwiaGVhZGVyXCIpLnRleHRDb250ZW50ID0gdGV4dDsgfVxuICAgIGdldCB0aXRsZSgpIHsgcmV0dXJuIHRoaXMuZGlhbG9nLnF1ZXJ5U2VsZWN0b3IoXCJoZWFkZXJcIikudGV4dENvbnRlbnQ7IH1cblxuICAgIHNldCBtZXNzYWdlKHRleHQpIHtcbiAgICAgICAgY29uc3QgYXJlYSA9IHRoaXMuZGlhbG9nLnF1ZXJ5U2VsZWN0b3IoXCIuY29udGVudC1hcmVhXCIpLmNoaWxkTm9kZXNbMF0udGV4dENvbnRlbnQgPSB0ZXh0O1xuICAgIH1cblxuICAgIGdldCBtZXNzYWdlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5kaWFsb2cucXVlcnlTZWxlY3RvcihcIi5jb250ZW50LWFyZWFcIikuY2hpbGROb2Rlc1swXS50ZXh0Q29udGVudDtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBOb3RpY2UgfSBmcm9tIFwib2JzaWRpYW5cIjtcbmltcG9ydCB7IHByb21wdCB9IGZyb20gXCJzbWFsbHRhbGtcIjtcblxuaW1wb3J0IFwiLi92YWxpZGF0aW9uLnNjc3NcIjtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHZhbGlkYXRlZElucHV0KHRpdGxlLCBtZXNzYWdlLCB2YWx1ZSA9IFwiXCIsIHJlZ2V4ID0gXCIuKlwiLCB3aGF0ID0gXCJlbnRyeVwiKSB7XG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgICAgY29uc3QgaW5wdXQgPSBwcm9tcHQodGl0bGUsIG1lc3NhZ2UsIHZhbHVlKTtcbiAgICAgICAgY29uc3QgaW5wdXRGaWVsZCA9IGlucHV0LmRpYWxvZy5maW5kKFwiaW5wdXRcIik7XG4gICAgICAgIGNvbnN0IGlzVmFsaWQgPSAodCkgPT4gbmV3IFJlZ0V4cChgXiR7cmVnZXh9JGApLnRlc3QodCk7XG5cbiAgICAgICAgaW5wdXRGaWVsZC5zZXRTZWxlY3Rpb25SYW5nZSh2YWx1ZS5sZW5ndGgsIHZhbHVlLmxlbmd0aCk7XG4gICAgICAgIGlucHV0RmllbGQucGF0dGVybiA9IHJlZ2V4O1xuICAgICAgICBpbnB1dEZpZWxkLm9uaW5wdXQgPSAoKSA9PiBpbnB1dEZpZWxkLnNldEF0dHJpYnV0ZShcImFyaWEtaW52YWxpZFwiLCAhaXNWYWxpZChpbnB1dEZpZWxkLnZhbHVlKSk7XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgaW5wdXQ7XG4gICAgICAgIGlmIChpc1ZhbGlkKHJlc3VsdCkpIHJldHVybiByZXN1bHQ7XG5cbiAgICAgICAgbmV3IE5vdGljZShgXCIke3Jlc3VsdH1cIiBpcyBub3QgYSB2YWxpZCAke3doYXR9YCk7XG4gICAgfVxufVxuIiwiZXhwb3J0IGNsYXNzIFRhZyB7XG4gICAgY29uc3RydWN0b3IobmFtZSkge1xuICAgICAgICB3aGlsZSAobmFtZS5zdGFydHNXaXRoKFwiI1wiKSkgbmFtZSA9IG5hbWUuc2xpY2UoMSk7XG4gICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgICAgIGNvbnN0XG4gICAgICAgICAgICBoYXNoZWQgPSB0aGlzLnRhZyA9IFwiI1wiICsgbmFtZSxcbiAgICAgICAgICAgIGNhbm9uaWNhbCA9IHRoaXMuY2Fub25pY2FsID0gaGFzaGVkLnRvTG93ZXJDYXNlKCksXG4gICAgICAgICAgICBjYW5vbmljYWxfcHJlZml4ID0gdGhpcy5jYW5vbmljYWxfcHJlZml4ID0gY2Fub25pY2FsICsgXCIvXCI7XG4gICAgICAgIHRoaXMubWF0Y2hlcyA9IGZ1bmN0aW9uICh0ZXh0KSB7XG4gICAgICAgICAgICB0ZXh0ID0gdGV4dC50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgICAgcmV0dXJuIHRleHQgPT0gY2Fub25pY2FsIHx8IHRleHQuc3RhcnRzV2l0aChjYW5vbmljYWxfcHJlZml4KTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgdG9TdHJpbmcoKSB7IHJldHVybiB0aGlzLnRhZzsgfVxufVxuXG5leHBvcnQgY2xhc3MgUmVwbGFjZW1lbnQge1xuXG4gICAgY29uc3RydWN0b3IoZnJvbVRhZywgdG9UYWcpIHtcbiAgICAgICAgY29uc3QgY2FjaGUgPSAgT2JqZWN0LmFzc2lnbihcbiAgICAgICAgICAgIE9iamVjdC5jcmVhdGUobnVsbCksIHtcbiAgICAgICAgICAgICAgICBbZnJvbVRhZy50YWddOiAgdG9UYWcudGFnLFxuICAgICAgICAgICAgICAgIFtmcm9tVGFnLm5hbWVdOiB0b1RhZy5uYW1lLFxuICAgICAgICAgICAgfVxuICAgICAgICApO1xuXG4gICAgICAgIHRoaXMuaW5TdHJpbmcgPSBmdW5jdGlvbih0ZXh0LCBwb3MgPSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gdGV4dC5zbGljZSgwLCBwb3MpICsgdG9UYWcudGFnICsgdGV4dC5zbGljZShwb3MgKyBmcm9tVGFnLnRhZy5sZW5ndGgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5pbkFycmF5ID0gKHRhZ3MsIHNraXBPZGQpID0+IHtcbiAgICAgICAgICAgIHJldHVybiB0YWdzLm1hcCgodCwgaSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChza2lwT2RkICYmIChpICYgMSkpIHJldHVybiB0OyAgIC8vIGxlYXZlIG9kZCBlbnRyaWVzIChzZXBhcmF0b3JzKSBhbG9uZVxuICAgICAgICAgICAgICAgIC8vIE9ic2lkaWFuIGFsbG93cyBzcGFjZXMgYXMgc2VwYXJhdG9ycyB3aXRoaW4gYXJyYXkgZWxlbWVudHNcbiAgICAgICAgICAgICAgICBpZiAodC5jb250YWlucyhcIiBcIikpIHJldHVybiB0aGlzLmluQXJyYXkodC5zcGxpdCgvKCArKS8pLCB0cnVlKS5qb2luKFwiXCIpO1xuICAgICAgICAgICAgICAgIGlmICghdCkgcmV0dXJuIHQ7XG4gICAgICAgICAgICAgICAgaWYgKGNhY2hlW3RdKSByZXR1cm4gY2FjaGVbdF07XG4gICAgICAgICAgICAgICAgY29uc3QgbGMgPSB0LnRvTG93ZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgaWYgKGNhY2hlW2xjXSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gY2FjaGVbdF0gPSBjYWNoZVtsY107XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChsYy5zdGFydHNXaXRoKGZyb21UYWcuY2Fub25pY2FsX3ByZWZpeCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNhY2hlW3RdID0gY2FjaGVbbGNdID0gdGhpcy5pblN0cmluZyh0KTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKChcIiNcIiArIGxjKS5zdGFydHNXaXRoKGZyb21UYWcuY2Fub25pY2FsX3ByZWZpeCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNhY2hlW3RdID0gY2FjaGVbbGNdID0gdGhpcy5pblN0cmluZyhcIiNcIiArIHQpLnNsaWNlKDEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gY2FjaGVbdF0gPSBjYWNoZVtsY10gPSB0O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy53aWxsTWVyZ2VUYWdzID0gZnVuY3Rpb24gKHRhZ05hbWVzKSB7XG4gICAgICAgICAgICAvLyBSZW5hbWluZyB0byBjaGFuZ2UgY2FzZSBkb2Vzbid0IGxvc2UgaW5mbywgc28gaWdub3JlIGl0XG4gICAgICAgICAgICBpZiAoZnJvbVRhZy5jYW5vbmljYWwgPT09IHRvVGFnLmNhbm9uaWNhbCkgcmV0dXJuO1xuXG4gICAgICAgICAgICBjb25zdCBleGlzdGluZyA9IG5ldyBTZXQodGFnTmFtZXMubWFwKHMgPT4gcy50b0xvd2VyQ2FzZSgpKSk7XG5cbiAgICAgICAgICAgIGZvciAoY29uc3QgdGFnTmFtZSBvZiB0YWdOYW1lcy5maWx0ZXIoZnJvbVRhZy5tYXRjaGVzKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNoYW5nZWQgPSB0aGlzLmluU3RyaW5nKHRhZ05hbWUpO1xuICAgICAgICAgICAgICAgIGlmIChleGlzdGluZy5oYXMoY2hhbmdlZC50b0xvd2VyQ2FzZSgpKSlcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFtuZXcgVGFnKHRhZ05hbWUpLCBuZXcgVGFnKGNoYW5nZWQpXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICB9XG4gICAgfVxufVxuXG5cbiIsImNvbnN0IENoYXIgPSB7XG4gIEFOQ0hPUjogJyYnLFxuICBDT01NRU5UOiAnIycsXG4gIFRBRzogJyEnLFxuICBESVJFQ1RJVkVTX0VORDogJy0nLFxuICBET0NVTUVOVF9FTkQ6ICcuJ1xufTtcbmNvbnN0IExvZ0xldmVsID0gT2JqZWN0LmFzc2lnbihbJ3NpbGVudCcsICdlcnJvcicsICd3YXJuJywgJ2RlYnVnJ10sIHtcbiAgU0lMRU5UOiAwLFxuICBFUlJPUjogMSxcbiAgV0FSTjogMixcbiAgREVCVUc6IDNcbn0pO1xuY29uc3QgVHlwZSA9IHtcbiAgQUxJQVM6ICdBTElBUycsXG4gIEJMQU5LX0xJTkU6ICdCTEFOS19MSU5FJyxcbiAgQkxPQ0tfRk9MREVEOiAnQkxPQ0tfRk9MREVEJyxcbiAgQkxPQ0tfTElURVJBTDogJ0JMT0NLX0xJVEVSQUwnLFxuICBDT01NRU5UOiAnQ09NTUVOVCcsXG4gIERJUkVDVElWRTogJ0RJUkVDVElWRScsXG4gIERPQ1VNRU5UOiAnRE9DVU1FTlQnLFxuICBGTE9XX01BUDogJ0ZMT1dfTUFQJyxcbiAgRkxPV19TRVE6ICdGTE9XX1NFUScsXG4gIE1BUDogJ01BUCcsXG4gIE1BUF9LRVk6ICdNQVBfS0VZJyxcbiAgTUFQX1ZBTFVFOiAnTUFQX1ZBTFVFJyxcbiAgUExBSU46ICdQTEFJTicsXG4gIFFVT1RFX0RPVUJMRTogJ1FVT1RFX0RPVUJMRScsXG4gIFFVT1RFX1NJTkdMRTogJ1FVT1RFX1NJTkdMRScsXG4gIFNFUTogJ1NFUScsXG4gIFNFUV9JVEVNOiAnU0VRX0lURU0nXG59O1xuY29uc3QgZGVmYXVsdFRhZ1ByZWZpeCA9ICd0YWc6eWFtbC5vcmcsMjAwMjonO1xuY29uc3QgZGVmYXVsdFRhZ3MgPSB7XG4gIE1BUDogJ3RhZzp5YW1sLm9yZywyMDAyOm1hcCcsXG4gIFNFUTogJ3RhZzp5YW1sLm9yZywyMDAyOnNlcScsXG4gIFNUUjogJ3RhZzp5YW1sLm9yZywyMDAyOnN0cidcbn07XG5cbmV4cG9ydCB7IENoYXIsIExvZ0xldmVsLCBUeXBlLCBkZWZhdWx0VGFnUHJlZml4LCBkZWZhdWx0VGFncyB9O1xuIiwiZnVuY3Rpb24gZmluZExpbmVTdGFydHMoc3JjKSB7XG4gIGNvbnN0IGxzID0gWzBdO1xuICBsZXQgb2Zmc2V0ID0gc3JjLmluZGV4T2YoJ1xcbicpO1xuXG4gIHdoaWxlIChvZmZzZXQgIT09IC0xKSB7XG4gICAgb2Zmc2V0ICs9IDE7XG4gICAgbHMucHVzaChvZmZzZXQpO1xuICAgIG9mZnNldCA9IHNyYy5pbmRleE9mKCdcXG4nLCBvZmZzZXQpO1xuICB9XG5cbiAgcmV0dXJuIGxzO1xufVxuXG5mdW5jdGlvbiBnZXRTcmNJbmZvKGNzdCkge1xuICBsZXQgbGluZVN0YXJ0cywgc3JjO1xuXG4gIGlmICh0eXBlb2YgY3N0ID09PSAnc3RyaW5nJykge1xuICAgIGxpbmVTdGFydHMgPSBmaW5kTGluZVN0YXJ0cyhjc3QpO1xuICAgIHNyYyA9IGNzdDtcbiAgfSBlbHNlIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShjc3QpKSBjc3QgPSBjc3RbMF07XG5cbiAgICBpZiAoY3N0ICYmIGNzdC5jb250ZXh0KSB7XG4gICAgICBpZiAoIWNzdC5saW5lU3RhcnRzKSBjc3QubGluZVN0YXJ0cyA9IGZpbmRMaW5lU3RhcnRzKGNzdC5jb250ZXh0LnNyYyk7XG4gICAgICBsaW5lU3RhcnRzID0gY3N0LmxpbmVTdGFydHM7XG4gICAgICBzcmMgPSBjc3QuY29udGV4dC5zcmM7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBsaW5lU3RhcnRzLFxuICAgIHNyY1xuICB9O1xufVxuLyoqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBMaW5lUG9zIC0gT25lLWluZGV4ZWQgcG9zaXRpb24gaW4gdGhlIHNvdXJjZVxuICogQHByb3BlcnR5IHtudW1iZXJ9IGxpbmVcbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBjb2xcbiAqL1xuXG4vKipcbiAqIERldGVybWluZSB0aGUgbGluZS9jb2wgcG9zaXRpb24gbWF0Y2hpbmcgYSBjaGFyYWN0ZXIgb2Zmc2V0LlxuICpcbiAqIEFjY2VwdHMgYSBzb3VyY2Ugc3RyaW5nIG9yIGEgQ1NUIGRvY3VtZW50IGFzIHRoZSBzZWNvbmQgcGFyYW1ldGVyLiBXaXRoXG4gKiB0aGUgbGF0dGVyLCBzdGFydGluZyBpbmRpY2VzIGZvciBsaW5lcyBhcmUgY2FjaGVkIGluIHRoZSBkb2N1bWVudCBhc1xuICogYGxpbmVTdGFydHM6IG51bWJlcltdYC5cbiAqXG4gKiBSZXR1cm5zIGEgb25lLWluZGV4ZWQgYHsgbGluZSwgY29sIH1gIGxvY2F0aW9uIGlmIGZvdW5kLCBvclxuICogYHVuZGVmaW5lZGAgb3RoZXJ3aXNlLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXRcbiAqIEBwYXJhbSB7c3RyaW5nfERvY3VtZW50fERvY3VtZW50W119IGNzdFxuICogQHJldHVybnMgez9MaW5lUG9zfVxuICovXG5cblxuZnVuY3Rpb24gZ2V0TGluZVBvcyhvZmZzZXQsIGNzdCkge1xuICBpZiAodHlwZW9mIG9mZnNldCAhPT0gJ251bWJlcicgfHwgb2Zmc2V0IDwgMCkgcmV0dXJuIG51bGw7XG4gIGNvbnN0IHtcbiAgICBsaW5lU3RhcnRzLFxuICAgIHNyY1xuICB9ID0gZ2V0U3JjSW5mbyhjc3QpO1xuICBpZiAoIWxpbmVTdGFydHMgfHwgIXNyYyB8fCBvZmZzZXQgPiBzcmMubGVuZ3RoKSByZXR1cm4gbnVsbDtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGxpbmVTdGFydHMubGVuZ3RoOyArK2kpIHtcbiAgICBjb25zdCBzdGFydCA9IGxpbmVTdGFydHNbaV07XG5cbiAgICBpZiAob2Zmc2V0IDwgc3RhcnQpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGxpbmU6IGksXG4gICAgICAgIGNvbDogb2Zmc2V0IC0gbGluZVN0YXJ0c1tpIC0gMV0gKyAxXG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmIChvZmZzZXQgPT09IHN0YXJ0KSByZXR1cm4ge1xuICAgICAgbGluZTogaSArIDEsXG4gICAgICBjb2w6IDFcbiAgICB9O1xuICB9XG5cbiAgY29uc3QgbGluZSA9IGxpbmVTdGFydHMubGVuZ3RoO1xuICByZXR1cm4ge1xuICAgIGxpbmUsXG4gICAgY29sOiBvZmZzZXQgLSBsaW5lU3RhcnRzW2xpbmUgLSAxXSArIDFcbiAgfTtcbn1cbi8qKlxuICogR2V0IGEgc3BlY2lmaWVkIGxpbmUgZnJvbSB0aGUgc291cmNlLlxuICpcbiAqIEFjY2VwdHMgYSBzb3VyY2Ugc3RyaW5nIG9yIGEgQ1NUIGRvY3VtZW50IGFzIHRoZSBzZWNvbmQgcGFyYW1ldGVyLiBXaXRoXG4gKiB0aGUgbGF0dGVyLCBzdGFydGluZyBpbmRpY2VzIGZvciBsaW5lcyBhcmUgY2FjaGVkIGluIHRoZSBkb2N1bWVudCBhc1xuICogYGxpbmVTdGFydHM6IG51bWJlcltdYC5cbiAqXG4gKiBSZXR1cm5zIHRoZSBsaW5lIGFzIGEgc3RyaW5nIGlmIGZvdW5kLCBvciBgbnVsbGAgb3RoZXJ3aXNlLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBsaW5lIE9uZS1pbmRleGVkIGxpbmUgbnVtYmVyXG4gKiBAcGFyYW0ge3N0cmluZ3xEb2N1bWVudHxEb2N1bWVudFtdfSBjc3RcbiAqIEByZXR1cm5zIHs/c3RyaW5nfVxuICovXG5cbmZ1bmN0aW9uIGdldExpbmUobGluZSwgY3N0KSB7XG4gIGNvbnN0IHtcbiAgICBsaW5lU3RhcnRzLFxuICAgIHNyY1xuICB9ID0gZ2V0U3JjSW5mbyhjc3QpO1xuICBpZiAoIWxpbmVTdGFydHMgfHwgIShsaW5lID49IDEpIHx8IGxpbmUgPiBsaW5lU3RhcnRzLmxlbmd0aCkgcmV0dXJuIG51bGw7XG4gIGNvbnN0IHN0YXJ0ID0gbGluZVN0YXJ0c1tsaW5lIC0gMV07XG4gIGxldCBlbmQgPSBsaW5lU3RhcnRzW2xpbmVdOyAvLyB1bmRlZmluZWQgZm9yIGxhc3QgbGluZTsgdGhhdCdzIG9rIGZvciBzbGljZSgpXG5cbiAgd2hpbGUgKGVuZCAmJiBlbmQgPiBzdGFydCAmJiBzcmNbZW5kIC0gMV0gPT09ICdcXG4nKSAtLWVuZDtcblxuICByZXR1cm4gc3JjLnNsaWNlKHN0YXJ0LCBlbmQpO1xufVxuLyoqXG4gKiBQcmV0dHktcHJpbnQgdGhlIHN0YXJ0aW5nIGxpbmUgZnJvbSB0aGUgc291cmNlIGluZGljYXRlZCBieSB0aGUgcmFuZ2UgYHBvc2BcbiAqXG4gKiBUcmltcyBvdXRwdXQgdG8gYG1heFdpZHRoYCBjaGFycyB3aGlsZSBrZWVwaW5nIHRoZSBzdGFydGluZyBjb2x1bW4gdmlzaWJsZSxcbiAqIHVzaW5nIGDigKZgIGF0IGVpdGhlciBlbmQgdG8gaW5kaWNhdGUgZHJvcHBlZCBjaGFyYWN0ZXJzLlxuICpcbiAqIFJldHVybnMgYSB0d28tbGluZSBzdHJpbmcgKG9yIGBudWxsYCkgd2l0aCBgXFxuYCBhcyBzZXBhcmF0b3I7IHRoZSBzZWNvbmQgbGluZVxuICogd2lsbCBob2xkIGFwcHJvcHJpYXRlbHkgaW5kZW50ZWQgYF5gIG1hcmtzIGluZGljYXRpbmcgdGhlIGNvbHVtbiByYW5nZS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gcG9zXG4gKiBAcGFyYW0ge0xpbmVQb3N9IHBvcy5zdGFydFxuICogQHBhcmFtIHtMaW5lUG9zfSBbcG9zLmVuZF1cbiAqIEBwYXJhbSB7c3RyaW5nfERvY3VtZW50fERvY3VtZW50W10qfSBjc3RcbiAqIEBwYXJhbSB7bnVtYmVyfSBbbWF4V2lkdGg9ODBdXG4gKiBAcmV0dXJucyB7P3N0cmluZ31cbiAqL1xuXG5mdW5jdGlvbiBnZXRQcmV0dHlDb250ZXh0KHtcbiAgc3RhcnQsXG4gIGVuZFxufSwgY3N0LCBtYXhXaWR0aCA9IDgwKSB7XG4gIGxldCBzcmMgPSBnZXRMaW5lKHN0YXJ0LmxpbmUsIGNzdCk7XG4gIGlmICghc3JjKSByZXR1cm4gbnVsbDtcbiAgbGV0IHtcbiAgICBjb2xcbiAgfSA9IHN0YXJ0O1xuXG4gIGlmIChzcmMubGVuZ3RoID4gbWF4V2lkdGgpIHtcbiAgICBpZiAoY29sIDw9IG1heFdpZHRoIC0gMTApIHtcbiAgICAgIHNyYyA9IHNyYy5zdWJzdHIoMCwgbWF4V2lkdGggLSAxKSArICfigKYnO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBoYWxmV2lkdGggPSBNYXRoLnJvdW5kKG1heFdpZHRoIC8gMik7XG4gICAgICBpZiAoc3JjLmxlbmd0aCA+IGNvbCArIGhhbGZXaWR0aCkgc3JjID0gc3JjLnN1YnN0cigwLCBjb2wgKyBoYWxmV2lkdGggLSAxKSArICfigKYnO1xuICAgICAgY29sIC09IHNyYy5sZW5ndGggLSBtYXhXaWR0aDtcbiAgICAgIHNyYyA9ICfigKYnICsgc3JjLnN1YnN0cigxIC0gbWF4V2lkdGgpO1xuICAgIH1cbiAgfVxuXG4gIGxldCBlcnJMZW4gPSAxO1xuICBsZXQgZXJyRW5kID0gJyc7XG5cbiAgaWYgKGVuZCkge1xuICAgIGlmIChlbmQubGluZSA9PT0gc3RhcnQubGluZSAmJiBjb2wgKyAoZW5kLmNvbCAtIHN0YXJ0LmNvbCkgPD0gbWF4V2lkdGggKyAxKSB7XG4gICAgICBlcnJMZW4gPSBlbmQuY29sIC0gc3RhcnQuY29sO1xuICAgIH0gZWxzZSB7XG4gICAgICBlcnJMZW4gPSBNYXRoLm1pbihzcmMubGVuZ3RoICsgMSwgbWF4V2lkdGgpIC0gY29sO1xuICAgICAgZXJyRW5kID0gJ+KApic7XG4gICAgfVxuICB9XG5cbiAgY29uc3Qgb2Zmc2V0ID0gY29sID4gMSA/ICcgJy5yZXBlYXQoY29sIC0gMSkgOiAnJztcbiAgY29uc3QgZXJyID0gJ14nLnJlcGVhdChlcnJMZW4pO1xuICByZXR1cm4gXCJcIi5jb25jYXQoc3JjLCBcIlxcblwiKS5jb25jYXQob2Zmc2V0KS5jb25jYXQoZXJyKS5jb25jYXQoZXJyRW5kKTtcbn1cblxuZXhwb3J0IHsgZ2V0TGluZSwgZ2V0TGluZVBvcywgZ2V0UHJldHR5Q29udGV4dCB9O1xuIiwiY2xhc3MgUmFuZ2Uge1xuICBzdGF0aWMgY29weShvcmlnKSB7XG4gICAgcmV0dXJuIG5ldyBSYW5nZShvcmlnLnN0YXJ0LCBvcmlnLmVuZCk7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihzdGFydCwgZW5kKSB7XG4gICAgdGhpcy5zdGFydCA9IHN0YXJ0O1xuICAgIHRoaXMuZW5kID0gZW5kIHx8IHN0YXJ0O1xuICB9XG5cbiAgaXNFbXB0eSgpIHtcbiAgICByZXR1cm4gdHlwZW9mIHRoaXMuc3RhcnQgIT09ICdudW1iZXInIHx8ICF0aGlzLmVuZCB8fCB0aGlzLmVuZCA8PSB0aGlzLnN0YXJ0O1xuICB9XG4gIC8qKlxuICAgKiBTZXQgYG9yaWdTdGFydGAgYW5kIGBvcmlnRW5kYCB0byBwb2ludCB0byB0aGUgb3JpZ2luYWwgc291cmNlIHJhbmdlIGZvclxuICAgKiB0aGlzIG5vZGUsIHdoaWNoIG1heSBkaWZmZXIgZHVlIHRvIGRyb3BwZWQgQ1IgY2hhcmFjdGVycy5cbiAgICpcbiAgICogQHBhcmFtIHtudW1iZXJbXX0gY3IgLSBQb3NpdGlvbnMgb2YgZHJvcHBlZCBDUiBjaGFyYWN0ZXJzXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgLSBTdGFydGluZyBpbmRleCBvZiBgY3JgIGZyb20gdGhlIGxhc3QgY2FsbFxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSAtIFRoZSBuZXh0IG9mZnNldCwgbWF0Y2hpbmcgdGhlIG9uZSBmb3VuZCBmb3IgYG9yaWdTdGFydGBcbiAgICovXG5cblxuICBzZXRPcmlnUmFuZ2UoY3IsIG9mZnNldCkge1xuICAgIGNvbnN0IHtcbiAgICAgIHN0YXJ0LFxuICAgICAgZW5kXG4gICAgfSA9IHRoaXM7XG5cbiAgICBpZiAoY3IubGVuZ3RoID09PSAwIHx8IGVuZCA8PSBjclswXSkge1xuICAgICAgdGhpcy5vcmlnU3RhcnQgPSBzdGFydDtcbiAgICAgIHRoaXMub3JpZ0VuZCA9IGVuZDtcbiAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgfVxuXG4gICAgbGV0IGkgPSBvZmZzZXQ7XG5cbiAgICB3aGlsZSAoaSA8IGNyLmxlbmd0aCkge1xuICAgICAgaWYgKGNyW2ldID4gc3RhcnQpIGJyZWFrO2Vsc2UgKytpO1xuICAgIH1cblxuICAgIHRoaXMub3JpZ1N0YXJ0ID0gc3RhcnQgKyBpO1xuICAgIGNvbnN0IG5leHRPZmZzZXQgPSBpO1xuXG4gICAgd2hpbGUgKGkgPCBjci5sZW5ndGgpIHtcbiAgICAgIC8vIGlmIGVuZCB3YXMgYXQgXFxuLCBpdCBzaG91bGQgbm93IGJlIGF0IFxcclxuICAgICAgaWYgKGNyW2ldID49IGVuZCkgYnJlYWs7ZWxzZSArK2k7XG4gICAgfVxuXG4gICAgdGhpcy5vcmlnRW5kID0gZW5kICsgaTtcbiAgICByZXR1cm4gbmV4dE9mZnNldDtcbiAgfVxuXG59XG5cbmV4cG9ydCB7IFJhbmdlIH07XG4iLCJpbXBvcnQgeyBDaGFyLCBUeXBlIH0gZnJvbSAnLi4vY29uc3RhbnRzLmpzJztcbmltcG9ydCB7IGdldExpbmVQb3MgfSBmcm9tICcuL3NvdXJjZS11dGlscy5qcyc7XG5pbXBvcnQgeyBSYW5nZSB9IGZyb20gJy4vUmFuZ2UuanMnO1xuXG4vKiogUm9vdCBjbGFzcyBvZiBhbGwgbm9kZXMgKi9cblxuY2xhc3MgTm9kZSB7XG4gIHN0YXRpYyBhZGRTdHJpbmdUZXJtaW5hdG9yKHNyYywgb2Zmc2V0LCBzdHIpIHtcbiAgICBpZiAoc3RyW3N0ci5sZW5ndGggLSAxXSA9PT0gJ1xcbicpIHJldHVybiBzdHI7XG4gICAgY29uc3QgbmV4dCA9IE5vZGUuZW5kT2ZXaGl0ZVNwYWNlKHNyYywgb2Zmc2V0KTtcbiAgICByZXR1cm4gbmV4dCA+PSBzcmMubGVuZ3RoIHx8IHNyY1tuZXh0XSA9PT0gJ1xcbicgPyBzdHIgKyAnXFxuJyA6IHN0cjtcbiAgfSAvLyBeKC0tLXwuLi4pXG5cblxuICBzdGF0aWMgYXREb2N1bWVudEJvdW5kYXJ5KHNyYywgb2Zmc2V0LCBzZXApIHtcbiAgICBjb25zdCBjaDAgPSBzcmNbb2Zmc2V0XTtcbiAgICBpZiAoIWNoMCkgcmV0dXJuIHRydWU7XG4gICAgY29uc3QgcHJldiA9IHNyY1tvZmZzZXQgLSAxXTtcbiAgICBpZiAocHJldiAmJiBwcmV2ICE9PSAnXFxuJykgcmV0dXJuIGZhbHNlO1xuXG4gICAgaWYgKHNlcCkge1xuICAgICAgaWYgKGNoMCAhPT0gc2VwKSByZXR1cm4gZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChjaDAgIT09IENoYXIuRElSRUNUSVZFU19FTkQgJiYgY2gwICE9PSBDaGFyLkRPQ1VNRU5UX0VORCkgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IGNoMSA9IHNyY1tvZmZzZXQgKyAxXTtcbiAgICBjb25zdCBjaDIgPSBzcmNbb2Zmc2V0ICsgMl07XG4gICAgaWYgKGNoMSAhPT0gY2gwIHx8IGNoMiAhPT0gY2gwKSByZXR1cm4gZmFsc2U7XG4gICAgY29uc3QgY2gzID0gc3JjW29mZnNldCArIDNdO1xuICAgIHJldHVybiAhY2gzIHx8IGNoMyA9PT0gJ1xcbicgfHwgY2gzID09PSAnXFx0JyB8fCBjaDMgPT09ICcgJztcbiAgfVxuXG4gIHN0YXRpYyBlbmRPZklkZW50aWZpZXIoc3JjLCBvZmZzZXQpIHtcbiAgICBsZXQgY2ggPSBzcmNbb2Zmc2V0XTtcbiAgICBjb25zdCBpc1ZlcmJhdGltID0gY2ggPT09ICc8JztcbiAgICBjb25zdCBub3RPayA9IGlzVmVyYmF0aW0gPyBbJ1xcbicsICdcXHQnLCAnICcsICc+J10gOiBbJ1xcbicsICdcXHQnLCAnICcsICdbJywgJ10nLCAneycsICd9JywgJywnXTtcblxuICAgIHdoaWxlIChjaCAmJiBub3RPay5pbmRleE9mKGNoKSA9PT0gLTEpIGNoID0gc3JjW29mZnNldCArPSAxXTtcblxuICAgIGlmIChpc1ZlcmJhdGltICYmIGNoID09PSAnPicpIG9mZnNldCArPSAxO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICBzdGF0aWMgZW5kT2ZJbmRlbnQoc3JjLCBvZmZzZXQpIHtcbiAgICBsZXQgY2ggPSBzcmNbb2Zmc2V0XTtcblxuICAgIHdoaWxlIChjaCA9PT0gJyAnKSBjaCA9IHNyY1tvZmZzZXQgKz0gMV07XG5cbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG5cbiAgc3RhdGljIGVuZE9mTGluZShzcmMsIG9mZnNldCkge1xuICAgIGxldCBjaCA9IHNyY1tvZmZzZXRdO1xuXG4gICAgd2hpbGUgKGNoICYmIGNoICE9PSAnXFxuJykgY2ggPSBzcmNbb2Zmc2V0ICs9IDFdO1xuXG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIHN0YXRpYyBlbmRPZldoaXRlU3BhY2Uoc3JjLCBvZmZzZXQpIHtcbiAgICBsZXQgY2ggPSBzcmNbb2Zmc2V0XTtcblxuICAgIHdoaWxlIChjaCA9PT0gJ1xcdCcgfHwgY2ggPT09ICcgJykgY2ggPSBzcmNbb2Zmc2V0ICs9IDFdO1xuXG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIHN0YXRpYyBzdGFydE9mTGluZShzcmMsIG9mZnNldCkge1xuICAgIGxldCBjaCA9IHNyY1tvZmZzZXQgLSAxXTtcbiAgICBpZiAoY2ggPT09ICdcXG4nKSByZXR1cm4gb2Zmc2V0O1xuXG4gICAgd2hpbGUgKGNoICYmIGNoICE9PSAnXFxuJykgY2ggPSBzcmNbb2Zmc2V0IC09IDFdO1xuXG4gICAgcmV0dXJuIG9mZnNldCArIDE7XG4gIH1cbiAgLyoqXG4gICAqIEVuZCBvZiBpbmRlbnRhdGlvbiwgb3IgbnVsbCBpZiB0aGUgbGluZSdzIGluZGVudCBsZXZlbCBpcyBub3QgbW9yZVxuICAgKiB0aGFuIGBpbmRlbnRgXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzcmNcbiAgICogQHBhcmFtIHtudW1iZXJ9IGluZGVudFxuICAgKiBAcGFyYW0ge251bWJlcn0gbGluZVN0YXJ0XG4gICAqIEByZXR1cm5zIHs/bnVtYmVyfVxuICAgKi9cblxuXG4gIHN0YXRpYyBlbmRPZkJsb2NrSW5kZW50KHNyYywgaW5kZW50LCBsaW5lU3RhcnQpIHtcbiAgICBjb25zdCBpbkVuZCA9IE5vZGUuZW5kT2ZJbmRlbnQoc3JjLCBsaW5lU3RhcnQpO1xuXG4gICAgaWYgKGluRW5kID4gbGluZVN0YXJ0ICsgaW5kZW50KSB7XG4gICAgICByZXR1cm4gaW5FbmQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHdzRW5kID0gTm9kZS5lbmRPZldoaXRlU3BhY2Uoc3JjLCBpbkVuZCk7XG4gICAgICBjb25zdCBjaCA9IHNyY1t3c0VuZF07XG4gICAgICBpZiAoIWNoIHx8IGNoID09PSAnXFxuJykgcmV0dXJuIHdzRW5kO1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgc3RhdGljIGF0Qmxhbmsoc3JjLCBvZmZzZXQsIGVuZEFzQmxhbmspIHtcbiAgICBjb25zdCBjaCA9IHNyY1tvZmZzZXRdO1xuICAgIHJldHVybiBjaCA9PT0gJ1xcbicgfHwgY2ggPT09ICdcXHQnIHx8IGNoID09PSAnICcgfHwgZW5kQXNCbGFuayAmJiAhY2g7XG4gIH1cblxuICBzdGF0aWMgbmV4dE5vZGVJc0luZGVudGVkKGNoLCBpbmRlbnREaWZmLCBpbmRpY2F0b3JBc0luZGVudCkge1xuICAgIGlmICghY2ggfHwgaW5kZW50RGlmZiA8IDApIHJldHVybiBmYWxzZTtcbiAgICBpZiAoaW5kZW50RGlmZiA+IDApIHJldHVybiB0cnVlO1xuICAgIHJldHVybiBpbmRpY2F0b3JBc0luZGVudCAmJiBjaCA9PT0gJy0nO1xuICB9IC8vIHNob3VsZCBiZSBhdCBsaW5lIG9yIHN0cmluZyBlbmQsIG9yIGF0IG5leHQgbm9uLXdoaXRlc3BhY2UgY2hhclxuXG5cbiAgc3RhdGljIG5vcm1hbGl6ZU9mZnNldChzcmMsIG9mZnNldCkge1xuICAgIGNvbnN0IGNoID0gc3JjW29mZnNldF07XG4gICAgcmV0dXJuICFjaCA/IG9mZnNldCA6IGNoICE9PSAnXFxuJyAmJiBzcmNbb2Zmc2V0IC0gMV0gPT09ICdcXG4nID8gb2Zmc2V0IC0gMSA6IE5vZGUuZW5kT2ZXaGl0ZVNwYWNlKHNyYywgb2Zmc2V0KTtcbiAgfSAvLyBmb2xkIHNpbmdsZSBuZXdsaW5lIGludG8gc3BhY2UsIG11bHRpcGxlIG5ld2xpbmVzIHRvIE4gLSAxIG5ld2xpbmVzXG4gIC8vIHByZXN1bWVzIHNyY1tvZmZzZXRdID09PSAnXFxuJ1xuXG5cbiAgc3RhdGljIGZvbGROZXdsaW5lKHNyYywgb2Zmc2V0LCBpbmRlbnQpIHtcbiAgICBsZXQgaW5Db3VudCA9IDA7XG4gICAgbGV0IGVycm9yID0gZmFsc2U7XG4gICAgbGV0IGZvbGQgPSAnJztcbiAgICBsZXQgY2ggPSBzcmNbb2Zmc2V0ICsgMV07XG5cbiAgICB3aGlsZSAoY2ggPT09ICcgJyB8fCBjaCA9PT0gJ1xcdCcgfHwgY2ggPT09ICdcXG4nKSB7XG4gICAgICBzd2l0Y2ggKGNoKSB7XG4gICAgICAgIGNhc2UgJ1xcbic6XG4gICAgICAgICAgaW5Db3VudCA9IDA7XG4gICAgICAgICAgb2Zmc2V0ICs9IDE7XG4gICAgICAgICAgZm9sZCArPSAnXFxuJztcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlICdcXHQnOlxuICAgICAgICAgIGlmIChpbkNvdW50IDw9IGluZGVudCkgZXJyb3IgPSB0cnVlO1xuICAgICAgICAgIG9mZnNldCA9IE5vZGUuZW5kT2ZXaGl0ZVNwYWNlKHNyYywgb2Zmc2V0ICsgMikgLSAxO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgJyAnOlxuICAgICAgICAgIGluQ291bnQgKz0gMTtcbiAgICAgICAgICBvZmZzZXQgKz0gMTtcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgY2ggPSBzcmNbb2Zmc2V0ICsgMV07XG4gICAgfVxuXG4gICAgaWYgKCFmb2xkKSBmb2xkID0gJyAnO1xuICAgIGlmIChjaCAmJiBpbkNvdW50IDw9IGluZGVudCkgZXJyb3IgPSB0cnVlO1xuICAgIHJldHVybiB7XG4gICAgICBmb2xkLFxuICAgICAgb2Zmc2V0LFxuICAgICAgZXJyb3JcbiAgICB9O1xuICB9XG5cbiAgY29uc3RydWN0b3IodHlwZSwgcHJvcHMsIGNvbnRleHQpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ2NvbnRleHQnLCB7XG4gICAgICB2YWx1ZTogY29udGV4dCB8fCBudWxsLFxuICAgICAgd3JpdGFibGU6IHRydWVcbiAgICB9KTtcbiAgICB0aGlzLmVycm9yID0gbnVsbDtcbiAgICB0aGlzLnJhbmdlID0gbnVsbDtcbiAgICB0aGlzLnZhbHVlUmFuZ2UgPSBudWxsO1xuICAgIHRoaXMucHJvcHMgPSBwcm9wcyB8fCBbXTtcbiAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgIHRoaXMudmFsdWUgPSBudWxsO1xuICB9XG5cbiAgZ2V0UHJvcFZhbHVlKGlkeCwga2V5LCBza2lwS2V5KSB7XG4gICAgaWYgKCF0aGlzLmNvbnRleHQpIHJldHVybiBudWxsO1xuICAgIGNvbnN0IHtcbiAgICAgIHNyY1xuICAgIH0gPSB0aGlzLmNvbnRleHQ7XG4gICAgY29uc3QgcHJvcCA9IHRoaXMucHJvcHNbaWR4XTtcbiAgICByZXR1cm4gcHJvcCAmJiBzcmNbcHJvcC5zdGFydF0gPT09IGtleSA/IHNyYy5zbGljZShwcm9wLnN0YXJ0ICsgKHNraXBLZXkgPyAxIDogMCksIHByb3AuZW5kKSA6IG51bGw7XG4gIH1cblxuICBnZXQgYW5jaG9yKCkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5wcm9wcy5sZW5ndGg7ICsraSkge1xuICAgICAgY29uc3QgYW5jaG9yID0gdGhpcy5nZXRQcm9wVmFsdWUoaSwgQ2hhci5BTkNIT1IsIHRydWUpO1xuICAgICAgaWYgKGFuY2hvciAhPSBudWxsKSByZXR1cm4gYW5jaG9yO1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgZ2V0IGNvbW1lbnQoKSB7XG4gICAgY29uc3QgY29tbWVudHMgPSBbXTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5wcm9wcy5sZW5ndGg7ICsraSkge1xuICAgICAgY29uc3QgY29tbWVudCA9IHRoaXMuZ2V0UHJvcFZhbHVlKGksIENoYXIuQ09NTUVOVCwgdHJ1ZSk7XG4gICAgICBpZiAoY29tbWVudCAhPSBudWxsKSBjb21tZW50cy5wdXNoKGNvbW1lbnQpO1xuICAgIH1cblxuICAgIHJldHVybiBjb21tZW50cy5sZW5ndGggPiAwID8gY29tbWVudHMuam9pbignXFxuJykgOiBudWxsO1xuICB9XG5cbiAgY29tbWVudEhhc1JlcXVpcmVkV2hpdGVzcGFjZShzdGFydCkge1xuICAgIGNvbnN0IHtcbiAgICAgIHNyY1xuICAgIH0gPSB0aGlzLmNvbnRleHQ7XG4gICAgaWYgKHRoaXMuaGVhZGVyICYmIHN0YXJ0ID09PSB0aGlzLmhlYWRlci5lbmQpIHJldHVybiBmYWxzZTtcbiAgICBpZiAoIXRoaXMudmFsdWVSYW5nZSkgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IHtcbiAgICAgIGVuZFxuICAgIH0gPSB0aGlzLnZhbHVlUmFuZ2U7XG4gICAgcmV0dXJuIHN0YXJ0ICE9PSBlbmQgfHwgTm9kZS5hdEJsYW5rKHNyYywgZW5kIC0gMSk7XG4gIH1cblxuICBnZXQgaGFzQ29tbWVudCgpIHtcbiAgICBpZiAodGhpcy5jb250ZXh0KSB7XG4gICAgICBjb25zdCB7XG4gICAgICAgIHNyY1xuICAgICAgfSA9IHRoaXMuY29udGV4dDtcblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnByb3BzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIGlmIChzcmNbdGhpcy5wcm9wc1tpXS5zdGFydF0gPT09IENoYXIuQ09NTUVOVCkgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZ2V0IGhhc1Byb3BzKCkge1xuICAgIGlmICh0aGlzLmNvbnRleHQpIHtcbiAgICAgIGNvbnN0IHtcbiAgICAgICAgc3JjXG4gICAgICB9ID0gdGhpcy5jb250ZXh0O1xuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMucHJvcHMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgaWYgKHNyY1t0aGlzLnByb3BzW2ldLnN0YXJ0XSAhPT0gQ2hhci5DT01NRU5UKSByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBnZXQgaW5jbHVkZXNUcmFpbGluZ0xpbmVzKCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGdldCBqc29uTGlrZSgpIHtcbiAgICBjb25zdCBqc29uTGlrZVR5cGVzID0gW1R5cGUuRkxPV19NQVAsIFR5cGUuRkxPV19TRVEsIFR5cGUuUVVPVEVfRE9VQkxFLCBUeXBlLlFVT1RFX1NJTkdMRV07XG4gICAgcmV0dXJuIGpzb25MaWtlVHlwZXMuaW5kZXhPZih0aGlzLnR5cGUpICE9PSAtMTtcbiAgfVxuXG4gIGdldCByYW5nZUFzTGluZVBvcygpIHtcbiAgICBpZiAoIXRoaXMucmFuZ2UgfHwgIXRoaXMuY29udGV4dCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICBjb25zdCBzdGFydCA9IGdldExpbmVQb3ModGhpcy5yYW5nZS5zdGFydCwgdGhpcy5jb250ZXh0LnJvb3QpO1xuICAgIGlmICghc3RhcnQpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgY29uc3QgZW5kID0gZ2V0TGluZVBvcyh0aGlzLnJhbmdlLmVuZCwgdGhpcy5jb250ZXh0LnJvb3QpO1xuICAgIHJldHVybiB7XG4gICAgICBzdGFydCxcbiAgICAgIGVuZFxuICAgIH07XG4gIH1cblxuICBnZXQgcmF3VmFsdWUoKSB7XG4gICAgaWYgKCF0aGlzLnZhbHVlUmFuZ2UgfHwgIXRoaXMuY29udGV4dCkgcmV0dXJuIG51bGw7XG4gICAgY29uc3Qge1xuICAgICAgc3RhcnQsXG4gICAgICBlbmRcbiAgICB9ID0gdGhpcy52YWx1ZVJhbmdlO1xuICAgIHJldHVybiB0aGlzLmNvbnRleHQuc3JjLnNsaWNlKHN0YXJ0LCBlbmQpO1xuICB9XG5cbiAgZ2V0IHRhZygpIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMucHJvcHMubGVuZ3RoOyArK2kpIHtcbiAgICAgIGNvbnN0IHRhZyA9IHRoaXMuZ2V0UHJvcFZhbHVlKGksIENoYXIuVEFHLCBmYWxzZSk7XG5cbiAgICAgIGlmICh0YWcgIT0gbnVsbCkge1xuICAgICAgICBpZiAodGFnWzFdID09PSAnPCcpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdmVyYmF0aW06IHRhZy5zbGljZSgyLCAtMSlcbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFyc1xuICAgICAgICAgIGNvbnN0IFtfLCBoYW5kbGUsIHN1ZmZpeF0gPSB0YWcubWF0Y2goL14oLiohKShbXiFdKikkLyk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGhhbmRsZSxcbiAgICAgICAgICAgIHN1ZmZpeFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGdldCB2YWx1ZVJhbmdlQ29udGFpbnNOZXdsaW5lKCkge1xuICAgIGlmICghdGhpcy52YWx1ZVJhbmdlIHx8ICF0aGlzLmNvbnRleHQpIHJldHVybiBmYWxzZTtcbiAgICBjb25zdCB7XG4gICAgICBzdGFydCxcbiAgICAgIGVuZFxuICAgIH0gPSB0aGlzLnZhbHVlUmFuZ2U7XG4gICAgY29uc3Qge1xuICAgICAgc3JjXG4gICAgfSA9IHRoaXMuY29udGV4dDtcblxuICAgIGZvciAobGV0IGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgICBpZiAoc3JjW2ldID09PSAnXFxuJykgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcGFyc2VDb21tZW50KHN0YXJ0KSB7XG4gICAgY29uc3Qge1xuICAgICAgc3JjXG4gICAgfSA9IHRoaXMuY29udGV4dDtcblxuICAgIGlmIChzcmNbc3RhcnRdID09PSBDaGFyLkNPTU1FTlQpIHtcbiAgICAgIGNvbnN0IGVuZCA9IE5vZGUuZW5kT2ZMaW5lKHNyYywgc3RhcnQgKyAxKTtcbiAgICAgIGNvbnN0IGNvbW1lbnRSYW5nZSA9IG5ldyBSYW5nZShzdGFydCwgZW5kKTtcbiAgICAgIHRoaXMucHJvcHMucHVzaChjb21tZW50UmFuZ2UpO1xuICAgICAgcmV0dXJuIGVuZDtcbiAgICB9XG5cbiAgICByZXR1cm4gc3RhcnQ7XG4gIH1cbiAgLyoqXG4gICAqIFBvcHVsYXRlcyB0aGUgYG9yaWdTdGFydGAgYW5kIGBvcmlnRW5kYCB2YWx1ZXMgb2YgYWxsIHJhbmdlcyBmb3IgdGhpc1xuICAgKiBub2RlLiBFeHRlbmRlZCBieSBjaGlsZCBjbGFzc2VzIHRvIGhhbmRsZSBkZXNjZW5kYW50IG5vZGVzLlxuICAgKlxuICAgKiBAcGFyYW0ge251bWJlcltdfSBjciAtIFBvc2l0aW9ucyBvZiBkcm9wcGVkIENSIGNoYXJhY3RlcnNcbiAgICogQHBhcmFtIHtudW1iZXJ9IG9mZnNldCAtIFN0YXJ0aW5nIGluZGV4IG9mIGBjcmAgZnJvbSB0aGUgbGFzdCBjYWxsXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IC0gVGhlIG5leHQgb2Zmc2V0LCBtYXRjaGluZyB0aGUgb25lIGZvdW5kIGZvciBgb3JpZ1N0YXJ0YFxuICAgKi9cblxuXG4gIHNldE9yaWdSYW5nZXMoY3IsIG9mZnNldCkge1xuICAgIGlmICh0aGlzLnJhbmdlKSBvZmZzZXQgPSB0aGlzLnJhbmdlLnNldE9yaWdSYW5nZShjciwgb2Zmc2V0KTtcbiAgICBpZiAodGhpcy52YWx1ZVJhbmdlKSB0aGlzLnZhbHVlUmFuZ2Uuc2V0T3JpZ1JhbmdlKGNyLCBvZmZzZXQpO1xuICAgIHRoaXMucHJvcHMuZm9yRWFjaChwcm9wID0+IHByb3Auc2V0T3JpZ1JhbmdlKGNyLCBvZmZzZXQpKTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG5cbiAgdG9TdHJpbmcoKSB7XG4gICAgY29uc3Qge1xuICAgICAgY29udGV4dDoge1xuICAgICAgICBzcmNcbiAgICAgIH0sXG4gICAgICByYW5nZSxcbiAgICAgIHZhbHVlXG4gICAgfSA9IHRoaXM7XG4gICAgaWYgKHZhbHVlICE9IG51bGwpIHJldHVybiB2YWx1ZTtcbiAgICBjb25zdCBzdHIgPSBzcmMuc2xpY2UocmFuZ2Uuc3RhcnQsIHJhbmdlLmVuZCk7XG4gICAgcmV0dXJuIE5vZGUuYWRkU3RyaW5nVGVybWluYXRvcihzcmMsIHJhbmdlLmVuZCwgc3RyKTtcbiAgfVxuXG59XG5cbmV4cG9ydCB7IE5vZGUgfTtcbiIsImltcG9ydCB7IE5vZGUgfSBmcm9tICcuL2NzdC9Ob2RlLmpzJztcbmltcG9ydCB7IGdldExpbmVQb3MsIGdldFByZXR0eUNvbnRleHQgfSBmcm9tICcuL2NzdC9zb3VyY2UtdXRpbHMuanMnO1xuaW1wb3J0IHsgUmFuZ2UgfSBmcm9tICcuL2NzdC9SYW5nZS5qcyc7XG5cbmNsYXNzIFlBTUxFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgY29uc3RydWN0b3IobmFtZSwgc291cmNlLCBtZXNzYWdlKSB7XG4gICAgaWYgKCFtZXNzYWdlIHx8ICEoc291cmNlIGluc3RhbmNlb2YgTm9kZSkpIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgYXJndW1lbnRzIGZvciBuZXcgXCIuY29uY2F0KG5hbWUpKTtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTtcbiAgICB0aGlzLnNvdXJjZSA9IHNvdXJjZTtcbiAgfVxuXG4gIG1ha2VQcmV0dHkoKSB7XG4gICAgaWYgKCF0aGlzLnNvdXJjZSkgcmV0dXJuO1xuICAgIHRoaXMubm9kZVR5cGUgPSB0aGlzLnNvdXJjZS50eXBlO1xuICAgIGNvbnN0IGNzdCA9IHRoaXMuc291cmNlLmNvbnRleHQgJiYgdGhpcy5zb3VyY2UuY29udGV4dC5yb290O1xuXG4gICAgaWYgKHR5cGVvZiB0aGlzLm9mZnNldCA9PT0gJ251bWJlcicpIHtcbiAgICAgIHRoaXMucmFuZ2UgPSBuZXcgUmFuZ2UodGhpcy5vZmZzZXQsIHRoaXMub2Zmc2V0ICsgMSk7XG4gICAgICBjb25zdCBzdGFydCA9IGNzdCAmJiBnZXRMaW5lUG9zKHRoaXMub2Zmc2V0LCBjc3QpO1xuXG4gICAgICBpZiAoc3RhcnQpIHtcbiAgICAgICAgY29uc3QgZW5kID0ge1xuICAgICAgICAgIGxpbmU6IHN0YXJ0LmxpbmUsXG4gICAgICAgICAgY29sOiBzdGFydC5jb2wgKyAxXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMubGluZVBvcyA9IHtcbiAgICAgICAgICBzdGFydCxcbiAgICAgICAgICBlbmRcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgZGVsZXRlIHRoaXMub2Zmc2V0O1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJhbmdlID0gdGhpcy5zb3VyY2UucmFuZ2U7XG4gICAgICB0aGlzLmxpbmVQb3MgPSB0aGlzLnNvdXJjZS5yYW5nZUFzTGluZVBvcztcbiAgICB9XG5cbiAgICBpZiAodGhpcy5saW5lUG9zKSB7XG4gICAgICBjb25zdCB7XG4gICAgICAgIGxpbmUsXG4gICAgICAgIGNvbFxuICAgICAgfSA9IHRoaXMubGluZVBvcy5zdGFydDtcbiAgICAgIHRoaXMubWVzc2FnZSArPSBcIiBhdCBsaW5lIFwiLmNvbmNhdChsaW5lLCBcIiwgY29sdW1uIFwiKS5jb25jYXQoY29sKTtcbiAgICAgIGNvbnN0IGN0eCA9IGNzdCAmJiBnZXRQcmV0dHlDb250ZXh0KHRoaXMubGluZVBvcywgY3N0KTtcbiAgICAgIGlmIChjdHgpIHRoaXMubWVzc2FnZSArPSBcIjpcXG5cXG5cIi5jb25jYXQoY3R4LCBcIlxcblwiKTtcbiAgICB9XG5cbiAgICBkZWxldGUgdGhpcy5zb3VyY2U7XG4gIH1cblxufVxuY2xhc3MgWUFNTFJlZmVyZW5jZUVycm9yIGV4dGVuZHMgWUFNTEVycm9yIHtcbiAgY29uc3RydWN0b3Ioc291cmNlLCBtZXNzYWdlKSB7XG4gICAgc3VwZXIoJ1lBTUxSZWZlcmVuY2VFcnJvcicsIHNvdXJjZSwgbWVzc2FnZSk7XG4gIH1cblxufVxuY2xhc3MgWUFNTFNlbWFudGljRXJyb3IgZXh0ZW5kcyBZQU1MRXJyb3Ige1xuICBjb25zdHJ1Y3Rvcihzb3VyY2UsIG1lc3NhZ2UpIHtcbiAgICBzdXBlcignWUFNTFNlbWFudGljRXJyb3InLCBzb3VyY2UsIG1lc3NhZ2UpO1xuICB9XG5cbn1cbmNsYXNzIFlBTUxTeW50YXhFcnJvciBleHRlbmRzIFlBTUxFcnJvciB7XG4gIGNvbnN0cnVjdG9yKHNvdXJjZSwgbWVzc2FnZSkge1xuICAgIHN1cGVyKCdZQU1MU3ludGF4RXJyb3InLCBzb3VyY2UsIG1lc3NhZ2UpO1xuICB9XG5cbn1cbmNsYXNzIFlBTUxXYXJuaW5nIGV4dGVuZHMgWUFNTEVycm9yIHtcbiAgY29uc3RydWN0b3Ioc291cmNlLCBtZXNzYWdlKSB7XG4gICAgc3VwZXIoJ1lBTUxXYXJuaW5nJywgc291cmNlLCBtZXNzYWdlKTtcbiAgfVxuXG59XG5cbmV4cG9ydCB7IFlBTUxFcnJvciwgWUFNTFJlZmVyZW5jZUVycm9yLCBZQU1MU2VtYW50aWNFcnJvciwgWUFNTFN5bnRheEVycm9yLCBZQU1MV2FybmluZyB9O1xuIiwiaW1wb3J0IHsgVHlwZSB9IGZyb20gJy4uL2NvbnN0YW50cy5qcyc7XG5pbXBvcnQgeyBOb2RlIH0gZnJvbSAnLi9Ob2RlLmpzJztcbmltcG9ydCB7IFJhbmdlIH0gZnJvbSAnLi9SYW5nZS5qcyc7XG5cbmNsYXNzIEJsYW5rTGluZSBleHRlbmRzIE5vZGUge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcihUeXBlLkJMQU5LX0xJTkUpO1xuICB9XG4gIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5cblxuICBnZXQgaW5jbHVkZXNUcmFpbGluZ0xpbmVzKCkge1xuICAgIC8vIFRoaXMgaXMgbmV2ZXIgY2FsbGVkIGZyb20gYW55d2hlcmUsIGJ1dCBpZiBpdCB3ZXJlLFxuICAgIC8vIHRoaXMgaXMgdGhlIHZhbHVlIGl0IHNob3VsZCByZXR1cm4uXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgLyoqXG4gICAqIFBhcnNlcyBhIGJsYW5rIGxpbmUgZnJvbSB0aGUgc291cmNlXG4gICAqXG4gICAqIEBwYXJhbSB7UGFyc2VDb250ZXh0fSBjb250ZXh0XG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydCAtIEluZGV4IG9mIGZpcnN0IFxcbiBjaGFyYWN0ZXJcbiAgICogQHJldHVybnMge251bWJlcn0gLSBJbmRleCBvZiB0aGUgY2hhcmFjdGVyIGFmdGVyIHRoaXNcbiAgICovXG5cblxuICBwYXJzZShjb250ZXh0LCBzdGFydCkge1xuICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG4gICAgdGhpcy5yYW5nZSA9IG5ldyBSYW5nZShzdGFydCwgc3RhcnQgKyAxKTtcbiAgICByZXR1cm4gc3RhcnQgKyAxO1xuICB9XG5cbn1cblxuZXhwb3J0IHsgQmxhbmtMaW5lIH07XG4iLCJpbXBvcnQgeyBUeXBlIH0gZnJvbSAnLi4vY29uc3RhbnRzLmpzJztcbmltcG9ydCB7IFlBTUxTZW1hbnRpY0Vycm9yIH0gZnJvbSAnLi4vZXJyb3JzLmpzJztcbmltcG9ydCB7IEJsYW5rTGluZSB9IGZyb20gJy4vQmxhbmtMaW5lLmpzJztcbmltcG9ydCB7IE5vZGUgfSBmcm9tICcuL05vZGUuanMnO1xuaW1wb3J0IHsgUmFuZ2UgfSBmcm9tICcuL1JhbmdlLmpzJztcblxuY2xhc3MgQ29sbGVjdGlvbkl0ZW0gZXh0ZW5kcyBOb2RlIHtcbiAgY29uc3RydWN0b3IodHlwZSwgcHJvcHMpIHtcbiAgICBzdXBlcih0eXBlLCBwcm9wcyk7XG4gICAgdGhpcy5ub2RlID0gbnVsbDtcbiAgfVxuXG4gIGdldCBpbmNsdWRlc1RyYWlsaW5nTGluZXMoKSB7XG4gICAgcmV0dXJuICEhdGhpcy5ub2RlICYmIHRoaXMubm9kZS5pbmNsdWRlc1RyYWlsaW5nTGluZXM7XG4gIH1cbiAgLyoqXG4gICAqIEBwYXJhbSB7UGFyc2VDb250ZXh0fSBjb250ZXh0XG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydCAtIEluZGV4IG9mIGZpcnN0IGNoYXJhY3RlclxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSAtIEluZGV4IG9mIHRoZSBjaGFyYWN0ZXIgYWZ0ZXIgdGhpc1xuICAgKi9cblxuXG4gIHBhcnNlKGNvbnRleHQsIHN0YXJ0KSB7XG4gICAgdGhpcy5jb250ZXh0ID0gY29udGV4dDtcbiAgICBjb25zdCB7XG4gICAgICBwYXJzZU5vZGUsXG4gICAgICBzcmNcbiAgICB9ID0gY29udGV4dDtcbiAgICBsZXQge1xuICAgICAgYXRMaW5lU3RhcnQsXG4gICAgICBsaW5lU3RhcnRcbiAgICB9ID0gY29udGV4dDtcbiAgICBpZiAoIWF0TGluZVN0YXJ0ICYmIHRoaXMudHlwZSA9PT0gVHlwZS5TRVFfSVRFTSkgdGhpcy5lcnJvciA9IG5ldyBZQU1MU2VtYW50aWNFcnJvcih0aGlzLCAnU2VxdWVuY2UgaXRlbXMgbXVzdCBub3QgaGF2ZSBwcmVjZWRpbmcgY29udGVudCBvbiB0aGUgc2FtZSBsaW5lJyk7XG4gICAgY29uc3QgaW5kZW50ID0gYXRMaW5lU3RhcnQgPyBzdGFydCAtIGxpbmVTdGFydCA6IGNvbnRleHQuaW5kZW50O1xuICAgIGxldCBvZmZzZXQgPSBOb2RlLmVuZE9mV2hpdGVTcGFjZShzcmMsIHN0YXJ0ICsgMSk7XG4gICAgbGV0IGNoID0gc3JjW29mZnNldF07XG4gICAgY29uc3QgaW5saW5lQ29tbWVudCA9IGNoID09PSAnIyc7XG4gICAgY29uc3QgY29tbWVudHMgPSBbXTtcbiAgICBsZXQgYmxhbmtMaW5lID0gbnVsbDtcblxuICAgIHdoaWxlIChjaCA9PT0gJ1xcbicgfHwgY2ggPT09ICcjJykge1xuICAgICAgaWYgKGNoID09PSAnIycpIHtcbiAgICAgICAgY29uc3QgZW5kID0gTm9kZS5lbmRPZkxpbmUoc3JjLCBvZmZzZXQgKyAxKTtcbiAgICAgICAgY29tbWVudHMucHVzaChuZXcgUmFuZ2Uob2Zmc2V0LCBlbmQpKTtcbiAgICAgICAgb2Zmc2V0ID0gZW5kO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXRMaW5lU3RhcnQgPSB0cnVlO1xuICAgICAgICBsaW5lU3RhcnQgPSBvZmZzZXQgKyAxO1xuICAgICAgICBjb25zdCB3c0VuZCA9IE5vZGUuZW5kT2ZXaGl0ZVNwYWNlKHNyYywgbGluZVN0YXJ0KTtcblxuICAgICAgICBpZiAoc3JjW3dzRW5kXSA9PT0gJ1xcbicgJiYgY29tbWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgYmxhbmtMaW5lID0gbmV3IEJsYW5rTGluZSgpO1xuICAgICAgICAgIGxpbmVTdGFydCA9IGJsYW5rTGluZS5wYXJzZSh7XG4gICAgICAgICAgICBzcmNcbiAgICAgICAgICB9LCBsaW5lU3RhcnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgb2Zmc2V0ID0gTm9kZS5lbmRPZkluZGVudChzcmMsIGxpbmVTdGFydCk7XG4gICAgICB9XG5cbiAgICAgIGNoID0gc3JjW29mZnNldF07XG4gICAgfVxuXG4gICAgaWYgKE5vZGUubmV4dE5vZGVJc0luZGVudGVkKGNoLCBvZmZzZXQgLSAobGluZVN0YXJ0ICsgaW5kZW50KSwgdGhpcy50eXBlICE9PSBUeXBlLlNFUV9JVEVNKSkge1xuICAgICAgdGhpcy5ub2RlID0gcGFyc2VOb2RlKHtcbiAgICAgICAgYXRMaW5lU3RhcnQsXG4gICAgICAgIGluQ29sbGVjdGlvbjogZmFsc2UsXG4gICAgICAgIGluZGVudCxcbiAgICAgICAgbGluZVN0YXJ0LFxuICAgICAgICBwYXJlbnQ6IHRoaXNcbiAgICAgIH0sIG9mZnNldCk7XG4gICAgfSBlbHNlIGlmIChjaCAmJiBsaW5lU3RhcnQgPiBzdGFydCArIDEpIHtcbiAgICAgIG9mZnNldCA9IGxpbmVTdGFydCAtIDE7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubm9kZSkge1xuICAgICAgaWYgKGJsYW5rTGluZSkge1xuICAgICAgICAvLyBPbmx5IGJsYW5rIGxpbmVzIHByZWNlZGluZyBub24tZW1wdHkgbm9kZXMgYXJlIGNhcHR1cmVkLiBOb3RlIHRoYXRcbiAgICAgICAgLy8gdGhpcyBtZWFucyB0aGF0IGNvbGxlY3Rpb24gaXRlbSByYW5nZSBzdGFydCBpbmRpY2VzIGRvIG5vdCBhbHdheXNcbiAgICAgICAgLy8gaW5jcmVhc2UgbW9ub3RvbmljYWxseS4gLS0gZWVtZWxpL3lhbWwjMTI2XG4gICAgICAgIGNvbnN0IGl0ZW1zID0gY29udGV4dC5wYXJlbnQuaXRlbXMgfHwgY29udGV4dC5wYXJlbnQuY29udGVudHM7XG4gICAgICAgIGlmIChpdGVtcykgaXRlbXMucHVzaChibGFua0xpbmUpO1xuICAgICAgfVxuXG4gICAgICBpZiAoY29tbWVudHMubGVuZ3RoKSBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseSh0aGlzLnByb3BzLCBjb21tZW50cyk7XG4gICAgICBvZmZzZXQgPSB0aGlzLm5vZGUucmFuZ2UuZW5kO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoaW5saW5lQ29tbWVudCkge1xuICAgICAgICBjb25zdCBjID0gY29tbWVudHNbMF07XG4gICAgICAgIHRoaXMucHJvcHMucHVzaChjKTtcbiAgICAgICAgb2Zmc2V0ID0gYy5lbmQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvZmZzZXQgPSBOb2RlLmVuZE9mTGluZShzcmMsIHN0YXJ0ICsgMSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgZW5kID0gdGhpcy5ub2RlID8gdGhpcy5ub2RlLnZhbHVlUmFuZ2UuZW5kIDogb2Zmc2V0O1xuICAgIHRoaXMudmFsdWVSYW5nZSA9IG5ldyBSYW5nZShzdGFydCwgZW5kKTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG5cbiAgc2V0T3JpZ1Jhbmdlcyhjciwgb2Zmc2V0KSB7XG4gICAgb2Zmc2V0ID0gc3VwZXIuc2V0T3JpZ1Jhbmdlcyhjciwgb2Zmc2V0KTtcbiAgICByZXR1cm4gdGhpcy5ub2RlID8gdGhpcy5ub2RlLnNldE9yaWdSYW5nZXMoY3IsIG9mZnNldCkgOiBvZmZzZXQ7XG4gIH1cblxuICB0b1N0cmluZygpIHtcbiAgICBjb25zdCB7XG4gICAgICBjb250ZXh0OiB7XG4gICAgICAgIHNyY1xuICAgICAgfSxcbiAgICAgIG5vZGUsXG4gICAgICByYW5nZSxcbiAgICAgIHZhbHVlXG4gICAgfSA9IHRoaXM7XG4gICAgaWYgKHZhbHVlICE9IG51bGwpIHJldHVybiB2YWx1ZTtcbiAgICBjb25zdCBzdHIgPSBub2RlID8gc3JjLnNsaWNlKHJhbmdlLnN0YXJ0LCBub2RlLnJhbmdlLnN0YXJ0KSArIFN0cmluZyhub2RlKSA6IHNyYy5zbGljZShyYW5nZS5zdGFydCwgcmFuZ2UuZW5kKTtcbiAgICByZXR1cm4gTm9kZS5hZGRTdHJpbmdUZXJtaW5hdG9yKHNyYywgcmFuZ2UuZW5kLCBzdHIpO1xuICB9XG5cbn1cblxuZXhwb3J0IHsgQ29sbGVjdGlvbkl0ZW0gfTtcbiIsImltcG9ydCB7IFR5cGUgfSBmcm9tICcuLi9jb25zdGFudHMuanMnO1xuaW1wb3J0IHsgTm9kZSB9IGZyb20gJy4vTm9kZS5qcyc7XG5pbXBvcnQgeyBSYW5nZSB9IGZyb20gJy4vUmFuZ2UuanMnO1xuXG5jbGFzcyBDb21tZW50IGV4dGVuZHMgTm9kZSB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKFR5cGUuQ09NTUVOVCk7XG4gIH1cbiAgLyoqXG4gICAqIFBhcnNlcyBhIGNvbW1lbnQgbGluZSBmcm9tIHRoZSBzb3VyY2VcbiAgICpcbiAgICogQHBhcmFtIHtQYXJzZUNvbnRleHR9IGNvbnRleHRcbiAgICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0IC0gSW5kZXggb2YgZmlyc3QgY2hhcmFjdGVyXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IC0gSW5kZXggb2YgdGhlIGNoYXJhY3RlciBhZnRlciB0aGlzIHNjYWxhclxuICAgKi9cblxuXG4gIHBhcnNlKGNvbnRleHQsIHN0YXJ0KSB7XG4gICAgdGhpcy5jb250ZXh0ID0gY29udGV4dDtcbiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLnBhcnNlQ29tbWVudChzdGFydCk7XG4gICAgdGhpcy5yYW5nZSA9IG5ldyBSYW5nZShzdGFydCwgb2Zmc2V0KTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG5cbn1cblxuZXhwb3J0IHsgQ29tbWVudCB9O1xuIiwiaW1wb3J0IHsgVHlwZSB9IGZyb20gJy4uL2NvbnN0YW50cy5qcyc7XG5pbXBvcnQgeyBZQU1MU3ludGF4RXJyb3IgfSBmcm9tICcuLi9lcnJvcnMuanMnO1xuaW1wb3J0IHsgQmxhbmtMaW5lIH0gZnJvbSAnLi9CbGFua0xpbmUuanMnO1xuaW1wb3J0IHsgQ29sbGVjdGlvbkl0ZW0gfSBmcm9tICcuL0NvbGxlY3Rpb25JdGVtLmpzJztcbmltcG9ydCB7IENvbW1lbnQgfSBmcm9tICcuL0NvbW1lbnQuanMnO1xuaW1wb3J0IHsgTm9kZSB9IGZyb20gJy4vTm9kZS5qcyc7XG5pbXBvcnQgeyBSYW5nZSB9IGZyb20gJy4vUmFuZ2UuanMnO1xuXG5mdW5jdGlvbiBncmFiQ29sbGVjdGlvbkVuZENvbW1lbnRzKG5vZGUpIHtcbiAgbGV0IGNub2RlID0gbm9kZTtcblxuICB3aGlsZSAoY25vZGUgaW5zdGFuY2VvZiBDb2xsZWN0aW9uSXRlbSkgY25vZGUgPSBjbm9kZS5ub2RlO1xuXG4gIGlmICghKGNub2RlIGluc3RhbmNlb2YgQ29sbGVjdGlvbikpIHJldHVybiBudWxsO1xuICBjb25zdCBsZW4gPSBjbm9kZS5pdGVtcy5sZW5ndGg7XG4gIGxldCBjaSA9IC0xO1xuXG4gIGZvciAobGV0IGkgPSBsZW4gLSAxOyBpID49IDA7IC0taSkge1xuICAgIGNvbnN0IG4gPSBjbm9kZS5pdGVtc1tpXTtcblxuICAgIGlmIChuLnR5cGUgPT09IFR5cGUuQ09NTUVOVCkge1xuICAgICAgLy8gS2VlcCBzdWZmaWNpZW50bHkgaW5kZW50ZWQgY29tbWVudHMgd2l0aCBwcmVjZWRpbmcgbm9kZVxuICAgICAgY29uc3Qge1xuICAgICAgICBpbmRlbnQsXG4gICAgICAgIGxpbmVTdGFydFxuICAgICAgfSA9IG4uY29udGV4dDtcbiAgICAgIGlmIChpbmRlbnQgPiAwICYmIG4ucmFuZ2Uuc3RhcnQgPj0gbGluZVN0YXJ0ICsgaW5kZW50KSBicmVhaztcbiAgICAgIGNpID0gaTtcbiAgICB9IGVsc2UgaWYgKG4udHlwZSA9PT0gVHlwZS5CTEFOS19MSU5FKSBjaSA9IGk7ZWxzZSBicmVhaztcbiAgfVxuXG4gIGlmIChjaSA9PT0gLTEpIHJldHVybiBudWxsO1xuICBjb25zdCBjYSA9IGNub2RlLml0ZW1zLnNwbGljZShjaSwgbGVuIC0gY2kpO1xuICBjb25zdCBwcmV2RW5kID0gY2FbMF0ucmFuZ2Uuc3RhcnQ7XG5cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBjbm9kZS5yYW5nZS5lbmQgPSBwcmV2RW5kO1xuICAgIGlmIChjbm9kZS52YWx1ZVJhbmdlICYmIGNub2RlLnZhbHVlUmFuZ2UuZW5kID4gcHJldkVuZCkgY25vZGUudmFsdWVSYW5nZS5lbmQgPSBwcmV2RW5kO1xuICAgIGlmIChjbm9kZSA9PT0gbm9kZSkgYnJlYWs7XG4gICAgY25vZGUgPSBjbm9kZS5jb250ZXh0LnBhcmVudDtcbiAgfVxuXG4gIHJldHVybiBjYTtcbn1cbmNsYXNzIENvbGxlY3Rpb24gZXh0ZW5kcyBOb2RlIHtcbiAgc3RhdGljIG5leHRDb250ZW50SGFzSW5kZW50KHNyYywgb2Zmc2V0LCBpbmRlbnQpIHtcbiAgICBjb25zdCBsaW5lU3RhcnQgPSBOb2RlLmVuZE9mTGluZShzcmMsIG9mZnNldCkgKyAxO1xuICAgIG9mZnNldCA9IE5vZGUuZW5kT2ZXaGl0ZVNwYWNlKHNyYywgbGluZVN0YXJ0KTtcbiAgICBjb25zdCBjaCA9IHNyY1tvZmZzZXRdO1xuICAgIGlmICghY2gpIHJldHVybiBmYWxzZTtcbiAgICBpZiAob2Zmc2V0ID49IGxpbmVTdGFydCArIGluZGVudCkgcmV0dXJuIHRydWU7XG4gICAgaWYgKGNoICE9PSAnIycgJiYgY2ggIT09ICdcXG4nKSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuIENvbGxlY3Rpb24ubmV4dENvbnRlbnRIYXNJbmRlbnQoc3JjLCBvZmZzZXQsIGluZGVudCk7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihmaXJzdEl0ZW0pIHtcbiAgICBzdXBlcihmaXJzdEl0ZW0udHlwZSA9PT0gVHlwZS5TRVFfSVRFTSA/IFR5cGUuU0VRIDogVHlwZS5NQVApO1xuXG4gICAgZm9yIChsZXQgaSA9IGZpcnN0SXRlbS5wcm9wcy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgaWYgKGZpcnN0SXRlbS5wcm9wc1tpXS5zdGFydCA8IGZpcnN0SXRlbS5jb250ZXh0LmxpbmVTdGFydCkge1xuICAgICAgICAvLyBwcm9wcyBvbiBwcmV2aW91cyBsaW5lIGFyZSBhc3N1bWVkIGJ5IHRoZSBjb2xsZWN0aW9uXG4gICAgICAgIHRoaXMucHJvcHMgPSBmaXJzdEl0ZW0ucHJvcHMuc2xpY2UoMCwgaSArIDEpO1xuICAgICAgICBmaXJzdEl0ZW0ucHJvcHMgPSBmaXJzdEl0ZW0ucHJvcHMuc2xpY2UoaSArIDEpO1xuICAgICAgICBjb25zdCBpdGVtUmFuZ2UgPSBmaXJzdEl0ZW0ucHJvcHNbMF0gfHwgZmlyc3RJdGVtLnZhbHVlUmFuZ2U7XG4gICAgICAgIGZpcnN0SXRlbS5yYW5nZS5zdGFydCA9IGl0ZW1SYW5nZS5zdGFydDtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5pdGVtcyA9IFtmaXJzdEl0ZW1dO1xuICAgIGNvbnN0IGVjID0gZ3JhYkNvbGxlY3Rpb25FbmRDb21tZW50cyhmaXJzdEl0ZW0pO1xuICAgIGlmIChlYykgQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkodGhpcy5pdGVtcywgZWMpO1xuICB9XG5cbiAgZ2V0IGluY2x1ZGVzVHJhaWxpbmdMaW5lcygpIHtcbiAgICByZXR1cm4gdGhpcy5pdGVtcy5sZW5ndGggPiAwO1xuICB9XG4gIC8qKlxuICAgKiBAcGFyYW0ge1BhcnNlQ29udGV4dH0gY29udGV4dFxuICAgKiBAcGFyYW0ge251bWJlcn0gc3RhcnQgLSBJbmRleCBvZiBmaXJzdCBjaGFyYWN0ZXJcbiAgICogQHJldHVybnMge251bWJlcn0gLSBJbmRleCBvZiB0aGUgY2hhcmFjdGVyIGFmdGVyIHRoaXNcbiAgICovXG5cblxuICBwYXJzZShjb250ZXh0LCBzdGFydCkge1xuICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG4gICAgY29uc3Qge1xuICAgICAgcGFyc2VOb2RlLFxuICAgICAgc3JjXG4gICAgfSA9IGNvbnRleHQ7IC8vIEl0J3MgZWFzaWVyIHRvIHJlY2FsY3VsYXRlIGxpbmVTdGFydCBoZXJlIHJhdGhlciB0aGFuIHRyYWNraW5nIGRvd24gdGhlXG4gICAgLy8gbGFzdCBjb250ZXh0IGZyb20gd2hpY2ggdG8gcmVhZCBpdCAtLSBlZW1lbGkveWFtbCMyXG5cbiAgICBsZXQgbGluZVN0YXJ0ID0gTm9kZS5zdGFydE9mTGluZShzcmMsIHN0YXJ0KTtcbiAgICBjb25zdCBmaXJzdEl0ZW0gPSB0aGlzLml0ZW1zWzBdOyAvLyBGaXJzdC1pdGVtIGNvbnRleHQgbmVlZHMgdG8gYmUgY29ycmVjdCBmb3IgbGF0ZXIgY29tbWVudCBoYW5kbGluZ1xuICAgIC8vIC0tIGVlbWVsaS95YW1sIzE3XG5cbiAgICBmaXJzdEl0ZW0uY29udGV4dC5wYXJlbnQgPSB0aGlzO1xuICAgIHRoaXMudmFsdWVSYW5nZSA9IFJhbmdlLmNvcHkoZmlyc3RJdGVtLnZhbHVlUmFuZ2UpO1xuICAgIGNvbnN0IGluZGVudCA9IGZpcnN0SXRlbS5yYW5nZS5zdGFydCAtIGZpcnN0SXRlbS5jb250ZXh0LmxpbmVTdGFydDtcbiAgICBsZXQgb2Zmc2V0ID0gc3RhcnQ7XG4gICAgb2Zmc2V0ID0gTm9kZS5ub3JtYWxpemVPZmZzZXQoc3JjLCBvZmZzZXQpO1xuICAgIGxldCBjaCA9IHNyY1tvZmZzZXRdO1xuICAgIGxldCBhdExpbmVTdGFydCA9IE5vZGUuZW5kT2ZXaGl0ZVNwYWNlKHNyYywgbGluZVN0YXJ0KSA9PT0gb2Zmc2V0O1xuICAgIGxldCBwcmV2SW5jbHVkZXNUcmFpbGluZ0xpbmVzID0gZmFsc2U7XG5cbiAgICB3aGlsZSAoY2gpIHtcbiAgICAgIHdoaWxlIChjaCA9PT0gJ1xcbicgfHwgY2ggPT09ICcjJykge1xuICAgICAgICBpZiAoYXRMaW5lU3RhcnQgJiYgY2ggPT09ICdcXG4nICYmICFwcmV2SW5jbHVkZXNUcmFpbGluZ0xpbmVzKSB7XG4gICAgICAgICAgY29uc3QgYmxhbmtMaW5lID0gbmV3IEJsYW5rTGluZSgpO1xuICAgICAgICAgIG9mZnNldCA9IGJsYW5rTGluZS5wYXJzZSh7XG4gICAgICAgICAgICBzcmNcbiAgICAgICAgICB9LCBvZmZzZXQpO1xuICAgICAgICAgIHRoaXMudmFsdWVSYW5nZS5lbmQgPSBvZmZzZXQ7XG5cbiAgICAgICAgICBpZiAob2Zmc2V0ID49IHNyYy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNoID0gbnVsbDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRoaXMuaXRlbXMucHVzaChibGFua0xpbmUpO1xuICAgICAgICAgIG9mZnNldCAtPSAxOyAvLyBibGFua0xpbmUucGFyc2UoKSBjb25zdW1lcyB0ZXJtaW5hbCBuZXdsaW5lXG4gICAgICAgIH0gZWxzZSBpZiAoY2ggPT09ICcjJykge1xuICAgICAgICAgIGlmIChvZmZzZXQgPCBsaW5lU3RhcnQgKyBpbmRlbnQgJiYgIUNvbGxlY3Rpb24ubmV4dENvbnRlbnRIYXNJbmRlbnQoc3JjLCBvZmZzZXQsIGluZGVudCkpIHtcbiAgICAgICAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgY29tbWVudCA9IG5ldyBDb21tZW50KCk7XG4gICAgICAgICAgb2Zmc2V0ID0gY29tbWVudC5wYXJzZSh7XG4gICAgICAgICAgICBpbmRlbnQsXG4gICAgICAgICAgICBsaW5lU3RhcnQsXG4gICAgICAgICAgICBzcmNcbiAgICAgICAgICB9LCBvZmZzZXQpO1xuICAgICAgICAgIHRoaXMuaXRlbXMucHVzaChjb21tZW50KTtcbiAgICAgICAgICB0aGlzLnZhbHVlUmFuZ2UuZW5kID0gb2Zmc2V0O1xuXG4gICAgICAgICAgaWYgKG9mZnNldCA+PSBzcmMubGVuZ3RoKSB7XG4gICAgICAgICAgICBjaCA9IG51bGw7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBsaW5lU3RhcnQgPSBvZmZzZXQgKyAxO1xuICAgICAgICBvZmZzZXQgPSBOb2RlLmVuZE9mSW5kZW50KHNyYywgbGluZVN0YXJ0KTtcblxuICAgICAgICBpZiAoTm9kZS5hdEJsYW5rKHNyYywgb2Zmc2V0KSkge1xuICAgICAgICAgIGNvbnN0IHdzRW5kID0gTm9kZS5lbmRPZldoaXRlU3BhY2Uoc3JjLCBvZmZzZXQpO1xuICAgICAgICAgIGNvbnN0IG5leHQgPSBzcmNbd3NFbmRdO1xuXG4gICAgICAgICAgaWYgKCFuZXh0IHx8IG5leHQgPT09ICdcXG4nIHx8IG5leHQgPT09ICcjJykge1xuICAgICAgICAgICAgb2Zmc2V0ID0gd3NFbmQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY2ggPSBzcmNbb2Zmc2V0XTtcbiAgICAgICAgYXRMaW5lU3RhcnQgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWNoKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBpZiAob2Zmc2V0ICE9PSBsaW5lU3RhcnQgKyBpbmRlbnQgJiYgKGF0TGluZVN0YXJ0IHx8IGNoICE9PSAnOicpKSB7XG4gICAgICAgIGlmIChvZmZzZXQgPCBsaW5lU3RhcnQgKyBpbmRlbnQpIHtcbiAgICAgICAgICBpZiAobGluZVN0YXJ0ID4gc3RhcnQpIG9mZnNldCA9IGxpbmVTdGFydDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfSBlbHNlIGlmICghdGhpcy5lcnJvcikge1xuICAgICAgICAgIGNvbnN0IG1zZyA9ICdBbGwgY29sbGVjdGlvbiBpdGVtcyBtdXN0IHN0YXJ0IGF0IHRoZSBzYW1lIGNvbHVtbic7XG4gICAgICAgICAgdGhpcy5lcnJvciA9IG5ldyBZQU1MU3ludGF4RXJyb3IodGhpcywgbXNnKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoZmlyc3RJdGVtLnR5cGUgPT09IFR5cGUuU0VRX0lURU0pIHtcbiAgICAgICAgaWYgKGNoICE9PSAnLScpIHtcbiAgICAgICAgICBpZiAobGluZVN0YXJ0ID4gc3RhcnQpIG9mZnNldCA9IGxpbmVTdGFydDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChjaCA9PT0gJy0nICYmICF0aGlzLmVycm9yKSB7XG4gICAgICAgIC8vIG1hcCBrZXkgbWF5IHN0YXJ0IHdpdGggLSwgYXMgbG9uZyBhcyBpdCdzIGZvbGxvd2VkIGJ5IGEgbm9uLXdoaXRlc3BhY2UgY2hhclxuICAgICAgICBjb25zdCBuZXh0ID0gc3JjW29mZnNldCArIDFdO1xuXG4gICAgICAgIGlmICghbmV4dCB8fCBuZXh0ID09PSAnXFxuJyB8fCBuZXh0ID09PSAnXFx0JyB8fCBuZXh0ID09PSAnICcpIHtcbiAgICAgICAgICBjb25zdCBtc2cgPSAnQSBjb2xsZWN0aW9uIGNhbm5vdCBiZSBib3RoIGEgbWFwcGluZyBhbmQgYSBzZXF1ZW5jZSc7XG4gICAgICAgICAgdGhpcy5lcnJvciA9IG5ldyBZQU1MU3ludGF4RXJyb3IodGhpcywgbXNnKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBub2RlID0gcGFyc2VOb2RlKHtcbiAgICAgICAgYXRMaW5lU3RhcnQsXG4gICAgICAgIGluQ29sbGVjdGlvbjogdHJ1ZSxcbiAgICAgICAgaW5kZW50LFxuICAgICAgICBsaW5lU3RhcnQsXG4gICAgICAgIHBhcmVudDogdGhpc1xuICAgICAgfSwgb2Zmc2V0KTtcbiAgICAgIGlmICghbm9kZSkgcmV0dXJuIG9mZnNldDsgLy8gYXQgbmV4dCBkb2N1bWVudCBzdGFydFxuXG4gICAgICB0aGlzLml0ZW1zLnB1c2gobm9kZSk7XG4gICAgICB0aGlzLnZhbHVlUmFuZ2UuZW5kID0gbm9kZS52YWx1ZVJhbmdlLmVuZDtcbiAgICAgIG9mZnNldCA9IE5vZGUubm9ybWFsaXplT2Zmc2V0KHNyYywgbm9kZS5yYW5nZS5lbmQpO1xuICAgICAgY2ggPSBzcmNbb2Zmc2V0XTtcbiAgICAgIGF0TGluZVN0YXJ0ID0gZmFsc2U7XG4gICAgICBwcmV2SW5jbHVkZXNUcmFpbGluZ0xpbmVzID0gbm9kZS5pbmNsdWRlc1RyYWlsaW5nTGluZXM7IC8vIE5lZWQgdG8gcmVzZXQgbGluZVN0YXJ0IGFuZCBhdExpbmVTdGFydCBoZXJlIGlmIHByZWNlZGluZyBub2RlJ3MgcmFuZ2VcbiAgICAgIC8vIGhhcyBhZHZhbmNlZCB0byBjaGVjayB0aGUgY3VycmVudCBsaW5lJ3MgaW5kZW50YXRpb24gbGV2ZWxcbiAgICAgIC8vIC0tIGVlbWVsaS95YW1sIzEwICYgZWVtZWxpL3lhbWwjMzhcblxuICAgICAgaWYgKGNoKSB7XG4gICAgICAgIGxldCBscyA9IG9mZnNldCAtIDE7XG4gICAgICAgIGxldCBwcmV2ID0gc3JjW2xzXTtcblxuICAgICAgICB3aGlsZSAocHJldiA9PT0gJyAnIHx8IHByZXYgPT09ICdcXHQnKSBwcmV2ID0gc3JjWy0tbHNdO1xuXG4gICAgICAgIGlmIChwcmV2ID09PSAnXFxuJykge1xuICAgICAgICAgIGxpbmVTdGFydCA9IGxzICsgMTtcbiAgICAgICAgICBhdExpbmVTdGFydCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgZWMgPSBncmFiQ29sbGVjdGlvbkVuZENvbW1lbnRzKG5vZGUpO1xuICAgICAgaWYgKGVjKSBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseSh0aGlzLml0ZW1zLCBlYyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIHNldE9yaWdSYW5nZXMoY3IsIG9mZnNldCkge1xuICAgIG9mZnNldCA9IHN1cGVyLnNldE9yaWdSYW5nZXMoY3IsIG9mZnNldCk7XG4gICAgdGhpcy5pdGVtcy5mb3JFYWNoKG5vZGUgPT4ge1xuICAgICAgb2Zmc2V0ID0gbm9kZS5zZXRPcmlnUmFuZ2VzKGNyLCBvZmZzZXQpO1xuICAgIH0pO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICB0b1N0cmluZygpIHtcbiAgICBjb25zdCB7XG4gICAgICBjb250ZXh0OiB7XG4gICAgICAgIHNyY1xuICAgICAgfSxcbiAgICAgIGl0ZW1zLFxuICAgICAgcmFuZ2UsXG4gICAgICB2YWx1ZVxuICAgIH0gPSB0aGlzO1xuICAgIGlmICh2YWx1ZSAhPSBudWxsKSByZXR1cm4gdmFsdWU7XG4gICAgbGV0IHN0ciA9IHNyYy5zbGljZShyYW5nZS5zdGFydCwgaXRlbXNbMF0ucmFuZ2Uuc3RhcnQpICsgU3RyaW5nKGl0ZW1zWzBdKTtcblxuICAgIGZvciAobGV0IGkgPSAxOyBpIDwgaXRlbXMubGVuZ3RoOyArK2kpIHtcbiAgICAgIGNvbnN0IGl0ZW0gPSBpdGVtc1tpXTtcbiAgICAgIGNvbnN0IHtcbiAgICAgICAgYXRMaW5lU3RhcnQsXG4gICAgICAgIGluZGVudFxuICAgICAgfSA9IGl0ZW0uY29udGV4dDtcbiAgICAgIGlmIChhdExpbmVTdGFydCkgZm9yIChsZXQgaSA9IDA7IGkgPCBpbmRlbnQ7ICsraSkgc3RyICs9ICcgJztcbiAgICAgIHN0ciArPSBTdHJpbmcoaXRlbSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIE5vZGUuYWRkU3RyaW5nVGVybWluYXRvcihzcmMsIHJhbmdlLmVuZCwgc3RyKTtcbiAgfVxuXG59XG5cbmV4cG9ydCB7IENvbGxlY3Rpb24sIGdyYWJDb2xsZWN0aW9uRW5kQ29tbWVudHMgfTtcbiIsImltcG9ydCB7IFR5cGUgfSBmcm9tICcuLi9jb25zdGFudHMuanMnO1xuaW1wb3J0IHsgTm9kZSB9IGZyb20gJy4vTm9kZS5qcyc7XG5pbXBvcnQgeyBSYW5nZSB9IGZyb20gJy4vUmFuZ2UuanMnO1xuXG5jbGFzcyBEaXJlY3RpdmUgZXh0ZW5kcyBOb2RlIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoVHlwZS5ESVJFQ1RJVkUpO1xuICAgIHRoaXMubmFtZSA9IG51bGw7XG4gIH1cblxuICBnZXQgcGFyYW1ldGVycygpIHtcbiAgICBjb25zdCByYXcgPSB0aGlzLnJhd1ZhbHVlO1xuICAgIHJldHVybiByYXcgPyByYXcudHJpbSgpLnNwbGl0KC9bIFxcdF0rLykgOiBbXTtcbiAgfVxuXG4gIHBhcnNlTmFtZShzdGFydCkge1xuICAgIGNvbnN0IHtcbiAgICAgIHNyY1xuICAgIH0gPSB0aGlzLmNvbnRleHQ7XG4gICAgbGV0IG9mZnNldCA9IHN0YXJ0O1xuICAgIGxldCBjaCA9IHNyY1tvZmZzZXRdO1xuXG4gICAgd2hpbGUgKGNoICYmIGNoICE9PSAnXFxuJyAmJiBjaCAhPT0gJ1xcdCcgJiYgY2ggIT09ICcgJykgY2ggPSBzcmNbb2Zmc2V0ICs9IDFdO1xuXG4gICAgdGhpcy5uYW1lID0gc3JjLnNsaWNlKHN0YXJ0LCBvZmZzZXQpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICBwYXJzZVBhcmFtZXRlcnMoc3RhcnQpIHtcbiAgICBjb25zdCB7XG4gICAgICBzcmNcbiAgICB9ID0gdGhpcy5jb250ZXh0O1xuICAgIGxldCBvZmZzZXQgPSBzdGFydDtcbiAgICBsZXQgY2ggPSBzcmNbb2Zmc2V0XTtcblxuICAgIHdoaWxlIChjaCAmJiBjaCAhPT0gJ1xcbicgJiYgY2ggIT09ICcjJykgY2ggPSBzcmNbb2Zmc2V0ICs9IDFdO1xuXG4gICAgdGhpcy52YWx1ZVJhbmdlID0gbmV3IFJhbmdlKHN0YXJ0LCBvZmZzZXQpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICBwYXJzZShjb250ZXh0LCBzdGFydCkge1xuICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG4gICAgbGV0IG9mZnNldCA9IHRoaXMucGFyc2VOYW1lKHN0YXJ0ICsgMSk7XG4gICAgb2Zmc2V0ID0gdGhpcy5wYXJzZVBhcmFtZXRlcnMob2Zmc2V0KTtcbiAgICBvZmZzZXQgPSB0aGlzLnBhcnNlQ29tbWVudChvZmZzZXQpO1xuICAgIHRoaXMucmFuZ2UgPSBuZXcgUmFuZ2Uoc3RhcnQsIG9mZnNldCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG59XG5cbmV4cG9ydCB7IERpcmVjdGl2ZSB9O1xuIiwiaW1wb3J0IHsgVHlwZSwgQ2hhciB9IGZyb20gJy4uL2NvbnN0YW50cy5qcyc7XG5pbXBvcnQgeyBZQU1MU2VtYW50aWNFcnJvciwgWUFNTFN5bnRheEVycm9yIH0gZnJvbSAnLi4vZXJyb3JzLmpzJztcbmltcG9ydCB7IEJsYW5rTGluZSB9IGZyb20gJy4vQmxhbmtMaW5lLmpzJztcbmltcG9ydCB7IGdyYWJDb2xsZWN0aW9uRW5kQ29tbWVudHMgfSBmcm9tICcuL0NvbGxlY3Rpb24uanMnO1xuaW1wb3J0IHsgQ29tbWVudCB9IGZyb20gJy4vQ29tbWVudC5qcyc7XG5pbXBvcnQgeyBEaXJlY3RpdmUgfSBmcm9tICcuL0RpcmVjdGl2ZS5qcyc7XG5pbXBvcnQgeyBOb2RlIH0gZnJvbSAnLi9Ob2RlLmpzJztcbmltcG9ydCB7IFJhbmdlIH0gZnJvbSAnLi9SYW5nZS5qcyc7XG5cbmNsYXNzIERvY3VtZW50IGV4dGVuZHMgTm9kZSB7XG4gIHN0YXRpYyBzdGFydENvbW1lbnRPckVuZEJsYW5rTGluZShzcmMsIHN0YXJ0KSB7XG4gICAgY29uc3Qgb2Zmc2V0ID0gTm9kZS5lbmRPZldoaXRlU3BhY2Uoc3JjLCBzdGFydCk7XG4gICAgY29uc3QgY2ggPSBzcmNbb2Zmc2V0XTtcbiAgICByZXR1cm4gY2ggPT09ICcjJyB8fCBjaCA9PT0gJ1xcbicgPyBvZmZzZXQgOiBzdGFydDtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKFR5cGUuRE9DVU1FTlQpO1xuICAgIHRoaXMuZGlyZWN0aXZlcyA9IG51bGw7XG4gICAgdGhpcy5jb250ZW50cyA9IG51bGw7XG4gICAgdGhpcy5kaXJlY3RpdmVzRW5kTWFya2VyID0gbnVsbDtcbiAgICB0aGlzLmRvY3VtZW50RW5kTWFya2VyID0gbnVsbDtcbiAgfVxuXG4gIHBhcnNlRGlyZWN0aXZlcyhzdGFydCkge1xuICAgIGNvbnN0IHtcbiAgICAgIHNyY1xuICAgIH0gPSB0aGlzLmNvbnRleHQ7XG4gICAgdGhpcy5kaXJlY3RpdmVzID0gW107XG4gICAgbGV0IGF0TGluZVN0YXJ0ID0gdHJ1ZTtcbiAgICBsZXQgaGFzRGlyZWN0aXZlcyA9IGZhbHNlO1xuICAgIGxldCBvZmZzZXQgPSBzdGFydDtcblxuICAgIHdoaWxlICghTm9kZS5hdERvY3VtZW50Qm91bmRhcnkoc3JjLCBvZmZzZXQsIENoYXIuRElSRUNUSVZFU19FTkQpKSB7XG4gICAgICBvZmZzZXQgPSBEb2N1bWVudC5zdGFydENvbW1lbnRPckVuZEJsYW5rTGluZShzcmMsIG9mZnNldCk7XG5cbiAgICAgIHN3aXRjaCAoc3JjW29mZnNldF0pIHtcbiAgICAgICAgY2FzZSAnXFxuJzpcbiAgICAgICAgICBpZiAoYXRMaW5lU3RhcnQpIHtcbiAgICAgICAgICAgIGNvbnN0IGJsYW5rTGluZSA9IG5ldyBCbGFua0xpbmUoKTtcbiAgICAgICAgICAgIG9mZnNldCA9IGJsYW5rTGluZS5wYXJzZSh7XG4gICAgICAgICAgICAgIHNyY1xuICAgICAgICAgICAgfSwgb2Zmc2V0KTtcblxuICAgICAgICAgICAgaWYgKG9mZnNldCA8IHNyYy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgdGhpcy5kaXJlY3RpdmVzLnB1c2goYmxhbmtMaW5lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgb2Zmc2V0ICs9IDE7XG4gICAgICAgICAgICBhdExpbmVTdGFydCA9IHRydWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSAnIyc6XG4gICAgICAgICAge1xuICAgICAgICAgICAgY29uc3QgY29tbWVudCA9IG5ldyBDb21tZW50KCk7XG4gICAgICAgICAgICBvZmZzZXQgPSBjb21tZW50LnBhcnNlKHtcbiAgICAgICAgICAgICAgc3JjXG4gICAgICAgICAgICB9LCBvZmZzZXQpO1xuICAgICAgICAgICAgdGhpcy5kaXJlY3RpdmVzLnB1c2goY29tbWVudCk7XG4gICAgICAgICAgICBhdExpbmVTdGFydCA9IGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlICclJzpcbiAgICAgICAgICB7XG4gICAgICAgICAgICBjb25zdCBkaXJlY3RpdmUgPSBuZXcgRGlyZWN0aXZlKCk7XG4gICAgICAgICAgICBvZmZzZXQgPSBkaXJlY3RpdmUucGFyc2Uoe1xuICAgICAgICAgICAgICBwYXJlbnQ6IHRoaXMsXG4gICAgICAgICAgICAgIHNyY1xuICAgICAgICAgICAgfSwgb2Zmc2V0KTtcbiAgICAgICAgICAgIHRoaXMuZGlyZWN0aXZlcy5wdXNoKGRpcmVjdGl2ZSk7XG4gICAgICAgICAgICBoYXNEaXJlY3RpdmVzID0gdHJ1ZTtcbiAgICAgICAgICAgIGF0TGluZVN0YXJ0ID0gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgaWYgKGhhc0RpcmVjdGl2ZXMpIHtcbiAgICAgICAgICAgIHRoaXMuZXJyb3IgPSBuZXcgWUFNTFNlbWFudGljRXJyb3IodGhpcywgJ01pc3NpbmcgZGlyZWN0aXZlcy1lbmQgaW5kaWNhdG9yIGxpbmUnKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuZGlyZWN0aXZlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLmNvbnRlbnRzID0gdGhpcy5kaXJlY3RpdmVzO1xuICAgICAgICAgICAgdGhpcy5kaXJlY3RpdmVzID0gW107XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIG9mZnNldDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc3JjW29mZnNldF0pIHtcbiAgICAgIHRoaXMuZGlyZWN0aXZlc0VuZE1hcmtlciA9IG5ldyBSYW5nZShvZmZzZXQsIG9mZnNldCArIDMpO1xuICAgICAgcmV0dXJuIG9mZnNldCArIDM7XG4gICAgfVxuXG4gICAgaWYgKGhhc0RpcmVjdGl2ZXMpIHtcbiAgICAgIHRoaXMuZXJyb3IgPSBuZXcgWUFNTFNlbWFudGljRXJyb3IodGhpcywgJ01pc3NpbmcgZGlyZWN0aXZlcy1lbmQgaW5kaWNhdG9yIGxpbmUnKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuZGlyZWN0aXZlcy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLmNvbnRlbnRzID0gdGhpcy5kaXJlY3RpdmVzO1xuICAgICAgdGhpcy5kaXJlY3RpdmVzID0gW107XG4gICAgfVxuXG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG4gIHBhcnNlQ29udGVudHMoc3RhcnQpIHtcbiAgICBjb25zdCB7XG4gICAgICBwYXJzZU5vZGUsXG4gICAgICBzcmNcbiAgICB9ID0gdGhpcy5jb250ZXh0O1xuICAgIGlmICghdGhpcy5jb250ZW50cykgdGhpcy5jb250ZW50cyA9IFtdO1xuICAgIGxldCBsaW5lU3RhcnQgPSBzdGFydDtcblxuICAgIHdoaWxlIChzcmNbbGluZVN0YXJ0IC0gMV0gPT09ICctJykgbGluZVN0YXJ0IC09IDE7XG5cbiAgICBsZXQgb2Zmc2V0ID0gTm9kZS5lbmRPZldoaXRlU3BhY2Uoc3JjLCBzdGFydCk7XG4gICAgbGV0IGF0TGluZVN0YXJ0ID0gbGluZVN0YXJ0ID09PSBzdGFydDtcbiAgICB0aGlzLnZhbHVlUmFuZ2UgPSBuZXcgUmFuZ2Uob2Zmc2V0KTtcblxuICAgIHdoaWxlICghTm9kZS5hdERvY3VtZW50Qm91bmRhcnkoc3JjLCBvZmZzZXQsIENoYXIuRE9DVU1FTlRfRU5EKSkge1xuICAgICAgc3dpdGNoIChzcmNbb2Zmc2V0XSkge1xuICAgICAgICBjYXNlICdcXG4nOlxuICAgICAgICAgIGlmIChhdExpbmVTdGFydCkge1xuICAgICAgICAgICAgY29uc3QgYmxhbmtMaW5lID0gbmV3IEJsYW5rTGluZSgpO1xuICAgICAgICAgICAgb2Zmc2V0ID0gYmxhbmtMaW5lLnBhcnNlKHtcbiAgICAgICAgICAgICAgc3JjXG4gICAgICAgICAgICB9LCBvZmZzZXQpO1xuXG4gICAgICAgICAgICBpZiAob2Zmc2V0IDwgc3JjLmxlbmd0aCkge1xuICAgICAgICAgICAgICB0aGlzLmNvbnRlbnRzLnB1c2goYmxhbmtMaW5lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgb2Zmc2V0ICs9IDE7XG4gICAgICAgICAgICBhdExpbmVTdGFydCA9IHRydWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgbGluZVN0YXJ0ID0gb2Zmc2V0O1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgJyMnOlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGNvbnN0IGNvbW1lbnQgPSBuZXcgQ29tbWVudCgpO1xuICAgICAgICAgICAgb2Zmc2V0ID0gY29tbWVudC5wYXJzZSh7XG4gICAgICAgICAgICAgIHNyY1xuICAgICAgICAgICAgfSwgb2Zmc2V0KTtcbiAgICAgICAgICAgIHRoaXMuY29udGVudHMucHVzaChjb21tZW50KTtcbiAgICAgICAgICAgIGF0TGluZVN0YXJ0ID0gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAge1xuICAgICAgICAgICAgY29uc3QgaUVuZCA9IE5vZGUuZW5kT2ZJbmRlbnQoc3JjLCBvZmZzZXQpO1xuICAgICAgICAgICAgY29uc3QgY29udGV4dCA9IHtcbiAgICAgICAgICAgICAgYXRMaW5lU3RhcnQsXG4gICAgICAgICAgICAgIGluZGVudDogLTEsXG4gICAgICAgICAgICAgIGluRmxvdzogZmFsc2UsXG4gICAgICAgICAgICAgIGluQ29sbGVjdGlvbjogZmFsc2UsXG4gICAgICAgICAgICAgIGxpbmVTdGFydCxcbiAgICAgICAgICAgICAgcGFyZW50OiB0aGlzXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3Qgbm9kZSA9IHBhcnNlTm9kZShjb250ZXh0LCBpRW5kKTtcbiAgICAgICAgICAgIGlmICghbm9kZSkgcmV0dXJuIHRoaXMudmFsdWVSYW5nZS5lbmQgPSBpRW5kOyAvLyBhdCBuZXh0IGRvY3VtZW50IHN0YXJ0XG5cbiAgICAgICAgICAgIHRoaXMuY29udGVudHMucHVzaChub2RlKTtcbiAgICAgICAgICAgIG9mZnNldCA9IG5vZGUucmFuZ2UuZW5kO1xuICAgICAgICAgICAgYXRMaW5lU3RhcnQgPSBmYWxzZTtcbiAgICAgICAgICAgIGNvbnN0IGVjID0gZ3JhYkNvbGxlY3Rpb25FbmRDb21tZW50cyhub2RlKTtcbiAgICAgICAgICAgIGlmIChlYykgQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkodGhpcy5jb250ZW50cywgZWMpO1xuICAgICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgb2Zmc2V0ID0gRG9jdW1lbnQuc3RhcnRDb21tZW50T3JFbmRCbGFua0xpbmUoc3JjLCBvZmZzZXQpO1xuICAgIH1cblxuICAgIHRoaXMudmFsdWVSYW5nZS5lbmQgPSBvZmZzZXQ7XG5cbiAgICBpZiAoc3JjW29mZnNldF0pIHtcbiAgICAgIHRoaXMuZG9jdW1lbnRFbmRNYXJrZXIgPSBuZXcgUmFuZ2Uob2Zmc2V0LCBvZmZzZXQgKyAzKTtcbiAgICAgIG9mZnNldCArPSAzO1xuXG4gICAgICBpZiAoc3JjW29mZnNldF0pIHtcbiAgICAgICAgb2Zmc2V0ID0gTm9kZS5lbmRPZldoaXRlU3BhY2Uoc3JjLCBvZmZzZXQpO1xuXG4gICAgICAgIGlmIChzcmNbb2Zmc2V0XSA9PT0gJyMnKSB7XG4gICAgICAgICAgY29uc3QgY29tbWVudCA9IG5ldyBDb21tZW50KCk7XG4gICAgICAgICAgb2Zmc2V0ID0gY29tbWVudC5wYXJzZSh7XG4gICAgICAgICAgICBzcmNcbiAgICAgICAgICB9LCBvZmZzZXQpO1xuICAgICAgICAgIHRoaXMuY29udGVudHMucHVzaChjb21tZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHN3aXRjaCAoc3JjW29mZnNldF0pIHtcbiAgICAgICAgICBjYXNlICdcXG4nOlxuICAgICAgICAgICAgb2Zmc2V0ICs9IDE7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgdW5kZWZpbmVkOlxuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgdGhpcy5lcnJvciA9IG5ldyBZQU1MU3ludGF4RXJyb3IodGhpcywgJ0RvY3VtZW50IGVuZCBtYXJrZXIgbGluZSBjYW5ub3QgaGF2ZSBhIG5vbi1jb21tZW50IHN1ZmZpeCcpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuICAvKipcbiAgICogQHBhcmFtIHtQYXJzZUNvbnRleHR9IGNvbnRleHRcbiAgICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0IC0gSW5kZXggb2YgZmlyc3QgY2hhcmFjdGVyXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IC0gSW5kZXggb2YgdGhlIGNoYXJhY3RlciBhZnRlciB0aGlzXG4gICAqL1xuXG5cbiAgcGFyc2UoY29udGV4dCwgc3RhcnQpIHtcbiAgICBjb250ZXh0LnJvb3QgPSB0aGlzO1xuICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG4gICAgY29uc3Qge1xuICAgICAgc3JjXG4gICAgfSA9IGNvbnRleHQ7XG4gICAgbGV0IG9mZnNldCA9IHNyYy5jaGFyQ29kZUF0KHN0YXJ0KSA9PT0gMHhmZWZmID8gc3RhcnQgKyAxIDogc3RhcnQ7IC8vIHNraXAgQk9NXG5cbiAgICBvZmZzZXQgPSB0aGlzLnBhcnNlRGlyZWN0aXZlcyhvZmZzZXQpO1xuICAgIG9mZnNldCA9IHRoaXMucGFyc2VDb250ZW50cyhvZmZzZXQpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICBzZXRPcmlnUmFuZ2VzKGNyLCBvZmZzZXQpIHtcbiAgICBvZmZzZXQgPSBzdXBlci5zZXRPcmlnUmFuZ2VzKGNyLCBvZmZzZXQpO1xuICAgIHRoaXMuZGlyZWN0aXZlcy5mb3JFYWNoKG5vZGUgPT4ge1xuICAgICAgb2Zmc2V0ID0gbm9kZS5zZXRPcmlnUmFuZ2VzKGNyLCBvZmZzZXQpO1xuICAgIH0pO1xuICAgIGlmICh0aGlzLmRpcmVjdGl2ZXNFbmRNYXJrZXIpIG9mZnNldCA9IHRoaXMuZGlyZWN0aXZlc0VuZE1hcmtlci5zZXRPcmlnUmFuZ2UoY3IsIG9mZnNldCk7XG4gICAgdGhpcy5jb250ZW50cy5mb3JFYWNoKG5vZGUgPT4ge1xuICAgICAgb2Zmc2V0ID0gbm9kZS5zZXRPcmlnUmFuZ2VzKGNyLCBvZmZzZXQpO1xuICAgIH0pO1xuICAgIGlmICh0aGlzLmRvY3VtZW50RW5kTWFya2VyKSBvZmZzZXQgPSB0aGlzLmRvY3VtZW50RW5kTWFya2VyLnNldE9yaWdSYW5nZShjciwgb2Zmc2V0KTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG5cbiAgdG9TdHJpbmcoKSB7XG4gICAgY29uc3Qge1xuICAgICAgY29udGVudHMsXG4gICAgICBkaXJlY3RpdmVzLFxuICAgICAgdmFsdWVcbiAgICB9ID0gdGhpcztcbiAgICBpZiAodmFsdWUgIT0gbnVsbCkgcmV0dXJuIHZhbHVlO1xuICAgIGxldCBzdHIgPSBkaXJlY3RpdmVzLmpvaW4oJycpO1xuXG4gICAgaWYgKGNvbnRlbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgIGlmIChkaXJlY3RpdmVzLmxlbmd0aCA+IDAgfHwgY29udGVudHNbMF0udHlwZSA9PT0gVHlwZS5DT01NRU5UKSBzdHIgKz0gJy0tLVxcbic7XG4gICAgICBzdHIgKz0gY29udGVudHMuam9pbignJyk7XG4gICAgfVxuXG4gICAgaWYgKHN0cltzdHIubGVuZ3RoIC0gMV0gIT09ICdcXG4nKSBzdHIgKz0gJ1xcbic7XG4gICAgcmV0dXJuIHN0cjtcbiAgfVxuXG59XG5cbmV4cG9ydCB7IERvY3VtZW50IH07XG4iLCJmdW5jdGlvbiBfZGVmaW5lUHJvcGVydHkob2JqLCBrZXksIHZhbHVlKSB7XG4gIGlmIChrZXkgaW4gb2JqKSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG9iaiwga2V5LCB7XG4gICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgd3JpdGFibGU6IHRydWVcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBvYmpba2V5XSA9IHZhbHVlO1xuICB9XG5cbiAgcmV0dXJuIG9iajtcbn1cblxuZXhwb3J0IHsgX2RlZmluZVByb3BlcnR5IGFzIGRlZmluZVByb3BlcnR5IH07XG4iLCJpbXBvcnQgeyBOb2RlIH0gZnJvbSAnLi9Ob2RlLmpzJztcbmltcG9ydCB7IFJhbmdlIH0gZnJvbSAnLi9SYW5nZS5qcyc7XG5cbmNsYXNzIEFsaWFzIGV4dGVuZHMgTm9kZSB7XG4gIC8qKlxuICAgKiBQYXJzZXMgYW4gKmFsaWFzIGZyb20gdGhlIHNvdXJjZVxuICAgKlxuICAgKiBAcGFyYW0ge1BhcnNlQ29udGV4dH0gY29udGV4dFxuICAgKiBAcGFyYW0ge251bWJlcn0gc3RhcnQgLSBJbmRleCBvZiBmaXJzdCBjaGFyYWN0ZXJcbiAgICogQHJldHVybnMge251bWJlcn0gLSBJbmRleCBvZiB0aGUgY2hhcmFjdGVyIGFmdGVyIHRoaXMgc2NhbGFyXG4gICAqL1xuICBwYXJzZShjb250ZXh0LCBzdGFydCkge1xuICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG4gICAgY29uc3Qge1xuICAgICAgc3JjXG4gICAgfSA9IGNvbnRleHQ7XG4gICAgbGV0IG9mZnNldCA9IE5vZGUuZW5kT2ZJZGVudGlmaWVyKHNyYywgc3RhcnQgKyAxKTtcbiAgICB0aGlzLnZhbHVlUmFuZ2UgPSBuZXcgUmFuZ2Uoc3RhcnQgKyAxLCBvZmZzZXQpO1xuICAgIG9mZnNldCA9IE5vZGUuZW5kT2ZXaGl0ZVNwYWNlKHNyYywgb2Zmc2V0KTtcbiAgICBvZmZzZXQgPSB0aGlzLnBhcnNlQ29tbWVudChvZmZzZXQpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxufVxuXG5leHBvcnQgeyBBbGlhcyB9O1xuIiwiaW1wb3J0IHsgVHlwZSB9IGZyb20gJy4uL2NvbnN0YW50cy5qcyc7XG5pbXBvcnQgeyBZQU1MU2VtYW50aWNFcnJvciB9IGZyb20gJy4uL2Vycm9ycy5qcyc7XG5pbXBvcnQgeyBOb2RlIH0gZnJvbSAnLi9Ob2RlLmpzJztcbmltcG9ydCB7IFJhbmdlIH0gZnJvbSAnLi9SYW5nZS5qcyc7XG5cbmNvbnN0IENob21wID0ge1xuICBDTElQOiAnQ0xJUCcsXG4gIEtFRVA6ICdLRUVQJyxcbiAgU1RSSVA6ICdTVFJJUCdcbn07XG5jbGFzcyBCbG9ja1ZhbHVlIGV4dGVuZHMgTm9kZSB7XG4gIGNvbnN0cnVjdG9yKHR5cGUsIHByb3BzKSB7XG4gICAgc3VwZXIodHlwZSwgcHJvcHMpO1xuICAgIHRoaXMuYmxvY2tJbmRlbnQgPSBudWxsO1xuICAgIHRoaXMuY2hvbXBpbmcgPSBDaG9tcC5DTElQO1xuICAgIHRoaXMuaGVhZGVyID0gbnVsbDtcbiAgfVxuXG4gIGdldCBpbmNsdWRlc1RyYWlsaW5nTGluZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2hvbXBpbmcgPT09IENob21wLktFRVA7XG4gIH1cblxuICBnZXQgc3RyVmFsdWUoKSB7XG4gICAgaWYgKCF0aGlzLnZhbHVlUmFuZ2UgfHwgIXRoaXMuY29udGV4dCkgcmV0dXJuIG51bGw7XG4gICAgbGV0IHtcbiAgICAgIHN0YXJ0LFxuICAgICAgZW5kXG4gICAgfSA9IHRoaXMudmFsdWVSYW5nZTtcbiAgICBjb25zdCB7XG4gICAgICBpbmRlbnQsXG4gICAgICBzcmNcbiAgICB9ID0gdGhpcy5jb250ZXh0O1xuICAgIGlmICh0aGlzLnZhbHVlUmFuZ2UuaXNFbXB0eSgpKSByZXR1cm4gJyc7XG4gICAgbGV0IGxhc3ROZXdMaW5lID0gbnVsbDtcbiAgICBsZXQgY2ggPSBzcmNbZW5kIC0gMV07XG5cbiAgICB3aGlsZSAoY2ggPT09ICdcXG4nIHx8IGNoID09PSAnXFx0JyB8fCBjaCA9PT0gJyAnKSB7XG4gICAgICBlbmQgLT0gMTtcblxuICAgICAgaWYgKGVuZCA8PSBzdGFydCkge1xuICAgICAgICBpZiAodGhpcy5jaG9tcGluZyA9PT0gQ2hvbXAuS0VFUCkgYnJlYWs7ZWxzZSByZXR1cm4gJyc7IC8vIHByb2JhYmx5IG5ldmVyIGhhcHBlbnNcbiAgICAgIH1cblxuICAgICAgaWYgKGNoID09PSAnXFxuJykgbGFzdE5ld0xpbmUgPSBlbmQ7XG4gICAgICBjaCA9IHNyY1tlbmQgLSAxXTtcbiAgICB9XG5cbiAgICBsZXQga2VlcFN0YXJ0ID0gZW5kICsgMTtcblxuICAgIGlmIChsYXN0TmV3TGluZSkge1xuICAgICAgaWYgKHRoaXMuY2hvbXBpbmcgPT09IENob21wLktFRVApIHtcbiAgICAgICAga2VlcFN0YXJ0ID0gbGFzdE5ld0xpbmU7XG4gICAgICAgIGVuZCA9IHRoaXMudmFsdWVSYW5nZS5lbmQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbmQgPSBsYXN0TmV3TGluZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBiaSA9IGluZGVudCArIHRoaXMuYmxvY2tJbmRlbnQ7XG4gICAgY29uc3QgZm9sZGVkID0gdGhpcy50eXBlID09PSBUeXBlLkJMT0NLX0ZPTERFRDtcbiAgICBsZXQgYXRTdGFydCA9IHRydWU7XG4gICAgbGV0IHN0ciA9ICcnO1xuICAgIGxldCBzZXAgPSAnJztcbiAgICBsZXQgcHJldk1vcmVJbmRlbnRlZCA9IGZhbHNlO1xuXG4gICAgZm9yIChsZXQgaSA9IHN0YXJ0OyBpIDwgZW5kOyArK2kpIHtcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgYmk7ICsraikge1xuICAgICAgICBpZiAoc3JjW2ldICE9PSAnICcpIGJyZWFrO1xuICAgICAgICBpICs9IDE7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNoID0gc3JjW2ldO1xuXG4gICAgICBpZiAoY2ggPT09ICdcXG4nKSB7XG4gICAgICAgIGlmIChzZXAgPT09ICdcXG4nKSBzdHIgKz0gJ1xcbic7ZWxzZSBzZXAgPSAnXFxuJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGxpbmVFbmQgPSBOb2RlLmVuZE9mTGluZShzcmMsIGkpO1xuICAgICAgICBjb25zdCBsaW5lID0gc3JjLnNsaWNlKGksIGxpbmVFbmQpO1xuICAgICAgICBpID0gbGluZUVuZDtcblxuICAgICAgICBpZiAoZm9sZGVkICYmIChjaCA9PT0gJyAnIHx8IGNoID09PSAnXFx0JykgJiYgaSA8IGtlZXBTdGFydCkge1xuICAgICAgICAgIGlmIChzZXAgPT09ICcgJykgc2VwID0gJ1xcbic7ZWxzZSBpZiAoIXByZXZNb3JlSW5kZW50ZWQgJiYgIWF0U3RhcnQgJiYgc2VwID09PSAnXFxuJykgc2VwID0gJ1xcblxcbic7XG4gICAgICAgICAgc3RyICs9IHNlcCArIGxpbmU7IC8vKyAoKGxpbmVFbmQgPCBlbmQgJiYgc3JjW2xpbmVFbmRdKSB8fCAnJylcblxuICAgICAgICAgIHNlcCA9IGxpbmVFbmQgPCBlbmQgJiYgc3JjW2xpbmVFbmRdIHx8ICcnO1xuICAgICAgICAgIHByZXZNb3JlSW5kZW50ZWQgPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN0ciArPSBzZXAgKyBsaW5lO1xuICAgICAgICAgIHNlcCA9IGZvbGRlZCAmJiBpIDwga2VlcFN0YXJ0ID8gJyAnIDogJ1xcbic7XG4gICAgICAgICAgcHJldk1vcmVJbmRlbnRlZCA9IGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGF0U3RhcnQgJiYgbGluZSAhPT0gJycpIGF0U3RhcnQgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5jaG9tcGluZyA9PT0gQ2hvbXAuU1RSSVAgPyBzdHIgOiBzdHIgKyAnXFxuJztcbiAgfVxuXG4gIHBhcnNlQmxvY2tIZWFkZXIoc3RhcnQpIHtcbiAgICBjb25zdCB7XG4gICAgICBzcmNcbiAgICB9ID0gdGhpcy5jb250ZXh0O1xuICAgIGxldCBvZmZzZXQgPSBzdGFydCArIDE7XG4gICAgbGV0IGJpID0gJyc7XG5cbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgY29uc3QgY2ggPSBzcmNbb2Zmc2V0XTtcblxuICAgICAgc3dpdGNoIChjaCkge1xuICAgICAgICBjYXNlICctJzpcbiAgICAgICAgICB0aGlzLmNob21waW5nID0gQ2hvbXAuU1RSSVA7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSAnKyc6XG4gICAgICAgICAgdGhpcy5jaG9tcGluZyA9IENob21wLktFRVA7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSAnMCc6XG4gICAgICAgIGNhc2UgJzEnOlxuICAgICAgICBjYXNlICcyJzpcbiAgICAgICAgY2FzZSAnMyc6XG4gICAgICAgIGNhc2UgJzQnOlxuICAgICAgICBjYXNlICc1JzpcbiAgICAgICAgY2FzZSAnNic6XG4gICAgICAgIGNhc2UgJzcnOlxuICAgICAgICBjYXNlICc4JzpcbiAgICAgICAgY2FzZSAnOSc6XG4gICAgICAgICAgYmkgKz0gY2g7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aGlzLmJsb2NrSW5kZW50ID0gTnVtYmVyKGJpKSB8fCBudWxsO1xuICAgICAgICAgIHRoaXMuaGVhZGVyID0gbmV3IFJhbmdlKHN0YXJ0LCBvZmZzZXQpO1xuICAgICAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgICB9XG5cbiAgICAgIG9mZnNldCArPSAxO1xuICAgIH1cbiAgfVxuXG4gIHBhcnNlQmxvY2tWYWx1ZShzdGFydCkge1xuICAgIGNvbnN0IHtcbiAgICAgIGluZGVudCxcbiAgICAgIHNyY1xuICAgIH0gPSB0aGlzLmNvbnRleHQ7XG4gICAgY29uc3QgZXhwbGljaXQgPSAhIXRoaXMuYmxvY2tJbmRlbnQ7XG4gICAgbGV0IG9mZnNldCA9IHN0YXJ0O1xuICAgIGxldCB2YWx1ZUVuZCA9IHN0YXJ0O1xuICAgIGxldCBtaW5CbG9ja0luZGVudCA9IDE7XG5cbiAgICBmb3IgKGxldCBjaCA9IHNyY1tvZmZzZXRdOyBjaCA9PT0gJ1xcbic7IGNoID0gc3JjW29mZnNldF0pIHtcbiAgICAgIG9mZnNldCArPSAxO1xuICAgICAgaWYgKE5vZGUuYXREb2N1bWVudEJvdW5kYXJ5KHNyYywgb2Zmc2V0KSkgYnJlYWs7XG4gICAgICBjb25zdCBlbmQgPSBOb2RlLmVuZE9mQmxvY2tJbmRlbnQoc3JjLCBpbmRlbnQsIG9mZnNldCk7IC8vIHNob3VsZCBub3QgaW5jbHVkZSB0YWI/XG5cbiAgICAgIGlmIChlbmQgPT09IG51bGwpIGJyZWFrO1xuICAgICAgY29uc3QgY2ggPSBzcmNbZW5kXTtcbiAgICAgIGNvbnN0IGxpbmVJbmRlbnQgPSBlbmQgLSAob2Zmc2V0ICsgaW5kZW50KTtcblxuICAgICAgaWYgKCF0aGlzLmJsb2NrSW5kZW50KSB7XG4gICAgICAgIC8vIG5vIGV4cGxpY2l0IGJsb2NrIGluZGVudCwgbm9uZSB5ZXQgZGV0ZWN0ZWRcbiAgICAgICAgaWYgKHNyY1tlbmRdICE9PSAnXFxuJykge1xuICAgICAgICAgIC8vIGZpcnN0IGxpbmUgd2l0aCBub24td2hpdGVzcGFjZSBjb250ZW50XG4gICAgICAgICAgaWYgKGxpbmVJbmRlbnQgPCBtaW5CbG9ja0luZGVudCkge1xuICAgICAgICAgICAgY29uc3QgbXNnID0gJ0Jsb2NrIHNjYWxhcnMgd2l0aCBtb3JlLWluZGVudGVkIGxlYWRpbmcgZW1wdHkgbGluZXMgbXVzdCB1c2UgYW4gZXhwbGljaXQgaW5kZW50YXRpb24gaW5kaWNhdG9yJztcbiAgICAgICAgICAgIHRoaXMuZXJyb3IgPSBuZXcgWUFNTFNlbWFudGljRXJyb3IodGhpcywgbXNnKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLmJsb2NrSW5kZW50ID0gbGluZUluZGVudDtcbiAgICAgICAgfSBlbHNlIGlmIChsaW5lSW5kZW50ID4gbWluQmxvY2tJbmRlbnQpIHtcbiAgICAgICAgICAvLyBlbXB0eSBsaW5lIHdpdGggbW9yZSB3aGl0ZXNwYWNlXG4gICAgICAgICAgbWluQmxvY2tJbmRlbnQgPSBsaW5lSW5kZW50O1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGNoICYmIGNoICE9PSAnXFxuJyAmJiBsaW5lSW5kZW50IDwgdGhpcy5ibG9ja0luZGVudCkge1xuICAgICAgICBpZiAoc3JjW2VuZF0gPT09ICcjJykgYnJlYWs7XG5cbiAgICAgICAgaWYgKCF0aGlzLmVycm9yKSB7XG4gICAgICAgICAgY29uc3Qgc3JjID0gZXhwbGljaXQgPyAnZXhwbGljaXQgaW5kZW50YXRpb24gaW5kaWNhdG9yJyA6ICdmaXJzdCBsaW5lJztcbiAgICAgICAgICBjb25zdCBtc2cgPSBcIkJsb2NrIHNjYWxhcnMgbXVzdCBub3QgYmUgbGVzcyBpbmRlbnRlZCB0aGFuIHRoZWlyIFwiLmNvbmNhdChzcmMpO1xuICAgICAgICAgIHRoaXMuZXJyb3IgPSBuZXcgWUFNTFNlbWFudGljRXJyb3IodGhpcywgbXNnKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoc3JjW2VuZF0gPT09ICdcXG4nKSB7XG4gICAgICAgIG9mZnNldCA9IGVuZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG9mZnNldCA9IHZhbHVlRW5kID0gTm9kZS5lbmRPZkxpbmUoc3JjLCBlbmQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLmNob21waW5nICE9PSBDaG9tcC5LRUVQKSB7XG4gICAgICBvZmZzZXQgPSBzcmNbdmFsdWVFbmRdID8gdmFsdWVFbmQgKyAxIDogdmFsdWVFbmQ7XG4gICAgfVxuXG4gICAgdGhpcy52YWx1ZVJhbmdlID0gbmV3IFJhbmdlKHN0YXJ0ICsgMSwgb2Zmc2V0KTtcbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG4gIC8qKlxuICAgKiBQYXJzZXMgYSBibG9jayB2YWx1ZSBmcm9tIHRoZSBzb3VyY2VcbiAgICpcbiAgICogQWNjZXB0ZWQgZm9ybXMgYXJlOlxuICAgKiBgYGBcbiAgICogQlNcbiAgICogYmxvY2tcbiAgICogbGluZXNcbiAgICpcbiAgICogQlMgI2NvbW1lbnRcbiAgICogYmxvY2tcbiAgICogbGluZXNcbiAgICogYGBgXG4gICAqIHdoZXJlIHRoZSBibG9jayBzdHlsZSBCUyBtYXRjaGVzIHRoZSByZWdleHAgYFt8Pl1bLSsxLTldKmAgYW5kIGJsb2NrIGxpbmVzXG4gICAqIGFyZSBlbXB0eSBvciBoYXZlIGFuIGluZGVudCBsZXZlbCBncmVhdGVyIHRoYW4gYGluZGVudGAuXG4gICAqXG4gICAqIEBwYXJhbSB7UGFyc2VDb250ZXh0fSBjb250ZXh0XG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydCAtIEluZGV4IG9mIGZpcnN0IGNoYXJhY3RlclxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSAtIEluZGV4IG9mIHRoZSBjaGFyYWN0ZXIgYWZ0ZXIgdGhpcyBibG9ja1xuICAgKi9cblxuXG4gIHBhcnNlKGNvbnRleHQsIHN0YXJ0KSB7XG4gICAgdGhpcy5jb250ZXh0ID0gY29udGV4dDtcbiAgICBjb25zdCB7XG4gICAgICBzcmNcbiAgICB9ID0gY29udGV4dDtcbiAgICBsZXQgb2Zmc2V0ID0gdGhpcy5wYXJzZUJsb2NrSGVhZGVyKHN0YXJ0KTtcbiAgICBvZmZzZXQgPSBOb2RlLmVuZE9mV2hpdGVTcGFjZShzcmMsIG9mZnNldCk7XG4gICAgb2Zmc2V0ID0gdGhpcy5wYXJzZUNvbW1lbnQob2Zmc2V0KTtcbiAgICBvZmZzZXQgPSB0aGlzLnBhcnNlQmxvY2tWYWx1ZShvZmZzZXQpO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICBzZXRPcmlnUmFuZ2VzKGNyLCBvZmZzZXQpIHtcbiAgICBvZmZzZXQgPSBzdXBlci5zZXRPcmlnUmFuZ2VzKGNyLCBvZmZzZXQpO1xuICAgIHJldHVybiB0aGlzLmhlYWRlciA/IHRoaXMuaGVhZGVyLnNldE9yaWdSYW5nZShjciwgb2Zmc2V0KSA6IG9mZnNldDtcbiAgfVxuXG59XG5cbmV4cG9ydCB7IEJsb2NrVmFsdWUsIENob21wIH07XG4iLCJpbXBvcnQgeyBUeXBlIH0gZnJvbSAnLi4vY29uc3RhbnRzLmpzJztcbmltcG9ydCB7IFlBTUxTZW1hbnRpY0Vycm9yIH0gZnJvbSAnLi4vZXJyb3JzLmpzJztcbmltcG9ydCB7IEJsYW5rTGluZSB9IGZyb20gJy4vQmxhbmtMaW5lLmpzJztcbmltcG9ydCB7IENvbW1lbnQgfSBmcm9tICcuL0NvbW1lbnQuanMnO1xuaW1wb3J0IHsgTm9kZSB9IGZyb20gJy4vTm9kZS5qcyc7XG5pbXBvcnQgeyBSYW5nZSB9IGZyb20gJy4vUmFuZ2UuanMnO1xuXG5jbGFzcyBGbG93Q29sbGVjdGlvbiBleHRlbmRzIE5vZGUge1xuICBjb25zdHJ1Y3Rvcih0eXBlLCBwcm9wcykge1xuICAgIHN1cGVyKHR5cGUsIHByb3BzKTtcbiAgICB0aGlzLml0ZW1zID0gbnVsbDtcbiAgfVxuXG4gIHByZXZOb2RlSXNKc29uTGlrZShpZHggPSB0aGlzLml0ZW1zLmxlbmd0aCkge1xuICAgIGNvbnN0IG5vZGUgPSB0aGlzLml0ZW1zW2lkeCAtIDFdO1xuICAgIHJldHVybiAhIW5vZGUgJiYgKG5vZGUuanNvbkxpa2UgfHwgbm9kZS50eXBlID09PSBUeXBlLkNPTU1FTlQgJiYgdGhpcy5wcmV2Tm9kZUlzSnNvbkxpa2UoaWR4IC0gMSkpO1xuICB9XG4gIC8qKlxuICAgKiBAcGFyYW0ge1BhcnNlQ29udGV4dH0gY29udGV4dFxuICAgKiBAcGFyYW0ge251bWJlcn0gc3RhcnQgLSBJbmRleCBvZiBmaXJzdCBjaGFyYWN0ZXJcbiAgICogQHJldHVybnMge251bWJlcn0gLSBJbmRleCBvZiB0aGUgY2hhcmFjdGVyIGFmdGVyIHRoaXNcbiAgICovXG5cblxuICBwYXJzZShjb250ZXh0LCBzdGFydCkge1xuICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG4gICAgY29uc3Qge1xuICAgICAgcGFyc2VOb2RlLFxuICAgICAgc3JjXG4gICAgfSA9IGNvbnRleHQ7XG4gICAgbGV0IHtcbiAgICAgIGluZGVudCxcbiAgICAgIGxpbmVTdGFydFxuICAgIH0gPSBjb250ZXh0O1xuICAgIGxldCBjaGFyID0gc3JjW3N0YXJ0XTsgLy8geyBvciBbXG5cbiAgICB0aGlzLml0ZW1zID0gW3tcbiAgICAgIGNoYXIsXG4gICAgICBvZmZzZXQ6IHN0YXJ0XG4gICAgfV07XG4gICAgbGV0IG9mZnNldCA9IE5vZGUuZW5kT2ZXaGl0ZVNwYWNlKHNyYywgc3RhcnQgKyAxKTtcbiAgICBjaGFyID0gc3JjW29mZnNldF07XG5cbiAgICB3aGlsZSAoY2hhciAmJiBjaGFyICE9PSAnXScgJiYgY2hhciAhPT0gJ30nKSB7XG4gICAgICBzd2l0Y2ggKGNoYXIpIHtcbiAgICAgICAgY2FzZSAnXFxuJzpcbiAgICAgICAgICB7XG4gICAgICAgICAgICBsaW5lU3RhcnQgPSBvZmZzZXQgKyAxO1xuICAgICAgICAgICAgY29uc3Qgd3NFbmQgPSBOb2RlLmVuZE9mV2hpdGVTcGFjZShzcmMsIGxpbmVTdGFydCk7XG5cbiAgICAgICAgICAgIGlmIChzcmNbd3NFbmRdID09PSAnXFxuJykge1xuICAgICAgICAgICAgICBjb25zdCBibGFua0xpbmUgPSBuZXcgQmxhbmtMaW5lKCk7XG4gICAgICAgICAgICAgIGxpbmVTdGFydCA9IGJsYW5rTGluZS5wYXJzZSh7XG4gICAgICAgICAgICAgICAgc3JjXG4gICAgICAgICAgICAgIH0sIGxpbmVTdGFydCk7XG4gICAgICAgICAgICAgIHRoaXMuaXRlbXMucHVzaChibGFua0xpbmUpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBvZmZzZXQgPSBOb2RlLmVuZE9mSW5kZW50KHNyYywgbGluZVN0YXJ0KTtcblxuICAgICAgICAgICAgaWYgKG9mZnNldCA8PSBsaW5lU3RhcnQgKyBpbmRlbnQpIHtcbiAgICAgICAgICAgICAgY2hhciA9IHNyY1tvZmZzZXRdO1xuXG4gICAgICAgICAgICAgIGlmIChvZmZzZXQgPCBsaW5lU3RhcnQgKyBpbmRlbnQgfHwgY2hhciAhPT0gJ10nICYmIGNoYXIgIT09ICd9Jykge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1zZyA9ICdJbnN1ZmZpY2llbnQgaW5kZW50YXRpb24gaW4gZmxvdyBjb2xsZWN0aW9uJztcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9yID0gbmV3IFlBTUxTZW1hbnRpY0Vycm9yKHRoaXMsIG1zZyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSAnLCc6XG4gICAgICAgICAge1xuICAgICAgICAgICAgdGhpcy5pdGVtcy5wdXNoKHtcbiAgICAgICAgICAgICAgY2hhcixcbiAgICAgICAgICAgICAgb2Zmc2V0XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIG9mZnNldCArPSAxO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlICcjJzpcbiAgICAgICAgICB7XG4gICAgICAgICAgICBjb25zdCBjb21tZW50ID0gbmV3IENvbW1lbnQoKTtcbiAgICAgICAgICAgIG9mZnNldCA9IGNvbW1lbnQucGFyc2Uoe1xuICAgICAgICAgICAgICBzcmNcbiAgICAgICAgICAgIH0sIG9mZnNldCk7XG4gICAgICAgICAgICB0aGlzLml0ZW1zLnB1c2goY29tbWVudCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgJz8nOlxuICAgICAgICBjYXNlICc6JzpcbiAgICAgICAgICB7XG4gICAgICAgICAgICBjb25zdCBuZXh0ID0gc3JjW29mZnNldCArIDFdO1xuXG4gICAgICAgICAgICBpZiAobmV4dCA9PT0gJ1xcbicgfHwgbmV4dCA9PT0gJ1xcdCcgfHwgbmV4dCA9PT0gJyAnIHx8IG5leHQgPT09ICcsJyB8fCAvLyBpbi1mbG93IDogYWZ0ZXIgSlNPTi1saWtlIGtleSBkb2VzIG5vdCBuZWVkIHRvIGJlIGZvbGxvd2VkIGJ5IHdoaXRlc3BhY2VcbiAgICAgICAgICAgIGNoYXIgPT09ICc6JyAmJiB0aGlzLnByZXZOb2RlSXNKc29uTGlrZSgpKSB7XG4gICAgICAgICAgICAgIHRoaXMuaXRlbXMucHVzaCh7XG4gICAgICAgICAgICAgICAgY2hhcixcbiAgICAgICAgICAgICAgICBvZmZzZXRcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIG9mZnNldCArPSAxO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIC8vIGZhbGx0aHJvdWdoXG5cbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB7XG4gICAgICAgICAgICBjb25zdCBub2RlID0gcGFyc2VOb2RlKHtcbiAgICAgICAgICAgICAgYXRMaW5lU3RhcnQ6IGZhbHNlLFxuICAgICAgICAgICAgICBpbkNvbGxlY3Rpb246IGZhbHNlLFxuICAgICAgICAgICAgICBpbkZsb3c6IHRydWUsXG4gICAgICAgICAgICAgIGluZGVudDogLTEsXG4gICAgICAgICAgICAgIGxpbmVTdGFydCxcbiAgICAgICAgICAgICAgcGFyZW50OiB0aGlzXG4gICAgICAgICAgICB9LCBvZmZzZXQpO1xuXG4gICAgICAgICAgICBpZiAoIW5vZGUpIHtcbiAgICAgICAgICAgICAgLy8gYXQgbmV4dCBkb2N1bWVudCBzdGFydFxuICAgICAgICAgICAgICB0aGlzLnZhbHVlUmFuZ2UgPSBuZXcgUmFuZ2Uoc3RhcnQsIG9mZnNldCk7XG4gICAgICAgICAgICAgIHJldHVybiBvZmZzZXQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuaXRlbXMucHVzaChub2RlKTtcbiAgICAgICAgICAgIG9mZnNldCA9IE5vZGUubm9ybWFsaXplT2Zmc2V0KHNyYywgbm9kZS5yYW5nZS5lbmQpO1xuICAgICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgb2Zmc2V0ID0gTm9kZS5lbmRPZldoaXRlU3BhY2Uoc3JjLCBvZmZzZXQpO1xuICAgICAgY2hhciA9IHNyY1tvZmZzZXRdO1xuICAgIH1cblxuICAgIHRoaXMudmFsdWVSYW5nZSA9IG5ldyBSYW5nZShzdGFydCwgb2Zmc2V0ICsgMSk7XG5cbiAgICBpZiAoY2hhcikge1xuICAgICAgdGhpcy5pdGVtcy5wdXNoKHtcbiAgICAgICAgY2hhcixcbiAgICAgICAgb2Zmc2V0XG4gICAgICB9KTtcbiAgICAgIG9mZnNldCA9IE5vZGUuZW5kT2ZXaGl0ZVNwYWNlKHNyYywgb2Zmc2V0ICsgMSk7XG4gICAgICBvZmZzZXQgPSB0aGlzLnBhcnNlQ29tbWVudChvZmZzZXQpO1xuICAgIH1cblxuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICBzZXRPcmlnUmFuZ2VzKGNyLCBvZmZzZXQpIHtcbiAgICBvZmZzZXQgPSBzdXBlci5zZXRPcmlnUmFuZ2VzKGNyLCBvZmZzZXQpO1xuICAgIHRoaXMuaXRlbXMuZm9yRWFjaChub2RlID0+IHtcbiAgICAgIGlmIChub2RlIGluc3RhbmNlb2YgTm9kZSkge1xuICAgICAgICBvZmZzZXQgPSBub2RlLnNldE9yaWdSYW5nZXMoY3IsIG9mZnNldCk7XG4gICAgICB9IGVsc2UgaWYgKGNyLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBub2RlLm9yaWdPZmZzZXQgPSBub2RlLm9mZnNldDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxldCBpID0gb2Zmc2V0O1xuXG4gICAgICAgIHdoaWxlIChpIDwgY3IubGVuZ3RoKSB7XG4gICAgICAgICAgaWYgKGNyW2ldID4gbm9kZS5vZmZzZXQpIGJyZWFrO2Vsc2UgKytpO1xuICAgICAgICB9XG5cbiAgICAgICAgbm9kZS5vcmlnT2Zmc2V0ID0gbm9kZS5vZmZzZXQgKyBpO1xuICAgICAgICBvZmZzZXQgPSBpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICB0b1N0cmluZygpIHtcbiAgICBjb25zdCB7XG4gICAgICBjb250ZXh0OiB7XG4gICAgICAgIHNyY1xuICAgICAgfSxcbiAgICAgIGl0ZW1zLFxuICAgICAgcmFuZ2UsXG4gICAgICB2YWx1ZVxuICAgIH0gPSB0aGlzO1xuICAgIGlmICh2YWx1ZSAhPSBudWxsKSByZXR1cm4gdmFsdWU7XG4gICAgY29uc3Qgbm9kZXMgPSBpdGVtcy5maWx0ZXIoaXRlbSA9PiBpdGVtIGluc3RhbmNlb2YgTm9kZSk7XG4gICAgbGV0IHN0ciA9ICcnO1xuICAgIGxldCBwcmV2RW5kID0gcmFuZ2Uuc3RhcnQ7XG4gICAgbm9kZXMuZm9yRWFjaChub2RlID0+IHtcbiAgICAgIGNvbnN0IHByZWZpeCA9IHNyYy5zbGljZShwcmV2RW5kLCBub2RlLnJhbmdlLnN0YXJ0KTtcbiAgICAgIHByZXZFbmQgPSBub2RlLnJhbmdlLmVuZDtcbiAgICAgIHN0ciArPSBwcmVmaXggKyBTdHJpbmcobm9kZSk7XG5cbiAgICAgIGlmIChzdHJbc3RyLmxlbmd0aCAtIDFdID09PSAnXFxuJyAmJiBzcmNbcHJldkVuZCAtIDFdICE9PSAnXFxuJyAmJiBzcmNbcHJldkVuZF0gPT09ICdcXG4nKSB7XG4gICAgICAgIC8vIENvbW1lbnQgcmFuZ2UgZG9lcyBub3QgaW5jbHVkZSB0aGUgdGVybWluYWwgbmV3bGluZSwgYnV0IGl0c1xuICAgICAgICAvLyBzdHJpbmdpZmllZCB2YWx1ZSBkb2VzLiBXaXRob3V0IHRoaXMgZml4LCBuZXdsaW5lcyBhdCBjb21tZW50IGVuZHNcbiAgICAgICAgLy8gZ2V0IGR1cGxpY2F0ZWQuXG4gICAgICAgIHByZXZFbmQgKz0gMTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBzdHIgKz0gc3JjLnNsaWNlKHByZXZFbmQsIHJhbmdlLmVuZCk7XG4gICAgcmV0dXJuIE5vZGUuYWRkU3RyaW5nVGVybWluYXRvcihzcmMsIHJhbmdlLmVuZCwgc3RyKTtcbiAgfVxuXG59XG5cbmV4cG9ydCB7IEZsb3dDb2xsZWN0aW9uIH07XG4iLCJpbXBvcnQgeyBZQU1MU2VtYW50aWNFcnJvciB9IGZyb20gJy4uL2Vycm9ycy5qcyc7XG5pbXBvcnQgeyBOb2RlIH0gZnJvbSAnLi9Ob2RlLmpzJztcbmltcG9ydCB7IFJhbmdlIH0gZnJvbSAnLi9SYW5nZS5qcyc7XG5cbmNsYXNzIFBsYWluVmFsdWUgZXh0ZW5kcyBOb2RlIHtcbiAgc3RhdGljIGVuZE9mTGluZShzcmMsIHN0YXJ0LCBpbkZsb3cpIHtcbiAgICBsZXQgY2ggPSBzcmNbc3RhcnRdO1xuICAgIGxldCBvZmZzZXQgPSBzdGFydDtcblxuICAgIHdoaWxlIChjaCAmJiBjaCAhPT0gJ1xcbicpIHtcbiAgICAgIGlmIChpbkZsb3cgJiYgKGNoID09PSAnWycgfHwgY2ggPT09ICddJyB8fCBjaCA9PT0gJ3snIHx8IGNoID09PSAnfScgfHwgY2ggPT09ICcsJykpIGJyZWFrO1xuICAgICAgY29uc3QgbmV4dCA9IHNyY1tvZmZzZXQgKyAxXTtcbiAgICAgIGlmIChjaCA9PT0gJzonICYmICghbmV4dCB8fCBuZXh0ID09PSAnXFxuJyB8fCBuZXh0ID09PSAnXFx0JyB8fCBuZXh0ID09PSAnICcgfHwgaW5GbG93ICYmIG5leHQgPT09ICcsJykpIGJyZWFrO1xuICAgICAgaWYgKChjaCA9PT0gJyAnIHx8IGNoID09PSAnXFx0JykgJiYgbmV4dCA9PT0gJyMnKSBicmVhaztcbiAgICAgIG9mZnNldCArPSAxO1xuICAgICAgY2ggPSBuZXh0O1xuICAgIH1cblxuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cblxuICBnZXQgc3RyVmFsdWUoKSB7XG4gICAgaWYgKCF0aGlzLnZhbHVlUmFuZ2UgfHwgIXRoaXMuY29udGV4dCkgcmV0dXJuIG51bGw7XG4gICAgbGV0IHtcbiAgICAgIHN0YXJ0LFxuICAgICAgZW5kXG4gICAgfSA9IHRoaXMudmFsdWVSYW5nZTtcbiAgICBjb25zdCB7XG4gICAgICBzcmNcbiAgICB9ID0gdGhpcy5jb250ZXh0O1xuICAgIGxldCBjaCA9IHNyY1tlbmQgLSAxXTtcblxuICAgIHdoaWxlIChzdGFydCA8IGVuZCAmJiAoY2ggPT09ICdcXG4nIHx8IGNoID09PSAnXFx0JyB8fCBjaCA9PT0gJyAnKSkgY2ggPSBzcmNbLS1lbmQgLSAxXTtcblxuICAgIGxldCBzdHIgPSAnJztcblxuICAgIGZvciAobGV0IGkgPSBzdGFydDsgaSA8IGVuZDsgKytpKSB7XG4gICAgICBjb25zdCBjaCA9IHNyY1tpXTtcblxuICAgICAgaWYgKGNoID09PSAnXFxuJykge1xuICAgICAgICBjb25zdCB7XG4gICAgICAgICAgZm9sZCxcbiAgICAgICAgICBvZmZzZXRcbiAgICAgICAgfSA9IE5vZGUuZm9sZE5ld2xpbmUoc3JjLCBpLCAtMSk7XG4gICAgICAgIHN0ciArPSBmb2xkO1xuICAgICAgICBpID0gb2Zmc2V0O1xuICAgICAgfSBlbHNlIGlmIChjaCA9PT0gJyAnIHx8IGNoID09PSAnXFx0Jykge1xuICAgICAgICAvLyB0cmltIHRyYWlsaW5nIHdoaXRlc3BhY2VcbiAgICAgICAgY29uc3Qgd3NTdGFydCA9IGk7XG4gICAgICAgIGxldCBuZXh0ID0gc3JjW2kgKyAxXTtcblxuICAgICAgICB3aGlsZSAoaSA8IGVuZCAmJiAobmV4dCA9PT0gJyAnIHx8IG5leHQgPT09ICdcXHQnKSkge1xuICAgICAgICAgIGkgKz0gMTtcbiAgICAgICAgICBuZXh0ID0gc3JjW2kgKyAxXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChuZXh0ICE9PSAnXFxuJykgc3RyICs9IGkgPiB3c1N0YXJ0ID8gc3JjLnNsaWNlKHdzU3RhcnQsIGkgKyAxKSA6IGNoO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RyICs9IGNoO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGNoMCA9IHNyY1tzdGFydF07XG5cbiAgICBzd2l0Y2ggKGNoMCkge1xuICAgICAgY2FzZSAnXFx0JzpcbiAgICAgICAge1xuICAgICAgICAgIGNvbnN0IG1zZyA9ICdQbGFpbiB2YWx1ZSBjYW5ub3Qgc3RhcnQgd2l0aCBhIHRhYiBjaGFyYWN0ZXInO1xuICAgICAgICAgIGNvbnN0IGVycm9ycyA9IFtuZXcgWUFNTFNlbWFudGljRXJyb3IodGhpcywgbXNnKV07XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGVycm9ycyxcbiAgICAgICAgICAgIHN0clxuICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgY2FzZSAnQCc6XG4gICAgICBjYXNlICdgJzpcbiAgICAgICAge1xuICAgICAgICAgIGNvbnN0IG1zZyA9IFwiUGxhaW4gdmFsdWUgY2Fubm90IHN0YXJ0IHdpdGggcmVzZXJ2ZWQgY2hhcmFjdGVyIFwiLmNvbmNhdChjaDApO1xuICAgICAgICAgIGNvbnN0IGVycm9ycyA9IFtuZXcgWUFNTFNlbWFudGljRXJyb3IodGhpcywgbXNnKV07XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGVycm9ycyxcbiAgICAgICAgICAgIHN0clxuICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHN0cjtcbiAgICB9XG4gIH1cblxuICBwYXJzZUJsb2NrVmFsdWUoc3RhcnQpIHtcbiAgICBjb25zdCB7XG4gICAgICBpbmRlbnQsXG4gICAgICBpbkZsb3csXG4gICAgICBzcmNcbiAgICB9ID0gdGhpcy5jb250ZXh0O1xuICAgIGxldCBvZmZzZXQgPSBzdGFydDtcbiAgICBsZXQgdmFsdWVFbmQgPSBzdGFydDtcblxuICAgIGZvciAobGV0IGNoID0gc3JjW29mZnNldF07IGNoID09PSAnXFxuJzsgY2ggPSBzcmNbb2Zmc2V0XSkge1xuICAgICAgaWYgKE5vZGUuYXREb2N1bWVudEJvdW5kYXJ5KHNyYywgb2Zmc2V0ICsgMSkpIGJyZWFrO1xuICAgICAgY29uc3QgZW5kID0gTm9kZS5lbmRPZkJsb2NrSW5kZW50KHNyYywgaW5kZW50LCBvZmZzZXQgKyAxKTtcbiAgICAgIGlmIChlbmQgPT09IG51bGwgfHwgc3JjW2VuZF0gPT09ICcjJykgYnJlYWs7XG5cbiAgICAgIGlmIChzcmNbZW5kXSA9PT0gJ1xcbicpIHtcbiAgICAgICAgb2Zmc2V0ID0gZW5kO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFsdWVFbmQgPSBQbGFpblZhbHVlLmVuZE9mTGluZShzcmMsIGVuZCwgaW5GbG93KTtcbiAgICAgICAgb2Zmc2V0ID0gdmFsdWVFbmQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMudmFsdWVSYW5nZS5pc0VtcHR5KCkpIHRoaXMudmFsdWVSYW5nZS5zdGFydCA9IHN0YXJ0O1xuICAgIHRoaXMudmFsdWVSYW5nZS5lbmQgPSB2YWx1ZUVuZDtcbiAgICByZXR1cm4gdmFsdWVFbmQ7XG4gIH1cbiAgLyoqXG4gICAqIFBhcnNlcyBhIHBsYWluIHZhbHVlIGZyb20gdGhlIHNvdXJjZVxuICAgKlxuICAgKiBBY2NlcHRlZCBmb3JtcyBhcmU6XG4gICAqIGBgYFxuICAgKiAjY29tbWVudFxuICAgKlxuICAgKiBmaXJzdCBsaW5lXG4gICAqXG4gICAqIGZpcnN0IGxpbmUgI2NvbW1lbnRcbiAgICpcbiAgICogZmlyc3QgbGluZVxuICAgKiBibG9ja1xuICAgKiBsaW5lc1xuICAgKlxuICAgKiAjY29tbWVudFxuICAgKiBibG9ja1xuICAgKiBsaW5lc1xuICAgKiBgYGBcbiAgICogd2hlcmUgYmxvY2sgbGluZXMgYXJlIGVtcHR5IG9yIGhhdmUgYW4gaW5kZW50IGxldmVsIGdyZWF0ZXIgdGhhbiBgaW5kZW50YC5cbiAgICpcbiAgICogQHBhcmFtIHtQYXJzZUNvbnRleHR9IGNvbnRleHRcbiAgICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0IC0gSW5kZXggb2YgZmlyc3QgY2hhcmFjdGVyXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IC0gSW5kZXggb2YgdGhlIGNoYXJhY3RlciBhZnRlciB0aGlzIHNjYWxhciwgbWF5IGJlIGBcXG5gXG4gICAqL1xuXG5cbiAgcGFyc2UoY29udGV4dCwgc3RhcnQpIHtcbiAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xuICAgIGNvbnN0IHtcbiAgICAgIGluRmxvdyxcbiAgICAgIHNyY1xuICAgIH0gPSBjb250ZXh0O1xuICAgIGxldCBvZmZzZXQgPSBzdGFydDtcbiAgICBjb25zdCBjaCA9IHNyY1tvZmZzZXRdO1xuXG4gICAgaWYgKGNoICYmIGNoICE9PSAnIycgJiYgY2ggIT09ICdcXG4nKSB7XG4gICAgICBvZmZzZXQgPSBQbGFpblZhbHVlLmVuZE9mTGluZShzcmMsIHN0YXJ0LCBpbkZsb3cpO1xuICAgIH1cblxuICAgIHRoaXMudmFsdWVSYW5nZSA9IG5ldyBSYW5nZShzdGFydCwgb2Zmc2V0KTtcbiAgICBvZmZzZXQgPSBOb2RlLmVuZE9mV2hpdGVTcGFjZShzcmMsIG9mZnNldCk7XG4gICAgb2Zmc2V0ID0gdGhpcy5wYXJzZUNvbW1lbnQob2Zmc2V0KTtcblxuICAgIGlmICghdGhpcy5oYXNDb21tZW50IHx8IHRoaXMudmFsdWVSYW5nZS5pc0VtcHR5KCkpIHtcbiAgICAgIG9mZnNldCA9IHRoaXMucGFyc2VCbG9ja1ZhbHVlKG9mZnNldCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG59XG5cbmV4cG9ydCB7IFBsYWluVmFsdWUgfTtcbiIsImltcG9ydCB7IFlBTUxTeW50YXhFcnJvciwgWUFNTFNlbWFudGljRXJyb3IgfSBmcm9tICcuLi9lcnJvcnMuanMnO1xuaW1wb3J0IHsgTm9kZSB9IGZyb20gJy4vTm9kZS5qcyc7XG5pbXBvcnQgeyBSYW5nZSB9IGZyb20gJy4vUmFuZ2UuanMnO1xuXG5jbGFzcyBRdW90ZURvdWJsZSBleHRlbmRzIE5vZGUge1xuICBzdGF0aWMgZW5kT2ZRdW90ZShzcmMsIG9mZnNldCkge1xuICAgIGxldCBjaCA9IHNyY1tvZmZzZXRdO1xuXG4gICAgd2hpbGUgKGNoICYmIGNoICE9PSAnXCInKSB7XG4gICAgICBvZmZzZXQgKz0gY2ggPT09ICdcXFxcJyA/IDIgOiAxO1xuICAgICAgY2ggPSBzcmNbb2Zmc2V0XTtcbiAgICB9XG5cbiAgICByZXR1cm4gb2Zmc2V0ICsgMTtcbiAgfVxuICAvKipcbiAgICogQHJldHVybnMge3N0cmluZyB8IHsgc3RyOiBzdHJpbmcsIGVycm9yczogWUFNTFN5bnRheEVycm9yW10gfX1cbiAgICovXG5cblxuICBnZXQgc3RyVmFsdWUoKSB7XG4gICAgaWYgKCF0aGlzLnZhbHVlUmFuZ2UgfHwgIXRoaXMuY29udGV4dCkgcmV0dXJuIG51bGw7XG4gICAgY29uc3QgZXJyb3JzID0gW107XG4gICAgY29uc3Qge1xuICAgICAgc3RhcnQsXG4gICAgICBlbmRcbiAgICB9ID0gdGhpcy52YWx1ZVJhbmdlO1xuICAgIGNvbnN0IHtcbiAgICAgIGluZGVudCxcbiAgICAgIHNyY1xuICAgIH0gPSB0aGlzLmNvbnRleHQ7XG4gICAgaWYgKHNyY1tlbmQgLSAxXSAhPT0gJ1wiJykgZXJyb3JzLnB1c2gobmV3IFlBTUxTeW50YXhFcnJvcih0aGlzLCAnTWlzc2luZyBjbG9zaW5nIFwicXVvdGUnKSk7IC8vIFVzaW5nIFN0cmluZyNyZXBsYWNlIGlzIHRvbyBwYWluZnVsIHdpdGggZXNjYXBlZCBuZXdsaW5lcyBwcmVjZWRlZCBieVxuICAgIC8vIGVzY2FwZWQgYmFja3NsYXNoZXM7IGFsc28sIHRoaXMgc2hvdWxkIGJlIGZhc3Rlci5cblxuICAgIGxldCBzdHIgPSAnJztcblxuICAgIGZvciAobGV0IGkgPSBzdGFydCArIDE7IGkgPCBlbmQgLSAxOyArK2kpIHtcbiAgICAgIGNvbnN0IGNoID0gc3JjW2ldO1xuXG4gICAgICBpZiAoY2ggPT09ICdcXG4nKSB7XG4gICAgICAgIGlmIChOb2RlLmF0RG9jdW1lbnRCb3VuZGFyeShzcmMsIGkgKyAxKSkgZXJyb3JzLnB1c2gobmV3IFlBTUxTZW1hbnRpY0Vycm9yKHRoaXMsICdEb2N1bWVudCBib3VuZGFyeSBpbmRpY2F0b3JzIGFyZSBub3QgYWxsb3dlZCB3aXRoaW4gc3RyaW5nIHZhbHVlcycpKTtcbiAgICAgICAgY29uc3Qge1xuICAgICAgICAgIGZvbGQsXG4gICAgICAgICAgb2Zmc2V0LFxuICAgICAgICAgIGVycm9yXG4gICAgICAgIH0gPSBOb2RlLmZvbGROZXdsaW5lKHNyYywgaSwgaW5kZW50KTtcbiAgICAgICAgc3RyICs9IGZvbGQ7XG4gICAgICAgIGkgPSBvZmZzZXQ7XG4gICAgICAgIGlmIChlcnJvcikgZXJyb3JzLnB1c2gobmV3IFlBTUxTZW1hbnRpY0Vycm9yKHRoaXMsICdNdWx0aS1saW5lIGRvdWJsZS1xdW90ZWQgc3RyaW5nIG5lZWRzIHRvIGJlIHN1ZmZpY2llbnRseSBpbmRlbnRlZCcpKTtcbiAgICAgIH0gZWxzZSBpZiAoY2ggPT09ICdcXFxcJykge1xuICAgICAgICBpICs9IDE7XG5cbiAgICAgICAgc3dpdGNoIChzcmNbaV0pIHtcbiAgICAgICAgICBjYXNlICcwJzpcbiAgICAgICAgICAgIHN0ciArPSAnXFwwJztcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIC8vIG51bGwgY2hhcmFjdGVyXG5cbiAgICAgICAgICBjYXNlICdhJzpcbiAgICAgICAgICAgIHN0ciArPSAnXFx4MDcnO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgLy8gYmVsbCBjaGFyYWN0ZXJcblxuICAgICAgICAgIGNhc2UgJ2InOlxuICAgICAgICAgICAgc3RyICs9ICdcXGInO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgLy8gYmFja3NwYWNlXG5cbiAgICAgICAgICBjYXNlICdlJzpcbiAgICAgICAgICAgIHN0ciArPSAnXFx4MWInO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgLy8gZXNjYXBlIGNoYXJhY3RlclxuXG4gICAgICAgICAgY2FzZSAnZic6XG4gICAgICAgICAgICBzdHIgKz0gJ1xcZic7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAvLyBmb3JtIGZlZWRcblxuICAgICAgICAgIGNhc2UgJ24nOlxuICAgICAgICAgICAgc3RyICs9ICdcXG4nO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgLy8gbGluZSBmZWVkXG5cbiAgICAgICAgICBjYXNlICdyJzpcbiAgICAgICAgICAgIHN0ciArPSAnXFxyJztcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIC8vIGNhcnJpYWdlIHJldHVyblxuXG4gICAgICAgICAgY2FzZSAndCc6XG4gICAgICAgICAgICBzdHIgKz0gJ1xcdCc7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAvLyBob3Jpem9udGFsIHRhYlxuXG4gICAgICAgICAgY2FzZSAndic6XG4gICAgICAgICAgICBzdHIgKz0gJ1xcdic7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAvLyB2ZXJ0aWNhbCB0YWJcblxuICAgICAgICAgIGNhc2UgJ04nOlxuICAgICAgICAgICAgc3RyICs9ICdcXHUwMDg1JztcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIC8vIFVuaWNvZGUgbmV4dCBsaW5lXG5cbiAgICAgICAgICBjYXNlICdfJzpcbiAgICAgICAgICAgIHN0ciArPSAnXFx1MDBhMCc7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAvLyBVbmljb2RlIG5vbi1icmVha2luZyBzcGFjZVxuXG4gICAgICAgICAgY2FzZSAnTCc6XG4gICAgICAgICAgICBzdHIgKz0gJ1xcdTIwMjgnO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgLy8gVW5pY29kZSBsaW5lIHNlcGFyYXRvclxuXG4gICAgICAgICAgY2FzZSAnUCc6XG4gICAgICAgICAgICBzdHIgKz0gJ1xcdTIwMjknO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgLy8gVW5pY29kZSBwYXJhZ3JhcGggc2VwYXJhdG9yXG5cbiAgICAgICAgICBjYXNlICcgJzpcbiAgICAgICAgICAgIHN0ciArPSAnICc7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgJ1wiJzpcbiAgICAgICAgICAgIHN0ciArPSAnXCInO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlICcvJzpcbiAgICAgICAgICAgIHN0ciArPSAnLyc7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgJ1xcXFwnOlxuICAgICAgICAgICAgc3RyICs9ICdcXFxcJztcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSAnXFx0JzpcbiAgICAgICAgICAgIHN0ciArPSAnXFx0JztcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSAneCc6XG4gICAgICAgICAgICBzdHIgKz0gdGhpcy5wYXJzZUNoYXJDb2RlKGkgKyAxLCAyLCBlcnJvcnMpO1xuICAgICAgICAgICAgaSArPSAyO1xuICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICBjYXNlICd1JzpcbiAgICAgICAgICAgIHN0ciArPSB0aGlzLnBhcnNlQ2hhckNvZGUoaSArIDEsIDQsIGVycm9ycyk7XG4gICAgICAgICAgICBpICs9IDQ7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGNhc2UgJ1UnOlxuICAgICAgICAgICAgc3RyICs9IHRoaXMucGFyc2VDaGFyQ29kZShpICsgMSwgOCwgZXJyb3JzKTtcbiAgICAgICAgICAgIGkgKz0gODtcbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgY2FzZSAnXFxuJzpcbiAgICAgICAgICAgIC8vIHNraXAgZXNjYXBlZCBuZXdsaW5lcywgYnV0IHN0aWxsIHRyaW0gdGhlIGZvbGxvd2luZyBsaW5lXG4gICAgICAgICAgICB3aGlsZSAoc3JjW2kgKyAxXSA9PT0gJyAnIHx8IHNyY1tpICsgMV0gPT09ICdcXHQnKSBpICs9IDE7XG5cbiAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIGVycm9ycy5wdXNoKG5ldyBZQU1MU3ludGF4RXJyb3IodGhpcywgXCJJbnZhbGlkIGVzY2FwZSBzZXF1ZW5jZSBcIi5jb25jYXQoc3JjLnN1YnN0cihpIC0gMSwgMikpKSk7XG4gICAgICAgICAgICBzdHIgKz0gJ1xcXFwnICsgc3JjW2ldO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGNoID09PSAnICcgfHwgY2ggPT09ICdcXHQnKSB7XG4gICAgICAgIC8vIHRyaW0gdHJhaWxpbmcgd2hpdGVzcGFjZVxuICAgICAgICBjb25zdCB3c1N0YXJ0ID0gaTtcbiAgICAgICAgbGV0IG5leHQgPSBzcmNbaSArIDFdO1xuXG4gICAgICAgIHdoaWxlIChuZXh0ID09PSAnICcgfHwgbmV4dCA9PT0gJ1xcdCcpIHtcbiAgICAgICAgICBpICs9IDE7XG4gICAgICAgICAgbmV4dCA9IHNyY1tpICsgMV07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobmV4dCAhPT0gJ1xcbicpIHN0ciArPSBpID4gd3NTdGFydCA/IHNyYy5zbGljZSh3c1N0YXJ0LCBpICsgMSkgOiBjaDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0ciArPSBjaDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZXJyb3JzLmxlbmd0aCA+IDAgPyB7XG4gICAgICBlcnJvcnMsXG4gICAgICBzdHJcbiAgICB9IDogc3RyO1xuICB9XG5cbiAgcGFyc2VDaGFyQ29kZShvZmZzZXQsIGxlbmd0aCwgZXJyb3JzKSB7XG4gICAgY29uc3Qge1xuICAgICAgc3JjXG4gICAgfSA9IHRoaXMuY29udGV4dDtcbiAgICBjb25zdCBjYyA9IHNyYy5zdWJzdHIob2Zmc2V0LCBsZW5ndGgpO1xuICAgIGNvbnN0IG9rID0gY2MubGVuZ3RoID09PSBsZW5ndGggJiYgL15bMC05YS1mQS1GXSskLy50ZXN0KGNjKTtcbiAgICBjb25zdCBjb2RlID0gb2sgPyBwYXJzZUludChjYywgMTYpIDogTmFOO1xuXG4gICAgaWYgKGlzTmFOKGNvZGUpKSB7XG4gICAgICBlcnJvcnMucHVzaChuZXcgWUFNTFN5bnRheEVycm9yKHRoaXMsIFwiSW52YWxpZCBlc2NhcGUgc2VxdWVuY2UgXCIuY29uY2F0KHNyYy5zdWJzdHIob2Zmc2V0IC0gMiwgbGVuZ3RoICsgMikpKSk7XG4gICAgICByZXR1cm4gc3JjLnN1YnN0cihvZmZzZXQgLSAyLCBsZW5ndGggKyAyKTtcbiAgICB9XG5cbiAgICByZXR1cm4gU3RyaW5nLmZyb21Db2RlUG9pbnQoY29kZSk7XG4gIH1cbiAgLyoqXG4gICAqIFBhcnNlcyBhIFwiZG91YmxlIHF1b3RlZFwiIHZhbHVlIGZyb20gdGhlIHNvdXJjZVxuICAgKlxuICAgKiBAcGFyYW0ge1BhcnNlQ29udGV4dH0gY29udGV4dFxuICAgKiBAcGFyYW0ge251bWJlcn0gc3RhcnQgLSBJbmRleCBvZiBmaXJzdCBjaGFyYWN0ZXJcbiAgICogQHJldHVybnMge251bWJlcn0gLSBJbmRleCBvZiB0aGUgY2hhcmFjdGVyIGFmdGVyIHRoaXMgc2NhbGFyXG4gICAqL1xuXG5cbiAgcGFyc2UoY29udGV4dCwgc3RhcnQpIHtcbiAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xuICAgIGNvbnN0IHtcbiAgICAgIHNyY1xuICAgIH0gPSBjb250ZXh0O1xuICAgIGxldCBvZmZzZXQgPSBRdW90ZURvdWJsZS5lbmRPZlF1b3RlKHNyYywgc3RhcnQgKyAxKTtcbiAgICB0aGlzLnZhbHVlUmFuZ2UgPSBuZXcgUmFuZ2Uoc3RhcnQsIG9mZnNldCk7XG4gICAgb2Zmc2V0ID0gTm9kZS5lbmRPZldoaXRlU3BhY2Uoc3JjLCBvZmZzZXQpO1xuICAgIG9mZnNldCA9IHRoaXMucGFyc2VDb21tZW50KG9mZnNldCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG59XG5cbmV4cG9ydCB7IFF1b3RlRG91YmxlIH07XG4iLCJpbXBvcnQgeyBZQU1MU3ludGF4RXJyb3IsIFlBTUxTZW1hbnRpY0Vycm9yIH0gZnJvbSAnLi4vZXJyb3JzLmpzJztcbmltcG9ydCB7IE5vZGUgfSBmcm9tICcuL05vZGUuanMnO1xuaW1wb3J0IHsgUmFuZ2UgfSBmcm9tICcuL1JhbmdlLmpzJztcblxuY2xhc3MgUXVvdGVTaW5nbGUgZXh0ZW5kcyBOb2RlIHtcbiAgc3RhdGljIGVuZE9mUXVvdGUoc3JjLCBvZmZzZXQpIHtcbiAgICBsZXQgY2ggPSBzcmNbb2Zmc2V0XTtcblxuICAgIHdoaWxlIChjaCkge1xuICAgICAgaWYgKGNoID09PSBcIidcIikge1xuICAgICAgICBpZiAoc3JjW29mZnNldCArIDFdICE9PSBcIidcIikgYnJlYWs7XG4gICAgICAgIGNoID0gc3JjW29mZnNldCArPSAyXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNoID0gc3JjW29mZnNldCArPSAxXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gb2Zmc2V0ICsgMTtcbiAgfVxuICAvKipcbiAgICogQHJldHVybnMge3N0cmluZyB8IHsgc3RyOiBzdHJpbmcsIGVycm9yczogWUFNTFN5bnRheEVycm9yW10gfX1cbiAgICovXG5cblxuICBnZXQgc3RyVmFsdWUoKSB7XG4gICAgaWYgKCF0aGlzLnZhbHVlUmFuZ2UgfHwgIXRoaXMuY29udGV4dCkgcmV0dXJuIG51bGw7XG4gICAgY29uc3QgZXJyb3JzID0gW107XG4gICAgY29uc3Qge1xuICAgICAgc3RhcnQsXG4gICAgICBlbmRcbiAgICB9ID0gdGhpcy52YWx1ZVJhbmdlO1xuICAgIGNvbnN0IHtcbiAgICAgIGluZGVudCxcbiAgICAgIHNyY1xuICAgIH0gPSB0aGlzLmNvbnRleHQ7XG4gICAgaWYgKHNyY1tlbmQgLSAxXSAhPT0gXCInXCIpIGVycm9ycy5wdXNoKG5ldyBZQU1MU3ludGF4RXJyb3IodGhpcywgXCJNaXNzaW5nIGNsb3NpbmcgJ3F1b3RlXCIpKTtcbiAgICBsZXQgc3RyID0gJyc7XG5cbiAgICBmb3IgKGxldCBpID0gc3RhcnQgKyAxOyBpIDwgZW5kIC0gMTsgKytpKSB7XG4gICAgICBjb25zdCBjaCA9IHNyY1tpXTtcblxuICAgICAgaWYgKGNoID09PSAnXFxuJykge1xuICAgICAgICBpZiAoTm9kZS5hdERvY3VtZW50Qm91bmRhcnkoc3JjLCBpICsgMSkpIGVycm9ycy5wdXNoKG5ldyBZQU1MU2VtYW50aWNFcnJvcih0aGlzLCAnRG9jdW1lbnQgYm91bmRhcnkgaW5kaWNhdG9ycyBhcmUgbm90IGFsbG93ZWQgd2l0aGluIHN0cmluZyB2YWx1ZXMnKSk7XG4gICAgICAgIGNvbnN0IHtcbiAgICAgICAgICBmb2xkLFxuICAgICAgICAgIG9mZnNldCxcbiAgICAgICAgICBlcnJvclxuICAgICAgICB9ID0gTm9kZS5mb2xkTmV3bGluZShzcmMsIGksIGluZGVudCk7XG4gICAgICAgIHN0ciArPSBmb2xkO1xuICAgICAgICBpID0gb2Zmc2V0O1xuICAgICAgICBpZiAoZXJyb3IpIGVycm9ycy5wdXNoKG5ldyBZQU1MU2VtYW50aWNFcnJvcih0aGlzLCAnTXVsdGktbGluZSBzaW5nbGUtcXVvdGVkIHN0cmluZyBuZWVkcyB0byBiZSBzdWZmaWNpZW50bHkgaW5kZW50ZWQnKSk7XG4gICAgICB9IGVsc2UgaWYgKGNoID09PSBcIidcIikge1xuICAgICAgICBzdHIgKz0gY2g7XG4gICAgICAgIGkgKz0gMTtcbiAgICAgICAgaWYgKHNyY1tpXSAhPT0gXCInXCIpIGVycm9ycy5wdXNoKG5ldyBZQU1MU3ludGF4RXJyb3IodGhpcywgJ1VuZXNjYXBlZCBzaW5nbGUgcXVvdGU/IFRoaXMgc2hvdWxkIG5vdCBoYXBwZW4uJykpO1xuICAgICAgfSBlbHNlIGlmIChjaCA9PT0gJyAnIHx8IGNoID09PSAnXFx0Jykge1xuICAgICAgICAvLyB0cmltIHRyYWlsaW5nIHdoaXRlc3BhY2VcbiAgICAgICAgY29uc3Qgd3NTdGFydCA9IGk7XG4gICAgICAgIGxldCBuZXh0ID0gc3JjW2kgKyAxXTtcblxuICAgICAgICB3aGlsZSAobmV4dCA9PT0gJyAnIHx8IG5leHQgPT09ICdcXHQnKSB7XG4gICAgICAgICAgaSArPSAxO1xuICAgICAgICAgIG5leHQgPSBzcmNbaSArIDFdO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG5leHQgIT09ICdcXG4nKSBzdHIgKz0gaSA+IHdzU3RhcnQgPyBzcmMuc2xpY2Uod3NTdGFydCwgaSArIDEpIDogY2g7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdHIgKz0gY2g7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGVycm9ycy5sZW5ndGggPiAwID8ge1xuICAgICAgZXJyb3JzLFxuICAgICAgc3RyXG4gICAgfSA6IHN0cjtcbiAgfVxuICAvKipcbiAgICogUGFyc2VzIGEgJ3NpbmdsZSBxdW90ZWQnIHZhbHVlIGZyb20gdGhlIHNvdXJjZVxuICAgKlxuICAgKiBAcGFyYW0ge1BhcnNlQ29udGV4dH0gY29udGV4dFxuICAgKiBAcGFyYW0ge251bWJlcn0gc3RhcnQgLSBJbmRleCBvZiBmaXJzdCBjaGFyYWN0ZXJcbiAgICogQHJldHVybnMge251bWJlcn0gLSBJbmRleCBvZiB0aGUgY2hhcmFjdGVyIGFmdGVyIHRoaXMgc2NhbGFyXG4gICAqL1xuXG5cbiAgcGFyc2UoY29udGV4dCwgc3RhcnQpIHtcbiAgICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xuICAgIGNvbnN0IHtcbiAgICAgIHNyY1xuICAgIH0gPSBjb250ZXh0O1xuICAgIGxldCBvZmZzZXQgPSBRdW90ZVNpbmdsZS5lbmRPZlF1b3RlKHNyYywgc3RhcnQgKyAxKTtcbiAgICB0aGlzLnZhbHVlUmFuZ2UgPSBuZXcgUmFuZ2Uoc3RhcnQsIG9mZnNldCk7XG4gICAgb2Zmc2V0ID0gTm9kZS5lbmRPZldoaXRlU3BhY2Uoc3JjLCBvZmZzZXQpO1xuICAgIG9mZnNldCA9IHRoaXMucGFyc2VDb21tZW50KG9mZnNldCk7XG4gICAgcmV0dXJuIG9mZnNldDtcbiAgfVxuXG59XG5cbmV4cG9ydCB7IFF1b3RlU2luZ2xlIH07XG4iLCJpbXBvcnQgeyBkZWZpbmVQcm9wZXJ0eSBhcyBfZGVmaW5lUHJvcGVydHkgfSBmcm9tICcuLi9fdmlydHVhbC9fcm9sbHVwUGx1Z2luQmFiZWxIZWxwZXJzLmpzJztcbmltcG9ydCB7IFR5cGUsIENoYXIgfSBmcm9tICcuLi9jb25zdGFudHMuanMnO1xuaW1wb3J0IHsgWUFNTFN5bnRheEVycm9yIH0gZnJvbSAnLi4vZXJyb3JzLmpzJztcbmltcG9ydCB7IEFsaWFzIH0gZnJvbSAnLi9BbGlhcy5qcyc7XG5pbXBvcnQgeyBCbG9ja1ZhbHVlIH0gZnJvbSAnLi9CbG9ja1ZhbHVlLmpzJztcbmltcG9ydCB7IENvbGxlY3Rpb24gfSBmcm9tICcuL0NvbGxlY3Rpb24uanMnO1xuaW1wb3J0IHsgQ29sbGVjdGlvbkl0ZW0gfSBmcm9tICcuL0NvbGxlY3Rpb25JdGVtLmpzJztcbmltcG9ydCB7IEZsb3dDb2xsZWN0aW9uIH0gZnJvbSAnLi9GbG93Q29sbGVjdGlvbi5qcyc7XG5pbXBvcnQgeyBOb2RlIH0gZnJvbSAnLi9Ob2RlLmpzJztcbmltcG9ydCB7IFBsYWluVmFsdWUgfSBmcm9tICcuL1BsYWluVmFsdWUuanMnO1xuaW1wb3J0IHsgUXVvdGVEb3VibGUgfSBmcm9tICcuL1F1b3RlRG91YmxlLmpzJztcbmltcG9ydCB7IFF1b3RlU2luZ2xlIH0gZnJvbSAnLi9RdW90ZVNpbmdsZS5qcyc7XG5pbXBvcnQgeyBSYW5nZSB9IGZyb20gJy4vUmFuZ2UuanMnO1xuXG5mdW5jdGlvbiBjcmVhdGVOZXdOb2RlKHR5cGUsIHByb3BzKSB7XG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgVHlwZS5BTElBUzpcbiAgICAgIHJldHVybiBuZXcgQWxpYXModHlwZSwgcHJvcHMpO1xuXG4gICAgY2FzZSBUeXBlLkJMT0NLX0ZPTERFRDpcbiAgICBjYXNlIFR5cGUuQkxPQ0tfTElURVJBTDpcbiAgICAgIHJldHVybiBuZXcgQmxvY2tWYWx1ZSh0eXBlLCBwcm9wcyk7XG5cbiAgICBjYXNlIFR5cGUuRkxPV19NQVA6XG4gICAgY2FzZSBUeXBlLkZMT1dfU0VROlxuICAgICAgcmV0dXJuIG5ldyBGbG93Q29sbGVjdGlvbih0eXBlLCBwcm9wcyk7XG5cbiAgICBjYXNlIFR5cGUuTUFQX0tFWTpcbiAgICBjYXNlIFR5cGUuTUFQX1ZBTFVFOlxuICAgIGNhc2UgVHlwZS5TRVFfSVRFTTpcbiAgICAgIHJldHVybiBuZXcgQ29sbGVjdGlvbkl0ZW0odHlwZSwgcHJvcHMpO1xuXG4gICAgY2FzZSBUeXBlLkNPTU1FTlQ6XG4gICAgY2FzZSBUeXBlLlBMQUlOOlxuICAgICAgcmV0dXJuIG5ldyBQbGFpblZhbHVlKHR5cGUsIHByb3BzKTtcblxuICAgIGNhc2UgVHlwZS5RVU9URV9ET1VCTEU6XG4gICAgICByZXR1cm4gbmV3IFF1b3RlRG91YmxlKHR5cGUsIHByb3BzKTtcblxuICAgIGNhc2UgVHlwZS5RVU9URV9TSU5HTEU6XG4gICAgICByZXR1cm4gbmV3IFF1b3RlU2luZ2xlKHR5cGUsIHByb3BzKTtcblxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgLy8gc2hvdWxkIG5ldmVyIGhhcHBlblxuICB9XG59XG4vKipcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gYXRMaW5lU3RhcnQgLSBOb2RlIHN0YXJ0cyBhdCBiZWdpbm5pbmcgb2YgbGluZVxuICogQHBhcmFtIHtib29sZWFufSBpbkZsb3cgLSB0cnVlIGlmIGN1cnJlbnRseSBpbiBhIGZsb3cgY29udGV4dFxuICogQHBhcmFtIHtib29sZWFufSBpbkNvbGxlY3Rpb24gLSB0cnVlIGlmIGN1cnJlbnRseSBpbiBhIGNvbGxlY3Rpb24gY29udGV4dFxuICogQHBhcmFtIHtudW1iZXJ9IGluZGVudCAtIEN1cnJlbnQgbGV2ZWwgb2YgaW5kZW50YXRpb25cbiAqIEBwYXJhbSB7bnVtYmVyfSBsaW5lU3RhcnQgLSBTdGFydCBvZiB0aGUgY3VycmVudCBsaW5lXG4gKiBAcGFyYW0ge05vZGV9IHBhcmVudCAtIFRoZSBwYXJlbnQgb2YgdGhlIG5vZGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBzcmMgLSBTb3VyY2Ugb2YgdGhlIFlBTUwgZG9jdW1lbnRcbiAqL1xuXG5cbmNsYXNzIFBhcnNlQ29udGV4dCB7XG4gIHN0YXRpYyBwYXJzZVR5cGUoc3JjLCBvZmZzZXQsIGluRmxvdykge1xuICAgIHN3aXRjaCAoc3JjW29mZnNldF0pIHtcbiAgICAgIGNhc2UgJyonOlxuICAgICAgICByZXR1cm4gVHlwZS5BTElBUztcblxuICAgICAgY2FzZSAnPic6XG4gICAgICAgIHJldHVybiBUeXBlLkJMT0NLX0ZPTERFRDtcblxuICAgICAgY2FzZSAnfCc6XG4gICAgICAgIHJldHVybiBUeXBlLkJMT0NLX0xJVEVSQUw7XG5cbiAgICAgIGNhc2UgJ3snOlxuICAgICAgICByZXR1cm4gVHlwZS5GTE9XX01BUDtcblxuICAgICAgY2FzZSAnWyc6XG4gICAgICAgIHJldHVybiBUeXBlLkZMT1dfU0VRO1xuXG4gICAgICBjYXNlICc/JzpcbiAgICAgICAgcmV0dXJuICFpbkZsb3cgJiYgTm9kZS5hdEJsYW5rKHNyYywgb2Zmc2V0ICsgMSwgdHJ1ZSkgPyBUeXBlLk1BUF9LRVkgOiBUeXBlLlBMQUlOO1xuXG4gICAgICBjYXNlICc6JzpcbiAgICAgICAgcmV0dXJuICFpbkZsb3cgJiYgTm9kZS5hdEJsYW5rKHNyYywgb2Zmc2V0ICsgMSwgdHJ1ZSkgPyBUeXBlLk1BUF9WQUxVRSA6IFR5cGUuUExBSU47XG5cbiAgICAgIGNhc2UgJy0nOlxuICAgICAgICByZXR1cm4gIWluRmxvdyAmJiBOb2RlLmF0Qmxhbmsoc3JjLCBvZmZzZXQgKyAxLCB0cnVlKSA/IFR5cGUuU0VRX0lURU0gOiBUeXBlLlBMQUlOO1xuXG4gICAgICBjYXNlICdcIic6XG4gICAgICAgIHJldHVybiBUeXBlLlFVT1RFX0RPVUJMRTtcblxuICAgICAgY2FzZSBcIidcIjpcbiAgICAgICAgcmV0dXJuIFR5cGUuUVVPVEVfU0lOR0xFO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gVHlwZS5QTEFJTjtcbiAgICB9XG4gIH1cblxuICBjb25zdHJ1Y3RvcihvcmlnID0ge30sIHtcbiAgICBhdExpbmVTdGFydCxcbiAgICBpbkNvbGxlY3Rpb24sXG4gICAgaW5GbG93LFxuICAgIGluZGVudCxcbiAgICBsaW5lU3RhcnQsXG4gICAgcGFyZW50XG4gIH0gPSB7fSkge1xuICAgIF9kZWZpbmVQcm9wZXJ0eSh0aGlzLCBcInBhcnNlTm9kZVwiLCAob3ZlcmxheSwgc3RhcnQpID0+IHtcbiAgICAgIGlmIChOb2RlLmF0RG9jdW1lbnRCb3VuZGFyeSh0aGlzLnNyYywgc3RhcnQpKSByZXR1cm4gbnVsbDtcbiAgICAgIGNvbnN0IGNvbnRleHQgPSBuZXcgUGFyc2VDb250ZXh0KHRoaXMsIG92ZXJsYXkpO1xuICAgICAgY29uc3Qge1xuICAgICAgICBwcm9wcyxcbiAgICAgICAgdHlwZSxcbiAgICAgICAgdmFsdWVTdGFydFxuICAgICAgfSA9IGNvbnRleHQucGFyc2VQcm9wcyhzdGFydCk7XG4gICAgICBjb25zdCBub2RlID0gY3JlYXRlTmV3Tm9kZSh0eXBlLCBwcm9wcyk7XG4gICAgICBsZXQgb2Zmc2V0ID0gbm9kZS5wYXJzZShjb250ZXh0LCB2YWx1ZVN0YXJ0KTtcbiAgICAgIG5vZGUucmFuZ2UgPSBuZXcgUmFuZ2Uoc3RhcnQsIG9mZnNldCk7XG4gICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cblxuICAgICAgaWYgKG9mZnNldCA8PSBzdGFydCkge1xuICAgICAgICAvLyBUaGlzIHNob3VsZCBuZXZlciBoYXBwZW4sIGJ1dCBpZiBpdCBkb2VzLCBsZXQncyBtYWtlIHN1cmUgdG8gYXQgbGVhc3RcbiAgICAgICAgLy8gc3RlcCBvbmUgY2hhcmFjdGVyIGZvcndhcmQgdG8gYXZvaWQgYSBidXN5IGxvb3AuXG4gICAgICAgIG5vZGUuZXJyb3IgPSBuZXcgRXJyb3IoXCJOb2RlI3BhcnNlIGNvbnN1bWVkIG5vIGNoYXJhY3RlcnNcIik7XG4gICAgICAgIG5vZGUuZXJyb3IucGFyc2VFbmQgPSBvZmZzZXQ7XG4gICAgICAgIG5vZGUuZXJyb3Iuc291cmNlID0gbm9kZTtcbiAgICAgICAgbm9kZS5yYW5nZS5lbmQgPSBzdGFydCArIDE7XG4gICAgICB9XG5cbiAgICAgIGlmIChjb250ZXh0Lm5vZGVTdGFydHNDb2xsZWN0aW9uKG5vZGUpKSB7XG4gICAgICAgIGlmICghbm9kZS5lcnJvciAmJiAhY29udGV4dC5hdExpbmVTdGFydCAmJiBjb250ZXh0LnBhcmVudC50eXBlID09PSBUeXBlLkRPQ1VNRU5UKSB7XG4gICAgICAgICAgbm9kZS5lcnJvciA9IG5ldyBZQU1MU3ludGF4RXJyb3Iobm9kZSwgJ0Jsb2NrIGNvbGxlY3Rpb24gbXVzdCBub3QgaGF2ZSBwcmVjZWRpbmcgY29udGVudCBoZXJlIChlLmcuIGRpcmVjdGl2ZXMtZW5kIGluZGljYXRvciknKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNvbGxlY3Rpb24gPSBuZXcgQ29sbGVjdGlvbihub2RlKTtcbiAgICAgICAgb2Zmc2V0ID0gY29sbGVjdGlvbi5wYXJzZShuZXcgUGFyc2VDb250ZXh0KGNvbnRleHQpLCBvZmZzZXQpO1xuICAgICAgICBjb2xsZWN0aW9uLnJhbmdlID0gbmV3IFJhbmdlKHN0YXJ0LCBvZmZzZXQpO1xuICAgICAgICByZXR1cm4gY29sbGVjdGlvbjtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG5vZGU7XG4gICAgfSk7XG5cbiAgICB0aGlzLmF0TGluZVN0YXJ0ID0gYXRMaW5lU3RhcnQgIT0gbnVsbCA/IGF0TGluZVN0YXJ0IDogb3JpZy5hdExpbmVTdGFydCB8fCBmYWxzZTtcbiAgICB0aGlzLmluQ29sbGVjdGlvbiA9IGluQ29sbGVjdGlvbiAhPSBudWxsID8gaW5Db2xsZWN0aW9uIDogb3JpZy5pbkNvbGxlY3Rpb24gfHwgZmFsc2U7XG4gICAgdGhpcy5pbkZsb3cgPSBpbkZsb3cgIT0gbnVsbCA/IGluRmxvdyA6IG9yaWcuaW5GbG93IHx8IGZhbHNlO1xuICAgIHRoaXMuaW5kZW50ID0gaW5kZW50ICE9IG51bGwgPyBpbmRlbnQgOiBvcmlnLmluZGVudDtcbiAgICB0aGlzLmxpbmVTdGFydCA9IGxpbmVTdGFydCAhPSBudWxsID8gbGluZVN0YXJ0IDogb3JpZy5saW5lU3RhcnQ7XG4gICAgdGhpcy5wYXJlbnQgPSBwYXJlbnQgIT0gbnVsbCA/IHBhcmVudCA6IG9yaWcucGFyZW50IHx8IHt9O1xuICAgIHRoaXMucm9vdCA9IG9yaWcucm9vdDtcbiAgICB0aGlzLnNyYyA9IG9yaWcuc3JjO1xuICB9XG5cbiAgbm9kZVN0YXJ0c0NvbGxlY3Rpb24obm9kZSkge1xuICAgIGNvbnN0IHtcbiAgICAgIGluQ29sbGVjdGlvbixcbiAgICAgIGluRmxvdyxcbiAgICAgIHNyY1xuICAgIH0gPSB0aGlzO1xuICAgIGlmIChpbkNvbGxlY3Rpb24gfHwgaW5GbG93KSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBDb2xsZWN0aW9uSXRlbSkgcmV0dXJuIHRydWU7IC8vIGNoZWNrIGZvciBpbXBsaWNpdCBrZXlcblxuICAgIGxldCBvZmZzZXQgPSBub2RlLnJhbmdlLmVuZDtcbiAgICBpZiAoc3JjW29mZnNldF0gPT09ICdcXG4nIHx8IHNyY1tvZmZzZXQgLSAxXSA9PT0gJ1xcbicpIHJldHVybiBmYWxzZTtcbiAgICBvZmZzZXQgPSBOb2RlLmVuZE9mV2hpdGVTcGFjZShzcmMsIG9mZnNldCk7XG4gICAgcmV0dXJuIHNyY1tvZmZzZXRdID09PSAnOic7XG4gIH0gLy8gQW5jaG9yIGFuZCB0YWcgYXJlIGJlZm9yZSB0eXBlLCB3aGljaCBkZXRlcm1pbmVzIHRoZSBub2RlIGltcGxlbWVudGF0aW9uXG4gIC8vIGNsYXNzOyBoZW5jZSB0aGlzIGludGVybWVkaWF0ZSBzdGVwLlxuXG5cbiAgcGFyc2VQcm9wcyhvZmZzZXQpIHtcbiAgICBjb25zdCB7XG4gICAgICBpbkZsb3csXG4gICAgICBwYXJlbnQsXG4gICAgICBzcmNcbiAgICB9ID0gdGhpcztcbiAgICBjb25zdCBwcm9wcyA9IFtdO1xuICAgIGxldCBsaW5lSGFzUHJvcHMgPSBmYWxzZTtcbiAgICBvZmZzZXQgPSB0aGlzLmF0TGluZVN0YXJ0ID8gTm9kZS5lbmRPZkluZGVudChzcmMsIG9mZnNldCkgOiBOb2RlLmVuZE9mV2hpdGVTcGFjZShzcmMsIG9mZnNldCk7XG4gICAgbGV0IGNoID0gc3JjW29mZnNldF07XG5cbiAgICB3aGlsZSAoY2ggPT09IENoYXIuQU5DSE9SIHx8IGNoID09PSBDaGFyLkNPTU1FTlQgfHwgY2ggPT09IENoYXIuVEFHIHx8IGNoID09PSAnXFxuJykge1xuICAgICAgaWYgKGNoID09PSAnXFxuJykge1xuICAgICAgICBjb25zdCBsaW5lU3RhcnQgPSBvZmZzZXQgKyAxO1xuICAgICAgICBjb25zdCBpbkVuZCA9IE5vZGUuZW5kT2ZJbmRlbnQoc3JjLCBsaW5lU3RhcnQpO1xuICAgICAgICBjb25zdCBpbmRlbnREaWZmID0gaW5FbmQgLSAobGluZVN0YXJ0ICsgdGhpcy5pbmRlbnQpO1xuICAgICAgICBjb25zdCBub0luZGljYXRvckFzSW5kZW50ID0gcGFyZW50LnR5cGUgPT09IFR5cGUuU0VRX0lURU0gJiYgcGFyZW50LmNvbnRleHQuYXRMaW5lU3RhcnQ7XG4gICAgICAgIGlmICghTm9kZS5uZXh0Tm9kZUlzSW5kZW50ZWQoc3JjW2luRW5kXSwgaW5kZW50RGlmZiwgIW5vSW5kaWNhdG9yQXNJbmRlbnQpKSBicmVhaztcbiAgICAgICAgdGhpcy5hdExpbmVTdGFydCA9IHRydWU7XG4gICAgICAgIHRoaXMubGluZVN0YXJ0ID0gbGluZVN0YXJ0O1xuICAgICAgICBsaW5lSGFzUHJvcHMgPSBmYWxzZTtcbiAgICAgICAgb2Zmc2V0ID0gaW5FbmQ7XG4gICAgICB9IGVsc2UgaWYgKGNoID09PSBDaGFyLkNPTU1FTlQpIHtcbiAgICAgICAgY29uc3QgZW5kID0gTm9kZS5lbmRPZkxpbmUoc3JjLCBvZmZzZXQgKyAxKTtcbiAgICAgICAgcHJvcHMucHVzaChuZXcgUmFuZ2Uob2Zmc2V0LCBlbmQpKTtcbiAgICAgICAgb2Zmc2V0ID0gZW5kO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGV0IGVuZCA9IE5vZGUuZW5kT2ZJZGVudGlmaWVyKHNyYywgb2Zmc2V0ICsgMSk7XG5cbiAgICAgICAgaWYgKGNoID09PSBDaGFyLlRBRyAmJiBzcmNbZW5kXSA9PT0gJywnICYmIC9eW2EtekEtWjAtOS1dK1xcLlthLXpBLVowLTktXSssXFxkXFxkXFxkXFxkKC1cXGRcXGQpezAsMn1cXC9cXFMvLnRlc3Qoc3JjLnNsaWNlKG9mZnNldCArIDEsIGVuZCArIDEzKSkpIHtcbiAgICAgICAgICAvLyBMZXQncyBwcmVzdW1lIHdlJ3JlIGRlYWxpbmcgd2l0aCBhIFlBTUwgMS4wIGRvbWFpbiB0YWcgaGVyZSwgcmF0aGVyXG4gICAgICAgICAgLy8gdGhhbiBhbiBlbXB0eSBidXQgJ2Zvby5iYXInIHByaXZhdGUtdGFnZ2VkIG5vZGUgaW4gYSBmbG93IGNvbGxlY3Rpb25cbiAgICAgICAgICAvLyBmb2xsb3dlZCB3aXRob3V0IHdoaXRlc3BhY2UgYnkgYSBwbGFpbiBzdHJpbmcgc3RhcnRpbmcgd2l0aCBhIHllYXJcbiAgICAgICAgICAvLyBvciBkYXRlIGRpdmlkZWQgYnkgc29tZXRoaW5nLlxuICAgICAgICAgIGVuZCA9IE5vZGUuZW5kT2ZJZGVudGlmaWVyKHNyYywgZW5kICsgNSk7XG4gICAgICAgIH1cblxuICAgICAgICBwcm9wcy5wdXNoKG5ldyBSYW5nZShvZmZzZXQsIGVuZCkpO1xuICAgICAgICBsaW5lSGFzUHJvcHMgPSB0cnVlO1xuICAgICAgICBvZmZzZXQgPSBOb2RlLmVuZE9mV2hpdGVTcGFjZShzcmMsIGVuZCk7XG4gICAgICB9XG5cbiAgICAgIGNoID0gc3JjW29mZnNldF07XG4gICAgfSAvLyAnLSAmYSA6IGInIGhhcyBhbiBhbmNob3Igb24gYW4gZW1wdHkgbm9kZVxuXG5cbiAgICBpZiAobGluZUhhc1Byb3BzICYmIGNoID09PSAnOicgJiYgTm9kZS5hdEJsYW5rKHNyYywgb2Zmc2V0ICsgMSwgdHJ1ZSkpIG9mZnNldCAtPSAxO1xuICAgIGNvbnN0IHR5cGUgPSBQYXJzZUNvbnRleHQucGFyc2VUeXBlKHNyYywgb2Zmc2V0LCBpbkZsb3cpO1xuICAgIHJldHVybiB7XG4gICAgICBwcm9wcyxcbiAgICAgIHR5cGUsXG4gICAgICB2YWx1ZVN0YXJ0OiBvZmZzZXRcbiAgICB9O1xuICB9XG4gIC8qKlxuICAgKiBQYXJzZXMgYSBub2RlIGZyb20gdGhlIHNvdXJjZVxuICAgKiBAcGFyYW0ge1BhcnNlQ29udGV4dH0gb3ZlcmxheVxuICAgKiBAcGFyYW0ge251bWJlcn0gc3RhcnQgLSBJbmRleCBvZiBmaXJzdCBub24td2hpdGVzcGFjZSBjaGFyYWN0ZXIgZm9yIHRoZSBub2RlXG4gICAqIEByZXR1cm5zIHs/Tm9kZX0gLSBudWxsIGlmIGF0IGEgZG9jdW1lbnQgYm91bmRhcnlcbiAgICovXG5cblxufVxuXG5leHBvcnQgeyBQYXJzZUNvbnRleHQgfTtcbiIsImltcG9ydCB7IERvY3VtZW50IH0gZnJvbSAnLi9Eb2N1bWVudC5qcyc7XG5pbXBvcnQgeyBQYXJzZUNvbnRleHQgfSBmcm9tICcuL1BhcnNlQ29udGV4dC5qcyc7XG5cbmZ1bmN0aW9uIHBhcnNlKHNyYykge1xuICBjb25zdCBjciA9IFtdO1xuXG4gIGlmIChzcmMuaW5kZXhPZignXFxyJykgIT09IC0xKSB7XG4gICAgc3JjID0gc3JjLnJlcGxhY2UoL1xcclxcbj8vZywgKG1hdGNoLCBvZmZzZXQpID0+IHtcbiAgICAgIGlmIChtYXRjaC5sZW5ndGggPiAxKSBjci5wdXNoKG9mZnNldCk7XG4gICAgICByZXR1cm4gJ1xcbic7XG4gICAgfSk7XG4gIH1cblxuICBjb25zdCBkb2N1bWVudHMgPSBbXTtcbiAgbGV0IG9mZnNldCA9IDA7XG5cbiAgZG8ge1xuICAgIGNvbnN0IGRvYyA9IG5ldyBEb2N1bWVudCgpO1xuICAgIGNvbnN0IGNvbnRleHQgPSBuZXcgUGFyc2VDb250ZXh0KHtcbiAgICAgIHNyY1xuICAgIH0pO1xuICAgIG9mZnNldCA9IGRvYy5wYXJzZShjb250ZXh0LCBvZmZzZXQpO1xuICAgIGRvY3VtZW50cy5wdXNoKGRvYyk7XG4gIH0gd2hpbGUgKG9mZnNldCA8IHNyYy5sZW5ndGgpO1xuXG4gIGRvY3VtZW50cy5zZXRPcmlnUmFuZ2VzID0gKCkgPT4ge1xuICAgIGlmIChjci5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTtcblxuICAgIGZvciAobGV0IGkgPSAxOyBpIDwgY3IubGVuZ3RoOyArK2kpIGNyW2ldIC09IGk7XG5cbiAgICBsZXQgY3JPZmZzZXQgPSAwO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkb2N1bWVudHMubGVuZ3RoOyArK2kpIHtcbiAgICAgIGNyT2Zmc2V0ID0gZG9jdW1lbnRzW2ldLnNldE9yaWdSYW5nZXMoY3IsIGNyT2Zmc2V0KTtcbiAgICB9XG5cbiAgICBjci5zcGxpY2UoMCwgY3IubGVuZ3RoKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfTtcblxuICBkb2N1bWVudHMudG9TdHJpbmcgPSAoKSA9PiBkb2N1bWVudHMuam9pbignLi4uXFxuJyk7XG5cbiAgcmV0dXJuIGRvY3VtZW50cztcbn1cblxuZXhwb3J0IHsgcGFyc2UgfTtcbiIsImltcG9ydCB7IFR5cGUgfSBmcm9tICcuLi9jb25zdGFudHMuanMnO1xuXG5jb25zdCBiaW5hcnlPcHRpb25zID0ge1xuICBkZWZhdWx0VHlwZTogVHlwZS5CTE9DS19MSVRFUkFMLFxuICBsaW5lV2lkdGg6IDc2XG59O1xuY29uc3QgYm9vbE9wdGlvbnMgPSB7XG4gIHRydWVTdHI6ICd0cnVlJyxcbiAgZmFsc2VTdHI6ICdmYWxzZSdcbn07XG5jb25zdCBpbnRPcHRpb25zID0ge1xuICBhc0JpZ0ludDogZmFsc2Vcbn07XG5jb25zdCBudWxsT3B0aW9ucyA9IHtcbiAgbnVsbFN0cjogJ251bGwnXG59O1xuY29uc3Qgc3RyT3B0aW9ucyA9IHtcbiAgZGVmYXVsdFR5cGU6IFR5cGUuUExBSU4sXG4gIGRlZmF1bHRLZXlUeXBlOiBUeXBlLlBMQUlOLFxuICBkZWZhdWx0UXVvdGVTaW5nbGU6IGZhbHNlLFxuICBkb3VibGVRdW90ZWQ6IHtcbiAgICBqc29uRW5jb2Rpbmc6IGZhbHNlLFxuICAgIG1pbk11bHRpTGluZUxlbmd0aDogNDBcbiAgfSxcbiAgZm9sZDoge1xuICAgIGxpbmVXaWR0aDogODAsXG4gICAgbWluQ29udGVudFdpZHRoOiAyMFxuICB9XG59O1xuXG5leHBvcnQgeyBiaW5hcnlPcHRpb25zLCBib29sT3B0aW9ucywgaW50T3B0aW9ucywgbnVsbE9wdGlvbnMsIHN0ck9wdGlvbnMgfTtcbiIsImltcG9ydCB7IGRlZmF1bHRUYWdQcmVmaXggfSBmcm9tICcuL2NvbnN0YW50cy5qcyc7XG5pbXBvcnQgeyBiaW5hcnlPcHRpb25zLCBib29sT3B0aW9ucywgaW50T3B0aW9ucywgbnVsbE9wdGlvbnMsIHN0ck9wdGlvbnMgfSBmcm9tICcuL3RhZ3Mvb3B0aW9ucy5qcyc7XG5cbmNvbnN0IGRlZmF1bHRPcHRpb25zID0ge1xuICBhbmNob3JQcmVmaXg6ICdhJyxcbiAgY3VzdG9tVGFnczogbnVsbCxcbiAgaW5kZW50OiAyLFxuICBpbmRlbnRTZXE6IHRydWUsXG4gIGtlZXBDc3ROb2RlczogZmFsc2UsXG4gIGtlZXBOb2RlVHlwZXM6IHRydWUsXG4gIGtlZXBVbmRlZmluZWQ6IGZhbHNlLFxuICBsb2dMZXZlbDogJ3dhcm4nLFxuICBtYXBBc01hcDogZmFsc2UsXG4gIG1heEFsaWFzQ291bnQ6IDEwMCxcbiAgcHJldHR5RXJyb3JzOiB0cnVlLFxuICBzaW1wbGVLZXlzOiBmYWxzZSxcbiAgdmVyc2lvbjogJzEuMidcbn07XG5jb25zdCBzY2FsYXJPcHRpb25zID0ge1xuICBnZXQgYmluYXJ5KCkge1xuICAgIHJldHVybiBiaW5hcnlPcHRpb25zO1xuICB9LFxuXG4gIHNldCBiaW5hcnkob3B0KSB7XG4gICAgT2JqZWN0LmFzc2lnbihiaW5hcnlPcHRpb25zLCBvcHQpO1xuICB9LFxuXG4gIGdldCBib29sKCkge1xuICAgIHJldHVybiBib29sT3B0aW9ucztcbiAgfSxcblxuICBzZXQgYm9vbChvcHQpIHtcbiAgICBPYmplY3QuYXNzaWduKGJvb2xPcHRpb25zLCBvcHQpO1xuICB9LFxuXG4gIGdldCBpbnQoKSB7XG4gICAgcmV0dXJuIGludE9wdGlvbnM7XG4gIH0sXG5cbiAgc2V0IGludChvcHQpIHtcbiAgICBPYmplY3QuYXNzaWduKGludE9wdGlvbnMsIG9wdCk7XG4gIH0sXG5cbiAgZ2V0IG51bGwoKSB7XG4gICAgcmV0dXJuIG51bGxPcHRpb25zO1xuICB9LFxuXG4gIHNldCBudWxsKG9wdCkge1xuICAgIE9iamVjdC5hc3NpZ24obnVsbE9wdGlvbnMsIG9wdCk7XG4gIH0sXG5cbiAgZ2V0IHN0cigpIHtcbiAgICByZXR1cm4gc3RyT3B0aW9ucztcbiAgfSxcblxuICBzZXQgc3RyKG9wdCkge1xuICAgIE9iamVjdC5hc3NpZ24oc3RyT3B0aW9ucywgb3B0KTtcbiAgfVxuXG59O1xuY29uc3QgZG9jdW1lbnRPcHRpb25zID0ge1xuICAnMS4wJzoge1xuICAgIHNjaGVtYTogJ3lhbWwtMS4xJyxcbiAgICBtZXJnZTogdHJ1ZSxcbiAgICB0YWdQcmVmaXhlczogW3tcbiAgICAgIGhhbmRsZTogJyEnLFxuICAgICAgcHJlZml4OiBkZWZhdWx0VGFnUHJlZml4XG4gICAgfSwge1xuICAgICAgaGFuZGxlOiAnISEnLFxuICAgICAgcHJlZml4OiAndGFnOnByaXZhdGUueWFtbC5vcmcsMjAwMjonXG4gICAgfV1cbiAgfSxcbiAgMS4xOiB7XG4gICAgc2NoZW1hOiAneWFtbC0xLjEnLFxuICAgIG1lcmdlOiB0cnVlLFxuICAgIHRhZ1ByZWZpeGVzOiBbe1xuICAgICAgaGFuZGxlOiAnIScsXG4gICAgICBwcmVmaXg6ICchJ1xuICAgIH0sIHtcbiAgICAgIGhhbmRsZTogJyEhJyxcbiAgICAgIHByZWZpeDogZGVmYXVsdFRhZ1ByZWZpeFxuICAgIH1dXG4gIH0sXG4gIDEuMjoge1xuICAgIHNjaGVtYTogJ2NvcmUnLFxuICAgIG1lcmdlOiBmYWxzZSxcbiAgICByZXNvbHZlS25vd25UYWdzOiB0cnVlLFxuICAgIHRhZ1ByZWZpeGVzOiBbe1xuICAgICAgaGFuZGxlOiAnIScsXG4gICAgICBwcmVmaXg6ICchJ1xuICAgIH0sIHtcbiAgICAgIGhhbmRsZTogJyEhJyxcbiAgICAgIHByZWZpeDogZGVmYXVsdFRhZ1ByZWZpeFxuICAgIH1dXG4gIH1cbn07XG5cbmV4cG9ydCB7IGRlZmF1bHRPcHRpb25zLCBkb2N1bWVudE9wdGlvbnMsIHNjYWxhck9wdGlvbnMgfTtcbiIsImZ1bmN0aW9uIGFkZENvbW1lbnRCZWZvcmUoc3RyLCBpbmRlbnQsIGNvbW1lbnQpIHtcbiAgaWYgKCFjb21tZW50KSByZXR1cm4gc3RyO1xuICBjb25zdCBjYyA9IGNvbW1lbnQucmVwbGFjZSgvW1xcc1xcU11eL2dtLCBcIiQmXCIuY29uY2F0KGluZGVudCwgXCIjXCIpKTtcbiAgcmV0dXJuIFwiI1wiLmNvbmNhdChjYywgXCJcXG5cIikuY29uY2F0KGluZGVudCkuY29uY2F0KHN0cik7XG59XG5mdW5jdGlvbiBhZGRDb21tZW50KHN0ciwgaW5kZW50LCBjb21tZW50KSB7XG4gIHJldHVybiAhY29tbWVudCA/IHN0ciA6IGNvbW1lbnQuaW5kZXhPZignXFxuJykgPT09IC0xID8gXCJcIi5jb25jYXQoc3RyLCBcIiAjXCIpLmNvbmNhdChjb21tZW50KSA6IFwiXCIuY29uY2F0KHN0ciwgXCJcXG5cIikgKyBjb21tZW50LnJlcGxhY2UoL14vZ20sIFwiXCIuY29uY2F0KGluZGVudCB8fCAnJywgXCIjXCIpKTtcbn1cblxuZXhwb3J0IHsgYWRkQ29tbWVudCwgYWRkQ29tbWVudEJlZm9yZSB9O1xuIiwiY2xhc3MgTm9kZSB7fVxuXG5leHBvcnQgeyBOb2RlIH07XG4iLCIvKipcbiAqIFJlY3Vyc2l2ZWx5IGNvbnZlcnQgYW55IG5vZGUgb3IgaXRzIGNvbnRlbnRzIHRvIG5hdGl2ZSBKYXZhU2NyaXB0XG4gKlxuICogQHBhcmFtIHZhbHVlIC0gVGhlIGlucHV0IHZhbHVlXG4gKiBAcGFyYW0ge3N0cmluZ3xudWxsfSBhcmcgLSBJZiBgdmFsdWVgIGRlZmluZXMgYSBgdG9KU09OKClgIG1ldGhvZCwgdXNlIHRoaXNcbiAqICAgYXMgaXRzIGZpcnN0IGFyZ3VtZW50XG4gKiBAcGFyYW0gY3R4IC0gQ29udmVyc2lvbiBjb250ZXh0LCBvcmlnaW5hbGx5IHNldCBpbiBEb2N1bWVudCN0b0pTKCkuIElmXG4gKiAgIGB7IGtlZXA6IHRydWUgfWAgaXMgbm90IHNldCwgb3V0cHV0IHNob3VsZCBiZSBzdWl0YWJsZSBmb3IgSlNPTlxuICogICBzdHJpbmdpZmljYXRpb24uXG4gKi9cbmZ1bmN0aW9uIHRvSlModmFsdWUsIGFyZywgY3R4KSB7XG4gIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkgcmV0dXJuIHZhbHVlLm1hcCgodiwgaSkgPT4gdG9KUyh2LCBTdHJpbmcoaSksIGN0eCkpO1xuXG4gIGlmICh2YWx1ZSAmJiB0eXBlb2YgdmFsdWUudG9KU09OID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY29uc3QgYW5jaG9yID0gY3R4ICYmIGN0eC5hbmNob3JzICYmIGN0eC5hbmNob3JzLmdldCh2YWx1ZSk7XG4gICAgaWYgKGFuY2hvcikgY3R4Lm9uQ3JlYXRlID0gcmVzID0+IHtcbiAgICAgIGFuY2hvci5yZXMgPSByZXM7XG4gICAgICBkZWxldGUgY3R4Lm9uQ3JlYXRlO1xuICAgIH07XG4gICAgY29uc3QgcmVzID0gdmFsdWUudG9KU09OKGFyZywgY3R4KTtcbiAgICBpZiAoYW5jaG9yICYmIGN0eC5vbkNyZWF0ZSkgY3R4Lm9uQ3JlYXRlKHJlcyk7XG4gICAgcmV0dXJuIHJlcztcbiAgfVxuXG4gIGlmICghKGN0eCAmJiBjdHgua2VlcCkgJiYgdHlwZW9mIHZhbHVlID09PSAnYmlnaW50JykgcmV0dXJuIE51bWJlcih2YWx1ZSk7XG4gIHJldHVybiB2YWx1ZTtcbn1cblxuZXhwb3J0IHsgdG9KUyB9O1xuIiwiaW1wb3J0IHsgTm9kZSB9IGZyb20gJy4vTm9kZS5qcyc7XG5pbXBvcnQgeyB0b0pTIH0gZnJvbSAnLi90b0pTLmpzJztcblxuY29uc3QgaXNTY2FsYXJWYWx1ZSA9IHZhbHVlID0+ICF2YWx1ZSB8fCB0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicgJiYgdHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JztcbmNsYXNzIFNjYWxhciBleHRlbmRzIE5vZGUge1xuICBjb25zdHJ1Y3Rvcih2YWx1ZSkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xuICB9XG5cbiAgdG9KU09OKGFyZywgY3R4KSB7XG4gICAgcmV0dXJuIGN0eCAmJiBjdHgua2VlcCA/IHRoaXMudmFsdWUgOiB0b0pTKHRoaXMudmFsdWUsIGFyZywgY3R4KTtcbiAgfVxuXG4gIHRvU3RyaW5nKCkge1xuICAgIHJldHVybiBTdHJpbmcodGhpcy52YWx1ZSk7XG4gIH1cblxufVxuXG5leHBvcnQgeyBTY2FsYXIsIGlzU2NhbGFyVmFsdWUgfTtcbiIsImltcG9ydCB7IE5vZGUgfSBmcm9tICcuLi9hc3QvTm9kZS5qcyc7XG5pbXBvcnQgeyBTY2FsYXIgfSBmcm9tICcuLi9hc3QvU2NhbGFyLmpzJztcbmltcG9ydCB7IGRlZmF1bHRUYWdQcmVmaXggfSBmcm9tICcuLi9jb25zdGFudHMuanMnO1xuXG5mdW5jdGlvbiBmaW5kVGFnT2JqZWN0KHZhbHVlLCB0YWdOYW1lLCB0YWdzKSB7XG4gIGlmICh0YWdOYW1lKSB7XG4gICAgY29uc3QgbWF0Y2ggPSB0YWdzLmZpbHRlcih0ID0+IHQudGFnID09PSB0YWdOYW1lKTtcbiAgICBjb25zdCB0YWdPYmogPSBtYXRjaC5maW5kKHQgPT4gIXQuZm9ybWF0KSB8fCBtYXRjaFswXTtcbiAgICBpZiAoIXRhZ09iaikgdGhyb3cgbmV3IEVycm9yKFwiVGFnIFwiLmNvbmNhdCh0YWdOYW1lLCBcIiBub3QgZm91bmRcIikpO1xuICAgIHJldHVybiB0YWdPYmo7XG4gIH1cblxuICByZXR1cm4gdGFncy5maW5kKHQgPT4gdC5pZGVudGlmeSAmJiB0LmlkZW50aWZ5KHZhbHVlKSAmJiAhdC5mb3JtYXQpO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVOb2RlKHZhbHVlLCB0YWdOYW1lLCBjdHgpIHtcbiAgaWYgKHZhbHVlIGluc3RhbmNlb2YgTm9kZSkgcmV0dXJuIHZhbHVlO1xuICBjb25zdCB7XG4gICAgb25BbGlhcyxcbiAgICBvblRhZ09iaixcbiAgICBwcmV2T2JqZWN0cyxcbiAgICB3cmFwU2NhbGFyc1xuICB9ID0gY3R4O1xuICBjb25zdCB7XG4gICAgbWFwLFxuICAgIHNlcSxcbiAgICB0YWdzXG4gIH0gPSBjdHguc2NoZW1hO1xuICBpZiAodGFnTmFtZSAmJiB0YWdOYW1lLnN0YXJ0c1dpdGgoJyEhJykpIHRhZ05hbWUgPSBkZWZhdWx0VGFnUHJlZml4ICsgdGFnTmFtZS5zbGljZSgyKTtcbiAgbGV0IHRhZ09iaiA9IGZpbmRUYWdPYmplY3QodmFsdWUsIHRhZ05hbWUsIHRhZ3MpO1xuXG4gIGlmICghdGFnT2JqKSB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZS50b0pTT04gPT09ICdmdW5jdGlvbicpIHZhbHVlID0gdmFsdWUudG9KU09OKCk7XG4gICAgaWYgKCF2YWx1ZSB8fCB0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnKSByZXR1cm4gd3JhcFNjYWxhcnMgPyBuZXcgU2NhbGFyKHZhbHVlKSA6IHZhbHVlO1xuICAgIHRhZ09iaiA9IHZhbHVlIGluc3RhbmNlb2YgTWFwID8gbWFwIDogdmFsdWVbU3ltYm9sLml0ZXJhdG9yXSA/IHNlcSA6IG1hcDtcbiAgfVxuXG4gIGlmIChvblRhZ09iaikge1xuICAgIG9uVGFnT2JqKHRhZ09iaik7XG4gICAgZGVsZXRlIGN0eC5vblRhZ09iajtcbiAgfSAvLyBEZXRlY3QgZHVwbGljYXRlIHJlZmVyZW5jZXMgdG8gdGhlIHNhbWUgb2JqZWN0ICYgdXNlIEFsaWFzIG5vZGVzIGZvciBhbGxcbiAgLy8gYWZ0ZXIgZmlyc3QuIFRoZSBgb2JqYCB3cmFwcGVyIGFsbG93cyBmb3IgY2lyY3VsYXIgcmVmZXJlbmNlcyB0byByZXNvbHZlLlxuXG5cbiAgY29uc3Qgb2JqID0ge1xuICAgIHZhbHVlOiB1bmRlZmluZWQsXG4gICAgbm9kZTogdW5kZWZpbmVkXG4gIH07XG5cbiAgaWYgKHZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcpIHtcbiAgICBjb25zdCBwcmV2ID0gcHJldk9iamVjdHMuZ2V0KHZhbHVlKTtcbiAgICBpZiAocHJldikgcmV0dXJuIG9uQWxpYXMocHJldik7XG4gICAgb2JqLnZhbHVlID0gdmFsdWU7XG4gICAgcHJldk9iamVjdHMuc2V0KHZhbHVlLCBvYmopO1xuICB9XG5cbiAgb2JqLm5vZGUgPSB0YWdPYmouY3JlYXRlTm9kZSA/IHRhZ09iai5jcmVhdGVOb2RlKGN0eC5zY2hlbWEsIHZhbHVlLCBjdHgpIDogd3JhcFNjYWxhcnMgPyBuZXcgU2NhbGFyKHZhbHVlKSA6IHZhbHVlO1xuICBpZiAodGFnTmFtZSAmJiBvYmoubm9kZSBpbnN0YW5jZW9mIE5vZGUpIG9iai5ub2RlLnRhZyA9IHRhZ05hbWU7XG4gIHJldHVybiBvYmoubm9kZTtcbn1cblxuZXhwb3J0IHsgY3JlYXRlTm9kZSB9O1xuIiwiaW1wb3J0IHsgZGVmaW5lUHJvcGVydHkgYXMgX2RlZmluZVByb3BlcnR5IH0gZnJvbSAnLi4vX3ZpcnR1YWwvX3JvbGx1cFBsdWdpbkJhYmVsSGVscGVycy5qcyc7XG5pbXBvcnQgeyBhZGRDb21tZW50IH0gZnJvbSAnLi4vc3RyaW5naWZ5L2FkZENvbW1lbnQuanMnO1xuaW1wb3J0IHsgVHlwZSB9IGZyb20gJy4uL2NvbnN0YW50cy5qcyc7XG5pbXBvcnQgeyBjcmVhdGVOb2RlIH0gZnJvbSAnLi4vZG9jL2NyZWF0ZU5vZGUuanMnO1xuaW1wb3J0IHsgTm9kZSB9IGZyb20gJy4vTm9kZS5qcyc7XG5pbXBvcnQgeyBTY2FsYXIgfSBmcm9tICcuL1NjYWxhci5qcyc7XG5cbmZ1bmN0aW9uIGNvbGxlY3Rpb25Gcm9tUGF0aChzY2hlbWEsIHBhdGgsIHZhbHVlKSB7XG4gIGxldCB2ID0gdmFsdWU7XG5cbiAgZm9yIChsZXQgaSA9IHBhdGgubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICBjb25zdCBrID0gcGF0aFtpXTtcblxuICAgIGlmIChOdW1iZXIuaXNJbnRlZ2VyKGspICYmIGsgPj0gMCkge1xuICAgICAgY29uc3QgYSA9IFtdO1xuICAgICAgYVtrXSA9IHY7XG4gICAgICB2ID0gYTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgbyA9IHt9O1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIGssIHtcbiAgICAgICAgdmFsdWU6IHYsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgIH0pO1xuICAgICAgdiA9IG87XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGNyZWF0ZU5vZGUodiwgbnVsbCwge1xuICAgIG9uQWxpYXMoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1JlcGVhdGVkIG9iamVjdHMgYXJlIG5vdCBzdXBwb3J0ZWQgaGVyZScpO1xuICAgIH0sXG5cbiAgICBwcmV2T2JqZWN0czogbmV3IE1hcCgpLFxuICAgIHNjaGVtYSxcbiAgICB3cmFwU2NhbGFyczogZmFsc2VcbiAgfSk7XG59IC8vIG51bGwsIHVuZGVmaW5lZCwgb3IgYW4gZW1wdHkgbm9uLXN0cmluZyBpdGVyYWJsZSAoZS5nLiBbXSlcblxuY29uc3QgaXNFbXB0eVBhdGggPSBwYXRoID0+IHBhdGggPT0gbnVsbCB8fCB0eXBlb2YgcGF0aCA9PT0gJ29iamVjdCcgJiYgcGF0aFtTeW1ib2wuaXRlcmF0b3JdKCkubmV4dCgpLmRvbmU7XG5jbGFzcyBDb2xsZWN0aW9uIGV4dGVuZHMgTm9kZSB7XG4gIGNvbnN0cnVjdG9yKHNjaGVtYSkge1xuICAgIHN1cGVyKCk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkodGhpcywgXCJpdGVtc1wiLCBbXSk7XG5cbiAgICB0aGlzLnNjaGVtYSA9IHNjaGVtYTtcbiAgfVxuXG4gIGFkZEluKHBhdGgsIHZhbHVlKSB7XG4gICAgaWYgKGlzRW1wdHlQYXRoKHBhdGgpKSB0aGlzLmFkZCh2YWx1ZSk7ZWxzZSB7XG4gICAgICBjb25zdCBba2V5LCAuLi5yZXN0XSA9IHBhdGg7XG4gICAgICBjb25zdCBub2RlID0gdGhpcy5nZXQoa2V5LCB0cnVlKTtcbiAgICAgIGlmIChub2RlIGluc3RhbmNlb2YgQ29sbGVjdGlvbikgbm9kZS5hZGRJbihyZXN0LCB2YWx1ZSk7ZWxzZSBpZiAobm9kZSA9PT0gdW5kZWZpbmVkICYmIHRoaXMuc2NoZW1hKSB0aGlzLnNldChrZXksIGNvbGxlY3Rpb25Gcm9tUGF0aCh0aGlzLnNjaGVtYSwgcmVzdCwgdmFsdWUpKTtlbHNlIHRocm93IG5ldyBFcnJvcihcIkV4cGVjdGVkIFlBTUwgY29sbGVjdGlvbiBhdCBcIi5jb25jYXQoa2V5LCBcIi4gUmVtYWluaW5nIHBhdGg6IFwiKS5jb25jYXQocmVzdCkpO1xuICAgIH1cbiAgfVxuXG4gIGRlbGV0ZUluKFtrZXksIC4uLnJlc3RdKSB7XG4gICAgaWYgKHJlc3QubGVuZ3RoID09PSAwKSByZXR1cm4gdGhpcy5kZWxldGUoa2V5KTtcbiAgICBjb25zdCBub2RlID0gdGhpcy5nZXQoa2V5LCB0cnVlKTtcbiAgICBpZiAobm9kZSBpbnN0YW5jZW9mIENvbGxlY3Rpb24pIHJldHVybiBub2RlLmRlbGV0ZUluKHJlc3QpO2Vsc2UgdGhyb3cgbmV3IEVycm9yKFwiRXhwZWN0ZWQgWUFNTCBjb2xsZWN0aW9uIGF0IFwiLmNvbmNhdChrZXksIFwiLiBSZW1haW5pbmcgcGF0aDogXCIpLmNvbmNhdChyZXN0KSk7XG4gIH1cblxuICBnZXRJbihba2V5LCAuLi5yZXN0XSwga2VlcFNjYWxhcikge1xuICAgIGNvbnN0IG5vZGUgPSB0aGlzLmdldChrZXksIHRydWUpO1xuICAgIGlmIChyZXN0Lmxlbmd0aCA9PT0gMCkgcmV0dXJuICFrZWVwU2NhbGFyICYmIG5vZGUgaW5zdGFuY2VvZiBTY2FsYXIgPyBub2RlLnZhbHVlIDogbm9kZTtlbHNlIHJldHVybiBub2RlIGluc3RhbmNlb2YgQ29sbGVjdGlvbiA/IG5vZGUuZ2V0SW4ocmVzdCwga2VlcFNjYWxhcikgOiB1bmRlZmluZWQ7XG4gIH1cblxuICBoYXNBbGxOdWxsVmFsdWVzKCkge1xuICAgIHJldHVybiB0aGlzLml0ZW1zLmV2ZXJ5KG5vZGUgPT4ge1xuICAgICAgaWYgKCFub2RlIHx8IG5vZGUudHlwZSAhPT0gJ1BBSVInKSByZXR1cm4gZmFsc2U7XG4gICAgICBjb25zdCBuID0gbm9kZS52YWx1ZTtcbiAgICAgIHJldHVybiBuID09IG51bGwgfHwgbiBpbnN0YW5jZW9mIFNjYWxhciAmJiBuLnZhbHVlID09IG51bGwgJiYgIW4uY29tbWVudEJlZm9yZSAmJiAhbi5jb21tZW50ICYmICFuLnRhZztcbiAgICB9KTtcbiAgfVxuXG4gIGhhc0luKFtrZXksIC4uLnJlc3RdKSB7XG4gICAgaWYgKHJlc3QubGVuZ3RoID09PSAwKSByZXR1cm4gdGhpcy5oYXMoa2V5KTtcbiAgICBjb25zdCBub2RlID0gdGhpcy5nZXQoa2V5LCB0cnVlKTtcbiAgICByZXR1cm4gbm9kZSBpbnN0YW5jZW9mIENvbGxlY3Rpb24gPyBub2RlLmhhc0luKHJlc3QpIDogZmFsc2U7XG4gIH1cblxuICBzZXRJbihba2V5LCAuLi5yZXN0XSwgdmFsdWUpIHtcbiAgICBpZiAocmVzdC5sZW5ndGggPT09IDApIHtcbiAgICAgIHRoaXMuc2V0KGtleSwgdmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBub2RlID0gdGhpcy5nZXQoa2V5LCB0cnVlKTtcbiAgICAgIGlmIChub2RlIGluc3RhbmNlb2YgQ29sbGVjdGlvbikgbm9kZS5zZXRJbihyZXN0LCB2YWx1ZSk7ZWxzZSBpZiAobm9kZSA9PT0gdW5kZWZpbmVkICYmIHRoaXMuc2NoZW1hKSB0aGlzLnNldChrZXksIGNvbGxlY3Rpb25Gcm9tUGF0aCh0aGlzLnNjaGVtYSwgcmVzdCwgdmFsdWUpKTtlbHNlIHRocm93IG5ldyBFcnJvcihcIkV4cGVjdGVkIFlBTUwgY29sbGVjdGlvbiBhdCBcIi5jb25jYXQoa2V5LCBcIi4gUmVtYWluaW5nIHBhdGg6IFwiKS5jb25jYXQocmVzdCkpO1xuICAgIH1cbiAgfVxuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dDogb3ZlcnJpZGRlbiBpbiBpbXBsZW1lbnRhdGlvbnMgKi9cblxuXG4gIHRvSlNPTigpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHRvU3RyaW5nKGN0eCwge1xuICAgIGJsb2NrSXRlbSxcbiAgICBmbG93Q2hhcnMsXG4gICAgaXNNYXAsXG4gICAgaXRlbUluZGVudFxuICB9LCBvbkNvbW1lbnQsIG9uQ2hvbXBLZWVwKSB7XG4gICAgY29uc3Qge1xuICAgICAgaW5kZW50LFxuICAgICAgaW5kZW50U3RlcCxcbiAgICAgIHN0cmluZ2lmeVxuICAgIH0gPSBjdHg7XG4gICAgY29uc3QgaW5GbG93ID0gdGhpcy50eXBlID09PSBUeXBlLkZMT1dfTUFQIHx8IHRoaXMudHlwZSA9PT0gVHlwZS5GTE9XX1NFUSB8fCBjdHguaW5GbG93O1xuICAgIGlmIChpbkZsb3cpIGl0ZW1JbmRlbnQgKz0gaW5kZW50U3RlcDtcbiAgICBjb25zdCBhbGxOdWxsVmFsdWVzID0gaXNNYXAgJiYgdGhpcy5oYXNBbGxOdWxsVmFsdWVzKCk7XG4gICAgY3R4ID0gT2JqZWN0LmFzc2lnbih7fSwgY3R4LCB7XG4gICAgICBhbGxOdWxsVmFsdWVzLFxuICAgICAgaW5kZW50OiBpdGVtSW5kZW50LFxuICAgICAgaW5GbG93LFxuICAgICAgdHlwZTogbnVsbFxuICAgIH0pO1xuICAgIGxldCBjaG9tcEtlZXAgPSBmYWxzZTtcbiAgICBsZXQgaGFzSXRlbVdpdGhOZXdMaW5lID0gZmFsc2U7XG4gICAgY29uc3Qgbm9kZXMgPSB0aGlzLml0ZW1zLnJlZHVjZSgobm9kZXMsIGl0ZW0sIGkpID0+IHtcbiAgICAgIGxldCBjb21tZW50O1xuXG4gICAgICBpZiAoaXRlbSkge1xuICAgICAgICBpZiAoIWNob21wS2VlcCAmJiBpdGVtLnNwYWNlQmVmb3JlKSBub2Rlcy5wdXNoKHtcbiAgICAgICAgICB0eXBlOiAnY29tbWVudCcsXG4gICAgICAgICAgc3RyOiAnJ1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGl0ZW0uY29tbWVudEJlZm9yZSkgaXRlbS5jb21tZW50QmVmb3JlLm1hdGNoKC9eLiokL2dtKS5mb3JFYWNoKGxpbmUgPT4ge1xuICAgICAgICAgIG5vZGVzLnB1c2goe1xuICAgICAgICAgICAgdHlwZTogJ2NvbW1lbnQnLFxuICAgICAgICAgICAgc3RyOiBcIiNcIi5jb25jYXQobGluZSlcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChpdGVtLmNvbW1lbnQpIGNvbW1lbnQgPSBpdGVtLmNvbW1lbnQ7XG4gICAgICAgIGlmIChpbkZsb3cgJiYgKCFjaG9tcEtlZXAgJiYgaXRlbS5zcGFjZUJlZm9yZSB8fCBpdGVtLmNvbW1lbnRCZWZvcmUgfHwgaXRlbS5jb21tZW50IHx8IGl0ZW0ua2V5ICYmIChpdGVtLmtleS5jb21tZW50QmVmb3JlIHx8IGl0ZW0ua2V5LmNvbW1lbnQpIHx8IGl0ZW0udmFsdWUgJiYgKGl0ZW0udmFsdWUuY29tbWVudEJlZm9yZSB8fCBpdGVtLnZhbHVlLmNvbW1lbnQpKSkgaGFzSXRlbVdpdGhOZXdMaW5lID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgY2hvbXBLZWVwID0gZmFsc2U7XG4gICAgICBsZXQgc3RyID0gc3RyaW5naWZ5KGl0ZW0sIGN0eCwgKCkgPT4gY29tbWVudCA9IG51bGwsICgpID0+IGNob21wS2VlcCA9IHRydWUpO1xuICAgICAgaWYgKGluRmxvdyAmJiAhaGFzSXRlbVdpdGhOZXdMaW5lICYmIHN0ci5pbmNsdWRlcygnXFxuJykpIGhhc0l0ZW1XaXRoTmV3TGluZSA9IHRydWU7XG4gICAgICBpZiAoaW5GbG93ICYmIGkgPCB0aGlzLml0ZW1zLmxlbmd0aCAtIDEpIHN0ciArPSAnLCc7XG4gICAgICBzdHIgPSBhZGRDb21tZW50KHN0ciwgaXRlbUluZGVudCwgY29tbWVudCk7XG4gICAgICBpZiAoY2hvbXBLZWVwICYmIChjb21tZW50IHx8IGluRmxvdykpIGNob21wS2VlcCA9IGZhbHNlO1xuICAgICAgbm9kZXMucHVzaCh7XG4gICAgICAgIHR5cGU6ICdpdGVtJyxcbiAgICAgICAgc3RyXG4gICAgICB9KTtcbiAgICAgIHJldHVybiBub2RlcztcbiAgICB9LCBbXSk7XG4gICAgbGV0IHN0cjtcblxuICAgIGlmIChub2Rlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHN0ciA9IGZsb3dDaGFycy5zdGFydCArIGZsb3dDaGFycy5lbmQ7XG4gICAgfSBlbHNlIGlmIChpbkZsb3cpIHtcbiAgICAgIGNvbnN0IHtcbiAgICAgICAgc3RhcnQsXG4gICAgICAgIGVuZFxuICAgICAgfSA9IGZsb3dDaGFycztcbiAgICAgIGNvbnN0IHN0cmluZ3MgPSBub2Rlcy5tYXAobiA9PiBuLnN0cik7XG5cbiAgICAgIGlmIChoYXNJdGVtV2l0aE5ld0xpbmUgfHwgc3RyaW5ncy5yZWR1Y2UoKHN1bSwgc3RyKSA9PiBzdW0gKyBzdHIubGVuZ3RoICsgMiwgMikgPiBDb2xsZWN0aW9uLm1heEZsb3dTdHJpbmdTaW5nbGVMaW5lTGVuZ3RoKSB7XG4gICAgICAgIHN0ciA9IHN0YXJ0O1xuXG4gICAgICAgIGZvciAoY29uc3QgcyBvZiBzdHJpbmdzKSB7XG4gICAgICAgICAgc3RyICs9IHMgPyBcIlxcblwiLmNvbmNhdChpbmRlbnRTdGVwKS5jb25jYXQoaW5kZW50KS5jb25jYXQocykgOiAnXFxuJztcbiAgICAgICAgfVxuXG4gICAgICAgIHN0ciArPSBcIlxcblwiLmNvbmNhdChpbmRlbnQpLmNvbmNhdChlbmQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RyID0gXCJcIi5jb25jYXQoc3RhcnQsIFwiIFwiKS5jb25jYXQoc3RyaW5ncy5qb2luKCcgJyksIFwiIFwiKS5jb25jYXQoZW5kKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3Qgc3RyaW5ncyA9IG5vZGVzLm1hcChibG9ja0l0ZW0pO1xuICAgICAgc3RyID0gc3RyaW5ncy5zaGlmdCgpO1xuXG4gICAgICBmb3IgKGNvbnN0IHMgb2Ygc3RyaW5ncykgc3RyICs9IHMgPyBcIlxcblwiLmNvbmNhdChpbmRlbnQpLmNvbmNhdChzKSA6ICdcXG4nO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmNvbW1lbnQpIHtcbiAgICAgIHN0ciArPSAnXFxuJyArIHRoaXMuY29tbWVudC5yZXBsYWNlKC9eL2dtLCBcIlwiLmNvbmNhdChpbmRlbnQsIFwiI1wiKSk7XG4gICAgICBpZiAob25Db21tZW50KSBvbkNvbW1lbnQoKTtcbiAgICB9IGVsc2UgaWYgKGNob21wS2VlcCAmJiBvbkNob21wS2VlcCkgb25DaG9tcEtlZXAoKTtcblxuICAgIHJldHVybiBzdHI7XG4gIH1cblxufVxuXG5fZGVmaW5lUHJvcGVydHkoQ29sbGVjdGlvbiwgXCJtYXhGbG93U3RyaW5nU2luZ2xlTGluZUxlbmd0aFwiLCA2MCk7XG5cbmV4cG9ydCB7IENvbGxlY3Rpb24sIGNvbGxlY3Rpb25Gcm9tUGF0aCwgaXNFbXB0eVBhdGggfTtcbiIsImltcG9ydCB7IExvZ0xldmVsIH0gZnJvbSAnLi9jb25zdGFudHMuanMnO1xuXG4vKiBnbG9iYWwgY29uc29sZSwgcHJvY2VzcyAqL1xuZnVuY3Rpb24gd2Fybihsb2dMZXZlbCwgd2FybmluZykge1xuICBpZiAoTG9nTGV2ZWwuaW5kZXhPZihsb2dMZXZlbCkgPj0gTG9nTGV2ZWwuV0FSTikge1xuICAgIGlmICh0eXBlb2YgcHJvY2VzcyAhPT0gJ3VuZGVmaW5lZCcgJiYgcHJvY2Vzcy5lbWl0V2FybmluZykgcHJvY2Vzcy5lbWl0V2FybmluZyh3YXJuaW5nKTtlbHNlIGNvbnNvbGUud2Fybih3YXJuaW5nKTtcbiAgfVxufVxuXG5leHBvcnQgeyB3YXJuIH07XG4iLCJpbXBvcnQgeyBDb2xsZWN0aW9uIH0gZnJvbSAnLi9Db2xsZWN0aW9uLmpzJztcbmltcG9ydCB7IFNjYWxhciwgaXNTY2FsYXJWYWx1ZSB9IGZyb20gJy4vU2NhbGFyLmpzJztcbmltcG9ydCB7IHRvSlMgfSBmcm9tICcuL3RvSlMuanMnO1xuXG5mdW5jdGlvbiBhc0l0ZW1JbmRleChrZXkpIHtcbiAgbGV0IGlkeCA9IGtleSBpbnN0YW5jZW9mIFNjYWxhciA/IGtleS52YWx1ZSA6IGtleTtcbiAgaWYgKGlkeCAmJiB0eXBlb2YgaWR4ID09PSAnc3RyaW5nJykgaWR4ID0gTnVtYmVyKGlkeCk7XG4gIHJldHVybiBOdW1iZXIuaXNJbnRlZ2VyKGlkeCkgJiYgaWR4ID49IDAgPyBpZHggOiBudWxsO1xufVxuXG5jbGFzcyBZQU1MU2VxIGV4dGVuZHMgQ29sbGVjdGlvbiB7XG4gIGFkZCh2YWx1ZSkge1xuICAgIHRoaXMuaXRlbXMucHVzaCh2YWx1ZSk7XG4gIH1cblxuICBkZWxldGUoa2V5KSB7XG4gICAgY29uc3QgaWR4ID0gYXNJdGVtSW5kZXgoa2V5KTtcbiAgICBpZiAodHlwZW9mIGlkeCAhPT0gJ251bWJlcicpIHJldHVybiBmYWxzZTtcbiAgICBjb25zdCBkZWwgPSB0aGlzLml0ZW1zLnNwbGljZShpZHgsIDEpO1xuICAgIHJldHVybiBkZWwubGVuZ3RoID4gMDtcbiAgfVxuXG4gIGdldChrZXksIGtlZXBTY2FsYXIpIHtcbiAgICBjb25zdCBpZHggPSBhc0l0ZW1JbmRleChrZXkpO1xuICAgIGlmICh0eXBlb2YgaWR4ICE9PSAnbnVtYmVyJykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICBjb25zdCBpdCA9IHRoaXMuaXRlbXNbaWR4XTtcbiAgICByZXR1cm4gIWtlZXBTY2FsYXIgJiYgaXQgaW5zdGFuY2VvZiBTY2FsYXIgPyBpdC52YWx1ZSA6IGl0O1xuICB9XG5cbiAgaGFzKGtleSkge1xuICAgIGNvbnN0IGlkeCA9IGFzSXRlbUluZGV4KGtleSk7XG4gICAgcmV0dXJuIHR5cGVvZiBpZHggPT09ICdudW1iZXInICYmIGlkeCA8IHRoaXMuaXRlbXMubGVuZ3RoO1xuICB9XG5cbiAgc2V0KGtleSwgdmFsdWUpIHtcbiAgICBjb25zdCBpZHggPSBhc0l0ZW1JbmRleChrZXkpO1xuICAgIGlmICh0eXBlb2YgaWR4ICE9PSAnbnVtYmVyJykgdGhyb3cgbmV3IEVycm9yKFwiRXhwZWN0ZWQgYSB2YWxpZCBpbmRleCwgbm90IFwiLmNvbmNhdChrZXksIFwiLlwiKSk7XG4gICAgY29uc3QgcHJldiA9IHRoaXMuaXRlbXNbaWR4XTtcbiAgICBpZiAocHJldiBpbnN0YW5jZW9mIFNjYWxhciAmJiBpc1NjYWxhclZhbHVlKHZhbHVlKSkgcHJldi52YWx1ZSA9IHZhbHVlO2Vsc2UgdGhpcy5pdGVtc1tpZHhdID0gdmFsdWU7XG4gIH1cblxuICB0b0pTT04oXywgY3R4KSB7XG4gICAgY29uc3Qgc2VxID0gW107XG4gICAgaWYgKGN0eCAmJiBjdHgub25DcmVhdGUpIGN0eC5vbkNyZWF0ZShzZXEpO1xuICAgIGxldCBpID0gMDtcblxuICAgIGZvciAoY29uc3QgaXRlbSBvZiB0aGlzLml0ZW1zKSBzZXEucHVzaCh0b0pTKGl0ZW0sIFN0cmluZyhpKyspLCBjdHgpKTtcblxuICAgIHJldHVybiBzZXE7XG4gIH1cblxuICB0b1N0cmluZyhjdHgsIG9uQ29tbWVudCwgb25DaG9tcEtlZXApIHtcbiAgICBpZiAoIWN0eCkgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHRoaXMpO1xuICAgIHJldHVybiBzdXBlci50b1N0cmluZyhjdHgsIHtcbiAgICAgIGJsb2NrSXRlbTogbiA9PiBuLnR5cGUgPT09ICdjb21tZW50JyA/IG4uc3RyIDogXCItIFwiLmNvbmNhdChuLnN0ciksXG4gICAgICBmbG93Q2hhcnM6IHtcbiAgICAgICAgc3RhcnQ6ICdbJyxcbiAgICAgICAgZW5kOiAnXSdcbiAgICAgIH0sXG4gICAgICBpc01hcDogZmFsc2UsXG4gICAgICBpdGVtSW5kZW50OiAoY3R4LmluZGVudCB8fCAnJykgKyAnICAnXG4gICAgfSwgb25Db21tZW50LCBvbkNob21wS2VlcCk7XG4gIH1cblxufVxuXG5leHBvcnQgeyBZQU1MU2VxIH07XG4iLCJpbXBvcnQgeyBkZWZpbmVQcm9wZXJ0eSBhcyBfZGVmaW5lUHJvcGVydHkgfSBmcm9tICcuLi9fdmlydHVhbC9fcm9sbHVwUGx1Z2luQmFiZWxIZWxwZXJzLmpzJztcbmltcG9ydCB7IFR5cGUgfSBmcm9tICcuLi9jb25zdGFudHMuanMnO1xuaW1wb3J0IHsgY3JlYXRlTm9kZSB9IGZyb20gJy4uL2RvYy9jcmVhdGVOb2RlLmpzJztcbmltcG9ydCB7IHdhcm4gfSBmcm9tICcuLi9sb2cuanMnO1xuaW1wb3J0IHsgYWRkQ29tbWVudCB9IGZyb20gJy4uL3N0cmluZ2lmeS9hZGRDb21tZW50LmpzJztcbmltcG9ydCB7IENvbGxlY3Rpb24gfSBmcm9tICcuL0NvbGxlY3Rpb24uanMnO1xuaW1wb3J0IHsgTm9kZSB9IGZyb20gJy4vTm9kZS5qcyc7XG5pbXBvcnQgeyBTY2FsYXIgfSBmcm9tICcuL1NjYWxhci5qcyc7XG5pbXBvcnQgeyBZQU1MU2VxIH0gZnJvbSAnLi9ZQU1MU2VxLmpzJztcbmltcG9ydCB7IHRvSlMgfSBmcm9tICcuL3RvSlMuanMnO1xuXG5mdW5jdGlvbiBzdHJpbmdpZnlLZXkoa2V5LCBqc0tleSwgY3R4KSB7XG4gIGlmIChqc0tleSA9PT0gbnVsbCkgcmV0dXJuICcnO1xuICBpZiAodHlwZW9mIGpzS2V5ICE9PSAnb2JqZWN0JykgcmV0dXJuIFN0cmluZyhqc0tleSk7XG5cbiAgaWYgKGtleSBpbnN0YW5jZW9mIE5vZGUgJiYgY3R4ICYmIGN0eC5kb2MpIHtcbiAgICBjb25zdCBzdHJLZXkgPSBrZXkudG9TdHJpbmcoe1xuICAgICAgYW5jaG9yczogT2JqZWN0LmNyZWF0ZShudWxsKSxcbiAgICAgIGRvYzogY3R4LmRvYyxcbiAgICAgIGluZGVudDogJycsXG4gICAgICBpbmRlbnRTdGVwOiBjdHguaW5kZW50U3RlcCxcbiAgICAgIGluRmxvdzogdHJ1ZSxcbiAgICAgIGluU3RyaW5naWZ5S2V5OiB0cnVlLFxuICAgICAgc3RyaW5naWZ5OiBjdHguc3RyaW5naWZ5XG4gICAgfSk7XG5cbiAgICBpZiAoIWN0eC5tYXBLZXlXYXJuZWQpIHtcbiAgICAgIGxldCBqc29uU3RyID0gSlNPTi5zdHJpbmdpZnkoc3RyS2V5KTtcbiAgICAgIGlmIChqc29uU3RyLmxlbmd0aCA+IDQwKSBqc29uU3RyID0ganNvblN0ci5zcGxpdCgnJykuc3BsaWNlKDM2LCAnLi4uXCInKS5qb2luKCcnKTtcbiAgICAgIHdhcm4oY3R4LmRvYy5vcHRpb25zLmxvZ0xldmVsLCBcIktleXMgd2l0aCBjb2xsZWN0aW9uIHZhbHVlcyB3aWxsIGJlIHN0cmluZ2lmaWVkIGR1ZSB0byBKUyBPYmplY3QgcmVzdHJpY3Rpb25zOiBcIi5jb25jYXQoanNvblN0ciwgXCIuIFNldCBtYXBBc01hcDogdHJ1ZSB0byB1c2Ugb2JqZWN0IGtleXMuXCIpKTtcbiAgICAgIGN0eC5tYXBLZXlXYXJuZWQgPSB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBzdHJLZXk7XG4gIH1cblxuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoanNLZXkpO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVQYWlyKGtleSwgdmFsdWUsIGN0eCkge1xuICBjb25zdCBrID0gY3JlYXRlTm9kZShrZXksIG51bGwsIGN0eCk7XG4gIGNvbnN0IHYgPSBjcmVhdGVOb2RlKHZhbHVlLCBudWxsLCBjdHgpO1xuICByZXR1cm4gbmV3IFBhaXIoaywgdik7XG59XG5jbGFzcyBQYWlyIGV4dGVuZHMgTm9kZSB7XG4gIGNvbnN0cnVjdG9yKGtleSwgdmFsdWUgPSBudWxsKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLmtleSA9IGtleTtcbiAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgdGhpcy50eXBlID0gUGFpci5UeXBlLlBBSVI7XG4gIH1cblxuICBnZXQgY29tbWVudEJlZm9yZSgpIHtcbiAgICByZXR1cm4gdGhpcy5rZXkgaW5zdGFuY2VvZiBOb2RlID8gdGhpcy5rZXkuY29tbWVudEJlZm9yZSA6IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHNldCBjb21tZW50QmVmb3JlKGNiKSB7XG4gICAgaWYgKHRoaXMua2V5ID09IG51bGwpIHRoaXMua2V5ID0gbmV3IFNjYWxhcihudWxsKTtcbiAgICBpZiAodGhpcy5rZXkgaW5zdGFuY2VvZiBOb2RlKSB0aGlzLmtleS5jb21tZW50QmVmb3JlID0gY2I7ZWxzZSB7XG4gICAgICBjb25zdCBtc2cgPSAnUGFpci5jb21tZW50QmVmb3JlIGlzIGFuIGFsaWFzIGZvciBQYWlyLmtleS5jb21tZW50QmVmb3JlLiBUbyBzZXQgaXQsIHRoZSBrZXkgbXVzdCBiZSBhIE5vZGUuJztcbiAgICAgIHRocm93IG5ldyBFcnJvcihtc2cpO1xuICAgIH1cbiAgfVxuXG4gIGFkZFRvSlNNYXAoY3R4LCBtYXApIHtcbiAgICBjb25zdCBrZXkgPSB0b0pTKHRoaXMua2V5LCAnJywgY3R4KTtcblxuICAgIGlmIChtYXAgaW5zdGFuY2VvZiBNYXApIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gdG9KUyh0aGlzLnZhbHVlLCBrZXksIGN0eCk7XG4gICAgICBtYXAuc2V0KGtleSwgdmFsdWUpO1xuICAgIH0gZWxzZSBpZiAobWFwIGluc3RhbmNlb2YgU2V0KSB7XG4gICAgICBtYXAuYWRkKGtleSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHN0cmluZ0tleSA9IHN0cmluZ2lmeUtleSh0aGlzLmtleSwga2V5LCBjdHgpO1xuICAgICAgY29uc3QgdmFsdWUgPSB0b0pTKHRoaXMudmFsdWUsIHN0cmluZ0tleSwgY3R4KTtcbiAgICAgIGlmIChzdHJpbmdLZXkgaW4gbWFwKSBPYmplY3QuZGVmaW5lUHJvcGVydHkobWFwLCBzdHJpbmdLZXksIHtcbiAgICAgICAgdmFsdWUsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgIH0pO2Vsc2UgbWFwW3N0cmluZ0tleV0gPSB2YWx1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gbWFwO1xuICB9XG5cbiAgdG9KU09OKF8sIGN0eCkge1xuICAgIGNvbnN0IHBhaXIgPSBjdHggJiYgY3R4Lm1hcEFzTWFwID8gbmV3IE1hcCgpIDoge307XG4gICAgcmV0dXJuIHRoaXMuYWRkVG9KU01hcChjdHgsIHBhaXIpO1xuICB9XG5cbiAgdG9TdHJpbmcoY3R4LCBvbkNvbW1lbnQsIG9uQ2hvbXBLZWVwKSB7XG4gICAgaWYgKCFjdHggfHwgIWN0eC5kb2MpIHJldHVybiBKU09OLnN0cmluZ2lmeSh0aGlzKTtcbiAgICBjb25zdCB7XG4gICAgICBpbmRlbnQ6IGluZGVudFNpemUsXG4gICAgICBpbmRlbnRTZXEsXG4gICAgICBzaW1wbGVLZXlzXG4gICAgfSA9IGN0eC5kb2Mub3B0aW9ucztcbiAgICBsZXQge1xuICAgICAga2V5LFxuICAgICAgdmFsdWVcbiAgICB9ID0gdGhpcztcbiAgICBsZXQga2V5Q29tbWVudCA9IGtleSBpbnN0YW5jZW9mIE5vZGUgJiYga2V5LmNvbW1lbnQ7XG5cbiAgICBpZiAoc2ltcGxlS2V5cykge1xuICAgICAgaWYgKGtleUNvbW1lbnQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdXaXRoIHNpbXBsZSBrZXlzLCBrZXkgbm9kZXMgY2Fubm90IGhhdmUgY29tbWVudHMnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGtleSBpbnN0YW5jZW9mIENvbGxlY3Rpb24pIHtcbiAgICAgICAgY29uc3QgbXNnID0gJ1dpdGggc2ltcGxlIGtleXMsIGNvbGxlY3Rpb24gY2Fubm90IGJlIHVzZWQgYXMgYSBrZXkgdmFsdWUnO1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBsZXQgZXhwbGljaXRLZXkgPSAhc2ltcGxlS2V5cyAmJiAoIWtleSB8fCBrZXlDb21tZW50IHx8IChrZXkgaW5zdGFuY2VvZiBOb2RlID8ga2V5IGluc3RhbmNlb2YgQ29sbGVjdGlvbiB8fCBrZXkudHlwZSA9PT0gVHlwZS5CTE9DS19GT0xERUQgfHwga2V5LnR5cGUgPT09IFR5cGUuQkxPQ0tfTElURVJBTCA6IHR5cGVvZiBrZXkgPT09ICdvYmplY3QnKSk7XG4gICAgY29uc3Qge1xuICAgICAgYWxsTnVsbFZhbHVlcyxcbiAgICAgIGRvYyxcbiAgICAgIGluZGVudCxcbiAgICAgIGluZGVudFN0ZXAsXG4gICAgICBzdHJpbmdpZnlcbiAgICB9ID0gY3R4O1xuICAgIGN0eCA9IE9iamVjdC5hc3NpZ24oe30sIGN0eCwge1xuICAgICAgaW1wbGljaXRLZXk6ICFleHBsaWNpdEtleSAmJiAoc2ltcGxlS2V5cyB8fCAhYWxsTnVsbFZhbHVlcyksXG4gICAgICBpbmRlbnQ6IGluZGVudCArIGluZGVudFN0ZXBcbiAgICB9KTtcbiAgICBsZXQgY2hvbXBLZWVwID0gZmFsc2U7XG4gICAgbGV0IHN0ciA9IHN0cmluZ2lmeShrZXksIGN0eCwgKCkgPT4ga2V5Q29tbWVudCA9IG51bGwsICgpID0+IGNob21wS2VlcCA9IHRydWUpO1xuICAgIHN0ciA9IGFkZENvbW1lbnQoc3RyLCBjdHguaW5kZW50LCBrZXlDb21tZW50KTtcblxuICAgIGlmICghZXhwbGljaXRLZXkgJiYgc3RyLmxlbmd0aCA+IDEwMjQpIHtcbiAgICAgIGlmIChzaW1wbGVLZXlzKSB0aHJvdyBuZXcgRXJyb3IoJ1dpdGggc2ltcGxlIGtleXMsIHNpbmdsZSBsaW5lIHNjYWxhciBtdXN0IG5vdCBzcGFuIG1vcmUgdGhhbiAxMDI0IGNoYXJhY3RlcnMnKTtcbiAgICAgIGV4cGxpY2l0S2V5ID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAoYWxsTnVsbFZhbHVlcyAmJiAhc2ltcGxlS2V5cykge1xuICAgICAgaWYgKHRoaXMuY29tbWVudCkge1xuICAgICAgICBzdHIgPSBhZGRDb21tZW50KHN0ciwgY3R4LmluZGVudCwgdGhpcy5jb21tZW50KTtcbiAgICAgICAgaWYgKG9uQ29tbWVudCkgb25Db21tZW50KCk7XG4gICAgICB9IGVsc2UgaWYgKGNob21wS2VlcCAmJiAha2V5Q29tbWVudCAmJiBvbkNob21wS2VlcCkgb25DaG9tcEtlZXAoKTtcblxuICAgICAgcmV0dXJuIGN0eC5pbkZsb3cgJiYgIWV4cGxpY2l0S2V5ID8gc3RyIDogXCI/IFwiLmNvbmNhdChzdHIpO1xuICAgIH1cblxuICAgIHN0ciA9IGV4cGxpY2l0S2V5ID8gXCI/IFwiLmNvbmNhdChzdHIsIFwiXFxuXCIpLmNvbmNhdChpbmRlbnQsIFwiOlwiKSA6IFwiXCIuY29uY2F0KHN0ciwgXCI6XCIpO1xuXG4gICAgaWYgKHRoaXMuY29tbWVudCkge1xuICAgICAgLy8gZXhwZWN0ZWQgKGJ1dCBub3Qgc3RyaWN0bHkgcmVxdWlyZWQpIHRvIGJlIGEgc2luZ2xlLWxpbmUgY29tbWVudFxuICAgICAgc3RyID0gYWRkQ29tbWVudChzdHIsIGN0eC5pbmRlbnQsIHRoaXMuY29tbWVudCk7XG4gICAgICBpZiAob25Db21tZW50KSBvbkNvbW1lbnQoKTtcbiAgICB9XG5cbiAgICBsZXQgdmNiID0gJyc7XG4gICAgbGV0IHZhbHVlQ29tbWVudCA9IG51bGw7XG5cbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBOb2RlKSB7XG4gICAgICBpZiAodmFsdWUuc3BhY2VCZWZvcmUpIHZjYiA9ICdcXG4nO1xuXG4gICAgICBpZiAodmFsdWUuY29tbWVudEJlZm9yZSkge1xuICAgICAgICBjb25zdCBjcyA9IHZhbHVlLmNvbW1lbnRCZWZvcmUucmVwbGFjZSgvXi9nbSwgXCJcIi5jb25jYXQoY3R4LmluZGVudCwgXCIjXCIpKTtcbiAgICAgICAgdmNiICs9IFwiXFxuXCIuY29uY2F0KGNzKTtcbiAgICAgIH1cblxuICAgICAgdmFsdWVDb21tZW50ID0gdmFsdWUuY29tbWVudDtcbiAgICB9IGVsc2UgaWYgKHZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIHZhbHVlID0gZG9jLmNyZWF0ZU5vZGUodmFsdWUpO1xuICAgIH1cblxuICAgIGN0eC5pbXBsaWNpdEtleSA9IGZhbHNlO1xuICAgIGlmICghZXhwbGljaXRLZXkgJiYgIXRoaXMuY29tbWVudCAmJiB2YWx1ZSBpbnN0YW5jZW9mIFNjYWxhcikgY3R4LmluZGVudEF0U3RhcnQgPSBzdHIubGVuZ3RoICsgMTtcbiAgICBjaG9tcEtlZXAgPSBmYWxzZTtcblxuICAgIGlmICghaW5kZW50U2VxICYmIGluZGVudFNpemUgPj0gMiAmJiAhY3R4LmluRmxvdyAmJiAhZXhwbGljaXRLZXkgJiYgdmFsdWUgaW5zdGFuY2VvZiBZQU1MU2VxICYmIHZhbHVlLnR5cGUgIT09IFR5cGUuRkxPV19TRVEgJiYgIXZhbHVlLnRhZyAmJiAhZG9jLmFuY2hvcnMuZ2V0TmFtZSh2YWx1ZSkpIHtcbiAgICAgIC8vIElmIGluZGVudFNlcSA9PT0gZmFsc2UsIGNvbnNpZGVyICctICcgYXMgcGFydCBvZiBpbmRlbnRhdGlvbiB3aGVyZSBwb3NzaWJsZVxuICAgICAgY3R4LmluZGVudCA9IGN0eC5pbmRlbnQuc3Vic3RyKDIpO1xuICAgIH1cblxuICAgIGNvbnN0IHZhbHVlU3RyID0gc3RyaW5naWZ5KHZhbHVlLCBjdHgsICgpID0+IHZhbHVlQ29tbWVudCA9IG51bGwsICgpID0+IGNob21wS2VlcCA9IHRydWUpO1xuICAgIGxldCB3cyA9ICcgJztcblxuICAgIGlmICh2Y2IgfHwgdGhpcy5jb21tZW50KSB7XG4gICAgICB3cyA9IFwiXCIuY29uY2F0KHZjYiwgXCJcXG5cIikuY29uY2F0KGN0eC5pbmRlbnQpO1xuICAgIH0gZWxzZSBpZiAoIWV4cGxpY2l0S2V5ICYmIHZhbHVlIGluc3RhbmNlb2YgQ29sbGVjdGlvbikge1xuICAgICAgY29uc3QgZmxvdyA9IHZhbHVlU3RyWzBdID09PSAnWycgfHwgdmFsdWVTdHJbMF0gPT09ICd7JztcbiAgICAgIGlmICghZmxvdyB8fCB2YWx1ZVN0ci5pbmNsdWRlcygnXFxuJykpIHdzID0gXCJcXG5cIi5jb25jYXQoY3R4LmluZGVudCk7XG4gICAgfSBlbHNlIGlmICh2YWx1ZVN0clswXSA9PT0gJ1xcbicpIHdzID0gJyc7XG5cbiAgICBpZiAoY2hvbXBLZWVwICYmICF2YWx1ZUNvbW1lbnQgJiYgb25DaG9tcEtlZXApIG9uQ2hvbXBLZWVwKCk7XG4gICAgcmV0dXJuIGFkZENvbW1lbnQoc3RyICsgd3MgKyB2YWx1ZVN0ciwgY3R4LmluZGVudCwgdmFsdWVDb21tZW50KTtcbiAgfVxuXG59XG5cbl9kZWZpbmVQcm9wZXJ0eShQYWlyLCBcIlR5cGVcIiwge1xuICBQQUlSOiAnUEFJUicsXG4gIE1FUkdFX1BBSVI6ICdNRVJHRV9QQUlSJ1xufSk7XG5cbmV4cG9ydCB7IFBhaXIsIGNyZWF0ZVBhaXIgfTtcbiIsImltcG9ydCB7IGRlZmluZVByb3BlcnR5IGFzIF9kZWZpbmVQcm9wZXJ0eSB9IGZyb20gJy4uL192aXJ0dWFsL19yb2xsdXBQbHVnaW5CYWJlbEhlbHBlcnMuanMnO1xuaW1wb3J0IHsgVHlwZSB9IGZyb20gJy4uL2NvbnN0YW50cy5qcyc7XG5pbXBvcnQgeyBZQU1MUmVmZXJlbmNlRXJyb3IgfSBmcm9tICcuLi9lcnJvcnMuanMnO1xuaW1wb3J0IHsgQ29sbGVjdGlvbiB9IGZyb20gJy4vQ29sbGVjdGlvbi5qcyc7XG5pbXBvcnQgeyBOb2RlIH0gZnJvbSAnLi9Ob2RlLmpzJztcbmltcG9ydCB7IFBhaXIgfSBmcm9tICcuL1BhaXIuanMnO1xuaW1wb3J0IHsgdG9KUyB9IGZyb20gJy4vdG9KUy5qcyc7XG5cbmNvbnN0IGdldEFsaWFzQ291bnQgPSAobm9kZSwgYW5jaG9ycykgPT4ge1xuICBpZiAobm9kZSBpbnN0YW5jZW9mIEFsaWFzKSB7XG4gICAgY29uc3QgYW5jaG9yID0gYW5jaG9ycy5nZXQobm9kZS5zb3VyY2UpO1xuICAgIHJldHVybiBhbmNob3IuY291bnQgKiBhbmNob3IuYWxpYXNDb3VudDtcbiAgfSBlbHNlIGlmIChub2RlIGluc3RhbmNlb2YgQ29sbGVjdGlvbikge1xuICAgIGxldCBjb3VudCA9IDA7XG5cbiAgICBmb3IgKGNvbnN0IGl0ZW0gb2Ygbm9kZS5pdGVtcykge1xuICAgICAgY29uc3QgYyA9IGdldEFsaWFzQ291bnQoaXRlbSwgYW5jaG9ycyk7XG4gICAgICBpZiAoYyA+IGNvdW50KSBjb3VudCA9IGM7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvdW50O1xuICB9IGVsc2UgaWYgKG5vZGUgaW5zdGFuY2VvZiBQYWlyKSB7XG4gICAgY29uc3Qga2MgPSBnZXRBbGlhc0NvdW50KG5vZGUua2V5LCBhbmNob3JzKTtcbiAgICBjb25zdCB2YyA9IGdldEFsaWFzQ291bnQobm9kZS52YWx1ZSwgYW5jaG9ycyk7XG4gICAgcmV0dXJuIE1hdGgubWF4KGtjLCB2Yyk7XG4gIH1cblxuICByZXR1cm4gMTtcbn07XG5cbmNsYXNzIEFsaWFzIGV4dGVuZHMgTm9kZSB7XG4gIHN0YXRpYyBzdHJpbmdpZnkoe1xuICAgIHJhbmdlLFxuICAgIHNvdXJjZVxuICB9LCB7XG4gICAgYW5jaG9ycyxcbiAgICBkb2MsXG4gICAgaW1wbGljaXRLZXksXG4gICAgaW5TdHJpbmdpZnlLZXlcbiAgfSkge1xuICAgIGxldCBhbmNob3IgPSBPYmplY3Qua2V5cyhhbmNob3JzKS5maW5kKGEgPT4gYW5jaG9yc1thXSA9PT0gc291cmNlKTtcbiAgICBpZiAoIWFuY2hvciAmJiBpblN0cmluZ2lmeUtleSkgYW5jaG9yID0gZG9jLmFuY2hvcnMuZ2V0TmFtZShzb3VyY2UpIHx8IGRvYy5hbmNob3JzLm5ld05hbWUoKTtcbiAgICBpZiAoYW5jaG9yKSByZXR1cm4gXCIqXCIuY29uY2F0KGFuY2hvcikuY29uY2F0KGltcGxpY2l0S2V5ID8gJyAnIDogJycpO1xuICAgIGNvbnN0IG1zZyA9IGRvYy5hbmNob3JzLmdldE5hbWUoc291cmNlKSA/ICdBbGlhcyBub2RlIG11c3QgYmUgYWZ0ZXIgc291cmNlIG5vZGUnIDogJ1NvdXJjZSBub2RlIG5vdCBmb3VuZCBmb3IgYWxpYXMgbm9kZSc7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiXCIuY29uY2F0KG1zZywgXCIgW1wiKS5jb25jYXQocmFuZ2UsIFwiXVwiKSk7XG4gIH1cblxuICBjb25zdHJ1Y3Rvcihzb3VyY2UpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuc291cmNlID0gc291cmNlO1xuICAgIHRoaXMudHlwZSA9IFR5cGUuQUxJQVM7XG4gIH1cblxuICBzZXQgdGFnKHQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0FsaWFzIG5vZGVzIGNhbm5vdCBoYXZlIHRhZ3MnKTtcbiAgfVxuXG4gIHRvSlNPTihhcmcsIGN0eCkge1xuICAgIGlmICghY3R4KSByZXR1cm4gdG9KUyh0aGlzLnNvdXJjZSwgYXJnLCBjdHgpO1xuICAgIGNvbnN0IHtcbiAgICAgIGFuY2hvcnMsXG4gICAgICBtYXhBbGlhc0NvdW50XG4gICAgfSA9IGN0eDtcbiAgICBjb25zdCBhbmNob3IgPSBhbmNob3JzLmdldCh0aGlzLnNvdXJjZSk7XG4gICAgLyogaXN0YW5idWwgaWdub3JlIGlmICovXG5cbiAgICBpZiAoIWFuY2hvciB8fCBhbmNob3IucmVzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IG1zZyA9ICdUaGlzIHNob3VsZCBub3QgaGFwcGVuOiBBbGlhcyBhbmNob3Igd2FzIG5vdCByZXNvbHZlZD8nO1xuICAgICAgaWYgKHRoaXMuY3N0Tm9kZSkgdGhyb3cgbmV3IFlBTUxSZWZlcmVuY2VFcnJvcih0aGlzLmNzdE5vZGUsIG1zZyk7ZWxzZSB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IobXNnKTtcbiAgICB9XG5cbiAgICBpZiAobWF4QWxpYXNDb3VudCA+PSAwKSB7XG4gICAgICBhbmNob3IuY291bnQgKz0gMTtcbiAgICAgIGlmIChhbmNob3IuYWxpYXNDb3VudCA9PT0gMCkgYW5jaG9yLmFsaWFzQ291bnQgPSBnZXRBbGlhc0NvdW50KHRoaXMuc291cmNlLCBhbmNob3JzKTtcblxuICAgICAgaWYgKGFuY2hvci5jb3VudCAqIGFuY2hvci5hbGlhc0NvdW50ID4gbWF4QWxpYXNDb3VudCkge1xuICAgICAgICBjb25zdCBtc2cgPSAnRXhjZXNzaXZlIGFsaWFzIGNvdW50IGluZGljYXRlcyBhIHJlc291cmNlIGV4aGF1c3Rpb24gYXR0YWNrJztcbiAgICAgICAgaWYgKHRoaXMuY3N0Tm9kZSkgdGhyb3cgbmV3IFlBTUxSZWZlcmVuY2VFcnJvcih0aGlzLmNzdE5vZGUsIG1zZyk7ZWxzZSB0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IobXNnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gYW5jaG9yLnJlcztcbiAgfSAvLyBPbmx5IGNhbGxlZCB3aGVuIHN0cmluZ2lmeWluZyBhbiBhbGlhcyBtYXBwaW5nIGtleSB3aGlsZSBjb25zdHJ1Y3RpbmdcbiAgLy8gT2JqZWN0IG91dHB1dC5cblxuXG4gIHRvU3RyaW5nKGN0eCkge1xuICAgIHJldHVybiBBbGlhcy5zdHJpbmdpZnkodGhpcywgY3R4KTtcbiAgfVxuXG59XG5cbl9kZWZpbmVQcm9wZXJ0eShBbGlhcywgXCJkZWZhdWx0XCIsIHRydWUpO1xuXG5leHBvcnQgeyBBbGlhcyB9O1xuIiwiaW1wb3J0IHsgU2NhbGFyIH0gZnJvbSAnLi4vYXN0L1NjYWxhci5qcyc7XG5cbmZ1bmN0aW9uIHJlc29sdmVTY2FsYXIoc3RyLCB0YWdzKSB7XG4gIGZvciAoY29uc3Qge1xuICAgIGZvcm1hdCxcbiAgICB0ZXN0LFxuICAgIHJlc29sdmVcbiAgfSBvZiB0YWdzKSB7XG4gICAgaWYgKHRlc3QgJiYgdGVzdC50ZXN0KHN0cikpIHtcbiAgICAgIGxldCByZXMgPSByZXNvbHZlKHN0cik7XG4gICAgICBpZiAoIShyZXMgaW5zdGFuY2VvZiBTY2FsYXIpKSByZXMgPSBuZXcgU2NhbGFyKHJlcyk7XG4gICAgICBpZiAoZm9ybWF0KSByZXMuZm9ybWF0ID0gZm9ybWF0O1xuICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmV3IFNjYWxhcihzdHIpOyAvLyBmYWxsYmFjayB0byBzdHJpbmdcbn1cblxuZXhwb3J0IHsgcmVzb2x2ZVNjYWxhciB9O1xuIiwiY29uc3QgRk9MRF9GTE9XID0gJ2Zsb3cnO1xuY29uc3QgRk9MRF9CTE9DSyA9ICdibG9jayc7XG5jb25zdCBGT0xEX1FVT1RFRCA9ICdxdW90ZWQnOyAvLyBwcmVzdW1lcyBpKzEgaXMgYXQgdGhlIHN0YXJ0IG9mIGEgbGluZVxuLy8gcmV0dXJucyBpbmRleCBvZiBsYXN0IG5ld2xpbmUgaW4gbW9yZS1pbmRlbnRlZCBibG9ja1xuXG5jb25zdCBjb25zdW1lTW9yZUluZGVudGVkTGluZXMgPSAodGV4dCwgaSkgPT4ge1xuICBsZXQgY2ggPSB0ZXh0W2kgKyAxXTtcblxuICB3aGlsZSAoY2ggPT09ICcgJyB8fCBjaCA9PT0gJ1xcdCcpIHtcbiAgICBkbyB7XG4gICAgICBjaCA9IHRleHRbaSArPSAxXTtcbiAgICB9IHdoaWxlIChjaCAmJiBjaCAhPT0gJ1xcbicpO1xuXG4gICAgY2ggPSB0ZXh0W2kgKyAxXTtcbiAgfVxuXG4gIHJldHVybiBpO1xufTtcbi8qKlxuICogVHJpZXMgdG8ga2VlcCBpbnB1dCBhdCB1cCB0byBgbGluZVdpZHRoYCBjaGFyYWN0ZXJzLCBzcGxpdHRpbmcgb25seSBvbiBzcGFjZXNcbiAqIG5vdCBmb2xsb3dlZCBieSBuZXdsaW5lcyBvciBzcGFjZXMgdW5sZXNzIGBtb2RlYCBpcyBgJ3F1b3RlZCdgLiBMaW5lcyBhcmVcbiAqIHRlcm1pbmF0ZWQgd2l0aCBgXFxuYCBhbmQgc3RhcnRlZCB3aXRoIGBpbmRlbnRgLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0XG4gKiBAcGFyYW0ge3N0cmluZ30gaW5kZW50XG4gKiBAcGFyYW0ge3N0cmluZ30gW21vZGU9J2Zsb3cnXSBgJ2Jsb2NrJ2AgcHJldmVudHMgbW9yZS1pbmRlbnRlZCBsaW5lc1xuICogICBmcm9tIGJlaW5nIGZvbGRlZDsgYCdxdW90ZWQnYCBhbGxvd3MgZm9yIGBcXGAgZXNjYXBlcywgaW5jbHVkaW5nIGVzY2FwZWRcbiAqICAgbmV3bGluZXNcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMuaW5kZW50QXRTdGFydF0gQWNjb3VudHMgZm9yIGxlYWRpbmcgY29udGVudHMgb25cbiAqICAgdGhlIGZpcnN0IGxpbmUsIGRlZmF1bHRpbmcgdG8gYGluZGVudC5sZW5ndGhgXG4gKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMubGluZVdpZHRoPTgwXVxuICogQHBhcmFtIHtudW1iZXJ9IFtvcHRpb25zLm1pbkNvbnRlbnRXaWR0aD0yMF0gQWxsb3cgaGlnaGx5IGluZGVudGVkIGxpbmVzIHRvXG4gKiAgIHN0cmV0Y2ggdGhlIGxpbmUgd2lkdGggb3IgaW5kZW50IGNvbnRlbnQgZnJvbSB0aGUgc3RhcnRcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IG9wdGlvbnMub25Gb2xkIENhbGxlZCBvbmNlIGlmIHRoZSB0ZXh0IGlzIGZvbGRlZFxuICogQHBhcmFtIHtmdW5jdGlvbn0gb3B0aW9ucy5vbkZvbGQgQ2FsbGVkIG9uY2UgaWYgYW55IGxpbmUgb2YgdGV4dCBleGNlZWRzXG4gKiAgIGxpbmVXaWR0aCBjaGFyYWN0ZXJzXG4gKi9cblxuXG5mdW5jdGlvbiBmb2xkRmxvd0xpbmVzKHRleHQsIGluZGVudCwgbW9kZSwge1xuICBpbmRlbnRBdFN0YXJ0LFxuICBsaW5lV2lkdGggPSA4MCxcbiAgbWluQ29udGVudFdpZHRoID0gMjAsXG4gIG9uRm9sZCxcbiAgb25PdmVyZmxvd1xufSkge1xuICBpZiAoIWxpbmVXaWR0aCB8fCBsaW5lV2lkdGggPCAwKSByZXR1cm4gdGV4dDtcbiAgY29uc3QgZW5kU3RlcCA9IE1hdGgubWF4KDEgKyBtaW5Db250ZW50V2lkdGgsIDEgKyBsaW5lV2lkdGggLSBpbmRlbnQubGVuZ3RoKTtcbiAgaWYgKHRleHQubGVuZ3RoIDw9IGVuZFN0ZXApIHJldHVybiB0ZXh0O1xuICBjb25zdCBmb2xkcyA9IFtdO1xuICBjb25zdCBlc2NhcGVkRm9sZHMgPSB7fTtcbiAgbGV0IGVuZCA9IGxpbmVXaWR0aCAtIGluZGVudC5sZW5ndGg7XG5cbiAgaWYgKHR5cGVvZiBpbmRlbnRBdFN0YXJ0ID09PSAnbnVtYmVyJykge1xuICAgIGlmIChpbmRlbnRBdFN0YXJ0ID4gbGluZVdpZHRoIC0gTWF0aC5tYXgoMiwgbWluQ29udGVudFdpZHRoKSkgZm9sZHMucHVzaCgwKTtlbHNlIGVuZCA9IGxpbmVXaWR0aCAtIGluZGVudEF0U3RhcnQ7XG4gIH1cblxuICBsZXQgc3BsaXQgPSB1bmRlZmluZWQ7XG4gIGxldCBwcmV2ID0gdW5kZWZpbmVkO1xuICBsZXQgb3ZlcmZsb3cgPSBmYWxzZTtcbiAgbGV0IGkgPSAtMTtcbiAgbGV0IGVzY1N0YXJ0ID0gLTE7XG4gIGxldCBlc2NFbmQgPSAtMTtcblxuICBpZiAobW9kZSA9PT0gRk9MRF9CTE9DSykge1xuICAgIGkgPSBjb25zdW1lTW9yZUluZGVudGVkTGluZXModGV4dCwgaSk7XG4gICAgaWYgKGkgIT09IC0xKSBlbmQgPSBpICsgZW5kU3RlcDtcbiAgfVxuXG4gIGZvciAobGV0IGNoOyBjaCA9IHRleHRbaSArPSAxXTspIHtcbiAgICBpZiAobW9kZSA9PT0gRk9MRF9RVU9URUQgJiYgY2ggPT09ICdcXFxcJykge1xuICAgICAgZXNjU3RhcnQgPSBpO1xuXG4gICAgICBzd2l0Y2ggKHRleHRbaSArIDFdKSB7XG4gICAgICAgIGNhc2UgJ3gnOlxuICAgICAgICAgIGkgKz0gMztcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlICd1JzpcbiAgICAgICAgICBpICs9IDU7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSAnVSc6XG4gICAgICAgICAgaSArPSA5O1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgaSArPSAxO1xuICAgICAgfVxuXG4gICAgICBlc2NFbmQgPSBpO1xuICAgIH1cblxuICAgIGlmIChjaCA9PT0gJ1xcbicpIHtcbiAgICAgIGlmIChtb2RlID09PSBGT0xEX0JMT0NLKSBpID0gY29uc3VtZU1vcmVJbmRlbnRlZExpbmVzKHRleHQsIGkpO1xuICAgICAgZW5kID0gaSArIGVuZFN0ZXA7XG4gICAgICBzcGxpdCA9IHVuZGVmaW5lZDtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGNoID09PSAnICcgJiYgcHJldiAmJiBwcmV2ICE9PSAnICcgJiYgcHJldiAhPT0gJ1xcbicgJiYgcHJldiAhPT0gJ1xcdCcpIHtcbiAgICAgICAgLy8gc3BhY2Ugc3Vycm91bmRlZCBieSBub24tc3BhY2UgY2FuIGJlIHJlcGxhY2VkIHdpdGggbmV3bGluZSArIGluZGVudFxuICAgICAgICBjb25zdCBuZXh0ID0gdGV4dFtpICsgMV07XG4gICAgICAgIGlmIChuZXh0ICYmIG5leHQgIT09ICcgJyAmJiBuZXh0ICE9PSAnXFxuJyAmJiBuZXh0ICE9PSAnXFx0Jykgc3BsaXQgPSBpO1xuICAgICAgfVxuXG4gICAgICBpZiAoaSA+PSBlbmQpIHtcbiAgICAgICAgaWYgKHNwbGl0KSB7XG4gICAgICAgICAgZm9sZHMucHVzaChzcGxpdCk7XG4gICAgICAgICAgZW5kID0gc3BsaXQgKyBlbmRTdGVwO1xuICAgICAgICAgIHNwbGl0ID0gdW5kZWZpbmVkO1xuICAgICAgICB9IGVsc2UgaWYgKG1vZGUgPT09IEZPTERfUVVPVEVEKSB7XG4gICAgICAgICAgLy8gd2hpdGUtc3BhY2UgY29sbGVjdGVkIGF0IGVuZCBtYXkgc3RyZXRjaCBwYXN0IGxpbmVXaWR0aFxuICAgICAgICAgIHdoaWxlIChwcmV2ID09PSAnICcgfHwgcHJldiA9PT0gJ1xcdCcpIHtcbiAgICAgICAgICAgIHByZXYgPSBjaDtcbiAgICAgICAgICAgIGNoID0gdGV4dFtpICs9IDFdO1xuICAgICAgICAgICAgb3ZlcmZsb3cgPSB0cnVlO1xuICAgICAgICAgIH0gLy8gQWNjb3VudCBmb3IgbmV3bGluZSBlc2NhcGUsIGJ1dCBkb24ndCBicmVhayBwcmVjZWRpbmcgZXNjYXBlXG5cblxuICAgICAgICAgIGNvbnN0IGogPSBpID4gZXNjRW5kICsgMSA/IGkgLSAyIDogZXNjU3RhcnQgLSAxOyAvLyBCYWlsIG91dCBpZiBsaW5lV2lkdGggJiBtaW5Db250ZW50V2lkdGggYXJlIHNob3J0ZXIgdGhhbiBhbiBlc2NhcGUgc3RyaW5nXG5cbiAgICAgICAgICBpZiAoZXNjYXBlZEZvbGRzW2pdKSByZXR1cm4gdGV4dDtcbiAgICAgICAgICBmb2xkcy5wdXNoKGopO1xuICAgICAgICAgIGVzY2FwZWRGb2xkc1tqXSA9IHRydWU7XG4gICAgICAgICAgZW5kID0gaiArIGVuZFN0ZXA7XG4gICAgICAgICAgc3BsaXQgPSB1bmRlZmluZWQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgb3ZlcmZsb3cgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcHJldiA9IGNoO1xuICB9XG5cbiAgaWYgKG92ZXJmbG93ICYmIG9uT3ZlcmZsb3cpIG9uT3ZlcmZsb3coKTtcbiAgaWYgKGZvbGRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHRleHQ7XG4gIGlmIChvbkZvbGQpIG9uRm9sZCgpO1xuICBsZXQgcmVzID0gdGV4dC5zbGljZSgwLCBmb2xkc1swXSk7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBmb2xkcy5sZW5ndGg7ICsraSkge1xuICAgIGNvbnN0IGZvbGQgPSBmb2xkc1tpXTtcbiAgICBjb25zdCBlbmQgPSBmb2xkc1tpICsgMV0gfHwgdGV4dC5sZW5ndGg7XG4gICAgaWYgKGZvbGQgPT09IDApIHJlcyA9IFwiXFxuXCIuY29uY2F0KGluZGVudCkuY29uY2F0KHRleHQuc2xpY2UoMCwgZW5kKSk7ZWxzZSB7XG4gICAgICBpZiAobW9kZSA9PT0gRk9MRF9RVU9URUQgJiYgZXNjYXBlZEZvbGRzW2ZvbGRdKSByZXMgKz0gXCJcIi5jb25jYXQodGV4dFtmb2xkXSwgXCJcXFxcXCIpO1xuICAgICAgcmVzICs9IFwiXFxuXCIuY29uY2F0KGluZGVudCkuY29uY2F0KHRleHQuc2xpY2UoZm9sZCArIDEsIGVuZCkpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXM7XG59XG5cbmV4cG9ydCB7IEZPTERfQkxPQ0ssIEZPTERfRkxPVywgRk9MRF9RVU9URUQsIGZvbGRGbG93TGluZXMgfTtcbiIsImltcG9ydCB7IGFkZENvbW1lbnRCZWZvcmUgfSBmcm9tICcuL2FkZENvbW1lbnQuanMnO1xuaW1wb3J0IHsgVHlwZSB9IGZyb20gJy4uL2NvbnN0YW50cy5qcyc7XG5pbXBvcnQgeyByZXNvbHZlU2NhbGFyIH0gZnJvbSAnLi4vcmVzb2x2ZS9yZXNvbHZlU2NhbGFyLmpzJztcbmltcG9ydCB7IGZvbGRGbG93TGluZXMsIEZPTERfUVVPVEVELCBGT0xEX0ZMT1csIEZPTERfQkxPQ0sgfSBmcm9tICcuL2ZvbGRGbG93TGluZXMuanMnO1xuaW1wb3J0IHsgc3RyT3B0aW9ucyB9IGZyb20gJy4uL3RhZ3Mvb3B0aW9ucy5qcyc7XG5cbmNvbnN0IGdldEZvbGRPcHRpb25zID0gKHtcbiAgaW5kZW50QXRTdGFydFxufSkgPT4gaW5kZW50QXRTdGFydCA/IE9iamVjdC5hc3NpZ24oe1xuICBpbmRlbnRBdFN0YXJ0XG59LCBzdHJPcHRpb25zLmZvbGQpIDogc3RyT3B0aW9ucy5mb2xkOyAvLyBBbHNvIGNoZWNrcyBmb3IgbGluZXMgc3RhcnRpbmcgd2l0aCAlLCBhcyBwYXJzaW5nIHRoZSBvdXRwdXQgYXMgWUFNTCAxLjEgd2lsbFxuLy8gcHJlc3VtZSB0aGF0J3Mgc3RhcnRpbmcgYSBuZXcgZG9jdW1lbnQuXG5cblxuY29uc3QgY29udGFpbnNEb2N1bWVudE1hcmtlciA9IHN0ciA9PiAvXiglfC0tLXxcXC5cXC5cXC4pL20udGVzdChzdHIpO1xuXG5mdW5jdGlvbiBsaW5lTGVuZ3RoT3ZlckxpbWl0KHN0ciwgbGltaXQpIHtcbiAgY29uc3Qgc3RyTGVuID0gc3RyLmxlbmd0aDtcbiAgaWYgKHN0ckxlbiA8PSBsaW1pdCkgcmV0dXJuIGZhbHNlO1xuXG4gIGZvciAobGV0IGkgPSAwLCBzdGFydCA9IDA7IGkgPCBzdHJMZW47ICsraSkge1xuICAgIGlmIChzdHJbaV0gPT09ICdcXG4nKSB7XG4gICAgICBpZiAoaSAtIHN0YXJ0ID4gbGltaXQpIHJldHVybiB0cnVlO1xuICAgICAgc3RhcnQgPSBpICsgMTtcbiAgICAgIGlmIChzdHJMZW4gLSBzdGFydCA8PSBsaW1pdCkgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBkb3VibGVRdW90ZWRTdHJpbmcodmFsdWUsIGN0eCkge1xuICBjb25zdCB7XG4gICAgaW1wbGljaXRLZXlcbiAgfSA9IGN0eDtcbiAgY29uc3Qge1xuICAgIGpzb25FbmNvZGluZyxcbiAgICBtaW5NdWx0aUxpbmVMZW5ndGhcbiAgfSA9IHN0ck9wdGlvbnMuZG91YmxlUXVvdGVkO1xuICBjb25zdCBqc29uID0gSlNPTi5zdHJpbmdpZnkodmFsdWUpO1xuICBpZiAoanNvbkVuY29kaW5nKSByZXR1cm4ganNvbjtcbiAgY29uc3QgaW5kZW50ID0gY3R4LmluZGVudCB8fCAoY29udGFpbnNEb2N1bWVudE1hcmtlcih2YWx1ZSkgPyAnICAnIDogJycpO1xuICBsZXQgc3RyID0gJyc7XG4gIGxldCBzdGFydCA9IDA7XG5cbiAgZm9yIChsZXQgaSA9IDAsIGNoID0ganNvbltpXTsgY2g7IGNoID0ganNvblsrK2ldKSB7XG4gICAgaWYgKGNoID09PSAnICcgJiYganNvbltpICsgMV0gPT09ICdcXFxcJyAmJiBqc29uW2kgKyAyXSA9PT0gJ24nKSB7XG4gICAgICAvLyBzcGFjZSBiZWZvcmUgbmV3bGluZSBuZWVkcyB0byBiZSBlc2NhcGVkIHRvIG5vdCBiZSBmb2xkZWRcbiAgICAgIHN0ciArPSBqc29uLnNsaWNlKHN0YXJ0LCBpKSArICdcXFxcICc7XG4gICAgICBpICs9IDE7XG4gICAgICBzdGFydCA9IGk7XG4gICAgICBjaCA9ICdcXFxcJztcbiAgICB9XG5cbiAgICBpZiAoY2ggPT09ICdcXFxcJykgc3dpdGNoIChqc29uW2kgKyAxXSkge1xuICAgICAgY2FzZSAndSc6XG4gICAgICAgIHtcbiAgICAgICAgICBzdHIgKz0ganNvbi5zbGljZShzdGFydCwgaSk7XG4gICAgICAgICAgY29uc3QgY29kZSA9IGpzb24uc3Vic3RyKGkgKyAyLCA0KTtcblxuICAgICAgICAgIHN3aXRjaCAoY29kZSkge1xuICAgICAgICAgICAgY2FzZSAnMDAwMCc6XG4gICAgICAgICAgICAgIHN0ciArPSAnXFxcXDAnO1xuICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZSAnMDAwNyc6XG4gICAgICAgICAgICAgIHN0ciArPSAnXFxcXGEnO1xuICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZSAnMDAwYic6XG4gICAgICAgICAgICAgIHN0ciArPSAnXFxcXHYnO1xuICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZSAnMDAxYic6XG4gICAgICAgICAgICAgIHN0ciArPSAnXFxcXGUnO1xuICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZSAnMDA4NSc6XG4gICAgICAgICAgICAgIHN0ciArPSAnXFxcXE4nO1xuICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZSAnMDBhMCc6XG4gICAgICAgICAgICAgIHN0ciArPSAnXFxcXF8nO1xuICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZSAnMjAyOCc6XG4gICAgICAgICAgICAgIHN0ciArPSAnXFxcXEwnO1xuICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZSAnMjAyOSc6XG4gICAgICAgICAgICAgIHN0ciArPSAnXFxcXFAnO1xuICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgaWYgKGNvZGUuc3Vic3RyKDAsIDIpID09PSAnMDAnKSBzdHIgKz0gJ1xcXFx4JyArIGNvZGUuc3Vic3RyKDIpO2Vsc2Ugc3RyICs9IGpzb24uc3Vic3RyKGksIDYpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGkgKz0gNTtcbiAgICAgICAgICBzdGFydCA9IGkgKyAxO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICduJzpcbiAgICAgICAgaWYgKGltcGxpY2l0S2V5IHx8IGpzb25baSArIDJdID09PSAnXCInIHx8IGpzb24ubGVuZ3RoIDwgbWluTXVsdGlMaW5lTGVuZ3RoKSB7XG4gICAgICAgICAgaSArPSAxO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGZvbGRpbmcgd2lsbCBlYXQgZmlyc3QgbmV3bGluZVxuICAgICAgICAgIHN0ciArPSBqc29uLnNsaWNlKHN0YXJ0LCBpKSArICdcXG5cXG4nO1xuXG4gICAgICAgICAgd2hpbGUgKGpzb25baSArIDJdID09PSAnXFxcXCcgJiYganNvbltpICsgM10gPT09ICduJyAmJiBqc29uW2kgKyA0XSAhPT0gJ1wiJykge1xuICAgICAgICAgICAgc3RyICs9ICdcXG4nO1xuICAgICAgICAgICAgaSArPSAyO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHN0ciArPSBpbmRlbnQ7IC8vIHNwYWNlIGFmdGVyIG5ld2xpbmUgbmVlZHMgdG8gYmUgZXNjYXBlZCB0byBub3QgYmUgZm9sZGVkXG5cbiAgICAgICAgICBpZiAoanNvbltpICsgMl0gPT09ICcgJykgc3RyICs9ICdcXFxcJztcbiAgICAgICAgICBpICs9IDE7XG4gICAgICAgICAgc3RhcnQgPSBpICsgMTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpICs9IDE7XG4gICAgfVxuICB9XG5cbiAgc3RyID0gc3RhcnQgPyBzdHIgKyBqc29uLnNsaWNlKHN0YXJ0KSA6IGpzb247XG4gIHJldHVybiBpbXBsaWNpdEtleSA/IHN0ciA6IGZvbGRGbG93TGluZXMoc3RyLCBpbmRlbnQsIEZPTERfUVVPVEVELCBnZXRGb2xkT3B0aW9ucyhjdHgpKTtcbn1cblxuZnVuY3Rpb24gc2luZ2xlUXVvdGVkU3RyaW5nKHZhbHVlLCBjdHgpIHtcbiAgaWYgKGN0eC5pbXBsaWNpdEtleSkge1xuICAgIGlmICgvXFxuLy50ZXN0KHZhbHVlKSkgcmV0dXJuIGRvdWJsZVF1b3RlZFN0cmluZyh2YWx1ZSwgY3R4KTtcbiAgfSBlbHNlIHtcbiAgICAvLyBzaW5nbGUgcXVvdGVkIHN0cmluZyBjYW4ndCBoYXZlIGxlYWRpbmcgb3IgdHJhaWxpbmcgd2hpdGVzcGFjZSBhcm91bmQgbmV3bGluZVxuICAgIGlmICgvWyBcXHRdXFxufFxcblsgXFx0XS8udGVzdCh2YWx1ZSkpIHJldHVybiBkb3VibGVRdW90ZWRTdHJpbmcodmFsdWUsIGN0eCk7XG4gIH1cblxuICBjb25zdCBpbmRlbnQgPSBjdHguaW5kZW50IHx8IChjb250YWluc0RvY3VtZW50TWFya2VyKHZhbHVlKSA/ICcgICcgOiAnJyk7XG4gIGNvbnN0IHJlcyA9IFwiJ1wiICsgdmFsdWUucmVwbGFjZSgvJy9nLCBcIicnXCIpLnJlcGxhY2UoL1xcbisvZywgXCIkJlxcblwiLmNvbmNhdChpbmRlbnQpKSArIFwiJ1wiO1xuICByZXR1cm4gY3R4LmltcGxpY2l0S2V5ID8gcmVzIDogZm9sZEZsb3dMaW5lcyhyZXMsIGluZGVudCwgRk9MRF9GTE9XLCBnZXRGb2xkT3B0aW9ucyhjdHgpKTtcbn1cblxuZnVuY3Rpb24gYmxvY2tTdHJpbmcoe1xuICBjb21tZW50LFxuICB0eXBlLFxuICB2YWx1ZVxufSwgY3R4LCBvbkNvbW1lbnQsIG9uQ2hvbXBLZWVwKSB7XG4gIC8vIDEuIEJsb2NrIGNhbid0IGVuZCBpbiB3aGl0ZXNwYWNlIHVubGVzcyB0aGUgbGFzdCBsaW5lIGlzIG5vbi1lbXB0eS5cbiAgLy8gMi4gU3RyaW5ncyBjb25zaXN0aW5nIG9mIG9ubHkgd2hpdGVzcGFjZSBhcmUgYmVzdCByZW5kZXJlZCBleHBsaWNpdGx5LlxuICBpZiAoL1xcbltcXHQgXSskLy50ZXN0KHZhbHVlKSB8fCAvXlxccyokLy50ZXN0KHZhbHVlKSkge1xuICAgIHJldHVybiBkb3VibGVRdW90ZWRTdHJpbmcodmFsdWUsIGN0eCk7XG4gIH1cblxuICBjb25zdCBpbmRlbnQgPSBjdHguaW5kZW50IHx8IChjdHguZm9yY2VCbG9ja0luZGVudCB8fCBjb250YWluc0RvY3VtZW50TWFya2VyKHZhbHVlKSA/ICcgICcgOiAnJyk7XG4gIGNvbnN0IGluZGVudFNpemUgPSBpbmRlbnQgPyAnMicgOiAnMSc7IC8vIHJvb3QgaXMgYXQgLTFcblxuICBjb25zdCBsaXRlcmFsID0gdHlwZSA9PT0gVHlwZS5CTE9DS19GT0xERUQgPyBmYWxzZSA6IHR5cGUgPT09IFR5cGUuQkxPQ0tfTElURVJBTCA/IHRydWUgOiAhbGluZUxlbmd0aE92ZXJMaW1pdCh2YWx1ZSwgc3RyT3B0aW9ucy5mb2xkLmxpbmVXaWR0aCAtIGluZGVudC5sZW5ndGgpO1xuICBsZXQgaGVhZGVyID0gbGl0ZXJhbCA/ICd8JyA6ICc+JztcbiAgaWYgKCF2YWx1ZSkgcmV0dXJuIGhlYWRlciArICdcXG4nO1xuICBsZXQgd3NTdGFydCA9ICcnO1xuICBsZXQgd3NFbmQgPSAnJztcbiAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKC9bXFxuXFx0IF0qJC8sIHdzID0+IHtcbiAgICBjb25zdCBuID0gd3MuaW5kZXhPZignXFxuJyk7XG5cbiAgICBpZiAobiA9PT0gLTEpIHtcbiAgICAgIGhlYWRlciArPSAnLSc7IC8vIHN0cmlwXG4gICAgfSBlbHNlIGlmICh2YWx1ZSA9PT0gd3MgfHwgbiAhPT0gd3MubGVuZ3RoIC0gMSkge1xuICAgICAgaGVhZGVyICs9ICcrJzsgLy8ga2VlcFxuXG4gICAgICBpZiAob25DaG9tcEtlZXApIG9uQ2hvbXBLZWVwKCk7XG4gICAgfVxuXG4gICAgd3NFbmQgPSB3cy5yZXBsYWNlKC9cXG4kLywgJycpO1xuICAgIHJldHVybiAnJztcbiAgfSkucmVwbGFjZSgvXltcXG4gXSovLCB3cyA9PiB7XG4gICAgaWYgKHdzLmluZGV4T2YoJyAnKSAhPT0gLTEpIGhlYWRlciArPSBpbmRlbnRTaXplO1xuICAgIGNvbnN0IG0gPSB3cy5tYXRjaCgvICskLyk7XG5cbiAgICBpZiAobSkge1xuICAgICAgd3NTdGFydCA9IHdzLnNsaWNlKDAsIC1tWzBdLmxlbmd0aCk7XG4gICAgICByZXR1cm4gbVswXTtcbiAgICB9IGVsc2Uge1xuICAgICAgd3NTdGFydCA9IHdzO1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgfSk7XG4gIGlmICh3c0VuZCkgd3NFbmQgPSB3c0VuZC5yZXBsYWNlKC9cXG4rKD8hXFxufCQpL2csIFwiJCZcIi5jb25jYXQoaW5kZW50KSk7XG4gIGlmICh3c1N0YXJ0KSB3c1N0YXJ0ID0gd3NTdGFydC5yZXBsYWNlKC9cXG4rL2csIFwiJCZcIi5jb25jYXQoaW5kZW50KSk7XG5cbiAgaWYgKGNvbW1lbnQpIHtcbiAgICBoZWFkZXIgKz0gJyAjJyArIGNvbW1lbnQucmVwbGFjZSgvID9bXFxyXFxuXSsvZywgJyAnKTtcbiAgICBpZiAob25Db21tZW50KSBvbkNvbW1lbnQoKTtcbiAgfVxuXG4gIGlmICghdmFsdWUpIHJldHVybiBcIlwiLmNvbmNhdChoZWFkZXIpLmNvbmNhdChpbmRlbnRTaXplLCBcIlxcblwiKS5jb25jYXQoaW5kZW50KS5jb25jYXQod3NFbmQpO1xuXG4gIGlmIChsaXRlcmFsKSB7XG4gICAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKC9cXG4rL2csIFwiJCZcIi5jb25jYXQoaW5kZW50KSk7XG4gICAgcmV0dXJuIFwiXCIuY29uY2F0KGhlYWRlciwgXCJcXG5cIikuY29uY2F0KGluZGVudCkuY29uY2F0KHdzU3RhcnQpLmNvbmNhdCh2YWx1ZSkuY29uY2F0KHdzRW5kKTtcbiAgfVxuXG4gIHZhbHVlID0gdmFsdWUucmVwbGFjZSgvXFxuKy9nLCAnXFxuJCYnKS5yZXBsYWNlKC8oPzpefFxcbikoW1xcdCBdLiopKD86KFtcXG5cXHQgXSopXFxuKD8hW1xcblxcdCBdKSk/L2csICckMSQyJykgLy8gbW9yZS1pbmRlbnRlZCBsaW5lcyBhcmVuJ3QgZm9sZGVkXG4gIC8vICAgICAgICAgXiBpbmQubGluZSAgXiBlbXB0eSAgICAgXiBjYXB0dXJlIG5leHQgZW1wdHkgbGluZXMgb25seSBhdCBlbmQgb2YgaW5kZW50XG4gIC5yZXBsYWNlKC9cXG4rL2csIFwiJCZcIi5jb25jYXQoaW5kZW50KSk7XG4gIGNvbnN0IGJvZHkgPSBmb2xkRmxvd0xpbmVzKFwiXCIuY29uY2F0KHdzU3RhcnQpLmNvbmNhdCh2YWx1ZSkuY29uY2F0KHdzRW5kKSwgaW5kZW50LCBGT0xEX0JMT0NLLCBzdHJPcHRpb25zLmZvbGQpO1xuICByZXR1cm4gXCJcIi5jb25jYXQoaGVhZGVyLCBcIlxcblwiKS5jb25jYXQoaW5kZW50KS5jb25jYXQoYm9keSk7XG59XG5cbmZ1bmN0aW9uIHBsYWluU3RyaW5nKGl0ZW0sIGN0eCwgb25Db21tZW50LCBvbkNob21wS2VlcCkge1xuICBjb25zdCB7XG4gICAgY29tbWVudCxcbiAgICB0eXBlLFxuICAgIHZhbHVlXG4gIH0gPSBpdGVtO1xuICBjb25zdCB7XG4gICAgYWN0dWFsU3RyaW5nLFxuICAgIGltcGxpY2l0S2V5LFxuICAgIGluZGVudCxcbiAgICBpbkZsb3dcbiAgfSA9IGN0eDtcblxuICBpZiAoaW1wbGljaXRLZXkgJiYgL1tcXG5bXFxde30sXS8udGVzdCh2YWx1ZSkgfHwgaW5GbG93ICYmIC9bW1xcXXt9LF0vLnRlc3QodmFsdWUpKSB7XG4gICAgcmV0dXJuIGRvdWJsZVF1b3RlZFN0cmluZyh2YWx1ZSwgY3R4KTtcbiAgfVxuXG4gIGlmICghdmFsdWUgfHwgL15bXFxuXFx0ICxbXFxde30jJiohfD4nXCIlQGBdfF5bPy1dJHxeWz8tXVsgXFx0XXxbXFxuOl1bIFxcdF18WyBcXHRdXFxufFtcXG5cXHQgXSN8W1xcblxcdCA6XSQvLnRlc3QodmFsdWUpKSB7XG4gICAgY29uc3QgaGFzRG91YmxlID0gdmFsdWUuaW5kZXhPZignXCInKSAhPT0gLTE7XG4gICAgY29uc3QgaGFzU2luZ2xlID0gdmFsdWUuaW5kZXhPZihcIidcIikgIT09IC0xO1xuICAgIGxldCBxdW90ZWRTdHJpbmc7XG5cbiAgICBpZiAoaGFzRG91YmxlICYmICFoYXNTaW5nbGUpIHtcbiAgICAgIHF1b3RlZFN0cmluZyA9IHNpbmdsZVF1b3RlZFN0cmluZztcbiAgICB9IGVsc2UgaWYgKGhhc1NpbmdsZSAmJiAhaGFzRG91YmxlKSB7XG4gICAgICBxdW90ZWRTdHJpbmcgPSBkb3VibGVRdW90ZWRTdHJpbmc7XG4gICAgfSBlbHNlIGlmIChzdHJPcHRpb25zLmRlZmF1bHRRdW90ZVNpbmdsZSkge1xuICAgICAgcXVvdGVkU3RyaW5nID0gc2luZ2xlUXVvdGVkU3RyaW5nO1xuICAgIH0gZWxzZSB7XG4gICAgICBxdW90ZWRTdHJpbmcgPSBkb3VibGVRdW90ZWRTdHJpbmc7XG4gICAgfSAvLyBub3QgYWxsb3dlZDpcbiAgICAvLyAtIGVtcHR5IHN0cmluZywgJy0nIG9yICc/J1xuICAgIC8vIC0gc3RhcnQgd2l0aCBhbiBpbmRpY2F0b3IgY2hhcmFjdGVyIChleGNlcHQgWz86LV0pIG9yIC9bPy1dIC9cbiAgICAvLyAtICdcXG4gJywgJzogJyBvciAnIFxcbicgYW55d2hlcmVcbiAgICAvLyAtICcjJyBub3QgcHJlY2VkZWQgYnkgYSBub24tc3BhY2UgY2hhclxuICAgIC8vIC0gZW5kIHdpdGggJyAnIG9yICc6J1xuXG5cbiAgICByZXR1cm4gaW1wbGljaXRLZXkgfHwgaW5GbG93IHx8IHZhbHVlLmluZGV4T2YoJ1xcbicpID09PSAtMSA/IHF1b3RlZFN0cmluZyh2YWx1ZSwgY3R4KSA6IGJsb2NrU3RyaW5nKGl0ZW0sIGN0eCwgb25Db21tZW50LCBvbkNob21wS2VlcCk7XG4gIH1cblxuICBpZiAoIWltcGxpY2l0S2V5ICYmICFpbkZsb3cgJiYgdHlwZSAhPT0gVHlwZS5QTEFJTiAmJiB2YWx1ZS5pbmRleE9mKCdcXG4nKSAhPT0gLTEpIHtcbiAgICAvLyBXaGVyZSBhbGxvd2VkICYgdHlwZSBub3Qgc2V0IGV4cGxpY2l0bHksIHByZWZlciBibG9jayBzdHlsZSBmb3IgbXVsdGlsaW5lIHN0cmluZ3NcbiAgICByZXR1cm4gYmxvY2tTdHJpbmcoaXRlbSwgY3R4LCBvbkNvbW1lbnQsIG9uQ2hvbXBLZWVwKTtcbiAgfVxuXG4gIGlmIChpbmRlbnQgPT09ICcnICYmIGNvbnRhaW5zRG9jdW1lbnRNYXJrZXIodmFsdWUpKSB7XG4gICAgY3R4LmZvcmNlQmxvY2tJbmRlbnQgPSB0cnVlO1xuICAgIHJldHVybiBibG9ja1N0cmluZyhpdGVtLCBjdHgsIG9uQ29tbWVudCwgb25DaG9tcEtlZXApO1xuICB9XG5cbiAgY29uc3Qgc3RyID0gdmFsdWUucmVwbGFjZSgvXFxuKy9nLCBcIiQmXFxuXCIuY29uY2F0KGluZGVudCkpOyAvLyBWZXJpZnkgdGhhdCBvdXRwdXQgd2lsbCBiZSBwYXJzZWQgYXMgYSBzdHJpbmcsIGFzIGUuZy4gcGxhaW4gbnVtYmVycyBhbmRcbiAgLy8gYm9vbGVhbnMgZ2V0IHBhcnNlZCB3aXRoIHRob3NlIHR5cGVzIGluIHYxLjIgKGUuZy4gJzQyJywgJ3RydWUnICYgJzAuOWUtMycpLFxuICAvLyBhbmQgb3RoZXJzIGluIHYxLjEuXG5cbiAgaWYgKGFjdHVhbFN0cmluZykge1xuICAgIGNvbnN0IHtcbiAgICAgIHRhZ3NcbiAgICB9ID0gY3R4LmRvYy5zY2hlbWE7XG4gICAgY29uc3QgcmVzb2x2ZWQgPSByZXNvbHZlU2NhbGFyKHN0ciwgdGFncykudmFsdWU7XG4gICAgaWYgKHR5cGVvZiByZXNvbHZlZCAhPT0gJ3N0cmluZycpIHJldHVybiBkb3VibGVRdW90ZWRTdHJpbmcodmFsdWUsIGN0eCk7XG4gIH1cblxuICBjb25zdCBib2R5ID0gaW1wbGljaXRLZXkgPyBzdHIgOiBmb2xkRmxvd0xpbmVzKHN0ciwgaW5kZW50LCBGT0xEX0ZMT1csIGdldEZvbGRPcHRpb25zKGN0eCkpO1xuXG4gIGlmIChjb21tZW50ICYmICFpbkZsb3cgJiYgKGJvZHkuaW5kZXhPZignXFxuJykgIT09IC0xIHx8IGNvbW1lbnQuaW5kZXhPZignXFxuJykgIT09IC0xKSkge1xuICAgIGlmIChvbkNvbW1lbnQpIG9uQ29tbWVudCgpO1xuICAgIHJldHVybiBhZGRDb21tZW50QmVmb3JlKGJvZHksIGluZGVudCwgY29tbWVudCk7XG4gIH1cblxuICByZXR1cm4gYm9keTtcbn1cblxuZnVuY3Rpb24gc3RyaW5naWZ5U3RyaW5nKGl0ZW0sIGN0eCwgb25Db21tZW50LCBvbkNob21wS2VlcCkge1xuICBjb25zdCB7XG4gICAgZGVmYXVsdEtleVR5cGUsXG4gICAgZGVmYXVsdFR5cGVcbiAgfSA9IHN0ck9wdGlvbnM7XG4gIGNvbnN0IHtcbiAgICBpbXBsaWNpdEtleSxcbiAgICBpbkZsb3dcbiAgfSA9IGN0eDtcbiAgbGV0IHtcbiAgICB0eXBlLFxuICAgIHZhbHVlXG4gIH0gPSBpdGVtO1xuXG4gIGlmICh0eXBlb2YgdmFsdWUgIT09ICdzdHJpbmcnKSB7XG4gICAgdmFsdWUgPSBTdHJpbmcodmFsdWUpO1xuICAgIGl0ZW0gPSBPYmplY3QuYXNzaWduKHt9LCBpdGVtLCB7XG4gICAgICB2YWx1ZVxuICAgIH0pO1xuICB9XG5cbiAgaWYgKHR5cGUgIT09IFR5cGUuUVVPVEVfRE9VQkxFKSB7XG4gICAgLy8gZm9yY2UgZG91YmxlIHF1b3RlcyBvbiBjb250cm9sIGNoYXJhY3RlcnMgJiB1bnBhaXJlZCBzdXJyb2dhdGVzXG4gICAgaWYgKC9bXFx4MDAtXFx4MDhcXHgwYi1cXHgxZlxceDdmLVxceDlmXFx1e0Q4MDB9LVxcdXtERkZGfV0vdS50ZXN0KHZhbHVlKSkgdHlwZSA9IFR5cGUuUVVPVEVfRE9VQkxFO1xuICB9XG5cbiAgY29uc3QgX3N0cmluZ2lmeSA9IF90eXBlID0+IHtcbiAgICBzd2l0Y2ggKF90eXBlKSB7XG4gICAgICBjYXNlIFR5cGUuQkxPQ0tfRk9MREVEOlxuICAgICAgY2FzZSBUeXBlLkJMT0NLX0xJVEVSQUw6XG4gICAgICAgIHJldHVybiBpbXBsaWNpdEtleSB8fCBpbkZsb3cgPyBkb3VibGVRdW90ZWRTdHJpbmcodmFsdWUsIGN0eCkgLy8gYmxvY2tzIGFyZSBub3QgdmFsaWQgaW5zaWRlIGZsb3cgY29udGFpbmVyc1xuICAgICAgICA6IGJsb2NrU3RyaW5nKGl0ZW0sIGN0eCwgb25Db21tZW50LCBvbkNob21wS2VlcCk7XG5cbiAgICAgIGNhc2UgVHlwZS5RVU9URV9ET1VCTEU6XG4gICAgICAgIHJldHVybiBkb3VibGVRdW90ZWRTdHJpbmcodmFsdWUsIGN0eCk7XG5cbiAgICAgIGNhc2UgVHlwZS5RVU9URV9TSU5HTEU6XG4gICAgICAgIHJldHVybiBzaW5nbGVRdW90ZWRTdHJpbmcodmFsdWUsIGN0eCk7XG5cbiAgICAgIGNhc2UgVHlwZS5QTEFJTjpcbiAgICAgICAgcmV0dXJuIHBsYWluU3RyaW5nKGl0ZW0sIGN0eCwgb25Db21tZW50LCBvbkNob21wS2VlcCk7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfTtcblxuICBsZXQgcmVzID0gX3N0cmluZ2lmeSh0eXBlKTtcblxuICBpZiAocmVzID09PSBudWxsKSB7XG4gICAgY29uc3QgdCA9IGltcGxpY2l0S2V5ID8gZGVmYXVsdEtleVR5cGUgOiBkZWZhdWx0VHlwZTtcbiAgICByZXMgPSBfc3RyaW5naWZ5KHQpO1xuICAgIGlmIChyZXMgPT09IG51bGwpIHRocm93IG5ldyBFcnJvcihcIlVuc3VwcG9ydGVkIGRlZmF1bHQgc3RyaW5nIHR5cGUgXCIuY29uY2F0KHQpKTtcbiAgfVxuXG4gIHJldHVybiByZXM7XG59XG5cbmV4cG9ydCB7IHN0cmluZ2lmeVN0cmluZyB9O1xuIiwiZnVuY3Rpb24gc3RyaW5naWZ5VGFnKGRvYywgdGFnKSB7XG4gIGlmICgoZG9jLnZlcnNpb24gfHwgZG9jLm9wdGlvbnMudmVyc2lvbikgPT09ICcxLjAnKSB7XG4gICAgY29uc3QgcHJpdiA9IHRhZy5tYXRjaCgvXnRhZzpwcml2YXRlXFwueWFtbFxcLm9yZywyMDAyOihbXjovXSspJC8pO1xuICAgIGlmIChwcml2KSByZXR1cm4gJyEnICsgcHJpdlsxXTtcbiAgICBjb25zdCB2b2NhYiA9IHRhZy5tYXRjaCgvXnRhZzooW2EtekEtWjAtOS1dKylcXC55YW1sXFwub3JnLDIwMDI6KC4qKS8pO1xuICAgIHJldHVybiB2b2NhYiA/IFwiIVwiLmNvbmNhdCh2b2NhYlsxXSwgXCIvXCIpLmNvbmNhdCh2b2NhYlsyXSkgOiBcIiFcIi5jb25jYXQodGFnLnJlcGxhY2UoL150YWc6LywgJycpKTtcbiAgfVxuXG4gIGxldCBwID0gZG9jLnRhZ1ByZWZpeGVzLmZpbmQocCA9PiB0YWcuaW5kZXhPZihwLnByZWZpeCkgPT09IDApO1xuXG4gIGlmICghcCkge1xuICAgIGNvbnN0IGR0cCA9IGRvYy5nZXREZWZhdWx0cygpLnRhZ1ByZWZpeGVzO1xuICAgIHAgPSBkdHAgJiYgZHRwLmZpbmQocCA9PiB0YWcuaW5kZXhPZihwLnByZWZpeCkgPT09IDApO1xuICB9XG5cbiAgaWYgKCFwKSByZXR1cm4gdGFnWzBdID09PSAnIScgPyB0YWcgOiBcIiE8XCIuY29uY2F0KHRhZywgXCI+XCIpO1xuICBjb25zdCBzdWZmaXggPSB0YWcuc3Vic3RyKHAucHJlZml4Lmxlbmd0aCkucmVwbGFjZSgvWyEsW1xcXXt9XS9nLCBjaCA9PiAoe1xuICAgICchJzogJyUyMScsXG4gICAgJywnOiAnJTJDJyxcbiAgICAnWyc6ICclNUInLFxuICAgICddJzogJyU1RCcsXG4gICAgJ3snOiAnJTdCJyxcbiAgICAnfSc6ICclN0QnXG4gIH0pW2NoXSk7XG4gIHJldHVybiBwLmhhbmRsZSArIHN1ZmZpeDtcbn1cblxuZXhwb3J0IHsgc3RyaW5naWZ5VGFnIH07XG4iLCJpbXBvcnQgeyBBbGlhcyB9IGZyb20gJy4uL2FzdC9BbGlhcy5qcyc7XG5pbXBvcnQgeyBOb2RlIH0gZnJvbSAnLi4vYXN0L05vZGUuanMnO1xuaW1wb3J0IHsgUGFpciB9IGZyb20gJy4uL2FzdC9QYWlyLmpzJztcbmltcG9ydCB7IFNjYWxhciB9IGZyb20gJy4uL2FzdC9TY2FsYXIuanMnO1xuaW1wb3J0IHsgc3RyaW5naWZ5U3RyaW5nIH0gZnJvbSAnLi9zdHJpbmdpZnlTdHJpbmcuanMnO1xuaW1wb3J0IHsgc3RyaW5naWZ5VGFnIH0gZnJvbSAnLi9zdHJpbmdpZnlUYWcuanMnO1xuXG5mdW5jdGlvbiBnZXRUYWdPYmplY3QodGFncywgaXRlbSkge1xuICBpZiAoaXRlbSBpbnN0YW5jZW9mIEFsaWFzKSByZXR1cm4gQWxpYXM7XG5cbiAgaWYgKGl0ZW0udGFnKSB7XG4gICAgY29uc3QgbWF0Y2ggPSB0YWdzLmZpbHRlcih0ID0+IHQudGFnID09PSBpdGVtLnRhZyk7XG4gICAgaWYgKG1hdGNoLmxlbmd0aCA+IDApIHJldHVybiBtYXRjaC5maW5kKHQgPT4gdC5mb3JtYXQgPT09IGl0ZW0uZm9ybWF0KSB8fCBtYXRjaFswXTtcbiAgfVxuXG4gIGxldCB0YWdPYmosIG9iajtcblxuICBpZiAoaXRlbSBpbnN0YW5jZW9mIFNjYWxhcikge1xuICAgIG9iaiA9IGl0ZW0udmFsdWU7XG4gICAgY29uc3QgbWF0Y2ggPSB0YWdzLmZpbHRlcih0ID0+IHQuaWRlbnRpZnkgJiYgdC5pZGVudGlmeShvYmopKTtcbiAgICB0YWdPYmogPSBtYXRjaC5maW5kKHQgPT4gdC5mb3JtYXQgPT09IGl0ZW0uZm9ybWF0KSB8fCBtYXRjaC5maW5kKHQgPT4gIXQuZm9ybWF0KTtcbiAgfSBlbHNlIHtcbiAgICBvYmogPSBpdGVtO1xuICAgIHRhZ09iaiA9IHRhZ3MuZmluZCh0ID0+IHQubm9kZUNsYXNzICYmIG9iaiBpbnN0YW5jZW9mIHQubm9kZUNsYXNzKTtcbiAgfVxuXG4gIGlmICghdGFnT2JqKSB7XG4gICAgY29uc3QgbmFtZSA9IG9iaiAmJiBvYmouY29uc3RydWN0b3IgPyBvYmouY29uc3RydWN0b3IubmFtZSA6IHR5cGVvZiBvYmo7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiVGFnIG5vdCByZXNvbHZlZCBmb3IgXCIuY29uY2F0KG5hbWUsIFwiIHZhbHVlXCIpKTtcbiAgfVxuXG4gIHJldHVybiB0YWdPYmo7XG59IC8vIG5lZWRzIHRvIGJlIGNhbGxlZCBiZWZvcmUgdmFsdWUgc3RyaW5naWZpZXIgdG8gYWxsb3cgZm9yIGNpcmN1bGFyIGFuY2hvciByZWZzXG5cblxuZnVuY3Rpb24gc3RyaW5naWZ5UHJvcHMobm9kZSwgdGFnT2JqLCB7XG4gIGFuY2hvcnMsXG4gIGRvY1xufSkge1xuICBjb25zdCBwcm9wcyA9IFtdO1xuICBjb25zdCBhbmNob3IgPSBkb2MuYW5jaG9ycy5nZXROYW1lKG5vZGUpO1xuXG4gIGlmIChhbmNob3IpIHtcbiAgICBhbmNob3JzW2FuY2hvcl0gPSBub2RlO1xuICAgIHByb3BzLnB1c2goXCImXCIuY29uY2F0KGFuY2hvcikpO1xuICB9XG5cbiAgaWYgKG5vZGUudGFnKSB7XG4gICAgcHJvcHMucHVzaChzdHJpbmdpZnlUYWcoZG9jLCBub2RlLnRhZykpO1xuICB9IGVsc2UgaWYgKCF0YWdPYmouZGVmYXVsdCkge1xuICAgIHByb3BzLnB1c2goc3RyaW5naWZ5VGFnKGRvYywgdGFnT2JqLnRhZykpO1xuICB9XG5cbiAgcmV0dXJuIHByb3BzLmpvaW4oJyAnKTtcbn1cblxuZnVuY3Rpb24gc3RyaW5naWZ5KGl0ZW0sIGN0eCwgb25Db21tZW50LCBvbkNob21wS2VlcCkge1xuICBjb25zdCB7XG4gICAgc2NoZW1hXG4gIH0gPSBjdHguZG9jO1xuICBsZXQgdGFnT2JqO1xuXG4gIGlmICghKGl0ZW0gaW5zdGFuY2VvZiBOb2RlKSkge1xuICAgIGl0ZW0gPSBjdHguZG9jLmNyZWF0ZU5vZGUoaXRlbSwge1xuICAgICAgb25UYWdPYmo6IG8gPT4gdGFnT2JqID0gbyxcbiAgICAgIHdyYXBTY2FsYXJzOiB0cnVlXG4gICAgfSk7XG4gIH1cblxuICBpZiAoaXRlbSBpbnN0YW5jZW9mIFBhaXIpIHJldHVybiBpdGVtLnRvU3RyaW5nKGN0eCwgb25Db21tZW50LCBvbkNob21wS2VlcCk7XG4gIGlmICghdGFnT2JqKSB0YWdPYmogPSBnZXRUYWdPYmplY3Qoc2NoZW1hLnRhZ3MsIGl0ZW0pO1xuICBjb25zdCBwcm9wcyA9IHN0cmluZ2lmeVByb3BzKGl0ZW0sIHRhZ09iaiwgY3R4KTtcbiAgaWYgKHByb3BzLmxlbmd0aCA+IDApIGN0eC5pbmRlbnRBdFN0YXJ0ID0gKGN0eC5pbmRlbnRBdFN0YXJ0IHx8IDApICsgcHJvcHMubGVuZ3RoICsgMTtcbiAgY29uc3Qgc3RyID0gdHlwZW9mIHRhZ09iai5zdHJpbmdpZnkgPT09ICdmdW5jdGlvbicgPyB0YWdPYmouc3RyaW5naWZ5KGl0ZW0sIGN0eCwgb25Db21tZW50LCBvbkNob21wS2VlcCkgOiBpdGVtIGluc3RhbmNlb2YgU2NhbGFyID8gc3RyaW5naWZ5U3RyaW5nKGl0ZW0sIGN0eCwgb25Db21tZW50LCBvbkNob21wS2VlcCkgOiBpdGVtLnRvU3RyaW5nKGN0eCwgb25Db21tZW50LCBvbkNob21wS2VlcCk7XG4gIGlmICghcHJvcHMpIHJldHVybiBzdHI7XG4gIHJldHVybiBpdGVtIGluc3RhbmNlb2YgU2NhbGFyIHx8IHN0clswXSA9PT0gJ3snIHx8IHN0clswXSA9PT0gJ1snID8gXCJcIi5jb25jYXQocHJvcHMsIFwiIFwiKS5jb25jYXQoc3RyKSA6IFwiXCIuY29uY2F0KHByb3BzLCBcIlxcblwiKS5jb25jYXQoY3R4LmluZGVudCkuY29uY2F0KHN0cik7XG59XG5cbmV4cG9ydCB7IHN0cmluZ2lmeSB9O1xuIiwiaW1wb3J0IHsgQ29sbGVjdGlvbiB9IGZyb20gJy4vQ29sbGVjdGlvbi5qcyc7XG5pbXBvcnQgeyBQYWlyIH0gZnJvbSAnLi9QYWlyLmpzJztcbmltcG9ydCB7IFNjYWxhciwgaXNTY2FsYXJWYWx1ZSB9IGZyb20gJy4vU2NhbGFyLmpzJztcblxuZnVuY3Rpb24gZmluZFBhaXIoaXRlbXMsIGtleSkge1xuICBjb25zdCBrID0ga2V5IGluc3RhbmNlb2YgU2NhbGFyID8ga2V5LnZhbHVlIDoga2V5O1xuXG4gIGZvciAoY29uc3QgaXQgb2YgaXRlbXMpIHtcbiAgICBpZiAoaXQgaW5zdGFuY2VvZiBQYWlyKSB7XG4gICAgICBpZiAoaXQua2V5ID09PSBrZXkgfHwgaXQua2V5ID09PSBrKSByZXR1cm4gaXQ7XG4gICAgICBpZiAoaXQua2V5ICYmIGl0LmtleS52YWx1ZSA9PT0gaykgcmV0dXJuIGl0O1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5jbGFzcyBZQU1MTWFwIGV4dGVuZHMgQ29sbGVjdGlvbiB7XG4gIGFkZChwYWlyLCBvdmVyd3JpdGUpIHtcbiAgICBpZiAoIXBhaXIpIHBhaXIgPSBuZXcgUGFpcihwYWlyKTtlbHNlIGlmICghKHBhaXIgaW5zdGFuY2VvZiBQYWlyKSkgcGFpciA9IG5ldyBQYWlyKHBhaXIua2V5IHx8IHBhaXIsIHBhaXIudmFsdWUpO1xuICAgIGNvbnN0IHByZXYgPSBmaW5kUGFpcih0aGlzLml0ZW1zLCBwYWlyLmtleSk7XG4gICAgY29uc3Qgc29ydEVudHJpZXMgPSB0aGlzLnNjaGVtYSAmJiB0aGlzLnNjaGVtYS5zb3J0TWFwRW50cmllcztcblxuICAgIGlmIChwcmV2KSB7XG4gICAgICBpZiAoIW92ZXJ3cml0ZSkgdGhyb3cgbmV3IEVycm9yKFwiS2V5IFwiLmNvbmNhdChwYWlyLmtleSwgXCIgYWxyZWFkeSBzZXRcIikpOyAvLyBGb3Igc2NhbGFycywga2VlcCB0aGUgb2xkIG5vZGUgJiBpdHMgY29tbWVudHMgYW5kIGFuY2hvcnNcblxuICAgICAgaWYgKHByZXYudmFsdWUgaW5zdGFuY2VvZiBTY2FsYXIgJiYgaXNTY2FsYXJWYWx1ZShwYWlyLnZhbHVlKSkgcHJldi52YWx1ZS52YWx1ZSA9IHBhaXIudmFsdWU7ZWxzZSBwcmV2LnZhbHVlID0gcGFpci52YWx1ZTtcbiAgICB9IGVsc2UgaWYgKHNvcnRFbnRyaWVzKSB7XG4gICAgICBjb25zdCBpID0gdGhpcy5pdGVtcy5maW5kSW5kZXgoaXRlbSA9PiBzb3J0RW50cmllcyhwYWlyLCBpdGVtKSA8IDApO1xuICAgICAgaWYgKGkgPT09IC0xKSB0aGlzLml0ZW1zLnB1c2gocGFpcik7ZWxzZSB0aGlzLml0ZW1zLnNwbGljZShpLCAwLCBwYWlyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5pdGVtcy5wdXNoKHBhaXIpO1xuICAgIH1cbiAgfVxuXG4gIGRlbGV0ZShrZXkpIHtcbiAgICBjb25zdCBpdCA9IGZpbmRQYWlyKHRoaXMuaXRlbXMsIGtleSk7XG4gICAgaWYgKCFpdCkgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IGRlbCA9IHRoaXMuaXRlbXMuc3BsaWNlKHRoaXMuaXRlbXMuaW5kZXhPZihpdCksIDEpO1xuICAgIHJldHVybiBkZWwubGVuZ3RoID4gMDtcbiAgfVxuXG4gIGdldChrZXksIGtlZXBTY2FsYXIpIHtcbiAgICBjb25zdCBpdCA9IGZpbmRQYWlyKHRoaXMuaXRlbXMsIGtleSk7XG4gICAgY29uc3Qgbm9kZSA9IGl0ICYmIGl0LnZhbHVlO1xuICAgIHJldHVybiAha2VlcFNjYWxhciAmJiBub2RlIGluc3RhbmNlb2YgU2NhbGFyID8gbm9kZS52YWx1ZSA6IG5vZGU7XG4gIH1cblxuICBoYXMoa2V5KSB7XG4gICAgcmV0dXJuICEhZmluZFBhaXIodGhpcy5pdGVtcywga2V5KTtcbiAgfVxuXG4gIHNldChrZXksIHZhbHVlKSB7XG4gICAgdGhpcy5hZGQobmV3IFBhaXIoa2V5LCB2YWx1ZSksIHRydWUpO1xuICB9XG4gIC8qKlxuICAgKiBAcGFyYW0gY3R4IC0gQ29udmVyc2lvbiBjb250ZXh0LCBvcmlnaW5hbGx5IHNldCBpbiBEb2N1bWVudCN0b0pTKClcbiAgICogQHBhcmFtIHtDbGFzc30gVHlwZSAtIElmIHNldCwgZm9yY2VzIHRoZSByZXR1cm5lZCBjb2xsZWN0aW9uIHR5cGVcbiAgICogQHJldHVybnMgSW5zdGFuY2Ugb2YgVHlwZSwgTWFwLCBvciBPYmplY3RcbiAgICovXG5cblxuICB0b0pTT04oXywgY3R4LCBUeXBlKSB7XG4gICAgY29uc3QgbWFwID0gVHlwZSA/IG5ldyBUeXBlKCkgOiBjdHggJiYgY3R4Lm1hcEFzTWFwID8gbmV3IE1hcCgpIDoge307XG4gICAgaWYgKGN0eCAmJiBjdHgub25DcmVhdGUpIGN0eC5vbkNyZWF0ZShtYXApO1xuXG4gICAgZm9yIChjb25zdCBpdGVtIG9mIHRoaXMuaXRlbXMpIGl0ZW0uYWRkVG9KU01hcChjdHgsIG1hcCk7XG5cbiAgICByZXR1cm4gbWFwO1xuICB9XG5cbiAgdG9TdHJpbmcoY3R4LCBvbkNvbW1lbnQsIG9uQ2hvbXBLZWVwKSB7XG4gICAgaWYgKCFjdHgpIHJldHVybiBKU09OLnN0cmluZ2lmeSh0aGlzKTtcblxuICAgIGZvciAoY29uc3QgaXRlbSBvZiB0aGlzLml0ZW1zKSB7XG4gICAgICBpZiAoIShpdGVtIGluc3RhbmNlb2YgUGFpcikpIHRocm93IG5ldyBFcnJvcihcIk1hcCBpdGVtcyBtdXN0IGFsbCBiZSBwYWlyczsgZm91bmQgXCIuY29uY2F0KEpTT04uc3RyaW5naWZ5KGl0ZW0pLCBcIiBpbnN0ZWFkXCIpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc3VwZXIudG9TdHJpbmcoY3R4LCB7XG4gICAgICBibG9ja0l0ZW06IG4gPT4gbi5zdHIsXG4gICAgICBmbG93Q2hhcnM6IHtcbiAgICAgICAgc3RhcnQ6ICd7JyxcbiAgICAgICAgZW5kOiAnfSdcbiAgICAgIH0sXG4gICAgICBpc01hcDogdHJ1ZSxcbiAgICAgIGl0ZW1JbmRlbnQ6IGN0eC5pbmRlbnQgfHwgJydcbiAgICB9LCBvbkNvbW1lbnQsIG9uQ2hvbXBLZWVwKTtcbiAgfVxuXG59XG5cbmV4cG9ydCB7IFlBTUxNYXAsIGZpbmRQYWlyIH07XG4iLCJpbXBvcnQgeyBQYWlyIH0gZnJvbSAnLi9QYWlyLmpzJztcbmltcG9ydCB7IFNjYWxhciB9IGZyb20gJy4vU2NhbGFyLmpzJztcbmltcG9ydCB7IFlBTUxNYXAgfSBmcm9tICcuL1lBTUxNYXAuanMnO1xuaW1wb3J0IHsgWUFNTFNlcSB9IGZyb20gJy4vWUFNTFNlcS5qcyc7XG5cbmNvbnN0IE1FUkdFX0tFWSA9ICc8PCc7XG5jbGFzcyBNZXJnZSBleHRlbmRzIFBhaXIge1xuICBjb25zdHJ1Y3RvcihwYWlyKSB7XG4gICAgaWYgKHBhaXIgaW5zdGFuY2VvZiBQYWlyKSB7XG4gICAgICBsZXQgc2VxID0gcGFpci52YWx1ZTtcblxuICAgICAgaWYgKCEoc2VxIGluc3RhbmNlb2YgWUFNTFNlcSkpIHtcbiAgICAgICAgc2VxID0gbmV3IFlBTUxTZXEoKTtcbiAgICAgICAgc2VxLml0ZW1zLnB1c2gocGFpci52YWx1ZSk7XG4gICAgICAgIHNlcS5yYW5nZSA9IHBhaXIudmFsdWUucmFuZ2U7XG4gICAgICB9XG5cbiAgICAgIHN1cGVyKHBhaXIua2V5LCBzZXEpO1xuICAgICAgdGhpcy5yYW5nZSA9IHBhaXIucmFuZ2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN1cGVyKG5ldyBTY2FsYXIoTUVSR0VfS0VZKSwgbmV3IFlBTUxTZXEoKSk7XG4gICAgfVxuXG4gICAgdGhpcy50eXBlID0gUGFpci5UeXBlLk1FUkdFX1BBSVI7XG4gIH0gLy8gSWYgdGhlIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCBhIG1lcmdlIGtleSBpcyBhIHNpbmdsZSBtYXBwaW5nIG5vZGUsIGVhY2ggb2ZcbiAgLy8gaXRzIGtleS92YWx1ZSBwYWlycyBpcyBpbnNlcnRlZCBpbnRvIHRoZSBjdXJyZW50IG1hcHBpbmcsIHVubGVzcyB0aGUga2V5XG4gIC8vIGFscmVhZHkgZXhpc3RzIGluIGl0LiBJZiB0aGUgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIHRoZSBtZXJnZSBrZXkgaXMgYVxuICAvLyBzZXF1ZW5jZSwgdGhlbiB0aGlzIHNlcXVlbmNlIGlzIGV4cGVjdGVkIHRvIGNvbnRhaW4gbWFwcGluZyBub2RlcyBhbmQgZWFjaFxuICAvLyBvZiB0aGVzZSBub2RlcyBpcyBtZXJnZWQgaW4gdHVybiBhY2NvcmRpbmcgdG8gaXRzIG9yZGVyIGluIHRoZSBzZXF1ZW5jZS5cbiAgLy8gS2V5cyBpbiBtYXBwaW5nIG5vZGVzIGVhcmxpZXIgaW4gdGhlIHNlcXVlbmNlIG92ZXJyaWRlIGtleXMgc3BlY2lmaWVkIGluXG4gIC8vIGxhdGVyIG1hcHBpbmcgbm9kZXMuIC0tIGh0dHA6Ly95YW1sLm9yZy90eXBlL21lcmdlLmh0bWxcblxuXG4gIGFkZFRvSlNNYXAoY3R4LCBtYXApIHtcbiAgICBmb3IgKGNvbnN0IHtcbiAgICAgIHNvdXJjZVxuICAgIH0gb2YgdGhpcy52YWx1ZS5pdGVtcykge1xuICAgICAgaWYgKCEoc291cmNlIGluc3RhbmNlb2YgWUFNTE1hcCkpIHRocm93IG5ldyBFcnJvcignTWVyZ2Ugc291cmNlcyBtdXN0IGJlIG1hcHMnKTtcbiAgICAgIGNvbnN0IHNyY01hcCA9IHNvdXJjZS50b0pTT04obnVsbCwgY3R4LCBNYXApO1xuXG4gICAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBzcmNNYXApIHtcbiAgICAgICAgaWYgKG1hcCBpbnN0YW5jZW9mIE1hcCkge1xuICAgICAgICAgIGlmICghbWFwLmhhcyhrZXkpKSBtYXAuc2V0KGtleSwgdmFsdWUpO1xuICAgICAgICB9IGVsc2UgaWYgKG1hcCBpbnN0YW5jZW9mIFNldCkge1xuICAgICAgICAgIG1hcC5hZGQoa2V5KTtcbiAgICAgICAgfSBlbHNlIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1hcCwga2V5KSkge1xuICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShtYXAsIGtleSwge1xuICAgICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBtYXA7XG4gIH1cblxuICB0b1N0cmluZyhjdHgsIG9uQ29tbWVudCkge1xuICAgIGNvbnN0IHNlcSA9IHRoaXMudmFsdWU7XG4gICAgaWYgKHNlcS5pdGVtcy5sZW5ndGggPiAxKSByZXR1cm4gc3VwZXIudG9TdHJpbmcoY3R4LCBvbkNvbW1lbnQpO1xuICAgIHRoaXMudmFsdWUgPSBzZXEuaXRlbXNbMF07XG4gICAgY29uc3Qgc3RyID0gc3VwZXIudG9TdHJpbmcoY3R4LCBvbkNvbW1lbnQpO1xuICAgIHRoaXMudmFsdWUgPSBzZXE7XG4gICAgcmV0dXJuIHN0cjtcbiAgfVxuXG59XG5cbmV4cG9ydCB7IE1FUkdFX0tFWSwgTWVyZ2UgfTtcbiIsImltcG9ydCB7IGRlZmluZVByb3BlcnR5IGFzIF9kZWZpbmVQcm9wZXJ0eSB9IGZyb20gJy4uL192aXJ0dWFsL19yb2xsdXBQbHVnaW5CYWJlbEhlbHBlcnMuanMnO1xuaW1wb3J0IHsgU2NhbGFyIH0gZnJvbSAnLi4vYXN0L1NjYWxhci5qcyc7XG5pbXBvcnQgeyBZQU1MU2VxIH0gZnJvbSAnLi4vYXN0L1lBTUxTZXEuanMnO1xuaW1wb3J0IHsgWUFNTE1hcCB9IGZyb20gJy4uL2FzdC9ZQU1MTWFwLmpzJztcbmltcG9ydCB7IEFsaWFzIH0gZnJvbSAnLi4vYXN0L0FsaWFzLmpzJztcbmltcG9ydCB7IE1lcmdlIH0gZnJvbSAnLi4vYXN0L01lcmdlLmpzJztcblxuY2xhc3MgQW5jaG9ycyB7XG4gIHN0YXRpYyB2YWxpZEFuY2hvck5vZGUobm9kZSkge1xuICAgIHJldHVybiBub2RlIGluc3RhbmNlb2YgU2NhbGFyIHx8IG5vZGUgaW5zdGFuY2VvZiBZQU1MU2VxIHx8IG5vZGUgaW5zdGFuY2VvZiBZQU1MTWFwO1xuICB9XG5cbiAgY29uc3RydWN0b3IocHJlZml4KSB7XG4gICAgX2RlZmluZVByb3BlcnR5KHRoaXMsIFwibWFwXCIsIE9iamVjdC5jcmVhdGUobnVsbCkpO1xuXG4gICAgdGhpcy5wcmVmaXggPSBwcmVmaXg7XG4gIH1cblxuICBjcmVhdGVBbGlhcyhub2RlLCBuYW1lKSB7XG4gICAgdGhpcy5zZXRBbmNob3Iobm9kZSwgbmFtZSk7XG4gICAgcmV0dXJuIG5ldyBBbGlhcyhub2RlKTtcbiAgfVxuXG4gIGNyZWF0ZU1lcmdlUGFpciguLi5zb3VyY2VzKSB7XG4gICAgY29uc3QgbWVyZ2UgPSBuZXcgTWVyZ2UoKTtcbiAgICBtZXJnZS52YWx1ZS5pdGVtcyA9IHNvdXJjZXMubWFwKHMgPT4ge1xuICAgICAgaWYgKHMgaW5zdGFuY2VvZiBBbGlhcykge1xuICAgICAgICBpZiAocy5zb3VyY2UgaW5zdGFuY2VvZiBZQU1MTWFwKSByZXR1cm4gcztcbiAgICAgIH0gZWxzZSBpZiAocyBpbnN0YW5jZW9mIFlBTUxNYXApIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlQWxpYXMocyk7XG4gICAgICB9XG5cbiAgICAgIHRocm93IG5ldyBFcnJvcignTWVyZ2Ugc291cmNlcyBtdXN0IGJlIE1hcCBub2RlcyBvciB0aGVpciBBbGlhc2VzJyk7XG4gICAgfSk7XG4gICAgcmV0dXJuIG1lcmdlO1xuICB9XG5cbiAgZ2V0TmFtZShub2RlKSB7XG4gICAgY29uc3Qge1xuICAgICAgbWFwXG4gICAgfSA9IHRoaXM7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKG1hcCkuZmluZChhID0+IG1hcFthXSA9PT0gbm9kZSk7XG4gIH1cblxuICBnZXROYW1lcygpIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5tYXApO1xuICB9XG5cbiAgZ2V0Tm9kZShuYW1lKSB7XG4gICAgcmV0dXJuIHRoaXMubWFwW25hbWVdO1xuICB9XG5cbiAgbmV3TmFtZShwcmVmaXgpIHtcbiAgICBpZiAoIXByZWZpeCkgcHJlZml4ID0gdGhpcy5wcmVmaXg7XG4gICAgY29uc3QgbmFtZXMgPSBPYmplY3Qua2V5cyh0aGlzLm1hcCk7XG5cbiAgICBmb3IgKGxldCBpID0gMTsgdHJ1ZTsgKytpKSB7XG4gICAgICBjb25zdCBuYW1lID0gXCJcIi5jb25jYXQocHJlZml4KS5jb25jYXQoaSk7XG4gICAgICBpZiAoIW5hbWVzLmluY2x1ZGVzKG5hbWUpKSByZXR1cm4gbmFtZTtcbiAgICB9XG4gIH0gLy8gRHVyaW5nIHBhcnNpbmcsIG1hcCAmIGFsaWFzZXMgY29udGFpbiBDU1Qgbm9kZXNcblxuXG4gIHJlc29sdmVOb2RlcygpIHtcbiAgICBjb25zdCB7XG4gICAgICBtYXAsXG4gICAgICBfY3N0QWxpYXNlc1xuICAgIH0gPSB0aGlzO1xuICAgIE9iamVjdC5rZXlzKG1hcCkuZm9yRWFjaChhID0+IHtcbiAgICAgIG1hcFthXSA9IG1hcFthXS5yZXNvbHZlZDtcbiAgICB9KTtcblxuICAgIF9jc3RBbGlhc2VzLmZvckVhY2goYSA9PiB7XG4gICAgICBhLnNvdXJjZSA9IGEuc291cmNlLnJlc29sdmVkO1xuICAgIH0pO1xuXG4gICAgZGVsZXRlIHRoaXMuX2NzdEFsaWFzZXM7XG4gIH1cblxuICBzZXRBbmNob3Iobm9kZSwgbmFtZSkge1xuICAgIGlmIChub2RlICE9IG51bGwgJiYgIUFuY2hvcnMudmFsaWRBbmNob3JOb2RlKG5vZGUpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FuY2hvcnMgbWF5IG9ubHkgYmUgc2V0IGZvciBTY2FsYXIsIFNlcSBhbmQgTWFwIG5vZGVzJyk7XG4gICAgfVxuXG4gICAgaWYgKG5hbWUgJiYgL1tcXHgwMC1cXHgxOVxccyxbXFxde31dLy50ZXN0KG5hbWUpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FuY2hvciBuYW1lcyBtdXN0IG5vdCBjb250YWluIHdoaXRlc3BhY2Ugb3IgY29udHJvbCBjaGFyYWN0ZXJzJyk7XG4gICAgfVxuXG4gICAgY29uc3Qge1xuICAgICAgbWFwXG4gICAgfSA9IHRoaXM7XG4gICAgY29uc3QgcHJldiA9IG5vZGUgJiYgT2JqZWN0LmtleXMobWFwKS5maW5kKGEgPT4gbWFwW2FdID09PSBub2RlKTtcblxuICAgIGlmIChwcmV2KSB7XG4gICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHByZXY7XG4gICAgICB9IGVsc2UgaWYgKHByZXYgIT09IG5hbWUpIHtcbiAgICAgICAgZGVsZXRlIG1hcFtwcmV2XTtcbiAgICAgICAgbWFwW25hbWVdID0gbm9kZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCFuYW1lKSB7XG4gICAgICAgIGlmICghbm9kZSkgcmV0dXJuIG51bGw7XG4gICAgICAgIG5hbWUgPSB0aGlzLm5ld05hbWUoKTtcbiAgICAgIH1cblxuICAgICAgbWFwW25hbWVdID0gbm9kZTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmFtZTtcbiAgfVxuXG59XG5cbmV4cG9ydCB7IEFuY2hvcnMgfTtcbiIsImZ1bmN0aW9uIHN0cmluZ2lmeU51bWJlcih7XG4gIGZvcm1hdCxcbiAgbWluRnJhY3Rpb25EaWdpdHMsXG4gIHRhZyxcbiAgdmFsdWVcbn0pIHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2JpZ2ludCcpIHJldHVybiBTdHJpbmcodmFsdWUpO1xuICBpZiAoIWlzRmluaXRlKHZhbHVlKSkgcmV0dXJuIGlzTmFOKHZhbHVlKSA/ICcubmFuJyA6IHZhbHVlIDwgMCA/ICctLmluZicgOiAnLmluZic7XG4gIGxldCBuID0gSlNPTi5zdHJpbmdpZnkodmFsdWUpO1xuXG4gIGlmICghZm9ybWF0ICYmIG1pbkZyYWN0aW9uRGlnaXRzICYmICghdGFnIHx8IHRhZyA9PT0gJ3RhZzp5YW1sLm9yZywyMDAyOmZsb2F0JykgJiYgL15cXGQvLnRlc3QobikpIHtcbiAgICBsZXQgaSA9IG4uaW5kZXhPZignLicpO1xuXG4gICAgaWYgKGkgPCAwKSB7XG4gICAgICBpID0gbi5sZW5ndGg7XG4gICAgICBuICs9ICcuJztcbiAgICB9XG5cbiAgICBsZXQgZCA9IG1pbkZyYWN0aW9uRGlnaXRzIC0gKG4ubGVuZ3RoIC0gaSAtIDEpO1xuXG4gICAgd2hpbGUgKGQtLSA+IDApIG4gKz0gJzAnO1xuICB9XG5cbiAgcmV0dXJuIG47XG59XG5cbmV4cG9ydCB7IHN0cmluZ2lmeU51bWJlciB9O1xuIiwiaW1wb3J0IHsgY3JlYXRlUGFpciB9IGZyb20gJy4uLy4uL2FzdC9QYWlyLmpzJztcbmltcG9ydCB7IFlBTUxNYXAgfSBmcm9tICcuLi8uLi9hc3QvWUFNTE1hcC5qcyc7XG5cbmZ1bmN0aW9uIGNyZWF0ZU1hcChzY2hlbWEsIG9iaiwgY3R4KSB7XG4gIGNvbnN0IHtcbiAgICBrZWVwVW5kZWZpbmVkLFxuICAgIHJlcGxhY2VyXG4gIH0gPSBjdHg7XG4gIGNvbnN0IG1hcCA9IG5ldyBZQU1MTWFwKHNjaGVtYSk7XG5cbiAgY29uc3QgYWRkID0gKGtleSwgdmFsdWUpID0+IHtcbiAgICBpZiAodHlwZW9mIHJlcGxhY2VyID09PSAnZnVuY3Rpb24nKSB2YWx1ZSA9IHJlcGxhY2VyLmNhbGwob2JqLCBrZXksIHZhbHVlKTtlbHNlIGlmIChBcnJheS5pc0FycmF5KHJlcGxhY2VyKSAmJiAhcmVwbGFjZXIuaW5jbHVkZXMoa2V5KSkgcmV0dXJuO1xuICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkIHx8IGtlZXBVbmRlZmluZWQpIG1hcC5pdGVtcy5wdXNoKGNyZWF0ZVBhaXIoa2V5LCB2YWx1ZSwgY3R4KSk7XG4gIH07XG5cbiAgaWYgKG9iaiBpbnN0YW5jZW9mIE1hcCkge1xuICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIG9iaikgYWRkKGtleSwgdmFsdWUpO1xuICB9IGVsc2UgaWYgKG9iaiAmJiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0Jykge1xuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKG9iaikpIGFkZChrZXksIG9ialtrZXldKTtcbiAgfVxuXG4gIGlmICh0eXBlb2Ygc2NoZW1hLnNvcnRNYXBFbnRyaWVzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgbWFwLml0ZW1zLnNvcnQoc2NoZW1hLnNvcnRNYXBFbnRyaWVzKTtcbiAgfVxuXG4gIHJldHVybiBtYXA7XG59XG5cbmNvbnN0IG1hcCA9IHtcbiAgY3JlYXRlTm9kZTogY3JlYXRlTWFwLFxuICBkZWZhdWx0OiB0cnVlLFxuICBub2RlQ2xhc3M6IFlBTUxNYXAsXG4gIHRhZzogJ3RhZzp5YW1sLm9yZywyMDAyOm1hcCcsXG4gIHJlc29sdmU6IG1hcCA9PiBtYXBcbn07XG5cbmV4cG9ydCB7IG1hcCB9O1xuIiwiaW1wb3J0IHsgWUFNTFNlcSB9IGZyb20gJy4uLy4uL2FzdC9ZQU1MU2VxLmpzJztcbmltcG9ydCB7IGNyZWF0ZU5vZGUgfSBmcm9tICcuLi8uLi9kb2MvY3JlYXRlTm9kZS5qcyc7XG5cbmZ1bmN0aW9uIGNyZWF0ZVNlcShzY2hlbWEsIG9iaiwgY3R4KSB7XG4gIGNvbnN0IHtcbiAgICByZXBsYWNlclxuICB9ID0gY3R4O1xuICBjb25zdCBzZXEgPSBuZXcgWUFNTFNlcShzY2hlbWEpO1xuXG4gIGlmIChvYmogJiYgb2JqW1N5bWJvbC5pdGVyYXRvcl0pIHtcbiAgICBsZXQgaSA9IDA7XG5cbiAgICBmb3IgKGxldCBpdCBvZiBvYmopIHtcbiAgICAgIGlmICh0eXBlb2YgcmVwbGFjZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgY29uc3Qga2V5ID0gb2JqIGluc3RhbmNlb2YgU2V0ID8gaXQgOiBTdHJpbmcoaSsrKTtcbiAgICAgICAgaXQgPSByZXBsYWNlci5jYWxsKG9iaiwga2V5LCBpdCk7XG4gICAgICB9XG5cbiAgICAgIHNlcS5pdGVtcy5wdXNoKGNyZWF0ZU5vZGUoaXQsIG51bGwsIGN0eCkpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBzZXE7XG59XG5cbmNvbnN0IHNlcSA9IHtcbiAgY3JlYXRlTm9kZTogY3JlYXRlU2VxLFxuICBkZWZhdWx0OiB0cnVlLFxuICBub2RlQ2xhc3M6IFlBTUxTZXEsXG4gIHRhZzogJ3RhZzp5YW1sLm9yZywyMDAyOnNlcScsXG4gIHJlc29sdmU6IHNlcSA9PiBzZXFcbn07XG5cbmV4cG9ydCB7IHNlcSB9O1xuIiwiaW1wb3J0IHsgc3RyaW5naWZ5U3RyaW5nIH0gZnJvbSAnLi4vLi4vc3RyaW5naWZ5L3N0cmluZ2lmeVN0cmluZy5qcyc7XG5pbXBvcnQgeyBzdHJPcHRpb25zIH0gZnJvbSAnLi4vb3B0aW9ucy5qcyc7XG5cbmNvbnN0IHN0cmluZyA9IHtcbiAgaWRlbnRpZnk6IHZhbHVlID0+IHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycsXG4gIGRlZmF1bHQ6IHRydWUsXG4gIHRhZzogJ3RhZzp5YW1sLm9yZywyMDAyOnN0cicsXG4gIHJlc29sdmU6IHN0ciA9PiBzdHIsXG5cbiAgc3RyaW5naWZ5KGl0ZW0sIGN0eCwgb25Db21tZW50LCBvbkNob21wS2VlcCkge1xuICAgIGN0eCA9IE9iamVjdC5hc3NpZ24oe1xuICAgICAgYWN0dWFsU3RyaW5nOiB0cnVlXG4gICAgfSwgY3R4KTtcbiAgICByZXR1cm4gc3RyaW5naWZ5U3RyaW5nKGl0ZW0sIGN0eCwgb25Db21tZW50LCBvbkNob21wS2VlcCk7XG4gIH0sXG5cbiAgb3B0aW9uczogc3RyT3B0aW9uc1xufTtcblxuZXhwb3J0IHsgc3RyaW5nIH07XG4iLCJpbXBvcnQgeyBtYXAgfSBmcm9tICcuL21hcC5qcyc7XG5pbXBvcnQgeyBzZXEgfSBmcm9tICcuL3NlcS5qcyc7XG5pbXBvcnQgeyBzdHJpbmcgfSBmcm9tICcuL3N0cmluZy5qcyc7XG5cbmNvbnN0IGZhaWxzYWZlID0gW21hcCwgc2VxLCBzdHJpbmddO1xuXG5leHBvcnQgeyBmYWlsc2FmZSB9O1xuIiwiaW1wb3J0IHsgU2NhbGFyIH0gZnJvbSAnLi4vYXN0L1NjYWxhci5qcyc7XG5pbXBvcnQgeyBzdHJpbmdpZnlOdW1iZXIgfSBmcm9tICcuLi9zdHJpbmdpZnkvc3RyaW5naWZ5TnVtYmVyLmpzJztcbmltcG9ydCB7IGZhaWxzYWZlIH0gZnJvbSAnLi9mYWlsc2FmZS9pbmRleC5qcyc7XG5pbXBvcnQgeyBudWxsT3B0aW9ucywgYm9vbE9wdGlvbnMsIGludE9wdGlvbnMgfSBmcm9tICcuL29wdGlvbnMuanMnO1xuXG4vKiBnbG9iYWwgQmlnSW50ICovXG5cbmNvbnN0IGludElkZW50aWZ5ID0gdmFsdWUgPT4gdHlwZW9mIHZhbHVlID09PSAnYmlnaW50JyB8fCBOdW1iZXIuaXNJbnRlZ2VyKHZhbHVlKTtcblxuY29uc3QgaW50UmVzb2x2ZSA9IChzcmMsIG9mZnNldCwgcmFkaXgpID0+IGludE9wdGlvbnMuYXNCaWdJbnQgPyBCaWdJbnQoc3JjKSA6IHBhcnNlSW50KHNyYy5zdWJzdHJpbmcob2Zmc2V0KSwgcmFkaXgpO1xuXG5mdW5jdGlvbiBpbnRTdHJpbmdpZnkobm9kZSwgcmFkaXgsIHByZWZpeCkge1xuICBjb25zdCB7XG4gICAgdmFsdWVcbiAgfSA9IG5vZGU7XG4gIGlmIChpbnRJZGVudGlmeSh2YWx1ZSkgJiYgdmFsdWUgPj0gMCkgcmV0dXJuIHByZWZpeCArIHZhbHVlLnRvU3RyaW5nKHJhZGl4KTtcbiAgcmV0dXJuIHN0cmluZ2lmeU51bWJlcihub2RlKTtcbn1cblxuZnVuY3Rpb24gc3RyaW5naWZ5Qm9vbChub2RlKSB7XG4gIGNvbnN0IHtcbiAgICB2YWx1ZSxcbiAgICBzb3VyY2VTdHJcbiAgfSA9IG5vZGU7XG5cbiAgaWYgKHNvdXJjZVN0cikge1xuICAgIGNvbnN0IG1hdGNoID0gYm9vbE9iai50ZXN0LnRlc3Qoc291cmNlU3RyKTtcbiAgICBpZiAobWF0Y2ggJiYgdmFsdWUgPT09IChzb3VyY2VTdHJbMF0gPT09ICd0JyB8fCBzb3VyY2VTdHJbMF0gPT09ICdUJykpIHJldHVybiBzb3VyY2VTdHI7XG4gIH1cblxuICByZXR1cm4gdmFsdWUgPyBib29sT3B0aW9ucy50cnVlU3RyIDogYm9vbE9wdGlvbnMuZmFsc2VTdHI7XG59XG5cbmNvbnN0IG51bGxPYmogPSB7XG4gIGlkZW50aWZ5OiB2YWx1ZSA9PiB2YWx1ZSA9PSBudWxsLFxuICBjcmVhdGVOb2RlOiAoc2NoZW1hLCB2YWx1ZSwgY3R4KSA9PiBjdHgud3JhcFNjYWxhcnMgPyBuZXcgU2NhbGFyKG51bGwpIDogbnVsbCxcbiAgZGVmYXVsdDogdHJ1ZSxcbiAgdGFnOiAndGFnOnlhbWwub3JnLDIwMDI6bnVsbCcsXG4gIHRlc3Q6IC9eKD86fnxbTm5ddWxsfE5VTEwpPyQvLFxuICByZXNvbHZlOiBzdHIgPT4ge1xuICAgIGNvbnN0IG5vZGUgPSBuZXcgU2NhbGFyKG51bGwpO1xuICAgIG5vZGUuc291cmNlU3RyID0gc3RyO1xuICAgIHJldHVybiBub2RlO1xuICB9LFxuICBvcHRpb25zOiBudWxsT3B0aW9ucyxcbiAgc3RyaW5naWZ5OiAoe1xuICAgIHNvdXJjZVN0clxuICB9KSA9PiBzb3VyY2VTdHIgIT09IG51bGwgJiYgc291cmNlU3RyICE9PSB2b2lkIDAgPyBzb3VyY2VTdHIgOiBudWxsT3B0aW9ucy5udWxsU3RyXG59O1xuY29uc3QgYm9vbE9iaiA9IHtcbiAgaWRlbnRpZnk6IHZhbHVlID0+IHR5cGVvZiB2YWx1ZSA9PT0gJ2Jvb2xlYW4nLFxuICBkZWZhdWx0OiB0cnVlLFxuICB0YWc6ICd0YWc6eWFtbC5vcmcsMjAwMjpib29sJyxcbiAgdGVzdDogL14oPzpbVHRdcnVlfFRSVUV8W0ZmXWFsc2V8RkFMU0UpJC8sXG4gIHJlc29sdmU6IHN0ciA9PiB7XG4gICAgY29uc3Qgbm9kZSA9IG5ldyBTY2FsYXIoc3RyWzBdID09PSAndCcgfHwgc3RyWzBdID09PSAnVCcpO1xuICAgIG5vZGUuc291cmNlU3RyID0gc3RyO1xuICAgIHJldHVybiBub2RlO1xuICB9LFxuICBvcHRpb25zOiBib29sT3B0aW9ucyxcbiAgc3RyaW5naWZ5OiBzdHJpbmdpZnlCb29sXG59O1xuY29uc3Qgb2N0T2JqID0ge1xuICBpZGVudGlmeTogdmFsdWUgPT4gaW50SWRlbnRpZnkodmFsdWUpICYmIHZhbHVlID49IDAsXG4gIGRlZmF1bHQ6IHRydWUsXG4gIHRhZzogJ3RhZzp5YW1sLm9yZywyMDAyOmludCcsXG4gIGZvcm1hdDogJ09DVCcsXG4gIHRlc3Q6IC9eMG9bMC03XSskLyxcbiAgcmVzb2x2ZTogc3RyID0+IGludFJlc29sdmUoc3RyLCAyLCA4KSxcbiAgb3B0aW9uczogaW50T3B0aW9ucyxcbiAgc3RyaW5naWZ5OiBub2RlID0+IGludFN0cmluZ2lmeShub2RlLCA4LCAnMG8nKVxufTtcbmNvbnN0IGludE9iaiA9IHtcbiAgaWRlbnRpZnk6IGludElkZW50aWZ5LFxuICBkZWZhdWx0OiB0cnVlLFxuICB0YWc6ICd0YWc6eWFtbC5vcmcsMjAwMjppbnQnLFxuICB0ZXN0OiAvXlstK10/WzAtOV0rJC8sXG4gIHJlc29sdmU6IHN0ciA9PiBpbnRSZXNvbHZlKHN0ciwgMCwgMTApLFxuICBvcHRpb25zOiBpbnRPcHRpb25zLFxuICBzdHJpbmdpZnk6IHN0cmluZ2lmeU51bWJlclxufTtcbmNvbnN0IGhleE9iaiA9IHtcbiAgaWRlbnRpZnk6IHZhbHVlID0+IGludElkZW50aWZ5KHZhbHVlKSAmJiB2YWx1ZSA+PSAwLFxuICBkZWZhdWx0OiB0cnVlLFxuICB0YWc6ICd0YWc6eWFtbC5vcmcsMjAwMjppbnQnLFxuICBmb3JtYXQ6ICdIRVgnLFxuICB0ZXN0OiAvXjB4WzAtOWEtZkEtRl0rJC8sXG4gIHJlc29sdmU6IHN0ciA9PiBpbnRSZXNvbHZlKHN0ciwgMiwgMTYpLFxuICBvcHRpb25zOiBpbnRPcHRpb25zLFxuICBzdHJpbmdpZnk6IG5vZGUgPT4gaW50U3RyaW5naWZ5KG5vZGUsIDE2LCAnMHgnKVxufTtcbmNvbnN0IG5hbk9iaiA9IHtcbiAgaWRlbnRpZnk6IHZhbHVlID0+IHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicsXG4gIGRlZmF1bHQ6IHRydWUsXG4gIHRhZzogJ3RhZzp5YW1sLm9yZywyMDAyOmZsb2F0JyxcbiAgdGVzdDogL14oPzpbLStdP1xcLig/OmluZnxJbmZ8SU5GfG5hbnxOYU58TkFOKSkkLyxcbiAgcmVzb2x2ZTogc3RyID0+IHN0ci5zbGljZSgtMykudG9Mb3dlckNhc2UoKSA9PT0gJ25hbicgPyBOYU4gOiBzdHJbMF0gPT09ICctJyA/IE51bWJlci5ORUdBVElWRV9JTkZJTklUWSA6IE51bWJlci5QT1NJVElWRV9JTkZJTklUWSxcbiAgc3RyaW5naWZ5OiBzdHJpbmdpZnlOdW1iZXJcbn07XG5jb25zdCBleHBPYmogPSB7XG4gIGlkZW50aWZ5OiB2YWx1ZSA9PiB0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInLFxuICBkZWZhdWx0OiB0cnVlLFxuICB0YWc6ICd0YWc6eWFtbC5vcmcsMjAwMjpmbG9hdCcsXG4gIGZvcm1hdDogJ0VYUCcsXG4gIHRlc3Q6IC9eWy0rXT8oPzpcXC5bMC05XSt8WzAtOV0rKD86XFwuWzAtOV0qKT8pW2VFXVstK10/WzAtOV0rJC8sXG4gIHJlc29sdmU6IHN0ciA9PiBwYXJzZUZsb2F0KHN0ciksXG4gIHN0cmluZ2lmeTogKHtcbiAgICB2YWx1ZVxuICB9KSA9PiBOdW1iZXIodmFsdWUpLnRvRXhwb25lbnRpYWwoKVxufTtcbmNvbnN0IGZsb2F0T2JqID0ge1xuICBpZGVudGlmeTogdmFsdWUgPT4gdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyxcbiAgZGVmYXVsdDogdHJ1ZSxcbiAgdGFnOiAndGFnOnlhbWwub3JnLDIwMDI6ZmxvYXQnLFxuICB0ZXN0OiAvXlstK10/KD86XFwuWzAtOV0rfFswLTldK1xcLlswLTldKikkLyxcblxuICByZXNvbHZlKHN0cikge1xuICAgIGNvbnN0IG5vZGUgPSBuZXcgU2NhbGFyKHBhcnNlRmxvYXQoc3RyKSk7XG4gICAgY29uc3QgZG90ID0gc3RyLmluZGV4T2YoJy4nKTtcbiAgICBpZiAoZG90ICE9PSAtMSAmJiBzdHJbc3RyLmxlbmd0aCAtIDFdID09PSAnMCcpIG5vZGUubWluRnJhY3Rpb25EaWdpdHMgPSBzdHIubGVuZ3RoIC0gZG90IC0gMTtcbiAgICByZXR1cm4gbm9kZTtcbiAgfSxcblxuICBzdHJpbmdpZnk6IHN0cmluZ2lmeU51bWJlclxufTtcbmNvbnN0IGNvcmUgPSBmYWlsc2FmZS5jb25jYXQoW251bGxPYmosIGJvb2xPYmosIG9jdE9iaiwgaW50T2JqLCBoZXhPYmosIG5hbk9iaiwgZXhwT2JqLCBmbG9hdE9ial0pO1xuXG5leHBvcnQgeyBib29sT2JqLCBjb3JlLCBleHBPYmosIGZsb2F0T2JqLCBoZXhPYmosIGludE9iaiwgbmFuT2JqLCBudWxsT2JqLCBvY3RPYmogfTtcbiIsImltcG9ydCB7IFNjYWxhciB9IGZyb20gJy4uL2FzdC9TY2FsYXIuanMnO1xuaW1wb3J0IHsgbWFwIH0gZnJvbSAnLi9mYWlsc2FmZS9tYXAuanMnO1xuaW1wb3J0IHsgc2VxIH0gZnJvbSAnLi9mYWlsc2FmZS9zZXEuanMnO1xuaW1wb3J0IHsgaW50T3B0aW9ucyB9IGZyb20gJy4vb3B0aW9ucy5qcyc7XG5cbi8qIGdsb2JhbCBCaWdJbnQgKi9cblxuY29uc3QgaW50SWRlbnRpZnkgPSB2YWx1ZSA9PiB0eXBlb2YgdmFsdWUgPT09ICdiaWdpbnQnIHx8IE51bWJlci5pc0ludGVnZXIodmFsdWUpO1xuXG5jb25zdCBzdHJpbmdpZnlKU09OID0gKHtcbiAgdmFsdWVcbn0pID0+IEpTT04uc3RyaW5naWZ5KHZhbHVlKTtcblxuY29uc3QganNvbiA9IFttYXAsIHNlcSwge1xuICBpZGVudGlmeTogdmFsdWUgPT4gdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyxcbiAgZGVmYXVsdDogdHJ1ZSxcbiAgdGFnOiAndGFnOnlhbWwub3JnLDIwMDI6c3RyJyxcbiAgcmVzb2x2ZTogc3RyID0+IHN0cixcbiAgc3RyaW5naWZ5OiBzdHJpbmdpZnlKU09OXG59LCB7XG4gIGlkZW50aWZ5OiB2YWx1ZSA9PiB2YWx1ZSA9PSBudWxsLFxuICBjcmVhdGVOb2RlOiAoc2NoZW1hLCB2YWx1ZSwgY3R4KSA9PiBjdHgud3JhcFNjYWxhcnMgPyBuZXcgU2NhbGFyKG51bGwpIDogbnVsbCxcbiAgZGVmYXVsdDogdHJ1ZSxcbiAgdGFnOiAndGFnOnlhbWwub3JnLDIwMDI6bnVsbCcsXG4gIHRlc3Q6IC9ebnVsbCQvLFxuICByZXNvbHZlOiAoKSA9PiBudWxsLFxuICBzdHJpbmdpZnk6IHN0cmluZ2lmeUpTT05cbn0sIHtcbiAgaWRlbnRpZnk6IHZhbHVlID0+IHR5cGVvZiB2YWx1ZSA9PT0gJ2Jvb2xlYW4nLFxuICBkZWZhdWx0OiB0cnVlLFxuICB0YWc6ICd0YWc6eWFtbC5vcmcsMjAwMjpib29sJyxcbiAgdGVzdDogL150cnVlfGZhbHNlJC8sXG4gIHJlc29sdmU6IHN0ciA9PiBzdHIgPT09ICd0cnVlJyxcbiAgc3RyaW5naWZ5OiBzdHJpbmdpZnlKU09OXG59LCB7XG4gIGlkZW50aWZ5OiBpbnRJZGVudGlmeSxcbiAgZGVmYXVsdDogdHJ1ZSxcbiAgdGFnOiAndGFnOnlhbWwub3JnLDIwMDI6aW50JyxcbiAgdGVzdDogL14tPyg/OjB8WzEtOV1bMC05XSopJC8sXG4gIHJlc29sdmU6IHN0ciA9PiBpbnRPcHRpb25zLmFzQmlnSW50ID8gQmlnSW50KHN0cikgOiBwYXJzZUludChzdHIsIDEwKSxcbiAgc3RyaW5naWZ5OiAoe1xuICAgIHZhbHVlXG4gIH0pID0+IGludElkZW50aWZ5KHZhbHVlKSA/IHZhbHVlLnRvU3RyaW5nKCkgOiBKU09OLnN0cmluZ2lmeSh2YWx1ZSlcbn0sIHtcbiAgaWRlbnRpZnk6IHZhbHVlID0+IHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicsXG4gIGRlZmF1bHQ6IHRydWUsXG4gIHRhZzogJ3RhZzp5YW1sLm9yZywyMDAyOmZsb2F0JyxcbiAgdGVzdDogL14tPyg/OjB8WzEtOV1bMC05XSopKD86XFwuWzAtOV0qKT8oPzpbZUVdWy0rXT9bMC05XSspPyQvLFxuICByZXNvbHZlOiBzdHIgPT4gcGFyc2VGbG9hdChzdHIpLFxuICBzdHJpbmdpZnk6IHN0cmluZ2lmeUpTT05cbn0sIHtcbiAgZGVmYXVsdDogdHJ1ZSxcbiAgdGVzdDogL14vLFxuXG4gIHJlc29sdmUoc3RyLCBvbkVycm9yKSB7XG4gICAgb25FcnJvcihcIlVucmVzb2x2ZWQgcGxhaW4gc2NhbGFyIFwiLmNvbmNhdChKU09OLnN0cmluZ2lmeShzdHIpKSk7XG4gICAgcmV0dXJuIHN0cjtcbiAgfVxuXG59XTtcblxuZXhwb3J0IHsganNvbiB9O1xuIiwiaW1wb3J0IHsgVHlwZSB9IGZyb20gJy4uLy4uL2NvbnN0YW50cy5qcyc7XG5pbXBvcnQgeyBzdHJpbmdpZnlTdHJpbmcgfSBmcm9tICcuLi8uLi9zdHJpbmdpZnkvc3RyaW5naWZ5U3RyaW5nLmpzJztcbmltcG9ydCB7IGJpbmFyeU9wdGlvbnMgfSBmcm9tICcuLi9vcHRpb25zLmpzJztcblxuLyogZ2xvYmFsIGF0b2IsIGJ0b2EsIEJ1ZmZlciAqL1xuY29uc3QgYmluYXJ5ID0ge1xuICBpZGVudGlmeTogdmFsdWUgPT4gdmFsdWUgaW5zdGFuY2VvZiBVaW50OEFycmF5LFxuICAvLyBCdWZmZXIgaW5oZXJpdHMgZnJvbSBVaW50OEFycmF5XG4gIGRlZmF1bHQ6IGZhbHNlLFxuICB0YWc6ICd0YWc6eWFtbC5vcmcsMjAwMjpiaW5hcnknLFxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgQnVmZmVyIGluIG5vZGUgYW5kIGFuIFVpbnQ4QXJyYXkgaW4gYnJvd3NlcnNcbiAgICpcbiAgICogVG8gdXNlIHRoZSByZXN1bHRpbmcgYnVmZmVyIGFzIGFuIGltYWdlLCB5b3UnbGwgd2FudCB0byBkbyBzb21ldGhpbmcgbGlrZTpcbiAgICpcbiAgICogICBjb25zdCBibG9iID0gbmV3IEJsb2IoW2J1ZmZlcl0sIHsgdHlwZTogJ2ltYWdlL2pwZWcnIH0pXG4gICAqICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI3Bob3RvJykuc3JjID0gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKVxuICAgKi9cbiAgcmVzb2x2ZShzcmMsIG9uRXJyb3IpIHtcbiAgICBpZiAodHlwZW9mIEJ1ZmZlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKHNyYywgJ2Jhc2U2NCcpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGF0b2IgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIC8vIE9uIElFIDExLCBhdG9iKCkgY2FuJ3QgaGFuZGxlIG5ld2xpbmVzXG4gICAgICBjb25zdCBzdHIgPSBhdG9iKHNyYy5yZXBsYWNlKC9bXFxuXFxyXS9nLCAnJykpO1xuICAgICAgY29uc3QgYnVmZmVyID0gbmV3IFVpbnQ4QXJyYXkoc3RyLmxlbmd0aCk7XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgKytpKSBidWZmZXJbaV0gPSBzdHIuY2hhckNvZGVBdChpKTtcblxuICAgICAgcmV0dXJuIGJ1ZmZlcjtcbiAgICB9IGVsc2Uge1xuICAgICAgb25FcnJvcignVGhpcyBlbnZpcm9ubWVudCBkb2VzIG5vdCBzdXBwb3J0IHJlYWRpbmcgYmluYXJ5IHRhZ3M7IGVpdGhlciBCdWZmZXIgb3IgYXRvYiBpcyByZXF1aXJlZCcpO1xuICAgICAgcmV0dXJuIHNyYztcbiAgICB9XG4gIH0sXG5cbiAgb3B0aW9uczogYmluYXJ5T3B0aW9ucyxcbiAgc3RyaW5naWZ5OiAoe1xuICAgIGNvbW1lbnQsXG4gICAgdHlwZSxcbiAgICB2YWx1ZVxuICB9LCBjdHgsIG9uQ29tbWVudCwgb25DaG9tcEtlZXApID0+IHtcbiAgICBsZXQgc3JjO1xuXG4gICAgaWYgKHR5cGVvZiBCdWZmZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHNyYyA9IHZhbHVlIGluc3RhbmNlb2YgQnVmZmVyID8gdmFsdWUudG9TdHJpbmcoJ2Jhc2U2NCcpIDogQnVmZmVyLmZyb20odmFsdWUuYnVmZmVyKS50b1N0cmluZygnYmFzZTY0Jyk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgYnRvYSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgbGV0IHMgPSAnJztcblxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB2YWx1ZS5sZW5ndGg7ICsraSkgcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHZhbHVlW2ldKTtcblxuICAgICAgc3JjID0gYnRvYShzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGlzIGVudmlyb25tZW50IGRvZXMgbm90IHN1cHBvcnQgd3JpdGluZyBiaW5hcnkgdGFnczsgZWl0aGVyIEJ1ZmZlciBvciBidG9hIGlzIHJlcXVpcmVkJyk7XG4gICAgfVxuXG4gICAgaWYgKCF0eXBlKSB0eXBlID0gYmluYXJ5T3B0aW9ucy5kZWZhdWx0VHlwZTtcblxuICAgIGlmICh0eXBlID09PSBUeXBlLlFVT1RFX0RPVUJMRSkge1xuICAgICAgdmFsdWUgPSBzcmM7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHtcbiAgICAgICAgbGluZVdpZHRoXG4gICAgICB9ID0gYmluYXJ5T3B0aW9ucztcbiAgICAgIGNvbnN0IG4gPSBNYXRoLmNlaWwoc3JjLmxlbmd0aCAvIGxpbmVXaWR0aCk7XG4gICAgICBjb25zdCBsaW5lcyA9IG5ldyBBcnJheShuKTtcblxuICAgICAgZm9yIChsZXQgaSA9IDAsIG8gPSAwOyBpIDwgbjsgKytpLCBvICs9IGxpbmVXaWR0aCkge1xuICAgICAgICBsaW5lc1tpXSA9IHNyYy5zdWJzdHIobywgbGluZVdpZHRoKTtcbiAgICAgIH1cblxuICAgICAgdmFsdWUgPSBsaW5lcy5qb2luKHR5cGUgPT09IFR5cGUuQkxPQ0tfTElURVJBTCA/ICdcXG4nIDogJyAnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc3RyaW5naWZ5U3RyaW5nKHtcbiAgICAgIGNvbW1lbnQsXG4gICAgICB0eXBlLFxuICAgICAgdmFsdWVcbiAgICB9LCBjdHgsIG9uQ29tbWVudCwgb25DaG9tcEtlZXApO1xuICB9XG59O1xuXG5leHBvcnQgeyBiaW5hcnkgfTtcbiIsImltcG9ydCB7IFBhaXIsIGNyZWF0ZVBhaXIgfSBmcm9tICcuLi8uLi9hc3QvUGFpci5qcyc7XG5pbXBvcnQgeyBZQU1MTWFwIH0gZnJvbSAnLi4vLi4vYXN0L1lBTUxNYXAuanMnO1xuaW1wb3J0IHsgWUFNTFNlcSB9IGZyb20gJy4uLy4uL2FzdC9ZQU1MU2VxLmpzJztcblxuZnVuY3Rpb24gcGFyc2VQYWlycyhzZXEsIG9uRXJyb3IpIHtcbiAgaWYgKHNlcSBpbnN0YW5jZW9mIFlBTUxTZXEpIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNlcS5pdGVtcy5sZW5ndGg7ICsraSkge1xuICAgICAgbGV0IGl0ZW0gPSBzZXEuaXRlbXNbaV07XG4gICAgICBpZiAoaXRlbSBpbnN0YW5jZW9mIFBhaXIpIGNvbnRpbnVlO2Vsc2UgaWYgKGl0ZW0gaW5zdGFuY2VvZiBZQU1MTWFwKSB7XG4gICAgICAgIGlmIChpdGVtLml0ZW1zLmxlbmd0aCA+IDEpIG9uRXJyb3IoJ0VhY2ggcGFpciBtdXN0IGhhdmUgaXRzIG93biBzZXF1ZW5jZSBpbmRpY2F0b3InKTtcbiAgICAgICAgY29uc3QgcGFpciA9IGl0ZW0uaXRlbXNbMF0gfHwgbmV3IFBhaXIoKTtcbiAgICAgICAgaWYgKGl0ZW0uY29tbWVudEJlZm9yZSkgcGFpci5jb21tZW50QmVmb3JlID0gcGFpci5jb21tZW50QmVmb3JlID8gXCJcIi5jb25jYXQoaXRlbS5jb21tZW50QmVmb3JlLCBcIlxcblwiKS5jb25jYXQocGFpci5jb21tZW50QmVmb3JlKSA6IGl0ZW0uY29tbWVudEJlZm9yZTtcbiAgICAgICAgaWYgKGl0ZW0uY29tbWVudCkgcGFpci5jb21tZW50ID0gcGFpci5jb21tZW50ID8gXCJcIi5jb25jYXQoaXRlbS5jb21tZW50LCBcIlxcblwiKS5jb25jYXQocGFpci5jb21tZW50KSA6IGl0ZW0uY29tbWVudDtcbiAgICAgICAgaXRlbSA9IHBhaXI7XG4gICAgICB9XG4gICAgICBzZXEuaXRlbXNbaV0gPSBpdGVtIGluc3RhbmNlb2YgUGFpciA/IGl0ZW0gOiBuZXcgUGFpcihpdGVtKTtcbiAgICB9XG4gIH0gZWxzZSBvbkVycm9yKCdFeHBlY3RlZCBhIHNlcXVlbmNlIGZvciB0aGlzIHRhZycpO1xuXG4gIHJldHVybiBzZXE7XG59XG5mdW5jdGlvbiBjcmVhdGVQYWlycyhzY2hlbWEsIGl0ZXJhYmxlLCBjdHgpIHtcbiAgY29uc3Qge1xuICAgIHJlcGxhY2VyXG4gIH0gPSBjdHg7XG4gIGNvbnN0IHBhaXJzID0gbmV3IFlBTUxTZXEoc2NoZW1hKTtcbiAgcGFpcnMudGFnID0gJ3RhZzp5YW1sLm9yZywyMDAyOnBhaXJzJztcbiAgbGV0IGkgPSAwO1xuXG4gIGZvciAobGV0IGl0IG9mIGl0ZXJhYmxlKSB7XG4gICAgaWYgKHR5cGVvZiByZXBsYWNlciA9PT0gJ2Z1bmN0aW9uJykgaXQgPSByZXBsYWNlci5jYWxsKGl0ZXJhYmxlLCBTdHJpbmcoaSsrKSwgaXQpO1xuICAgIGxldCBrZXksIHZhbHVlO1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoaXQpKSB7XG4gICAgICBpZiAoaXQubGVuZ3RoID09PSAyKSB7XG4gICAgICAgIGtleSA9IGl0WzBdO1xuICAgICAgICB2YWx1ZSA9IGl0WzFdO1xuICAgICAgfSBlbHNlIHRocm93IG5ldyBUeXBlRXJyb3IoXCJFeHBlY3RlZCBba2V5LCB2YWx1ZV0gdHVwbGU6IFwiLmNvbmNhdChpdCkpO1xuICAgIH0gZWxzZSBpZiAoaXQgJiYgaXQgaW5zdGFuY2VvZiBPYmplY3QpIHtcbiAgICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhpdCk7XG5cbiAgICAgIGlmIChrZXlzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICBrZXkgPSBrZXlzWzBdO1xuICAgICAgICB2YWx1ZSA9IGl0W2tleV07XG4gICAgICB9IGVsc2UgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkV4cGVjdGVkIHsga2V5OiB2YWx1ZSB9IHR1cGxlOiBcIi5jb25jYXQoaXQpKTtcbiAgICB9IGVsc2Uge1xuICAgICAga2V5ID0gaXQ7XG4gICAgfVxuXG4gICAgcGFpcnMuaXRlbXMucHVzaChjcmVhdGVQYWlyKGtleSwgdmFsdWUsIGN0eCkpO1xuICB9XG5cbiAgcmV0dXJuIHBhaXJzO1xufVxuY29uc3QgcGFpcnMgPSB7XG4gIGRlZmF1bHQ6IGZhbHNlLFxuICB0YWc6ICd0YWc6eWFtbC5vcmcsMjAwMjpwYWlycycsXG4gIHJlc29sdmU6IHBhcnNlUGFpcnMsXG4gIGNyZWF0ZU5vZGU6IGNyZWF0ZVBhaXJzXG59O1xuXG5leHBvcnQgeyBjcmVhdGVQYWlycywgcGFpcnMsIHBhcnNlUGFpcnMgfTtcbiIsImltcG9ydCB7IGRlZmluZVByb3BlcnR5IGFzIF9kZWZpbmVQcm9wZXJ0eSB9IGZyb20gJy4uLy4uL192aXJ0dWFsL19yb2xsdXBQbHVnaW5CYWJlbEhlbHBlcnMuanMnO1xuaW1wb3J0IHsgUGFpciB9IGZyb20gJy4uLy4uL2FzdC9QYWlyLmpzJztcbmltcG9ydCB7IFNjYWxhciB9IGZyb20gJy4uLy4uL2FzdC9TY2FsYXIuanMnO1xuaW1wb3J0IHsgWUFNTE1hcCB9IGZyb20gJy4uLy4uL2FzdC9ZQU1MTWFwLmpzJztcbmltcG9ydCB7IFlBTUxTZXEgfSBmcm9tICcuLi8uLi9hc3QvWUFNTFNlcS5qcyc7XG5pbXBvcnQgeyB0b0pTIH0gZnJvbSAnLi4vLi4vYXN0L3RvSlMuanMnO1xuaW1wb3J0IHsgcGFyc2VQYWlycywgY3JlYXRlUGFpcnMgfSBmcm9tICcuL3BhaXJzLmpzJztcblxuY2xhc3MgWUFNTE9NYXAgZXh0ZW5kcyBZQU1MU2VxIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIF9kZWZpbmVQcm9wZXJ0eSh0aGlzLCBcImFkZFwiLCBZQU1MTWFwLnByb3RvdHlwZS5hZGQuYmluZCh0aGlzKSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkodGhpcywgXCJkZWxldGVcIiwgWUFNTE1hcC5wcm90b3R5cGUuZGVsZXRlLmJpbmQodGhpcykpO1xuXG4gICAgX2RlZmluZVByb3BlcnR5KHRoaXMsIFwiZ2V0XCIsIFlBTUxNYXAucHJvdG90eXBlLmdldC5iaW5kKHRoaXMpKTtcblxuICAgIF9kZWZpbmVQcm9wZXJ0eSh0aGlzLCBcImhhc1wiLCBZQU1MTWFwLnByb3RvdHlwZS5oYXMuYmluZCh0aGlzKSk7XG5cbiAgICBfZGVmaW5lUHJvcGVydHkodGhpcywgXCJzZXRcIiwgWUFNTE1hcC5wcm90b3R5cGUuc2V0LmJpbmQodGhpcykpO1xuXG4gICAgdGhpcy50YWcgPSBZQU1MT01hcC50YWc7XG4gIH1cblxuICB0b0pTT04oXywgY3R4KSB7XG4gICAgY29uc3QgbWFwID0gbmV3IE1hcCgpO1xuICAgIGlmIChjdHggJiYgY3R4Lm9uQ3JlYXRlKSBjdHgub25DcmVhdGUobWFwKTtcblxuICAgIGZvciAoY29uc3QgcGFpciBvZiB0aGlzLml0ZW1zKSB7XG4gICAgICBsZXQga2V5LCB2YWx1ZTtcblxuICAgICAgaWYgKHBhaXIgaW5zdGFuY2VvZiBQYWlyKSB7XG4gICAgICAgIGtleSA9IHRvSlMocGFpci5rZXksICcnLCBjdHgpO1xuICAgICAgICB2YWx1ZSA9IHRvSlMocGFpci52YWx1ZSwga2V5LCBjdHgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAga2V5ID0gdG9KUyhwYWlyLCAnJywgY3R4KTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1hcC5oYXMoa2V5KSkgdGhyb3cgbmV3IEVycm9yKCdPcmRlcmVkIG1hcHMgbXVzdCBub3QgaW5jbHVkZSBkdXBsaWNhdGUga2V5cycpO1xuICAgICAgbWFwLnNldChrZXksIHZhbHVlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbWFwO1xuICB9XG5cbn1cblxuX2RlZmluZVByb3BlcnR5KFlBTUxPTWFwLCBcInRhZ1wiLCAndGFnOnlhbWwub3JnLDIwMDI6b21hcCcpO1xuXG5mdW5jdGlvbiBwYXJzZU9NYXAoc2VxLCBvbkVycm9yKSB7XG4gIGNvbnN0IHBhaXJzID0gcGFyc2VQYWlycyhzZXEsIG9uRXJyb3IpO1xuICBjb25zdCBzZWVuS2V5cyA9IFtdO1xuXG4gIGZvciAoY29uc3Qge1xuICAgIGtleVxuICB9IG9mIHBhaXJzLml0ZW1zKSB7XG4gICAgaWYgKGtleSBpbnN0YW5jZW9mIFNjYWxhcikge1xuICAgICAgaWYgKHNlZW5LZXlzLmluY2x1ZGVzKGtleS52YWx1ZSkpIHtcbiAgICAgICAgb25FcnJvcihcIk9yZGVyZWQgbWFwcyBtdXN0IG5vdCBpbmNsdWRlIGR1cGxpY2F0ZSBrZXlzOiBcIi5jb25jYXQoa2V5LnZhbHVlKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZWVuS2V5cy5wdXNoKGtleS52YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIE9iamVjdC5hc3NpZ24obmV3IFlBTUxPTWFwKCksIHBhaXJzKTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlT01hcChzY2hlbWEsIGl0ZXJhYmxlLCBjdHgpIHtcbiAgY29uc3QgcGFpcnMgPSBjcmVhdGVQYWlycyhzY2hlbWEsIGl0ZXJhYmxlLCBjdHgpO1xuICBjb25zdCBvbWFwID0gbmV3IFlBTUxPTWFwKCk7XG4gIG9tYXAuaXRlbXMgPSBwYWlycy5pdGVtcztcbiAgcmV0dXJuIG9tYXA7XG59XG5cbmNvbnN0IG9tYXAgPSB7XG4gIGlkZW50aWZ5OiB2YWx1ZSA9PiB2YWx1ZSBpbnN0YW5jZW9mIE1hcCxcbiAgbm9kZUNsYXNzOiBZQU1MT01hcCxcbiAgZGVmYXVsdDogZmFsc2UsXG4gIHRhZzogJ3RhZzp5YW1sLm9yZywyMDAyOm9tYXAnLFxuICByZXNvbHZlOiBwYXJzZU9NYXAsXG4gIGNyZWF0ZU5vZGU6IGNyZWF0ZU9NYXBcbn07XG5cbmV4cG9ydCB7IFlBTUxPTWFwLCBvbWFwIH07XG4iLCJpbXBvcnQgeyBkZWZpbmVQcm9wZXJ0eSBhcyBfZGVmaW5lUHJvcGVydHkgfSBmcm9tICcuLi8uLi9fdmlydHVhbC9fcm9sbHVwUGx1Z2luQmFiZWxIZWxwZXJzLmpzJztcbmltcG9ydCB7IFBhaXIsIGNyZWF0ZVBhaXIgfSBmcm9tICcuLi8uLi9hc3QvUGFpci5qcyc7XG5pbXBvcnQgeyBTY2FsYXIgfSBmcm9tICcuLi8uLi9hc3QvU2NhbGFyLmpzJztcbmltcG9ydCB7IFlBTUxNYXAsIGZpbmRQYWlyIH0gZnJvbSAnLi4vLi4vYXN0L1lBTUxNYXAuanMnO1xuXG5jbGFzcyBZQU1MU2V0IGV4dGVuZHMgWUFNTE1hcCB7XG4gIGNvbnN0cnVjdG9yKHNjaGVtYSkge1xuICAgIHN1cGVyKHNjaGVtYSk7XG4gICAgdGhpcy50YWcgPSBZQU1MU2V0LnRhZztcbiAgfVxuXG4gIGFkZChrZXkpIHtcbiAgICBjb25zdCBwYWlyID0ga2V5IGluc3RhbmNlb2YgUGFpciA/IGtleSA6IG5ldyBQYWlyKGtleSk7XG4gICAgY29uc3QgcHJldiA9IGZpbmRQYWlyKHRoaXMuaXRlbXMsIHBhaXIua2V5KTtcbiAgICBpZiAoIXByZXYpIHRoaXMuaXRlbXMucHVzaChwYWlyKTtcbiAgfVxuXG4gIGdldChrZXksIGtlZXBQYWlyKSB7XG4gICAgY29uc3QgcGFpciA9IGZpbmRQYWlyKHRoaXMuaXRlbXMsIGtleSk7XG4gICAgcmV0dXJuICFrZWVwUGFpciAmJiBwYWlyIGluc3RhbmNlb2YgUGFpciA/IHBhaXIua2V5IGluc3RhbmNlb2YgU2NhbGFyID8gcGFpci5rZXkudmFsdWUgOiBwYWlyLmtleSA6IHBhaXI7XG4gIH1cblxuICBzZXQoa2V5LCB2YWx1ZSkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdib29sZWFuJykgdGhyb3cgbmV3IEVycm9yKFwiRXhwZWN0ZWQgYm9vbGVhbiB2YWx1ZSBmb3Igc2V0KGtleSwgdmFsdWUpIGluIGEgWUFNTCBzZXQsIG5vdCBcIi5jb25jYXQodHlwZW9mIHZhbHVlKSk7XG4gICAgY29uc3QgcHJldiA9IGZpbmRQYWlyKHRoaXMuaXRlbXMsIGtleSk7XG5cbiAgICBpZiAocHJldiAmJiAhdmFsdWUpIHtcbiAgICAgIHRoaXMuaXRlbXMuc3BsaWNlKHRoaXMuaXRlbXMuaW5kZXhPZihwcmV2KSwgMSk7XG4gICAgfSBlbHNlIGlmICghcHJldiAmJiB2YWx1ZSkge1xuICAgICAgdGhpcy5pdGVtcy5wdXNoKG5ldyBQYWlyKGtleSkpO1xuICAgIH1cbiAgfVxuXG4gIHRvSlNPTihfLCBjdHgpIHtcbiAgICByZXR1cm4gc3VwZXIudG9KU09OKF8sIGN0eCwgU2V0KTtcbiAgfVxuXG4gIHRvU3RyaW5nKGN0eCwgb25Db21tZW50LCBvbkNob21wS2VlcCkge1xuICAgIGlmICghY3R4KSByZXR1cm4gSlNPTi5zdHJpbmdpZnkodGhpcyk7XG4gICAgaWYgKHRoaXMuaGFzQWxsTnVsbFZhbHVlcygpKSByZXR1cm4gc3VwZXIudG9TdHJpbmcoY3R4LCBvbkNvbW1lbnQsIG9uQ2hvbXBLZWVwKTtlbHNlIHRocm93IG5ldyBFcnJvcignU2V0IGl0ZW1zIG11c3QgYWxsIGhhdmUgbnVsbCB2YWx1ZXMnKTtcbiAgfVxuXG59XG5cbl9kZWZpbmVQcm9wZXJ0eShZQU1MU2V0LCBcInRhZ1wiLCAndGFnOnlhbWwub3JnLDIwMDI6c2V0Jyk7XG5cbmZ1bmN0aW9uIHBhcnNlU2V0KG1hcCwgb25FcnJvcikge1xuICBpZiAobWFwIGluc3RhbmNlb2YgWUFNTE1hcCkge1xuICAgIGlmIChtYXAuaGFzQWxsTnVsbFZhbHVlcygpKSByZXR1cm4gT2JqZWN0LmFzc2lnbihuZXcgWUFNTFNldCgpLCBtYXApO2Vsc2Ugb25FcnJvcignU2V0IGl0ZW1zIG11c3QgYWxsIGhhdmUgbnVsbCB2YWx1ZXMnKTtcbiAgfSBlbHNlIG9uRXJyb3IoJ0V4cGVjdGVkIGEgbWFwcGluZyBmb3IgdGhpcyB0YWcnKTtcblxuICByZXR1cm4gbWFwO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVTZXQoc2NoZW1hLCBpdGVyYWJsZSwgY3R4KSB7XG4gIGNvbnN0IHtcbiAgICByZXBsYWNlclxuICB9ID0gY3R4O1xuICBjb25zdCBzZXQgPSBuZXcgWUFNTFNldChzY2hlbWEpO1xuXG4gIGZvciAobGV0IHZhbHVlIG9mIGl0ZXJhYmxlKSB7XG4gICAgaWYgKHR5cGVvZiByZXBsYWNlciA9PT0gJ2Z1bmN0aW9uJykgdmFsdWUgPSByZXBsYWNlci5jYWxsKGl0ZXJhYmxlLCB2YWx1ZSwgdmFsdWUpO1xuICAgIHNldC5pdGVtcy5wdXNoKGNyZWF0ZVBhaXIodmFsdWUsIG51bGwsIGN0eCkpO1xuICB9XG5cbiAgcmV0dXJuIHNldDtcbn1cblxuY29uc3Qgc2V0ID0ge1xuICBpZGVudGlmeTogdmFsdWUgPT4gdmFsdWUgaW5zdGFuY2VvZiBTZXQsXG4gIG5vZGVDbGFzczogWUFNTFNldCxcbiAgZGVmYXVsdDogZmFsc2UsXG4gIHRhZzogJ3RhZzp5YW1sLm9yZywyMDAyOnNldCcsXG4gIHJlc29sdmU6IHBhcnNlU2V0LFxuICBjcmVhdGVOb2RlOiBjcmVhdGVTZXRcbn07XG5cbmV4cG9ydCB7IFlBTUxTZXQsIHNldCB9O1xuIiwiaW1wb3J0IHsgaW50T3B0aW9ucyB9IGZyb20gJy4uL29wdGlvbnMuanMnO1xuaW1wb3J0IHsgc3RyaW5naWZ5TnVtYmVyIH0gZnJvbSAnLi4vLi4vc3RyaW5naWZ5L3N0cmluZ2lmeU51bWJlci5qcyc7XG5cbi8qIGdsb2JhbCBCaWdJbnQgKi9cblxuY29uc3QgcGFyc2VTZXhhZ2VzaW1hbCA9IChzdHIsIGlzSW50KSA9PiB7XG4gIGNvbnN0IHNpZ24gPSBzdHJbMF07XG4gIGNvbnN0IHBhcnRzID0gc2lnbiA9PT0gJy0nIHx8IHNpZ24gPT09ICcrJyA/IHN0ci5zdWJzdHJpbmcoMSkgOiBzdHI7XG5cbiAgY29uc3QgbnVtID0gbiA9PiBpc0ludCAmJiBpbnRPcHRpb25zLmFzQmlnSW50ID8gQmlnSW50KG4pIDogTnVtYmVyKG4pO1xuXG4gIGNvbnN0IHJlcyA9IHBhcnRzLnJlcGxhY2UoL18vZywgJycpLnNwbGl0KCc6JykucmVkdWNlKChyZXMsIHApID0+IHJlcyAqIG51bSg2MCkgKyBudW0ocCksIG51bSgwKSk7XG4gIHJldHVybiBzaWduID09PSAnLScgPyBudW0oLTEpICogcmVzIDogcmVzO1xufTsgLy8gaGhoaDptbTpzcy5zc3NcblxuXG5jb25zdCBzdHJpbmdpZnlTZXhhZ2VzaW1hbCA9ICh7XG4gIHZhbHVlXG59KSA9PiB7XG4gIGxldCBudW0gPSBuID0+IG47XG5cbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2JpZ2ludCcpIG51bSA9IG4gPT4gQmlnSW50KG4pO2Vsc2UgaWYgKGlzTmFOKHZhbHVlKSB8fCAhaXNGaW5pdGUodmFsdWUpKSByZXR1cm4gc3RyaW5naWZ5TnVtYmVyKHZhbHVlKTtcbiAgbGV0IHNpZ24gPSAnJztcblxuICBpZiAodmFsdWUgPCAwKSB7XG4gICAgc2lnbiA9ICctJztcbiAgICB2YWx1ZSAqPSBudW0oLTEpO1xuICB9XG5cbiAgY29uc3QgXzYwID0gbnVtKDYwKTtcblxuICBjb25zdCBwYXJ0cyA9IFt2YWx1ZSAlIF82MF07IC8vIHNlY29uZHMsIGluY2x1ZGluZyBtc1xuXG4gIGlmICh2YWx1ZSA8IDYwKSB7XG4gICAgcGFydHMudW5zaGlmdCgwKTsgLy8gYXQgbGVhc3Qgb25lIDogaXMgcmVxdWlyZWRcbiAgfSBlbHNlIHtcbiAgICB2YWx1ZSA9ICh2YWx1ZSAtIHBhcnRzWzBdKSAvIF82MDtcbiAgICBwYXJ0cy51bnNoaWZ0KHZhbHVlICUgXzYwKTsgLy8gbWludXRlc1xuXG4gICAgaWYgKHZhbHVlID49IDYwKSB7XG4gICAgICB2YWx1ZSA9ICh2YWx1ZSAtIHBhcnRzWzBdKSAvIF82MDtcbiAgICAgIHBhcnRzLnVuc2hpZnQodmFsdWUpOyAvLyBob3Vyc1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBzaWduICsgcGFydHMubWFwKG4gPT4gbiA8IDEwID8gJzAnICsgU3RyaW5nKG4pIDogU3RyaW5nKG4pKS5qb2luKCc6JykucmVwbGFjZSgvMDAwMDAwXFxkKiQvLCAnJykgLy8gJSA2MCBtYXkgaW50cm9kdWNlIGVycm9yXG4gIDtcbn07XG5cbmNvbnN0IGludFRpbWUgPSB7XG4gIGlkZW50aWZ5OiB2YWx1ZSA9PiB0eXBlb2YgdmFsdWUgPT09ICdiaWdpbnQnIHx8IE51bWJlci5pc0ludGVnZXIodmFsdWUpLFxuICBkZWZhdWx0OiB0cnVlLFxuICB0YWc6ICd0YWc6eWFtbC5vcmcsMjAwMjppbnQnLFxuICBmb3JtYXQ6ICdUSU1FJyxcbiAgdGVzdDogL15bLStdP1swLTldWzAtOV9dKig/OjpbMC01XT9bMC05XSkrJC8sXG4gIHJlc29sdmU6IHN0ciA9PiBwYXJzZVNleGFnZXNpbWFsKHN0ciwgdHJ1ZSksXG4gIHN0cmluZ2lmeTogc3RyaW5naWZ5U2V4YWdlc2ltYWxcbn07XG5jb25zdCBmbG9hdFRpbWUgPSB7XG4gIGlkZW50aWZ5OiB2YWx1ZSA9PiB0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInLFxuICBkZWZhdWx0OiB0cnVlLFxuICB0YWc6ICd0YWc6eWFtbC5vcmcsMjAwMjpmbG9hdCcsXG4gIGZvcm1hdDogJ1RJTUUnLFxuICB0ZXN0OiAvXlstK10/WzAtOV1bMC05X10qKD86OlswLTVdP1swLTldKStcXC5bMC05X10qJC8sXG4gIHJlc29sdmU6IHN0ciA9PiBwYXJzZVNleGFnZXNpbWFsKHN0ciwgZmFsc2UpLFxuICBzdHJpbmdpZnk6IHN0cmluZ2lmeVNleGFnZXNpbWFsXG59O1xuY29uc3QgdGltZXN0YW1wID0ge1xuICBpZGVudGlmeTogdmFsdWUgPT4gdmFsdWUgaW5zdGFuY2VvZiBEYXRlLFxuICBkZWZhdWx0OiB0cnVlLFxuICB0YWc6ICd0YWc6eWFtbC5vcmcsMjAwMjp0aW1lc3RhbXAnLFxuICAvLyBJZiB0aGUgdGltZSB6b25lIGlzIG9taXR0ZWQsIHRoZSB0aW1lc3RhbXAgaXMgYXNzdW1lZCB0byBiZSBzcGVjaWZpZWQgaW4gVVRDLiBUaGUgdGltZSBwYXJ0XG4gIC8vIG1heSBiZSBvbWl0dGVkIGFsdG9nZXRoZXIsIHJlc3VsdGluZyBpbiBhIGRhdGUgZm9ybWF0LiBJbiBzdWNoIGEgY2FzZSwgdGhlIHRpbWUgcGFydCBpc1xuICAvLyBhc3N1bWVkIHRvIGJlIDAwOjAwOjAwWiAoc3RhcnQgb2YgZGF5LCBVVEMpLlxuICB0ZXN0OiBSZWdFeHAoJ14oWzAtOV17NH0pLShbMC05XXsxLDJ9KS0oWzAtOV17MSwyfSknICsgLy8gWVlZWS1NbS1EZFxuICAnKD86JyArIC8vIHRpbWUgaXMgb3B0aW9uYWxcbiAgJyg/OnR8VHxbIFxcXFx0XSspJyArIC8vIHQgfCBUIHwgd2hpdGVzcGFjZVxuICAnKFswLTldezEsMn0pOihbMC05XXsxLDJ9KTooWzAtOV17MSwyfShcXFxcLlswLTldKyk/KScgKyAvLyBIaDpNbTpTcyguc3MpP1xuICAnKD86WyBcXFxcdF0qKFp8Wy0rXVswMTJdP1swLTldKD86OlswLTldezJ9KT8pKT8nICsgLy8gWiB8ICs1IHwgLTAzOjMwXG4gICcpPyQnKSxcblxuICByZXNvbHZlKHN0cikge1xuICAgIGxldCBbLCB5ZWFyLCBtb250aCwgZGF5LCBob3VyLCBtaW51dGUsIHNlY29uZCwgbWlsbGlzZWMsIHR6XSA9IHN0ci5tYXRjaCh0aW1lc3RhbXAudGVzdCk7XG4gICAgaWYgKG1pbGxpc2VjKSBtaWxsaXNlYyA9IChtaWxsaXNlYyArICcwMCcpLnN1YnN0cigxLCAzKTtcbiAgICBsZXQgZGF0ZSA9IERhdGUuVVRDKHllYXIsIG1vbnRoIC0gMSwgZGF5LCBob3VyIHx8IDAsIG1pbnV0ZSB8fCAwLCBzZWNvbmQgfHwgMCwgbWlsbGlzZWMgfHwgMCk7XG5cbiAgICBpZiAodHogJiYgdHogIT09ICdaJykge1xuICAgICAgbGV0IGQgPSBwYXJzZVNleGFnZXNpbWFsKHR6LCBmYWxzZSk7XG4gICAgICBpZiAoTWF0aC5hYnMoZCkgPCAzMCkgZCAqPSA2MDtcbiAgICAgIGRhdGUgLT0gNjAwMDAgKiBkO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgRGF0ZShkYXRlKTtcbiAgfSxcblxuICBzdHJpbmdpZnk6ICh7XG4gICAgdmFsdWVcbiAgfSkgPT4gdmFsdWUudG9JU09TdHJpbmcoKS5yZXBsYWNlKC8oKFQwMDowMCk/OjAwKT9cXC4wMDBaJC8sICcnKVxufTtcblxuZXhwb3J0IHsgZmxvYXRUaW1lLCBpbnRUaW1lLCB0aW1lc3RhbXAgfTtcbiIsImltcG9ydCB7IFNjYWxhciB9IGZyb20gJy4uLy4uL2FzdC9TY2FsYXIuanMnO1xuaW1wb3J0IHsgc3RyaW5naWZ5TnVtYmVyIH0gZnJvbSAnLi4vLi4vc3RyaW5naWZ5L3N0cmluZ2lmeU51bWJlci5qcyc7XG5pbXBvcnQgeyBmYWlsc2FmZSB9IGZyb20gJy4uL2ZhaWxzYWZlL2luZGV4LmpzJztcbmltcG9ydCB7IG51bGxPcHRpb25zLCBib29sT3B0aW9ucywgaW50T3B0aW9ucyB9IGZyb20gJy4uL29wdGlvbnMuanMnO1xuaW1wb3J0IHsgYmluYXJ5IH0gZnJvbSAnLi9iaW5hcnkuanMnO1xuaW1wb3J0IHsgb21hcCB9IGZyb20gJy4vb21hcC5qcyc7XG5pbXBvcnQgeyBwYWlycyB9IGZyb20gJy4vcGFpcnMuanMnO1xuaW1wb3J0IHsgc2V0IH0gZnJvbSAnLi9zZXQuanMnO1xuaW1wb3J0IHsgaW50VGltZSwgZmxvYXRUaW1lLCB0aW1lc3RhbXAgfSBmcm9tICcuL3RpbWVzdGFtcC5qcyc7XG5cbi8qIGdsb2JhbCBCaWdJbnQgKi9cblxuY29uc3QgYm9vbFN0cmluZ2lmeSA9ICh7XG4gIHZhbHVlLFxuICBzb3VyY2VTdHJcbn0pID0+IHtcbiAgY29uc3QgYm9vbE9iaiA9IHZhbHVlID8gdHJ1ZU9iaiA6IGZhbHNlT2JqO1xuICBpZiAoc291cmNlU3RyICYmIGJvb2xPYmoudGVzdC50ZXN0KHNvdXJjZVN0cikpIHJldHVybiBzb3VyY2VTdHI7XG4gIHJldHVybiB2YWx1ZSA/IGJvb2xPcHRpb25zLnRydWVTdHIgOiBib29sT3B0aW9ucy5mYWxzZVN0cjtcbn07XG5cbmNvbnN0IGJvb2xSZXNvbHZlID0gKHZhbHVlLCBzdHIpID0+IHtcbiAgY29uc3Qgbm9kZSA9IG5ldyBTY2FsYXIodmFsdWUpO1xuICBub2RlLnNvdXJjZVN0ciA9IHN0cjtcbiAgcmV0dXJuIG5vZGU7XG59O1xuXG5jb25zdCB0cnVlT2JqID0ge1xuICBpZGVudGlmeTogdmFsdWUgPT4gdmFsdWUgPT09IHRydWUsXG4gIGRlZmF1bHQ6IHRydWUsXG4gIHRhZzogJ3RhZzp5YW1sLm9yZywyMDAyOmJvb2wnLFxuICB0ZXN0OiAvXig/Oll8eXxbWXldZXN8WUVTfFtUdF1ydWV8VFJVRXxbT29dbnxPTikkLyxcbiAgcmVzb2x2ZTogc3RyID0+IGJvb2xSZXNvbHZlKHRydWUsIHN0ciksXG4gIG9wdGlvbnM6IGJvb2xPcHRpb25zLFxuICBzdHJpbmdpZnk6IGJvb2xTdHJpbmdpZnlcbn07XG5jb25zdCBmYWxzZU9iaiA9IHtcbiAgaWRlbnRpZnk6IHZhbHVlID0+IHZhbHVlID09PSBmYWxzZSxcbiAgZGVmYXVsdDogdHJ1ZSxcbiAgdGFnOiAndGFnOnlhbWwub3JnLDIwMDI6Ym9vbCcsXG4gIHRlc3Q6IC9eKD86TnxufFtObl1vfE5PfFtGZl1hbHNlfEZBTFNFfFtPb11mZnxPRkYpJC9pLFxuICByZXNvbHZlOiBzdHIgPT4gYm9vbFJlc29sdmUoZmFsc2UsIHN0ciksXG4gIG9wdGlvbnM6IGJvb2xPcHRpb25zLFxuICBzdHJpbmdpZnk6IGJvb2xTdHJpbmdpZnlcbn07XG5cbmNvbnN0IGludElkZW50aWZ5ID0gdmFsdWUgPT4gdHlwZW9mIHZhbHVlID09PSAnYmlnaW50JyB8fCBOdW1iZXIuaXNJbnRlZ2VyKHZhbHVlKTtcblxuZnVuY3Rpb24gaW50UmVzb2x2ZShzdHIsIG9mZnNldCwgcmFkaXgpIHtcbiAgY29uc3Qgc2lnbiA9IHN0clswXTtcbiAgaWYgKHNpZ24gPT09ICctJyB8fCBzaWduID09PSAnKycpIG9mZnNldCArPSAxO1xuICBzdHIgPSBzdHIuc3Vic3RyaW5nKG9mZnNldCkucmVwbGFjZSgvXy9nLCAnJyk7XG5cbiAgaWYgKGludE9wdGlvbnMuYXNCaWdJbnQpIHtcbiAgICBzd2l0Y2ggKHJhZGl4KSB7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIHN0ciA9IFwiMGJcIi5jb25jYXQoc3RyKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgODpcbiAgICAgICAgc3RyID0gXCIwb1wiLmNvbmNhdChzdHIpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAxNjpcbiAgICAgICAgc3RyID0gXCIweFwiLmNvbmNhdChzdHIpO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBjb25zdCBuID0gQmlnSW50KHN0cik7XG4gICAgcmV0dXJuIHNpZ24gPT09ICctJyA/IEJpZ0ludCgtMSkgKiBuIDogbjtcbiAgfVxuXG4gIGNvbnN0IG4gPSBwYXJzZUludChzdHIsIHJhZGl4KTtcbiAgcmV0dXJuIHNpZ24gPT09ICctJyA/IC0xICogbiA6IG47XG59XG5cbmZ1bmN0aW9uIGludFN0cmluZ2lmeShub2RlLCByYWRpeCwgcHJlZml4KSB7XG4gIGNvbnN0IHtcbiAgICB2YWx1ZVxuICB9ID0gbm9kZTtcblxuICBpZiAoaW50SWRlbnRpZnkodmFsdWUpKSB7XG4gICAgY29uc3Qgc3RyID0gdmFsdWUudG9TdHJpbmcocmFkaXgpO1xuICAgIHJldHVybiB2YWx1ZSA8IDAgPyAnLScgKyBwcmVmaXggKyBzdHIuc3Vic3RyKDEpIDogcHJlZml4ICsgc3RyO1xuICB9XG5cbiAgcmV0dXJuIHN0cmluZ2lmeU51bWJlcihub2RlKTtcbn1cblxuY29uc3QgeWFtbDExID0gZmFpbHNhZmUuY29uY2F0KFt7XG4gIGlkZW50aWZ5OiB2YWx1ZSA9PiB2YWx1ZSA9PSBudWxsLFxuICBjcmVhdGVOb2RlOiAoc2NoZW1hLCB2YWx1ZSwgY3R4KSA9PiBjdHgud3JhcFNjYWxhcnMgPyBuZXcgU2NhbGFyKG51bGwpIDogbnVsbCxcbiAgZGVmYXVsdDogdHJ1ZSxcbiAgdGFnOiAndGFnOnlhbWwub3JnLDIwMDI6bnVsbCcsXG4gIHRlc3Q6IC9eKD86fnxbTm5ddWxsfE5VTEwpPyQvLFxuICByZXNvbHZlOiBzdHIgPT4ge1xuICAgIGNvbnN0IG5vZGUgPSBuZXcgU2NhbGFyKG51bGwpO1xuICAgIG5vZGUuc291cmNlU3RyID0gc3RyO1xuICAgIHJldHVybiBub2RlO1xuICB9LFxuICBvcHRpb25zOiBudWxsT3B0aW9ucyxcbiAgc3RyaW5naWZ5OiAoe1xuICAgIHNvdXJjZVN0clxuICB9KSA9PiBzb3VyY2VTdHIgIT09IG51bGwgJiYgc291cmNlU3RyICE9PSB2b2lkIDAgPyBzb3VyY2VTdHIgOiBudWxsT3B0aW9ucy5udWxsU3RyXG59LCB0cnVlT2JqLCBmYWxzZU9iaiwge1xuICBpZGVudGlmeTogaW50SWRlbnRpZnksXG4gIGRlZmF1bHQ6IHRydWUsXG4gIHRhZzogJ3RhZzp5YW1sLm9yZywyMDAyOmludCcsXG4gIGZvcm1hdDogJ0JJTicsXG4gIHRlc3Q6IC9eWy0rXT8wYlswLTFfXSskLyxcbiAgcmVzb2x2ZTogc3RyID0+IGludFJlc29sdmUoc3RyLCAyLCAyKSxcbiAgc3RyaW5naWZ5OiBub2RlID0+IGludFN0cmluZ2lmeShub2RlLCAyLCAnMGInKVxufSwge1xuICBpZGVudGlmeTogaW50SWRlbnRpZnksXG4gIGRlZmF1bHQ6IHRydWUsXG4gIHRhZzogJ3RhZzp5YW1sLm9yZywyMDAyOmludCcsXG4gIGZvcm1hdDogJ09DVCcsXG4gIHRlc3Q6IC9eWy0rXT8wWzAtN19dKyQvLFxuICByZXNvbHZlOiBzdHIgPT4gaW50UmVzb2x2ZShzdHIsIDEsIDgpLFxuICBzdHJpbmdpZnk6IG5vZGUgPT4gaW50U3RyaW5naWZ5KG5vZGUsIDgsICcwJylcbn0sIHtcbiAgaWRlbnRpZnk6IGludElkZW50aWZ5LFxuICBkZWZhdWx0OiB0cnVlLFxuICB0YWc6ICd0YWc6eWFtbC5vcmcsMjAwMjppbnQnLFxuICB0ZXN0OiAvXlstK10/WzAtOV1bMC05X10qJC8sXG4gIHJlc29sdmU6IHN0ciA9PiBpbnRSZXNvbHZlKHN0ciwgMCwgMTApLFxuICBzdHJpbmdpZnk6IHN0cmluZ2lmeU51bWJlclxufSwge1xuICBpZGVudGlmeTogaW50SWRlbnRpZnksXG4gIGRlZmF1bHQ6IHRydWUsXG4gIHRhZzogJ3RhZzp5YW1sLm9yZywyMDAyOmludCcsXG4gIGZvcm1hdDogJ0hFWCcsXG4gIHRlc3Q6IC9eWy0rXT8weFswLTlhLWZBLUZfXSskLyxcbiAgcmVzb2x2ZTogc3RyID0+IGludFJlc29sdmUoc3RyLCAyLCAxNiksXG4gIHN0cmluZ2lmeTogbm9kZSA9PiBpbnRTdHJpbmdpZnkobm9kZSwgMTYsICcweCcpXG59LCB7XG4gIGlkZW50aWZ5OiB2YWx1ZSA9PiB0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInLFxuICBkZWZhdWx0OiB0cnVlLFxuICB0YWc6ICd0YWc6eWFtbC5vcmcsMjAwMjpmbG9hdCcsXG4gIHRlc3Q6IC9eWy0rXT9cXC4oPzppbmZ8SW5mfElORnxuYW58TmFOfE5BTikkLyxcbiAgcmVzb2x2ZTogc3RyID0+IHN0ci5zbGljZSgtMykudG9Mb3dlckNhc2UoKSA9PT0gJ25hbicgPyBOYU4gOiBzdHJbMF0gPT09ICctJyA/IE51bWJlci5ORUdBVElWRV9JTkZJTklUWSA6IE51bWJlci5QT1NJVElWRV9JTkZJTklUWSxcbiAgc3RyaW5naWZ5OiBzdHJpbmdpZnlOdW1iZXJcbn0sIHtcbiAgaWRlbnRpZnk6IHZhbHVlID0+IHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicsXG4gIGRlZmF1bHQ6IHRydWUsXG4gIHRhZzogJ3RhZzp5YW1sLm9yZywyMDAyOmZsb2F0JyxcbiAgZm9ybWF0OiAnRVhQJyxcbiAgdGVzdDogL15bLStdPyg/OlswLTldWzAtOV9dKik/KD86XFwuWzAtOV9dKik/W2VFXVstK10/WzAtOV0rJC8sXG4gIHJlc29sdmU6IHN0ciA9PiBwYXJzZUZsb2F0KHN0ci5yZXBsYWNlKC9fL2csICcnKSksXG4gIHN0cmluZ2lmeTogKHtcbiAgICB2YWx1ZVxuICB9KSA9PiBOdW1iZXIodmFsdWUpLnRvRXhwb25lbnRpYWwoKVxufSwge1xuICBpZGVudGlmeTogdmFsdWUgPT4gdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyxcbiAgZGVmYXVsdDogdHJ1ZSxcbiAgdGFnOiAndGFnOnlhbWwub3JnLDIwMDI6ZmxvYXQnLFxuICB0ZXN0OiAvXlstK10/KD86WzAtOV1bMC05X10qKT9cXC5bMC05X10qJC8sXG5cbiAgcmVzb2x2ZShzdHIpIHtcbiAgICBjb25zdCBub2RlID0gbmV3IFNjYWxhcihwYXJzZUZsb2F0KHN0ci5yZXBsYWNlKC9fL2csICcnKSkpO1xuICAgIGNvbnN0IGRvdCA9IHN0ci5pbmRleE9mKCcuJyk7XG5cbiAgICBpZiAoZG90ICE9PSAtMSkge1xuICAgICAgY29uc3QgZiA9IHN0ci5zdWJzdHJpbmcoZG90ICsgMSkucmVwbGFjZSgvXy9nLCAnJyk7XG4gICAgICBpZiAoZltmLmxlbmd0aCAtIDFdID09PSAnMCcpIG5vZGUubWluRnJhY3Rpb25EaWdpdHMgPSBmLmxlbmd0aDtcbiAgICB9XG5cbiAgICByZXR1cm4gbm9kZTtcbiAgfSxcblxuICBzdHJpbmdpZnk6IHN0cmluZ2lmeU51bWJlclxufV0sIGJpbmFyeSwgb21hcCwgcGFpcnMsIHNldCwgaW50VGltZSwgZmxvYXRUaW1lLCB0aW1lc3RhbXApO1xuXG5leHBvcnQgeyB5YW1sMTEgfTtcbiIsImltcG9ydCB7IGJvb2xPYmosIGZsb2F0T2JqLCBleHBPYmosIG5hbk9iaiwgaW50T2JqLCBoZXhPYmosIG9jdE9iaiwgbnVsbE9iaiwgY29yZSB9IGZyb20gJy4vY29yZS5qcyc7XG5pbXBvcnQgeyBmYWlsc2FmZSB9IGZyb20gJy4vZmFpbHNhZmUvaW5kZXguanMnO1xuaW1wb3J0IHsganNvbiB9IGZyb20gJy4vanNvbi5qcyc7XG5pbXBvcnQgeyB5YW1sMTEgfSBmcm9tICcuL3lhbWwtMS4xL2luZGV4LmpzJztcbmltcG9ydCB7IG1hcCB9IGZyb20gJy4vZmFpbHNhZmUvbWFwLmpzJztcbmltcG9ydCB7IHNlcSB9IGZyb20gJy4vZmFpbHNhZmUvc2VxLmpzJztcbmltcG9ydCB7IGJpbmFyeSB9IGZyb20gJy4veWFtbC0xLjEvYmluYXJ5LmpzJztcbmltcG9ydCB7IG9tYXAgfSBmcm9tICcuL3lhbWwtMS4xL29tYXAuanMnO1xuaW1wb3J0IHsgcGFpcnMgfSBmcm9tICcuL3lhbWwtMS4xL3BhaXJzLmpzJztcbmltcG9ydCB7IHNldCB9IGZyb20gJy4veWFtbC0xLjEvc2V0LmpzJztcbmltcG9ydCB7IGZsb2F0VGltZSwgaW50VGltZSwgdGltZXN0YW1wIH0gZnJvbSAnLi95YW1sLTEuMS90aW1lc3RhbXAuanMnO1xuXG5jb25zdCBzY2hlbWFzID0ge1xuICBjb3JlLFxuICBmYWlsc2FmZSxcbiAganNvbixcbiAgeWFtbDExXG59O1xuY29uc3QgdGFncyA9IHtcbiAgYmluYXJ5LFxuICBib29sOiBib29sT2JqLFxuICBmbG9hdDogZmxvYXRPYmosXG4gIGZsb2F0RXhwOiBleHBPYmosXG4gIGZsb2F0TmFOOiBuYW5PYmosXG4gIGZsb2F0VGltZSxcbiAgaW50OiBpbnRPYmosXG4gIGludEhleDogaGV4T2JqLFxuICBpbnRPY3Q6IG9jdE9iaixcbiAgaW50VGltZSxcbiAgbWFwLFxuICBudWxsOiBudWxsT2JqLFxuICBvbWFwLFxuICBwYWlycyxcbiAgc2VxLFxuICBzZXQsXG4gIHRpbWVzdGFtcFxufTtcblxuZXhwb3J0IHsgc2NoZW1hcywgdGFncyB9O1xuIiwiZnVuY3Rpb24gZ2V0U2NoZW1hVGFncyhzY2hlbWFzLCBrbm93blRhZ3MsIGN1c3RvbVRhZ3MsIHNjaGVtYUlkKSB7XG4gIGxldCB0YWdzID0gc2NoZW1hc1tzY2hlbWFJZC5yZXBsYWNlKC9cXFcvZywgJycpXTsgLy8gJ3lhbWwtMS4xJyAtPiAneWFtbDExJ1xuXG4gIGlmICghdGFncykge1xuICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhzY2hlbWFzKS5tYXAoa2V5ID0+IEpTT04uc3RyaW5naWZ5KGtleSkpLmpvaW4oJywgJyk7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBzY2hlbWEgXFxcIlwiLmNvbmNhdChzY2hlbWFJZCwgXCJcXFwiOyB1c2Ugb25lIG9mIFwiKS5jb25jYXQoa2V5cykpO1xuICB9XG5cbiAgaWYgKEFycmF5LmlzQXJyYXkoY3VzdG9tVGFncykpIHtcbiAgICBmb3IgKGNvbnN0IHRhZyBvZiBjdXN0b21UYWdzKSB0YWdzID0gdGFncy5jb25jYXQodGFnKTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgY3VzdG9tVGFncyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHRhZ3MgPSBjdXN0b21UYWdzKHRhZ3Muc2xpY2UoKSk7XG4gIH1cblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHRhZ3MubGVuZ3RoOyArK2kpIHtcbiAgICBjb25zdCB0YWcgPSB0YWdzW2ldO1xuXG4gICAgaWYgKHR5cGVvZiB0YWcgPT09ICdzdHJpbmcnKSB7XG4gICAgICBjb25zdCB0YWdPYmogPSBrbm93blRhZ3NbdGFnXTtcblxuICAgICAgaWYgKCF0YWdPYmopIHtcbiAgICAgICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKGtub3duVGFncykubWFwKGtleSA9PiBKU09OLnN0cmluZ2lmeShrZXkpKS5qb2luKCcsICcpO1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIGN1c3RvbSB0YWcgXFxcIlwiLmNvbmNhdCh0YWcsIFwiXFxcIjsgdXNlIG9uZSBvZiBcIikuY29uY2F0KGtleXMpKTtcbiAgICAgIH1cblxuICAgICAgdGFnc1tpXSA9IHRhZ09iajtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGFncztcbn1cblxuZXhwb3J0IHsgZ2V0U2NoZW1hVGFncyB9O1xuIiwiaW1wb3J0IHsgdGFncywgc2NoZW1hcyB9IGZyb20gJy4uL3RhZ3MvaW5kZXguanMnO1xuaW1wb3J0IHsgZ2V0U2NoZW1hVGFncyB9IGZyb20gJy4vZ2V0U2NoZW1hVGFncy5qcyc7XG5cbmNvbnN0IHNvcnRNYXBFbnRyaWVzQnlLZXkgPSAoYSwgYikgPT4gYS5rZXkgPCBiLmtleSA/IC0xIDogYS5rZXkgPiBiLmtleSA/IDEgOiAwO1xuXG5jb25zdCBjb3JlS25vd25UYWdzID0ge1xuICAndGFnOnlhbWwub3JnLDIwMDI6YmluYXJ5JzogdGFncy5iaW5hcnksXG4gICd0YWc6eWFtbC5vcmcsMjAwMjpvbWFwJzogdGFncy5vbWFwLFxuICAndGFnOnlhbWwub3JnLDIwMDI6cGFpcnMnOiB0YWdzLnBhaXJzLFxuICAndGFnOnlhbWwub3JnLDIwMDI6c2V0JzogdGFncy5zZXQsXG4gICd0YWc6eWFtbC5vcmcsMjAwMjp0aW1lc3RhbXAnOiB0YWdzLnRpbWVzdGFtcFxufTtcbmNsYXNzIFNjaGVtYSB7XG4gIGNvbnN0cnVjdG9yKHtcbiAgICBjdXN0b21UYWdzLFxuICAgIG1lcmdlLFxuICAgIHJlc29sdmVLbm93blRhZ3MsXG4gICAgc2NoZW1hLFxuICAgIHNvcnRNYXBFbnRyaWVzXG4gIH0pIHtcbiAgICB0aGlzLm1lcmdlID0gISFtZXJnZTtcbiAgICB0aGlzLm5hbWUgPSBzY2hlbWE7XG4gICAgdGhpcy5rbm93blRhZ3MgPSByZXNvbHZlS25vd25UYWdzID8gY29yZUtub3duVGFncyA6IHt9O1xuICAgIHRoaXMudGFncyA9IGdldFNjaGVtYVRhZ3Moc2NoZW1hcywgdGFncywgY3VzdG9tVGFncywgc2NoZW1hKTsgLy8gVXNlZCBieSBjcmVhdGVOb2RlKCksIHRvIGF2b2lkIGNpcmN1bGFyIGRlcGVuZGVuY2llc1xuXG4gICAgdGhpcy5tYXAgPSB0YWdzLm1hcDtcbiAgICB0aGlzLnNlcSA9IHRhZ3Muc2VxOyAvLyBVc2VkIGJ5IGNyZWF0ZU1hcCgpXG5cbiAgICB0aGlzLnNvcnRNYXBFbnRyaWVzID0gc29ydE1hcEVudHJpZXMgPT09IHRydWUgPyBzb3J0TWFwRW50cmllc0J5S2V5IDogc29ydE1hcEVudHJpZXMgfHwgbnVsbDtcbiAgfVxuXG59XG5cbmV4cG9ydCB7IFNjaGVtYSB9O1xuIiwiLyoqXG4gKiBBcHBsaWVzIHRoZSBKU09OLnBhcnNlIHJldml2ZXIgYWxnb3JpdGhtIGFzIGRlZmluZWQgaW4gdGhlIEVDTUEtMjYyIHNwZWMsXG4gKiBpbiBzZWN0aW9uIDI0LjUuMS4xIFwiUnVudGltZSBTZW1hbnRpY3M6IEludGVybmFsaXplSlNPTlByb3BlcnR5XCIgb2YgdGhlXG4gKiAyMDIxIGVkaXRpb246IGh0dHBzOi8vdGMzOS5lcy9lY21hMjYyLyNzZWMtanNvbi5wYXJzZVxuICpcbiAqIEluY2x1ZGVzIGV4dGVuc2lvbnMgZm9yIGhhbmRsaW5nIE1hcCBhbmQgU2V0IG9iamVjdHMuXG4gKi9cbmZ1bmN0aW9uIGFwcGx5UmV2aXZlcihyZXZpdmVyLCBvYmosIGtleSwgdmFsKSB7XG4gIGlmICh2YWwgJiYgdHlwZW9mIHZhbCA9PT0gJ29iamVjdCcpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWwpKSB7XG4gICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gdmFsLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICAgIGNvbnN0IHYwID0gdmFsW2ldO1xuICAgICAgICBjb25zdCB2MSA9IGFwcGx5UmV2aXZlcihyZXZpdmVyLCB2YWwsIFN0cmluZyhpKSwgdjApO1xuICAgICAgICBpZiAodjEgPT09IHVuZGVmaW5lZCkgZGVsZXRlIHZhbFtpXTtlbHNlIGlmICh2MSAhPT0gdjApIHZhbFtpXSA9IHYxO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodmFsIGluc3RhbmNlb2YgTWFwKSB7XG4gICAgICBmb3IgKGNvbnN0IGsgb2YgQXJyYXkuZnJvbSh2YWwua2V5cygpKSkge1xuICAgICAgICBjb25zdCB2MCA9IHZhbC5nZXQoayk7XG4gICAgICAgIGNvbnN0IHYxID0gYXBwbHlSZXZpdmVyKHJldml2ZXIsIHZhbCwgaywgdjApO1xuICAgICAgICBpZiAodjEgPT09IHVuZGVmaW5lZCkgdmFsLmRlbGV0ZShrKTtlbHNlIGlmICh2MSAhPT0gdjApIHZhbC5zZXQoaywgdjEpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodmFsIGluc3RhbmNlb2YgU2V0KSB7XG4gICAgICBmb3IgKGNvbnN0IHYwIG9mIEFycmF5LmZyb20odmFsKSkge1xuICAgICAgICBjb25zdCB2MSA9IGFwcGx5UmV2aXZlcihyZXZpdmVyLCB2YWwsIHYwLCB2MCk7XG4gICAgICAgIGlmICh2MSA9PT0gdW5kZWZpbmVkKSB2YWwuZGVsZXRlKHYwKTtlbHNlIGlmICh2MSAhPT0gdjApIHtcbiAgICAgICAgICB2YWwuZGVsZXRlKHYwKTtcbiAgICAgICAgICB2YWwuYWRkKHYxKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKGNvbnN0IFtrLCB2MF0gb2YgT2JqZWN0LmVudHJpZXModmFsKSkge1xuICAgICAgICBjb25zdCB2MSA9IGFwcGx5UmV2aXZlcihyZXZpdmVyLCB2YWwsIGssIHYwKTtcbiAgICAgICAgaWYgKHYxID09PSB1bmRlZmluZWQpIGRlbGV0ZSB2YWxba107ZWxzZSBpZiAodjEgIT09IHYwKSB2YWxba10gPSB2MTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmV2aXZlci5jYWxsKG9iaiwga2V5LCB2YWwpO1xufVxuXG5leHBvcnQgeyBhcHBseVJldml2ZXIgfTtcbiIsImltcG9ydCB7IENvbGxlY3Rpb24gfSBmcm9tICcuLi9hc3QvQ29sbGVjdGlvbi5qcyc7XG5pbXBvcnQgeyBQYWlyIH0gZnJvbSAnLi4vYXN0L1BhaXIuanMnO1xuaW1wb3J0IHsgU2NhbGFyIH0gZnJvbSAnLi4vYXN0L1NjYWxhci5qcyc7XG5cbmNvbnN0IHZpc2l0ID0gKG5vZGUsIHRhZ3MpID0+IHtcbiAgaWYgKG5vZGUgJiYgdHlwZW9mIG5vZGUgPT09ICdvYmplY3QnKSB7XG4gICAgY29uc3Qge1xuICAgICAgdGFnXG4gICAgfSA9IG5vZGU7XG5cbiAgICBpZiAobm9kZSBpbnN0YW5jZW9mIENvbGxlY3Rpb24pIHtcbiAgICAgIGlmICh0YWcpIHRhZ3NbdGFnXSA9IHRydWU7XG4gICAgICBub2RlLml0ZW1zLmZvckVhY2gobiA9PiB2aXNpdChuLCB0YWdzKSk7XG4gICAgfSBlbHNlIGlmIChub2RlIGluc3RhbmNlb2YgUGFpcikge1xuICAgICAgdmlzaXQobm9kZS5rZXksIHRhZ3MpO1xuICAgICAgdmlzaXQobm9kZS52YWx1ZSwgdGFncyk7XG4gICAgfSBlbHNlIGlmIChub2RlIGluc3RhbmNlb2YgU2NhbGFyKSB7XG4gICAgICBpZiAodGFnKSB0YWdzW3RhZ10gPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0YWdzO1xufTtcblxuY29uc3QgbGlzdFRhZ05hbWVzID0gbm9kZSA9PiBPYmplY3Qua2V5cyh2aXNpdChub2RlLCB7fSkpO1xuXG5leHBvcnQgeyBsaXN0VGFnTmFtZXMgfTtcbiIsImltcG9ydCB7IFR5cGUsIGRlZmF1bHRUYWdzIH0gZnJvbSAnLi4vY29uc3RhbnRzLmpzJztcbmltcG9ydCB7IFlBTUxTZW1hbnRpY0Vycm9yLCBZQU1MV2FybmluZyB9IGZyb20gJy4uL2Vycm9ycy5qcyc7XG5cbmZ1bmN0aW9uIHJlc29sdmVUYWdIYW5kbGUoZG9jLCBub2RlKSB7XG4gIGNvbnN0IHtcbiAgICBoYW5kbGUsXG4gICAgc3VmZml4XG4gIH0gPSBub2RlLnRhZztcbiAgbGV0IHByZWZpeCA9IGRvYy50YWdQcmVmaXhlcy5maW5kKHAgPT4gcC5oYW5kbGUgPT09IGhhbmRsZSk7XG5cbiAgaWYgKCFwcmVmaXgpIHtcbiAgICBjb25zdCBkdHAgPSBkb2MuZ2V0RGVmYXVsdHMoKS50YWdQcmVmaXhlcztcbiAgICBpZiAoZHRwKSBwcmVmaXggPSBkdHAuZmluZChwID0+IHAuaGFuZGxlID09PSBoYW5kbGUpO1xuICAgIGlmICghcHJlZml4KSB0aHJvdyBuZXcgWUFNTFNlbWFudGljRXJyb3Iobm9kZSwgXCJUaGUgXCIuY29uY2F0KGhhbmRsZSwgXCIgdGFnIGhhbmRsZSBpcyBub24tZGVmYXVsdCBhbmQgd2FzIG5vdCBkZWNsYXJlZC5cIikpO1xuICB9XG5cbiAgaWYgKCFzdWZmaXgpIHRocm93IG5ldyBZQU1MU2VtYW50aWNFcnJvcihub2RlLCBcIlRoZSBcIi5jb25jYXQoaGFuZGxlLCBcIiB0YWcgaGFzIG5vIHN1ZmZpeC5cIikpO1xuXG4gIGlmIChoYW5kbGUgPT09ICchJyAmJiAoZG9jLnZlcnNpb24gfHwgZG9jLm9wdGlvbnMudmVyc2lvbikgPT09ICcxLjAnKSB7XG4gICAgaWYgKHN1ZmZpeFswXSA9PT0gJ14nKSB7XG4gICAgICBkb2Mud2FybmluZ3MucHVzaChuZXcgWUFNTFdhcm5pbmcobm9kZSwgJ1lBTUwgMS4wIF4gdGFnIGV4cGFuc2lvbiBpcyBub3Qgc3VwcG9ydGVkJykpO1xuICAgICAgcmV0dXJuIHN1ZmZpeDtcbiAgICB9XG5cbiAgICBpZiAoL1s6L10vLnRlc3Qoc3VmZml4KSkge1xuICAgICAgLy8gd29yZC9mb28gLT4gdGFnOndvcmQueWFtbC5vcmcsMjAwMjpmb29cbiAgICAgIGNvbnN0IHZvY2FiID0gc3VmZml4Lm1hdGNoKC9eKFthLXowLTktXSspXFwvKC4qKS9pKTtcbiAgICAgIHJldHVybiB2b2NhYiA/IFwidGFnOlwiLmNvbmNhdCh2b2NhYlsxXSwgXCIueWFtbC5vcmcsMjAwMjpcIikuY29uY2F0KHZvY2FiWzJdKSA6IFwidGFnOlwiLmNvbmNhdChzdWZmaXgpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBwcmVmaXgucHJlZml4ICsgZGVjb2RlVVJJQ29tcG9uZW50KHN1ZmZpeCk7XG59XG5cbmZ1bmN0aW9uIHJlc29sdmVUYWdOYW1lKGRvYywgbm9kZSkge1xuICBjb25zdCB7XG4gICAgdGFnLFxuICAgIHR5cGVcbiAgfSA9IG5vZGU7XG4gIGxldCBub25TcGVjaWZpYyA9IGZhbHNlO1xuXG4gIGlmICh0YWcpIHtcbiAgICBjb25zdCB7XG4gICAgICBoYW5kbGUsXG4gICAgICBzdWZmaXgsXG4gICAgICB2ZXJiYXRpbVxuICAgIH0gPSB0YWc7XG5cbiAgICBpZiAodmVyYmF0aW0pIHtcbiAgICAgIGlmICh2ZXJiYXRpbSAhPT0gJyEnICYmIHZlcmJhdGltICE9PSAnISEnKSByZXR1cm4gdmVyYmF0aW07XG4gICAgICBjb25zdCBtc2cgPSBcIlZlcmJhdGltIHRhZ3MgYXJlbid0IHJlc29sdmVkLCBzbyBcIi5jb25jYXQodmVyYmF0aW0sIFwiIGlzIGludmFsaWQuXCIpO1xuICAgICAgZG9jLmVycm9ycy5wdXNoKG5ldyBZQU1MU2VtYW50aWNFcnJvcihub2RlLCBtc2cpKTtcbiAgICB9IGVsc2UgaWYgKGhhbmRsZSA9PT0gJyEnICYmICFzdWZmaXgpIHtcbiAgICAgIG5vblNwZWNpZmljID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIHJlc29sdmVUYWdIYW5kbGUoZG9jLCBub2RlKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGRvYy5lcnJvcnMucHVzaChlcnJvcik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSBUeXBlLkJMT0NLX0ZPTERFRDpcbiAgICBjYXNlIFR5cGUuQkxPQ0tfTElURVJBTDpcbiAgICBjYXNlIFR5cGUuUVVPVEVfRE9VQkxFOlxuICAgIGNhc2UgVHlwZS5RVU9URV9TSU5HTEU6XG4gICAgICByZXR1cm4gZGVmYXVsdFRhZ3MuU1RSO1xuXG4gICAgY2FzZSBUeXBlLkZMT1dfTUFQOlxuICAgIGNhc2UgVHlwZS5NQVA6XG4gICAgICByZXR1cm4gZGVmYXVsdFRhZ3MuTUFQO1xuXG4gICAgY2FzZSBUeXBlLkZMT1dfU0VROlxuICAgIGNhc2UgVHlwZS5TRVE6XG4gICAgICByZXR1cm4gZGVmYXVsdFRhZ3MuU0VRO1xuXG4gICAgY2FzZSBUeXBlLlBMQUlOOlxuICAgICAgcmV0dXJuIG5vblNwZWNpZmljID8gZGVmYXVsdFRhZ3MuU1RSIDogbnVsbDtcblxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG5leHBvcnQgeyByZXNvbHZlVGFnTmFtZSB9O1xuIiwiaW1wb3J0IHsgWUFNTFNlbWFudGljRXJyb3IgfSBmcm9tICcuLi9lcnJvcnMuanMnO1xuaW1wb3J0IHsgVHlwZSB9IGZyb20gJy4uL2NvbnN0YW50cy5qcyc7XG5cbmZ1bmN0aW9uIGNoZWNrRmxvd0NvbGxlY3Rpb25FbmQoZXJyb3JzLCBjc3QpIHtcbiAgbGV0IGNoYXIsIG5hbWU7XG5cbiAgc3dpdGNoIChjc3QudHlwZSkge1xuICAgIGNhc2UgVHlwZS5GTE9XX01BUDpcbiAgICAgIGNoYXIgPSAnfSc7XG4gICAgICBuYW1lID0gJ2Zsb3cgbWFwJztcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBUeXBlLkZMT1dfU0VROlxuICAgICAgY2hhciA9ICddJztcbiAgICAgIG5hbWUgPSAnZmxvdyBzZXF1ZW5jZSc7XG4gICAgICBicmVhaztcblxuICAgIGRlZmF1bHQ6XG4gICAgICBlcnJvcnMucHVzaChuZXcgWUFNTFNlbWFudGljRXJyb3IoY3N0LCAnTm90IGEgZmxvdyBjb2xsZWN0aW9uIT8nKSk7XG4gICAgICByZXR1cm47XG4gIH1cblxuICBsZXQgbGFzdEl0ZW07XG5cbiAgZm9yIChsZXQgaSA9IGNzdC5pdGVtcy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgIGNvbnN0IGl0ZW0gPSBjc3QuaXRlbXNbaV07XG5cbiAgICBpZiAoIWl0ZW0gfHwgaXRlbS50eXBlICE9PSBUeXBlLkNPTU1FTlQpIHtcbiAgICAgIGxhc3RJdGVtID0gaXRlbTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIGlmIChsYXN0SXRlbSAmJiBsYXN0SXRlbS5jaGFyICE9PSBjaGFyKSB7XG4gICAgY29uc3QgbXNnID0gXCJFeHBlY3RlZCBcIi5jb25jYXQobmFtZSwgXCIgdG8gZW5kIHdpdGggXCIpLmNvbmNhdChjaGFyKTtcbiAgICBsZXQgZXJyO1xuXG4gICAgaWYgKHR5cGVvZiBsYXN0SXRlbS5vZmZzZXQgPT09ICdudW1iZXInKSB7XG4gICAgICBlcnIgPSBuZXcgWUFNTFNlbWFudGljRXJyb3IoY3N0LCBtc2cpO1xuICAgICAgZXJyLm9mZnNldCA9IGxhc3RJdGVtLm9mZnNldCArIDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVyciA9IG5ldyBZQU1MU2VtYW50aWNFcnJvcihsYXN0SXRlbSwgbXNnKTtcbiAgICAgIGlmIChsYXN0SXRlbS5yYW5nZSAmJiBsYXN0SXRlbS5yYW5nZS5lbmQpIGVyci5vZmZzZXQgPSBsYXN0SXRlbS5yYW5nZS5lbmQgLSBsYXN0SXRlbS5yYW5nZS5zdGFydDtcbiAgICB9XG5cbiAgICBlcnJvcnMucHVzaChlcnIpO1xuICB9XG59XG5mdW5jdGlvbiBjaGVja0Zsb3dDb21tZW50U3BhY2UoZXJyb3JzLCBjb21tZW50KSB7XG4gIGNvbnN0IHByZXYgPSBjb21tZW50LmNvbnRleHQuc3JjW2NvbW1lbnQucmFuZ2Uuc3RhcnQgLSAxXTtcblxuICBpZiAocHJldiAhPT0gJ1xcbicgJiYgcHJldiAhPT0gJ1xcdCcgJiYgcHJldiAhPT0gJyAnKSB7XG4gICAgY29uc3QgbXNnID0gJ0NvbW1lbnRzIG11c3QgYmUgc2VwYXJhdGVkIGZyb20gb3RoZXIgdG9rZW5zIGJ5IHdoaXRlIHNwYWNlIGNoYXJhY3RlcnMnO1xuICAgIGVycm9ycy5wdXNoKG5ldyBZQU1MU2VtYW50aWNFcnJvcihjb21tZW50LCBtc2cpKTtcbiAgfVxufVxuZnVuY3Rpb24gZ2V0TG9uZ0tleUVycm9yKHNvdXJjZSwga2V5KSB7XG4gIGNvbnN0IHNrID0gU3RyaW5nKGtleSk7XG4gIGNvbnN0IGsgPSBzay5zdWJzdHIoMCwgOCkgKyAnLi4uJyArIHNrLnN1YnN0cigtOCk7XG4gIHJldHVybiBuZXcgWUFNTFNlbWFudGljRXJyb3Ioc291cmNlLCBcIlRoZSBcXFwiXCIuY29uY2F0KGssIFwiXFxcIiBrZXkgaXMgdG9vIGxvbmdcIikpO1xufVxuZnVuY3Rpb24gcmVzb2x2ZUNvbW1lbnRzKGNvbGxlY3Rpb24sIGNvbW1lbnRzKSB7XG4gIGZvciAoY29uc3Qge1xuICAgIGFmdGVyS2V5LFxuICAgIGJlZm9yZSxcbiAgICBjb21tZW50XG4gIH0gb2YgY29tbWVudHMpIHtcbiAgICBsZXQgaXRlbSA9IGNvbGxlY3Rpb24uaXRlbXNbYmVmb3JlXTtcblxuICAgIGlmICghaXRlbSkge1xuICAgICAgaWYgKGNvbW1lbnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpZiAoY29sbGVjdGlvbi5jb21tZW50KSBjb2xsZWN0aW9uLmNvbW1lbnQgKz0gJ1xcbicgKyBjb21tZW50O2Vsc2UgY29sbGVjdGlvbi5jb21tZW50ID0gY29tbWVudDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGFmdGVyS2V5ICYmIGl0ZW0udmFsdWUpIGl0ZW0gPSBpdGVtLnZhbHVlO1xuXG4gICAgICBpZiAoY29tbWVudCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmIChhZnRlcktleSB8fCAhaXRlbS5jb21tZW50QmVmb3JlKSBpdGVtLnNwYWNlQmVmb3JlID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChpdGVtLmNvbW1lbnRCZWZvcmUpIGl0ZW0uY29tbWVudEJlZm9yZSArPSAnXFxuJyArIGNvbW1lbnQ7ZWxzZSBpdGVtLmNvbW1lbnRCZWZvcmUgPSBjb21tZW50O1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgeyBjaGVja0Zsb3dDb2xsZWN0aW9uRW5kLCBjaGVja0Zsb3dDb21tZW50U3BhY2UsIGdldExvbmdLZXlFcnJvciwgcmVzb2x2ZUNvbW1lbnRzIH07XG4iLCJpbXBvcnQgeyBBbGlhcyB9IGZyb20gJy4uL2FzdC9BbGlhcy5qcyc7XG5pbXBvcnQgeyBNRVJHRV9LRVksIE1lcmdlIH0gZnJvbSAnLi4vYXN0L01lcmdlLmpzJztcbmltcG9ydCB7IFBhaXIgfSBmcm9tICcuLi9hc3QvUGFpci5qcyc7XG5pbXBvcnQgeyBZQU1MTWFwIH0gZnJvbSAnLi4vYXN0L1lBTUxNYXAuanMnO1xuaW1wb3J0IHsgVHlwZSwgQ2hhciB9IGZyb20gJy4uL2NvbnN0YW50cy5qcyc7XG5pbXBvcnQgeyBQbGFpblZhbHVlIH0gZnJvbSAnLi4vY3N0L1BsYWluVmFsdWUuanMnO1xuaW1wb3J0IHsgWUFNTFNlbWFudGljRXJyb3IsIFlBTUxTeW50YXhFcnJvciB9IGZyb20gJy4uL2Vycm9ycy5qcyc7XG5pbXBvcnQgeyByZXNvbHZlQ29tbWVudHMsIGdldExvbmdLZXlFcnJvciwgY2hlY2tGbG93Q29tbWVudFNwYWNlLCBjaGVja0Zsb3dDb2xsZWN0aW9uRW5kIH0gZnJvbSAnLi9jb2xsZWN0aW9uLXV0aWxzLmpzJztcbmltcG9ydCB7IHJlc29sdmVOb2RlIH0gZnJvbSAnLi9yZXNvbHZlTm9kZS5qcyc7XG5cbmZ1bmN0aW9uIHJlc29sdmVNYXAoZG9jLCBjc3QpIHtcbiAgY29uc3Qge1xuICAgIGNvbW1lbnRzLFxuICAgIGl0ZW1zXG4gIH0gPSBjc3QudHlwZSA9PT0gVHlwZS5GTE9XX01BUCA/IHJlc29sdmVGbG93TWFwSXRlbXMoZG9jLCBjc3QpIDogcmVzb2x2ZUJsb2NrTWFwSXRlbXMoZG9jLCBjc3QpO1xuICBjb25zdCBtYXAgPSBuZXcgWUFNTE1hcChkb2Muc2NoZW1hKTtcbiAgbWFwLml0ZW1zID0gaXRlbXM7XG4gIHJlc29sdmVDb21tZW50cyhtYXAsIGNvbW1lbnRzKTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGl0ZW1zLmxlbmd0aDsgKytpKSB7XG4gICAgY29uc3Qge1xuICAgICAga2V5OiBpS2V5XG4gICAgfSA9IGl0ZW1zW2ldO1xuXG4gICAgaWYgKGRvYy5zY2hlbWEubWVyZ2UgJiYgaUtleSAmJiBpS2V5LnZhbHVlID09PSBNRVJHRV9LRVkpIHtcbiAgICAgIGl0ZW1zW2ldID0gbmV3IE1lcmdlKGl0ZW1zW2ldKTtcbiAgICAgIGNvbnN0IHNvdXJjZXMgPSBpdGVtc1tpXS52YWx1ZS5pdGVtcztcbiAgICAgIGxldCBlcnJvciA9IG51bGw7XG4gICAgICBzb3VyY2VzLnNvbWUobm9kZSA9PiB7XG4gICAgICAgIGlmIChub2RlIGluc3RhbmNlb2YgQWxpYXMpIHtcbiAgICAgICAgICAvLyBEdXJpbmcgcGFyc2luZywgYWxpYXMgc291cmNlcyBhcmUgQ1NUIG5vZGVzOyB0byBhY2NvdW50IGZvclxuICAgICAgICAgIC8vIGNpcmN1bGFyIHJlZmVyZW5jZXMgdGhlaXIgcmVzb2x2ZWQgdmFsdWVzIGNhbid0IGJlIHVzZWQgaGVyZS5cbiAgICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICB0eXBlXG4gICAgICAgICAgfSA9IG5vZGUuc291cmNlO1xuICAgICAgICAgIGlmICh0eXBlID09PSBUeXBlLk1BUCB8fCB0eXBlID09PSBUeXBlLkZMT1dfTUFQKSByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgcmV0dXJuIGVycm9yID0gJ01lcmdlIG5vZGVzIGFsaWFzZXMgY2FuIG9ubHkgcG9pbnQgdG8gbWFwcyc7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZXJyb3IgPSAnTWVyZ2Ugbm9kZXMgY2FuIG9ubHkgaGF2ZSBBbGlhcyBub2RlcyBhcyB2YWx1ZXMnO1xuICAgICAgfSk7XG4gICAgICBpZiAoZXJyb3IpIGRvYy5lcnJvcnMucHVzaChuZXcgWUFNTFNlbWFudGljRXJyb3IoY3N0LCBlcnJvcikpO1xuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKGxldCBqID0gaSArIDE7IGogPCBpdGVtcy5sZW5ndGg7ICsraikge1xuICAgICAgICBjb25zdCB7XG4gICAgICAgICAga2V5OiBqS2V5XG4gICAgICAgIH0gPSBpdGVtc1tqXTtcblxuICAgICAgICBpZiAoaUtleSA9PT0gaktleSB8fCBpS2V5ICYmIGpLZXkgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGlLZXksICd2YWx1ZScpICYmIGlLZXkudmFsdWUgPT09IGpLZXkudmFsdWUpIHtcbiAgICAgICAgICBjb25zdCBtc2cgPSBcIk1hcCBrZXlzIG11c3QgYmUgdW5pcXVlOyBcXFwiXCIuY29uY2F0KGlLZXksIFwiXFxcIiBpcyByZXBlYXRlZFwiKTtcbiAgICAgICAgICBkb2MuZXJyb3JzLnB1c2gobmV3IFlBTUxTZW1hbnRpY0Vycm9yKGNzdCwgbXNnKSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjc3QucmVzb2x2ZWQgPSBtYXA7XG4gIHJldHVybiBtYXA7XG59XG5cbmNvbnN0IHZhbHVlSGFzUGFpckNvbW1lbnQgPSAoe1xuICBjb250ZXh0OiB7XG4gICAgbGluZVN0YXJ0LFxuICAgIG5vZGUsXG4gICAgc3JjXG4gIH0sXG4gIHByb3BzXG59KSA9PiB7XG4gIGlmIChwcm9wcy5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTtcbiAgY29uc3Qge1xuICAgIHN0YXJ0XG4gIH0gPSBwcm9wc1swXTtcbiAgaWYgKG5vZGUgJiYgc3RhcnQgPiBub2RlLnZhbHVlUmFuZ2Uuc3RhcnQpIHJldHVybiBmYWxzZTtcbiAgaWYgKHNyY1tzdGFydF0gIT09IENoYXIuQ09NTUVOVCkgcmV0dXJuIGZhbHNlO1xuXG4gIGZvciAobGV0IGkgPSBsaW5lU3RhcnQ7IGkgPCBzdGFydDsgKytpKSBpZiAoc3JjW2ldID09PSAnXFxuJykgcmV0dXJuIGZhbHNlO1xuXG4gIHJldHVybiB0cnVlO1xufTtcblxuZnVuY3Rpb24gcmVzb2x2ZVBhaXJDb21tZW50KGl0ZW0sIHBhaXIpIHtcbiAgaWYgKCF2YWx1ZUhhc1BhaXJDb21tZW50KGl0ZW0pKSByZXR1cm47XG4gIGNvbnN0IGNvbW1lbnQgPSBpdGVtLmdldFByb3BWYWx1ZSgwLCBDaGFyLkNPTU1FTlQsIHRydWUpO1xuICBsZXQgZm91bmQgPSBmYWxzZTtcbiAgY29uc3QgY2IgPSBwYWlyLnZhbHVlLmNvbW1lbnRCZWZvcmU7XG5cbiAgaWYgKGNiICYmIGNiLnN0YXJ0c1dpdGgoY29tbWVudCkpIHtcbiAgICBwYWlyLnZhbHVlLmNvbW1lbnRCZWZvcmUgPSBjYi5zdWJzdHIoY29tbWVudC5sZW5ndGggKyAxKTtcbiAgICBmb3VuZCA9IHRydWU7XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgY2MgPSBwYWlyLnZhbHVlLmNvbW1lbnQ7XG5cbiAgICBpZiAoIWl0ZW0ubm9kZSAmJiBjYyAmJiBjYy5zdGFydHNXaXRoKGNvbW1lbnQpKSB7XG4gICAgICBwYWlyLnZhbHVlLmNvbW1lbnQgPSBjYy5zdWJzdHIoY29tbWVudC5sZW5ndGggKyAxKTtcbiAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICBpZiAoZm91bmQpIHBhaXIuY29tbWVudCA9IGNvbW1lbnQ7XG59XG5cbmZ1bmN0aW9uIHJlc29sdmVCbG9ja01hcEl0ZW1zKGRvYywgY3N0KSB7XG4gIGNvbnN0IGNvbW1lbnRzID0gW107XG4gIGNvbnN0IGl0ZW1zID0gW107XG4gIGxldCBrZXkgPSB1bmRlZmluZWQ7XG4gIGxldCBrZXlTdGFydCA9IG51bGw7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBjc3QuaXRlbXMubGVuZ3RoOyArK2kpIHtcbiAgICBjb25zdCBpdGVtID0gY3N0Lml0ZW1zW2ldO1xuXG4gICAgc3dpdGNoIChpdGVtLnR5cGUpIHtcbiAgICAgIGNhc2UgVHlwZS5CTEFOS19MSU5FOlxuICAgICAgICBjb21tZW50cy5wdXNoKHtcbiAgICAgICAgICBhZnRlcktleTogISFrZXksXG4gICAgICAgICAgYmVmb3JlOiBpdGVtcy5sZW5ndGhcbiAgICAgICAgfSk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIFR5cGUuQ09NTUVOVDpcbiAgICAgICAgY29tbWVudHMucHVzaCh7XG4gICAgICAgICAgYWZ0ZXJLZXk6ICEha2V5LFxuICAgICAgICAgIGJlZm9yZTogaXRlbXMubGVuZ3RoLFxuICAgICAgICAgIGNvbW1lbnQ6IGl0ZW0uY29tbWVudFxuICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgVHlwZS5NQVBfS0VZOlxuICAgICAgICBpZiAoa2V5ICE9PSB1bmRlZmluZWQpIGl0ZW1zLnB1c2gobmV3IFBhaXIoa2V5KSk7XG4gICAgICAgIGlmIChpdGVtLmVycm9yKSBkb2MuZXJyb3JzLnB1c2goaXRlbS5lcnJvcik7XG4gICAgICAgIGtleSA9IHJlc29sdmVOb2RlKGRvYywgaXRlbS5ub2RlKTtcbiAgICAgICAga2V5U3RhcnQgPSBudWxsO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBUeXBlLk1BUF9WQUxVRTpcbiAgICAgICAge1xuICAgICAgICAgIGlmIChrZXkgPT09IHVuZGVmaW5lZCkga2V5ID0gbnVsbDtcbiAgICAgICAgICBpZiAoaXRlbS5lcnJvcikgZG9jLmVycm9ycy5wdXNoKGl0ZW0uZXJyb3IpO1xuXG4gICAgICAgICAgaWYgKCFpdGVtLmNvbnRleHQuYXRMaW5lU3RhcnQgJiYgaXRlbS5ub2RlICYmIGl0ZW0ubm9kZS50eXBlID09PSBUeXBlLk1BUCAmJiAhaXRlbS5ub2RlLmNvbnRleHQuYXRMaW5lU3RhcnQpIHtcbiAgICAgICAgICAgIGNvbnN0IG1zZyA9ICdOZXN0ZWQgbWFwcGluZ3MgYXJlIG5vdCBhbGxvd2VkIGluIGNvbXBhY3QgbWFwcGluZ3MnO1xuICAgICAgICAgICAgZG9jLmVycm9ycy5wdXNoKG5ldyBZQU1MU2VtYW50aWNFcnJvcihpdGVtLm5vZGUsIG1zZykpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGxldCB2YWx1ZU5vZGUgPSBpdGVtLm5vZGU7XG5cbiAgICAgICAgICBpZiAoIXZhbHVlTm9kZSAmJiBpdGVtLnByb3BzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIC8vIENvbW1lbnRzIG9uIGFuIGVtcHR5IG1hcHBpbmcgdmFsdWUgbmVlZCB0byBiZSBwcmVzZXJ2ZWQsIHNvIHdlXG4gICAgICAgICAgICAvLyBuZWVkIHRvIGNvbnN0cnVjdCBhIG1pbmltYWwgZW1wdHkgbm9kZSBoZXJlIHRvIHVzZSBpbnN0ZWFkIG9mIHRoZVxuICAgICAgICAgICAgLy8gbWlzc2luZyBgaXRlbS5ub2RlYC4gLS0gZWVtZWxpL3lhbWwjMTlcbiAgICAgICAgICAgIHZhbHVlTm9kZSA9IG5ldyBQbGFpblZhbHVlKFR5cGUuUExBSU4sIFtdKTtcbiAgICAgICAgICAgIHZhbHVlTm9kZS5jb250ZXh0ID0ge1xuICAgICAgICAgICAgICBwYXJlbnQ6IGl0ZW0sXG4gICAgICAgICAgICAgIHNyYzogaXRlbS5jb250ZXh0LnNyY1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IHBvcyA9IGl0ZW0ucmFuZ2Uuc3RhcnQgKyAxO1xuICAgICAgICAgICAgdmFsdWVOb2RlLnJhbmdlID0ge1xuICAgICAgICAgICAgICBzdGFydDogcG9zLFxuICAgICAgICAgICAgICBlbmQ6IHBvc1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHZhbHVlTm9kZS52YWx1ZVJhbmdlID0ge1xuICAgICAgICAgICAgICBzdGFydDogcG9zLFxuICAgICAgICAgICAgICBlbmQ6IHBvc1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgaWYgKHR5cGVvZiBpdGVtLnJhbmdlLm9yaWdTdGFydCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgY29uc3Qgb3JpZ1BvcyA9IGl0ZW0ucmFuZ2Uub3JpZ1N0YXJ0ICsgMTtcbiAgICAgICAgICAgICAgdmFsdWVOb2RlLnJhbmdlLm9yaWdTdGFydCA9IHZhbHVlTm9kZS5yYW5nZS5vcmlnRW5kID0gb3JpZ1BvcztcbiAgICAgICAgICAgICAgdmFsdWVOb2RlLnZhbHVlUmFuZ2Uub3JpZ1N0YXJ0ID0gdmFsdWVOb2RlLnZhbHVlUmFuZ2Uub3JpZ0VuZCA9IG9yaWdQb3M7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgcGFpciA9IG5ldyBQYWlyKGtleSwgcmVzb2x2ZU5vZGUoZG9jLCB2YWx1ZU5vZGUpKTtcbiAgICAgICAgICByZXNvbHZlUGFpckNvbW1lbnQoaXRlbSwgcGFpcik7XG4gICAgICAgICAgaXRlbXMucHVzaChwYWlyKTtcblxuICAgICAgICAgIGlmIChrZXkgJiYgdHlwZW9mIGtleVN0YXJ0ID09PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgaWYgKGl0ZW0ucmFuZ2Uuc3RhcnQgPiBrZXlTdGFydCArIDEwMjQpIGRvYy5lcnJvcnMucHVzaChnZXRMb25nS2V5RXJyb3IoY3N0LCBrZXkpKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBrZXkgPSB1bmRlZmluZWQ7XG4gICAgICAgICAga2V5U3RhcnQgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAoa2V5ICE9PSB1bmRlZmluZWQpIGl0ZW1zLnB1c2gobmV3IFBhaXIoa2V5KSk7XG4gICAgICAgIGtleSA9IHJlc29sdmVOb2RlKGRvYywgaXRlbSk7XG4gICAgICAgIGtleVN0YXJ0ID0gaXRlbS5yYW5nZS5zdGFydDtcbiAgICAgICAgaWYgKGl0ZW0uZXJyb3IpIGRvYy5lcnJvcnMucHVzaChpdGVtLmVycm9yKTtcblxuICAgICAgICBuZXh0OiBmb3IgKGxldCBqID0gaSArIDE7OyArK2opIHtcbiAgICAgICAgICBjb25zdCBuZXh0SXRlbSA9IGNzdC5pdGVtc1tqXTtcblxuICAgICAgICAgIHN3aXRjaCAobmV4dEl0ZW0gJiYgbmV4dEl0ZW0udHlwZSkge1xuICAgICAgICAgICAgY2FzZSBUeXBlLkJMQU5LX0xJTkU6XG4gICAgICAgICAgICBjYXNlIFR5cGUuQ09NTUVOVDpcbiAgICAgICAgICAgICAgY29udGludWUgbmV4dDtcblxuICAgICAgICAgICAgY2FzZSBUeXBlLk1BUF9WQUxVRTpcbiAgICAgICAgICAgICAgYnJlYWsgbmV4dDtcblxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGNvbnN0IG1zZyA9ICdJbXBsaWNpdCBtYXAga2V5cyBuZWVkIHRvIGJlIGZvbGxvd2VkIGJ5IG1hcCB2YWx1ZXMnO1xuICAgICAgICAgICAgICAgIGRvYy5lcnJvcnMucHVzaChuZXcgWUFNTFNlbWFudGljRXJyb3IoaXRlbSwgbXNnKSk7XG4gICAgICAgICAgICAgICAgYnJlYWsgbmV4dDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpdGVtLnZhbHVlUmFuZ2VDb250YWluc05ld2xpbmUpIHtcbiAgICAgICAgICBjb25zdCBtc2cgPSAnSW1wbGljaXQgbWFwIGtleXMgbmVlZCB0byBiZSBvbiBhIHNpbmdsZSBsaW5lJztcbiAgICAgICAgICBkb2MuZXJyb3JzLnB1c2gobmV3IFlBTUxTZW1hbnRpY0Vycm9yKGl0ZW0sIG1zZykpO1xuICAgICAgICB9XG5cbiAgICB9XG4gIH1cblxuICBpZiAoa2V5ICE9PSB1bmRlZmluZWQpIGl0ZW1zLnB1c2gobmV3IFBhaXIoa2V5KSk7XG4gIHJldHVybiB7XG4gICAgY29tbWVudHMsXG4gICAgaXRlbXNcbiAgfTtcbn1cblxuZnVuY3Rpb24gcmVzb2x2ZUZsb3dNYXBJdGVtcyhkb2MsIGNzdCkge1xuICBjb25zdCBjb21tZW50cyA9IFtdO1xuICBjb25zdCBpdGVtcyA9IFtdO1xuICBsZXQga2V5ID0gdW5kZWZpbmVkO1xuICBsZXQgZXhwbGljaXRLZXkgPSBmYWxzZTtcbiAgbGV0IG5leHQgPSAneyc7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBjc3QuaXRlbXMubGVuZ3RoOyArK2kpIHtcbiAgICBjb25zdCBpdGVtID0gY3N0Lml0ZW1zW2ldO1xuXG4gICAgaWYgKHR5cGVvZiBpdGVtLmNoYXIgPT09ICdzdHJpbmcnKSB7XG4gICAgICBjb25zdCB7XG4gICAgICAgIGNoYXIsXG4gICAgICAgIG9mZnNldFxuICAgICAgfSA9IGl0ZW07XG5cbiAgICAgIGlmIChjaGFyID09PSAnPycgJiYga2V5ID09PSB1bmRlZmluZWQgJiYgIWV4cGxpY2l0S2V5KSB7XG4gICAgICAgIGV4cGxpY2l0S2V5ID0gdHJ1ZTtcbiAgICAgICAgbmV4dCA9ICc6JztcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChjaGFyID09PSAnOicpIHtcbiAgICAgICAgaWYgKGtleSA9PT0gdW5kZWZpbmVkKSBrZXkgPSBudWxsO1xuXG4gICAgICAgIGlmIChuZXh0ID09PSAnOicpIHtcbiAgICAgICAgICBuZXh0ID0gJywnO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoZXhwbGljaXRLZXkpIHtcbiAgICAgICAgICBpZiAoa2V5ID09PSB1bmRlZmluZWQgJiYgY2hhciAhPT0gJywnKSBrZXkgPSBudWxsO1xuICAgICAgICAgIGV4cGxpY2l0S2V5ID0gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoa2V5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBpdGVtcy5wdXNoKG5ldyBQYWlyKGtleSkpO1xuICAgICAgICAgIGtleSA9IHVuZGVmaW5lZDtcblxuICAgICAgICAgIGlmIChjaGFyID09PSAnLCcpIHtcbiAgICAgICAgICAgIG5leHQgPSAnOic7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGNoYXIgPT09ICd9Jykge1xuICAgICAgICBpZiAoaSA9PT0gY3N0Lml0ZW1zLmxlbmd0aCAtIDEpIGNvbnRpbnVlO1xuICAgICAgfSBlbHNlIGlmIChjaGFyID09PSBuZXh0KSB7XG4gICAgICAgIG5leHQgPSAnOic7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBtc2cgPSBcIkZsb3cgbWFwIGNvbnRhaW5zIGFuIHVuZXhwZWN0ZWQgXCIuY29uY2F0KGNoYXIpO1xuICAgICAgY29uc3QgZXJyID0gbmV3IFlBTUxTeW50YXhFcnJvcihjc3QsIG1zZyk7XG4gICAgICBlcnIub2Zmc2V0ID0gb2Zmc2V0O1xuICAgICAgZG9jLmVycm9ycy5wdXNoKGVycik7XG4gICAgfSBlbHNlIGlmIChpdGVtLnR5cGUgPT09IFR5cGUuQkxBTktfTElORSkge1xuICAgICAgY29tbWVudHMucHVzaCh7XG4gICAgICAgIGFmdGVyS2V5OiAhIWtleSxcbiAgICAgICAgYmVmb3JlOiBpdGVtcy5sZW5ndGhcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAoaXRlbS50eXBlID09PSBUeXBlLkNPTU1FTlQpIHtcbiAgICAgIGNoZWNrRmxvd0NvbW1lbnRTcGFjZShkb2MuZXJyb3JzLCBpdGVtKTtcbiAgICAgIGNvbW1lbnRzLnB1c2goe1xuICAgICAgICBhZnRlcktleTogISFrZXksXG4gICAgICAgIGJlZm9yZTogaXRlbXMubGVuZ3RoLFxuICAgICAgICBjb21tZW50OiBpdGVtLmNvbW1lbnRcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAoa2V5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChuZXh0ID09PSAnLCcpIGRvYy5lcnJvcnMucHVzaChuZXcgWUFNTFNlbWFudGljRXJyb3IoaXRlbSwgJ1NlcGFyYXRvciAsIG1pc3NpbmcgaW4gZmxvdyBtYXAnKSk7XG4gICAgICBrZXkgPSByZXNvbHZlTm9kZShkb2MsIGl0ZW0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAobmV4dCAhPT0gJywnKSBkb2MuZXJyb3JzLnB1c2gobmV3IFlBTUxTZW1hbnRpY0Vycm9yKGl0ZW0sICdJbmRpY2F0b3IgOiBtaXNzaW5nIGluIGZsb3cgbWFwIGVudHJ5JykpO1xuICAgICAgaXRlbXMucHVzaChuZXcgUGFpcihrZXksIHJlc29sdmVOb2RlKGRvYywgaXRlbSkpKTtcbiAgICAgIGtleSA9IHVuZGVmaW5lZDtcbiAgICAgIGV4cGxpY2l0S2V5ID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgY2hlY2tGbG93Q29sbGVjdGlvbkVuZChkb2MuZXJyb3JzLCBjc3QpO1xuICBpZiAoa2V5ICE9PSB1bmRlZmluZWQpIGl0ZW1zLnB1c2gobmV3IFBhaXIoa2V5KSk7XG4gIHJldHVybiB7XG4gICAgY29tbWVudHMsXG4gICAgaXRlbXNcbiAgfTtcbn1cblxuZXhwb3J0IHsgcmVzb2x2ZU1hcCB9O1xuIiwiaW1wb3J0IHsgUGFpciB9IGZyb20gJy4uL2FzdC9QYWlyLmpzJztcbmltcG9ydCB7IFlBTUxTZXEgfSBmcm9tICcuLi9hc3QvWUFNTFNlcS5qcyc7XG5pbXBvcnQgeyBUeXBlIH0gZnJvbSAnLi4vY29uc3RhbnRzLmpzJztcbmltcG9ydCB7IFlBTUxTeW50YXhFcnJvciwgWUFNTFNlbWFudGljRXJyb3IgfSBmcm9tICcuLi9lcnJvcnMuanMnO1xuaW1wb3J0IHsgcmVzb2x2ZUNvbW1lbnRzLCBnZXRMb25nS2V5RXJyb3IsIGNoZWNrRmxvd0NvbW1lbnRTcGFjZSwgY2hlY2tGbG93Q29sbGVjdGlvbkVuZCB9IGZyb20gJy4vY29sbGVjdGlvbi11dGlscy5qcyc7XG5pbXBvcnQgeyByZXNvbHZlTm9kZSB9IGZyb20gJy4vcmVzb2x2ZU5vZGUuanMnO1xuXG5mdW5jdGlvbiByZXNvbHZlU2VxKGRvYywgY3N0KSB7XG4gIGNvbnN0IHtcbiAgICBjb21tZW50cyxcbiAgICBpdGVtc1xuICB9ID0gY3N0LnR5cGUgPT09IFR5cGUuRkxPV19TRVEgPyByZXNvbHZlRmxvd1NlcUl0ZW1zKGRvYywgY3N0KSA6IHJlc29sdmVCbG9ja1NlcUl0ZW1zKGRvYywgY3N0KTtcbiAgY29uc3Qgc2VxID0gbmV3IFlBTUxTZXEoZG9jLnNjaGVtYSk7XG4gIHNlcS5pdGVtcyA9IGl0ZW1zO1xuICByZXNvbHZlQ29tbWVudHMoc2VxLCBjb21tZW50cyk7XG4gIGNzdC5yZXNvbHZlZCA9IHNlcTtcbiAgcmV0dXJuIHNlcTtcbn1cblxuZnVuY3Rpb24gcmVzb2x2ZUJsb2NrU2VxSXRlbXMoZG9jLCBjc3QpIHtcbiAgY29uc3QgY29tbWVudHMgPSBbXTtcbiAgY29uc3QgaXRlbXMgPSBbXTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGNzdC5pdGVtcy5sZW5ndGg7ICsraSkge1xuICAgIGNvbnN0IGl0ZW0gPSBjc3QuaXRlbXNbaV07XG5cbiAgICBzd2l0Y2ggKGl0ZW0udHlwZSkge1xuICAgICAgY2FzZSBUeXBlLkJMQU5LX0xJTkU6XG4gICAgICAgIGNvbW1lbnRzLnB1c2goe1xuICAgICAgICAgIGJlZm9yZTogaXRlbXMubGVuZ3RoXG4gICAgICAgIH0pO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBUeXBlLkNPTU1FTlQ6XG4gICAgICAgIGNvbW1lbnRzLnB1c2goe1xuICAgICAgICAgIGNvbW1lbnQ6IGl0ZW0uY29tbWVudCxcbiAgICAgICAgICBiZWZvcmU6IGl0ZW1zLmxlbmd0aFxuICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgVHlwZS5TRVFfSVRFTTpcbiAgICAgICAgaWYgKGl0ZW0uZXJyb3IpIGRvYy5lcnJvcnMucHVzaChpdGVtLmVycm9yKTtcbiAgICAgICAgaXRlbXMucHVzaChyZXNvbHZlTm9kZShkb2MsIGl0ZW0ubm9kZSkpO1xuXG4gICAgICAgIGlmIChpdGVtLmhhc1Byb3BzKSB7XG4gICAgICAgICAgY29uc3QgbXNnID0gJ1NlcXVlbmNlIGl0ZW1zIGNhbm5vdCBoYXZlIHRhZ3Mgb3IgYW5jaG9ycyBiZWZvcmUgdGhlIC0gaW5kaWNhdG9yJztcbiAgICAgICAgICBkb2MuZXJyb3JzLnB1c2gobmV3IFlBTUxTZW1hbnRpY0Vycm9yKGl0ZW0sIG1zZykpO1xuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChpdGVtLmVycm9yKSBkb2MuZXJyb3JzLnB1c2goaXRlbS5lcnJvcik7XG4gICAgICAgIGRvYy5lcnJvcnMucHVzaChuZXcgWUFNTFN5bnRheEVycm9yKGl0ZW0sIFwiVW5leHBlY3RlZCBcIi5jb25jYXQoaXRlbS50eXBlLCBcIiBub2RlIGluIHNlcXVlbmNlXCIpKSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBjb21tZW50cyxcbiAgICBpdGVtc1xuICB9O1xufVxuXG5mdW5jdGlvbiByZXNvbHZlRmxvd1NlcUl0ZW1zKGRvYywgY3N0KSB7XG4gIGNvbnN0IGNvbW1lbnRzID0gW107XG4gIGNvbnN0IGl0ZW1zID0gW107XG4gIGxldCBleHBsaWNpdEtleSA9IGZhbHNlO1xuICBsZXQga2V5ID0gdW5kZWZpbmVkO1xuICBsZXQga2V5U3RhcnQgPSBudWxsO1xuICBsZXQgbmV4dCA9ICdbJztcbiAgbGV0IHByZXZJdGVtID0gbnVsbDtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IGNzdC5pdGVtcy5sZW5ndGg7ICsraSkge1xuICAgIGNvbnN0IGl0ZW0gPSBjc3QuaXRlbXNbaV07XG5cbiAgICBpZiAodHlwZW9mIGl0ZW0uY2hhciA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGNvbnN0IHtcbiAgICAgICAgY2hhcixcbiAgICAgICAgb2Zmc2V0XG4gICAgICB9ID0gaXRlbTtcblxuICAgICAgaWYgKGNoYXIgIT09ICc6JyAmJiAoZXhwbGljaXRLZXkgfHwga2V5ICE9PSB1bmRlZmluZWQpKSB7XG4gICAgICAgIGlmIChleHBsaWNpdEtleSAmJiBrZXkgPT09IHVuZGVmaW5lZCkga2V5ID0gbmV4dCA/IGl0ZW1zLnBvcCgpIDogbnVsbDtcbiAgICAgICAgaXRlbXMucHVzaChuZXcgUGFpcihrZXkpKTtcbiAgICAgICAgZXhwbGljaXRLZXkgPSBmYWxzZTtcbiAgICAgICAga2V5ID0gdW5kZWZpbmVkO1xuICAgICAgICBrZXlTdGFydCA9IG51bGw7XG4gICAgICB9XG5cbiAgICAgIGlmIChjaGFyID09PSBuZXh0KSB7XG4gICAgICAgIG5leHQgPSBudWxsO1xuICAgICAgfSBlbHNlIGlmICghbmV4dCAmJiBjaGFyID09PSAnPycpIHtcbiAgICAgICAgZXhwbGljaXRLZXkgPSB0cnVlO1xuICAgICAgfSBlbHNlIGlmIChuZXh0ICE9PSAnWycgJiYgY2hhciA9PT0gJzonICYmIGtleSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGlmIChuZXh0ID09PSAnLCcpIHtcbiAgICAgICAgICBrZXkgPSBpdGVtcy5wb3AoKTtcblxuICAgICAgICAgIGlmIChrZXkgaW5zdGFuY2VvZiBQYWlyKSB7XG4gICAgICAgICAgICBjb25zdCBtc2cgPSAnQ2hhaW5pbmcgZmxvdyBzZXF1ZW5jZSBwYWlycyBpcyBpbnZhbGlkJztcbiAgICAgICAgICAgIGNvbnN0IGVyciA9IG5ldyBZQU1MU2VtYW50aWNFcnJvcihjc3QsIG1zZyk7XG4gICAgICAgICAgICBlcnIub2Zmc2V0ID0gb2Zmc2V0O1xuICAgICAgICAgICAgZG9jLmVycm9ycy5wdXNoKGVycik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKCFleHBsaWNpdEtleSAmJiB0eXBlb2Yga2V5U3RhcnQgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICBjb25zdCBrZXlFbmQgPSBpdGVtLnJhbmdlID8gaXRlbS5yYW5nZS5zdGFydCA6IGl0ZW0ub2Zmc2V0O1xuICAgICAgICAgICAgaWYgKGtleUVuZCA+IGtleVN0YXJ0ICsgMTAyNCkgZG9jLmVycm9ycy5wdXNoKGdldExvbmdLZXlFcnJvcihjc3QsIGtleSkpO1xuICAgICAgICAgICAgY29uc3Qge1xuICAgICAgICAgICAgICBzcmNcbiAgICAgICAgICAgIH0gPSBwcmV2SXRlbS5jb250ZXh0O1xuXG4gICAgICAgICAgICBmb3IgKGxldCBpID0ga2V5U3RhcnQ7IGkgPCBrZXlFbmQ7ICsraSkgaWYgKHNyY1tpXSA9PT0gJ1xcbicpIHtcbiAgICAgICAgICAgICAgY29uc3QgbXNnID0gJ0ltcGxpY2l0IGtleXMgb2YgZmxvdyBzZXF1ZW5jZSBwYWlycyBuZWVkIHRvIGJlIG9uIGEgc2luZ2xlIGxpbmUnO1xuICAgICAgICAgICAgICBkb2MuZXJyb3JzLnB1c2gobmV3IFlBTUxTZW1hbnRpY0Vycm9yKHByZXZJdGVtLCBtc2cpKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGtleSA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBrZXlTdGFydCA9IG51bGw7XG4gICAgICAgIGV4cGxpY2l0S2V5ID0gZmFsc2U7XG4gICAgICAgIG5leHQgPSBudWxsO1xuICAgICAgfSBlbHNlIGlmIChuZXh0ID09PSAnWycgfHwgY2hhciAhPT0gJ10nIHx8IGkgPCBjc3QuaXRlbXMubGVuZ3RoIC0gMSkge1xuICAgICAgICBjb25zdCBtc2cgPSBcIkZsb3cgc2VxdWVuY2UgY29udGFpbnMgYW4gdW5leHBlY3RlZCBcIi5jb25jYXQoY2hhcik7XG4gICAgICAgIGNvbnN0IGVyciA9IG5ldyBZQU1MU3ludGF4RXJyb3IoY3N0LCBtc2cpO1xuICAgICAgICBlcnIub2Zmc2V0ID0gb2Zmc2V0O1xuICAgICAgICBkb2MuZXJyb3JzLnB1c2goZXJyKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGl0ZW0udHlwZSA9PT0gVHlwZS5CTEFOS19MSU5FKSB7XG4gICAgICBjb21tZW50cy5wdXNoKHtcbiAgICAgICAgYmVmb3JlOiBpdGVtcy5sZW5ndGhcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAoaXRlbS50eXBlID09PSBUeXBlLkNPTU1FTlQpIHtcbiAgICAgIGNoZWNrRmxvd0NvbW1lbnRTcGFjZShkb2MuZXJyb3JzLCBpdGVtKTtcbiAgICAgIGNvbW1lbnRzLnB1c2goe1xuICAgICAgICBjb21tZW50OiBpdGVtLmNvbW1lbnQsXG4gICAgICAgIGJlZm9yZTogaXRlbXMubGVuZ3RoXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKG5leHQpIHtcbiAgICAgICAgY29uc3QgbXNnID0gXCJFeHBlY3RlZCBhIFwiLmNvbmNhdChuZXh0LCBcIiBpbiBmbG93IHNlcXVlbmNlXCIpO1xuICAgICAgICBkb2MuZXJyb3JzLnB1c2gobmV3IFlBTUxTZW1hbnRpY0Vycm9yKGl0ZW0sIG1zZykpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB2YWx1ZSA9IHJlc29sdmVOb2RlKGRvYywgaXRlbSk7XG5cbiAgICAgIGlmIChrZXkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBpdGVtcy5wdXNoKHZhbHVlKTtcbiAgICAgICAgcHJldkl0ZW0gPSBpdGVtO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaXRlbXMucHVzaChuZXcgUGFpcihrZXksIHZhbHVlKSk7XG4gICAgICAgIGtleSA9IHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgICAga2V5U3RhcnQgPSBpdGVtLnJhbmdlLnN0YXJ0O1xuICAgICAgbmV4dCA9ICcsJztcbiAgICB9XG4gIH1cblxuICBjaGVja0Zsb3dDb2xsZWN0aW9uRW5kKGRvYy5lcnJvcnMsIGNzdCk7XG4gIGlmIChrZXkgIT09IHVuZGVmaW5lZCkgaXRlbXMucHVzaChuZXcgUGFpcihrZXkpKTtcbiAgcmV0dXJuIHtcbiAgICBjb21tZW50cyxcbiAgICBpdGVtc1xuICB9O1xufVxuXG5leHBvcnQgeyByZXNvbHZlU2VxIH07XG4iLCJpbXBvcnQgeyBDb2xsZWN0aW9uIH0gZnJvbSAnLi4vYXN0L0NvbGxlY3Rpb24uanMnO1xuaW1wb3J0IHsgU2NhbGFyIH0gZnJvbSAnLi4vYXN0L1NjYWxhci5qcyc7XG5pbXBvcnQgeyBUeXBlLCBkZWZhdWx0VGFncyB9IGZyb20gJy4uL2NvbnN0YW50cy5qcyc7XG5pbXBvcnQgeyBZQU1MU2VtYW50aWNFcnJvciwgWUFNTFdhcm5pbmcsIFlBTUxSZWZlcmVuY2VFcnJvciB9IGZyb20gJy4uL2Vycm9ycy5qcyc7XG5pbXBvcnQgeyByZXNvbHZlTWFwIH0gZnJvbSAnLi9yZXNvbHZlTWFwLmpzJztcbmltcG9ydCB7IHJlc29sdmVTY2FsYXIgfSBmcm9tICcuL3Jlc29sdmVTY2FsYXIuanMnO1xuaW1wb3J0IHsgcmVzb2x2ZVNlcSB9IGZyb20gJy4vcmVzb2x2ZVNlcS5qcyc7XG5cbmZ1bmN0aW9uIHJlc29sdmVCeVRhZ05hbWUoe1xuICBrbm93blRhZ3MsXG4gIHRhZ3Ncbn0sIHRhZ05hbWUsIHZhbHVlLCBvbkVycm9yKSB7XG4gIGNvbnN0IG1hdGNoV2l0aFRlc3QgPSBbXTtcblxuICBmb3IgKGNvbnN0IHRhZyBvZiB0YWdzKSB7XG4gICAgaWYgKHRhZy50YWcgPT09IHRhZ05hbWUpIHtcbiAgICAgIGlmICh0YWcudGVzdCkge1xuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykgbWF0Y2hXaXRoVGVzdC5wdXNoKHRhZyk7ZWxzZSBvbkVycm9yKFwiVGhlIHRhZyBcIi5jb25jYXQodGFnTmFtZSwgXCIgY2Fubm90IGJlIGFwcGxpZWQgdG8gYSBjb2xsZWN0aW9uXCIpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHJlcyA9IHRhZy5yZXNvbHZlKHZhbHVlLCBvbkVycm9yKTtcbiAgICAgICAgcmV0dXJuIHJlcyBpbnN0YW5jZW9mIENvbGxlY3Rpb24gPyByZXMgOiBuZXcgU2NhbGFyKHJlcyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKG1hdGNoV2l0aFRlc3QubGVuZ3RoID4gMCkgcmV0dXJuIHJlc29sdmVTY2FsYXIodmFsdWUsIG1hdGNoV2l0aFRlc3QpO1xuICBjb25zdCBrdCA9IGtub3duVGFnc1t0YWdOYW1lXTtcblxuICBpZiAoa3QpIHtcbiAgICB0YWdzLnB1c2goT2JqZWN0LmFzc2lnbih7fSwga3QsIHtcbiAgICAgIGRlZmF1bHQ6IGZhbHNlLFxuICAgICAgdGVzdDogdW5kZWZpbmVkXG4gICAgfSkpO1xuICAgIGNvbnN0IHJlcyA9IGt0LnJlc29sdmUodmFsdWUsIG9uRXJyb3IpO1xuICAgIHJldHVybiByZXMgaW5zdGFuY2VvZiBDb2xsZWN0aW9uID8gcmVzIDogbmV3IFNjYWxhcihyZXMpO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIHJlc29sdmVUYWcoZG9jLCBub2RlLCB0YWdOYW1lKSB7XG4gIGNvbnN0IHtcbiAgICBNQVAsXG4gICAgU0VRLFxuICAgIFNUUlxuICB9ID0gZGVmYXVsdFRhZ3M7XG4gIGxldCB2YWx1ZSwgZmFsbGJhY2s7XG5cbiAgY29uc3Qgb25FcnJvciA9IG1lc3NhZ2UgPT4gZG9jLmVycm9ycy5wdXNoKG5ldyBZQU1MU2VtYW50aWNFcnJvcihub2RlLCBtZXNzYWdlKSk7XG5cbiAgdHJ5IHtcbiAgICBzd2l0Y2ggKG5vZGUudHlwZSkge1xuICAgICAgY2FzZSBUeXBlLkZMT1dfTUFQOlxuICAgICAgY2FzZSBUeXBlLk1BUDpcbiAgICAgICAgdmFsdWUgPSByZXNvbHZlTWFwKGRvYywgbm9kZSk7XG4gICAgICAgIGZhbGxiYWNrID0gTUFQO1xuICAgICAgICBpZiAodGFnTmFtZSA9PT0gU0VRIHx8IHRhZ05hbWUgPT09IFNUUikgb25FcnJvcihcIlRoZSB0YWcgXCIuY29uY2F0KHRhZ05hbWUsIFwiIGNhbm5vdCBiZSBhcHBsaWVkIHRvIGEgbWFwcGluZ1wiKSk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIFR5cGUuRkxPV19TRVE6XG4gICAgICBjYXNlIFR5cGUuU0VROlxuICAgICAgICB2YWx1ZSA9IHJlc29sdmVTZXEoZG9jLCBub2RlKTtcbiAgICAgICAgZmFsbGJhY2sgPSBTRVE7XG4gICAgICAgIGlmICh0YWdOYW1lID09PSBNQVAgfHwgdGFnTmFtZSA9PT0gU1RSKSBvbkVycm9yKFwiVGhlIHRhZyBcIi5jb25jYXQodGFnTmFtZSwgXCIgY2Fubm90IGJlIGFwcGxpZWQgdG8gYSBzZXF1ZW5jZVwiKSk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICB2YWx1ZSA9IG5vZGUuc3RyVmFsdWUgfHwgJyc7XG5cbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICB2YWx1ZS5lcnJvcnMuZm9yRWFjaChlcnJvciA9PiBkb2MuZXJyb3JzLnB1c2goZXJyb3IpKTtcbiAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnN0cjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0YWdOYW1lID09PSBNQVAgfHwgdGFnTmFtZSA9PT0gU0VRKSBvbkVycm9yKFwiVGhlIHRhZyBcIi5jb25jYXQodGFnTmFtZSwgXCIgY2Fubm90IGJlIGFwcGxpZWQgdG8gYSBzY2FsYXJcIikpO1xuICAgICAgICBmYWxsYmFjayA9IFNUUjtcbiAgICB9XG5cbiAgICBjb25zdCByZXMgPSByZXNvbHZlQnlUYWdOYW1lKGRvYy5zY2hlbWEsIHRhZ05hbWUsIHZhbHVlLCBvbkVycm9yKTtcblxuICAgIGlmIChyZXMpIHtcbiAgICAgIGlmICh0YWdOYW1lICYmIG5vZGUudGFnKSByZXMudGFnID0gdGFnTmFtZTtcbiAgICAgIHJldHVybiByZXM7XG4gICAgfVxuICB9IGNhdGNoIChlcnJvcikge1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgIGlmICghZXJyb3Iuc291cmNlKSBlcnJvci5zb3VyY2UgPSBub2RlO1xuICAgIGRvYy5lcnJvcnMucHVzaChlcnJvcik7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB0cnkge1xuICAgIGlmICghZmFsbGJhY2spIHRocm93IG5ldyBFcnJvcihcIlRoZSB0YWcgXCIuY29uY2F0KHRhZ05hbWUsIFwiIGlzIHVuYXZhaWxhYmxlXCIpKTtcbiAgICBjb25zdCBtc2cgPSBcIlRoZSB0YWcgXCIuY29uY2F0KHRhZ05hbWUsIFwiIGlzIHVuYXZhaWxhYmxlLCBmYWxsaW5nIGJhY2sgdG8gXCIpLmNvbmNhdChmYWxsYmFjayk7XG4gICAgZG9jLndhcm5pbmdzLnB1c2gobmV3IFlBTUxXYXJuaW5nKG5vZGUsIG1zZykpO1xuICAgIGNvbnN0IHJlcyA9IHJlc29sdmVCeVRhZ05hbWUoZG9jLnNjaGVtYSwgZmFsbGJhY2ssIHZhbHVlLCBvbkVycm9yKTtcbiAgICByZXMudGFnID0gdGFnTmFtZTtcbiAgICByZXR1cm4gcmVzO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGNvbnN0IHJlZkVycm9yID0gbmV3IFlBTUxSZWZlcmVuY2VFcnJvcihub2RlLCBlcnJvci5tZXNzYWdlKTtcbiAgICByZWZFcnJvci5zdGFjayA9IGVycm9yLnN0YWNrO1xuICAgIGRvYy5lcnJvcnMucHVzaChyZWZFcnJvcik7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuZXhwb3J0IHsgcmVzb2x2ZVRhZyB9O1xuIiwiaW1wb3J0IHsgQWxpYXMgfSBmcm9tICcuLi9hc3QvQWxpYXMuanMnO1xuaW1wb3J0IHsgVHlwZSwgQ2hhciB9IGZyb20gJy4uL2NvbnN0YW50cy5qcyc7XG5pbXBvcnQgeyBZQU1MU2VtYW50aWNFcnJvciwgWUFNTFJlZmVyZW5jZUVycm9yLCBZQU1MU3ludGF4RXJyb3IgfSBmcm9tICcuLi9lcnJvcnMuanMnO1xuaW1wb3J0IHsgcmVzb2x2ZVNjYWxhciB9IGZyb20gJy4vcmVzb2x2ZVNjYWxhci5qcyc7XG5pbXBvcnQgeyByZXNvbHZlVGFnTmFtZSB9IGZyb20gJy4vcmVzb2x2ZVRhZ05hbWUuanMnO1xuaW1wb3J0IHsgcmVzb2x2ZVRhZyB9IGZyb20gJy4vcmVzb2x2ZVRhZy5qcyc7XG5cbmNvbnN0IGlzQ29sbGVjdGlvbkl0ZW0gPSBub2RlID0+IHtcbiAgaWYgKCFub2RlKSByZXR1cm4gZmFsc2U7XG4gIGNvbnN0IHtcbiAgICB0eXBlXG4gIH0gPSBub2RlO1xuICByZXR1cm4gdHlwZSA9PT0gVHlwZS5NQVBfS0VZIHx8IHR5cGUgPT09IFR5cGUuTUFQX1ZBTFVFIHx8IHR5cGUgPT09IFR5cGUuU0VRX0lURU07XG59O1xuXG5mdW5jdGlvbiByZXNvbHZlTm9kZVByb3BzKGVycm9ycywgbm9kZSkge1xuICBjb25zdCBjb21tZW50cyA9IHtcbiAgICBiZWZvcmU6IFtdLFxuICAgIGFmdGVyOiBbXVxuICB9O1xuICBsZXQgaGFzQW5jaG9yID0gZmFsc2U7XG4gIGxldCBoYXNUYWcgPSBmYWxzZTtcbiAgY29uc3QgcHJvcHMgPSBpc0NvbGxlY3Rpb25JdGVtKG5vZGUuY29udGV4dC5wYXJlbnQpID8gbm9kZS5jb250ZXh0LnBhcmVudC5wcm9wcy5jb25jYXQobm9kZS5wcm9wcykgOiBub2RlLnByb3BzO1xuXG4gIGZvciAoY29uc3Qge1xuICAgIHN0YXJ0LFxuICAgIGVuZFxuICB9IG9mIHByb3BzKSB7XG4gICAgc3dpdGNoIChub2RlLmNvbnRleHQuc3JjW3N0YXJ0XSkge1xuICAgICAgY2FzZSBDaGFyLkNPTU1FTlQ6XG4gICAgICAgIHtcbiAgICAgICAgICBpZiAoIW5vZGUuY29tbWVudEhhc1JlcXVpcmVkV2hpdGVzcGFjZShzdGFydCkpIHtcbiAgICAgICAgICAgIGNvbnN0IG1zZyA9ICdDb21tZW50cyBtdXN0IGJlIHNlcGFyYXRlZCBmcm9tIG90aGVyIHRva2VucyBieSB3aGl0ZSBzcGFjZSBjaGFyYWN0ZXJzJztcbiAgICAgICAgICAgIGVycm9ycy5wdXNoKG5ldyBZQU1MU2VtYW50aWNFcnJvcihub2RlLCBtc2cpKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICBoZWFkZXIsXG4gICAgICAgICAgICB2YWx1ZVJhbmdlXG4gICAgICAgICAgfSA9IG5vZGU7XG4gICAgICAgICAgY29uc3QgY2MgPSB2YWx1ZVJhbmdlICYmIChzdGFydCA+IHZhbHVlUmFuZ2Uuc3RhcnQgfHwgaGVhZGVyICYmIHN0YXJ0ID4gaGVhZGVyLnN0YXJ0KSA/IGNvbW1lbnRzLmFmdGVyIDogY29tbWVudHMuYmVmb3JlO1xuICAgICAgICAgIGNjLnB1c2gobm9kZS5jb250ZXh0LnNyYy5zbGljZShzdGFydCArIDEsIGVuZCkpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAvLyBBY3R1YWwgYW5jaG9yICYgdGFnIHJlc29sdXRpb24gaXMgaGFuZGxlZCBieSBzY2hlbWEsIGhlcmUgd2UganVzdCBjb21wbGFpblxuXG4gICAgICBjYXNlIENoYXIuQU5DSE9SOlxuICAgICAgICBpZiAoaGFzQW5jaG9yKSB7XG4gICAgICAgICAgY29uc3QgbXNnID0gJ0Egbm9kZSBjYW4gaGF2ZSBhdCBtb3N0IG9uZSBhbmNob3InO1xuICAgICAgICAgIGVycm9ycy5wdXNoKG5ldyBZQU1MU2VtYW50aWNFcnJvcihub2RlLCBtc2cpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGhhc0FuY2hvciA9IHRydWU7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIENoYXIuVEFHOlxuICAgICAgICBpZiAoaGFzVGFnKSB7XG4gICAgICAgICAgY29uc3QgbXNnID0gJ0Egbm9kZSBjYW4gaGF2ZSBhdCBtb3N0IG9uZSB0YWcnO1xuICAgICAgICAgIGVycm9ycy5wdXNoKG5ldyBZQU1MU2VtYW50aWNFcnJvcihub2RlLCBtc2cpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGhhc1RhZyA9IHRydWU7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgY29tbWVudHMsXG4gICAgaGFzQW5jaG9yLFxuICAgIGhhc1RhZ1xuICB9O1xufVxuXG5mdW5jdGlvbiByZXNvbHZlTm9kZVZhbHVlKGRvYywgbm9kZSkge1xuICBjb25zdCB7XG4gICAgYW5jaG9ycyxcbiAgICBlcnJvcnMsXG4gICAgc2NoZW1hXG4gIH0gPSBkb2M7XG5cbiAgaWYgKG5vZGUudHlwZSA9PT0gVHlwZS5BTElBUykge1xuICAgIGNvbnN0IG5hbWUgPSBub2RlLnJhd1ZhbHVlO1xuICAgIGNvbnN0IHNyYyA9IGFuY2hvcnMuZ2V0Tm9kZShuYW1lKTtcblxuICAgIGlmICghc3JjKSB7XG4gICAgICBjb25zdCBtc2cgPSBcIkFsaWFzZWQgYW5jaG9yIG5vdCBmb3VuZDogXCIuY29uY2F0KG5hbWUpO1xuICAgICAgZXJyb3JzLnB1c2gobmV3IFlBTUxSZWZlcmVuY2VFcnJvcihub2RlLCBtc2cpKTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0gLy8gTGF6eSByZXNvbHV0aW9uIGZvciBjaXJjdWxhciByZWZlcmVuY2VzXG5cblxuICAgIGNvbnN0IHJlcyA9IG5ldyBBbGlhcyhzcmMpO1xuXG4gICAgYW5jaG9ycy5fY3N0QWxpYXNlcy5wdXNoKHJlcyk7XG5cbiAgICByZXR1cm4gcmVzO1xuICB9XG5cbiAgY29uc3QgdGFnTmFtZSA9IHJlc29sdmVUYWdOYW1lKGRvYywgbm9kZSk7XG4gIGlmICh0YWdOYW1lKSByZXR1cm4gcmVzb2x2ZVRhZyhkb2MsIG5vZGUsIHRhZ05hbWUpO1xuXG4gIGlmIChub2RlLnR5cGUgIT09IFR5cGUuUExBSU4pIHtcbiAgICBjb25zdCBtc2cgPSBcIkZhaWxlZCB0byByZXNvbHZlIFwiLmNvbmNhdChub2RlLnR5cGUsIFwiIG5vZGUgaGVyZVwiKTtcbiAgICBlcnJvcnMucHVzaChuZXcgWUFNTFN5bnRheEVycm9yKG5vZGUsIG1zZykpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBsZXQgc3RyID0gbm9kZS5zdHJWYWx1ZSB8fCAnJztcblxuICAgIGlmICh0eXBlb2Ygc3RyICE9PSAnc3RyaW5nJykge1xuICAgICAgc3RyLmVycm9ycy5mb3JFYWNoKGVycm9yID0+IGRvYy5lcnJvcnMucHVzaChlcnJvcikpO1xuICAgICAgc3RyID0gc3RyLnN0cjtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzb2x2ZVNjYWxhcihzdHIsIHNjaGVtYS50YWdzKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoIWVycm9yLnNvdXJjZSkgZXJyb3Iuc291cmNlID0gbm9kZTtcbiAgICBlcnJvcnMucHVzaChlcnJvcik7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn0gLy8gc2V0cyBub2RlLnJlc29sdmVkIG9uIHN1Y2Nlc3NcblxuXG5mdW5jdGlvbiByZXNvbHZlTm9kZShkb2MsIG5vZGUpIHtcbiAgaWYgKCFub2RlKSByZXR1cm4gbnVsbDtcbiAgaWYgKG5vZGUuZXJyb3IpIGRvYy5lcnJvcnMucHVzaChub2RlLmVycm9yKTtcbiAgY29uc3Qge1xuICAgIGNvbW1lbnRzLFxuICAgIGhhc0FuY2hvcixcbiAgICBoYXNUYWdcbiAgfSA9IHJlc29sdmVOb2RlUHJvcHMoZG9jLmVycm9ycywgbm9kZSk7XG5cbiAgaWYgKGhhc0FuY2hvcikge1xuICAgIGNvbnN0IHtcbiAgICAgIGFuY2hvcnNcbiAgICB9ID0gZG9jO1xuICAgIGNvbnN0IG5hbWUgPSBub2RlLmFuY2hvcjtcbiAgICBjb25zdCBwcmV2ID0gYW5jaG9ycy5nZXROb2RlKG5hbWUpOyAvLyBBdCB0aGlzIHBvaW50LCBhbGlhc2VzIGZvciBhbnkgcHJlY2VkaW5nIG5vZGUgd2l0aCB0aGUgc2FtZSBhbmNob3JcbiAgICAvLyBuYW1lIGhhdmUgYWxyZWFkeSBiZWVuIHJlc29sdmVkLCBzbyBpdCBtYXkgc2FmZWx5IGJlIHJlbmFtZWQuXG5cbiAgICBpZiAocHJldikgYW5jaG9ycy5tYXBbYW5jaG9ycy5uZXdOYW1lKG5hbWUpXSA9IHByZXY7IC8vIER1cmluZyBwYXJzaW5nLCB3ZSBuZWVkIHRvIHN0b3JlIHRoZSBDU1Qgbm9kZSBpbiBhbmNob3JzLm1hcCBhc1xuICAgIC8vIGFuY2hvcnMgbmVlZCB0byBiZSBhdmFpbGFibGUgZHVyaW5nIHJlc29sdXRpb24gdG8gYWxsb3cgZm9yXG4gICAgLy8gY2lyY3VsYXIgcmVmZXJlbmNlcy5cblxuICAgIGFuY2hvcnMubWFwW25hbWVdID0gbm9kZTtcbiAgfVxuXG4gIGlmIChub2RlLnR5cGUgPT09IFR5cGUuQUxJQVMgJiYgKGhhc0FuY2hvciB8fCBoYXNUYWcpKSB7XG4gICAgY29uc3QgbXNnID0gJ0FuIGFsaWFzIG5vZGUgbXVzdCBub3Qgc3BlY2lmeSBhbnkgcHJvcGVydGllcyc7XG4gICAgZG9jLmVycm9ycy5wdXNoKG5ldyBZQU1MU2VtYW50aWNFcnJvcihub2RlLCBtc2cpKTtcbiAgfVxuXG4gIGNvbnN0IHJlcyA9IHJlc29sdmVOb2RlVmFsdWUoZG9jLCBub2RlKTtcblxuICBpZiAocmVzKSB7XG4gICAgcmVzLnJhbmdlID0gW25vZGUucmFuZ2Uuc3RhcnQsIG5vZGUucmFuZ2UuZW5kXTtcbiAgICBpZiAoZG9jLm9wdGlvbnMua2VlcENzdE5vZGVzKSByZXMuY3N0Tm9kZSA9IG5vZGU7XG4gICAgaWYgKGRvYy5vcHRpb25zLmtlZXBOb2RlVHlwZXMpIHJlcy50eXBlID0gbm9kZS50eXBlO1xuICAgIGNvbnN0IGNiID0gY29tbWVudHMuYmVmb3JlLmpvaW4oJ1xcbicpO1xuXG4gICAgaWYgKGNiKSB7XG4gICAgICByZXMuY29tbWVudEJlZm9yZSA9IHJlcy5jb21tZW50QmVmb3JlID8gXCJcIi5jb25jYXQocmVzLmNvbW1lbnRCZWZvcmUsIFwiXFxuXCIpLmNvbmNhdChjYikgOiBjYjtcbiAgICB9XG5cbiAgICBjb25zdCBjYSA9IGNvbW1lbnRzLmFmdGVyLmpvaW4oJ1xcbicpO1xuICAgIGlmIChjYSkgcmVzLmNvbW1lbnQgPSByZXMuY29tbWVudCA/IFwiXCIuY29uY2F0KHJlcy5jb21tZW50LCBcIlxcblwiKS5jb25jYXQoY2EpIDogY2E7XG4gIH1cblxuICByZXR1cm4gbm9kZS5yZXNvbHZlZCA9IHJlcztcbn1cblxuZXhwb3J0IHsgcmVzb2x2ZU5vZGUgfTtcbiIsImltcG9ydCB7IFR5cGUgfSBmcm9tICcuLi9jb25zdGFudHMuanMnO1xuaW1wb3J0IHsgWUFNTFN5bnRheEVycm9yIH0gZnJvbSAnLi4vZXJyb3JzLmpzJztcbmltcG9ydCB7IHJlc29sdmVOb2RlIH0gZnJvbSAnLi4vcmVzb2x2ZS9yZXNvbHZlTm9kZS5qcyc7XG5pbXBvcnQgeyBDb2xsZWN0aW9uIH0gZnJvbSAnLi4vYXN0L0NvbGxlY3Rpb24uanMnO1xuXG5mdW5jdGlvbiBwYXJzZUNvbnRlbnRzKGRvYywgY29udGVudHMpIHtcbiAgY29uc3QgY29tbWVudHMgPSB7XG4gICAgYmVmb3JlOiBbXSxcbiAgICBhZnRlcjogW11cbiAgfTtcbiAgbGV0IGJvZHkgPSB1bmRlZmluZWQ7XG4gIGxldCBzcGFjZUJlZm9yZSA9IGZhbHNlO1xuXG4gIGZvciAoY29uc3Qgbm9kZSBvZiBjb250ZW50cykge1xuICAgIGlmIChub2RlLnZhbHVlUmFuZ2UpIHtcbiAgICAgIGlmIChib2R5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29uc3QgbXNnID0gJ0RvY3VtZW50IGNvbnRhaW5zIHRyYWlsaW5nIGNvbnRlbnQgbm90IHNlcGFyYXRlZCBieSBhIC4uLiBvciAtLS0gbGluZSc7XG4gICAgICAgIGRvYy5lcnJvcnMucHVzaChuZXcgWUFNTFN5bnRheEVycm9yKG5vZGUsIG1zZykpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVzID0gcmVzb2x2ZU5vZGUoZG9jLCBub2RlKTtcblxuICAgICAgaWYgKHNwYWNlQmVmb3JlKSB7XG4gICAgICAgIHJlcy5zcGFjZUJlZm9yZSA9IHRydWU7XG4gICAgICAgIHNwYWNlQmVmb3JlID0gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGJvZHkgPSByZXM7XG4gICAgfSBlbHNlIGlmIChub2RlLmNvbW1lbnQgIT09IG51bGwpIHtcbiAgICAgIGNvbnN0IGNjID0gYm9keSA9PT0gdW5kZWZpbmVkID8gY29tbWVudHMuYmVmb3JlIDogY29tbWVudHMuYWZ0ZXI7XG4gICAgICBjYy5wdXNoKG5vZGUuY29tbWVudCk7XG4gICAgfSBlbHNlIGlmIChub2RlLnR5cGUgPT09IFR5cGUuQkxBTktfTElORSkge1xuICAgICAgc3BhY2VCZWZvcmUgPSB0cnVlO1xuXG4gICAgICBpZiAoYm9keSA9PT0gdW5kZWZpbmVkICYmIGNvbW1lbnRzLmJlZm9yZS5sZW5ndGggPiAwICYmICFkb2MuY29tbWVudEJlZm9yZSkge1xuICAgICAgICAvLyBzcGFjZS1zZXBhcmF0ZWQgY29tbWVudHMgYXQgc3RhcnQgYXJlIHBhcnNlZCBhcyBkb2N1bWVudCBjb21tZW50c1xuICAgICAgICBkb2MuY29tbWVudEJlZm9yZSA9IGNvbW1lbnRzLmJlZm9yZS5qb2luKCdcXG4nKTtcbiAgICAgICAgY29tbWVudHMuYmVmb3JlID0gW107XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZG9jLmNvbnRlbnRzID0gYm9keSB8fCBudWxsO1xuXG4gIGlmICghYm9keSkge1xuICAgIGRvYy5jb21tZW50ID0gY29tbWVudHMuYmVmb3JlLmNvbmNhdChjb21tZW50cy5hZnRlcikuam9pbignXFxuJykgfHwgbnVsbDtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCBjYiA9IGNvbW1lbnRzLmJlZm9yZS5qb2luKCdcXG4nKTtcblxuICAgIGlmIChjYikge1xuICAgICAgY29uc3QgY2JOb2RlID0gYm9keSBpbnN0YW5jZW9mIENvbGxlY3Rpb24gJiYgYm9keS5pdGVtc1swXSA/IGJvZHkuaXRlbXNbMF0gOiBib2R5O1xuICAgICAgY2JOb2RlLmNvbW1lbnRCZWZvcmUgPSBjYk5vZGUuY29tbWVudEJlZm9yZSA/IFwiXCIuY29uY2F0KGNiLCBcIlxcblwiKS5jb25jYXQoY2JOb2RlLmNvbW1lbnRCZWZvcmUpIDogY2I7XG4gICAgfVxuXG4gICAgZG9jLmNvbW1lbnQgPSBjb21tZW50cy5hZnRlci5qb2luKCdcXG4nKSB8fCBudWxsO1xuICB9XG59XG5cbmV4cG9ydCB7IHBhcnNlQ29udGVudHMgfTtcbiIsImltcG9ydCB7IFlBTUxXYXJuaW5nLCBZQU1MU2VtYW50aWNFcnJvciB9IGZyb20gJy4uL2Vycm9ycy5qcyc7XG5pbXBvcnQgeyBkb2N1bWVudE9wdGlvbnMgfSBmcm9tICcuLi9vcHRpb25zLmpzJztcblxuZnVuY3Rpb24gcmVzb2x2ZVRhZ0RpcmVjdGl2ZSh7XG4gIHRhZ1ByZWZpeGVzXG59LCBkaXJlY3RpdmUpIHtcbiAgY29uc3QgW2hhbmRsZSwgcHJlZml4XSA9IGRpcmVjdGl2ZS5wYXJhbWV0ZXJzO1xuXG4gIGlmICghaGFuZGxlIHx8ICFwcmVmaXgpIHtcbiAgICBjb25zdCBtc2cgPSAnSW5zdWZmaWNpZW50IHBhcmFtZXRlcnMgZ2l2ZW4gZm9yICVUQUcgZGlyZWN0aXZlJztcbiAgICB0aHJvdyBuZXcgWUFNTFNlbWFudGljRXJyb3IoZGlyZWN0aXZlLCBtc2cpO1xuICB9XG5cbiAgaWYgKHRhZ1ByZWZpeGVzLnNvbWUocCA9PiBwLmhhbmRsZSA9PT0gaGFuZGxlKSkge1xuICAgIGNvbnN0IG1zZyA9ICdUaGUgJVRBRyBkaXJlY3RpdmUgbXVzdCBvbmx5IGJlIGdpdmVuIGF0IG1vc3Qgb25jZSBwZXIgaGFuZGxlIGluIHRoZSBzYW1lIGRvY3VtZW50Lic7XG4gICAgdGhyb3cgbmV3IFlBTUxTZW1hbnRpY0Vycm9yKGRpcmVjdGl2ZSwgbXNnKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgaGFuZGxlLFxuICAgIHByZWZpeFxuICB9O1xufVxuXG5mdW5jdGlvbiByZXNvbHZlWWFtbERpcmVjdGl2ZShkb2MsIGRpcmVjdGl2ZSkge1xuICBsZXQgW3ZlcnNpb25dID0gZGlyZWN0aXZlLnBhcmFtZXRlcnM7XG4gIGlmIChkaXJlY3RpdmUubmFtZSA9PT0gJ1lBTUw6MS4wJykgdmVyc2lvbiA9ICcxLjAnO1xuXG4gIGlmICghdmVyc2lvbikge1xuICAgIGNvbnN0IG1zZyA9ICdJbnN1ZmZpY2llbnQgcGFyYW1ldGVycyBnaXZlbiBmb3IgJVlBTUwgZGlyZWN0aXZlJztcbiAgICB0aHJvdyBuZXcgWUFNTFNlbWFudGljRXJyb3IoZGlyZWN0aXZlLCBtc2cpO1xuICB9XG5cbiAgaWYgKCFkb2N1bWVudE9wdGlvbnNbdmVyc2lvbl0pIHtcbiAgICBjb25zdCB2MCA9IGRvYy52ZXJzaW9uIHx8IGRvYy5vcHRpb25zLnZlcnNpb247XG4gICAgY29uc3QgbXNnID0gXCJEb2N1bWVudCB3aWxsIGJlIHBhcnNlZCBhcyBZQU1MIFwiLmNvbmNhdCh2MCwgXCIgcmF0aGVyIHRoYW4gWUFNTCBcIikuY29uY2F0KHZlcnNpb24pO1xuICAgIGRvYy53YXJuaW5ncy5wdXNoKG5ldyBZQU1MV2FybmluZyhkaXJlY3RpdmUsIG1zZykpO1xuICB9XG5cbiAgcmV0dXJuIHZlcnNpb247XG59XG5cbmZ1bmN0aW9uIHBhcnNlRGlyZWN0aXZlcyhkb2MsIGRpcmVjdGl2ZXMsIHByZXZEb2MpIHtcbiAgY29uc3QgZGlyZWN0aXZlQ29tbWVudHMgPSBbXTtcbiAgbGV0IGhhc0RpcmVjdGl2ZXMgPSBmYWxzZTtcblxuICBmb3IgKGNvbnN0IGRpcmVjdGl2ZSBvZiBkaXJlY3RpdmVzKSB7XG4gICAgY29uc3Qge1xuICAgICAgY29tbWVudCxcbiAgICAgIG5hbWVcbiAgICB9ID0gZGlyZWN0aXZlO1xuXG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgICBjYXNlICdUQUcnOlxuICAgICAgICB0cnkge1xuICAgICAgICAgIGRvYy50YWdQcmVmaXhlcy5wdXNoKHJlc29sdmVUYWdEaXJlY3RpdmUoZG9jLCBkaXJlY3RpdmUpKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICBkb2MuZXJyb3JzLnB1c2goZXJyb3IpO1xuICAgICAgICB9XG5cbiAgICAgICAgaGFzRGlyZWN0aXZlcyA9IHRydWU7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdZQU1MJzpcbiAgICAgIGNhc2UgJ1lBTUw6MS4wJzpcbiAgICAgICAgaWYgKGRvYy52ZXJzaW9uKSB7XG4gICAgICAgICAgY29uc3QgbXNnID0gJ1RoZSAlWUFNTCBkaXJlY3RpdmUgbXVzdCBvbmx5IGJlIGdpdmVuIGF0IG1vc3Qgb25jZSBwZXIgZG9jdW1lbnQuJztcbiAgICAgICAgICBkb2MuZXJyb3JzLnB1c2gobmV3IFlBTUxTZW1hbnRpY0Vycm9yKGRpcmVjdGl2ZSwgbXNnKSk7XG4gICAgICAgIH1cblxuICAgICAgICB0cnkge1xuICAgICAgICAgIGRvYy52ZXJzaW9uID0gcmVzb2x2ZVlhbWxEaXJlY3RpdmUoZG9jLCBkaXJlY3RpdmUpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGRvYy5lcnJvcnMucHVzaChlcnJvcik7XG4gICAgICAgIH1cblxuICAgICAgICBoYXNEaXJlY3RpdmVzID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmIChuYW1lKSB7XG4gICAgICAgICAgY29uc3QgbXNnID0gXCJZQU1MIG9ubHkgc3VwcG9ydHMgJVRBRyBhbmQgJVlBTUwgZGlyZWN0aXZlcywgYW5kIG5vdCAlXCIuY29uY2F0KG5hbWUpO1xuICAgICAgICAgIGRvYy53YXJuaW5ncy5wdXNoKG5ldyBZQU1MV2FybmluZyhkaXJlY3RpdmUsIG1zZykpO1xuICAgICAgICB9XG5cbiAgICB9XG5cbiAgICBpZiAoY29tbWVudCkgZGlyZWN0aXZlQ29tbWVudHMucHVzaChjb21tZW50KTtcbiAgfVxuXG4gIGlmIChwcmV2RG9jICYmICFoYXNEaXJlY3RpdmVzICYmICcxLjEnID09PSAoZG9jLnZlcnNpb24gfHwgcHJldkRvYy52ZXJzaW9uIHx8IGRvYy5vcHRpb25zLnZlcnNpb24pKSB7XG4gICAgY29uc3QgY29weVRhZ1ByZWZpeCA9ICh7XG4gICAgICBoYW5kbGUsXG4gICAgICBwcmVmaXhcbiAgICB9KSA9PiAoe1xuICAgICAgaGFuZGxlLFxuICAgICAgcHJlZml4XG4gICAgfSk7XG5cbiAgICBkb2MudGFnUHJlZml4ZXMgPSBwcmV2RG9jLnRhZ1ByZWZpeGVzLm1hcChjb3B5VGFnUHJlZml4KTtcbiAgICBkb2MudmVyc2lvbiA9IHByZXZEb2MudmVyc2lvbjtcbiAgfVxuXG4gIGRvYy5jb21tZW50QmVmb3JlID0gZGlyZWN0aXZlQ29tbWVudHMuam9pbignXFxuJykgfHwgbnVsbDtcbn1cblxuZXhwb3J0IHsgcGFyc2VEaXJlY3RpdmVzIH07XG4iLCJpbXBvcnQgeyBkZWZpbmVQcm9wZXJ0eSBhcyBfZGVmaW5lUHJvcGVydHkgfSBmcm9tICcuLi9fdmlydHVhbC9fcm9sbHVwUGx1Z2luQmFiZWxIZWxwZXJzLmpzJztcbmltcG9ydCB7IERvY3VtZW50IGFzIERvY3VtZW50JDEgfSBmcm9tICcuLi9jc3QvRG9jdW1lbnQuanMnO1xuaW1wb3J0IHsgZGVmYXVsdFRhZ1ByZWZpeCB9IGZyb20gJy4uL2NvbnN0YW50cy5qcyc7XG5pbXBvcnQgeyBZQU1MRXJyb3IgfSBmcm9tICcuLi9lcnJvcnMuanMnO1xuaW1wb3J0IHsgZGVmYXVsdE9wdGlvbnMsIGRvY3VtZW50T3B0aW9ucyB9IGZyb20gJy4uL29wdGlvbnMuanMnO1xuaW1wb3J0IHsgYWRkQ29tbWVudCB9IGZyb20gJy4uL3N0cmluZ2lmeS9hZGRDb21tZW50LmpzJztcbmltcG9ydCB7IHN0cmluZ2lmeSB9IGZyb20gJy4uL3N0cmluZ2lmeS9zdHJpbmdpZnkuanMnO1xuaW1wb3J0IHsgQW5jaG9ycyB9IGZyb20gJy4vQW5jaG9ycy5qcyc7XG5pbXBvcnQgeyBTY2hlbWEgfSBmcm9tICcuL1NjaGVtYS5qcyc7XG5pbXBvcnQgeyBhcHBseVJldml2ZXIgfSBmcm9tICcuL2FwcGx5UmV2aXZlci5qcyc7XG5pbXBvcnQgeyBjcmVhdGVOb2RlIH0gZnJvbSAnLi9jcmVhdGVOb2RlLmpzJztcbmltcG9ydCB7IGxpc3RUYWdOYW1lcyB9IGZyb20gJy4vbGlzdFRhZ05hbWVzLmpzJztcbmltcG9ydCB7IHBhcnNlQ29udGVudHMgfSBmcm9tICcuL3BhcnNlQ29udGVudHMuanMnO1xuaW1wb3J0IHsgcGFyc2VEaXJlY3RpdmVzIH0gZnJvbSAnLi9wYXJzZURpcmVjdGl2ZXMuanMnO1xuaW1wb3J0IHsgUGFpciB9IGZyb20gJy4uL2FzdC9QYWlyLmpzJztcbmltcG9ydCB7IGlzRW1wdHlQYXRoLCBDb2xsZWN0aW9uLCBjb2xsZWN0aW9uRnJvbVBhdGggfSBmcm9tICcuLi9hc3QvQ29sbGVjdGlvbi5qcyc7XG5pbXBvcnQgeyBTY2FsYXIgfSBmcm9tICcuLi9hc3QvU2NhbGFyLmpzJztcbmltcG9ydCB7IHRvSlMgfSBmcm9tICcuLi9hc3QvdG9KUy5qcyc7XG5pbXBvcnQgeyBOb2RlIH0gZnJvbSAnLi4vYXN0L05vZGUuanMnO1xuaW1wb3J0IHsgQWxpYXMgfSBmcm9tICcuLi9hc3QvQWxpYXMuanMnO1xuXG5mdW5jdGlvbiBhc3NlcnRDb2xsZWN0aW9uKGNvbnRlbnRzKSB7XG4gIGlmIChjb250ZW50cyBpbnN0YW5jZW9mIENvbGxlY3Rpb24pIHJldHVybiB0cnVlO1xuICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIGEgWUFNTCBjb2xsZWN0aW9uIGFzIGRvY3VtZW50IGNvbnRlbnRzJyk7XG59XG5cbmNsYXNzIERvY3VtZW50IHtcbiAgY29uc3RydWN0b3IodmFsdWUsIHJlcGxhY2VyLCBvcHRpb25zKSB7XG4gICAgaWYgKG9wdGlvbnMgPT09IHVuZGVmaW5lZCAmJiByZXBsYWNlciAmJiB0eXBlb2YgcmVwbGFjZXIgPT09ICdvYmplY3QnICYmICFBcnJheS5pc0FycmF5KHJlcGxhY2VyKSkge1xuICAgICAgb3B0aW9ucyA9IHJlcGxhY2VyO1xuICAgICAgcmVwbGFjZXIgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgdGhpcy5vcHRpb25zID0gT2JqZWN0LmFzc2lnbih7fSwgZGVmYXVsdE9wdGlvbnMsIG9wdGlvbnMpO1xuICAgIHRoaXMuYW5jaG9ycyA9IG5ldyBBbmNob3JzKHRoaXMub3B0aW9ucy5hbmNob3JQcmVmaXgpO1xuICAgIHRoaXMuY29tbWVudEJlZm9yZSA9IG51bGw7XG4gICAgdGhpcy5jb21tZW50ID0gbnVsbDtcbiAgICB0aGlzLmRpcmVjdGl2ZXNFbmRNYXJrZXIgPSBudWxsO1xuICAgIHRoaXMuZXJyb3JzID0gW107XG4gICAgdGhpcy5zY2hlbWEgPSBudWxsO1xuICAgIHRoaXMudGFnUHJlZml4ZXMgPSBbXTtcbiAgICB0aGlzLnZlcnNpb24gPSBudWxsO1xuICAgIHRoaXMud2FybmluZ3MgPSBbXTtcblxuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBub3RlIHRoYXQgdGhpcy5zY2hlbWEgaXMgbGVmdCBhcyBudWxsIGhlcmVcbiAgICAgIHRoaXMuY29udGVudHMgPSBudWxsO1xuICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBEb2N1bWVudCQxKSB7XG4gICAgICB0aGlzLnBhcnNlKHZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jb250ZW50cyA9IHRoaXMuY3JlYXRlTm9kZSh2YWx1ZSwge1xuICAgICAgICByZXBsYWNlclxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgYWRkKHZhbHVlKSB7XG4gICAgYXNzZXJ0Q29sbGVjdGlvbih0aGlzLmNvbnRlbnRzKTtcbiAgICByZXR1cm4gdGhpcy5jb250ZW50cy5hZGQodmFsdWUpO1xuICB9XG5cbiAgYWRkSW4ocGF0aCwgdmFsdWUpIHtcbiAgICBhc3NlcnRDb2xsZWN0aW9uKHRoaXMuY29udGVudHMpO1xuICAgIHRoaXMuY29udGVudHMuYWRkSW4ocGF0aCwgdmFsdWUpO1xuICB9XG5cbiAgY3JlYXRlTm9kZSh2YWx1ZSwge1xuICAgIGtlZXBVbmRlZmluZWQsXG4gICAgb25UYWdPYmosXG4gICAgcmVwbGFjZXIsXG4gICAgdGFnLFxuICAgIHdyYXBTY2FsYXJzXG4gIH0gPSB7fSkge1xuICAgIHRoaXMuc2V0U2NoZW1hKCk7XG4gICAgaWYgKHR5cGVvZiByZXBsYWNlciA9PT0gJ2Z1bmN0aW9uJykgdmFsdWUgPSByZXBsYWNlci5jYWxsKHtcbiAgICAgICcnOiB2YWx1ZVxuICAgIH0sICcnLCB2YWx1ZSk7ZWxzZSBpZiAoQXJyYXkuaXNBcnJheShyZXBsYWNlcikpIHtcbiAgICAgIGNvbnN0IGtleVRvU3RyID0gdiA9PiB0eXBlb2YgdiA9PT0gJ251bWJlcicgfHwgdiBpbnN0YW5jZW9mIFN0cmluZyB8fCB2IGluc3RhbmNlb2YgTnVtYmVyO1xuXG4gICAgICBjb25zdCBhc1N0ciA9IHJlcGxhY2VyLmZpbHRlcihrZXlUb1N0cikubWFwKFN0cmluZyk7XG4gICAgICBpZiAoYXNTdHIubGVuZ3RoID4gMCkgcmVwbGFjZXIgPSByZXBsYWNlci5jb25jYXQoYXNTdHIpO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGtlZXBVbmRlZmluZWQgIT09ICdib29sZWFuJykga2VlcFVuZGVmaW5lZCA9ICEhdGhpcy5vcHRpb25zLmtlZXBVbmRlZmluZWQ7XG4gICAgY29uc3QgYWxpYXNOb2RlcyA9IFtdO1xuICAgIGNvbnN0IGN0eCA9IHtcbiAgICAgIGtlZXBVbmRlZmluZWQsXG5cbiAgICAgIG9uQWxpYXMoc291cmNlKSB7XG4gICAgICAgIGNvbnN0IGFsaWFzID0gbmV3IEFsaWFzKHNvdXJjZSk7XG4gICAgICAgIGFsaWFzTm9kZXMucHVzaChhbGlhcyk7XG4gICAgICAgIHJldHVybiBhbGlhcztcbiAgICAgIH0sXG5cbiAgICAgIG9uVGFnT2JqLFxuICAgICAgcHJldk9iamVjdHM6IG5ldyBNYXAoKSxcbiAgICAgIHJlcGxhY2VyLFxuICAgICAgc2NoZW1hOiB0aGlzLnNjaGVtYSxcbiAgICAgIHdyYXBTY2FsYXJzOiB3cmFwU2NhbGFycyAhPT0gZmFsc2VcbiAgICB9O1xuICAgIGNvbnN0IG5vZGUgPSBjcmVhdGVOb2RlKHZhbHVlLCB0YWcsIGN0eCk7XG5cbiAgICBmb3IgKGNvbnN0IGFsaWFzIG9mIGFsaWFzTm9kZXMpIHtcbiAgICAgIC8vIFdpdGggY2lyY3VsYXIgcmVmZXJlbmNlcywgdGhlIHNvdXJjZSBub2RlIGlzIG9ubHkgcmVzb2x2ZWQgYWZ0ZXIgYWxsIG9mXG4gICAgICAvLyBpdHMgY2hpbGQgbm9kZXMgYXJlLiBUaGlzIGlzIHdoeSBhbmNob3JzIGFyZSBzZXQgb25seSBhZnRlciBhbGwgb2YgdGhlXG4gICAgICAvLyBub2RlcyBoYXZlIGJlZW4gY3JlYXRlZC5cbiAgICAgIGFsaWFzLnNvdXJjZSA9IGFsaWFzLnNvdXJjZS5ub2RlO1xuICAgICAgbGV0IG5hbWUgPSB0aGlzLmFuY2hvcnMuZ2V0TmFtZShhbGlhcy5zb3VyY2UpO1xuXG4gICAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgbmFtZSA9IHRoaXMuYW5jaG9ycy5uZXdOYW1lKCk7XG4gICAgICAgIHRoaXMuYW5jaG9ycy5tYXBbbmFtZV0gPSBhbGlhcy5zb3VyY2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG5vZGU7XG4gIH1cblxuICBjcmVhdGVQYWlyKGtleSwgdmFsdWUsIG9wdGlvbnMgPSB7fSkge1xuICAgIGNvbnN0IGsgPSB0aGlzLmNyZWF0ZU5vZGUoa2V5LCBvcHRpb25zKTtcbiAgICBjb25zdCB2ID0gdGhpcy5jcmVhdGVOb2RlKHZhbHVlLCBvcHRpb25zKTtcbiAgICByZXR1cm4gbmV3IFBhaXIoaywgdik7XG4gIH1cblxuICBkZWxldGUoa2V5KSB7XG4gICAgYXNzZXJ0Q29sbGVjdGlvbih0aGlzLmNvbnRlbnRzKTtcbiAgICByZXR1cm4gdGhpcy5jb250ZW50cy5kZWxldGUoa2V5KTtcbiAgfVxuXG4gIGRlbGV0ZUluKHBhdGgpIHtcbiAgICBpZiAoaXNFbXB0eVBhdGgocGF0aCkpIHtcbiAgICAgIGlmICh0aGlzLmNvbnRlbnRzID09IG51bGwpIHJldHVybiBmYWxzZTtcbiAgICAgIHRoaXMuY29udGVudHMgPSBudWxsO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgYXNzZXJ0Q29sbGVjdGlvbih0aGlzLmNvbnRlbnRzKTtcbiAgICByZXR1cm4gdGhpcy5jb250ZW50cy5kZWxldGVJbihwYXRoKTtcbiAgfVxuXG4gIGdldERlZmF1bHRzKCkge1xuICAgIHJldHVybiBEb2N1bWVudC5kZWZhdWx0c1t0aGlzLnZlcnNpb25dIHx8IERvY3VtZW50LmRlZmF1bHRzW3RoaXMub3B0aW9ucy52ZXJzaW9uXSB8fCB7fTtcbiAgfVxuXG4gIGdldChrZXksIGtlZXBTY2FsYXIpIHtcbiAgICByZXR1cm4gdGhpcy5jb250ZW50cyBpbnN0YW5jZW9mIENvbGxlY3Rpb24gPyB0aGlzLmNvbnRlbnRzLmdldChrZXksIGtlZXBTY2FsYXIpIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgZ2V0SW4ocGF0aCwga2VlcFNjYWxhcikge1xuICAgIGlmIChpc0VtcHR5UGF0aChwYXRoKSkgcmV0dXJuICFrZWVwU2NhbGFyICYmIHRoaXMuY29udGVudHMgaW5zdGFuY2VvZiBTY2FsYXIgPyB0aGlzLmNvbnRlbnRzLnZhbHVlIDogdGhpcy5jb250ZW50cztcbiAgICByZXR1cm4gdGhpcy5jb250ZW50cyBpbnN0YW5jZW9mIENvbGxlY3Rpb24gPyB0aGlzLmNvbnRlbnRzLmdldEluKHBhdGgsIGtlZXBTY2FsYXIpIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgaGFzKGtleSkge1xuICAgIHJldHVybiB0aGlzLmNvbnRlbnRzIGluc3RhbmNlb2YgQ29sbGVjdGlvbiA/IHRoaXMuY29udGVudHMuaGFzKGtleSkgOiBmYWxzZTtcbiAgfVxuXG4gIGhhc0luKHBhdGgpIHtcbiAgICBpZiAoaXNFbXB0eVBhdGgocGF0aCkpIHJldHVybiB0aGlzLmNvbnRlbnRzICE9PSB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIHRoaXMuY29udGVudHMgaW5zdGFuY2VvZiBDb2xsZWN0aW9uID8gdGhpcy5jb250ZW50cy5oYXNJbihwYXRoKSA6IGZhbHNlO1xuICB9XG5cbiAgc2V0KGtleSwgdmFsdWUpIHtcbiAgICBpZiAodGhpcy5jb250ZW50cyA9PSBudWxsKSB7XG4gICAgICB0aGlzLnNldFNjaGVtYSgpO1xuICAgICAgdGhpcy5jb250ZW50cyA9IGNvbGxlY3Rpb25Gcm9tUGF0aCh0aGlzLnNjaGVtYSwgW2tleV0sIHZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXNzZXJ0Q29sbGVjdGlvbih0aGlzLmNvbnRlbnRzKTtcbiAgICAgIHRoaXMuY29udGVudHMuc2V0KGtleSwgdmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIHNldEluKHBhdGgsIHZhbHVlKSB7XG4gICAgaWYgKGlzRW1wdHlQYXRoKHBhdGgpKSB0aGlzLmNvbnRlbnRzID0gdmFsdWU7ZWxzZSBpZiAodGhpcy5jb250ZW50cyA9PSBudWxsKSB7XG4gICAgICB0aGlzLnNldFNjaGVtYSgpO1xuICAgICAgdGhpcy5jb250ZW50cyA9IGNvbGxlY3Rpb25Gcm9tUGF0aCh0aGlzLnNjaGVtYSwgcGF0aCwgdmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBhc3NlcnRDb2xsZWN0aW9uKHRoaXMuY29udGVudHMpO1xuICAgICAgdGhpcy5jb250ZW50cy5zZXRJbihwYXRoLCB2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgc2V0U2NoZW1hKGlkLCBjdXN0b21UYWdzKSB7XG4gICAgaWYgKCFpZCAmJiAhY3VzdG9tVGFncyAmJiB0aGlzLnNjaGVtYSkgcmV0dXJuO1xuICAgIGlmICh0eXBlb2YgaWQgPT09ICdudW1iZXInKSBpZCA9IGlkLnRvRml4ZWQoMSk7XG5cbiAgICBpZiAoaWQgPT09ICcxLjAnIHx8IGlkID09PSAnMS4xJyB8fCBpZCA9PT0gJzEuMicpIHtcbiAgICAgIGlmICh0aGlzLnZlcnNpb24pIHRoaXMudmVyc2lvbiA9IGlkO2Vsc2UgdGhpcy5vcHRpb25zLnZlcnNpb24gPSBpZDtcbiAgICAgIGRlbGV0ZSB0aGlzLm9wdGlvbnMuc2NoZW1hO1xuICAgIH0gZWxzZSBpZiAoaWQgJiYgdHlwZW9mIGlkID09PSAnc3RyaW5nJykge1xuICAgICAgdGhpcy5vcHRpb25zLnNjaGVtYSA9IGlkO1xuICAgIH1cblxuICAgIGlmIChBcnJheS5pc0FycmF5KGN1c3RvbVRhZ3MpKSB0aGlzLm9wdGlvbnMuY3VzdG9tVGFncyA9IGN1c3RvbVRhZ3M7XG4gICAgY29uc3Qgb3B0ID0gT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5nZXREZWZhdWx0cygpLCB0aGlzLm9wdGlvbnMpO1xuICAgIHRoaXMuc2NoZW1hID0gbmV3IFNjaGVtYShvcHQpO1xuICB9XG5cbiAgcGFyc2Uobm9kZSwgcHJldkRvYykge1xuICAgIGlmICh0aGlzLm9wdGlvbnMua2VlcENzdE5vZGVzKSB0aGlzLmNzdE5vZGUgPSBub2RlO1xuICAgIGlmICh0aGlzLm9wdGlvbnMua2VlcE5vZGVUeXBlcykgdGhpcy50eXBlID0gJ0RPQ1VNRU5UJztcbiAgICBjb25zdCB7XG4gICAgICBkaXJlY3RpdmVzID0gW10sXG4gICAgICBjb250ZW50cyA9IFtdLFxuICAgICAgZGlyZWN0aXZlc0VuZE1hcmtlcixcbiAgICAgIGVycm9yLFxuICAgICAgdmFsdWVSYW5nZVxuICAgIH0gPSBub2RlO1xuXG4gICAgaWYgKGVycm9yKSB7XG4gICAgICBpZiAoIWVycm9yLnNvdXJjZSkgZXJyb3Iuc291cmNlID0gdGhpcztcbiAgICAgIHRoaXMuZXJyb3JzLnB1c2goZXJyb3IpO1xuICAgIH1cblxuICAgIHBhcnNlRGlyZWN0aXZlcyh0aGlzLCBkaXJlY3RpdmVzLCBwcmV2RG9jKTtcbiAgICBpZiAoZGlyZWN0aXZlc0VuZE1hcmtlcikgdGhpcy5kaXJlY3RpdmVzRW5kTWFya2VyID0gdHJ1ZTtcbiAgICB0aGlzLnJhbmdlID0gdmFsdWVSYW5nZSA/IFt2YWx1ZVJhbmdlLnN0YXJ0LCB2YWx1ZVJhbmdlLmVuZF0gOiBudWxsO1xuICAgIHRoaXMuc2V0U2NoZW1hKCk7XG4gICAgdGhpcy5hbmNob3JzLl9jc3RBbGlhc2VzID0gW107XG4gICAgcGFyc2VDb250ZW50cyh0aGlzLCBjb250ZW50cyk7XG4gICAgdGhpcy5hbmNob3JzLnJlc29sdmVOb2RlcygpO1xuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5wcmV0dHlFcnJvcnMpIHtcbiAgICAgIGZvciAoY29uc3QgZXJyb3Igb2YgdGhpcy5lcnJvcnMpIGlmIChlcnJvciBpbnN0YW5jZW9mIFlBTUxFcnJvcikgZXJyb3IubWFrZVByZXR0eSgpO1xuXG4gICAgICBmb3IgKGNvbnN0IHdhcm4gb2YgdGhpcy53YXJuaW5ncykgaWYgKHdhcm4gaW5zdGFuY2VvZiBZQU1MRXJyb3IpIHdhcm4ubWFrZVByZXR0eSgpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgbGlzdE5vbkRlZmF1bHRUYWdzKCkge1xuICAgIHJldHVybiBsaXN0VGFnTmFtZXModGhpcy5jb250ZW50cykuZmlsdGVyKHQgPT4gdC5pbmRleE9mKGRlZmF1bHRUYWdQcmVmaXgpICE9PSAwKTtcbiAgfVxuXG4gIHNldFRhZ1ByZWZpeChoYW5kbGUsIHByZWZpeCkge1xuICAgIGlmIChoYW5kbGVbMF0gIT09ICchJyB8fCBoYW5kbGVbaGFuZGxlLmxlbmd0aCAtIDFdICE9PSAnIScpIHRocm93IG5ldyBFcnJvcignSGFuZGxlIG11c3Qgc3RhcnQgYW5kIGVuZCB3aXRoICEnKTtcblxuICAgIGlmIChwcmVmaXgpIHtcbiAgICAgIGNvbnN0IHByZXYgPSB0aGlzLnRhZ1ByZWZpeGVzLmZpbmQocCA9PiBwLmhhbmRsZSA9PT0gaGFuZGxlKTtcbiAgICAgIGlmIChwcmV2KSBwcmV2LnByZWZpeCA9IHByZWZpeDtlbHNlIHRoaXMudGFnUHJlZml4ZXMucHVzaCh7XG4gICAgICAgIGhhbmRsZSxcbiAgICAgICAgcHJlZml4XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy50YWdQcmVmaXhlcyA9IHRoaXMudGFnUHJlZml4ZXMuZmlsdGVyKHAgPT4gcC5oYW5kbGUgIT09IGhhbmRsZSk7XG4gICAgfVxuICB9XG5cbiAgdG9KUyh7XG4gICAganNvbixcbiAgICBqc29uQXJnLFxuICAgIG1hcEFzTWFwLFxuICAgIG9uQW5jaG9yLFxuICAgIHJldml2ZXJcbiAgfSA9IHt9KSB7XG4gICAgY29uc3QgYW5jaG9yTm9kZXMgPSBPYmplY3QudmFsdWVzKHRoaXMuYW5jaG9ycy5tYXApLm1hcChub2RlID0+IFtub2RlLCB7XG4gICAgICBhbGlhczogW10sXG4gICAgICBhbGlhc0NvdW50OiAwLFxuICAgICAgY291bnQ6IDFcbiAgICB9XSk7XG4gICAgY29uc3QgYW5jaG9ycyA9IGFuY2hvck5vZGVzLmxlbmd0aCA+IDAgPyBuZXcgTWFwKGFuY2hvck5vZGVzKSA6IG51bGw7XG4gICAgY29uc3QgY3R4ID0ge1xuICAgICAgYW5jaG9ycyxcbiAgICAgIGRvYzogdGhpcyxcbiAgICAgIGluZGVudFN0ZXA6ICcgICcsXG4gICAgICBrZWVwOiAhanNvbixcbiAgICAgIG1hcEFzTWFwOiB0eXBlb2YgbWFwQXNNYXAgPT09ICdib29sZWFuJyA/IG1hcEFzTWFwIDogISF0aGlzLm9wdGlvbnMubWFwQXNNYXAsXG4gICAgICBtYXBLZXlXYXJuZWQ6IGZhbHNlLFxuICAgICAgbWF4QWxpYXNDb3VudDogdGhpcy5vcHRpb25zLm1heEFsaWFzQ291bnQsXG4gICAgICBzdHJpbmdpZnkgLy8gUmVxdWlyaW5nIGRpcmVjdGx5IGluIFBhaXIgd291bGQgY3JlYXRlIGNpcmN1bGFyIGRlcGVuZGVuY2llc1xuXG4gICAgfTtcbiAgICBjb25zdCByZXMgPSB0b0pTKHRoaXMuY29udGVudHMsIGpzb25BcmcgfHwgJycsIGN0eCk7XG4gICAgaWYgKHR5cGVvZiBvbkFuY2hvciA9PT0gJ2Z1bmN0aW9uJyAmJiBhbmNob3JzKSBmb3IgKGNvbnN0IHtcbiAgICAgIGNvdW50LFxuICAgICAgcmVzXG4gICAgfSBvZiBhbmNob3JzLnZhbHVlcygpKSBvbkFuY2hvcihyZXMsIGNvdW50KTtcbiAgICByZXR1cm4gdHlwZW9mIHJldml2ZXIgPT09ICdmdW5jdGlvbicgPyBhcHBseVJldml2ZXIocmV2aXZlciwge1xuICAgICAgJyc6IHJlc1xuICAgIH0sICcnLCByZXMpIDogcmVzO1xuICB9XG5cbiAgdG9KU09OKGpzb25BcmcsIG9uQW5jaG9yKSB7XG4gICAgcmV0dXJuIHRoaXMudG9KUyh7XG4gICAgICBqc29uOiB0cnVlLFxuICAgICAganNvbkFyZyxcbiAgICAgIG1hcEFzTWFwOiBmYWxzZSxcbiAgICAgIG9uQW5jaG9yXG4gICAgfSk7XG4gIH1cblxuICB0b1N0cmluZygpIHtcbiAgICBpZiAodGhpcy5lcnJvcnMubGVuZ3RoID4gMCkgdGhyb3cgbmV3IEVycm9yKCdEb2N1bWVudCB3aXRoIGVycm9ycyBjYW5ub3QgYmUgc3RyaW5naWZpZWQnKTtcbiAgICBjb25zdCBpbmRlbnRTaXplID0gdGhpcy5vcHRpb25zLmluZGVudDtcblxuICAgIGlmICghTnVtYmVyLmlzSW50ZWdlcihpbmRlbnRTaXplKSB8fCBpbmRlbnRTaXplIDw9IDApIHtcbiAgICAgIGNvbnN0IHMgPSBKU09OLnN0cmluZ2lmeShpbmRlbnRTaXplKTtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlxcXCJpbmRlbnRcXFwiIG9wdGlvbiBtdXN0IGJlIGEgcG9zaXRpdmUgaW50ZWdlciwgbm90IFwiLmNvbmNhdChzKSk7XG4gICAgfVxuXG4gICAgdGhpcy5zZXRTY2hlbWEoKTtcbiAgICBjb25zdCBsaW5lcyA9IFtdO1xuICAgIGxldCBoYXNEaXJlY3RpdmVzID0gZmFsc2U7XG5cbiAgICBpZiAodGhpcy52ZXJzaW9uKSB7XG4gICAgICBsZXQgdmQgPSAnJVlBTUwgMS4yJztcblxuICAgICAgaWYgKHRoaXMuc2NoZW1hLm5hbWUgPT09ICd5YW1sLTEuMScpIHtcbiAgICAgICAgaWYgKHRoaXMudmVyc2lvbiA9PT0gJzEuMCcpIHZkID0gJyVZQU1MOjEuMCc7ZWxzZSBpZiAodGhpcy52ZXJzaW9uID09PSAnMS4xJykgdmQgPSAnJVlBTUwgMS4xJztcbiAgICAgIH1cblxuICAgICAgbGluZXMucHVzaCh2ZCk7XG4gICAgICBoYXNEaXJlY3RpdmVzID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBjb25zdCB0YWdOYW1lcyA9IHRoaXMubGlzdE5vbkRlZmF1bHRUYWdzKCk7XG4gICAgdGhpcy50YWdQcmVmaXhlcy5mb3JFYWNoKCh7XG4gICAgICBoYW5kbGUsXG4gICAgICBwcmVmaXhcbiAgICB9KSA9PiB7XG4gICAgICBpZiAodGFnTmFtZXMuc29tZSh0ID0+IHQuaW5kZXhPZihwcmVmaXgpID09PSAwKSkge1xuICAgICAgICBsaW5lcy5wdXNoKFwiJVRBRyBcIi5jb25jYXQoaGFuZGxlLCBcIiBcIikuY29uY2F0KHByZWZpeCkpO1xuICAgICAgICBoYXNEaXJlY3RpdmVzID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBpZiAoaGFzRGlyZWN0aXZlcyB8fCB0aGlzLmRpcmVjdGl2ZXNFbmRNYXJrZXIpIGxpbmVzLnB1c2goJy0tLScpO1xuXG4gICAgaWYgKHRoaXMuY29tbWVudEJlZm9yZSkge1xuICAgICAgaWYgKGhhc0RpcmVjdGl2ZXMgfHwgIXRoaXMuZGlyZWN0aXZlc0VuZE1hcmtlcikgbGluZXMudW5zaGlmdCgnJyk7XG4gICAgICBsaW5lcy51bnNoaWZ0KHRoaXMuY29tbWVudEJlZm9yZS5yZXBsYWNlKC9eL2dtLCAnIycpKTtcbiAgICB9XG5cbiAgICBjb25zdCBjdHggPSB7XG4gICAgICBhbmNob3JzOiBPYmplY3QuY3JlYXRlKG51bGwpLFxuICAgICAgZG9jOiB0aGlzLFxuICAgICAgaW5kZW50OiAnJyxcbiAgICAgIGluZGVudFN0ZXA6ICcgJy5yZXBlYXQoaW5kZW50U2l6ZSksXG4gICAgICBzdHJpbmdpZnkgLy8gUmVxdWlyaW5nIGRpcmVjdGx5IGluIG5vZGVzIHdvdWxkIGNyZWF0ZSBjaXJjdWxhciBkZXBlbmRlbmNpZXNcblxuICAgIH07XG4gICAgbGV0IGNob21wS2VlcCA9IGZhbHNlO1xuICAgIGxldCBjb250ZW50Q29tbWVudCA9IG51bGw7XG5cbiAgICBpZiAodGhpcy5jb250ZW50cykge1xuICAgICAgaWYgKHRoaXMuY29udGVudHMgaW5zdGFuY2VvZiBOb2RlKSB7XG4gICAgICAgIGlmICh0aGlzLmNvbnRlbnRzLnNwYWNlQmVmb3JlICYmIChoYXNEaXJlY3RpdmVzIHx8IHRoaXMuZGlyZWN0aXZlc0VuZE1hcmtlcikpIGxpbmVzLnB1c2goJycpO1xuICAgICAgICBpZiAodGhpcy5jb250ZW50cy5jb21tZW50QmVmb3JlKSBsaW5lcy5wdXNoKHRoaXMuY29udGVudHMuY29tbWVudEJlZm9yZS5yZXBsYWNlKC9eL2dtLCAnIycpKTsgLy8gdG9wLWxldmVsIGJsb2NrIHNjYWxhcnMgbmVlZCB0byBiZSBpbmRlbnRlZCBpZiBmb2xsb3dlZCBieSBhIGNvbW1lbnRcblxuICAgICAgICBjdHguZm9yY2VCbG9ja0luZGVudCA9ICEhdGhpcy5jb21tZW50O1xuICAgICAgICBjb250ZW50Q29tbWVudCA9IHRoaXMuY29udGVudHMuY29tbWVudDtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgb25DaG9tcEtlZXAgPSBjb250ZW50Q29tbWVudCA/IG51bGwgOiAoKSA9PiBjaG9tcEtlZXAgPSB0cnVlO1xuICAgICAgY29uc3QgYm9keSA9IHN0cmluZ2lmeSh0aGlzLmNvbnRlbnRzLCBjdHgsICgpID0+IGNvbnRlbnRDb21tZW50ID0gbnVsbCwgb25DaG9tcEtlZXApO1xuICAgICAgbGluZXMucHVzaChhZGRDb21tZW50KGJvZHksICcnLCBjb250ZW50Q29tbWVudCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsaW5lcy5wdXNoKHN0cmluZ2lmeSh0aGlzLmNvbnRlbnRzLCBjdHgpKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jb21tZW50KSB7XG4gICAgICBpZiAoKCFjaG9tcEtlZXAgfHwgY29udGVudENvbW1lbnQpICYmIGxpbmVzW2xpbmVzLmxlbmd0aCAtIDFdICE9PSAnJykgbGluZXMucHVzaCgnJyk7XG4gICAgICBsaW5lcy5wdXNoKHRoaXMuY29tbWVudC5yZXBsYWNlKC9eL2dtLCAnIycpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbGluZXMuam9pbignXFxuJykgKyAnXFxuJztcbiAgfVxuXG59XG5cbl9kZWZpbmVQcm9wZXJ0eShEb2N1bWVudCwgXCJkZWZhdWx0c1wiLCBkb2N1bWVudE9wdGlvbnMpO1xuXG5leHBvcnQgeyBEb2N1bWVudCB9O1xuIiwiaW1wb3J0IHsgTG9nTGV2ZWwgfSBmcm9tICcuL2NvbnN0YW50cy5qcyc7XG5pbXBvcnQgeyBwYXJzZSBhcyBwYXJzZSQxIH0gZnJvbSAnLi9jc3QvcGFyc2UuanMnO1xuZXhwb3J0IHsgcGFyc2UgYXMgcGFyc2VDU1QgfSBmcm9tICcuL2NzdC9wYXJzZS5qcyc7XG5pbXBvcnQgeyBEb2N1bWVudCB9IGZyb20gJy4vZG9jL0RvY3VtZW50LmpzJztcbmV4cG9ydCB7IERvY3VtZW50IH0gZnJvbSAnLi9kb2MvRG9jdW1lbnQuanMnO1xuaW1wb3J0IHsgWUFNTFNlbWFudGljRXJyb3IgfSBmcm9tICcuL2Vycm9ycy5qcyc7XG5pbXBvcnQgeyB3YXJuIH0gZnJvbSAnLi9sb2cuanMnO1xuZXhwb3J0IHsgZGVmYXVsdE9wdGlvbnMsIHNjYWxhck9wdGlvbnMgfSBmcm9tICcuL29wdGlvbnMuanMnO1xuZXhwb3J0IHsgdmlzaXQgfSBmcm9tICcuL3Zpc2l0LmpzJztcblxuZnVuY3Rpb24gcGFyc2VBbGxEb2N1bWVudHMoc3JjLCBvcHRpb25zKSB7XG4gIGNvbnN0IHN0cmVhbSA9IFtdO1xuICBsZXQgcHJldjtcblxuICBmb3IgKGNvbnN0IGNzdERvYyBvZiBwYXJzZSQxKHNyYykpIHtcbiAgICBjb25zdCBkb2MgPSBuZXcgRG9jdW1lbnQodW5kZWZpbmVkLCBudWxsLCBvcHRpb25zKTtcbiAgICBkb2MucGFyc2UoY3N0RG9jLCBwcmV2KTtcbiAgICBzdHJlYW0ucHVzaChkb2MpO1xuICAgIHByZXYgPSBkb2M7XG4gIH1cblxuICByZXR1cm4gc3RyZWFtO1xufVxuZnVuY3Rpb24gcGFyc2VEb2N1bWVudChzcmMsIG9wdGlvbnMpIHtcbiAgY29uc3QgY3N0ID0gcGFyc2UkMShzcmMpO1xuICBjb25zdCBkb2MgPSBuZXcgRG9jdW1lbnQoY3N0WzBdLCBudWxsLCBvcHRpb25zKTtcblxuICBpZiAoY3N0Lmxlbmd0aCA+IDEgJiYgTG9nTGV2ZWwuaW5kZXhPZihkb2Mub3B0aW9ucy5sb2dMZXZlbCkgPj0gTG9nTGV2ZWwuRVJST1IpIHtcbiAgICBjb25zdCBlcnJNc2cgPSAnU291cmNlIGNvbnRhaW5zIG11bHRpcGxlIGRvY3VtZW50czsgcGxlYXNlIHVzZSBZQU1MLnBhcnNlQWxsRG9jdW1lbnRzKCknO1xuICAgIGRvYy5lcnJvcnMudW5zaGlmdChuZXcgWUFNTFNlbWFudGljRXJyb3IoY3N0WzFdLCBlcnJNc2cpKTtcbiAgfVxuXG4gIHJldHVybiBkb2M7XG59XG5mdW5jdGlvbiBwYXJzZShzcmMsIHJldml2ZXIsIG9wdGlvbnMpIHtcbiAgaWYgKG9wdGlvbnMgPT09IHVuZGVmaW5lZCAmJiByZXZpdmVyICYmIHR5cGVvZiByZXZpdmVyID09PSAnb2JqZWN0Jykge1xuICAgIG9wdGlvbnMgPSByZXZpdmVyO1xuICAgIHJldml2ZXIgPSB1bmRlZmluZWQ7XG4gIH1cblxuICBjb25zdCBkb2MgPSBwYXJzZURvY3VtZW50KHNyYywgb3B0aW9ucyk7XG4gIGRvYy53YXJuaW5ncy5mb3JFYWNoKHdhcm5pbmcgPT4gd2Fybihkb2Mub3B0aW9ucy5sb2dMZXZlbCwgd2FybmluZykpO1xuXG4gIGlmIChkb2MuZXJyb3JzLmxlbmd0aCA+IDApIHtcbiAgICBpZiAoTG9nTGV2ZWwuaW5kZXhPZihkb2Mub3B0aW9ucy5sb2dMZXZlbCkgPj0gTG9nTGV2ZWwuRVJST1IpIHRocm93IGRvYy5lcnJvcnNbMF07ZWxzZSBkb2MuZXJyb3JzID0gW107XG4gIH1cblxuICByZXR1cm4gZG9jLnRvSlMoe1xuICAgIHJldml2ZXJcbiAgfSk7XG59XG5mdW5jdGlvbiBzdHJpbmdpZnkodmFsdWUsIHJlcGxhY2VyLCBvcHRpb25zKSB7XG4gIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ3N0cmluZycpIG9wdGlvbnMgPSBvcHRpb25zLmxlbmd0aDtcblxuICBpZiAodHlwZW9mIG9wdGlvbnMgPT09ICdudW1iZXInKSB7XG4gICAgY29uc3QgaW5kZW50ID0gTWF0aC5yb3VuZChvcHRpb25zKTtcbiAgICBvcHRpb25zID0gaW5kZW50IDwgMSA/IHVuZGVmaW5lZCA6IGluZGVudCA+IDggPyB7XG4gICAgICBpbmRlbnQ6IDhcbiAgICB9IDoge1xuICAgICAgaW5kZW50XG4gICAgfTtcbiAgfVxuXG4gIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgY29uc3Qge1xuICAgICAga2VlcFVuZGVmaW5lZFxuICAgIH0gPSBvcHRpb25zIHx8IHJlcGxhY2VyIHx8IHt9O1xuICAgIGlmICgha2VlcFVuZGVmaW5lZCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHJldHVybiBuZXcgRG9jdW1lbnQodmFsdWUsIHJlcGxhY2VyLCBvcHRpb25zKS50b1N0cmluZygpO1xufVxuXG5leHBvcnQgeyBwYXJzZSwgcGFyc2VBbGxEb2N1bWVudHMsIHBhcnNlRG9jdW1lbnQsIHN0cmluZ2lmeSB9O1xuIiwiaW1wb3J0IHsgTm90aWNlIH0gZnJvbSBcIm9ic2lkaWFuXCI7XG5pbXBvcnQgeyBwYXJzZURvY3VtZW50IH0gZnJvbSBcInlhbWxcIjtcbmltcG9ydCB7IFJlcGxhY2VtZW50IH0gZnJvbSBcIi4vVGFnXCI7XG5cbmV4cG9ydCBjbGFzcyBGaWxlIHtcblxuICAgIGNvbnN0cnVjdG9yKGFwcCwgZmlsZW5hbWUsIHRhZ1Bvc2l0aW9ucywgaGFzRnJvbnRNYXR0ZXIpIHtcbiAgICAgICAgdGhpcy5hcHAgPSBhcHA7XG4gICAgICAgIHRoaXMuZmlsZW5hbWUgPSBmaWxlbmFtZTtcbiAgICAgICAgdGhpcy5iYXNlbmFtZSA9IGZpbGVuYW1lLnNwbGl0KFwiL1wiKS5wb3AoKTtcbiAgICAgICAgdGhpcy50YWdQb3NpdGlvbnMgPSB0YWdQb3NpdGlvbnM7XG4gICAgICAgIHRoaXMuaGFzRnJvbnRNYXR0ZXIgPSAhIWhhc0Zyb250TWF0dGVyO1xuICAgIH1cblxuICAgIC8qKiBAcGFyYW0ge1JlcGxhY2VtZW50fSByZXBsYWNlICovXG4gICAgYXN5bmMgcmVuYW1lZChyZXBsYWNlKSB7XG4gICAgICAgIGNvbnN0IGZpbGUgPSB0aGlzLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgodGhpcy5maWxlbmFtZSk7XG4gICAgICAgIGNvbnN0IG9yaWdpbmFsID0gYXdhaXQgdGhpcy5hcHAudmF1bHQucmVhZChmaWxlKTtcbiAgICAgICAgbGV0IHRleHQgPSBvcmlnaW5hbDtcblxuICAgICAgICBmb3IgKGNvbnN0IHsgcG9zaXRpb246IHsgc3RhcnQsIGVuZCB9LCB0YWcgfSBvZiB0aGlzLnRhZ1Bvc2l0aW9ucykge1xuICAgICAgICAgICAgaWYgKHRleHQuc2xpY2Uoc3RhcnQub2Zmc2V0LCBlbmQub2Zmc2V0KSAhPT0gdGFnKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbXNnID0gYEZpbGUgJHt0aGlzLmZpbGVuYW1lfSBoYXMgY2hhbmdlZDsgc2tpcHBpbmdgO1xuICAgICAgICAgICAgICAgIG5ldyBOb3RpY2UobXNnKTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKG1zZyk7XG4gICAgICAgICAgICAgICAgY29uc29sZS5kZWJ1Zyh0ZXh0LnNsaWNlKHN0YXJ0Lm9mZnNldCwgZW5kLm9mZnNldCksIHRhZyk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGV4dCA9IHJlcGxhY2UuaW5TdHJpbmcodGV4dCwgc3RhcnQub2Zmc2V0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmhhc0Zyb250TWF0dGVyKVxuICAgICAgICAgICAgdGV4dCA9IHRoaXMucmVwbGFjZUluRnJvbnRNYXR0ZXIodGV4dCwgcmVwbGFjZSk7XG5cbiAgICAgICAgaWYgKHRleHQgIT09IG9yaWdpbmFsKSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmFwcC52YXVsdC5tb2RpZnkoZmlsZSwgdGV4dCk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBAcGFyYW0ge1JlcGxhY2VtZW50fSByZXBsYWNlICovXG4gICAgcmVwbGFjZUluRnJvbnRNYXR0ZXIodGV4dCwgcmVwbGFjZSkge1xuICAgICAgICBjb25zdCBbZW1wdHksIGZyb250TWF0dGVyXSA9IHRleHQuc3BsaXQoL14tLS1cXHI/JFxcbj8vbSwgMik7XG5cbiAgICAgICAgLy8gQ2hlY2sgZm9yIHZhbGlkLCBub24tZW1wdHksIHByb3Blcmx5IHRlcm1pbmF0ZWQgZnJvbnQgbWF0dGVyXG4gICAgICAgIGlmIChlbXB0eS50cmltKCkgIT09IFwiXCIgfHwgIWZyb250TWF0dGVyLnRyaW0oKSB8fCAhZnJvbnRNYXR0ZXIuZW5kc1dpdGgoXCJcXG5cIikpXG4gICAgICAgICAgICByZXR1cm4gdGV4dDtcblxuICAgICAgICBjb25zdCBwYXJzZWQgPSBwYXJzZURvY3VtZW50KGZyb250TWF0dGVyKTtcbiAgICAgICAgaWYgKHBhcnNlZC5lcnJvcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICBjb25zdCBlcnJvciA9IGBZQU1MIGlzc3VlIHdpdGggJHt0aGlzLmZpbGVuYW1lfTogJHtwYXJzZWQuZXJyb3JzWzBdfWA7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTsgbmV3IE5vdGljZShlcnJvciArIFwiOyBza2lwcGluZyBmcm9udG1hdHRlclwiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBjaGFuZ2VkID0gZmFsc2U7XG4gICAgICAgIGZvciAoY29uc3Qge2tleToge3ZhbHVlOnByb3B9fSBvZiBwYXJzZWQuY29udGVudHMuaXRlbXMpIHtcbiAgICAgICAgICAgIGlmICghL150YWdzPyQvaS50ZXN0KHByb3ApKSBjb250aW51ZTtcbiAgICAgICAgICAgIGNvbnN0IG5vZGUgPSBwYXJzZWQuZ2V0KHByb3AsIHRydWUpO1xuICAgICAgICAgICAgaWYgKCFub2RlKSBjb250aW51ZTtcbiAgICAgICAgICAgIGNvbnN0IGZpZWxkID0gbm9kZS50b0pTT04oKTtcbiAgICAgICAgICAgIGlmICghZmllbGQgfHwgIWZpZWxkLmxlbmd0aCkgY29udGludWU7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGZpZWxkID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcGFydHMgPSBmaWVsZC5zcGxpdCgvKFtcXHMsXSspLyk7XG4gICAgICAgICAgICAgICAgY29uc3QgYWZ0ZXIgPSByZXBsYWNlLmluQXJyYXkocGFydHMsIHRydWUpLmpvaW4oXCJcIik7XG4gICAgICAgICAgICAgICAgaWYgKGZpZWxkICE9IGFmdGVyKSB7IHBhcnNlZC5zZXQocHJvcCwgYWZ0ZXIpOyBjaGFuZ2VkID0gdHJ1ZTsgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KGZpZWxkKSkge1xuICAgICAgICAgICAgICAgIHJlcGxhY2UuaW5BcnJheShmaWVsZCkuZm9yRWFjaCgodiwgaSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZmllbGRbaV0gIT09IHYpXG4gICAgICAgICAgICAgICAgICAgICAgICBub2RlLnNldChpLCB2KTsgY2hhbmdlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNoYW5nZWQgPyB0ZXh0LnJlcGxhY2UoZnJvbnRNYXR0ZXIsIHBhcnNlZC50b1N0cmluZygpKSA6IHRleHQ7XG4gICAgfVxufVxuIiwiaW1wb3J0IHtjb25maXJtfSBmcm9tIFwic21hbGx0YWxrXCI7XG5pbXBvcnQge1Byb2dyZXNzfSBmcm9tIFwiLi9wcm9ncmVzc1wiO1xuaW1wb3J0IHt2YWxpZGF0ZWRJbnB1dH0gZnJvbSBcIi4vdmFsaWRhdGlvblwiO1xuaW1wb3J0IHtOb3RpY2UsIHBhcnNlRnJvbnRNYXR0ZXJUYWdzfSBmcm9tIFwib2JzaWRpYW5cIjtcbmltcG9ydCB7VGFnLCBSZXBsYWNlbWVudH0gZnJvbSBcIi4vVGFnXCI7XG5pbXBvcnQge0ZpbGV9IGZyb20gXCIuL0ZpbGVcIjtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlbmFtZVRhZyhhcHAsIHRhZ05hbWUpIHtcbiAgICBjb25zdCBuZXdOYW1lID0gYXdhaXQgcHJvbXB0Rm9yTmV3TmFtZSh0YWdOYW1lKTtcbiAgICBpZiAobmV3TmFtZSA9PT0gZmFsc2UpIHJldHVybjsgIC8vIGFib3J0ZWRcblxuICAgIGlmICghbmV3TmFtZSB8fCBuZXdOYW1lID09PSB0YWdOYW1lKSB7XG4gICAgICAgIHJldHVybiBuZXcgTm90aWNlKFwiVW5jaGFuZ2VkIG9yIGVtcHR5IHRhZzogTm8gY2hhbmdlcyBtYWRlLlwiKTtcbiAgICB9XG5cbiAgICBjb25zdFxuICAgICAgICBvbGRUYWcgID0gbmV3IFRhZyh0YWdOYW1lKSxcbiAgICAgICAgbmV3VGFnICA9IG5ldyBUYWcobmV3TmFtZSksXG4gICAgICAgIHJlcGxhY2UgPSBuZXcgUmVwbGFjZW1lbnQob2xkVGFnLCBuZXdUYWcpLFxuICAgICAgICBjbGFzaGluZyA9IHJlcGxhY2Uud2lsbE1lcmdlVGFncyhcbiAgICAgICAgICAgIGFsbFRhZ3MoYXBwKS5yZXZlcnNlKCkgICAvLyBmaW5kIGxvbmdlc3QgY2xhc2ggZmlyc3RcbiAgICAgICAgKSxcbiAgICAgICAgc2hvdWxkQWJvcnQgPSBjbGFzaGluZyAmJlxuICAgICAgICAgICAgYXdhaXQgc2hvdWxkQWJvcnREdWVUb0NsYXNoKGNsYXNoaW5nLCBvbGRUYWcsIG5ld1RhZylcbiAgICAgICAgO1xuXG4gICAgaWYgKHNob3VsZEFib3J0KSByZXR1cm47XG5cbiAgICBjb25zdCB0YXJnZXRzID0gYXdhaXQgZmluZFRhcmdldHMoYXBwLCBvbGRUYWcpO1xuICAgIGlmICghdGFyZ2V0cykgcmV0dXJuO1xuXG4gICAgY29uc3QgcHJvZ3Jlc3MgPSBuZXcgUHJvZ3Jlc3MoYFJlbmFtaW5nIHRvICMke25ld05hbWV9LypgLCBcIlByb2Nlc3NpbmcgZmlsZXMuLi5cIik7XG4gICAgbGV0IHJlbmFtZWQgPSAwO1xuICAgIGF3YWl0IHByb2dyZXNzLmZvckVhY2godGFyZ2V0cywgYXN5bmMgKHRhcmdldCkgPT4ge1xuICAgICAgICBwcm9ncmVzcy5tZXNzYWdlID0gXCJQcm9jZXNzaW5nIFwiICsgdGFyZ2V0LmJhc2VuYW1lO1xuICAgICAgICBpZiAoYXdhaXQgdGFyZ2V0LnJlbmFtZWQocmVwbGFjZSkpIHJlbmFtZWQrKztcbiAgICB9KTtcblxuICAgIHJldHVybiBuZXcgTm90aWNlKGBPcGVyYXRpb24gJHtwcm9ncmVzcy5hYm9ydGVkID8gXCJjYW5jZWxsZWRcIiA6IFwiY29tcGxldGVcIn06ICR7cmVuYW1lZH0gZmlsZShzKSB1cGRhdGVkYCk7XG59XG5cbmZ1bmN0aW9uIGFsbFRhZ3MoYXBwKSB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKGFwcC5tZXRhZGF0YUNhY2hlLmdldFRhZ3MoKSk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBmaW5kVGFyZ2V0cyhhcHAsIHRhZykge1xuICAgIGNvbnN0IHRhcmdldHMgPSBbXTtcbiAgICBjb25zdCBwcm9ncmVzcyA9IG5ldyBQcm9ncmVzcyhgU2VhcmNoaW5nIGZvciAke3RhZ30vKmAsIFwiTWF0Y2hpbmcgZmlsZXMuLi5cIik7XG4gICAgYXdhaXQgcHJvZ3Jlc3MuZm9yRWFjaChcbiAgICAgICAgYXBwLm1ldGFkYXRhQ2FjaGUuZ2V0Q2FjaGVkRmlsZXMoKSxcbiAgICAgICAgZmlsZW5hbWUgPT4ge1xuICAgICAgICAgICAgbGV0IHsgZnJvbnRtYXR0ZXIsIHRhZ3MgfSA9IGFwcC5tZXRhZGF0YUNhY2hlLmdldENhY2hlKGZpbGVuYW1lKSB8fCB7fTtcbiAgICAgICAgICAgIHRhZ3MgPSAodGFncyB8fCBbXSkuZmlsdGVyKHQgPT4gdC50YWcgJiYgdGFnLm1hdGNoZXModC50YWcpKS5yZXZlcnNlKCk7IC8vIGxhc3QgcG9zaXRpb25zIGZpcnN0XG4gICAgICAgICAgICBjb25zdCBmbXRhZ3MgPSAocGFyc2VGcm9udE1hdHRlclRhZ3MoZnJvbnRtYXR0ZXIpIHx8IFtdKS5maWx0ZXIodGFnLm1hdGNoZXMpO1xuICAgICAgICAgICAgaWYgKHRhZ3MubGVuZ3RoIHx8IGZtdGFncy5sZW5ndGgpXG4gICAgICAgICAgICAgICAgdGFyZ2V0cy5wdXNoKG5ldyBGaWxlKGFwcCwgZmlsZW5hbWUsIHRhZ3MsIGZtdGFncy5sZW5ndGgpKTtcbiAgICAgICAgfVxuICAgICk7XG4gICAgaWYgKCFwcm9ncmVzcy5hYm9ydGVkKVxuICAgICAgICByZXR1cm4gdGFyZ2V0cztcbn1cblxuYXN5bmMgZnVuY3Rpb24gcHJvbXB0Rm9yTmV3TmFtZSh0YWdOYW1lKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHZhbGlkYXRlZElucHV0KFxuICAgICAgICAgICAgYFJlbmFtaW5nICMke3RhZ05hbWV9IChhbmQgYW55IHN1Yi10YWdzKWAsIFwiRW50ZXIgbmV3IG5hbWUgKG11c3QgYmUgYSB2YWxpZCBPYnNpZGlhbiB0YWcpOlxcblwiLFxuICAgICAgICAgICAgdGFnTmFtZSxcbiAgICAgICAgICAgIFwiW15cXHUyMDAwLVxcdTIwNkZcXHUyRTAwLVxcdTJFN0YnIVxcXCIjJCUmKCkqKywuOjs8PT4/QF5ge3x9flxcXFxbXFxcXF1cXFxcXFxcXFxcXFxzXStcIixcbiAgICAgICAgICAgIFwiT2JzaWRpYW4gdGFnIG5hbWVcIlxuICAgICAgICApO1xuICAgIH0gY2F0Y2goZSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7ICAvLyB1c2VyIGNhbmNlbGxlZFxuICAgIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gc2hvdWxkQWJvcnREdWVUb0NsYXNoKFtvcmlnaW4sIGNsYXNoXSwgb2xkVGFnLCBuZXdUYWcpIHtcbiAgICB0cnkge1xuICAgICAgICBhd2FpdCBjb25maXJtKFxuICAgICAgICAgICAgXCJXQVJOSU5HOiBObyBVbmRvIVwiLFxuICAgICAgICAgICAgYFJlbmFtaW5nIDxjb2RlPiR7b2xkVGFnfTwvY29kZT4gdG8gPGNvZGU+JHtuZXdUYWd9PC9jb2RlPiB3aWxsIG1lcmdlICR7XG4gICAgICAgICAgICAgICAgKG9yaWdpbi5jYW5vbmljYWwgPT09IG9sZFRhZy5jYW5vbmljYWwpID9cbiAgICAgICAgICAgICAgICAgICAgYHRoZXNlIHRhZ3NgIDogYG11bHRpcGxlIHRhZ3NcbiAgICAgICAgICAgICAgICAgICAgaW50byBleGlzdGluZyB0YWdzIChzdWNoIGFzIDxjb2RlPiR7b3JpZ2lufTwvY29kZT5cbiAgICAgICAgICAgICAgICAgICAgbWVyZ2luZyB3aXRoIDxjb2RlPiR7Y2xhc2h9PC9jb2RlPilgXG4gICAgICAgICAgICB9LlxuXG4gICAgICAgICAgICBUaGlzIDxiPmNhbm5vdDwvYj4gYmUgdW5kb25lLiAgRG8geW91IHdpc2ggdG8gcHJvY2VlZD9gXG4gICAgICAgICk7XG4gICAgfSBjYXRjaChlKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbn1cbiIsImltcG9ydCB7TWVudSwgTm90aWNlLCBQbHVnaW4sIFNjb3BlfSBmcm9tIFwib2JzaWRpYW5cIjtcbmltcG9ydCB7cmVuYW1lVGFnLCBmaW5kVGFyZ2V0c30gZnJvbSBcIi4vcmVuYW1pbmdcIjtcbmltcG9ydCB7VGFnfSBmcm9tIFwiLi9UYWdcIjtcblxuZnVuY3Rpb24gb25FbGVtZW50KGVsLCBldmVudCwgc2VsZWN0b3IsIGNhbGxiYWNrLCBvcHRpb25zKSB7XG4gICAgZWwub24oZXZlbnQsIHNlbGVjdG9yLCBjYWxsYmFjaywgb3B0aW9ucylcbiAgICByZXR1cm4gKCkgPT4gZWwub2ZmKGV2ZW50LCBzZWxlY3RvciwgY2FsbGJhY2ssIG9wdGlvbnMpO1xufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBUYWdXcmFuZ2xlciBleHRlbmRzIFBsdWdpbiB7XG4gICAgb25sb2FkKCl7XG4gICAgICAgIHRoaXMucmVnaXN0ZXIoXG4gICAgICAgICAgICBvbkVsZW1lbnQoZG9jdW1lbnQsIFwiY29udGV4dG1lbnVcIiwgXCIudGFnLXBhbmUtdGFnXCIsIHRoaXMub25NZW51LmJpbmQodGhpcyksIHtjYXB0dXJlOiB0cnVlfSlcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBvbk1lbnUoZSwgdGFnRWwpIHtcbiAgICAgICAgaWYgKCFlLm9ic2lkaWFuX2NvbnRleHRtZW51KSB7XG4gICAgICAgICAgICBlLm9ic2lkaWFuX2NvbnRleHRtZW51ID0gbmV3IE1lbnUodGhpcy5hcHApO1xuICAgICAgICAgICAgc2V0SW1tZWRpYXRlKCgpID0+IG1lbnUuc2hvd0F0UG9zaXRpb24oe3g6IGUucGFnZVgsIHk6IGUucGFnZVl9KSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdFxuICAgICAgICAgICAgdGFnTmFtZSA9IHRhZ0VsLmZpbmQoXCIudGFnLXBhbmUtdGFnLXRleHRcIikudGV4dENvbnRlbnQsXG4gICAgICAgICAgICBpc0hpZXJhcmNoeSA9IHRhZ0VsLnBhcmVudEVsZW1lbnQucGFyZW50RWxlbWVudC5maW5kKFwiLmNvbGxhcHNlLWljb25cIiksXG4gICAgICAgICAgICBzZWFyY2hQbHVnaW4gPSB0aGlzLmFwcC5pbnRlcm5hbFBsdWdpbnMuZ2V0UGx1Z2luQnlJZChcImdsb2JhbC1zZWFyY2hcIiksXG4gICAgICAgICAgICBzZWFyY2ggPSBzZWFyY2hQbHVnaW4gJiYgc2VhcmNoUGx1Z2luLmluc3RhbmNlLFxuICAgICAgICAgICAgcXVlcnkgPSBzZWFyY2ggJiYgc2VhcmNoLmdldEdsb2JhbFNlYXJjaFF1ZXJ5KCksXG4gICAgICAgICAgICByYW5kb20gPSB0aGlzLmFwcC5wbHVnaW5zLnBsdWdpbnNbXCJzbWFydC1yYW5kb20tbm90ZVwiXSxcbiAgICAgICAgICAgIG1lbnUgPSBlLm9ic2lkaWFuX2NvbnRleHRtZW51LmFkZEl0ZW0oaXRlbShcInBlbmNpbFwiLCBcIlJlbmFtZSAjXCIrdGFnTmFtZSwgKCkgPT4gdGhpcy5yZW5hbWUodGFnTmFtZSkpKTtcblxuICAgICAgICBtZW51LnJlZ2lzdGVyKFxuICAgICAgICAgICAgb25FbGVtZW50KGRvY3VtZW50LCBcImtleWRvd25cIiwgXCIqXCIsIGUgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChlLmtleT09PVwiRXNjYXBlXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgICAgICAgICBtZW51LmhpZGUoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LCB7Y2FwdHVyZTogdHJ1ZX0pXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKHNlYXJjaCkge1xuICAgICAgICAgICAgbWVudS5hZGRTZXBhcmF0b3IoKS5hZGRJdGVtKFxuICAgICAgICAgICAgICAgIGl0ZW0oXCJtYWduaWZ5aW5nLWdsYXNzXCIsIFwiTmV3IHNlYXJjaCBmb3IgI1wiK3RhZ05hbWUsICgpID0+IHNlYXJjaC5vcGVuR2xvYmFsU2VhcmNoKFwidGFnOlwiICsgdGFnTmFtZSkpXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKHF1ZXJ5KSB7XG4gICAgICAgICAgICAgICAgbWVudS5hZGRJdGVtKFxuICAgICAgICAgICAgICAgICAgICBpdGVtKFwic2hlZXRzLWluLWJveFwiLCBcIlJlcXVpcmUgI1wiK3RhZ05hbWUrXCIgaW4gc2VhcmNoXCIgICwgKCkgPT4gc2VhcmNoLm9wZW5HbG9iYWxTZWFyY2gocXVlcnkrXCIgdGFnOlwiICArIHRhZ05hbWUpKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBtZW51LmFkZEl0ZW0oXG4gICAgICAgICAgICAgICAgaXRlbShcImNyb3NzZWQtc3RhclwiICwgXCJFeGNsdWRlICNcIit0YWdOYW1lK1wiIGZyb20gc2VhcmNoXCIsICgpID0+IHNlYXJjaC5vcGVuR2xvYmFsU2VhcmNoKHF1ZXJ5K1wiIC10YWc6XCIgKyB0YWdOYW1lKSlcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocmFuZG9tKSB7XG4gICAgICAgICAgICBtZW51LmFkZFNlcGFyYXRvcigpLmFkZEl0ZW0oXG4gICAgICAgICAgICAgICAgaXRlbShcImRpY2VcIiwgXCJPcGVuIHJhbmRvbSBub3RlXCIsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdGFyZ2V0cyA9IGF3YWl0IGZpbmRUYXJnZXRzKHRoaXMuYXBwLCBuZXcgVGFnKHRhZ05hbWUpKTtcbiAgICAgICAgICAgICAgICAgICAgcmFuZG9tLm9wZW5SYW5kb21Ob3RlKHRhcmdldHMubWFwKGY9PmYuZmlsZW5hbWUpKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuYXBwLndvcmtzcGFjZS50cmlnZ2VyKFwidGFnLXdyYW5nbGVyOmNvbnRleHRtZW51XCIsIG1lbnUsIHRhZ05hbWUsIHtzZWFyY2gsIHF1ZXJ5LCBpc0hpZXJhcmNoeX0pO1xuXG4gICAgICAgIGlmIChpc0hpZXJhcmNoeSkge1xuICAgICAgICAgICAgY29uc3RcbiAgICAgICAgICAgICAgICB0YWdQYXJlbnQgPSB0YWdOYW1lLnNwbGl0KFwiL1wiKS5zbGljZSgwLCAtMSkuam9pbihcIi9cIiksXG4gICAgICAgICAgICAgICAgdGFnVmlldyA9IHRoaXMubGVhZlZpZXcodGFnRWwubWF0Y2hQYXJlbnQoXCIud29ya3NwYWNlLWxlYWZcIikpLFxuICAgICAgICAgICAgICAgIHRhZ0NvbnRhaW5lciA9IHRhZ1BhcmVudCA/IHRhZ1ZpZXcudGFnRG9tc1tcIiNcIiArIHRhZ1BhcmVudC50b0xvd2VyQ2FzZSgpXTogdGFnVmlldy5yb290XG4gICAgICAgICAgICA7XG4gICAgICAgICAgICBmdW5jdGlvbiB0b2dnbGUoY29sbGFwc2UpIHtcbiAgICAgICAgICAgICAgICBmb3IoY29uc3QgdGFnIG9mIHRhZ0NvbnRhaW5lci5jaGlsZHJlbikgdGFnLnNldENvbGxhcHNlZChjb2xsYXBzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBtZW51LmFkZFNlcGFyYXRvcigpXG4gICAgICAgICAgICAuYWRkSXRlbShpdGVtKFwidmVydGljYWwtdGhyZWUtZG90c1wiLCBcIkNvbGxhcHNlIHRhZ3MgYXQgdGhpcyBsZXZlbFwiLCAoKSA9PiB0b2dnbGUodHJ1ZSApKSlcbiAgICAgICAgICAgIC5hZGRJdGVtKGl0ZW0oXCJleHBhbmQtdmVydGljYWxseVwiICAsIFwiRXhwYW5kIHRhZ3MgYXQgdGhpcyBsZXZlbFwiICAsICgpID0+IHRvZ2dsZShmYWxzZSkpKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgbGVhZlZpZXcoY29udGFpbmVyRWwpIHtcbiAgICAgICAgbGV0IHZpZXc7XG4gICAgICAgIHRoaXMuYXBwLndvcmtzcGFjZS5pdGVyYXRlQWxsTGVhdmVzKChsZWFmKSA9PiB7XG4gICAgICAgICAgICBpZiAobGVhZi5jb250YWluZXJFbCA9PT0gY29udGFpbmVyRWwpIHsgdmlldyA9IGxlYWYudmlldzsgcmV0dXJuIHRydWU7IH1cbiAgICAgICAgfSlcbiAgICAgICAgcmV0dXJuIHZpZXc7XG4gICAgfVxuXG5cbiAgICBhc3luYyByZW5hbWUodGFnTmFtZSkge1xuICAgICAgICBjb25zdCBzY29wZSA9IG5ldyBTY29wZTtcbiAgICAgICAgdGhpcy5hcHAua2V5bWFwLnB1c2hTY29wZShzY29wZSk7XG4gICAgICAgIHRyeSB7IGF3YWl0IHJlbmFtZVRhZyh0aGlzLmFwcCwgdGFnTmFtZSk7IH1cbiAgICAgICAgY2F0Y2ggKGUpIHsgY29uc29sZS5lcnJvcihlKTsgbmV3IE5vdGljZShcImVycm9yOiBcIiArIGUpOyB9XG4gICAgICAgIHRoaXMuYXBwLmtleW1hcC5wb3BTY29wZShzY29wZSk7XG4gICAgfVxuXG59XG5cbmZ1bmN0aW9uIGl0ZW0oaWNvbiwgdGl0bGUsIGNsaWNrKSB7XG4gICAgcmV0dXJuIGkgPT4gaS5zZXRJY29uKGljb24pLnNldFRpdGxlKHRpdGxlKS5vbkNsaWNrKGNsaWNrKTtcbn1cblxuIl0sIm5hbWVzIjpbImN1cnJpZnkiLCJzdG9yZSIsInF1ZXJ5IiwiTm90aWNlIiwiTm9kZSIsIkNvbGxlY3Rpb24iLCJBbGlhcyIsImludElkZW50aWZ5Iiwic2V0IiwiaW50UmVzb2x2ZSIsImludFN0cmluZ2lmeSIsIkRvY3VtZW50IiwiRG9jdW1lbnQkMSIsInBhcnNlJDEiLCJwYXJzZUZyb250TWF0dGVyVGFncyIsIlBsdWdpbiIsIk1lbnUiLCJTY29wZSJdLCJtYXBwaW5ncyI6Ijs7OztBQUVBLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxLQUFLO0FBQ2xCO0FBQ0EsSUFBSSxVQUFVLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQztBQUMzQyxJQUFJLFVBQVUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDLEdBQUcsU0FBUyxDQUFDLENBQUMsQ0FBQztBQUM5QyxJQUFJLFVBQVUsQ0FBQyxFQUFF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QUFFLE9BQU87QUFDVCxJQUFJLElBQUk7QUFDUixJQUFJLEdBQUcsRUFBRSxNQUFNLEdBQUcsVUFBVSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDO0FBQzFDLEdBQUcsQ0FBQztBQUNKLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUyxPQUFPLENBQUMsSUFBSSxFQUFFLEdBQUcsRUFBRTtBQUM1QixFQUFFLE1BQU07QUFDUixJQUFJLFVBQVU7QUFDZCxJQUFJLEdBQUc7QUFDUCxHQUFHLEdBQUcsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3RCLEVBQUUsSUFBSSxDQUFDLFVBQVUsSUFBSSxFQUFFLElBQUksSUFBSSxDQUFDLENBQUMsSUFBSSxJQUFJLEdBQUcsVUFBVSxDQUFDLE1BQU0sRUFBRSxPQUFPLElBQUksQ0FBQztBQUMzRSxFQUFFLE1BQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDckMsRUFBRSxJQUFJLEdBQUcsR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDN0I7QUFDQSxFQUFFLE9BQU8sR0FBRyxJQUFJLEdBQUcsR0FBRyxLQUFLLElBQUksR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsS0FBSyxJQUFJLEVBQUUsRUFBRSxHQUFHLENBQUM7QUFDNUQ7QUFDQSxFQUFFLE9BQU8sR0FBRyxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDL0IsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTLGdCQUFnQixDQUFDO0FBQzFCLEVBQUUsS0FBSztBQUNQLEVBQUUsR0FBRztBQUNMLENBQUMsRUFBRSxHQUFHLEVBQUUsUUFBUSxHQUFHLEVBQUUs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QUksU0FBUyxHQUFHLE1BQU0sQ0FBQyxFQUFFLElBQUksQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFO0FBQ2pHLE1BQU0sSUFBSSxDQUFDLElBQUksR0FBRyxTQUFTLENBQUM7QUFDNUIsUUFBUSxXQUFXO0FBQ25CLFFBQVEsWUFBWSxFQUFFLEtBQUs7QUFDM0IsUUFBUSxNQUFNO0FBQ2QsUUFBUSxTQUFTO0FBQ2pCLFFBQVEsTUFBTSxFQUFFLElBQUk7QUFDcEIsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQ2pCLEtBQUssTUFBTSxJQUFJLEVBQUUsSUFBSSxTQUFTLEdBQUcsS0FBSyxHQUFHLENBQUMsRUFBRTtBQUM1QyxNQUFNLE1BQU0sR0FBRyxTQUFTLEdBQUcsQ0FBQyxDQUFDO0FBQzdCLEtBQUs7QUFDTDtBQUNBLElBQUksSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFO0FBQ25CLE1BQU0sSUFBSSxTQUFTLEVBQUU7QUFDckI7QUFDQTtBQUNBO0FBQ0EsUUFBUSxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssSUFBSSxPQUFPLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQztBQUN0RSxRQUFRLElBQUksS0FBSyxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDekMsT0FBTztBQUNQO0FBQ0EsTUFBTSxJQUFJLFFBQVEsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLENBQUM7QUFDNUUsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDO0FBQ25DLEtBQUssTUFBTTtBQUNYLE1BQU0sSUFBSSxhQUFhLEVBQUU7QUFDekIsUUFBUSxNQUFNLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDOUIsUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUks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LENBQUM7QUFDbEU7QUFDQSxJQUFJLEtBQUssSUFBSSxDQUFDLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUU7QUFDMUQsTUFBTSxJQUFJLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFO0FBQ2xFO0FBQ0EsUUFBUSxJQUFJLENBQUMsS0FBSyxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDckQsUUFBUSxTQUFTLENBQUMsS0FBSyxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUN2RCxRQUFRLE1BQU0sU0FBUyxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksU0FBUyxDQUFDLFVBQVUsQ0FBQztBQUNyRSxRQUFRLFNBQVMsQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUM7QUFDaEQsUUFBUSxNQUFNO0FBQ2QsT0FBTztBQUNQLEtBQUs7QUFDTDtBQUNBLElBQUksSUFBSSxDQUFDLEtBQUssR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQzdCLElBQUksTUFBTSxFQUFFLEdBQUcseUJBQXlCLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDcEQsSUFBSSxJQUFJLEVBQUUsRUFBRSxLQUFLLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztBQUN2RCxHQUFHO0FBQ0g7QUFDQSxFQUFFLElBQUkscUJBQXFCLEdBQUc7QUFDOUIsSUFBSSxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztBQUNqQyxHQUFHO0FBQ0g7QUFD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O0FBQ0E7QUFDQSxVQUFVLEtBQUssR0FBRztBQUNsQixZQUFZLEdBQUcsSUFBSSxJQUFJLENBQUM7QUFDeEIsWUFBWSxNQUFNO0FBQ2xCO0FBQ0E7QUFDQSxVQUFVLEtBQUssR0FBRztBQUNsQixZQUFZLEdBQUcsSUFBSSxJQUFJLENBQUM7QUFDeEIsWUFBWSxNQUFNO0FBQ2xCO0FBQ0E7QUFDQSxVQUFVLEtBQUssR0FBRztBQUNsQixZQUFZLEdBQUcsSUFBSSxJQUFJLENBQUM7QUFDeEIsWUFBWSxNQUFNO0FBQ2xCO0FBQ0E7QUFDQSxVQUFVLEtBQUssR0FBRztBQUNsQixZQUFZLEdBQUcsSUFBSSxJQUFJLENBQUM7QUFDeEIsWUFBWSxNQUFNO0FBQ2xCO0FBQ0E7QUFDQSxVQUFVLEtBQUssR0FBRztBQUNsQixZQUFZLEdBQUcsSUFBSSxRQUFRLENBQUM7QUFDNUIsWUFBWSxNQUFNO0FBQ2xCO0FBQ0E7QUFDQSxVQUFVLEtBQUssR0FBRztBQUNsQixZQUFZLEdBQUcsSUFBSSxRQUFRLENBQUM7QUFDNUIsWUFBWSxNQUFNO0FBQ2xCO0FBQ0E7QUFDQSxVQUFVLEtBQUssR0FBRztBQUNsQixZQUFZLEdBQUcsSUFBSSxRQUFRLENBQUM7QUFDNUIsWUFBWSxNQUFNO0FBQ2xCO0FBQ0E7QUFDQSxVQUFVLEtBQUssR0FBRztBQUNsQixZQUFZLEdBQUcsSUFBSSxRQUFRLENBQUM7QUFDNUIsWUFBWSxNQUFNO0FBQ2xCO0FBQ0E7QUFDQSxVQUFVLEtBQUssR0FBRztBQUNsQixZQUFZLEdBQUcsSUFBSSxHQUFHLENBQUM7QUFDdkIsWUFBWSxNQUFNO0FBQ2xCO0FBQ0EsVUFBVSxLQUFLLEdBQUc7QUFDbEIsWUFBWSxHQUFHLElBQUksR0FBRyxDQUFDO0FBQ3ZCLFlBQVksTUFBTTtBQUNsQjtBQUNBLFVBQVUsS0FBSyxHQUFHO0FBQ2xCLFlBQVksR0FBRyxJQUFJLEdBQUcsQ0FBQztBQUN2QixZQUFZLE1BQU07QUFDbEI7QUFDQSxVQUFVLEtBQUssSUFBSTtBQUNuQixZQUFZLEdBQUcsSUFBSSxJQUFJLENBQUM7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R0FBRztBQUNIO0FBQ0E7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUyxZQUFZLENBQUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFO0FBQzlDLEVBQUUsSUFBSSxHQUFHLElBQUksT0FBTyxHQUFHLEtBQUssUUFBUSxFQUFFO0FBQ3RDLElBQUksSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFO0FBQzVCLE1BQU0sS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxHQUFHLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxHQUFHLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRTtBQUN0RCxRQUFRLE1BQU0sRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMxQixRQUFRLE1BQU0sRUFBRSxHQUFHLFlBQVksQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUM3RCxRQUFRLElBQUksRUFBRSxLQUFLLFNBQVMsRUFBRSxPQUFPLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQzVFLE9BQU87QUFDUCxLQUFLLE1BQU0sSUFBSSxHQUFHLFlBQVksR0FBRyxFQUFFO0FBQ25DLE1BQU0sS0FBSyxNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFO0FBQzlDLFFBQVEsTUFBTSxFQUFFLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM5QixRQUFRLE1BQU0sRUFBRSxHQUFHLFlBQVksQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUNyRCxRQUFRLElBQUksRUFBRSxLQUFLLFNBQVMsRUFBRSxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQy9FLE9BQU87QUFDUCxLQUFLLE1BQU0sSUFBSSxHQUFHLFlBQVksR0FBRyxFQUFFO0FBQ25DLE1BQU0sS0FBSyxNQUFNLEVBQUUsSUFBSSxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFO0FBQ3hDLFFBQVEsTUFBTSxFQUFFLEdBQUcsWUFBWSxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQ3RELFFBQVEsSUFBSSxFQUFFLEtBQUssU0FBUyxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUU7QUFDakUsVUFBVSxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3pCLFVBQVUsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUN0QixTQUFTO0FBQ1QsT0FBTztBQUNQLEtBQUssTUFBTTtBQUNYLE1BQU0sS0FBSyxNQUFNLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUU7QUFDakQsUUFBUSxNQUFNLEVBQUUsR0FBRyxZQUFZLENBQUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDckQsUUFBUSxJQUFJLEVBQUUsS0FBSyxTQUFTLEVBQUUsT0FBTyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUM1RSxPQUFPO0FBQ1AsS0FBSztBQUNMLEdBQUc7QUFDSDtBQUNBLEVBQUUsT0FBTyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDckM7O0FDbENBLE1BQU0sS0FBSyxHQUFHLENBQUMsSUFBSSxFQUFFLElBQUksS0FBSztBQUM5QixFQUFFLElBQUksSUFBSSxJQUFJLE9BQU8sSUFBSSxLQUFLLFFBQVEsRUFBRTtBQUN4QyxJQUFJLE1BQU07QUFDVixNQUFNLEdBQUc7QUFDVCxLQUFLLEdBQUcsSUFBSSxDQUFDO0FBQ2I7QUFDQSxJQUFJLElBQUksSUFBSSxZQUFZSCxZQUFVLEVBQUU7QUFDcEMsTUFBTSxJQUFJLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDO0FBQ2hDLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLEtBQUssQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztBQUM5QyxLQUFLLE1BQU0sSUFBSSxJQUFJLFlBQVksSUFBSSxFQUFFO0FBQ3JDLE1BQU0sS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDNUIsTUFBTSxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztBQUM5QixLQUFLLE1BQU0sSUFBSSxJQUFJLFlBQVksTUFBTSxFQUFFO0FBQ3ZDLE1BQU0sSUFBSSxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQztBQUNoQyxLQUFLO0FBQ0wsR0FBRztBQUNIO0FBQ0EsRUFBRSxPQUFPLElBQUksQ0FBQztBQUNkLENBQUMsQ0FBQztBQUNGO0FBQ0EsTUFBTSxZQUFZLEdBQUcsSUFBSSxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQzs7QUNyQnpELFNBQVMsZ0JBQWdCLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRTtBQUNyQyxFQUFFLE1BQU07QUFDUixJQUFJLE1BQU07QUFDVixJQUFJLE1BQU07QUFDVixHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQztBQUNmLEVBQUUsSUFBSSxNQUFNLEdBQUcsR0FBRyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLEtBQUssTUFBTSxDQUFDLENBQUM7QUFDOUQ7QUFDQSxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUU7QUFDZixJQUFJLE1BQU0sR0FBRyxHQUFHLEdBQUcsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxXQUFXLENBQUM7QUFDOUMsSUFBSSxJQUFJLEdBQUcsRUFBRSxNQUFNLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQU0sS0FBSyxNQUFNLENBQUMsQ0FBQztBQUN6RCxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsTUFBTSxJQUFJLGlCQUFpQixDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxrREFBa0QsQ0FBQyxDQUFDLENBQUM7QUFDOUgsR0FBRztBQUNIO0FBQ0EsRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUscUJBQXFCLENBQUMsQ0FBQyxDQUFDO0FBQy9GO0FBQ0EsRUFBRSxJQUFJLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxJQUFJLEdBQUcsQ0FBQyxPQUFPLENBQUMsT0FBTyxNQUFNLEtBQUssRUFBRTtBQUN4RSxJQUFJLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsRUFBRTtBQUMzQixNQUFNLEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksV0FBVyxDQUFDLElBQUksRUFBRSwyQ0FBMkMsQ0FBQyxDQUFDLENBQUM7QUFDNUYsTUFBTSxPQUFPLE1BQU0sQ0FBQztBQUNwQixLQUFLO0FBQ0w7QUFDQSxJQUFJLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRTtBQUM3QjtBQUNBLE1BQU0sTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO0FBQ3pELE1BQU0sT0FBTyxLQUFLLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsaUJBQWlCLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUN6RyxLQUFLO0FBQ0wsR0FBRztBQUNIO0FBQ0EsRUFBRSxPQUFPLE1BQU0sQ0FBQyxNQUFNLEdBQUcsa0JBQWtCLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDcEQsQ0FBQztBQUNEO0FBQ0EsU0FBUyxjQUFjLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRTtBQUNuQyxFQUFFLE1BQU07QUFDUixJQUFJLEdBQUc7QUFDUCxJQUFJLElBQUk7QUFDUixHQUFHLEdBQUcsSUFBSSxDQUFDO0FBQ1gsRUFBRSxJQUFJLFdBQVcsR0FBRyxLQUFLLENBQUM7QUFDMUI7QUFDQSxFQUFFLElBQUksR0FBRyxFQUFFO0FBQ1gsSUFBSSxNQUFNO0FBQ1YsTUFBTSxNQUFNO0FBQ1osTUFBTSxNQUFNO0FBQ1osTUFBTSxRQUFRO0FBQ2QsS0FBSyxHQUFHLEdBQUcsQ0FBQztBQUNaO0FBQ0EsSUFBSSxJQUFJLFFBQVEsRUFBRTtBQUNsQixNQUFNLElBQUksUUFBUSxLQUFLLEdBQUcsSUFBSSxRQUFRLEtBQUssSUFBSSxFQUFFLE9BQU8sUUFBUSxDQUFDO0FBQ2pFLE1BQU0sTUFBTSxHQUFHLEdBQUcsb0NBQW9DLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxjQUFjLENBQUMsQ0FBQztBQUN4RixNQUFNLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksaUJBQWlCLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDeEQsS0FBSyxNQUFNLElBQUksTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRTtBQUMxQyxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUM7QUFDekIsS0FBSyxNQUFNO0FBQ1gsTUFBTSxJQUFJO0FBQ1YsUUFBUSxPQUFPLGdCQUFnQixDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztBQUMzQyxPQUFPLENBQUMsT0FBTyxLQUFLLEVBQUU7QUFDdEIsUUFBUSxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUMvQixPQUFPO0FBQ1AsS0FBSztBQUNMLEdBQUc7QUFDSDtBQUNBLEVBQUUsUUFBUSxJQUFJO0FBQ2QsSUFBSSxLQUFLLElBQUksQ0FBQyxZQUFZLENBQUM7QUFDM0IsSUFBSSxLQUFLLElBQUksQ0FBQyxhQUFhLENBQUM7QUFDNUIsSUFBSSxLQUFLLElBQUksQ0FBQyxZQUFZLENBQUM7QUFDM0IsSUFBSSxLQUFLLElBQUksQ0FBQyxZQUFZO0FBQzFCLE1BQU0sT0FBTyxXQUFXLENBQUMsR0FBRyxDQUFDO0FBQzdCO0FBQ0EsSUFBSSxLQUFLLElBQUksQ0FBQyxRQUFRLENBQUM7QUFDdkIsSUFBSSxLQUFLLElBQUksQ0FBQyxHQUFHO0FBQ2pCLE1BQU0sT0FBTyxXQUFXLENBQUMsR0FBRyxDQUFDO0FBQzdCO0FBQ0EsSUFBSSxLQUFLLElBQUksQ0FBQyxRQUFRLENBQUM7QUFDdkIsSUFBSSxLQUFLLElBQUksQ0FBQyxHQUFHO0FBQ2pCLE1BQU0sT0FBTyxXQUFXLENBQUMsR0FBRyxDQUFDO0FBQzdCO0FBQ0EsSUFBSSxLQUFLLElBQUksQ0FBQyxLQUFLO0FBQ25CLE1BQU0sT0FBTyxXQUFXLEdBQUcsV0FBVyxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUM7QUFDbEQ7QUFDQSxJQUFJO0FBQ0osTUFBTSxPQUFPLElBQUksQ0FBQztBQUNsQixHQUFHO0FBQ0g7O0FDakZBLFNBQVMsc0JBQXNCLENBQUMsTUFBTSxFQUFFLEdBQUcsRUFBRTtBQUM3QyxFQUFFLElBQUksSUFBSSxFQUFFLElBQUksQ0FBQztBQUNqQjtBQUNBLEVBQUUsUUFBUSxHQUFHLENBQUMsSUFBSTtBQUNsQixJQUFJLEtBQUssSUFBSSxDQUFDLFFBQVE7QUFDdEIsTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDO0FBQ2pCLE1BQU0sSUFBSSxHQUFHLFVBQVUsQ0FBQztBQUN4QixNQUFNLE1BQU07QUFDWjtBQUNBLElBQUksS0FBSyxJQUFJLENBQUMsUUFBUTtBQUN0QixNQUFNLElBQUksR0FBRyxHQUFHLENBQUM7QUFDakIsTUFBTSxJQUFJLEdBQUcsZUFBZSxDQUFDO0FBQzdCLE1BQU0sTUFBTTtBQUNaO0FBQ0EsSUFBSTtBQUNKLE1BQU0sTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLGlCQUFpQixDQUFDLEdBQUcsRUFBRSx5QkFBeUIsQ0FBQyxDQUFDLENBQUM7QUFDekUsTUFBTSxPQUFPO0FBQ2IsR0FBRztBQUNIO0FBQ0EsRUFBRSxJQUFJLFFBQVEsQ0FBQztBQUNmO0FBQ0EsRUFBRSxLQUFLLElBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFO0FBQ2xELElBQUksTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM5QjtBQUNBLElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLElBQUksQ0FBQyxPQUFPLEVBQUU7QUFDN0MsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDO0FBQ3RCLE1BQU0sTUFBTTtBQUNaLEtBQUs7QUFDTCxHQUFHO0FBQ0g7QUFDQSxFQUFFLElBQUksUUFBUSxJQUFJLFFBQVEsQ0FBQyxJQUFJLEtBQUssSUFBSSxFQUFFO0FBQzFDLElBQUksTUFBTSxHQUFHLEdBQUcsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsZUFBZSxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ3ZFLElBQUksSUFBSSxHQUFHLENBQUM7QUFDWjtBQUNBLElBQUksSUFBSSxPQUFPLFFBQVEsQ0FBQyxNQUFNLEtBQUssUUFBUSxFQUFFO0FBQzdDLE1BQU0sR0FBRyxHQUFHLElBQUksaUJBQWlCLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQzVDLE1BQU0sR0FBRyxDQUFDLE1BQU0sR0FBRyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztBQUN2QyxLQUFLLE1BQU07QUFDWCxNQUFNLEdBQUcsR0FBRyxJQUFJLGlCQUFpQixDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsQ0FBQztBQUNqRCxNQUFNLElBQUksUUFBUSxDQUFDLEtBQUssSUFBSSxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsTUFBTSxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsR0FBRyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDO0FBQ3ZHLEtBQUs7QUFDTDtBQUNBLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNyQixHQUFHO0FBQ0gsQ0FBQztBQUNELFNBQVMscUJBQXFCLENBQUMsTUFBTSxFQUFFLE9BQU8sRUFBRTtBQUNoRCxFQUFFLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQzVEO0FBQ0EsRUFBRSxJQUFJLElBQUksS0FBSyxJQUFJLElBQUksSUFBSSxLQUFLLElBQUksSUFBSSxJQUFJLEtBQUssR0FBRyxFQUFFO0FBQ3RELElBQUksTUFBTSxHQUFHLEdBQUcsd0VBQXdFLENBQUM7QUFDekYsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksaUJBQWlCLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDckQsR0FBRztBQUNILENBQUM7QUFDRCxTQUFTLGVBQWUsQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFO0FBQ3RDLEVBQUUsTUFBTSxFQUFFLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3pCLEVBQUUsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsS0FBSyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNwRCxFQUFFLE9BQU8sSUFBSSxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsb0JBQW9CLENBQUMsQ0FBQyxDQUFDO0FBQ2pGLENBQUM7QUFDRCxTQUFTLGVBQWUsQ0FBQyxVQUFVLEVBQUUsUUFBUSxFQUFFO0FBQy9DLEVBQUUsS0FBSyxNQUFNO0FBQ2IsSUFBSSxRQUFRO0FBQ1osSUFBSSxNQUFNO0FBQ1YsSUFBSSxPQUFPO0FBQ1gsR0FBRyxJQUFJLFFBQVEsRUFBRTtBQUNqQixJQUFJLElBQUksSUFBSSxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDeEM7QUFDQSxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUU7QUFDZixNQUFNLElBQUksT0FBTyxLQUFLLFNBQVMsRUFBRTtBQUNqQyxRQUFRLElBQUksVUFBVSxDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUMsT0FBTyxJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsS0FBSyxVQUFVLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztBQUN2RyxPQUFPO0FBQ1AsS0FBSyxNQUFNO0FBQ1gsTUFBTSxJQUFJLFFBQVEsSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO0FBQ3BEO0FBQ0EsTUFBTSxJQUFJLE9BQU8sS0FBSyxTQUFTLEVBQUU7QUFDakMsUUFBUSxJQUFJLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7QUFDckUsT0FBTyxNQUFNO0FBQ2IsUUFBUSxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLGFBQWEsSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLEtBQUssSUFBSSxDQUFDLGFBQWEsR0FBRyxPQUFPLENBQUM7QUFDdkcsT0FBTztBQUNQLEtBQUs7QUFDTCxHQUFHO0FBQ0g7O0FDekVBLFNBQVMsVUFBVSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUU7QUFDOUIsRUFBRSxNQUFNO0FBQ1IsSUFBSSxRQUFRO0FBQ1osSUFBSSxLQUFLO0FBQ1QsR0FBRyxHQUFHLEdBQUcsQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLFFBQVEsR0FBRyxtQkFBbUIsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLEdBQUcsb0JBQW9CLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ2xHLEVBQUUsTUFBTSxHQUFHLEdBQUcsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ3RDLEVBQUUsR0FBRyxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7QUFDcEIsRUFBRSxlQUFlLENBQUMsR0FBRyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBQ2pDO0FBQ0EsRUFBRSxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsRUFBRTtBQUN6QyxJQUFJLE1BQU07QUFDVixNQUFNLEdBQUcsRUFBRSxJQUFJO0FBQ2YsS0FBSyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqQjtBQUNBLElBQUksSUFBSSxHQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLEtBQUssS0FBSyxTQUFTLEVBQUU7QUFDOUQsTUFBTSxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDckMsTUFBTSxNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQztBQUMzQyxNQUFNLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQztBQUN2QixNQUFNLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJO0FBQzNCLFFBQVEsSUFBSSxJQUFJLFlBQVlDLE9BQUssRUFBRTtBQUNuQztBQUNBO0FBQ0EsVUFBVSxNQUFNO0FBQ2hCLFlBQVksSUFBSTtBQUNoQixXQUFXLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztBQUMxQixVQUFVLElBQUksSUFBSSxLQUFLLElBQUksQ0FBQyxHQUFHLElBQUksSUFBSSxLQUFLLElBQUksQ0FBQyxRQUFRLEVBQUUsT0FBTyxLQUFLLENBQUM7QUFDeEUsVUFBVSxPQUFPLEtBQUssR0FBRyw0Q0FBNEMsQ0FBQztBQUN0RSxTQUFTO0FBQ1Q7QUFDQSxRQUFRLE9BQU8sS0FBSyxHQUFHLGlEQUFpRCxDQUFDO0FBQ3pFLE9BQU8sQ0FBQyxDQUFDO0FBQ1QsTUFBTSxJQUFJLEtBQUssRUFBRSxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLGlCQUFpQixDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQ3BFLEtBQUssTUFBTTtBQUNYLE1BQU0sS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxFQUFFO0FBQ2pELFFBQVEsTUFBTTtBQUNkLFVBQVUsR0FBRyxFQUFFLElBQUk7QUFDbkIsU0FBUyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNyQjtBQUNBLFFBQVEsSUFBSSxJQUFJLEtBQUssSUFBSSxJQUFJLElBQUksSUFBSSxJQUFJLElBQUksTUFBTSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSSxJQUFJLENBQUMsS0FBSyxLQUFLLElBQUksQ0FBQyxLQUFLLEVBQUU7QUFDL0gsVUFBVSxNQUFNLEdBQUcsR0FBRyw2QkFBNkIsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLGdCQUFnQixDQUFDLENBQUM7QUFDbkYsVUFBVSxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLGlCQUFpQixDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQzNELFVBQVUsTUFBTTtBQUNoQixTQUFTO0FBQ1QsT0FBTztBQUNQLEtBQUs7QUFDTCxHQUFHO0FBQ0g7QUFDQSxFQUFFLEdBQUcsQ0FBQyxRQUFRLEdBQUcsR0FBRyxDQUFDO0FBQ3JCLEVBQUUsT0FBTyxHQUFHLENBQUM7QUFDYixDQUFDO0FBQ0Q7QUFDQSxNQUFNLG1CQUFtQixHQUFHLENBQUM7QUFDN0IsRUFBRSxPQUFPLEVBQUU7QUFDWCxJQUFJLFNBQVM7QUFDYixJQUFJLElBQUk7QUFDUixJQUFJLEdBQUc7QUFDUCxHQUFHO0FBQ0gsRUFBRSxLQUFLO0FBQ1AsQ0FBQyxLQUFLO0FBQ04sRUFBRSxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLE9BQU8sS0FBSyxDQUFDO0FBQ3ZDLEVBQUUsTUFBTTtBQUNSLElBQUksS0FBSztBQUNULEdBQUcsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDZixFQUFFLElBQUksSUFBSSxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxPQUFPLEtBQUssQ0FBQztBQUMxRCxFQUFFLElBQUksR0FBRyxDQUFDLEtBQUssQ0FBQyxLQUFLLElBQUksQ0FBQyxPQUFPLEVBQUUsT0FBTyxLQUFLLENBQUM7QUFDaEQ7QUFDQSxFQUFFLEtBQUssSUFBSSxDQUFDLEdBQUcsU0FBUyxFQUFFLENBQUMsR0FBRyxLQUFLLEVBQUUsRUFBRSxDQUFDLEVBQUUsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxFQUFFLE9BQU8sS0FBSyxDQUFDO0FBQzVFO0FBQ0EsRUFBRSxPQUFPLElBQUksQ0FBQztBQUNkLENBQUMsQ0FBQztBQUNGO0FBQ0EsU0FBUyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFO0FBQ3hDLEVBQUUsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxFQUFFLE9BQU87QUFDekMsRUFBRSxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQzNELEVBQUUsSUFBSSxLQUFLLEdBQUcsS0FBSyxDQUFDO0FBQ3BCLEVBQUUsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUM7QUFDdEM7QUFDQSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLEVBQUU7QUFDcEMsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLGFBQWEsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDN0QsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDO0FBQ2pCLEdBQUcsTUFBTTtBQUNULElBQUksTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUM7QUFDbEM7QUFDQSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxFQUFFO0FBQ3BELE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3pELE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQztBQUNuQixLQUFLO0FBQ0wsR0FBRztBQUNIO0FBQ0EsRUFBRSxJQUFJLEtBQUssRUFBRSxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztBQUNwQyxDQUFDO0FBQ0Q7QUFDQSxTQUFTLG9CQUFvQixDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUU7QUFDeEMsRUFBRSxNQUFNLFFBQVEsR0FBRyxFQUFFLENBQUM7QUFDdEIsRUFBRSxNQUFNLEtBQUssR0FBRyxFQUFFLENBQUM7QUFDbkIsRUFBRSxJQUFJLEdBQUcsR0FBRyxTQUFTLENBQUM7QUFDdEIsRUFBRSxJQUFJLFFBQVEsR0FBRyxJQUFJLENBQUM7QUFDdEI7QUFDQSxFQUFFLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsRUFBRTtBQUM3QyxJQUFJLE1BQU0sSUFBSSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDOUI7QUFDQSxJQUFJLFFBQVEsSUFBSSxDQUFDLElBQUk7QUFDckIsTUFBTSxLQUFLLElBQUksQ0FBQyxVQUFVO0FBQzFCLFFBQVEsUUFBUSxDQUFDLElBQUksQ0FBQztBQUN0QixVQUFVLFFBQVEsRUFBRSxDQUFDLENBQUMsR0FBRztBQUN6QixVQUFVLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTTtBQUM5QixTQUFTLENBQUMsQ0FBQztBQUNYLFFBQVEsTUFBTTtBQUNkO0FBQ0EsTUFBTSxLQUFLLElBQUksQ0FBQyxPQUFPO0FBQ3ZCLFFBQVEsUUFBUSxDQUFDLElBQUksQ0FBQztBQUN0QixVQUFVLFFBQVEsRUFBRSxDQUFDLENBQUMsR0FBRztBQUN6QixVQUFVLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTTtBQUM5QixVQUFVLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTztBQUMvQixTQUFTLENBQUMsQ0FBQztBQUNYLFFBQVEsTUFBTTtBQUNkO0FBQ0EsTUFBTSxLQUFLLElBQUksQ0FBQyxPQUFPO0FBQ3ZCLFFBQVEsSUFBSSxHQUFHLEtBQUssU0FBUyxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUN6RCxRQUFRLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDcEQsUUFBUSxHQUFHLEdBQUcsV0FBVyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDMUMsUUFBUSxRQUFRLEdBQUcsSUFBSSxDQUFDO0FBQ3hCLFFBQVEsTUFBTTtBQUNkO0FBQ0EsTUFBTSxLQUFLLElBQUksQ0FBQyxTQUFTO0FBQ3pCLFFBQVE7QUFDUixVQUFVLElBQUksR0FBRyxLQUFLLFNBQVMsRUFBRSxHQUFHLEdBQUcsSUFBSSxDQUFDO0FBQzVDLFVBQVUsSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUN0RDtBQUNBLFVBQVUsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxJQUFJLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRTtBQUN2SCxZQUFZLE1BQU0sR0FBRyxHQUFHLHFEQUFxRCxDQUFDO0FBQzlFLFlBQVksR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDbkUsV0FBVztBQUNYO0FBQ0EsVUFBVSxJQUFJLFNBQVMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO0FBQ3BDO0FBQ0EsVUFBVSxJQUFJLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtBQUNuRDtBQUNBO0FBQ0E7QUFDQSxZQUFZLFNBQVMsR0FBRyxJQUFJLFVBQVUsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQ3ZELFlBQVksU0FBUyxDQUFDLE9BQU8sR0FBRztBQUNoQyxjQUFjLE1BQU0sRUFBRSxJQUFJO0FBQzFCLGNBQWMsR0FBRyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRztBQUNuQyxhQUFhLENBQUM7QUFDZCxZQUFZLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQztBQUM3QyxZQUFZLFNBQVMsQ0FBQyxLQUFLLEdBQUc7QUFDOUIsY0FBYyxLQUFLLEVBQUUsR0FBRztBQUN4QixjQUFjLEdBQUcsRUFBRSxHQUFHO0FBQ3RCLGFBQWEsQ0FBQztBQUNkLFlBQVksU0FBUyxDQUFDLFVBQVUsR0FBRztBQUNuQyxjQUFjLEtBQUssRUFBRSxHQUFHO0FBQ3hCLGNBQWMsR0FBRyxFQUFFLEdBQUc7QUFDdEIsYUFBYSxDQUFDO0FBQ2Q7QUFDQSxZQUFZLElBQUksT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsS0FBSyxRQUFRLEVBQUU7QUFDMUQsY0FBYyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUM7QUFDdkQsY0FBYyxTQUFTLENBQUMsS0FBSyxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7QUFDNUUsY0FBYyxTQUFTLENBQUMsVUFBVSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUMsVUFBVSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7QUFDdEYsYUFBYTtBQUNiLFdBQVc7QUFDWDtBQUNBLFVBQVUsTUFBTSxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsR0FBRyxFQUFFLFdBQVcsQ0FBQyxHQUFHLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQztBQUNsRSxVQUFVLGtCQUFrQixDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztBQUN6QyxVQUFVLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDM0I7QUFDQSxVQUFVLElBQUksR0FBRyxJQUFJLE9BQU8sUUFBUSxLQUFLLFFBQVEsRUFBRTtBQUNuRCxZQUFZLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsUUFBUSxHQUFHLElBQUksRUFBRSxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDL0YsV0FBVztBQUNYO0FBQ0EsVUFBVSxHQUFHLEdBQUcsU0FBUyxDQUFDO0FBQzFCLFVBQVUsUUFBUSxHQUFHLElBQUksQ0FBQztBQUMxQixTQUFTO0FBQ1QsUUFBUSxNQUFNO0FBQ2Q7QUFDQSxNQUFNO0FBQ04sUUFBUSxJQUFJLEdBQUcsS0FBSyxTQUFTLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3pELFFBQVEsR0FBRyxHQUFHLFdBQVcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDckMsUUFBUSxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUM7QUFDcEMsUUFBUSxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3BEO0FBQ0EsUUFBUSxJQUFJLEVBQUUsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFO0FBQ3hDLFVBQVUsTUFBTSxRQUFRLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN4QztBQUNBLFVBQVUsUUFBUSxRQUFRLElBQUksUUFBUSxDQUFDLElBQUk7QUFDM0MsWUFBWSxLQUFLLElBQUksQ0FBQyxVQUFVLENBQUM7QUFDakMsWUFBWSxLQUFLLElBQUksQ0FBQyxPQUFPO0FBQzdCLGNBQWMsU0FBUyxJQUFJLENBQUM7QUFDNUI7QUFDQSxZQUFZLEtBQUssSUFBSSxDQUFDLFNBQVM7QUFDL0IsY0FBYyxNQUFNLElBQUksQ0FBQztBQUN6QjtBQUNBLFlBQVk7QUFDWixjQUFjO0FBQ2QsZ0JBQWdCLE1BQU0sR0FBRyxHQUFHLHFEQUFxRCxDQUFDO0FBQ2xGLGdCQUFnQixHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLGlCQUFpQixDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ2xFLGdCQUFnQixNQUFNLElBQUksQ0FBQztBQUMzQixlQUFlO0FBQ2YsV0FBVztBQUNYLFNBQVM7QUFDVDtBQUNBLFFBQVEsSUFBSSxJQUFJLENBQUMseUJBQXlCLEVBQUU7QUFDNUMsVUFBVSxNQUFNLEdBQUcsR0FBRywrQ0FBK0MsQ0FBQztBQUN0RSxVQUFVLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksaUJBQWlCLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDNUQsU0FBUztBQUNUO0FBQ0EsS0FBSztBQUNMLEdBQUc7QUFDSDtBQUNBLEVBQUUsSUFBSSxHQUFHLEtBQUssU0FBUyxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNuRCxFQUFFLE9BQU87QUFDVCxJQUFJLFFBQVE7QUFDWixJQUFJLEtBQUs7QUFDVCxHQUFHLENBQUM7QUFDSixDQUFDO0FBQ0Q7QUFDQSxTQUFTLG1CQUFtQixDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUU7QUFDdkMsRUFBRSxNQUFNLFFBQVEsR0FBRyxFQUFFLENBQUM7QUFDdEIsRUFBRSxNQUFNLEtBQUssR0FBRyxFQUFFLENBQUM7QUFDbkIsRUFBRSxJQUFJLEdBQUcsR0FBRyxTQUFTLENBQUM7QUFDdEIsRUFBRSxJQUFJLFdBQVcsR0FBRyxLQUFLLENBQUM7QUFDMUIsRUFBRSxJQUFJLElBQUksR0FBRyxHQUFHLENBQUM7QUFDakI7QUFDQSxFQUFFLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsRUFBRTtBQUM3QyxJQUFJLE1BQU0sSUFBSSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDOUI7QUFDQSxJQUFJLElBQUksT0FBTyxJQUFJLENBQUMsSUFBSSxLQUFLLFFBQVEsRUFBRTtBQUN2QyxNQUFNLE1BQU07QUFDWixRQUFRLElBQUk7QUFDWixRQUFRLE1BQU07QUFDZCxPQUFPLEdBQUcsSUFBSSxDQUFDO0FBQ2Y7QUFDQSxNQUFNLElBQUksSUFBSSxLQUFLLEdBQUcsSUFBSSxHQUFHLEtBQUssU0FBUyxJQUFJLENBQUMsV0FBVyxFQUFFO0FBQzdELFFBQVEsV0FBVyxHQUFHLElBQUksQ0FBQztBQUMzQixRQUFRLElBQUksR0FBRyxHQUFHLENBQUM7QUFDbkIsUUFBUSxTQUFTO0FBQ2pCLE9BQU87QUFDUDtBQUNBLE1BQU0sSUFBSSxJQUFJLEtBQUssR0FBRyxFQUFFO0FBQ3hCLFFBQVEsSUFBSSxHQUFHLEtBQUssU0FBUyxFQUFFLEdBQUcsR0FBRyxJQUFJLENBQUM7QUFDMUM7QUFDQSxRQUFRLElBQUksSUFBSSxLQUFLLEdBQUcsRUFBRTtBQUMxQixVQUFVLElBQUksR0FBRyxHQUFHLENBQUM7QUFDckIsVUFBVSxTQUFTO0FBQ25CLFNBQVM7QUFDVCxPQUFPLE1BQU07QUFDYixRQUFRLElBQUksV0FBVyxFQUFFO0FBQ3pCLFVBQVUsSUFBSSxHQUFHLEtBQUssU0FBUyxJQUFJLElBQUksS0FBSyxHQUFHLEVBQUUsR0FBRyxHQUFHLElBQUksQ0FBQztBQUM1RCxVQUFVLFdBQVcsR0FBRyxLQUFLLENBQUM7QUFDOUIsU0FBUztBQUNUO0FBQ0EsUUFBUSxJQUFJLEdBQUcsS0FBSyxTQUFTLEVBQUU7QUFDL0IsVUFBVSxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDcEMsVUFBVSxHQUFHLEdBQUcsU0FBUyxDQUFDO0FBQzFCO0FBQ0EsVUFBVSxJQUFJLElBQUksS0FBSyxHQUFHLEVBQUU7QUFDNUIsWUFBWSxJQUFJLEdBQUcsR0FBRyxDQUFDO0FBQ3ZCLFlBQVksU0FBUztBQUNyQixXQUFXO0FBQ1gsU0FBUztBQUNULE9BQU87QUFDUDtBQUNBLE1BQU0sSUFBSSxJQUFJLEtBQUssR0FBRyxFQUFFO0FBQ3hCLFFBQVEsSUFBSSxDQUFDLEtBQUssR0FBRyxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLFNBQVM7QUFDakQsT0FBTyxNQUFNLElBQUksSUFBSSxLQUFLLElBQUksRUFBRTtBQUNoQyxRQUFRLElBQUksR0FBRyxHQUFHLENBQUM7QUFDbkIsUUFBUSxTQUFTO0FBQ2pCLE9BQU87QUFDUDtBQUNBLE1BQU0sTUFBTSxHQUFHLEdBQUcsa0NBQWtDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ2xFLE1BQU0sTUFBTSxHQUFHLEdBQUcsSUFBSSxlQUFlLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ2hELE1BQU0sR0FBRyxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7QUFDMUIsTUFBTSxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUMzQixLQUFLLE1BQU0sSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLElBQUksQ0FBQyxVQUFVLEVBQUU7QUFDOUMsTUFBTSxRQUFRLENBQUMsSUFBSSxDQUFDO0FBQ3BCLFFBQVEsUUFBUSxFQUFFLENBQUMsQ0FBQyxHQUFHO0FBQ3ZCLFFBQVEsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNO0FBQzVCLE9BQU8sQ0FBQyxDQUFDO0FBQ1QsS0FBSyxNQUFNLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsT0FBTyxFQUFFO0FBQzNDLE1BQU0scUJBQXFCLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztBQUM5QyxNQUFNLFFBQVEsQ0FBQyxJQUFJLENBQUM7QUFDcEIsUUFBUSxRQUFRLEVBQUUsQ0FBQyxDQUFDLEdBQUc7QUFDdkIsUUFBUSxNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU07QUFDNUIsUUFBUSxPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU87QUFDN0IsT0FBTyxDQUFDLENBQUM7QUFDVCxLQUFLLE1BQU0sSUFBSSxHQUFHLEtBQUssU0FBUyxFQUFFO0FBQ2xDLE1BQU0sSUFBSSxJQUFJLEtBQUssR0FBRyxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksaUJBQWlCLENBQUMsSUFBSSxFQUFFLGlDQUFpQyxDQUFDLENBQUMsQ0FBQztBQUN4RyxNQUFNLEdBQUcsR0FBRyxXQUFXLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQ25DLEtBQUssTUFBTTtBQUNYLE1BQU0sSUFBSSxJQUFJLEtBQUssR0FBRyxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksaUJBQWlCLENBQUMsSUFBSSxFQUFFLHVDQUF1QyxDQUFDLENBQUMsQ0FBQztBQUM5RyxNQUFNLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxFQUFFLFdBQVcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3hELE1BQU0sR0FBRyxHQUFHLFNBQVMsQ0FBQztBQUN0QixNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUM7QUFDMUIsS0FBSztBQUNMLEdBQUc7QUFDSDtBQUNBLEVBQUUsc0JBQXNCLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQztBQUMxQyxFQUFFLElBQUksR0FBRyxLQUFLLFNBQVMsRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDbkQsRUFBRSxPQUFPO0FBQ1QsSUFBSSxRQUFRO0FBQ1osSUFBSSxLQUFLO0FBQ1QsR0FBRyxDQUFDO0FBQ0o7O0FDalRBLFNBQVMsVUFBVSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUU7QUFDOUIsRUFBRSxNQUFNO0FBQ1IsSUFBSSxRQUFRO0FBQ1osSUFBSSxLQUFLO0FBQ1QsR0FBRyxHQUFHLEdBQUcsQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLFFBQVEsR0FBRyxtQkFBbUIsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLEdBQUcsb0JBQW9CLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ2xHLEVBQUUsTUFBTSxHQUFHLEdBQUcsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ3RDLEVBQUUsR0FBRyxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7QUFDcEIsRUFBRSxlQUFlLENBQUMsR0FBRyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBQ2pDLEVBQUUsR0FBRyxDQUFDLFFBQVEsR0FBRyxHQUFHLENBQUM7QUFDckIsRUFBRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFDRDtBQUNBLFNBQVMsb0JBQW9CLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRTtBQUN4QyxFQUFFLE1BQU0sUUFBUSxHQUFHLEVBQUUsQ0FBQztBQUN0QixFQUFFLE1BQU0sS0FBSyxHQUFHLEVBQUUsQ0FBQztBQUNuQjtBQUNBLEVBQUUsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxFQUFFO0FBQzdDLElBQUksTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM5QjtBQUNBLElBQUksUUFBUSxJQUFJLENBQUMsSUFBSTtBQUNyQixNQUFNLEtBQUssSUFBSSxDQUFDLFVBQVU7QUFDMUIsUUFBUSxRQUFRLENBQUMsSUFBSSxDQUFDO0FBQ3RCLFVBQVUsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNO0FBQzlCLFNBQVMsQ0FBQyxDQUFDO0FBQ1gsUUFBUSxNQUFNO0FBQ2Q7QUFDQSxNQUFNLEtBQUssSUFBSSxDQUFDLE9BQU87QUFDdkIsUUFBUSxRQUFRLENBQUMsSUFBSSxDQUFDO0FBQ3RCLFVBQVUsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPO0FBQy9CLFVBQVUsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNO0FBQzlCLFNBQVMsQ0FBQyxDQUFDO0FBQ1gsUUFBUSxNQUFNO0FBQ2Q7QUFDQSxNQUFNLEtBQUssSUFBSSxDQUFDLFFBQVE7QUFDeEIsUUFBUSxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3BELFFBQVEsS0FBSyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ2hEO0FBQ0EsUUFBUSxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7QUFDM0IsVUFBVSxNQUFNLEdBQUcsR0FBRyxtRUFBbUUsQ0FBQztBQUMxRixVQUFVLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksaUJBQWlCLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDNUQsU0FBUztBQUNUO0FBQ0EsUUFBUSxNQUFNO0FBQ2Q7QUFDQSxNQUFNO0FBQ04sUUFBUSxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3BELFFBQVEsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxlQUFlLENBQUMsSUFBSSxFQUFFLGFBQWEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUN6RyxLQUFLO0FBQ0wsR0FBRztBQUNIO0FBQ0EsRUFBRSxPQUFPO0FBQ1QsSUFBSSxRQUFRO0FBQ1osSUFBSSxLQUFLO0FBQ1QsR0FBRyxDQUFDO0FBQ0osQ0FBQztBQUNEO0FBQ0EsU0FBUyxtQkFBbUIsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFO0FBQ3ZDLEVBQUUsTUFBTSxRQUFRLEdBQUcsRUFBRSxDQUFDO0FBQ3RCLEVBQUUsTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFDO0FBQ25CLEVBQUUsSUFBSSxXQUFXLEdBQUcsS0FBSyxDQUFDO0FBQzFCLEVBQUUsSUFBSSxHQUFHLEdBQUcsU0FBUyxDQUFDO0FBQ3RCLEVBQUUsSUFBSSxRQUFRLEdBQUcsSUFBSSxDQUFDO0FBQ3RCLEVBQUUsSUFBSSxJQUFJLEdBQUcsR0FBRyxDQUFDO0FBQ2pCLEVBQUUsSUFBSSxRQUFRLEdBQUcsSUFBSSxDQUFDO0FBQ3RCO0FBQ0EsRUFBRSxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLEVBQUU7QUFDN0MsSUFBSSxNQUFNLElBQUksR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzlCO0FBQ0EsSUFBSSxJQUFJLE9BQU8sSUFBSSxDQUFDLElBQUksS0FBSyxRQUFRLEVBQUU7QUFDdkMsTUFBTSxNQUFNO0FBQ1osUUFBUSxJQUFJO0FBQ1osUUFBUSxNQUFNO0FBQ2QsT0FBTyxHQUFHLElBQUksQ0FBQztBQUNmO0FBQ0EsTUFBTSxJQUFJLElBQUksS0FBSyxHQUFHLEtBQUssV0FBVyxJQUFJLEdBQUcsS0FBSyxTQUFTLENBQUMsRUFBRTtBQUM5RCxRQUFRLElBQUksV0FBVyxJQUFJLEdBQUcsS0FBSyxTQUFTLEVBQUUsR0FBRyxHQUFHLElBQUksR0FBRyxLQUFLLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBQzlFLFFBQVEsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ2xDLFFBQVEsV0FBVyxHQUFHLEtBQUssQ0FBQztBQUM1QixRQUFRLEdBQUcsR0FBRyxTQUFTLENBQUM7QUFDeEIsUUFBUSxRQUFRLEdBQUcsSUFBSSxDQUFDO0FBQ3hCLE9BQU87QUFDUDtBQUNBLE1BQU0sSUFBSSxJQUFJLEtBQUssSUFBSSxFQUFFO0FBQ3pCLFFBQVEsSUFBSSxHQUFHLElBQUksQ0FBQztBQUNwQixPQUFPLE1BQU0sSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLEtBQUssR0FBRyxFQUFFO0FBQ3hDLFFBQVEsV0FBVyxHQUFHLElBQUksQ0FBQztBQUMzQixPQUFPLE1BQU0sSUFBSSxJQUFJLEtBQUssR0FBRyxJQUFJLElBQUksS0FBSyxHQUFHLElBQUksR0FBRyxLQUFLLFNBQVMsRUFBRTtBQUNwRSxRQUFRLElBQUksSUFBSSxLQUFLLEdBQUcsRUFBRTtBQUMxQixVQUFVLEdBQUcsR0FBRyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDNUI7QUFDQSxVQUFVLElBQUksR0FBRyxZQUFZLElBQUksRUFBRTtBQUNuQyxZQUFZLE1BQU0sR0FBRyxHQUFHLHlDQUF5QyxDQUFDO0FBQ2xFLFlBQVksTUFBTSxHQUFHLEdBQUcsSUFBSSxpQkFBaUIsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDeEQsWUFBWSxHQUFHLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztBQUNoQyxZQUFZLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2pDLFdBQVc7QUFDWDtBQUNBLFVBQVUsSUFBSSxDQUFDLFdBQVcsSUFBSSxPQUFPLFFBQVEsS0FBSyxRQUFRLEVBQUU7QUFDNUQsWUFBWSxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7QUFDdkUsWUFBWSxJQUFJLE1BQU0sR0FBRyxRQUFRLEdBQUcsSUFBSSxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNyRixZQUFZLE1BQU07QUFDbEIsY0FBYyxHQUFHO0FBQ2pCLGFBQWEsR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDO0FBQ2pDO0FBQ0EsWUFBWSxLQUFLLElBQUksQ0FBQyxHQUFHLFFBQVEsRUFBRSxDQUFDLEdBQUcsTUFBTSxFQUFFLEVBQUUsQ0FBQyxFQUFFLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksRUFBRTtBQUN6RSxjQUFjLE1BQU0sR0FBRyxHQUFHLGtFQUFrRSxDQUFDO0FBQzdGLGNBQWMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNwRSxjQUFjLE1BQU07QUFDcEIsYUFBYTtBQUNiLFdBQVc7QUFDWCxTQUFTLE1BQU07QUFDZixVQUFVLEdBQUcsR0FBRyxJQUFJLENBQUM7QUFDckIsU0FBUztBQUNUO0FBQ0EsUUFBUSxRQUFRLEdBQUcsSUFBSSxDQUFDO0FBQ3hCLFFBQVEsV0FBVyxHQUFHLEtBQUssQ0FBQztBQUM1QixRQUFRLElBQUksR0FBRyxJQUFJLENBQUM7QUFDcEIsT0FBTyxNQUFNLElBQUksSUFBSSxLQUFLLEdBQUcsSUFBSSxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7QUFDM0UsUUFBUSxNQUFNLEdBQUcsR0FBRyx1Q0FBdUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDekUsUUFBUSxNQUFNLEdBQUcsR0FBRyxJQUFJLGVBQWUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDbEQsUUFBUSxHQUFHLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztBQUM1QixRQUFRLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQzdCLE9BQU87QUFDUCxLQUFLLE1BQU0sSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLElBQUksQ0FBQyxVQUFVLEVBQUU7QUFDOUMsTUFBTSxRQUFRLENBQUMsSUFBSSxDQUFDO0FBQ3BCLFFBQVEsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNO0FBQzVCLE9BQU8sQ0FBQyxDQUFDO0FBQ1QsS0FBSyxNQUFNLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsT0FBTyxFQUFFO0FBQzNDLE1BQU0scUJBQXFCLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztBQUM5QyxNQUFNLFFBQVEsQ0FBQyxJQUFJLENBQUM7QUFDcEIsUUFBUSxPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU87QUFDN0IsUUFBUSxNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU07QUFDNUIsT0FBTyxDQUFDLENBQUM7QUFDVCxLQUFLLE1BQU07QUFDWCxNQUFNLElBQUksSUFBSSxFQUFFO0FBQ2hCLFFBQVEsTUFBTSxHQUFHLEdBQUcsYUFBYSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztBQUNwRSxRQUFRLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksaUJBQWlCLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDMUQsT0FBTztBQUNQO0FBQ0EsTUFBTSxNQUFNLEtBQUssR0FBRyxXQUFXLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQzNDO0FBQ0EsTUFBTSxJQUFJLEdBQUcsS0FBSyxTQUFTLEVBQUU7QUFDN0IsUUFBUSxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQzFCLFFBQVEsUUFBUSxHQUFHLElBQUksQ0FBQztBQUN4QixPQUFPLE1BQU07QUFDYixRQUFRLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDekMsUUFBUSxHQUFHLEdBQUcsU0FBUyxDQUFDO0FBQ3hCLE9BQU87QUFDUDtBQUNBLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDO0FBQ2xDLE1BQU0sSUFBSSxHQUFHLEdBQUcsQ0FBQztBQUNqQixLQUFLO0FBQ0wsR0FBRztBQUNIO0FBQ0EsRUFBRSxzQkFBc0IsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQzFDLEVBQUUsSUFBSSxHQUFHLEtBQUssU0FBUyxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNuRCxFQUFFLE9BQU87QUFDVCxJQUFJLFFBQVE7QUFDWixJQUFJLEtBQUs7QUFDVCxHQUFHLENBQUM7QUFDSjs7QUMvSkEsU0FBUyxnQkFBZ0IsQ0FBQztBQUMxQixFQUFFLFNBQVM7QUFDWCxFQUFFLElBQUk7QUFDTixDQUFDLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUU7QUFDNUIsRUFBRSxNQUFNLGFBQWEsR0FBRyxFQUFFLENBQUM7QUFDM0I7QUFDQSxFQUFFLEtBQUssTUFBTSxHQUFHLElBQUksSUFBSSxFQUFFO0FBQzFCLElBQUksSUFBSSxHQUFHLENBQUMsR0FBRyxLQUFLLE9BQU8sRUFBRTtBQUM3QixNQUFNLElBQUksR0FBRyxDQUFDLElBQUksRUFBRTtBQUNwQixRQUFRLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFLGFBQWEsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxPQUFPLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsb0NBQW9DLENBQUMsQ0FBQyxDQUFDO0FBQzlJLE9BQU8sTUFBTTtBQUNiLFFBQVEsTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDaEQsUUFBUSxPQUFPLEdBQUcsWUFBWUQsWUFBVSxHQUFHLEdBQUcsR0FBRyxJQUFJLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNqRSxPQUFPO0FBQ1AsS0FBSztBQUNMLEdBQUc7QUFDSDtBQUNBLEVBQUUsSUFBSSxhQUFhLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxPQUFPLGFBQWEsQ0FBQyxLQUFLLEVBQUUsYUFBYSxDQUFDLENBQUM7QUFDM0UsRUFBRSxNQUFNLEVBQUUsR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDaEM7QUFDQSxFQUFFLElBQUksRUFBRSxFQUFFO0FBQ1YsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRTtBQUNwQyxNQUFNLE9BQU8sRUFBRSxLQUFLO0FBQ3BCLE1BQU0sSUFBSSxFQUFFLFNBQVM7QUFDckIsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUNSLElBQUksTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDM0MsSUFBSSxPQUFPLEdBQUcsWUFBWUEsWUFBVSxHQUFHLEdBQUcsR0FBRyxJQUFJLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUM3RCxHQUFHO0FBQ0g7QUFDQSxFQUFFLE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQztBQUNEO0FBQ0EsU0FBUyxVQUFVLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUU7QUFDeEMsRUFBRSxNQUFNO0FBQ1IsSUFBSSxHQUFHO0FBQ1AsSUFBSSxHQUFHO0FBQ1AsSUFBSSxHQUFHO0FBQ1AsR0FBRyxHQUFHLFdBQVcsQ0FBQztBQUNsQixFQUFFLElBQUksS0FBSyxFQUFFLFFBQVEsQ0FBQztBQUN0QjtBQUNBLEVBQUUsTUFBTSxPQUFPLEdBQUcsT0FBTyxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksaUJBQWlCLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUM7QUFDbkY7QUFDQSxFQUFFLElBQUk7QUFDTixJQUFJLFFBQVEsSUFBSSxDQUFDLElBQUk7QUFDckIsTUFBTSxLQUFLLElBQUksQ0FBQyxRQUFRLENBQUM7QUFDekIsTUFBTSxLQUFLLElBQUksQ0FBQyxHQUFHO0FBQ25CLFFBQVEsS0FBSyxHQUFHLFVBQVUsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDdEMsUUFBUSxRQUFRLEdBQUcsR0FBRyxDQUFDO0FBQ3ZCLFFBQVEsSUFBSSxPQUFPLEtBQUssR0FBRyxJQUFJLE9BQU8sS0FBSyxHQUFHLEVBQUUsT0FBTyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLGlDQUFpQyxDQUFDLENBQUMsQ0FBQztBQUN2SCxRQUFRLE1BQU07QUFDZDtBQUNBLE1BQU0sS0FBSyxJQUFJLENBQUMsUUFBUSxDQUFDO0FBQ3pCLE1BQU0sS0FBSyxJQUFJLENBQUMsR0FBRztBQUNuQixRQUFRLEtBQUssR0FBRyxVQUFVLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQ3RDLFFBQVEsUUFBUSxHQUFHLEdBQUcsQ0FBQztBQUN2QixRQUFRLElBQUksT0FBTyxLQUFLLEdBQUcsSUFBSSxPQUFPLEtBQUssR0FBRyxFQUFFLE9BQU8sQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxrQ0FBa0MsQ0FBQyxDQUFDLENBQUM7QUFDeEgsUUFBUSxNQUFNO0FBQ2Q7QUFDQSxNQUFNO0FBQ04sUUFBUSxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsSUFBSSxFQUFFLENBQUM7QUFDcEM7QUFDQSxRQUFRLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFO0FBQ3ZDLFVBQVUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDaEUsVUFBVSxLQUFLLEdBQUcsS0FBSyxDQUFDLEdBQUcsQ0FBQztBQUM1QixTQUFTO0FBQ1Q7QUFDQSxRQUFRLElBQUksT0FBTyxLQUFLLEdBQUcsSUFBSSxPQUFPLEtBQUssR0FBRyxFQUFFLE9BQU8sQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxnQ0FBZ0MsQ0FBQyxDQUFDLENBQUM7QUFDdEgsUUFBUSxRQUFRLEdBQUcsR0FBRyxDQUFDO0FBQ3ZCLEtBQUs7QUFDTDtBQUNBLElBQUksTUFBTSxHQUFHLEdBQUcsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQ3RFO0FBQ0EsSUFBSSxJQUFJLEdBQUcsRUFBRTtBQUNiLE1BQU0sSUFBSSxPQUFPLElBQUksSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxHQUFHLE9BQU8sQ0FBQztBQUNqRCxNQUFNLE9BQU8sR0FBRyxDQUFDO0FBQ2pCLEtBQUs7QUFDTCxHQUFHLENBQUMsT0FBTyxLQUFLLEVBQUU7QUFDbEI7QUFDQSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO0FBQzNDLElBQUksR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDM0IsSUFBSSxPQUFPLElBQUksQ0FBQztBQUNoQixHQUFHO0FBQ0g7QUFDQSxFQUFFLElBQUk7QUFDTixJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxpQkFBaUIsQ0FBQyxDQUFDLENBQUM7QUFDbEYsSUFBSSxNQUFNLEdBQUcsR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxtQ0FBbUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUNqRyxJQUFJLEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksV0FBVyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ2xELElBQUksTUFBTSxHQUFHLEdBQUcsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQ3ZFLElBQUksR0FBRyxDQUFDLEdBQUcsR0FBRyxPQUFPLENBQUM7QUFDdEIsSUFBSSxPQUFPLEdBQUcsQ0FBQztBQUNmLEdBQUcsQ0FBQyxPQUFPLEtBQUssRUFBRTtBQUNsQixJQUFJLE1BQU0sUUFBUSxHQUFHLElBQUksa0JBQWtCLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUNqRSxJQUFJLFFBQVEsQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQztBQUNqQyxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQzlCLElBQUksT0FBTyxJQUFJLENBQUM7QUFDaEIsR0FBRztBQUNIOztBQ2pHQSxNQUFNLGdCQUFnQixHQUFHLElBQUksSUFBSTtBQUNqQyxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsT0FBTyxLQUFLLENBQUM7QUFDMUIsRUFBRSxNQUFNO0FBQ1IsSUFBSSxJQUFJO0FBQ1IsR0FBRyxHQUFHLElBQUksQ0FBQztBQUNYLEVBQUUsT0FBTyxJQUFJLEtBQUssSUFBSSxDQUFDLE9BQU8sSUFBSSxJQUFJLEtBQUssSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLEtBQUssSUFBSSxDQUFDLFFBQVEsQ0FBQztBQUNwRixDQUFDLENBQUM7QUFDRjtBQUNBLFNBQVMsZ0JBQWdCLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRTtBQUN4QyxFQUFFLE1BQU0sUUFBUSxHQUFHO0FBQ25CLElBQUksTUFBTSxFQUFFLEVBQUU7QUFDZCxJQUFJLEtBQUssRUFBRSxFQUFFO0FBQ2IsR0FBRyxDQUFDO0FBQ0osRUFBRSxJQUFJLFNBQVMsR0FBRyxLQUFLLENBQUM7QUFDeEIsRUFBRSxJQUFJLE1BQU0sR0FBRyxLQUFLLENBQUM7QUFDckIsRUFBRSxNQUFNLEtBQUssR0FBRyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7QUFDbEg7QUFDQSxFQUFFLEtBQUssTUFBTTtBQUNiLElBQUksS0FBSztBQUNULElBQUksR0FBRztBQUNQLEdBQUcsSUFBSSxLQUFLLEVBQUU7QUFDZCxJQUFJLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDO0FBQ25DLE1BQU0sS0FBSyxJQUFJLENBQUMsT0FBTztBQUN2QixRQUFRO0FBQ1IsVUFBVSxJQUFJLENBQUMsSUFBSSxDQUFDLDRCQUE0QixDQUFDLEtBQUssQ0FBQyxFQUFFO0FBQ3pELFlBQVksTUFBTSxHQUFHLEdBQUcsd0VBQXdFLENBQUM7QUFDakcsWUFBWSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksaUJBQWlCLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDMUQsV0FBVztBQUNYO0FBQ0EsVUFBVSxNQUFNO0FBQ2hCLFlBQVksTUFBTTtBQUNsQixZQUFZLFVBQVU7QUFDdEIsV0FBVyxHQUFHLElBQUksQ0FBQztBQUNuQixVQUFVLE1BQU0sRUFBRSxHQUFHLFVBQVUsS0FBSyxLQUFLLEdBQUcsVUFBVSxDQUFDLEtBQUssSUFBSSxNQUFNLElBQUksS0FBSyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxRQUFRLENBQUMsS0FBSyxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUM7QUFDbkksVUFBVSxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDMUQsVUFBVSxNQUFNO0FBQ2hCLFNBQVM7QUFDVDtBQUNBO0FBQ0EsTUFBTSxLQUFLLElBQUksQ0FBQyxNQUFNO0FBQ3RCLFFBQVEsSUFBSSxTQUFTLEVBQUU7QUFDdkIsVUFBVSxNQUFNLEdBQUcsR0FBRyxvQ0FBb0MsQ0FBQztBQUMzRCxVQUFVLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxpQkFBaUIsQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUN4RCxTQUFTO0FBQ1Q7QUFDQSxRQUFRLFNBQVMsR0FBRyxJQUFJLENBQUM7QUFDekIsUUFBUSxNQUFNO0FBQ2Q7QUFDQSxNQUFNLEtBQUssSUFBSSxDQUFDLEdBQUc7QUFDbkIsUUFBUSxJQUFJLE1BQU0sRUFBRTtBQUNwQixVQUFVLE1BQU0sR0FBRyxHQUFHLGlDQUFpQyxDQUFDO0FBQ3hELFVBQVUsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLGlCQUFpQixDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3hELFNBQVM7QUFDVDtBQUNBLFFBQVEsTUFBTSxHQUFHLElBQUksQ0FBQztBQUN0QixRQUFRLE1BQU07QUFDZCxLQUFLO0FBQ0wsR0FBRztBQUNIO0FBQ0EsRUFBRSxPQUFPO0FBQ1QsSUFBSSxRQUFRO0FBQ1osSUFBSSxTQUFTO0FBQ2IsSUFBSSxNQUFNO0FBQ1YsR0FBRyxDQUFDO0FBQ0osQ0FBQztBQUNEO0FBQ0EsU0FBUyxnQkFBZ0IsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFO0FBQ3JDLEVBQUUsTUFBTTtBQUNSLElBQUksT0FBTztBQUNYLElBQUksTUFBTTtBQUNWLElBQUksTUFBTTtBQUNWLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDVjtBQUNBLEVBQUUsSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLElBQUksQ0FBQyxLQUFLLEVBQUU7QUFDaEMsSUFBSSxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDO0FBQy9CLElBQUksTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUN0QztBQUNBLElBQUksSUFBSSxDQUFDLEdBQUcsRUFBRTtBQUNkLE1BQU0sTUFBTSxHQUFHLEdBQUcsNEJBQTRCLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQzVELE1BQU0sTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLGtCQUFrQixDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3JELE1BQU0sT0FBTyxJQUFJLENBQUM7QUFDbEIsS0FBSztBQUNMO0FBQ0E7QUFDQSxJQUFJLE1BQU0sR0FBRyxHQUFHLElBQUlDLE9BQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUMvQjtBQUNBLElBQUksT0FBTyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDbEM7QUFDQSxJQUFJLE9BQU8sR0FBRyxDQUFDO0FBQ2YsR0FBRztBQUNIO0FBQ0EsRUFBRSxNQUFNLE9BQU8sR0FBRyxjQUFjLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQzVDLEVBQUUsSUFBSSxPQUFPLEVBQUUsT0FBTyxVQUFVLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztBQUNyRDtBQUNBLEVBQUUsSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLElBQUksQ0FBQyxLQUFLLEVBQUU7QUFDaEMsSUFBSSxNQUFNLEdBQUcsR0FBRyxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxZQUFZLENBQUMsQ0FBQztBQUNyRSxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxlQUFlLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDaEQsSUFBSSxPQUFPLElBQUksQ0FBQztBQUNoQixHQUFHO0FBQ0g7QUFDQSxFQUFFLElBQUk7QUFDTixJQUFJLElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxRQUFRLElBQUksRUFBRSxDQUFDO0FBQ2xDO0FBQ0EsSUFBSSxJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVEsRUFBRTtBQUNqQyxNQUFNLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssSUFBSSxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQzFELE1BQU0sR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUM7QUFDcEIsS0FBSztBQUNMO0FBQ0EsSUFBSSxPQUFPLGFBQWEsQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQzNDLEdBQUcsQ0FBQyxPQUFPLEtBQUssRUFBRTtBQUNsQixJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO0FBQzNDLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUN2QixJQUFJLE9BQU8sSUFBSSxDQUFDO0FBQ2hCLEdBQUc7QUFDSCxDQUFDO0FBQ0Q7QUFDQTtBQUNBLFNBQVMsV0FBVyxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUU7QUFDaEMsRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFLE9BQU8sSUFBSSxDQUFDO0FBQ3pCLEVBQUUsSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUM5QyxFQUFFLE1BQU07QUFDUixJQUFJLFFBQVE7QUFDWixJQUFJLFNBQVM7QUFDYixJQUFJLE1BQU07QUFDVixHQUFHLEdBQUcsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztBQUN6QztBQUNBLEVBQUUsSUFBSSxTQUFTLEVBQUU7QUFDakIsSUFBSSxNQUFNO0FBQ1YsTUFBTSxPQUFPO0FBQ2IsS0FBSyxHQUFHLEdBQUcsQ0FBQztBQUNaLElBQUksTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztBQUM3QixJQUFJLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDdkM7QUFDQTtBQUNBLElBQUksSUFBSSxJQUFJLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDO0FBQ3hEO0FBQ0E7QUFDQTtBQUNBLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUM7QUFDN0IsR0FBRztBQUNIO0FBQ0EsRUFBRSxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLEtBQUssS0FBSyxTQUFTLElBQUksTUFBTSxDQUFDLEVBQUU7QUFDekQsSUFBSSxNQUFNLEdBQUcsR0FBRywrQ0FBK0MsQ0FBQztBQUNoRSxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksaUJBQWlCLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDdEQsR0FBRztBQUNIO0FBQ0EsRUFBRSxNQUFNLEdBQUcsR0FBRyxnQkFBZ0IsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDMUM7QUFDQSxFQUFFLElBQUksR0FBRyxFQUFFO0FBQ1gsSUFBSSxHQUFHLENBQUMsS0FBSyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNuRCxJQUFJLElBQUksR0FBRyxDQUFDLE9BQU8sQ0FBQyxZQUFZLEVBQUUsR0FBRyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUM7QUFDckQsSUFBSSxJQUFJLEdBQUcsQ0FBQyxPQUFPLENBQUMsYUFBYSxFQUFFLEdBQUcsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztBQUN4RCxJQUFJLE1BQU0sRUFBRSxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQzFDO0FBQ0EsSUFBSSxJQUFJLEVBQUUsRUFBRTtBQUNaLE1BQU0sR0FBRyxDQUFDLGFBQWEsR0FBRyxHQUFHLENBQUMsYUFBYSxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2pHLEtBQUs7QUFDTDtBQUNBLElBQUksTUFBTSxFQUFFLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDekMsSUFBSSxJQUFJLEVBQUUsRUFBRSxHQUFHLENBQUMsT0FBTyxHQUFHLEdBQUcsQ0FBQyxPQUFPLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDckYsR0FBRztBQUNIO0FBQ0EsRUFBRSxPQUFPLElBQUksQ0FBQyxRQUFRLEdBQUcsR0FBRyxDQUFDO0FBQzdCOztBQ3JLQSxTQUFTLGFBQWEsQ0FBQyxHQUFHLEVBQUUsUUFBUSxFQUFFO0FBQ3RDLEVBQUUsTUFBTSxRQUFRLEdBQUc7QUFDbkIsSUFBSSxNQUFNLEVBQUUsRUFBRTtBQUNkLElBQUksS0FBSyxFQUFFLEVBQUU7QUFDYixHQUFHLENBQUM7QUFDSixFQUFFLElBQUksSUFBSSxHQUFHLFNBQVMsQ0FBQztBQUN2QixFQUFFLElBQUksV0FBVyxHQUFHLEtBQUssQ0FBQztBQUMxQjtBQUNBLEVBQUUsS0FBSyxNQUFNLElBQUksSUFBSSxRQUFRLEVBQUU7QUFDL0IsSUFBSSxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUU7QUFDekIsTUFBTSxJQUFJLElBQUksS0FBSyxTQUFTLEVBQUU7QUFDOUIsUUFBUSxNQUFNLEdBQUcsR0FBRyx1RUFBdUUsQ0FBQztBQUM1RixRQUFRLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksZUFBZSxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3hELFFBQVEsTUFBTTtBQUNkLE9BQU87QUFDUDtBQUNBLE1BQU0sTUFBTSxHQUFHLEdBQUcsV0FBVyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztBQUN6QztBQUNBLE1BQU0sSUFBSSxXQUFXLEVBQUU7QUFDdkIsUUFBUSxHQUFHLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztBQUMvQixRQUFRLFdBQVcsR0FBRyxLQUFLLENBQUM7QUFDNUIsT0FBTztBQUNQO0FBQ0EsTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDO0FBQ2pCLEtBQUssTUFBTSxJQUFJLElBQUksQ0FBQyxPQUFPLEtBQUssSUFBSSxFQUFFO0FBQ3RDLE1BQU0sTUFBTSxFQUFFLEdBQUcsSUFBSSxLQUFLLFNBQVMsR0FBRyxRQUFRLENBQUMsTUFBTSxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUM7QUFDdkUsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUM1QixLQUFLLE1BQU0sSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLElBQUksQ0FBQyxVQUFVLEVBQUU7QUFDOUMsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDO0FBQ3pCO0FBQ0EsTUFBTSxJQUFJLElBQUksS0FBSyxTQUFTLElBQUksUUFBUSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRTtBQUNsRjtBQUNBLFFBQVEsR0FBRyxDQUFDLGFBQWEsR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUN2RCxRQUFRLFFBQVEsQ0FBQyxNQUFNLEdBQUcsRUFBRSxDQUFDO0FBQzdCLE9BQU87QUFDUCxLQUFLO0FBQ0wsR0FBRztBQUNIO0FBQ0EsRUFBRSxHQUFHLENBQUMsUUFBUSxHQUFHLElBQUksSUFBSSxJQUFJLENBQUM7QUFDOUI7QUFDQSxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUU7QUFDYixJQUFJLEdBQUcsQ0FBQyxPQUFPLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUM7QUFDNUUsR0FBRyxNQUFNO0FBQ1QsSUFBSSxNQUFNLEVBQUUsR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUMxQztBQUNBLElBQUksSUFBSSxFQUFFLEVBQUU7QUFDWixNQUFNLE1BQU0sTUFBTSxHQUFHLElBQUksWUFBWUQsWUFBVSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUM7QUFDeEYsTUFBTSxNQUFNLENBQUMsYUFBYSxHQUFHLE1BQU0sQ0FBQyxhQUFhLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDMUcsS0FBSztBQUNMO0FBQ0EsSUFBSSxHQUFHLENBQUMsT0FBTyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQztBQUNwRCxHQUFHO0FBQ0g7O0FDdERBLFNBQVMsbUJBQW1CLENBQUM7QUFDN0IsRUFBRSxXQUFXO0FBQ2IsQ0FBQyxFQUFFLFNBQVMsRUFBRTtBQUNkLEVBQUUsTUFBTSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsR0FBRyxTQUFTLENBQUMsVUFBVSxDQUFDO0FBQ2hEO0FBQ0EsRUFBRSxJQUFJLENBQUMsTUFBTSxJQUFJLENBQUMsTUFBTSxFQUFFO0FBQzFCLElBQUksTUFBTSxHQUFHLEdBQUcsa0RBQWtELENBQUM7QUFDbkUsSUFBSSxNQUFNLElBQUksaUJBQWlCLENBQUMsU0FBUyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ2hELEdBQUc7QUFDSDtBQUNBLEVBQUUsSUFBSSxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxLQUFLLE1BQU0sQ0FBQyxFQUFFO0FBQ2xELElBQUksTUFBTSxHQUFHLEdBQUcscUZBQXFGLENBQUM7QUFDdEcsSUFBSSxNQUFNLElBQUksaUJBQWlCLENBQUMsU0FBUyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ2hELEdBQUc7QUFDSDtBQUNBLEVBQUUsT0FBTztBQUNULElBQUksTUFBTTtBQUNWLElBQUksTUFBTTtBQUNWLEdBQUcsQ0FBQztBQUNKLENBQUM7QUFDRDtBQUNBLFNBQVMsb0JBQW9CLENBQUMsR0FBRyxFQUFFLFNBQVMsRUFBRTtBQUM5QyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxTQUFTLENBQUMsVUFBVSxDQUFDO0FBQ3ZDLEVBQUUsSUFBSSxTQUFTLENBQUMsSUFBSSxLQUFLLFVBQVUsRUFBRSxPQUFPLEdBQUcsS0FBSyxDQUFDO0FBQ3JEO0FBQ0EsRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFO0FBQ2hCLElBQUksTUFBTSxHQUFHLEdBQUcsbURBQW1ELENBQUM7QUFDcEUsSUFBSSxNQUFNLElBQUksaUJBQWlCLENBQUMsU0FBUyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ2hELEdBQUc7QUFDSDtBQUNBLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsRUFBRTtBQUNqQyxJQUFJLE1BQU0sRUFBRSxHQUFHLEdBQUcsQ0FBQyxPQUFPLElBQUksR0FBRyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUM7QUFDbEQsSUFBSSxNQUFNLEdBQUcsR0FBRyxrQ0FBa0MsQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLG9CQUFvQixDQUFDLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3BHLElBQUksR0FBRyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxXQUFXLENBQUMsU0FBUyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDdkQsR0FBRztBQUNIO0FBQ0EsRUFBRSxPQUFPLE9BQU8sQ0FBQztBQUNqQixDQUFDO0FBQ0Q7QUFDQSxTQUFTLGVBQWUsQ0FBQyxHQUFHLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRTtBQUNuRCxFQUFFLE1BQU0saUJBQWlCLEdBQUcsRUFBRSxDQUFDO0FBQy9CLEVBQUUsSUFBSSxhQUFhLEdBQUcsS0FBSyxDQUFDO0FBQzVCO0FBQ0EsRUFBRSxLQUFLLE1BQU0sU0FBUyxJQUFJLFVBQVUsRUFBRTtBQUN0QyxJQUFJLE1BQU07QUFDVixNQUFNLE9BQU87QUFDYixNQUFNLElBQUk7QUFDVixLQUFLLEdBQUcsU0FBUyxDQUFDO0FBQ2xCO0FBQ0EsSUFBSSxRQUFRLElBQUk7QUFDaEIsTUFBTSxLQUFLLEtBQUs7QUFDaEIsUUFBUSxJQUFJO0FBQ1osVUFBVSxHQUFHLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxHQUFHLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQztBQUNwRSxTQUFTLENBQUMsT0FBTyxLQUFLLEVBQUU7QUFDeEIsVUFBVSxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUNqQyxTQUFTO0FBQ1Q7QUFDQSxRQUFRLGFBQWEsR0FBRyxJQUFJLENBQUM7QUFDN0IsUUFBUSxNQUFNO0FBQ2Q7QUFDQSxNQUFNLEtBQUssTUFBTSxDQUFDO0FBQ2xCLE1BQU0sS0FBSyxVQUFVO0FBQ3JCLFFBQVEsSUFBSSxHQUFHLENBQUMsT0FBTyxFQUFFO0FBQ3pCLFVBQVUsTUFBTSxHQUFHLEdBQUcsbUVBQW1FLENBQUM7QUFDMUYsVUFBVSxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLGlCQUFpQixDQUFDLFNBQVMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ2pFLFNBQVM7QUFDVDtBQUNBLFFBQVEsSUFBSTtBQUNaLFVBQVUsR0FBRyxDQUFDLE9BQU8sR0FBRyxvQkFBb0IsQ0FBQyxHQUFHLEVBQUUsU0FBUyxDQUFDLENBQUM7QUFDN0QsU0FBUyxDQUFDLE9BQU8sS0FBSyxFQUFFO0FBQ3hCLFVBQVUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDakMsU0FBUztBQUNUO0FBQ0EsUUFBUSxhQUFhLEdBQUcsSUFBSSxDQUFDO0FBQzdCLFFBQVEsTUFBTTtBQUNkO0FBQ0EsTUFBTTtBQUNOLFFBQVEsSUFBSSxJQUFJLEVBQUU7QUFDbEIsVUFBVSxNQUFNLEdBQUcsR0FBRyx5REFBeUQsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDN0YsVUFBVSxHQUFHLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLFdBQVcsQ0FBQyxTQUFTLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUM3RCxTQUFTO0FBQ1Q7QUFDQSxLQUFLO0FBQ0w7QUFDQSxJQUFJLElBQUksT0FBTyxFQUFFLGlCQUFpQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUNqRCxHQUFHO0FBQ0g7QUFDQSxFQUFFLElBQUksT0FBTyxJQUFJLENBQUMsYUFBYSxJQUFJLEtBQUssTUFBTSxHQUFHLENBQUMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxPQUFPLElBQUksR0FBRyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRTtBQUN0RyxJQUFJLE1BQU0sYUFBYSxHQUFHLENBQUM7QUFDM0IsTUFBTSxNQUFNO0FBQ1osTUFBTSxNQUFNO0FBQ1osS0FBSyxNQUFNO0FBQ1gsTUFBTSxNQUFNO0FBQ1osTUFBTSxNQUFNO0FBQ1osS0FBSyxDQUFDLENBQUM7QUFDUDtBQUNBLElBQUksR0FBRyxDQUFDLFdBQVcsR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsQ0FBQztBQUM3RCxJQUFJLEdBQUcsQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQztBQUNsQyxHQUFHO0FBQ0g7QUFDQSxFQUFFLEdBQUcsQ0FBQyxhQUFhLEdBQUcsaUJBQWlCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQztBQUMzRDs7QUNuRkEsU0FBUyxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUU7QUFDcEMsRUFBRSxJQUFJLFFBQVEsWUFBWUEsWUFBVSxFQUFFLE9BQU8sSUFBSSxDQUFDO0FBQ2xELEVBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxpREFBaUQsQ0FBQyxDQUFDO0FBQ3JFLENBQUM7QUFDRDtBQUNBLE1BQU1NLFVBQVEsQ0FBQztBQUNmLEVBQUUsV0FBVyxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFO0FBQ3hDLElBQUksSUFBSSxPQUFPLEtBQUssU0FBUyxJQUFJLFFBQVEsSUFBSSxPQUFPLFFBQVEsS0FBSyxRQUFRLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFO0FBQ3ZHLE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQztBQUN6QixNQUFNLFFBQVEsR0FBRyxTQUFTLENBQUM7QUFDM0IsS0FBSztBQUNMO0FBQ0EsSUFBSSxJQUFJLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLGNBQWMsRUFBRSxPQUFPLENBQUMsQ0FBQztBQUM5RCxJQUFJLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUMxRCxJQUFJLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDO0FBQzlCLElBQUksSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUM7QUFDeEIsSUFBSSxJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxDQUFDO0FBQ3BDLElBQUksSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUM7QUFDckIsSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQztBQUN2QixJQUFJLElBQUksQ0FBQyxXQUFXLEdBQUcsRUFBRSxDQUFDO0FBQzFCLElBQUksSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUM7QUFDeEIsSUFBSSxJQUFJLENBQUMsUUFBUSxHQUFHLEVBQUUsQ0FBQztBQUN2QjtBQUNBLElBQUksSUFBSSxLQUFLLEtBQUssU0FBUyxFQUFFO0FBQzdCO0FBQ0EsTUFBTSxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztBQUMzQixLQUFLLE1BQU0sSUFBSSxLQUFLLFlBQVlDLFFBQVUsRUFBRTtBQUM1QyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDeEIsS0FBSyxNQUFNO0FBQ1gsTUFBTSxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFO0FBQzdDLFFBQVEsUUFBUTtBQUNoQixPQUFPLENBQUMsQ0FBQztBQUNULEtBQUs7QUFDTCxHQUFHO0FBQ0g7QUFDQSxFQUFFLEdBQUcsQ0FBQyxLQUFLLEVBQUU7QUFDYixJQUFJLGdCQUFnQixDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUNwQyxJQUFJLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDcEMsR0FBRztBQUNIO0FBQ0EsRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRTtBQUNyQixJQUFJLGdCQUFnQixDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUNwQyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztBQUNyQyxHQUFHO0FBQ0g7QUFDQSxFQUFFLFVBQVUsQ0FBQyxLQUFLLEVBQUU7QUFDcEIsSUFBSSxhQUFhO0FBQ2pCLElBQUksUUFBUTtBQUNaLElBQUksUUFBUTtBQUNaLElBQUksR0FBRztBQUNQLElBQUksV0FBVztBQUNmLEdBQUcsR0FBRyxFQUFFLEVBQUU7QUFDVixJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztBQUNyQixJQUFJLElBQUksT0FBTyxRQUFRLEtBQUssVUFBVSxFQUFFLEtBQUssR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDO0FBQzlELE1BQU0sRUFBRSxFQUFFLEtBQUs7QUFDZixLQUFLLEVBQUUsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDLEtBQUssSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFO0FBQ3BELE1BQU0sTUFBTSxRQUFRLEdBQUcsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxLQUFLLFFBQVEsSUFBSSxDQUFDLFlBQVksTUFBTSxJQUFJLENBQUMsWUFBWSxNQUFNLENBQUM7QUFDaEc7QUFDQSxNQUFNLE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQzFELE1BQU0sSUFBSSxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxRQUFRLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUM5RCxLQUFLO0FBQ0wsSUFBSSxJQUFJLE9BQU8sYUFBYSxLQUFLLFNBQVMsRUFBRSxhQUFhLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDO0FBQ3pGLElBQUksTUFBTSxVQUFVLEdBQUcsRUFBRSxDQUFDO0FBQzFCLElBQUksTUFBTSxHQUFHLEdBQUc7QUFDaEIsTUFBTSxhQUFhO0FBQ25CO0FBQ0EsTUFBTSxPQUFPLENBQUMsTUFBTSxFQUFFO0FBQ3RCLFFBQVEsTUFBTSxLQUFLLEdBQUcsSUFBSU4sT0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ3hDLFFBQVEsVUFBVSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUMvQixRQUFRLE9BQU8sS0FBSyxDQUFDO0FBQ3JCLE9BQU87QUFDUDtBQUNBLE1BQU0sUUFBUTtBQUNkLE1BQU0sV0FBVyxFQUFFLElBQUksR0FBRyxFQUFFO0FBQzVCLE1BQU0sUUFBUTtBQUNkLE1BQU0sTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO0FBQ3pCLE1BQU0sV0FBVyxFQUFFLFdBQVcsS0FBSyxLQUFLO0FBQ3hDLEtBQUssQ0FBQztBQUNOLElBQUksTUFBTSxJQUFJLEdBQUcsVUFBVSxDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFDN0M7QUFDQSxJQUFJLEtBQUssTUFBTSxLQUFLLElBQUksVUFBVSxFQUFFO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBLE1BQU0sS0FBSyxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztBQUN2QyxNQUFNLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUNwRDtBQUNBLE1BQU0sSUFBSSxDQUFDLElBQUksRUFBRTtBQUNqQixRQUFRLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDO0FBQ3RDLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQztBQUM5QyxPQUFPO0FBQ1AsS0FBSztBQUNMO0FBQ0EsSUFBSSxPQUFPLElBQUksQ0FBQztBQUNoQixHQUFHO0FBQ0g7QUFDQSxFQUFFLFVBQVUsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLE9BQU8sR0FBRyxFQUFFLEVBQUU7QUFDdkMsSUFBSSxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRSxPQUFPLENBQUMsQ0FBQztBQUM1QyxJQUFJLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQzlDLElBQUksT0FBTyxJQUFJLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDMUIsR0FBRztBQUNIO0FBQ0EsRUFBRSxNQUFNLENBQUMsR0FBRyxFQUFFO0FBQ2QsSUFBSSxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDcEMsSUFBSSxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3JDLEdBQUc7QUFDSDtBQUNBLEVBQUUsUUFBUSxDQUFDLElBQUksRUFBRTtBQUNqQixJQUFJLElBQUksV0FBVyxDQUFDLElBQUksQ0FBQyxFQUFFO0FBQzNCLE1BQU0sSUFBSSxJQUFJLENBQUMsUUFBUSxJQUFJLElBQUksRUFBRSxPQUFPLEtBQUssQ0FBQztBQUM5QyxNQUFNLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO0FBQzNCLE1BQU0sT0FBTyxJQUFJLENBQUM7QUFDbEIsS0FBSztBQUNMO0FBQ0EsSUFBSSxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDcEMsSUFBSSxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ3hDLEdBQUc7QUFDSDtBQUNBLEVBQUUsV0FBVyxHQUFHO0FBQ2hCLElBQUksT0FBT0ssVUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUlBLFVBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUM7QUFDNUYsR0FBRztBQUNIO0FBQ0EsRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLFVBQVUsRUFBRTtBQUN2QixJQUFJLE9BQU8sSUFBSSxDQUFDLFFBQVEsWUFBWU4sWUFBVSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxVQUFVLENBQUMsR0FBRyxTQUFTLENBQUM7QUFDaEcsR0FBRztBQUNIO0FBQ0EsRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLFVBQVUsRUFBRTtBQUMxQixJQUFJLElBQUksV0FBVyxDQUFDLElBQUksQ0FBQyxFQUFFLE9BQU8sQ0FBQyxVQUFVLElBQUksSUFBSSxDQUFDLFFBQVEsWUFBWSxNQUFNLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQztBQUN2SCxJQUFJLE9BQU8sSUFBSSxDQUFDLFFBQVEsWUFBWUEsWUFBVSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxVQUFVLENBQUMsR0FBRyxTQUFTLENBQUM7QUFDbkcsR0FBRztBQUNIO0FBQ0EsRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFO0FBQ1gsSUFBSSxPQUFPLElBQUksQ0FBQyxRQUFRLFlBQVlBLFlBQVUsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxLQUFLLENBQUM7QUFDaEYsR0FBRztBQUNIO0FBQ0EsRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFO0FBQ2QsSUFBSSxJQUFJLFdBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxPQUFPLElBQUksQ0FBQyxRQUFRLEtBQUssU0FBUyxDQUFDO0FBQzlELElBQUksT0FBTyxJQUFJLENBQUMsUUFBUSxZQUFZQSxZQUFVLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDO0FBQ25GLEdBQUc7QUFDSDtBQUNBLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUU7QUFDbEIsSUFBSSxJQUFJLElBQUksQ0FBQyxRQUFRLElBQUksSUFBSSxFQUFFO0FBQy9CLE1BQU0sSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO0FBQ3ZCLE1BQU0sSUFBSSxDQUFDLFFBQVEsR0FBRyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDcEUsS0FBSyxNQUFNO0FBQ1gsTUFBTSxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDdEMsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDcEMsS0FBSztBQUNMLEdBQUc7QUFDSDtBQUNBLEVBQUUsS0FBSyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUU7QUFDckIsSUFBSSxJQUFJLFdBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLFFBQVEsSUFBSSxJQUFJLEVBQUU7QUFDakYsTUFBTSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7QUFDdkIsTUFBTSxJQUFJLENBQUMsUUFBUSxHQUFHLGtCQUFrQixDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQ25FLEtBQUssTUFBTTtBQUNYLE1BQU0sZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ3RDLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQ3ZDLEtBQUs7QUFDTCxHQUFHO0FBQ0g7QUFDQSxFQUFFLFNBQVMsQ0FBQyxFQUFFLEVBQUUsVUFBVSxFQUFFO0FBQzVCLElBQUksSUFBSSxDQUFDLEVBQUUsSUFBSSxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLE9BQU87QUFDbEQsSUFBSSxJQUFJLE9BQU8sRUFBRSxLQUFLLFFBQVEsRUFBRSxFQUFFLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNuRDtBQUNBLElBQUksSUFBSSxFQUFFLEtBQUssS0FBSyxJQUFJLEVBQUUsS0FBSyxLQUFLLElBQUksRUFBRSxLQUFLLEtBQUssRUFBRTtBQUN0RCxNQUFNLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQyxLQUFLLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztBQUN6RSxNQUFNLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7QUFDakMsS0FBSyxNQUFNLElBQUksRUFBRSxJQUFJLE9BQU8sRUFBRSxLQUFLLFFBQVEsRUFBRTtBQUM3QyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQztBQUMvQixLQUFLO0FBQ0w7QUFDQSxJQUFJLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7QUFDeEUsSUFBSSxNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsV0FBVyxFQUFFLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3BFLElBQUksSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNsQyxHQUFHO0FBQ0g7QUFDQSxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsT0FBTyxFQUFFO0FBQ3ZCLElBQUksSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztBQUN2RCxJQUFJLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLElBQUksR0FBRyxVQUFVLENBQUM7QUFDM0QsSUFBSSxNQUFNO0FBQ1YsTUFBTSxVQUFVLEdBQUcsRUFBRTtBQUNyQixNQUFNLFFBQVEsR0FBRyxFQUFFO0FBQ25CLE1BQU0sbUJBQW1CO0FBQ3pCLE1BQU0sS0FBSztBQUNYLE1BQU0sVUFBVTtBQUNoQixLQUFLLEdBQUcsSUFBSSxDQUFDO0FBQ2I7QUFDQSxJQUFJLElBQUksS0FBSyxFQUFFO0FBQ2YsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQztBQUM3QyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQzlCLEtBQUs7QUFDTDtBQUNBLElBQUksZUFBZSxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDL0MsSUFBSSxJQUFJLG1CQUFtQixFQUFFLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUM7QUFDN0QsSUFBSSxJQUFJLENBQUMsS0FBSyxHQUFHLFVBQVUsR0FBRyxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQztBQUN4RSxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztBQUNyQixJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxHQUFHLEVBQUUsQ0FBQztBQUNsQyxJQUFJLGFBQWEsQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUM7QUFDbEMsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksRUFBRSxDQUFDO0FBQ2hDO0FBQ0EsSUFBSSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFO0FBQ25DLE1BQU0sS0FBSyxNQUFNLEtBQUssSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksS0FBSyxZQUFZLFNBQVMsRUFBRSxLQUFLLENBQUMsVUFBVSxFQUFFLENBQUM7QUFDMUY7QUFDQSxNQUFNLEtBQUssTUFBTSxJQUFJLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLElBQUksWUFBWSxTQUFTLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO0FBQ3pGLEtBQUs7QUFDTDtBQUNBLElBQUksT0FBTyxJQUFJLENBQUM7QUFDaEIsR0FBRztBQUNIO0FBQ0EsRUFBRSxrQkFBa0IsR0FBRztBQUN2QixJQUFJLE9BQU8sWUFBWSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUN0RixHQUFHO0FBQ0g7QUFDQSxFQUFFLFlBQVksQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFO0FBQy9CLElBQUksSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxLQUFLLEdBQUcsRUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLGtDQUFrQyxDQUFDLENBQUM7QUFDcEg7QUFDQSxJQUFJLElBQUksTUFBTSxFQUFFO0FBQ2hCLE1BQU0sTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLEtBQUssTUFBTSxDQUFDLENBQUM7QUFDbkUsTUFBTSxJQUFJLElBQUksRUFBRSxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxLQUFLLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDO0FBQ2hFLFFBQVEsTUFBTTtBQUNkLFFBQVEsTUFBTTtBQUNkLE9BQU8sQ0FBQyxDQUFDO0FBQ1QsS0FBSyxNQUFNO0FBQ1gsTUFBTSxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxLQUFLLE1BQU0sQ0FBQyxDQUFDO0FBQzNFLEtBQUs7QUFDTCxHQUFHO0FBQ0g7QUFDQSxFQUFFLElBQUksQ0FBQztBQUNQLElBQUksSUFBSTtBQUNSLElBQUksT0FBTztBQUNYLElBQUksUUFBUTtBQUNaLElBQUksUUFBUTtBQUNaLElBQUksT0FBTztBQUNYLEdBQUcsR0FBRyxFQUFFLEVBQUU7QUFDVixJQUFJLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFO0FBQzNFLE1BQU0sS0FBSyxFQUFFLEVBQUU7QUFDZixNQUFNLFVBQVUsRUFBRSxDQUFDO0FBQ25CLE1BQU0sS0FBSyxFQUFFLENBQUM7QUFDZCxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQ1IsSUFBSSxNQUFNLE9BQU8sR0FBRyxXQUFXLENBQUMsTUFBTSxHQUFHLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxXQUFXLENBQUMsR0FBRyxJQUFJLENBQUM7QUFDekUsSUFBSSxNQUFNLEdBQUcsR0FBRztBQUNoQixNQUFNLE9BQU87QUFDYixNQUFNLEdBQUcsRUFBRSxJQUFJO0FBQ2YsTUFBTSxVQUFVLEVBQUUsSUFBSTtBQUN0QixNQUFNLElBQUksRUFBRSxDQUFDLElBQUk7QUFDakIsTUFBTSxRQUFRLEVBQUUsT0FBTyxRQUFRLEtBQUssU0FBUyxHQUFHLFFBQVEsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRO0FBQ2xGLE1BQU0sWUFBWSxFQUFFLEtBQUs7QUFDekIsTUFBTSxhQUFhLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhO0FBQy9DLE1BQU0sU0FBUztBQUNmO0FBQ0EsS0FBSyxDQUFDO0FBQ04sSUFBSSxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxPQUFPLElBQUksRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ3hELElBQUksSUFBSSxPQUFPLFFBQVEsS0FBSyxVQUFVLElBQUksT0FBTyxFQUFFLEtBQUssTUFBTTtBQUM5RCxNQUFNLEtBQUs7QUFDWCxNQUFNLEdBQUc7QUFDVCxLQUFLLElBQUksT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLFFBQVEsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDaEQsSUFBSSxPQUFPLE9BQU8sT0FBTyxLQUFLLFVBQVUsR0FBRyxZQUFZLENBQUMsT0FBTyxFQUFFO0FBQ2pFLE1BQU0sRUFBRSxFQUFFLEdBQUc7QUFDYixLQUFLLEVBQUUsRUFBRSxFQUFFLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUN0QixHQUFHO0FBQ0g7QUFDQSxFQUFFLE1BQU0sQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFO0FBQzVCLElBQUksT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDO0FBQ3JCLE1BQU0sSUFBSSxFQUFFLElBQUk7QUFDaEIsTUFBTSxPQUFPO0FBQ2IsTUFBTSxRQUFRLEVBQUUsS0FBSztBQUNyQixNQUFNLFFBQVE7QUFDZCxLQUFLLENBQUMsQ0FBQztBQUNQLEdBQUc7QUFDSDtBQUNBLEVBQUUsUUFBUSxHQUFHO0FBQ2IsSUFBSSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLDRDQUE0QyxDQUFDLENBQUM7QUFDOUYsSUFBSSxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQztBQUMzQztBQUNBLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLElBQUksVUFBVSxJQUFJLENBQUMsRUFBRTtBQUMxRCxNQUFNLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLENBQUM7QUFDM0MsTUFBTSxNQUFNLElBQUksS0FBSyxDQUFDLG9EQUFvRCxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3RGLEtBQUs7QUFDTDtBQUNBLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO0FBQ3JCLElBQUksTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFDO0FBQ3JCLElBQUksSUFBSSxhQUFhLEdBQUcsS0FBSyxDQUFDO0FBQzlCO0FBQ0EsSUFBSSxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUU7QUFDdEIsTUFBTSxJQUFJLEVBQUUsR0FBRyxXQUFXLENBQUM7QUFDM0I7QUFDQSxNQUFNLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssVUFBVSxFQUFFO0FBQzNDLFFBQVEsSUFBSSxJQUFJLENBQUMsT0FBTyxLQUFLLEtBQUssRUFBRSxFQUFFLEdBQUcsV0FBVyxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsT0FBTyxLQUFLLEtBQUssRUFBRSxFQUFFLEdBQUcsV0FBVyxDQUFDO0FBQ3ZHLE9BQU87QUFDUDtBQUNBLE1BQU0sS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNyQixNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUM7QUFDM0IsS0FBSztBQUNMO0FBQ0EsSUFBSSxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztBQUMvQyxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDOUIsTUFBTSxNQUFNO0FBQ1osTUFBTSxNQUFNO0FBQ1osS0FBSyxLQUFLO0FBQ1YsTUFBTSxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUU7QUFDdkQsUUFBUSxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO0FBQy9ELFFBQVEsYUFBYSxHQUFHLElBQUksQ0FBQztBQUM3QixPQUFPO0FBQ1AsS0FBSyxDQUFDLENBQUM7QUFDUCxJQUFJLElBQUksYUFBYSxJQUFJLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ3JFO0FBQ0EsSUFBSSxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUU7QUFDNUIsTUFBTSxJQUFJLGFBQWEsSUFBSSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3hFLE1BQU0sS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUM1RCxLQUFLO0FBQ0w7QUFDQSxJQUFJLE1BQU0sR0FBRyxHQUFHO0FBQ2hCLE1BQU0sT0FBTyxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDO0FBQ2xDLE1BQU0sR0FBRyxFQUFFLElBQUk7QUFDZixNQUFNLE1BQU0sRUFBRSxFQUFFO0FBQ2hCLE1BQU0sVUFBVSxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDO0FBQ3hDLE1BQU0sU0FBUztBQUNmO0FBQ0EsS0FBSyxDQUFDO0FBQ04sSUFBSSxJQUFJLFNBQVMsR0FBRyxLQUFLLENBQUM7QUFDMUIsSUFBSSxJQUFJLGNBQWMsR0FBRyxJQUFJLENBQUM7QUFDOUI7QUFDQSxJQUFJLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtBQUN2QixNQUFNLElBQUksSUFBSSxDQUFDLFFBQVEsWUFBWUQsTUFBSSxFQUFFO0FBQ3pDLFFBQVEsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsS0FBSyxhQUFhLElBQUksSUFBSSxDQUFDLG1CQUFtQixDQUFDLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNyRyxRQUFRLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDckc7QUFDQSxRQUFRLEdBQUcsQ0FBQyxnQkFBZ0IsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztBQUM5QyxRQUFRLGNBQWMsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQztBQUMvQyxPQUFPO0FBQ1A7QUFDQSxNQUFNLE1BQU0sV0FBVyxHQUFHLGNBQWMsR0FBRyxJQUFJLEdBQUcsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDO0FBQ3pFLE1BQU0sTUFBTSxJQUFJLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsR0FBRyxFQUFFLE1BQU0sY0FBYyxHQUFHLElBQUksRUFBRSxXQUFXLENBQUMsQ0FBQztBQUMzRixNQUFNLEtBQUssQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxFQUFFLEVBQUUsY0FBYyxDQUFDLENBQUMsQ0FBQztBQUN2RCxLQUFLLE1BQU07QUFDWCxNQUFNLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUNoRCxLQUFLO0FBQ0w7QUFDQSxJQUFJLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRTtBQUN0QixNQUFNLElBQUksQ0FBQyxDQUFDLFNBQVMsSUFBSSxjQUFjLEtBQUssS0FBSyxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDM0YsTUFBTSxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ25ELEtBQUs7QUFDTDtBQUNBLElBQUksT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQztBQUNuQyxHQUFHO0FBQ0g7QUFDQSxDQUFDO0FBQ0Q7QUFDQSxlQUFlLENBQUNPLFVBQVEsRUFBRSxVQUFVLEVBQUUsZUFBZSxDQUFDOztBQzFWdEQsU0FBUyxhQUFhLENBQUMsR0FBRyxFQUFFLE9BQU8sRUFBRTtBQUNyQyxFQUFFLE1BQU0sR0FBRyxHQUFHRSxLQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDM0IsRUFBRSxNQUFNLEdBQUcsR0FBRyxJQUFJRixVQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztBQUNsRDtBQUNBLEVBQUUsSUFBSSxHQUFHLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksUUFBUSxDQUFDLEtBQUssRUFBRTtBQUNsRixJQUFJLE1BQU0sTUFBTSxHQUFHLHlFQUF5RSxDQUFDO0FBQzdGLElBQUksR0FBRyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQztBQUM5RCxHQUFHO0FBQ0g7QUFDQSxFQUFFLE9BQU8sR0FBRyxDQUFDO0FBQ2I7O0FDN0JPLE1BQU0sSUFBSSxDQUFDO0FBQ2xCO0FBQ0EsSUFBSSxXQUFXLENBQUMsR0FBRyxFQUFFLFFBQVEsRUFBRSxZQUFZLEVBQUUsY0FBYyxFQUFFO0FBQzdELFFBQVEsSUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDdkIsUUFBUSxJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztBQUNqQyxRQUFRLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNsRCxRQUFRLElBQUksQ0FBQyxZQUFZLEdBQUcsWUFBWSxDQUFDO0FBQ3pDLFFBQVEsSUFBSSxDQUFDLGNBQWMsR0FBRyxDQUFDLENBQUMsY0FBYyxDQUFDO0FBQy9DLEtBQUs7QUFDTDtBQUNBO0FBQ0EsSUFBSSxNQUFNLE9BQU8sQ0FBQyxPQUFPLEVBQUU7QUFDM0IsUUFBUSxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDekUsUUFBUSxNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUN6RCxRQUFRLElBQUksSUFBSSxHQUFHLFFBQVEsQ0FBQztBQUM1QjtBQUNBLFFBQVEsS0FBSyxNQUFNLEVBQUUsUUFBUSxFQUFFLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxFQUFFLEdBQUcsRUFBRSxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUU7QUFDM0UsWUFBWSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssR0FBRyxFQUFFO0FBQzlELGdCQUFnQixNQUFNLEdBQUcsR0FBRyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLHNCQUFzQixDQUFDLENBQUM7QUFDMUUsZ0JBQWdCLElBQUlSLGVBQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNoQyxnQkFBZ0IsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNuQyxnQkFBZ0IsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ3pFLGdCQUFnQixPQUFPO0FBQ3ZCLGFBQWE7QUFDYixZQUFZLElBQUksR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDeEQsU0FBUztBQUNUO0FBQ0EsUUFBUSxJQUFJLElBQUksQ0FBQyxjQUFjO0FBQy9CLFlBQVksSUFBSSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDNUQ7QUFDQSxRQUFRLElBQUksSUFBSSxLQUFLLFFBQVEsRUFBRTtBQUMvQixZQUFZLE1BQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztBQUNwRCxZQUFZLE9BQU8sSUFBSSxDQUFDO0FBQ3hCLFNBQVM7QUFDVCxLQUFLO0FBQ0w7QUFDQTtBQUNBLElBQUksb0JBQW9CLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRTtBQUN4QyxRQUFRLE1BQU0sQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDbkU7QUFDQTtBQUNBLFFBQVEsSUFBSSxLQUFLLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUM7QUFDckYsWUFBWSxPQUFPLElBQUksQ0FBQztBQUN4QjtBQUNBLFFBQVEsTUFBTSxNQUFNLEdBQUcsYUFBYSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQ2xELFFBQVEsSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRTtBQUNsQyxZQUFZLE1BQU0sS0FBSyxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEYsWUFBWSxPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSUEsZUFBTSxDQUFDLEtBQUssR0FBRyx3QkFBd0IsQ0FBQyxDQUFDO0FBQy9FLFlBQVksT0FBTztBQUNuQixTQUFTO0FBQ1Q7QUFDQSxRQUFRLElBQUksT0FBTyxHQUFHLEtBQUssQ0FBQztBQUM1QixRQUFRLEtBQUssTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFO0FBQ2pFLFlBQVksSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsU0FBUztBQUNqRCxZQUFZLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQ2hELFlBQVksSUFBSSxDQUFDLElBQUksRUFBRSxTQUFTO0FBQ2hDLFlBQVksTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO0FBQ3hDLFlBQVksSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsU0FBUztBQUNsRCxZQUFZLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFO0FBQzNDLGdCQUFnQixNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQ3RELGdCQUFnQixNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDcEUsZ0JBQWdCLElBQUksS0FBSyxJQUFJLEtBQUssRUFBRSxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxFQUFFO0FBQ2hGLGFBQWEsTUFBTSxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUU7QUFDN0MsZ0JBQWdCLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsS0FBSztBQUN6RCxvQkFBb0IsSUFBSSxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztBQUN0Qyx3QkFBd0IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO0FBQ3ZELGlCQUFpQixDQUFDLENBQUM7QUFDbkIsYUFBYTtBQUNiLFNBQVM7QUFDVCxRQUFRLE9BQU8sT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQztBQUM3RSxLQUFLO0FBQ0w7O0FDcEVPLGVBQWUsU0FBUyxDQUFDLEdBQUcsRUFBRSxPQUFPLEVBQUU7QUFDOUMsSUFBSSxNQUFNLE9BQU8sR0FBRyxNQUFNLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3BELElBQUksSUFBSSxPQUFPLEtBQUssS0FBSyxFQUFFLE9BQU87QUFDbEM7QUFDQSxJQUFJLElBQUksQ0FBQyxPQUFPLElBQUksT0FBTyxLQUFLLE9BQU8sRUFBRTtBQUN6QyxRQUFRLE9BQU8sSUFBSUEsZUFBTSxDQUFDLDBDQUEwQyxDQUFDLENBQUM7QUFDdEUsS0FBSztBQUNMO0FBQ0EsSUFBSTtBQUNKLFFBQVEsTUFBTSxJQUFJLElBQUksR0FBRyxDQUFDLE9BQU8sQ0FBQztBQUNsQyxRQUFRLE1BQU0sSUFBSSxJQUFJLEdBQUcsQ0FBQyxPQUFPLENBQUM7QUFDbEMsUUFBUSxPQUFPLEdBQUcsSUFBSSxXQUFXLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQztBQUNqRCxRQUFRLFFBQVEsR0FBRyxPQUFPLENBQUMsYUFBYTtBQUN4QyxZQUFZLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUU7QUFDbEMsU0FBUztBQUNULFFBQVEsV0FBVyxHQUFHLFFBQVE7QUFDOUIsWUFBWSxNQUFNLHFCQUFxQixDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDO0FBQ2pFLFNBQVM7QUFDVDtBQUNBLElBQUksSUFBSSxXQUFXLEVBQUUsT0FBTztBQUM1QjtBQUNBLElBQUksTUFBTSxPQUFPLEdBQUcsTUFBTSxXQUFXLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQ25ELElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxPQUFPO0FBQ3pCO0FBQ0EsSUFBSSxNQUFNLFFBQVEsR0FBRyxJQUFJLFFBQVEsQ0FBQyxDQUFDLGFBQWEsRUFBRSxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUUscUJBQXFCLENBQUMsQ0FBQztBQUN0RixJQUFJLElBQUksT0FBTyxHQUFHLENBQUMsQ0FBQztBQUNwQixJQUFJLE1BQU0sUUFBUSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsT0FBTyxNQUFNLEtBQUs7QUFDdEQsUUFBUSxRQUFRLENBQUMsT0FBTyxHQUFHLGFBQWEsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDO0FBQzNELFFBQVEsSUFBSSxNQUFNLE1BQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUM7QUFDckQsS0FBSyxDQUFDLENBQUM7QUFDUDtBQUNBLElBQUksT0FBTyxJQUFJQSxlQUFNLENBQUMsQ0FBQyxVQUFVLEVBQUUsUUFBUSxDQUFDLE9BQU8sR0FBRyxXQUFXLEdBQUcsVUFBVSxDQUFDLEVBQUUsRUFBRSxPQUFPLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDO0FBQzlHLENBQUM7QUFDRDtBQUNBLFNBQVMsT0FBTyxDQUFDLEdBQUcsRUFBRTtBQUN0QixJQUFJLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7QUFDcEQsQ0FBQztBQUNEO0FBQ08sZUFBZSxXQUFXLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRTtBQUM1QyxJQUFJLE1BQU0sT0FBTyxHQUFHLEVBQUUsQ0FBQztBQUN2QixJQUFJLE1BQU0sUUFBUSxHQUFHLElBQUksUUFBUSxDQUFDLENBQUMsY0FBYyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO0FBQ2pGLElBQUksTUFBTSxRQUFRLENBQUMsT0FBTztBQUMxQixRQUFRLEdBQUcsQ0FBQyxhQUFhLENBQUMsY0FBYyxFQUFFO0FBQzFDLFFBQVEsUUFBUSxJQUFJO0FBQ3BCLFlBQVksSUFBSSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsR0FBRyxHQUFHLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUM7QUFDbkYsWUFBWSxJQUFJLEdBQUcsQ0FBQyxJQUFJLElBQUksRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO0FBQ25GLFlBQVksTUFBTSxNQUFNLEdBQUcsQ0FBQ1csNkJBQW9CLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDekYsWUFBWSxJQUFJLElBQUksQ0FBQyxNQUFNLElBQUksTUFBTSxDQUFDLE1BQU07QUFDNUMsZ0JBQWdCLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7QUFDM0UsU0FBUztBQUNULEtBQUssQ0FBQztBQUNOLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPO0FBQ3pCLFFBQVEsT0FBTyxPQUFPLENBQUM7QUFDdkIsQ0FBQztBQUNEO0FBQ0EsZUFBZSxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUU7QUFDekMsSUFBSSxJQUFJO0FBQ1IsUUFBUSxPQUFPLE1BQU0sY0FBYztBQUNuQyxZQUFZLENBQUMsVUFBVSxFQUFFLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxFQUFFLGtEQUFrRDtBQUN6RyxZQUFZLE9BQU87QUFDbkIsWUFBWSx3RUFBd0U7QUFDcEYsWUFBWSxtQkFBbUI7QUFDL0IsU0FBUyxDQUFDO0FBQ1YsS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFO0FBQ2YsUUFBUSxPQUFPLEtBQUssQ0FBQztBQUNyQixLQUFLO0FBQ0wsQ0FBQztBQUNEO0FBQ0EsZUFBZSxxQkFBcUIsQ0FBQyxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFO0FBQ3RFLElBQUksSUFBSTtBQUNSLFFBQVEsTUFBTSxPQUFPO0FBQ3JCLFlBQVksbUJBQW1CO0FBQy9CLFlBQVksQ0FBQyxlQUFlLEVBQUUsTUFBTSxDQUFDLGlCQUFpQixFQUFFLE1BQU0sQ0FBQyxtQkFBbUI7QUFDbEYsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLFNBQVMsS0FBSyxNQUFNLENBQUMsU0FBUztBQUN0RCxvQkFBb0IsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDO0FBQ3BDLHNEQUFzRCxFQUFFLE1BQU0sQ0FBQztBQUMvRCx1Q0FBdUMsRUFBRSxLQUFLLENBQUMsUUFBUSxDQUFDO0FBQ3hELGFBQWE7QUFDYjtBQUNBLGtFQUFrRSxDQUFDO0FBQ25FLFNBQVMsQ0FBQztBQUNWLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBRTtBQUNmLFFBQVEsT0FBTyxJQUFJLENBQUM7QUFDcEIsS0FBSztBQUNMOztBQ3ZGQSxTQUFTLFNBQVMsQ0FBQyxFQUFFLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFO0FBQzNELElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUM7QUFDN0MsSUFBSSxPQUFPLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxPQUFPLENBQUMsQ0FBQztBQUM1RCxDQUFDO0FBQ0Q7QUFDZSxNQUFNLFdBQVcsU0FBU0MsZUFBTSxDQUFDO0FBQ2hELElBQUksTUFBTSxFQUFFO0FBQ1osUUFBUSxJQUFJLENBQUMsUUFBUTtBQUNyQixZQUFZLFNBQVMsQ0FBQyxRQUFRLEVBQUUsYUFBYSxFQUFFLGVBQWUsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQztBQUN4RyxTQUFTLENBQUM7QUFDVixLQUFLO0FBQ0w7QUFDQSxJQUFJLE1BQU0sQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFO0FBQ3JCLFFBQVEsSUFBSSxDQUFDLENBQUMsQ0FBQyxvQkFBb0IsRUFBRTtBQUNyQyxZQUFZLENBQUMsQ0FBQyxvQkFBb0IsR0FBRyxJQUFJQyxhQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3hELFlBQVksWUFBWSxDQUFDLE1BQU0sSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzlFLFNBQVM7QUFDVDtBQUNBLFFBQVE7QUFDUixZQUFZLE9BQU8sR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUMsV0FBVztBQUNsRSxZQUFZLFdBQVcsR0FBRyxLQUFLLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUM7QUFDbEYsWUFBWSxZQUFZLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxlQUFlLENBQUMsYUFBYSxDQUFDLGVBQWUsQ0FBQztBQUNsRixZQUFZLE1BQU0sR0FBRyxZQUFZLElBQUksWUFBWSxDQUFDLFFBQVE7QUFDMUQsWUFBWSxLQUFLLEdBQUcsTUFBTSxJQUFJLE1BQU0sQ0FBQyxvQkFBb0IsRUFBRTtBQUMzRCxZQUFZLE1BQU0sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsbUJBQW1CLENBQUM7QUFDbEUsWUFBWSxJQUFJLEdBQUcsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxPQUFPLEVBQUUsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNsSDtBQUNBLFFBQVEsSUFBSSxDQUFDLFFBQVE7QUFDckIsWUFBWSxTQUFTLENBQUMsUUFBUSxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJO0FBQ3JELGdCQUFnQixJQUFJLENBQUMsQ0FBQyxHQUFHLEdBQUcsUUFBUSxFQUFFO0FBQ3RDLG9CQUFvQixDQUFDLENBQUMsY0FBYyxFQUFFLENBQUM7QUFDdkMsb0JBQW9CLENBQUMsQ0FBQyxlQUFlLEVBQUUsQ0FBQztBQUN4QyxvQkFBb0IsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO0FBQ2hDLGlCQUFpQjtBQUNqQixhQUFhLEVBQUUsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDL0IsU0FBUyxDQUFDO0FBQ1Y7QUFDQSxRQUFRLElBQUksTUFBTSxFQUFFO0FBQ3BCLFlBQVksSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLE9BQU87QUFDdkMsZ0JBQWdCLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxrQkFBa0IsQ0FBQyxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxHQUFHLE9BQU8sQ0FBQyxDQUFDO0FBQ3JILGFBQWEsQ0FBQztBQUNkLFlBQVksSUFBSSxLQUFLLEVBQUU7QUFDdkIsZ0JBQWdCLElBQUksQ0FBQyxPQUFPO0FBQzVCLG9CQUFvQixJQUFJLENBQUMsZUFBZSxFQUFFLFdBQVcsQ0FBQyxPQUFPLENBQUMsWUFBWSxJQUFJLE1BQU0sTUFBTSxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLENBQUM7QUFDdEksaUJBQWlCLENBQUM7QUFDbEIsYUFBYTtBQUNiLFlBQVksSUFBSSxDQUFDLE9BQU87QUFDeEIsZ0JBQWdCLElBQUksQ0FBQyxjQUFjLEdBQUcsV0FBVyxDQUFDLE9BQU8sQ0FBQyxjQUFjLEVBQUUsTUFBTSxNQUFNLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsQ0FBQztBQUNsSSxhQUFhLENBQUM7QUFDZCxTQUFTO0FBQ1Q7QUFDQSxRQUFRLElBQUksTUFBTSxFQUFFO0FBQ3BCLFlBQVksSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLE9BQU87QUFDdkMsZ0JBQWdCLElBQUksQ0FBQyxNQUFNLEVBQUUsa0JBQWtCLEVBQUUsWUFBWTtBQUM3RCxvQkFBb0IsTUFBTSxPQUFPLEdBQUcsTUFBTSxXQUFXLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxJQUFJLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO0FBQ2xGLG9CQUFvQixNQUFNLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO0FBQ3RFLGlCQUFpQixDQUFDO0FBQ2xCLGFBQWEsQ0FBQztBQUNkLFNBQVM7QUFDVDtBQUNBLFFBQVEsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLDBCQUEwQixFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUM7QUFDNUc7QUFDQSxRQUFRLElBQUksV0FBVyxFQUFFO0FBQ3pCLFlBQVk7QUFDWixnQkFBZ0IsU0FBUyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUM7QUFDckUsZ0JBQWdCLE9BQU8sR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsaUJBQWlCLENBQUMsQ0FBQztBQUM3RSxnQkFBZ0IsWUFBWSxHQUFHLFNBQVMsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLEdBQUcsR0FBRyxTQUFTLENBQUMsV0FBVyxFQUFFLENBQUMsRUFBRSxPQUFPLENBQUMsSUFBSTtBQUN2RyxhQUFhO0FBQ2IsWUFBWSxTQUFTLE1BQU0sQ0FBQyxRQUFRLEVBQUU7QUFDdEMsZ0JBQWdCLElBQUksTUFBTSxHQUFHLElBQUksWUFBWSxDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ25GLGFBQWE7QUFDYixZQUFZLElBQUksQ0FBQyxZQUFZLEVBQUU7QUFDL0IsYUFBYSxPQUFPLENBQUMsSUFBSSxDQUFDLHFCQUFxQixFQUFFLDZCQUE2QixFQUFFLE1BQU0sTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7QUFDckcsYUFBYSxPQUFPLENBQUMsSUFBSSxDQUFDLG1CQUFtQixJQUFJLDJCQUEyQixJQUFJLE1BQU0sTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUM7QUFDckcsU0FBUztBQUNULEtBQUs7QUFDTDtBQUNBLElBQUksUUFBUSxDQUFDLFdBQVcsRUFBRTtBQUMxQixRQUFRLElBQUksSUFBSSxDQUFDO0FBQ2pCLFFBQVEsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxJQUFJLEtBQUs7QUFDdEQsWUFBWSxJQUFJLElBQUksQ0FBQyxXQUFXLEtBQUssV0FBVyxFQUFFLEVBQUUsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLElBQUksQ0FBQyxFQUFFO0FBQ3BGLFNBQVMsRUFBQztBQUNWLFFBQVEsT0FBTyxJQUFJLENBQUM7QUFDcEIsS0FBSztBQUNMO0FBQ0E7QUFDQSxJQUFJLE1BQU0sTUFBTSxDQUFDLE9BQU8sRUFBRTtBQUMxQixRQUFRLE1BQU0sS0FBSyxHQUFHLElBQUlDLGNBQUssQ0FBQztBQUNoQyxRQUFRLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUN6QyxRQUFRLElBQUksRUFBRSxNQUFNLFNBQVMsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLE9BQU8sQ0FBQyxDQUFDLEVBQUU7QUFDbkQsUUFBUSxPQUFPLENBQUMsRUFBRSxFQUFFLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJZCxlQUFNLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUU7QUFDbEUsUUFBUSxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDeEMsS0FBSztBQUNMO0FBQ0EsQ0FBQztBQUNEO0FBQ0EsU0FBUyxJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUU7QUFDbEMsSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDL0Q7Ozs7In0= diff --git a/.obsidian/plugins/tag-wrangler/manifest.json b/.obsidian/plugins/tag-wrangler/manifest.json new file mode 100644 index 0000000..24159ba --- /dev/null +++ b/.obsidian/plugins/tag-wrangler/manifest.json @@ -0,0 +1,8 @@ +{ + "id": "tag-wrangler", + "name": "Tag Wrangler", + "version": "0.4.6", + "minAppVersion": "0.12.5", + "description": "Rename, merge, toggle, and search tags from the tag pane", + "isDesktopOnly": true +} diff --git a/.obsidian/plugins/tag-wrangler/styles.css b/.obsidian/plugins/tag-wrangler/styles.css new file mode 100644 index 0000000..d58564c --- /dev/null +++ b/.obsidian/plugins/tag-wrangler/styles.css @@ -0,0 +1,172 @@ +.smalltalk { + display: flex; + + align-items: center; + flex-direction: column; + justify-content: center; + + transition: 200ms opacity; + + bottom: 0; + left: 0; + overflow: auto; + padding: 20px; + position: fixed; + right: 0; + top: 0; + + z-index: 100; +} + +.smalltalk + .smalltalk { + transition: ease 1s; +} + +.smalltalk .page { + border-radius: 3px; + background: white; + box-shadow: 0 4px 23px 5px rgba(0, 0, 0, .2), 0 2px 6px rgba(0, 0, 0, .15); + color: #333; + min-width: 400px; + padding: 0; + position: relative; + z-index: 0; +} + +@media only screen and (max-width: 500px) { + .smalltalk .page { + min-width: 0; + } +} + +.smalltalk .page > .close-button { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAQAAAC1QeVaAAAAUklEQVR4XqXPYQrAIAhAYW/gXd8NJxTopVqsGEhtf+L9/ERU2k/HSMFQpKcYJeNFI9Be0LCMij8cYyjj5EHIivGBkwLfrbX3IF8PqumVmnDpEG+eDsKibPG2JwAAAABJRU5ErkJggg==); + background-position: center; + background-repeat: no-repeat; + height: 14px; + position: absolute; + right: 7px; + top: 7px; + width: 14px; + z-index: 1; +} + +.smalltalk .page > .close-button:hover { + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAQAAAC1QeVaAAAAnUlEQVR4XoWQQQ6CQAxFewjkJkMCyXgJPMk7AiYczyBeZEAX6AKctGIaN+bt+trk9wtGQc/IkhnoKGxqqiWxOSZalapWFZ6VrIUDExsN0a5JRBq9LoVOR0eEQMoEhKizXhhsn0p1sCWVo7CwOf1RytPL8CPvwuBUoHL6ugeK30CVD1TqK7V/hdpe+VNChhOzV8xWny/+xosHF8578W/Hmc1OOC3wmwAAAABJRU5ErkJggg==); +} + +.smalltalk .progress { + display: block; + width: 100%; +} + +.smalltalk .page header { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + max-width: 500px; + + user-select: none; + color: #333; + font-size: 120%; + font-weight: bold; + margin: 0; + padding: 14px 17px; + text-shadow: white 0 1px 2px; +} + +.smalltalk .page .content-area { + overflow: hidden; + text-overflow: ellipsis; + + padding: 6px 17px; + position: relative; +} + +.smalltalk .page .action-area { + padding: 14px 17px; +} + +button { + font-family: Ubuntu, Arial, sans-serif; +} + +.smalltalk button, .smalltalk .smalltalk { + min-height: 2em; + min-width: 4em; +} + +.smalltalk button { + appearance: none; + user-select: none; + background-image: linear-gradient(#ededed, #ededed 38%, #dedede); + + border: 1px solid rgba(0, 0, 0, 0.25); + border-radius: 2px; + box-shadow: 0 1px 0 rgba(0, 0, 0, 0.08), inset 0 1px 2px rgba(255, 255, 255, 0.75); + color: #444; + font: inherit; + margin: 0 1px 0 0; + text-shadow: 0 1px 0 rgb(240, 240, 240); +} + +.smalltalk button::-moz-focus-inner { + border: 0; +} + +.smalltalk button:enabled:active { + background-image: linear-gradient(#e7e7e7, #e7e7e7 38%, #d7d7d7); + box-shadow: none; + text-shadow: none; +} + +.smalltalk .page .button-strip { + display: flex; + + flex-direction: row; + justify-content: flex-end; +} + +.smalltalk .page .button-strip > button { + margin-left: 10px; +} + +.smalltalk input { + width: 100%; + border: 1px solid #bfbfbf; + border-radius: 2px; + box-sizing: border-box; + color: #444; + font: inherit; + margin: 0; + min-height: 2em; + padding: 3px; + outline: none; +} + +.smalltalk button:enabled:focus, .smalltalk input:enabled:focus { + transition: border-color 200ms; + border-color: rgb(77, 144, 254); + outline: none; +} + + +.smalltalk input[pattern]:invalid, .smalltalk input[pattern]:invalid:enabled:focus, .smalltalk input[pattern][aria-invalid='true'], .smalltalk input[pattern][aria-invalid='true']:enabled:focus { + border-color: var(--text-error); + background-color: var(--background-modifier-error); } + +.smalltalk .page, .smalltalk .page header, .smalltalk input, .smalltalk button { + color: var(--text-normal); + text-shadow: none; } + +.smalltalk .page { + background: var(--background-primary); } + +.smalltalk button[data-name="js-ok"] { + background: var(--background-modifier-error); } + +.smalltalk button[data-name="js-cancel"] { + background: var(--background-secondary-alt); } + +.smalltalk button { + box-shadow: none; } diff --git a/.obsidian/plugins/templater-obsidian/data.json b/.obsidian/plugins/templater-obsidian/data.json index eea2dd2..48c4f7a 100644 --- a/.obsidian/plugins/templater-obsidian/data.json +++ b/.obsidian/plugins/templater-obsidian/data.json @@ -8,7 +8,7 @@ ] ], "trigger_on_file_creation": false, - "auto_jump_to_cursor": false, + "auto_jump_to_cursor": true, "enable_system_commands": false, "shell_path": "", "user_scripts_folder": "", diff --git a/.obsidian/plugins/vantage-obsidian/main.js b/.obsidian/plugins/vantage-obsidian/main.js deleted file mode 100644 index bc42701..0000000 --- a/.obsidian/plugins/vantage-obsidian/main.js +++ /dev/null @@ -1,815 +0,0 @@ -'use strict'; - -var obsidian = require('obsidian'); - -/*! ***************************************************************************** -Copyright (c) Microsoft Corporation. - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. -***************************************************************************** */ -/* global Reflect, Promise */ - -var extendStatics = function(d, b) { - extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; - return extendStatics(d, b); -}; - -function __extends(d, b) { - if (typeof b !== "function" && b !== null) - throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); -} - -function __awaiter(thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -} - -function __generator(thisArg, body) { - var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; - return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; - function verb(n) { return function (v) { return step([n, v]); }; } - function step(op) { - if (f) throw new TypeError("Generator is already executing."); - while (_) try { - if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [op[0] & 2, t.value]; - switch (op[0]) { - case 0: case 1: t = op; break; - case 4: _.label++; return { value: op[1], done: false }; - case 5: _.label++; y = op[1]; op = [0]; continue; - case 7: op = _.ops.pop(); _.trys.pop(); continue; - default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } - if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } - if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } - if (t[2]) _.ops.pop(); - _.trys.pop(); continue; - } - op = body.call(thisArg, _); - } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } - if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; - } -} - -var MyVantagePlugin = /** @class */ (function (_super) { - __extends(MyVantagePlugin, _super); - function MyVantagePlugin() { - return _super !== null && _super.apply(this, arguments) || this; - } - MyVantagePlugin.prototype.onload = function () { - var _this = this; - console.log('Loading the Vantage plugin.'); - if (this.app.workspace.layoutReady) { - this.onLayoutReady(); - } - else { - this.app.workspace.on("layout-ready", this.onLayoutReady.bind(this)); - } - this.addCommand({ - id: 'build-search', - name: "Build a new search", - checkCallback: function (checking) { - var leaf = _this.app.workspace.activeLeaf; - if (leaf) { - if (!checking) { - new VantageModal(_this.app).open(); - } - return true; - } - return false; - } - }); - this.addRibbonIcon('magnifying-glass', 'Vantage - Advanced search builder', function () { - var leaf = _this.app.workspace.activeLeaf; - if (leaf) { - new VantageModal(_this.app).open(); - return true; - } - return false; - }); - // this.addSettingTab(new SampleSettingTab(this.app, this)); - }; - MyVantagePlugin.prototype.onLayoutReady = function () { - // Check for the Natural Language Dates plugin after all the plugins are loaded. - // If not found, tell the user to install it/initialize it. - var naturalLanguageDates = this.app.plugins.getPlugin('nldates-obsidian'); - if (!naturalLanguageDates) { - new obsidian.Notice("The Natural Language Dates plugin was not found. The Vantage plugin requires the Natural Language Dates plugin. Please install it first and make sure it is updated and enabled before using Vantage."); - } - }; - MyVantagePlugin.prototype.onunload = function () { - console.log('Unloading the Vantage plugin'); - }; - // getBacklinks(someFile: TFile) { // No longer used - // let obsidianApp = this.app; - // let allNotes = this.app.vault.getMarkdownFiles(); - // let currentBacklinks: Object[] = []; - // allNotes.forEach((markdownFile: TFile) => { - // this.app.metadataCache.getFileCache(markdownFile); - // let thisMetadataCache = obsidianApp.metadataCache.getFileCache(markdownFile); - // if (thisMetadataCache.links) { - // for (let eachLink of thisMetadataCache.links) { - // if (eachLink.link === currentFileName) { - // currentBacklinks.push({noteName: markdownFile.basename, startPosition: eachLink.position.start, endPosition: eachLink.position.end}); - // } - // } - // } - // if (thisMetadataCache.embeds) { - // for (let eachEmbed of thisMetadataCache.embeds) { - // if (eachEmbed.link.contains(currentFileName)) { - // currentBacklinks.push({noteName: markdownFile.basename, startPosition: eachEmbed.position.start, endPosition: eachEmbed.position.end}); - // } - // } - // } - // }); - // return currentBacklinks; - // } - MyVantagePlugin.prototype.delay = function (waittimeInMilliseconds) { - return new Promise(function (resolve) { - setTimeout(function () { - resolve(2); - }, waittimeInMilliseconds); - }); - }; - MyVantagePlugin.prototype.getSearch = function (someSearchQuery) { - return __awaiter(this, void 0, void 0, function () { - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - this.app.internalPlugins.getPluginById('global-search').instance.openGlobalSearch(someSearchQuery); - return [4 /*yield*/, this.delay(5000)]; - case 1: - _a.sent(); - this.app.workspace.getLeavesOfType('search')[0].view.dom.resultDoms; - return [2 /*return*/]; - } - }); - }); - }; - return MyVantagePlugin; -}(obsidian.Plugin)); -var VantageModal = /** @class */ (function (_super) { - __extends(VantageModal, _super); - function VantageModal(app) { - return _super.call(this, app) || this; - } - VantageModal.prototype.onOpen = function () { - var _this = this; - var contentEl = this.contentEl; - var searchModal = this; - contentEl.parentElement.addClass("vantage-modal"); - var vantagePlugin = this.app.plugins.getPlugin("vantage-obsidian"); - var naturalLanguageDates = this.app.plugins.getPlugin('nldates-obsidian'); // Get the Natural Language Dates plugin. - this.titleEl.setText("Vantage - Advanced Search"); - var vantageSettingsDiv = contentEl.createEl("div"); - var vantageSettingsDescriptionDiv = contentEl.createEl("div"); - vantageSettingsDescriptionDiv.addClass("setting-item"); - var vantageSettingsDescriptionSubdiv = contentEl.createEl("div"); - vantageSettingsDescriptionSubdiv.addClass("setting-item-info"); - var vantageSettingsDescription = contentEl.createEl("div", { "text": "Vantage helps create complex search queries. See Obsidian's search documentation for more." }); - vantageSettingsDescription.addClass("setting-item-description"); - var vantageSettingsDescriptionLink = contentEl.createEl("a", { "text": "https://publish.obsidian.md/help/Plugins/Search" }); - var vantageSettingsLinebreakDiv = contentEl.createEl("div"); - var vantageSettingsLinebreak = contentEl.createEl("br"); - vantageSettingsLinebreakDiv.append(vantageSettingsLinebreak); - vantageSettingsLinebreakDiv.addClass("setting-item-description"); - vantageSettingsDescriptionLink.addClass("setting-item-description"); - vantageSettingsDescriptionLink.setAttr("href", "https://publish.obsidian.md/help/Plugins/Search"); - var vantageSettingsRegexDescription = contentEl.createEl("div", { "text": "Many complex searches use Regular Expressions. These help us search for patterns in our text. Visit RegExr to learn more and to practice with regular expressions." }); - vantageSettingsRegexDescription.addClass("setting-item-description"); - var vantageSettingsRegexLink = contentEl.createEl("a", { "text": "https://regexr.com/" }); - vantageSettingsRegexLink.setAttr("href", "https://regexr.com/"); - vantageSettingsRegexLink.addClass("setting-item-description"); - vantageSettingsDescriptionSubdiv.append(vantageSettingsDescription); - vantageSettingsDescriptionSubdiv.append(vantageSettingsDescriptionLink); - vantageSettingsDescriptionSubdiv.append(vantageSettingsLinebreakDiv); - vantageSettingsDescriptionSubdiv.append(vantageSettingsRegexDescription); - vantageSettingsDescriptionSubdiv.append(vantageSettingsRegexLink); - vantageSettingsDescriptionDiv.append(vantageSettingsDescriptionSubdiv); - vantageSettingsDiv.append(vantageSettingsDescriptionDiv); - // Note attributes - var noteAttributesHeadingDiv = contentEl.createEl("h2", { "text": "Search note attributes" }); - noteAttributesHeadingDiv.addClass("setting-item"); - noteAttributesHeadingDiv.addClass("setting-item-heading"); - vantageSettingsDiv.append(noteAttributesHeadingDiv); - // Note Titles - var noteTitleContainsDiv = contentEl.createEl("div"); - noteTitleContainsDiv.addClass("setting-item"); - var noteTitleInfoDiv = contentEl.createEl("div"); - noteTitleInfoDiv.addClass("setting-item-info"); - var noteTitleControlDiv = contentEl.createEl("div"); - noteTitleControlDiv.addClass("setting-item-control"); - var noteTitleContainsText = contentEl.createEl("span", { "text": "Note title contains: " }); - noteTitleContainsText.addClass("setting-item-name"); - var noteTitleContainsInput = contentEl.createEl("input", { "type": "text" }); - noteTitleContainsInput.id = "note-title-input"; - //noteTitleContainsInput.setAttr("style", "float: right; width: 50%"); - noteTitleInfoDiv.append(noteTitleContainsText); - noteTitleControlDiv.append(noteTitleContainsInput); - noteTitleContainsDiv.append(noteTitleInfoDiv); - noteTitleContainsDiv.append(noteTitleControlDiv); - vantageSettingsDiv.append(noteTitleContainsDiv); - // Date range: - var dateRangeDiv = contentEl.createEl("div"); - dateRangeDiv.addClass("setting-item"); - var dateRangeHeaderDiv = contentEl.createEl("div"); - dateRangeHeaderDiv.addClass("setting-item-info"); - var dateRangeHeader = contentEl.createEl("div", { "text": "Date range: " }); - dateRangeHeader.addClass("setting-item-name"); - var dateRangeSubtitle = contentEl.createEl("span", { "text": "(Entering data here will make the search include only daily notes (and may conflict with the above). Use natural language.)" }); - dateRangeSubtitle.setAttr("class", "setting-item-description"); - dateRangeHeaderDiv.append(dateRangeHeader); - dateRangeHeaderDiv.append(dateRangeSubtitle); - var startDateDiv = contentEl.createEl("div"); - var startDateInfoDiv = contentEl.createEl("div"); - startDateInfoDiv.addClass("setting-item-info"); - var startDateText = contentEl.createEl("div", { "text": "Start date: " }); - startDateText.addClass("setting-item-name"); - startDateInfoDiv.append(startDateText); - var startDateControlDiv = contentEl.createEl("div"); - startDateControlDiv.addClass("setting-item-control"); - var fileStartDateInput = contentEl.createEl("input", { "type": "text" }); - startDateControlDiv.append(fileStartDateInput); - startDateDiv.append(startDateInfoDiv); - startDateDiv.append(startDateControlDiv); - var endDateDiv = contentEl.createEl("div"); - var endDateInfoDiv = contentEl.createEl("div"); - endDateInfoDiv.addClass("setting-item-info"); - var endDateText = contentEl.createEl("div", { "text": "End date: " }); - endDateText.addClass("setting-item-name"); - endDateInfoDiv.append(endDateText); - var endDateControlDiv = contentEl.createEl("div"); - endDateControlDiv.addClass("setting-item-control"); - var fileEndDateInput = contentEl.createEl("input", { "type": "text" }); - endDateControlDiv.append(fileEndDateInput); - endDateDiv.append(endDateInfoDiv); - endDateDiv.append(endDateControlDiv); - dateRangeDiv.append(dateRangeHeaderDiv); - dateRangeDiv.append(startDateDiv); - dateRangeDiv.append(endDateDiv); - vantageSettingsDiv.append(dateRangeDiv); - // Tagged with - var tagDiv = contentEl.createEl("div"); - tagDiv.addClass("setting-item"); - var tagInfoDiv = contentEl.createEl("div"); - var tagControlDiv = contentEl.createEl("div"); - tagInfoDiv.addClass("setting-item-info"); - tagControlDiv.addClass("setting-item-control"); - var noteTagText = contentEl.createEl("div", { "text": "Tagged with: " }); - noteTagText.addClass("setting-item-name"); - tagInfoDiv.append(noteTagText); - var tagInput = contentEl.createEl("input", { "type": "text" }); - tagControlDiv.append(tagInput); - tagDiv.append(tagInfoDiv); - tagDiv.append(tagControlDiv); - vantageSettingsDiv.append(tagDiv); - // Notes with Path - var notesPathDiv = contentEl.createEl("div"); - notesPathDiv.addClass("setting-item"); - var notesPathInfoDiv = contentEl.createEl("div"); - var notesPathControlDiv = contentEl.createEl("div"); - notesPathInfoDiv.addClass("setting-item-info"); - notesPathControlDiv.addClass("setting-item-control"); - var notesPathText = contentEl.createEl("div", { "text": "Notes in folder or path: " }); - notesPathText.addClass("setting-item-name"); - var notePathDescription = contentEl.createEl("span", { "text": "For example, include the folder to your Daily Notes to search all daily notes." }); - notePathDescription.setAttr("class", "setting-item-description"); - notesPathInfoDiv.append(notesPathText); - notesPathInfoDiv.append(notePathDescription); - var notesPathInput = contentEl.createEl("input", { "type": "text" }); - notesPathControlDiv.append(notesPathInput); - notesPathDiv.append(notesPathInfoDiv); - notesPathDiv.append(notesPathControlDiv); - vantageSettingsDiv.append(notesPathDiv); - // Note contents - var noteContentsHeadingDiv = contentEl.createEl("h2", { "text": "Search note contents" }); - noteContentsHeadingDiv.addClass("setting-item"); - noteContentsHeadingDiv.addClass("setting-item-heading"); - vantageSettingsDiv.append(noteContentsHeadingDiv); - contentEl.append(vantageSettingsDiv); - var focusInputBox = contentEl.querySelector("#note-title-input"); - focusInputBox.focus(); - var queryDivs = contentEl.querySelectorAll("div"); - queryDivs.forEach(function (div) { - var inputBoxes = div.querySelectorAll("input"); - inputBoxes.forEach(function (inputBox) { - inputBox.addEventListener('keypress', function (keypressed) { - if (keypressed.key === 'Enter') { - initiateSearch(); - } - }); - }); - }); - function initiateSearch() { - var searchQuery = setSearchQuery(); - searchModal.close(); - vantagePlugin.getSearch(searchQuery); - } - function processDateRange(startDate, endDate) { - console.log("Start date:"); - var parsedFileStartDate = naturalLanguageDates.parseDate(startDate); - console.log("End date:"); - var parsedFileEndDate = naturalLanguageDates.parseDate(endDate); - var currentDate = naturalLanguageDates.getFormattedDate(parsedFileStartDate.moment); - var dateDirection = "forward"; - var allDates = naturalLanguageDates.getFormattedDate(parsedFileStartDate.moment); - if (parsedFileEndDate.moment.isAfter(parsedFileStartDate.moment)) { - console.log("Dates go forward in time."); - dateDirection = "forward"; - } - else { - dateDirection = "backward"; - console.log("Dates go backwards in time."); - } - while (!(currentDate === naturalLanguageDates.getFormattedDate(parsedFileEndDate.moment))) { - var currentDateMoment = parsedFileStartDate.moment; - if (dateDirection === "forward") { - currentDateMoment = currentDateMoment.add(1, "days"); - } - else { - currentDateMoment = currentDateMoment.subtract(1, "days"); - } - var nextDate = naturalLanguageDates.getFormattedDate(currentDateMoment); - allDates = allDates + " OR " + nextDate; - currentDate = nextDate; - } - return allDates; - } - function processTags(inputTags) { - //split by spaces, then return each with tag: appended - //if no #, add the # too - var allTags = inputTags.split(" "); - var processedTags = ""; - for (var _i = 0, allTags_1 = allTags; _i < allTags_1.length; _i++) { - var eachTag = allTags_1[_i]; - if (eachTag.includes("#")) { - processedTags = processedTags + "tag:" + eachTag + " "; - } - else { - processedTags = processedTags + "tag:#" + eachTag + " "; - } - } - processedTags = processedTags.trim(); - return processedTags; - } - function setSearchQuery() { - var searchQuery = ""; - if (noteTitleContainsInput.value != "") { - if ((fileStartDateInput.value != "") && (fileEndDateInput.value != "")) { - searchQuery = searchQuery + "file:(" + noteTitleContainsInput.value + processDateRange(fileStartDateInput.value, fileEndDateInput.value) + ") "; - } - else { - searchQuery = searchQuery + "file:(" + noteTitleContainsInput.value + ") "; - } - } - else if ((fileStartDateInput.value != "") && (fileEndDateInput.value != "")) { - searchQuery = searchQuery + "file:(" + processDateRange(fileStartDateInput.value, fileEndDateInput.value) + ") "; - } - if (tagInput.value != "") { - searchQuery = searchQuery + "(" + processTags(tagInput.value) + ") "; - } - if (notesPathInput.value != "") { - searchQuery = searchQuery + "path:(" + notesPathInput.value + ") "; - } - var newQueries = contentEl.querySelectorAll("div"); - newQueries.forEach(function (div) { - if ((div.id.contains("AND")) || (div.id.contains("OR")) || (div.id.contains("NOT"))) { - var contentQuery = div.querySelectorAll("input"); - var subquery_1 = contentQuery.item(0).value; - var selectBoxes = div.querySelectorAll("select"); - selectBoxes.forEach(function (select) { - if (select.id.contains("Subtype")) { - if (select.value == "") ; - if (select.value.contains("link")) { - subquery_1 = "\\[\\[.*" + subquery_1 + ".*\\]\\]"; - } - if (select.value.contains("email")) { - subquery_1 = "([a-zA-Z0-9_\\-\\.]+)@([a-zA-Z0-9_\\-\\.]+)\.([a-zA-Z]{2,5})"; - } - if (select.value.contains("phone")) { - subquery_1 = "[+]*[(]{0,1}[0-9]{1,4}[)]{0,1}[-\\s\\./0-9]*"; - } - } - }); - selectBoxes.forEach(function (select) { - if (select.id.contains("List")) { - if (select.value.contains("any")) { - if ((subquery_1.contains("[a-zA-Z0-9_")) || subquery_1.contains("}[0-9]")) { - subquery_1 = "(/" + subquery_1 + "/)"; - } - } - if (select.value.contains("list item")) { - subquery_1 = "(/- [^\[.\]].*" + subquery_1 + ".*/)"; - } - if (select.value.contains("incomplete")) { - subquery_1 = "(/- \\[ \\].*" + subquery_1 + ".*/)"; - } - if (select.value.contains("completed")) { - subquery_1 = "(/- \\[x\\].*" + subquery_1 + ".*/)"; - } - if (select.value.contains("all")) { - subquery_1 = "(/- \\[.\\].*" + subquery_1 + ".*/)"; - } - } - }); - selectBoxes.forEach(function (select) { - if (select.id.contains("Type")) { - if (select.value.contains("note")) ; - if (select.value.contains("section")) { - subquery_1 = "section:" + subquery_1; - } - if (select.value.contains("block")) { - subquery_1 = "block:" + subquery_1; - } - if (select.value.contains("line")) { - subquery_1 = "line:" + subquery_1; - } - } - }); - if (div.id.contains("AND")) { - console.log("This is an AND query"); - searchQuery = searchQuery + " (" + subquery_1 + ")"; - } - else if (div.id.contains("OR")) { - console.log("This is an OR query"); - searchQuery = searchQuery + " OR (" + subquery_1 + ")"; - } - else if (div.id.contains("NOT")) { - console.log("This is a NOT query"); - searchQuery = searchQuery + " -(" + subquery_1 + ")"; - } - } - }); - return searchQuery; - } - var vantageButtonsDiv = contentEl.createEl("div"); - vantageButtonsDiv.addClass("setting-item"); - var vantageButtonsControlDiv = contentEl.createEl("div"); - vantageButtonsControlDiv.addClass("setting-item-control"); - var vantageAddedQueriesDiv = contentEl.createEl("div"); - vantageSettingsDiv.append(vantageAddedQueriesDiv); - var queryCount = 1; - new obsidian.ButtonComponent(vantageSettingsDiv) - .setButtonText("Add an AND search token") - .setClass("mod-cta") - .onClick(function () { - var newQueryDiv = contentEl.createEl("div"); - newQueryDiv.addClass("setting-item"); - newQueryDiv.setAttr("id", "AND query" + queryCount); - var newQueryInfoDiv = contentEl.createEl("div"); - newQueryInfoDiv.addClass("setting-item-info"); - var newQueryControlDiv = contentEl.createEl("div"); - newQueryControlDiv.addClass("setting-item-control"); - var newQuerySentenceStart = contentEl.createEl("div", { "text": "AND search⠀" }); - newQueryControlDiv.append(newQuerySentenceStart); - // choose query type - var queryType = contentEl.createEl("select"); - queryType.setAttr("class", "dropdown"); - queryType.multiple; - //queryType.setAttr("style", "float: right;"); - queryType.setAttr("id", "Additional Query Type " + queryCount); - var defaultTypeOption = contentEl.createEl("option", { "value": "note", "text": "notes" }); - defaultTypeOption.selected; - queryType.append(defaultTypeOption); - queryType.append(contentEl.createEl("option", { "value": "section", "text": "sections" })); - queryType.append(contentEl.createEl("option", { "value": "block", "text": "blocks" })); - queryType.append(contentEl.createEl("option", { "value": "line", "text": "lines" })); - newQueryControlDiv.append(queryType); - var newQueryForText = contentEl.createEl("div", { "text": "⠀for⠀" }); - newQueryControlDiv.append(newQueryForText); - // choose list type - var listType = contentEl.createEl("select"); - listType.setAttr("class", "dropdown"); - listType.multiple; - //listType.setAttr("style", "float: right;"); - listType.setAttr("id", "Additional Query List Type " + queryCount); - var defaultListTypeOption = contentEl.createEl("option", { "value": "any", "text": "any line type" }); - defaultListTypeOption.selected; - listType.append(defaultListTypeOption); - listType.append(contentEl.createEl("option", { "value": "list item", "text": "list items" })); - listType.append(contentEl.createEl("option", { "value": "incomplete tasks", "text": "incomplete tasks" })); - listType.append(contentEl.createEl("option", { "value": "completed tasks", "text": "completed tasks" })); - listType.append(contentEl.createEl("option", { "value": "all tasks", "text": "all tasks" })); - newQueryControlDiv.append(listType); - // choose query subtype - var querySubtype = contentEl.createEl("select"); - querySubtype.setAttr("class", "dropdown"); - querySubtype.multiple; - querySubtype.setAttr("id", "Additional Query Subtype " + queryCount); - // querySubtype.setAttr("style", "float: right;"); - var defaultSubtypeOption = contentEl.createEl("option", { "value": "", "text": "with text containing" }); - defaultSubtypeOption.selected; - querySubtype.append(defaultSubtypeOption); - querySubtype.append(contentEl.createEl("option", { "value": "with a link to notes with names containing", "text": "with links to notes with names containing" })); - querySubtype.append(contentEl.createEl("option", { "value": "with an email address", "text": "with email addresses (ignores the following search field)" })); - querySubtype.append(contentEl.createEl("option", { "value": "with a phone number", "text": "with phone numbers (ignores the following search field)" })); - newQueryControlDiv.append(querySubtype); - var newQuery = contentEl.createEl("input", { "type": "text" }); - newQuery.setAttr("id", "AND query " + queryCount); - queryCount = queryCount + 1; - newQueryControlDiv.append(newQuery); - newQueryDiv.append(newQueryInfoDiv); - newQueryDiv.append(newQueryControlDiv); - vantageAddedQueriesDiv.append(newQueryDiv); - var inputBoxes = vantageAddedQueriesDiv.querySelectorAll("input"); - inputBoxes.forEach(function (inputBox) { - inputBox.addEventListener('keypress', function (keypressed) { - if (keypressed.key === 'Enter') { - initiateSearch(); - } - }); - }); - var optionBoxes = vantageAddedQueriesDiv.querySelectorAll("select"); - optionBoxes.forEach(function (optionBox) { - optionBox.addEventListener('keypress', function (keypressed) { - if (keypressed.key === 'Enter') { - initiateSearch(); - } - }); - }); - }); - new obsidian.ButtonComponent(vantageSettingsDiv) - .setButtonText("Add an OR search token") - .setClass("mod-cta") - .onClick(function () { - var newQueryDiv = contentEl.createEl("div"); - newQueryDiv.addClass("setting-item"); - newQueryDiv.setAttr("id", "OR query" + queryCount); - var newQueryInfoDiv = contentEl.createEl("div"); - newQueryInfoDiv.addClass("setting-item-info"); - // let newQueryTextLabel = contentEl.createEl("div", {"text":"OR search ..."}); - // newQueryInfoDiv.append(newQueryTextLabel); - var newQueryControlDiv = contentEl.createEl("div"); - newQueryControlDiv.addClass("setting-item-control"); - var newQuerySentenceStart = contentEl.createEl("div", { "text": "OR search⠀" }); - newQueryControlDiv.append(newQuerySentenceStart); - // choose query type - var queryType = contentEl.createEl("select"); - queryType.setAttr("class", "dropdown"); - queryType.multiple; - //queryType.setAttr("style", "float: right;"); - queryType.setAttr("id", "Additional Query Type " + queryCount); - var defaultTypeOption = contentEl.createEl("option", { "value": "note", "text": "notes" }); - defaultTypeOption.selected; - queryType.append(defaultTypeOption); - queryType.append(contentEl.createEl("option", { "value": "section", "text": "sections" })); - queryType.append(contentEl.createEl("option", { "value": "block", "text": "blocks" })); - queryType.append(contentEl.createEl("option", { "value": "line", "text": "lines" })); - newQueryControlDiv.append(queryType); - var newQueryForText = contentEl.createEl("div", { "text": "⠀for⠀" }); - newQueryControlDiv.append(newQueryForText); - // choose list type - var listType = contentEl.createEl("select"); - listType.setAttr("class", "dropdown"); - listType.multiple; - //listType.setAttr("style", "float: right;"); - listType.setAttr("id", "Additional Query List Type " + queryCount); - var defaultListTypeOption = contentEl.createEl("option", { "value": "any", "text": "any line type" }); - defaultListTypeOption.selected; - listType.append(defaultListTypeOption); - listType.append(contentEl.createEl("option", { "value": "list item", "text": "list items" })); - listType.append(contentEl.createEl("option", { "value": "incomplete tasks", "text": "incomplete tasks" })); - listType.append(contentEl.createEl("option", { "value": "completed tasks", "text": "completed tasks" })); - listType.append(contentEl.createEl("option", { "value": "all tasks", "text": "all tasks" })); - newQueryControlDiv.append(listType); - // choose query subtype - var querySubtype = contentEl.createEl("select"); - querySubtype.setAttr("class", "dropdown"); - querySubtype.multiple; - querySubtype.setAttr("id", "Additional Query Subtype " + queryCount); - // querySubtype.setAttr("style", "float: right;"); - var defaultSubtypeOption = contentEl.createEl("option", { "value": "", "text": "with text containing" }); - defaultSubtypeOption.selected; - querySubtype.append(defaultSubtypeOption); - querySubtype.append(contentEl.createEl("option", { "value": "with a link to notes with names containing", "text": "with links to notes with names containing" })); - querySubtype.append(contentEl.createEl("option", { "value": "with an email address", "text": "with email addresses (ignores the following search field)" })); - querySubtype.append(contentEl.createEl("option", { "value": "with a phone number", "text": "with phone numbers (ignores the following search field)" })); - newQueryControlDiv.append(querySubtype); - var newQuery = contentEl.createEl("input", { "type": "text" }); - newQuery.setAttr("id", "OR query " + queryCount); - queryCount = queryCount + 1; - newQueryControlDiv.append(newQuery); - newQueryDiv.append(newQueryInfoDiv); - newQueryDiv.append(newQueryControlDiv); - vantageAddedQueriesDiv.append(newQueryDiv); - var inputBoxes = vantageAddedQueriesDiv.querySelectorAll("input"); - inputBoxes.forEach(function (inputBox) { - inputBox.addEventListener('keypress', function (keypressed) { - if (keypressed.key === 'Enter') { - initiateSearch(); - } - }); - }); - var optionBoxes = vantageAddedQueriesDiv.querySelectorAll("select"); - optionBoxes.forEach(function (optionBox) { - optionBox.addEventListener('keypress', function (keypressed) { - if (keypressed.key === 'Enter') { - initiateSearch(); - } - }); - }); - }); - new obsidian.ButtonComponent(vantageSettingsDiv) - .setButtonText("Add a NOT search token") - .setClass("mod-cta") - .onClick(function () { - var newQueryDiv = contentEl.createEl("div"); - newQueryDiv.addClass("setting-item"); - newQueryDiv.setAttr("id", "NOT query" + queryCount); - var newQueryInfoDiv = contentEl.createEl("div"); - newQueryInfoDiv.addClass("setting-item-info"); - var newQueryControlDiv = contentEl.createEl("div"); - newQueryControlDiv.addClass("setting-item-control"); - var newQuerySentenceStart = contentEl.createEl("div", { "text": "NOT search⠀" }); - newQueryControlDiv.append(newQuerySentenceStart); - // choose query type - var queryType = contentEl.createEl("select"); - queryType.setAttr("class", "dropdown"); - queryType.multiple; - //queryType.setAttr("style", "float: right;"); - queryType.setAttr("id", "Additional Query Type " + queryCount); - var defaultTypeOption = contentEl.createEl("option", { "value": "note", "text": "notes" }); - defaultTypeOption.selected; - queryType.append(defaultTypeOption); - queryType.append(contentEl.createEl("option", { "value": "section", "text": "sections" })); - queryType.append(contentEl.createEl("option", { "value": "block", "text": "blocks" })); - queryType.append(contentEl.createEl("option", { "value": "line", "text": "lines" })); - newQueryControlDiv.append(queryType); - var newQueryForText = contentEl.createEl("div", { "text": "⠀for⠀" }); - newQueryControlDiv.append(newQueryForText); - // choose list type - var listType = contentEl.createEl("select"); - listType.setAttr("class", "dropdown"); - listType.multiple; - //listType.setAttr("style", "float: right;"); - listType.setAttr("id", "Additional Query List Type " + queryCount); - var defaultListTypeOption = contentEl.createEl("option", { "value": "any", "text": "any line type" }); - defaultListTypeOption.selected; - listType.append(defaultListTypeOption); - listType.append(contentEl.createEl("option", { "value": "list item", "text": "list items" })); - listType.append(contentEl.createEl("option", { "value": "incomplete tasks", "text": "incomplete tasks" })); - listType.append(contentEl.createEl("option", { "value": "completed tasks", "text": "completed tasks" })); - listType.append(contentEl.createEl("option", { "value": "all tasks", "text": "all tasks" })); - newQueryControlDiv.append(listType); - // choose query subtype - var querySubtype = contentEl.createEl("select"); - querySubtype.setAttr("class", "dropdown"); - querySubtype.multiple; - querySubtype.setAttr("id", "Additional Query Subtype " + queryCount); - // querySubtype.setAttr("style", "float: right;"); - var defaultSubtypeOption = contentEl.createEl("option", { "value": "", "text": "with text containing" }); - defaultSubtypeOption.selected; - querySubtype.append(defaultSubtypeOption); - querySubtype.append(contentEl.createEl("option", { "value": "with a link to notes with names containing", "text": "with links to notes with names containing" })); - querySubtype.append(contentEl.createEl("option", { "value": "with an email address", "text": "with email addresses (ignores the following search field)" })); - querySubtype.append(contentEl.createEl("option", { "value": "with a phone number", "text": "with phone numbers (ignores the following search field)" })); - newQueryControlDiv.append(querySubtype); - var newQuery = contentEl.createEl("input", { "type": "text" }); - newQuery.setAttr("id", "NOT query " + queryCount); - queryCount = queryCount + 1; - newQueryControlDiv.append(newQuery); - newQueryDiv.append(newQueryInfoDiv); - newQueryDiv.append(newQueryControlDiv); - vantageAddedQueriesDiv.append(newQueryDiv); - var inputBoxes = vantageAddedQueriesDiv.querySelectorAll("input"); - inputBoxes.forEach(function (inputBox) { - inputBox.addEventListener('keypress', function (keypressed) { - if (keypressed.key === 'Enter') { - initiateSearch(); - } - }); - }); - var optionBoxes = vantageAddedQueriesDiv.querySelectorAll("select"); - optionBoxes.forEach(function (optionBox) { - optionBox.addEventListener('keypress', function (keypressed) { - if (keypressed.key === 'Enter') { - initiateSearch(); - } - }); - }); - }); - new obsidian.ButtonComponent(vantageButtonsControlDiv) - .setButtonText("Create embedded search") - .setClass("mod-cta") - .onClick(function () { - var embeddedSearchQueryHeader = "```query\n"; - var embeddedSearchQueryFooter = "\n```"; - var embeddedSearchQuery; - fileStartDateInput.removeAttribute("style"); - fileEndDateInput.removeAttribute("style"); - if ((fileStartDateInput.value != "") && (fileEndDateInput.value != "")) { // If both date fields have values, the user is trying to search daily notes - var parsedFileStartDate = naturalLanguageDates.parseDate(fileStartDateInput.value); - var parsedFileEndDate = naturalLanguageDates.parseDate(fileEndDateInput.value); - if (naturalLanguageDates.getFormattedDate(parsedFileStartDate.moment).contains("Invalid")) { // if the start date cannot be processed, let the user know - console.log("Start date could not be processed."); - new obsidian.Notice("Sorry, something seems to be wrong with that start date."); - fileStartDateInput.setAttr("style", "border-color: var(--background-modifier-error); border-width: .1em;"); - } - if (naturalLanguageDates.getFormattedDate(parsedFileEndDate.moment).contains("Invalid")) { // if the end date cannot be processed, let the user know - console.log("End date could not be processed."); - new obsidian.Notice("Sorry, something seems to be wrong with that end date."); - fileEndDateInput.setAttr("style", "border-color: var(--background-modifier-error); border-width: .1em;"); - } - if (!(naturalLanguageDates.getFormattedDate(parsedFileStartDate.moment).contains("Invalid")) && !(naturalLanguageDates.getFormattedDate(parsedFileEndDate.moment).contains("Invalid"))) { // otherwise go ahead with the search - embeddedSearchQuery = embeddedSearchQueryHeader + setSearchQuery() + embeddedSearchQueryFooter; - // let doc = this.app.workspace.activeLeaf.view.sourceMode.cmEditor.getDoc(); - var view = _this.app.workspace.getActiveViewOfType(obsidian.MarkdownView); - if (!view) { - new obsidian.Notice("No editable document is open. Perhaps you meant to click \"New search\"?"); - return; - } - _this.close(); - var doc = view.sourceMode.cmEditor.getDoc(); - var cursor = doc.getCursor(); - doc.replaceRange(embeddedSearchQuery, cursor); - } - } - else { // no dates have been entered, so the search can continue - embeddedSearchQuery = embeddedSearchQueryHeader + setSearchQuery() + embeddedSearchQueryFooter; - var view = _this.app.workspace.getActiveViewOfType(obsidian.MarkdownView); - if (!view) { - new obsidian.Notice("No editable document is open. Perhaps you meant to click \"New search\"?"); - return; - } - _this.close(); - var doc = view.sourceMode.cmEditor.getDoc(); - var cursor = doc.getCursor(); - doc.replaceRange(embeddedSearchQuery, cursor); - } - }); - new obsidian.ButtonComponent(vantageButtonsControlDiv) - .setButtonText("New search") - .setClass("mod-cta") - .onClick(function () { - fileStartDateInput.removeAttribute("style"); - fileEndDateInput.removeAttribute("style"); - if ((fileStartDateInput.value != "") && (fileEndDateInput.value != "")) { // If both date fields have values, the user is trying to search daily notes - var parsedFileStartDate = naturalLanguageDates.parseDate(fileStartDateInput.value); - var parsedFileEndDate = naturalLanguageDates.parseDate(fileEndDateInput.value); - if (naturalLanguageDates.getFormattedDate(parsedFileStartDate.moment).contains("Invalid")) { // if the start date cannot be processed, let the user know - console.log("Start date could not be processed."); - new obsidian.Notice("Sorry, something seems to be wrong with that start date."); - fileStartDateInput.setAttr("style", "border-color: var(--background-modifier-error); border-width: .1em;"); - return; - } - if (naturalLanguageDates.getFormattedDate(parsedFileEndDate.moment).contains("Invalid")) { // if the end date cannot be processed, let the user know - console.log("End date could not be processed."); - new obsidian.Notice("Sorry, something seems to be wrong with that end date."); - fileEndDateInput.setAttr("style", "border-color: var(--background-modifier-error); border-width: .1em;"); - return; - } - if (!(naturalLanguageDates.getFormattedDate(parsedFileStartDate.moment).contains("Invalid")) && !(naturalLanguageDates.getFormattedDate(parsedFileEndDate.moment).contains("Invalid"))) { // otherwise go ahead with the search - initiateSearch(); - } - } - else { // no dates have been entered, so the search can continue - initiateSearch(); - } - }); - vantageButtonsDiv.append(vantageButtonsControlDiv); - vantageSettingsDiv.append(vantageButtonsDiv); - }; - VantageModal.prototype.onClose = function () { - var contentEl = this.contentEl; - contentEl.empty(); - }; - return VantageModal; -}(obsidian.Modal)); -// class SampleSettingTab extends PluginSettingTab { -// display(): void { -// let {containerEl} = this; -// containerEl.empty(); -// containerEl.createEl('h2', {text: 'Settings for my awesome plugin.'}); -// new Setting(containerEl) -// .setName('Setting #1') -// .setDesc('It\'s a secret') -// .addText(text => text.setPlaceholder('Enter your secret') -// .setValue('') -// .onChange((value) => { -// console.log('Secret: ' + value); -// })); -// } -// } - -module.exports = MyVantagePlugin; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZXMiOlsibm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsIm1haW4udHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyohICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcbkNvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLlxyXG5cclxuUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IgYW55XHJcbnB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZC5cclxuXHJcblRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEhcclxuUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZXHJcbkFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIERJUkVDVCxcclxuSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NXHJcbkxPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SXHJcbk9USEVSIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1JcclxuUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS5cclxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi9cclxuLyogZ2xvYmFsIFJlZmxlY3QsIFByb21pc2UgKi9cclxuXHJcbnZhciBleHRlbmRTdGF0aWNzID0gZnVuY3Rpb24oZCwgYikge1xyXG4gICAgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHRlbmRzKGQsIGIpIHtcclxuICAgIGlmICh0eXBlb2YgYiAhPT0gXCJmdW5jdGlvblwiICYmIGIgIT09IG51bGwpXHJcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNsYXNzIGV4dGVuZHMgdmFsdWUgXCIgKyBTdHJpbmcoYikgKyBcIiBpcyBub3QgYSBjb25zdHJ1Y3RvciBvciBudWxsXCIpO1xyXG4gICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fYXNzaWduID0gZnVuY3Rpb24oKSB7XHJcbiAgICBfX2Fzc2lnbiA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gX19hc3NpZ24odCkge1xyXG4gICAgICAgIGZvciAodmFyIHMsIGkgPSAxLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IG47IGkrKykge1xyXG4gICAgICAgICAgICBzID0gYXJndW1lbnRzW2ldO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkpIHRbcF0gPSBzW3BdO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdDtcclxuICAgIH1cclxuICAgIHJldHVybiBfX2Fzc2lnbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZXN0KHMsIGUpIHtcclxuICAgIHZhciB0ID0ge307XHJcbiAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkgJiYgZS5pbmRleE9mKHApIDwgMClcclxuICAgICAgICB0W3BdID0gc1twXTtcclxuICAgIGlmIChzICE9IG51bGwgJiYgdHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPT09IFwiZnVuY3Rpb25cIilcclxuICAgICAgICBmb3IgKHZhciBpID0gMCwgcCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMocyk7IGkgPCBwLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmIChlLmluZGV4T2YocFtpXSkgPCAwICYmIE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChzLCBwW2ldKSlcclxuICAgICAgICAgICAgICAgIHRbcFtpXV0gPSBzW3BbaV1dO1xyXG4gICAgICAgIH1cclxuICAgIHJldHVybiB0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYykge1xyXG4gICAgdmFyIGMgPSBhcmd1bWVudHMubGVuZ3RoLCByID0gYyA8IDMgPyB0YXJnZXQgOiBkZXNjID09PSBudWxsID8gZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBrZXkpIDogZGVzYywgZDtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5kZWNvcmF0ZSA9PT0gXCJmdW5jdGlvblwiKSByID0gUmVmbGVjdC5kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYyk7XHJcbiAgICBlbHNlIGZvciAodmFyIGkgPSBkZWNvcmF0b3JzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSBpZiAoZCA9IGRlY29yYXRvcnNbaV0pIHIgPSAoYyA8IDMgPyBkKHIpIDogYyA+IDMgPyBkKHRhcmdldCwga2V5LCByKSA6IGQodGFyZ2V0LCBrZXkpKSB8fCByO1xyXG4gICAgcmV0dXJuIGMgPiAzICYmIHIgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCByKSwgcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcGFyYW0ocGFyYW1JbmRleCwgZGVjb3JhdG9yKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwga2V5KSB7IGRlY29yYXRvcih0YXJnZXQsIGtleSwgcGFyYW1JbmRleCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fbWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpIHtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5tZXRhZGF0YSA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gUmVmbGVjdC5tZXRhZGF0YShtZXRhZGF0YUtleSwgbWV0YWRhdGFWYWx1ZSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2F3YWl0ZXIodGhpc0FyZywgX2FyZ3VtZW50cywgUCwgZ2VuZXJhdG9yKSB7XHJcbiAgICBmdW5jdGlvbiBhZG9wdCh2YWx1ZSkgeyByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBQID8gdmFsdWUgOiBuZXcgUChmdW5jdGlvbiAocmVzb2x2ZSkgeyByZXNvbHZlKHZhbHVlKTsgfSk7IH1cclxuICAgIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIGZ1bGZpbGxlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvci5uZXh0KHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiByZWplY3RlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvcltcInRocm93XCJdKHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cclxuICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IGFkb3B0KHJlc3VsdC52YWx1ZSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxyXG4gICAgICAgIHN0ZXAoKGdlbmVyYXRvciA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSkubmV4dCgpKTtcclxuICAgIH0pO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19nZW5lcmF0b3IodGhpc0FyZywgYm9keSkge1xyXG4gICAgdmFyIF8gPSB7IGxhYmVsOiAwLCBzZW50OiBmdW5jdGlvbigpIHsgaWYgKHRbMF0gJiAxKSB0aHJvdyB0WzFdOyByZXR1cm4gdFsxXTsgfSwgdHJ5czogW10sIG9wczogW10gfSwgZiwgeSwgdCwgZztcclxuICAgIHJldHVybiBnID0geyBuZXh0OiB2ZXJiKDApLCBcInRocm93XCI6IHZlcmIoMSksIFwicmV0dXJuXCI6IHZlcmIoMikgfSwgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIChnW1N5bWJvbC5pdGVyYXRvcl0gPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXM7IH0pLCBnO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IHJldHVybiBmdW5jdGlvbiAodikgeyByZXR1cm4gc3RlcChbbiwgdl0pOyB9OyB9XHJcbiAgICBmdW5jdGlvbiBzdGVwKG9wKSB7XHJcbiAgICAgICAgaWYgKGYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJHZW5lcmF0b3IgaXMgYWxyZWFkeSBleGVjdXRpbmcuXCIpO1xyXG4gICAgICAgIHdoaWxlIChfKSB0cnkge1xyXG4gICAgICAgICAgICBpZiAoZiA9IDEsIHkgJiYgKHQgPSBvcFswXSAmIDIgPyB5W1wicmV0dXJuXCJdIDogb3BbMF0gPyB5W1widGhyb3dcIl0gfHwgKCh0ID0geVtcInJldHVyblwiXSkgJiYgdC5jYWxsKHkpLCAwKSA6IHkubmV4dCkgJiYgISh0ID0gdC5jYWxsKHksIG9wWzFdKSkuZG9uZSkgcmV0dXJuIHQ7XHJcbiAgICAgICAgICAgIGlmICh5ID0gMCwgdCkgb3AgPSBbb3BbMF0gJiAyLCB0LnZhbHVlXTtcclxuICAgICAgICAgICAgc3dpdGNoIChvcFswXSkge1xyXG4gICAgICAgICAgICAgICAgY2FzZSAwOiBjYXNlIDE6IHQgPSBvcDsgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIDQ6IF8ubGFiZWwrKzsgcmV0dXJuIHsgdmFsdWU6IG9wWzFdLCBkb25lOiBmYWxzZSB9O1xyXG4gICAgICAgICAgICAgICAgY2FzZSA1OiBfLmxhYmVsKys7IHkgPSBvcFsxXTsgb3AgPSBbMF07IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA3OiBvcCA9IF8ub3BzLnBvcCgpOyBfLnRyeXMucG9wKCk7IGNvbnRpbnVlO1xyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgICAgICBpZiAoISh0ID0gXy50cnlzLCB0ID0gdC5sZW5ndGggPiAwICYmIHRbdC5sZW5ndGggLSAxXSkgJiYgKG9wWzBdID09PSA2IHx8IG9wWzBdID09PSAyKSkgeyBfID0gMDsgY29udGludWU7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDMgJiYgKCF0IHx8IChvcFsxXSA+IHRbMF0gJiYgb3BbMV0gPCB0WzNdKSkpIHsgXy5sYWJlbCA9IG9wWzFdOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChvcFswXSA9PT0gNiAmJiBfLmxhYmVsIDwgdFsxXSkgeyBfLmxhYmVsID0gdFsxXTsgdCA9IG9wOyBicmVhazsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0ICYmIF8ubGFiZWwgPCB0WzJdKSB7IF8ubGFiZWwgPSB0WzJdOyBfLm9wcy5wdXNoKG9wKTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodFsyXSkgXy5vcHMucG9wKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBvcCA9IGJvZHkuY2FsbCh0aGlzQXJnLCBfKTtcclxuICAgICAgICB9IGNhdGNoIChlKSB7IG9wID0gWzYsIGVdOyB5ID0gMDsgfSBmaW5hbGx5IHsgZiA9IHQgPSAwOyB9XHJcbiAgICAgICAgaWYgKG9wWzBdICYgNSkgdGhyb3cgb3BbMV07IHJldHVybiB7IHZhbHVlOiBvcFswXSA/IG9wWzFdIDogdm9pZCAwLCBkb25lOiB0cnVlIH07XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCB2YXIgX19jcmVhdGVCaW5kaW5nID0gT2JqZWN0LmNyZWF0ZSA/IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xyXG4gICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvLCBrMiwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gbVtrXTsgfSB9KTtcclxufSkgOiAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcclxuICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XHJcbiAgICBvW2syXSA9IG1ba107XHJcbn0pO1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXhwb3J0U3RhcihtLCBvKSB7XHJcbiAgICBmb3IgKHZhciBwIGluIG0pIGlmIChwICE9PSBcImRlZmF1bHRcIiAmJiAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG8sIHApKSBfX2NyZWF0ZUJpbmRpbmcobywgbSwgcCk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3ZhbHVlcyhvKSB7XHJcbiAgICB2YXIgcyA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBTeW1ib2wuaXRlcmF0b3IsIG0gPSBzICYmIG9bc10sIGkgPSAwO1xyXG4gICAgaWYgKG0pIHJldHVybiBtLmNhbGwobyk7XHJcbiAgICBpZiAobyAmJiB0eXBlb2Ygby5sZW5ndGggPT09IFwibnVtYmVyXCIpIHJldHVybiB7XHJcbiAgICAgICAgbmV4dDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAobyAmJiBpID49IG8ubGVuZ3RoKSBvID0gdm9pZCAwO1xyXG4gICAgICAgICAgICByZXR1cm4geyB2YWx1ZTogbyAmJiBvW2krK10sIGRvbmU6ICFvIH07XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IocyA/IFwiT2JqZWN0IGlzIG5vdCBpdGVyYWJsZS5cIiA6IFwiU3ltYm9sLml0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVhZChvLCBuKSB7XHJcbiAgICB2YXIgbSA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvW1N5bWJvbC5pdGVyYXRvcl07XHJcbiAgICBpZiAoIW0pIHJldHVybiBvO1xyXG4gICAgdmFyIGkgPSBtLmNhbGwobyksIHIsIGFyID0gW10sIGU7XHJcbiAgICB0cnkge1xyXG4gICAgICAgIHdoaWxlICgobiA9PT0gdm9pZCAwIHx8IG4tLSA+IDApICYmICEociA9IGkubmV4dCgpKS5kb25lKSBhci5wdXNoKHIudmFsdWUpO1xyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGVycm9yKSB7IGUgPSB7IGVycm9yOiBlcnJvciB9OyB9XHJcbiAgICBmaW5hbGx5IHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBpZiAociAmJiAhci5kb25lICYmIChtID0gaVtcInJldHVyblwiXSkpIG0uY2FsbChpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZmluYWxseSB7IGlmIChlKSB0aHJvdyBlLmVycm9yOyB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbi8qKiBAZGVwcmVjYXRlZCAqL1xyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWQoKSB7XHJcbiAgICBmb3IgKHZhciBhciA9IFtdLCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKylcclxuICAgICAgICBhciA9IGFyLmNvbmNhdChfX3JlYWQoYXJndW1lbnRzW2ldKSk7XHJcbiAgICByZXR1cm4gYXI7XHJcbn1cclxuXHJcbi8qKiBAZGVwcmVjYXRlZCAqL1xyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWRBcnJheXMoKSB7XHJcbiAgICBmb3IgKHZhciBzID0gMCwgaSA9IDAsIGlsID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IGlsOyBpKyspIHMgKz0gYXJndW1lbnRzW2ldLmxlbmd0aDtcclxuICAgIGZvciAodmFyIHIgPSBBcnJheShzKSwgayA9IDAsIGkgPSAwOyBpIDwgaWw7IGkrKylcclxuICAgICAgICBmb3IgKHZhciBhID0gYXJndW1lbnRzW2ldLCBqID0gMCwgamwgPSBhLmxlbmd0aDsgaiA8IGpsOyBqKyssIGsrKylcclxuICAgICAgICAgICAgcltrXSA9IGFbal07XHJcbiAgICByZXR1cm4gcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fc3ByZWFkQXJyYXkodG8sIGZyb20sIHBhY2spIHtcclxuICAgIGlmIChwYWNrIHx8IGFyZ3VtZW50cy5sZW5ndGggPT09IDIpIGZvciAodmFyIGkgPSAwLCBsID0gZnJvbS5sZW5ndGgsIGFyOyBpIDwgbDsgaSsrKSB7XHJcbiAgICAgICAgaWYgKGFyIHx8ICEoaSBpbiBmcm9tKSkge1xyXG4gICAgICAgICAgICBpZiAoIWFyKSBhciA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGZyb20sIDAsIGkpO1xyXG4gICAgICAgICAgICBhcltpXSA9IGZyb21baV07XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRvLmNvbmNhdChhciB8fCBmcm9tKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXQodikge1xyXG4gICAgcmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBfX2F3YWl0ID8gKHRoaXMudiA9IHYsIHRoaXMpIDogbmV3IF9fYXdhaXQodik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jR2VuZXJhdG9yKHRoaXNBcmcsIF9hcmd1bWVudHMsIGdlbmVyYXRvcikge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBnID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pLCBpLCBxID0gW107XHJcbiAgICByZXR1cm4gaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgaWYgKGdbbl0pIGlbbl0gPSBmdW5jdGlvbiAodikgeyByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKGEsIGIpIHsgcS5wdXNoKFtuLCB2LCBhLCBiXSkgPiAxIHx8IHJlc3VtZShuLCB2KTsgfSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHJlc3VtZShuLCB2KSB7IHRyeSB7IHN0ZXAoZ1tuXSh2KSk7IH0gY2F0Y2ggKGUpIHsgc2V0dGxlKHFbMF1bM10sIGUpOyB9IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAocikgeyByLnZhbHVlIGluc3RhbmNlb2YgX19hd2FpdCA/IFByb21pc2UucmVzb2x2ZShyLnZhbHVlLnYpLnRoZW4oZnVsZmlsbCwgcmVqZWN0KSA6IHNldHRsZShxWzBdWzJdLCByKTsgfVxyXG4gICAgZnVuY3Rpb24gZnVsZmlsbCh2YWx1ZSkgeyByZXN1bWUoXCJuZXh0XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gcmVqZWN0KHZhbHVlKSB7IHJlc3VtZShcInRocm93XCIsIHZhbHVlKTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKGYsIHYpIHsgaWYgKGYodiksIHEuc2hpZnQoKSwgcS5sZW5ndGgpIHJlc3VtZShxWzBdWzBdLCBxWzBdWzFdKTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hc3luY0RlbGVnYXRvcihvKSB7XHJcbiAgICB2YXIgaSwgcDtcclxuICAgIHJldHVybiBpID0ge30sIHZlcmIoXCJuZXh0XCIpLCB2ZXJiKFwidGhyb3dcIiwgZnVuY3Rpb24gKGUpIHsgdGhyb3cgZTsgfSksIHZlcmIoXCJyZXR1cm5cIiksIGlbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGk7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4sIGYpIHsgaVtuXSA9IG9bbl0gPyBmdW5jdGlvbiAodikgeyByZXR1cm4gKHAgPSAhcCkgPyB7IHZhbHVlOiBfX2F3YWl0KG9bbl0odikpLCBkb25lOiBuID09PSBcInJldHVyblwiIH0gOiBmID8gZih2KSA6IHY7IH0gOiBmOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jVmFsdWVzKG8pIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgbSA9IG9bU3ltYm9sLmFzeW5jSXRlcmF0b3JdLCBpO1xyXG4gICAgcmV0dXJuIG0gPyBtLmNhbGwobykgOiAobyA9IHR5cGVvZiBfX3ZhbHVlcyA9PT0gXCJmdW5jdGlvblwiID8gX192YWx1ZXMobykgOiBvW1N5bWJvbC5pdGVyYXRvcl0oKSwgaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGkpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IGlbbl0gPSBvW25dICYmIGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7IHYgPSBvW25dKHYpLCBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCB2LmRvbmUsIHYudmFsdWUpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgZCwgdikgeyBQcm9taXNlLnJlc29sdmUodikudGhlbihmdW5jdGlvbih2KSB7IHJlc29sdmUoeyB2YWx1ZTogdiwgZG9uZTogZCB9KTsgfSwgcmVqZWN0KTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tYWtlVGVtcGxhdGVPYmplY3QoY29va2VkLCByYXcpIHtcclxuICAgIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvb2tlZCwgXCJyYXdcIiwgeyB2YWx1ZTogcmF3IH0pOyB9IGVsc2UgeyBjb29rZWQucmF3ID0gcmF3OyB9XHJcbiAgICByZXR1cm4gY29va2VkO1xyXG59O1xyXG5cclxudmFyIF9fc2V0TW9kdWxlRGVmYXVsdCA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgdikge1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIFwiZGVmYXVsdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2IH0pO1xyXG59KSA6IGZ1bmN0aW9uKG8sIHYpIHtcclxuICAgIG9bXCJkZWZhdWx0XCJdID0gdjtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydFN0YXIobW9kKSB7XHJcbiAgICBpZiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSByZXR1cm4gbW9kO1xyXG4gICAgdmFyIHJlc3VsdCA9IHt9O1xyXG4gICAgaWYgKG1vZCAhPSBudWxsKSBmb3IgKHZhciBrIGluIG1vZCkgaWYgKGsgIT09IFwiZGVmYXVsdFwiICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChtb2QsIGspKSBfX2NyZWF0ZUJpbmRpbmcocmVzdWx0LCBtb2QsIGspO1xyXG4gICAgX19zZXRNb2R1bGVEZWZhdWx0KHJlc3VsdCwgbW9kKTtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2ltcG9ydERlZmF1bHQobW9kKSB7XHJcbiAgICByZXR1cm4gKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgPyBtb2QgOiB7IGRlZmF1bHQ6IG1vZCB9O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZEdldChyZWNlaXZlciwgc3RhdGUsIGtpbmQsIGYpIHtcclxuICAgIGlmIChraW5kID09PSBcImFcIiAmJiAhZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlByaXZhdGUgYWNjZXNzb3Igd2FzIGRlZmluZWQgd2l0aG91dCBhIGdldHRlclwiKTtcclxuICAgIGlmICh0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZiA6ICFzdGF0ZS5oYXMocmVjZWl2ZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xyXG4gICAgcmV0dXJuIGtpbmQgPT09IFwibVwiID8gZiA6IGtpbmQgPT09IFwiYVwiID8gZi5jYWxsKHJlY2VpdmVyKSA6IGYgPyBmLnZhbHVlIDogc3RhdGUuZ2V0KHJlY2VpdmVyKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fY2xhc3NQcml2YXRlRmllbGRTZXQocmVjZWl2ZXIsIHN0YXRlLCB2YWx1ZSwga2luZCwgZikge1xyXG4gICAgaWYgKGtpbmQgPT09IFwibVwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBtZXRob2QgaXMgbm90IHdyaXRhYmxlXCIpO1xyXG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgc2V0dGVyXCIpO1xyXG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3Qgd3JpdGUgcHJpdmF0ZSBtZW1iZXIgdG8gYW4gb2JqZWN0IHdob3NlIGNsYXNzIGRpZCBub3QgZGVjbGFyZSBpdFwiKTtcclxuICAgIHJldHVybiAoa2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIsIHZhbHVlKSA6IGYgPyBmLnZhbHVlID0gdmFsdWUgOiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSksIHZhbHVlO1xyXG59XHJcbiIsImltcG9ydCB7IEFwcCwgTW9kYWwsIEl0ZW1WaWV3LCBNYXJrZG93blZpZXcsIE5vdGljZSwgUGx1Z2luLCBQbHVnaW5TZXR0aW5nVGFiLCBTZXR0aW5nLCBXb3Jrc3BhY2VMZWFmLCBURmlsZSwgVG9nZ2xlQ29tcG9uZW50LCBUZXh0Q29tcG9uZW50LCBEcm9wZG93bkNvbXBvbmVudCwgQnV0dG9uQ29tcG9uZW50LCBXb3Jrc3BhY2UgfSBmcm9tICdvYnNpZGlhbic7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNeVZhbnRhZ2VQbHVnaW4gZXh0ZW5kcyBQbHVnaW4ge1xyXG5cdG9ubG9hZCgpIHtcclxuXHRcdGNvbnNvbGUubG9nKCdMb2FkaW5nIHRoZSBWYW50YWdlIHBsdWdpbi4nKTtcclxuXHJcblx0XHRpZiAodGhpcy5hcHAud29ya3NwYWNlLmxheW91dFJlYWR5KSB7XHJcblx0XHRcdHRoaXMub25MYXlvdXRSZWFkeSgpO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0dGhpcy5hcHAud29ya3NwYWNlLm9uKFwibGF5b3V0LXJlYWR5XCIsIHRoaXMub25MYXlvdXRSZWFkeS5iaW5kKHRoaXMpKTtcclxuXHRcdH1cclxuXHJcblx0XHR0aGlzLmFkZENvbW1hbmQoe1xyXG5cdFx0XHRpZDogJ2J1aWxkLXNlYXJjaCcsXHJcblx0XHRcdG5hbWU6IFwiQnVpbGQgYSBuZXcgc2VhcmNoXCIsXHJcblx0XHRcdFxyXG5cdFx0XHRjaGVja0NhbGxiYWNrOiAoY2hlY2tpbmc6IGJvb2xlYW4pID0+IHtcclxuXHRcdFx0XHRsZXQgbGVhZiA9IHRoaXMuYXBwLndvcmtzcGFjZS5hY3RpdmVMZWFmO1xyXG5cdFx0XHRcdGlmIChsZWFmKSB7XHJcblx0XHRcdFx0XHRpZiAoIWNoZWNraW5nKSB7XHJcblx0XHRcdFx0XHRcdG5ldyBWYW50YWdlTW9kYWwodGhpcy5hcHApLm9wZW4oKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHRcdHRoaXMuYWRkUmliYm9uSWNvbignbWFnbmlmeWluZy1nbGFzcycsICdWYW50YWdlIC0gQWR2YW5jZWQgc2VhcmNoIGJ1aWxkZXInLCAoKSA9PiB7XHJcblx0XHRcdFx0bGV0IGxlYWYgPSB0aGlzLmFwcC53b3Jrc3BhY2UuYWN0aXZlTGVhZjtcclxuXHRcdFx0XHRpZiAobGVhZikge1xyXG5cdFx0XHRcdFx0XHRuZXcgVmFudGFnZU1vZGFsKHRoaXMuYXBwKS5vcGVuKCk7XHJcblx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0Ly8gdGhpcy5hZGRTZXR0aW5nVGFiKG5ldyBTYW1wbGVTZXR0aW5nVGFiKHRoaXMuYXBwLCB0aGlzKSk7XHJcblx0fVxyXG5cclxuXHRvbkxheW91dFJlYWR5KCkge1xyXG5cdFx0Ly8gQ2hlY2sgZm9yIHRoZSBOYXR1cmFsIExhbmd1YWdlIERhdGVzIHBsdWdpbiBhZnRlciBhbGwgdGhlIHBsdWdpbnMgYXJlIGxvYWRlZC5cclxuXHRcdC8vIElmIG5vdCBmb3VuZCwgdGVsbCB0aGUgdXNlciB0byBpbnN0YWxsIGl0L2luaXRpYWxpemUgaXQuXHJcblx0XHRsZXQgbmF0dXJhbExhbmd1YWdlRGF0ZXMgPSAoPGFueT50aGlzLmFwcCkucGx1Z2lucy5nZXRQbHVnaW4oJ25sZGF0ZXMtb2JzaWRpYW4nKTtcclxuXHRcdGlmICghbmF0dXJhbExhbmd1YWdlRGF0ZXMpIHtcclxuXHRcdFx0bmV3IE5vdGljZShcIlRoZSBOYXR1cmFsIExhbmd1YWdlIERhdGVzIHBsdWdpbiB3YXMgbm90IGZvdW5kLiBUaGUgVmFudGFnZSBwbHVnaW4gcmVxdWlyZXMgdGhlIE5hdHVyYWwgTGFuZ3VhZ2UgRGF0ZXMgcGx1Z2luLiBQbGVhc2UgaW5zdGFsbCBpdCBmaXJzdCBhbmQgbWFrZSBzdXJlIGl0IGlzIHVwZGF0ZWQgYW5kIGVuYWJsZWQgYmVmb3JlIHVzaW5nIFZhbnRhZ2UuXCIpO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0b251bmxvYWQoKSB7XHJcblx0XHRjb25zb2xlLmxvZygnVW5sb2FkaW5nIHRoZSBWYW50YWdlIHBsdWdpbicpO1xyXG5cdH1cclxuXHJcblx0Ly8gZ2V0QmFja2xpbmtzKHNvbWVGaWxlOiBURmlsZSkgeyAvLyBObyBsb25nZXIgdXNlZFxyXG5cdC8vIFx0bGV0IG9ic2lkaWFuQXBwID0gdGhpcy5hcHA7XHJcblx0Ly8gXHRsZXQgYWxsTm90ZXMgPSB0aGlzLmFwcC52YXVsdC5nZXRNYXJrZG93bkZpbGVzKCk7XHJcblx0Ly8gXHRsZXQgY3VycmVudEJhY2tsaW5rczogT2JqZWN0W10gPSBbXTtcclxuXHJcblx0Ly8gXHRhbGxOb3Rlcy5mb3JFYWNoKChtYXJrZG93bkZpbGU6IFRGaWxlKSA9PiB7XHJcblx0Ly8gXHRcdHRoaXMuYXBwLm1ldGFkYXRhQ2FjaGUuZ2V0RmlsZUNhY2hlKG1hcmtkb3duRmlsZSk7XHJcblx0Ly8gXHRcdGxldCB0aGlzTWV0YWRhdGFDYWNoZSA9IG9ic2lkaWFuQXBwLm1ldGFkYXRhQ2FjaGUuZ2V0RmlsZUNhY2hlKG1hcmtkb3duRmlsZSk7XHJcblx0Ly8gXHRcdGlmICh0aGlzTWV0YWRhdGFDYWNoZS5saW5rcykge1xyXG5cdC8vIFx0XHRcdGZvciAobGV0IGVhY2hMaW5rIG9mIHRoaXNNZXRhZGF0YUNhY2hlLmxpbmtzKSB7XHJcblx0Ly8gXHRcdFx0XHRpZiAoZWFjaExpbmsubGluayA9PT0gY3VycmVudEZpbGVOYW1lKSB7XHJcblx0Ly8gXHRcdFx0XHRcdGN1cnJlbnRCYWNrbGlua3MucHVzaCh7bm90ZU5hbWU6IG1hcmtkb3duRmlsZS5iYXNlbmFtZSwgc3RhcnRQb3NpdGlvbjogZWFjaExpbmsucG9zaXRpb24uc3RhcnQsIGVuZFBvc2l0aW9uOiBlYWNoTGluay5wb3NpdGlvbi5lbmR9KTtcclxuXHQvLyBcdFx0XHRcdH1cclxuXHQvLyBcdFx0XHR9XHJcblx0Ly8gXHRcdH1cclxuXHQvLyBcdFx0aWYgKHRoaXNNZXRhZGF0YUNhY2hlLmVtYmVkcykge1xyXG5cdC8vIFx0XHRcdGZvciAobGV0IGVhY2hFbWJlZCBvZiB0aGlzTWV0YWRhdGFDYWNoZS5lbWJlZHMpIHtcclxuXHQvLyBcdFx0XHRcdGlmIChlYWNoRW1iZWQubGluay5jb250YWlucyhjdXJyZW50RmlsZU5hbWUpKSB7XHJcblx0Ly8gXHRcdFx0XHRcdGN1cnJlbnRCYWNrbGlua3MucHVzaCh7bm90ZU5hbWU6IG1hcmtkb3duRmlsZS5iYXNlbmFtZSwgc3RhcnRQb3NpdGlvbjogZWFjaEVtYmVkLnBvc2l0aW9uLnN0YXJ0LCBlbmRQb3NpdGlvbjogZWFjaEVtYmVkLnBvc2l0aW9uLmVuZH0pO1xyXG5cdC8vIFx0XHRcdFx0fVxyXG5cdC8vIFx0XHRcdH1cclxuXHQvLyBcdFx0fVxyXG5cdC8vIFx0fSk7XHJcblxyXG5cdC8vIFx0cmV0dXJuIGN1cnJlbnRCYWNrbGlua3M7XHJcblx0Ly8gfVxyXG5cclxuXHRkZWxheSh3YWl0dGltZUluTWlsbGlzZWNvbmRzOiBudW1iZXIpIHsgLy8gaGF0LXRpcCB0byBSb2hpdGggSyBQIGZvciB0aGlzIGhhbmR5IGFzeW5jaHJvbm91cyBkZWxheSBmdW5jdGlvbiAoaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTc4ODM2OTIvaG93LXRvLXNldC10aW1lLWRlbGF5LWluLWphdmFzY3JpcHQvNDk4MTM0NzIjNDk4MTM0NzIpXHJcblx0XHRyZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XHJcblx0XHQgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG5cdFx0XHRyZXNvbHZlKDIpO1xyXG5cdFx0ICB9LCB3YWl0dGltZUluTWlsbGlzZWNvbmRzKTtcclxuXHRcdH0pO1xyXG5cdCAgfVxyXG5cclxuXHRhc3luYyBnZXRTZWFyY2goc29tZVNlYXJjaFF1ZXJ5OiBzdHJpbmcpIHtcclxuXHRcdHRoaXMuYXBwLmludGVybmFsUGx1Z2lucy5nZXRQbHVnaW5CeUlkKCdnbG9iYWwtc2VhcmNoJykuaW5zdGFuY2Uub3Blbkdsb2JhbFNlYXJjaChzb21lU2VhcmNoUXVlcnkpO1xyXG5cdFx0YXdhaXQgdGhpcy5kZWxheSg1MDAwKTtcclxuXHRcdGxldCBzZWFyY2hSZXN1bHRzID0gdGhpcy5hcHAud29ya3NwYWNlLmdldExlYXZlc09mVHlwZSgnc2VhcmNoJylbMF0udmlldy5kb20ucmVzdWx0RG9tczsvL2hhdC10aXAgdG8gTXJKYWNrUGhpbCBmb3IgZmlndXJpbmcgb3V0IGhvdyB0byBwbGF5IHdpdGggU2VhcmNoXHJcblx0XHQvLyBjb25zb2xlLmxvZyhzZWFyY2hSZXN1bHRzKTtcclxuXHRcdC8vIGlmIChzZWFyY2hSZXN1bHRzLmxlbmd0aCAhPSAwKSB7XHJcblx0XHQvLyBcdHNlYXJjaFJlc3VsdHMuZm9yRWFjaChlYWNoRmlsZSA9PiBjb25zb2xlLmxvZyhlYWNoRmlsZS5maWxlLmJhc2VuYW1lKSk7XHRcclxuXHRcdC8vIH1cclxuXHR9XHJcblxyXG5cdC8vIG9wZW5BbmNob3JQYW5lKHNvbWVMZWFmOiBXb3Jrc3BhY2VMZWFmKSB7IC8vIE9sZCBtZXRob2QgZm9yIGFuIG9sZCBkZXNpZ25cclxuXHQvLyBcdGxldCBvYnNpZGlhbkFwcCA9IHRoaXMuYXBwO1xyXG5cdC8vIFx0bGV0IGN1cnJlbnRMZWFmID0gc29tZUxlYWY7XHJcblx0Ly8gXHRsZXQgZWRpdG9yID0gb2JzaWRpYW5BcHAud29ya3NwYWNlLmFjdGl2ZUxlYWYudmlldy5zb3VyY2VNb2RlLmNtRWRpdG9yO1xyXG5cdC8vIFx0bGV0IGN1cnJlbnRGaWxlID0gY3VycmVudExlYWYudmlldy5maWxlO1xyXG5cdC8vIFx0bGV0IGN1cnJlbnRGaWxlTmFtZSA9IGN1cnJlbnRGaWxlLmJhc2VuYW1lO1xyXG5cdC8vIFx0bGV0IGRvYyA9IGVkaXRvci5nZXREb2MoKTtcclxuXHQvLyBcdGxldCBjdXJzb3IgPSBlZGl0b3IuZ2V0Q3Vyc29yKCk7XHJcblxyXG5cdC8vIFx0Y29uc29sZS5sb2cob2JzaWRpYW5BcHAubWV0YWRhdGFDYWNoZS5nZXRGaWxlQ2FjaGUoY3VycmVudEZpbGUpKTtcclxuXHJcblx0Ly8gXHRsZXQgdGhlQmFja2xpbmtzID0gdGhpcy5nZXRCYWNrbGlua3MoY3VycmVudEZpbGUpO1xyXG5cclxuXHQvLyBcdC8vVGhpcyBzdWNjZXNzZnVsbHkgZ2VuZXJhdGVzIGEgbGlzdCBvZiBsaW5rcyB0byB0aGUgY3VycmVudCBub3RlLCBpbmNsdWRpbmcgdGhlIHN0YXJ0IGFuZCBlbmQgcG9zaXRpb24gb2YgdGhvc2UgbGlua3MuIFxyXG5cdC8vIFx0Y29uc29sZS5sb2codGhlQmFja2xpbmtzKTtcclxuXHJcblx0Ly8gXHQvLyDimJAgSG93IGRvIEkgZ2V0IHRoZSBwbHVnaW4gdG8gbm90aWNlIHdoZW4gYSBuZXcgYmFja2xpbmsgaGFzIGJlZW4gYWRkZWQsIGFuZCByZWZyZXNoIHRoZSBsaXN0P1xyXG5cdC8vIFx0Ly8g4piQIEhvdyBkbyBJIGRpc3BsYXkgdGhpcyBsaXN0IGluIGEgcGFuZSB0aGF0IGNhbiBiZSBjdXN0b21pemVkL21vdmVkIGFyb3VuZD9cclxuXHQvLyBcdC8vIOKYkCBIb3cgZG8gSSBtYWtlIHN1cmUgdGhlIGl0ZW1zIGluIHRoaXMgbGlzdCBhcmUgbGlua3MgdG8gdGhlaXIgc291cmNlP1xyXG5cdC8vIFx0Ly8g4piR77iOIEhvdyBkbyBJIGRvIHRoZSBhYm92ZSB3aXRoIHRhZ3M/IEFuc3dlcjogdXNlIHNlYXJjaCwgcmlmZmluZyBvZmYgb2YgTXJKYWNrUGhpbCdzIGV4cGFuZCBlbWJlZHMgd29ya2Zsb3cuIFNlZSBnZXRTZWFyY2ggYWJvdmVcclxuXHJcblx0Ly8gfVxyXG5cclxuXHJcbn1cclxuXHJcbmNsYXNzIFZhbnRhZ2VNb2RhbCBleHRlbmRzIE1vZGFsIHtcclxuXHRjb25zdHJ1Y3RvcihhcHA6IEFwcCkge1xyXG5cdFx0c3VwZXIoYXBwKTtcclxuXHR9XHJcblxyXG5cdG9uT3BlbigpIHtcclxuXHRcdGxldCB7Y29udGVudEVsfSA9IHRoaXM7XHJcblx0XHRsZXQgc2VhcmNoTW9kYWwgPSB0aGlzO1xyXG5cdFx0Y29udGVudEVsLnBhcmVudEVsZW1lbnQuYWRkQ2xhc3MoXCJ2YW50YWdlLW1vZGFsXCIpO1xyXG5cdFx0bGV0IHZhbnRhZ2VQbHVnaW4gPSB0aGlzLmFwcC5wbHVnaW5zLmdldFBsdWdpbihcInZhbnRhZ2Utb2JzaWRpYW5cIik7XHJcblx0XHRsZXQgbmF0dXJhbExhbmd1YWdlRGF0ZXMgPSB0aGlzLmFwcC5wbHVnaW5zLmdldFBsdWdpbignbmxkYXRlcy1vYnNpZGlhbicpOyAvLyBHZXQgdGhlIE5hdHVyYWwgTGFuZ3VhZ2UgRGF0ZXMgcGx1Z2luLlxyXG5cdFx0dGhpcy50aXRsZUVsLnNldFRleHQoXCJWYW50YWdlIC0gQWR2YW5jZWQgU2VhcmNoXCIpO1xyXG5cdFx0bGV0IHZhbnRhZ2VTZXR0aW5nc0RpdiA9IGNvbnRlbnRFbC5jcmVhdGVFbChcImRpdlwiKTtcclxuXHJcblx0XHRsZXQgdmFudGFnZVNldHRpbmdzRGVzY3JpcHRpb25EaXYgPSBjb250ZW50RWwuY3JlYXRlRWwoXCJkaXZcIik7XHJcblx0XHR2YW50YWdlU2V0dGluZ3NEZXNjcmlwdGlvbkRpdi5hZGRDbGFzcyhcInNldHRpbmctaXRlbVwiKTtcclxuXHRcdGxldCB2YW50YWdlU2V0dGluZ3NEZXNjcmlwdGlvblN1YmRpdiA9IGNvbnRlbnRFbC5jcmVhdGVFbChcImRpdlwiKTtcclxuXHRcdHZhbnRhZ2VTZXR0aW5nc0Rlc2NyaXB0aW9uU3ViZGl2LmFkZENsYXNzKFwic2V0dGluZy1pdGVtLWluZm9cIik7XHJcblx0XHRsZXQgdmFudGFnZVNldHRpbmdzRGVzY3JpcHRpb24gPSBjb250ZW50RWwuY3JlYXRlRWwoXCJkaXZcIiwgeyBcInRleHRcIjogXCJWYW50YWdlIGhlbHBzIGNyZWF0ZSBjb21wbGV4IHNlYXJjaCBxdWVyaWVzLiBTZWUgT2JzaWRpYW4ncyBzZWFyY2ggZG9jdW1lbnRhdGlvbiBmb3IgbW9yZS5cIn0pO1xyXG5cdFx0dmFudGFnZVNldHRpbmdzRGVzY3JpcHRpb24uYWRkQ2xhc3MoXCJzZXR0aW5nLWl0ZW0tZGVzY3JpcHRpb25cIik7XHJcblx0XHRsZXQgdmFudGFnZVNldHRpbmdzRGVzY3JpcHRpb25MaW5rID0gY29udGVudEVsLmNyZWF0ZUVsKFwiYVwiLCB7XCJ0ZXh0XCI6IFwiaHR0cHM6Ly9wdWJsaXNoLm9ic2lkaWFuLm1kL2hlbHAvUGx1Z2lucy9TZWFyY2hcIn0pO1xyXG5cdFx0bGV0IHZhbnRhZ2VTZXR0aW5nc0xpbmVicmVha0RpdiA9IGNvbnRlbnRFbC5jcmVhdGVFbChcImRpdlwiKTtcclxuXHRcdGxldCB2YW50YWdlU2V0dGluZ3NMaW5lYnJlYWsgPSBjb250ZW50RWwuY3JlYXRlRWwoXCJiclwiKTtcclxuXHRcdHZhbnRhZ2VTZXR0aW5nc0xpbmVicmVha0Rpdi5hcHBlbmQodmFudGFnZVNldHRpbmdzTGluZWJyZWFrKTtcclxuXHRcdHZhbnRhZ2VTZXR0aW5nc0xpbmVicmVha0Rpdi5hZGRDbGFzcyhcInNldHRpbmctaXRlbS1kZXNjcmlwdGlvblwiKTtcclxuXHRcdHZhbnRhZ2VTZXR0aW5nc0Rlc2NyaXB0aW9uTGluay5hZGRDbGFzcyhcInNldHRpbmctaXRlbS1kZXNjcmlwdGlvblwiKTtcclxuXHRcdHZhbnRhZ2VTZXR0aW5nc0Rlc2NyaXB0aW9uTGluay5zZXRBdHRyKFwiaHJlZlwiLCBcImh0dHBzOi8vcHVibGlzaC5vYnNpZGlhbi5tZC9oZWxwL1BsdWdpbnMvU2VhcmNoXCIpO1xyXG5cdFx0bGV0IHZhbnRhZ2VTZXR0aW5nc1JlZ2V4RGVzY3JpcHRpb24gPSBjb250ZW50RWwuY3JlYXRlRWwoXCJkaXZcIiwge1widGV4dFwiOiBcIk1hbnkgY29tcGxleCBzZWFyY2hlcyB1c2UgUmVndWxhciBFeHByZXNzaW9ucy4gVGhlc2UgaGVscCB1cyBzZWFyY2ggZm9yIHBhdHRlcm5zIGluIG91ciB0ZXh0LiBWaXNpdCBSZWdFeHIgdG8gbGVhcm4gbW9yZSBhbmQgdG8gcHJhY3RpY2Ugd2l0aCByZWd1bGFyIGV4cHJlc3Npb25zLlwifSk7XHJcblx0XHR2YW50YWdlU2V0dGluZ3NSZWdleERlc2NyaXB0aW9uLmFkZENsYXNzKFwic2V0dGluZy1pdGVtLWRlc2NyaXB0aW9uXCIpO1xyXG5cdFx0bGV0IHZhbnRhZ2VTZXR0aW5nc1JlZ2V4TGluayA9IGNvbnRlbnRFbC5jcmVhdGVFbChcImFcIiwge1widGV4dFwiOiBcImh0dHBzOi8vcmVnZXhyLmNvbS9cIn0pO1xyXG5cdFx0dmFudGFnZVNldHRpbmdzUmVnZXhMaW5rLnNldEF0dHIoXCJocmVmXCIsIFwiaHR0cHM6Ly9yZWdleHIuY29tL1wiKTtcclxuXHRcdHZhbnRhZ2VTZXR0aW5nc1JlZ2V4TGluay5hZGRDbGFzcyhcInNldHRpbmctaXRlbS1kZXNjcmlwdGlvblwiKTtcclxuXHRcdHZhbnRhZ2VTZXR0aW5nc0Rlc2NyaXB0aW9uU3ViZGl2LmFwcGVuZCh2YW50YWdlU2V0dGluZ3NEZXNjcmlwdGlvbik7XHJcblx0XHR2YW50YWdlU2V0dGluZ3NEZXNjcmlwdGlvblN1YmRpdi5hcHBlbmQodmFudGFnZVNldHRpbmdzRGVzY3JpcHRpb25MaW5rKTtcclxuXHRcdHZhbnRhZ2VTZXR0aW5nc0Rlc2NyaXB0aW9uU3ViZGl2LmFwcGVuZCh2YW50YWdlU2V0dGluZ3NMaW5lYnJlYWtEaXYpO1xyXG5cdFx0dmFudGFnZVNldHRpbmdzRGVzY3JpcHRpb25TdWJkaXYuYXBwZW5kKHZhbnRhZ2VTZXR0aW5nc1JlZ2V4RGVzY3JpcHRpb24pO1xyXG5cdFx0dmFudGFnZVNldHRpbmdzRGVzY3JpcHRpb25TdWJkaXYuYXBwZW5kKHZhbnRhZ2VTZXR0aW5nc1JlZ2V4TGluayk7XHJcblx0XHR2YW50YWdlU2V0dGluZ3NEZXNjcmlwdGlvbkRpdi5hcHBlbmQodmFudGFnZVNldHRpbmdzRGVzY3JpcHRpb25TdWJkaXYpO1xyXG5cdFx0dmFudGFnZVNldHRpbmdzRGl2LmFwcGVuZCh2YW50YWdlU2V0dGluZ3NEZXNjcmlwdGlvbkRpdik7XHJcblxyXG5cdFx0Ly8gTm90ZSBhdHRyaWJ1dGVzXHJcblx0XHRsZXQgbm90ZUF0dHJpYnV0ZXNIZWFkaW5nRGl2ID0gY29udGVudEVsLmNyZWF0ZUVsKFwiaDJcIiwgeyBcInRleHRcIjogXCJTZWFyY2ggbm90ZSBhdHRyaWJ1dGVzXCJ9KTtcclxuXHRcdG5vdGVBdHRyaWJ1dGVzSGVhZGluZ0Rpdi5hZGRDbGFzcyhcInNldHRpbmctaXRlbVwiKTtcclxuXHRcdG5vdGVBdHRyaWJ1dGVzSGVhZGluZ0Rpdi5hZGRDbGFzcyhcInNldHRpbmctaXRlbS1oZWFkaW5nXCIpO1xyXG5cdFx0dmFudGFnZVNldHRpbmdzRGl2LmFwcGVuZChub3RlQXR0cmlidXRlc0hlYWRpbmdEaXYpO1xyXG5cclxuXHRcdC8vIE5vdGUgVGl0bGVzXHJcblx0XHRsZXQgbm90ZVRpdGxlQ29udGFpbnNEaXYgPSBjb250ZW50RWwuY3JlYXRlRWwoXCJkaXZcIik7XHJcblx0XHRub3RlVGl0bGVDb250YWluc0Rpdi5hZGRDbGFzcyhcInNldHRpbmctaXRlbVwiKTtcclxuXHRcdGxldCBub3RlVGl0bGVJbmZvRGl2ID0gY29udGVudEVsLmNyZWF0ZUVsKFwiZGl2XCIpO1xyXG5cdFx0bm90ZVRpdGxlSW5mb0Rpdi5hZGRDbGFzcyhcInNldHRpbmctaXRlbS1pbmZvXCIpO1xyXG5cdFx0bGV0IG5vdGVUaXRsZUNvbnRyb2xEaXYgPSBjb250ZW50RWwuY3JlYXRlRWwoXCJkaXZcIik7XHJcblx0XHRub3RlVGl0bGVDb250cm9sRGl2LmFkZENsYXNzKFwic2V0dGluZy1pdGVtLWNvbnRyb2xcIik7XHJcblx0XHRsZXQgbm90ZVRpdGxlQ29udGFpbnNUZXh0ID0gY29udGVudEVsLmNyZWF0ZUVsKFwic3BhblwiLCB7IFwidGV4dFwiOiBcIk5vdGUgdGl0bGUgY29udGFpbnM6IFwiIH0pO1xyXG5cdFx0bm90ZVRpdGxlQ29udGFpbnNUZXh0LmFkZENsYXNzKFwic2V0dGluZy1pdGVtLW5hbWVcIik7XHJcblx0XHRsZXQgbm90ZVRpdGxlQ29udGFpbnNJbnB1dCA9IGNvbnRlbnRFbC5jcmVhdGVFbChcImlucHV0XCIsIHtcInR5cGVcIjogXCJ0ZXh0XCJ9KTtcclxuXHRcdG5vdGVUaXRsZUNvbnRhaW5zSW5wdXQuaWQgPSBcIm5vdGUtdGl0bGUtaW5wdXRcIjtcclxuXHRcdC8vbm90ZVRpdGxlQ29udGFpbnNJbnB1dC5zZXRBdHRyKFwic3R5bGVcIiwgXCJmbG9hdDogcmlnaHQ7IHdpZHRoOiA1MCVcIik7XHJcblx0XHRub3RlVGl0bGVJbmZvRGl2LmFwcGVuZChub3RlVGl0bGVDb250YWluc1RleHQpO1xyXG5cdFx0bm90ZVRpdGxlQ29udHJvbERpdi5hcHBlbmQobm90ZVRpdGxlQ29udGFpbnNJbnB1dCk7XHJcblx0XHRub3RlVGl0bGVDb250YWluc0Rpdi5hcHBlbmQobm90ZVRpdGxlSW5mb0Rpdik7XHJcblx0XHRub3RlVGl0bGVDb250YWluc0Rpdi5hcHBlbmQobm90ZVRpdGxlQ29udHJvbERpdik7XHJcblx0XHR2YW50YWdlU2V0dGluZ3NEaXYuYXBwZW5kKG5vdGVUaXRsZUNvbnRhaW5zRGl2KTtcclxuXHJcblx0XHQvLyBEYXRlIHJhbmdlOlxyXG5cdFx0bGV0IGRhdGVSYW5nZURpdiA9IGNvbnRlbnRFbC5jcmVhdGVFbChcImRpdlwiKTtcclxuXHRcdGRhdGVSYW5nZURpdi5hZGRDbGFzcyhcInNldHRpbmctaXRlbVwiKVxyXG5cdFx0bGV0IGRhdGVSYW5nZUhlYWRlckRpdiA9IGNvbnRlbnRFbC5jcmVhdGVFbChcImRpdlwiKTtcclxuXHRcdGRhdGVSYW5nZUhlYWRlckRpdi5hZGRDbGFzcyhcInNldHRpbmctaXRlbS1pbmZvXCIpO1xyXG5cdFx0bGV0IGRhdGVSYW5nZUhlYWRlciA9IGNvbnRlbnRFbC5jcmVhdGVFbChcImRpdlwiLCB7IFwidGV4dFwiOiBcIkRhdGUgcmFuZ2U6IFwiIH0pO1xyXG5cdFx0ZGF0ZVJhbmdlSGVhZGVyLmFkZENsYXNzKFwic2V0dGluZy1pdGVtLW5hbWVcIik7XHJcblx0XHRsZXQgZGF0ZVJhbmdlU3VidGl0bGUgPSBjb250ZW50RWwuY3JlYXRlRWwoXCJzcGFuXCIsIHsgXCJ0ZXh0XCI6IFwiKEVudGVyaW5nIGRhdGEgaGVyZSB3aWxsIG1ha2UgdGhlIHNlYXJjaCBpbmNsdWRlIG9ubHkgZGFpbHkgbm90ZXMgKGFuZCBtYXkgY29uZmxpY3Qgd2l0aCB0aGUgYWJvdmUpLiBVc2UgbmF0dXJhbCBsYW5ndWFnZS4pXCJ9KTtcclxuXHRcdGRhdGVSYW5nZVN1YnRpdGxlLnNldEF0dHIoXCJjbGFzc1wiLCBcInNldHRpbmctaXRlbS1kZXNjcmlwdGlvblwiKTtcclxuXHRcdGRhdGVSYW5nZUhlYWRlckRpdi5hcHBlbmQoZGF0ZVJhbmdlSGVhZGVyKTtcclxuXHRcdGRhdGVSYW5nZUhlYWRlckRpdi5hcHBlbmQoZGF0ZVJhbmdlU3VidGl0bGUpO1xyXG5cclxuXHRcdGxldCBzdGFydERhdGVEaXYgPSBjb250ZW50RWwuY3JlYXRlRWwoXCJkaXZcIik7XHJcblx0XHRsZXQgc3RhcnREYXRlSW5mb0RpdiA9IGNvbnRlbnRFbC5jcmVhdGVFbChcImRpdlwiKTtcclxuXHRcdHN0YXJ0RGF0ZUluZm9EaXYuYWRkQ2xhc3MoXCJzZXR0aW5nLWl0ZW0taW5mb1wiKTtcclxuXHRcdGxldCBzdGFydERhdGVUZXh0ID0gY29udGVudEVsLmNyZWF0ZUVsKFwiZGl2XCIsIHtcInRleHRcIjogXCJTdGFydCBkYXRlOiBcIn0pO1xyXG5cdFx0c3RhcnREYXRlVGV4dC5hZGRDbGFzcyhcInNldHRpbmctaXRlbS1uYW1lXCIpO1xyXG5cdFx0c3RhcnREYXRlSW5mb0Rpdi5hcHBlbmQoc3RhcnREYXRlVGV4dCk7XHJcblx0XHRsZXQgc3RhcnREYXRlQ29udHJvbERpdiA9IGNvbnRlbnRFbC5jcmVhdGVFbChcImRpdlwiKTtcclxuXHRcdHN0YXJ0RGF0ZUNvbnRyb2xEaXYuYWRkQ2xhc3MoXCJzZXR0aW5nLWl0ZW0tY29udHJvbFwiKTtcclxuXHRcdGxldCBmaWxlU3RhcnREYXRlSW5wdXQgPSBjb250ZW50RWwuY3JlYXRlRWwoXCJpbnB1dFwiLCB7XCJ0eXBlXCI6IFwidGV4dFwifSk7XHJcblx0XHRzdGFydERhdGVDb250cm9sRGl2LmFwcGVuZChmaWxlU3RhcnREYXRlSW5wdXQpO1xyXG5cdFx0c3RhcnREYXRlRGl2LmFwcGVuZChzdGFydERhdGVJbmZvRGl2KTtcclxuXHRcdHN0YXJ0RGF0ZURpdi5hcHBlbmQoc3RhcnREYXRlQ29udHJvbERpdik7XHJcblxyXG5cdFx0bGV0IGVuZERhdGVEaXYgPSBjb250ZW50RWwuY3JlYXRlRWwoXCJkaXZcIik7XHJcblx0XHRsZXQgZW5kRGF0ZUluZm9EaXYgPSBjb250ZW50RWwuY3JlYXRlRWwoXCJkaXZcIik7XHJcblx0XHRlbmREYXRlSW5mb0Rpdi5hZGRDbGFzcyhcInNldHRpbmctaXRlbS1pbmZvXCIpO1xyXG5cdFx0bGV0IGVuZERhdGVUZXh0ID0gY29udGVudEVsLmNyZWF0ZUVsKFwiZGl2XCIsIHtcInRleHRcIjogXCJFbmQgZGF0ZTogXCJ9KTtcclxuXHRcdGVuZERhdGVUZXh0LmFkZENsYXNzKFwic2V0dGluZy1pdGVtLW5hbWVcIik7XHJcblx0XHRlbmREYXRlSW5mb0Rpdi5hcHBlbmQoZW5kRGF0ZVRleHQpO1xyXG5cdFx0bGV0IGVuZERhdGVDb250cm9sRGl2ID0gY29udGVudEVsLmNyZWF0ZUVsKFwiZGl2XCIpO1xyXG5cdFx0ZW5kRGF0ZUNvbnRyb2xEaXYuYWRkQ2xhc3MoXCJzZXR0aW5nLWl0ZW0tY29udHJvbFwiKTtcclxuXHRcdGxldCBmaWxlRW5kRGF0ZUlucHV0ID0gY29udGVudEVsLmNyZWF0ZUVsKFwiaW5wdXRcIiwge1widHlwZVwiOiBcInRleHRcIn0pO1xyXG5cdFx0ZW5kRGF0ZUNvbnRyb2xEaXYuYXBwZW5kKGZpbGVFbmREYXRlSW5wdXQpO1xyXG5cdFx0ZW5kRGF0ZURpdi5hcHBlbmQoZW5kRGF0ZUluZm9EaXYpO1xyXG5cdFx0ZW5kRGF0ZURpdi5hcHBlbmQoZW5kRGF0ZUNvbnRyb2xEaXYpO1xyXG5cclxuXHRcdGRhdGVSYW5nZURpdi5hcHBlbmQoZGF0ZVJhbmdlSGVhZGVyRGl2KTtcclxuXHRcdGRhdGVSYW5nZURpdi5hcHBlbmQoc3RhcnREYXRlRGl2KTtcclxuXHRcdGRhdGVSYW5nZURpdi5hcHBlbmQoZW5kRGF0ZURpdik7XHJcblx0XHR2YW50YWdlU2V0dGluZ3NEaXYuYXBwZW5kKGRhdGVSYW5nZURpdik7XHJcblx0XHRcclxuXHRcdC8vIFRhZ2dlZCB3aXRoXHJcblx0XHRsZXQgdGFnRGl2ID0gY29udGVudEVsLmNyZWF0ZUVsKFwiZGl2XCIpO1xyXG5cdFx0dGFnRGl2LmFkZENsYXNzKFwic2V0dGluZy1pdGVtXCIpO1xyXG5cdFx0bGV0IHRhZ0luZm9EaXYgPSBjb250ZW50RWwuY3JlYXRlRWwoXCJkaXZcIik7XHJcblx0XHRsZXQgdGFnQ29udHJvbERpdiA9IGNvbnRlbnRFbC5jcmVhdGVFbChcImRpdlwiKTtcclxuXHRcdHRhZ0luZm9EaXYuYWRkQ2xhc3MoXCJzZXR0aW5nLWl0ZW0taW5mb1wiKTtcclxuXHRcdHRhZ0NvbnRyb2xEaXYuYWRkQ2xhc3MoXCJzZXR0aW5nLWl0ZW0tY29udHJvbFwiKTtcclxuXHRcdGxldCBub3RlVGFnVGV4dCA9IGNvbnRlbnRFbC5jcmVhdGVFbChcImRpdlwiLCB7IFwidGV4dFwiOiBcIlRhZ2dlZCB3aXRoOiBcIiB9KTtcclxuXHRcdG5vdGVUYWdUZXh0LmFkZENsYXNzKFwic2V0dGluZy1pdGVtLW5hbWVcIik7XHJcblx0XHR0YWdJbmZvRGl2LmFwcGVuZChub3RlVGFnVGV4dCk7XHJcblx0XHRsZXQgdGFnSW5wdXQgPSBjb250ZW50RWwuY3JlYXRlRWwoXCJpbnB1dFwiLCB7XCJ0eXBlXCI6IFwidGV4dFwifSk7XHJcblx0XHR0YWdDb250cm9sRGl2LmFwcGVuZCh0YWdJbnB1dCk7XHJcblx0XHR0YWdEaXYuYXBwZW5kKHRhZ0luZm9EaXYpO1xyXG5cdFx0dGFnRGl2LmFwcGVuZCh0YWdDb250cm9sRGl2KTtcclxuXHRcdHZhbnRhZ2VTZXR0aW5nc0Rpdi5hcHBlbmQodGFnRGl2KTtcclxuXHJcblxyXG5cdFx0Ly8gTm90ZXMgd2l0aCBQYXRoXHJcblx0XHRsZXQgbm90ZXNQYXRoRGl2ID0gY29udGVudEVsLmNyZWF0ZUVsKFwiZGl2XCIpO1xyXG5cdFx0bm90ZXNQYXRoRGl2LmFkZENsYXNzKFwic2V0dGluZy1pdGVtXCIpO1xyXG5cdFx0bGV0IG5vdGVzUGF0aEluZm9EaXYgPSBjb250ZW50RWwuY3JlYXRlRWwoXCJkaXZcIik7XHJcblx0XHRsZXQgbm90ZXNQYXRoQ29udHJvbERpdiA9IGNvbnRlbnRFbC5jcmVhdGVFbChcImRpdlwiKTtcclxuXHRcdG5vdGVzUGF0aEluZm9EaXYuYWRkQ2xhc3MoXCJzZXR0aW5nLWl0ZW0taW5mb1wiKTtcclxuXHRcdG5vdGVzUGF0aENvbnRyb2xEaXYuYWRkQ2xhc3MoXCJzZXR0aW5nLWl0ZW0tY29udHJvbFwiKTtcclxuXHRcdGxldCBub3Rlc1BhdGhUZXh0ID0gY29udGVudEVsLmNyZWF0ZUVsKFwiZGl2XCIsIHsgXCJ0ZXh0XCI6IFwiTm90ZXMgaW4gZm9sZGVyIG9yIHBhdGg6IFwiIH0pO1xyXG5cdFx0bm90ZXNQYXRoVGV4dC5hZGRDbGFzcyhcInNldHRpbmctaXRlbS1uYW1lXCIpO1xyXG5cdFx0bGV0IG5vdGVQYXRoRGVzY3JpcHRpb24gPSBjb250ZW50RWwuY3JlYXRlRWwoXCJzcGFuXCIsIHsgXCJ0ZXh0XCI6IFwiRm9yIGV4YW1wbGUsIGluY2x1ZGUgdGhlIGZvbGRlciB0byB5b3VyIERhaWx5IE5vdGVzIHRvIHNlYXJjaCBhbGwgZGFpbHkgbm90ZXMuXCJ9KTtcclxuXHRcdG5vdGVQYXRoRGVzY3JpcHRpb24uc2V0QXR0cihcImNsYXNzXCIsIFwic2V0dGluZy1pdGVtLWRlc2NyaXB0aW9uXCIpO1xyXG5cdFx0bm90ZXNQYXRoSW5mb0Rpdi5hcHBlbmQobm90ZXNQYXRoVGV4dCk7XHJcblx0XHRub3Rlc1BhdGhJbmZvRGl2LmFwcGVuZChub3RlUGF0aERlc2NyaXB0aW9uKTtcclxuXHRcdGxldCBub3Rlc1BhdGhJbnB1dCA9IGNvbnRlbnRFbC5jcmVhdGVFbChcImlucHV0XCIsIHtcInR5cGVcIjogXCJ0ZXh0XCJ9KTtcclxuXHRcdG5vdGVzUGF0aENvbnRyb2xEaXYuYXBwZW5kKG5vdGVzUGF0aElucHV0KTtcclxuXHRcdG5vdGVzUGF0aERpdi5hcHBlbmQobm90ZXNQYXRoSW5mb0Rpdik7XHJcblx0XHRub3Rlc1BhdGhEaXYuYXBwZW5kKG5vdGVzUGF0aENvbnRyb2xEaXYpO1xyXG5cdFx0dmFudGFnZVNldHRpbmdzRGl2LmFwcGVuZChub3Rlc1BhdGhEaXYpO1xyXG5cclxuXHRcdC8vIE5vdGUgY29udGVudHNcclxuXHRcdGxldCBub3RlQ29udGVudHNIZWFkaW5nRGl2ID0gY29udGVudEVsLmNyZWF0ZUVsKFwiaDJcIiwgeyBcInRleHRcIjogXCJTZWFyY2ggbm90ZSBjb250ZW50c1wifSk7XHJcblx0XHRub3RlQ29udGVudHNIZWFkaW5nRGl2LmFkZENsYXNzKFwic2V0dGluZy1pdGVtXCIpO1xyXG5cdFx0bm90ZUNvbnRlbnRzSGVhZGluZ0Rpdi5hZGRDbGFzcyhcInNldHRpbmctaXRlbS1oZWFkaW5nXCIpO1xyXG5cdFx0dmFudGFnZVNldHRpbmdzRGl2LmFwcGVuZChub3RlQ29udGVudHNIZWFkaW5nRGl2KTtcclxuXHJcblxyXG5cdFx0Y29udGVudEVsLmFwcGVuZCh2YW50YWdlU2V0dGluZ3NEaXYpO1xyXG5cclxuXHRcdGxldCBmb2N1c0lucHV0Qm94ID0gY29udGVudEVsLnF1ZXJ5U2VsZWN0b3IoXCIjbm90ZS10aXRsZS1pbnB1dFwiKTtcclxuXHRcdGZvY3VzSW5wdXRCb3guZm9jdXMoKTtcclxuXHJcblx0XHRsZXQgcXVlcnlEaXZzID0gY29udGVudEVsLnF1ZXJ5U2VsZWN0b3JBbGwoXCJkaXZcIik7XHJcblx0XHRxdWVyeURpdnMuZm9yRWFjaCgoZGl2KSA9PiB7XHJcblx0XHRcdGxldCBpbnB1dEJveGVzID0gZGl2LnF1ZXJ5U2VsZWN0b3JBbGwoXCJpbnB1dFwiKTtcclxuXHRcdFx0aW5wdXRCb3hlcy5mb3JFYWNoKChpbnB1dEJveCkgPT4ge1xyXG5cdFx0XHRcdGlucHV0Qm94LmFkZEV2ZW50TGlzdGVuZXIoJ2tleXByZXNzJywgZnVuY3Rpb24gKGtleXByZXNzZWQpIHtcclxuXHRcdFx0XHRcdGlmIChrZXlwcmVzc2VkLmtleSA9PT0gJ0VudGVyJykge1xyXG5cdFx0XHRcdFx0XHRpbml0aWF0ZVNlYXJjaCgpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH0pO1xyXG5cdFx0XHR9KTtcclxuXHRcdH0pO1xyXG5cclxuXHRcdGZ1bmN0aW9uIGluaXRpYXRlU2VhcmNoKCkge1xyXG5cdFx0XHRsZXQgc2VhcmNoUXVlcnkgPSBzZXRTZWFyY2hRdWVyeSgpO1xyXG5cdFx0XHRzZWFyY2hNb2RhbC5jbG9zZSgpO1xyXG5cdFx0XHR2YW50YWdlUGx1Z2luLmdldFNlYXJjaChzZWFyY2hRdWVyeSk7XHJcblx0XHR9XHJcblxyXG5cclxuXHRcdGZ1bmN0aW9uIHByb2Nlc3NEYXRlUmFuZ2Uoc3RhcnREYXRlOiBzdHJpbmcsIGVuZERhdGU6IHN0cmluZykgeyBcclxuXHRcdFx0Y29uc29sZS5sb2coXCJTdGFydCBkYXRlOlwiKTtcclxuXHRcdFx0bGV0IHBhcnNlZEZpbGVTdGFydERhdGUgPSBuYXR1cmFsTGFuZ3VhZ2VEYXRlcy5wYXJzZURhdGUoc3RhcnREYXRlKTtcclxuXHJcblx0XHRcdGNvbnNvbGUubG9nKFwiRW5kIGRhdGU6XCIpO1xyXG5cdFx0XHRsZXQgcGFyc2VkRmlsZUVuZERhdGUgPSBuYXR1cmFsTGFuZ3VhZ2VEYXRlcy5wYXJzZURhdGUoZW5kRGF0ZSk7XHJcblxyXG5cdFx0XHRsZXQgY3VycmVudERhdGUgPSBuYXR1cmFsTGFuZ3VhZ2VEYXRlcy5nZXRGb3JtYXR0ZWREYXRlKHBhcnNlZEZpbGVTdGFydERhdGUubW9tZW50KTtcclxuXHRcdFx0bGV0IGRhdGVEaXJlY3Rpb24gPSBcImZvcndhcmRcIjtcclxuXHRcdFx0bGV0IGFsbERhdGVzID0gbmF0dXJhbExhbmd1YWdlRGF0ZXMuZ2V0Rm9ybWF0dGVkRGF0ZShwYXJzZWRGaWxlU3RhcnREYXRlLm1vbWVudCk7XHJcblxyXG5cdFx0XHRpZiAocGFyc2VkRmlsZUVuZERhdGUubW9tZW50LmlzQWZ0ZXIocGFyc2VkRmlsZVN0YXJ0RGF0ZS5tb21lbnQpKSB7XHJcblx0XHRcdFx0Y29uc29sZS5sb2coXCJEYXRlcyBnbyBmb3J3YXJkIGluIHRpbWUuXCIpO1xyXG5cdFx0XHRcdGRhdGVEaXJlY3Rpb24gPSBcImZvcndhcmRcIjtcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRkYXRlRGlyZWN0aW9uID0gXCJiYWNrd2FyZFwiO1xyXG5cdFx0XHRcdGNvbnNvbGUubG9nKFwiRGF0ZXMgZ28gYmFja3dhcmRzIGluIHRpbWUuXCIpO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHR3aGlsZSAoIShjdXJyZW50RGF0ZSA9PT0gbmF0dXJhbExhbmd1YWdlRGF0ZXMuZ2V0Rm9ybWF0dGVkRGF0ZShwYXJzZWRGaWxlRW5kRGF0ZS5tb21lbnQpKSkge1xyXG5cdFx0XHRcdGxldCBjdXJyZW50RGF0ZU1vbWVudCA9IHBhcnNlZEZpbGVTdGFydERhdGUubW9tZW50O1xyXG5cdFx0XHRcdGlmIChkYXRlRGlyZWN0aW9uID09PSBcImZvcndhcmRcIikge1xyXG5cdFx0XHRcdFx0Y3VycmVudERhdGVNb21lbnQgPSBjdXJyZW50RGF0ZU1vbWVudC5hZGQoMSwgXCJkYXlzXCIpO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRjdXJyZW50RGF0ZU1vbWVudCA9IGN1cnJlbnREYXRlTW9tZW50LnN1YnRyYWN0KDEsIFwiZGF5c1wiKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0bGV0IG5leHREYXRlID0gbmF0dXJhbExhbmd1YWdlRGF0ZXMuZ2V0Rm9ybWF0dGVkRGF0ZShjdXJyZW50RGF0ZU1vbWVudCk7XHJcblx0XHRcdFx0YWxsRGF0ZXMgPSBhbGxEYXRlcyArIFwiIE9SIFwiICsgbmV4dERhdGU7XHJcblx0XHRcdFx0Y3VycmVudERhdGUgPSBuZXh0RGF0ZTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0cmV0dXJuIGFsbERhdGVzO1xyXG5cdFx0fVxyXG5cclxuXHRcdGZ1bmN0aW9uIHByb2Nlc3NUYWdzKGlucHV0VGFnczogc3RyaW5nKSB7XHJcblx0XHRcdC8vc3BsaXQgYnkgc3BhY2VzLCB0aGVuIHJldHVybiBlYWNoIHdpdGggdGFnOiBhcHBlbmRlZFxyXG5cdFx0XHQvL2lmIG5vICMsIGFkZCB0aGUgIyB0b29cclxuXHRcdFx0bGV0IGFsbFRhZ3MgPSBpbnB1dFRhZ3Muc3BsaXQoXCIgXCIpO1xyXG5cdFx0XHRsZXQgcHJvY2Vzc2VkVGFncyA9IFwiXCJcclxuXHRcdFx0Zm9yICh2YXIgZWFjaFRhZyBvZiBhbGxUYWdzKSB7XHJcblx0XHRcdFx0aWYgKGVhY2hUYWcuaW5jbHVkZXMoXCIjXCIpKSB7XHJcblx0XHRcdFx0XHRwcm9jZXNzZWRUYWdzID0gcHJvY2Vzc2VkVGFncyArIFwidGFnOlwiICsgZWFjaFRhZyArIFwiIFwiO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRwcm9jZXNzZWRUYWdzID0gcHJvY2Vzc2VkVGFncyArIFwidGFnOiNcIiArIGVhY2hUYWcgKyBcIiBcIjtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0cHJvY2Vzc2VkVGFncyA9IHByb2Nlc3NlZFRhZ3MudHJpbSgpO1xyXG5cdFx0XHRyZXR1cm4gcHJvY2Vzc2VkVGFncztcclxuXHRcdH1cclxuXHJcblx0XHRmdW5jdGlvbiBzZXRTZWFyY2hRdWVyeSgpIHtcclxuXHRcdFx0bGV0IHNlYXJjaFF1ZXJ5ID0gXCJcIjtcclxuXHRcdFx0aWYgKG5vdGVUaXRsZUNvbnRhaW5zSW5wdXQudmFsdWUgIT0gXCJcIikge1xyXG5cdFx0XHRcdGlmICgoZmlsZVN0YXJ0RGF0ZUlucHV0LnZhbHVlICE9IFwiXCIpICYmIChmaWxlRW5kRGF0ZUlucHV0LnZhbHVlICE9IFwiXCIpKSB7XHJcblx0XHRcdFx0XHRzZWFyY2hRdWVyeSA9IHNlYXJjaFF1ZXJ5ICsgXCJmaWxlOihcIiArIG5vdGVUaXRsZUNvbnRhaW5zSW5wdXQudmFsdWUgKyBwcm9jZXNzRGF0ZVJhbmdlKGZpbGVTdGFydERhdGVJbnB1dC52YWx1ZSwgZmlsZUVuZERhdGVJbnB1dC52YWx1ZSkgKyBcIikgXCI7XHJcblx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdHNlYXJjaFF1ZXJ5ID0gc2VhcmNoUXVlcnkgKyBcImZpbGU6KFwiICsgbm90ZVRpdGxlQ29udGFpbnNJbnB1dC52YWx1ZSArIFwiKSBcIjtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0gZWxzZSBpZiAoKGZpbGVTdGFydERhdGVJbnB1dC52YWx1ZSAhPSBcIlwiKSAmJiAoZmlsZUVuZERhdGVJbnB1dC52YWx1ZSAhPSBcIlwiKSkge1xyXG5cdFx0XHRcdHNlYXJjaFF1ZXJ5ID0gc2VhcmNoUXVlcnkgKyBcImZpbGU6KFwiICsgcHJvY2Vzc0RhdGVSYW5nZShmaWxlU3RhcnREYXRlSW5wdXQudmFsdWUsIGZpbGVFbmREYXRlSW5wdXQudmFsdWUpICsgXCIpIFwiO1xyXG5cdFx0XHR9XHJcblx0XHRcdGlmICh0YWdJbnB1dC52YWx1ZSAhPSBcIlwiKSB7XHJcblx0XHRcdFx0c2VhcmNoUXVlcnkgPSBzZWFyY2hRdWVyeSArIFwiKFwiICsgcHJvY2Vzc1RhZ3ModGFnSW5wdXQudmFsdWUpICsgXCIpIFwiO1xyXG5cdFx0XHR9XHJcblx0XHRcdGlmIChub3Rlc1BhdGhJbnB1dC52YWx1ZSAhPSBcIlwiKSB7XHJcblx0XHRcdFx0c2VhcmNoUXVlcnkgPSBzZWFyY2hRdWVyeSArIFwicGF0aDooXCIgKyBub3Rlc1BhdGhJbnB1dC52YWx1ZSArIFwiKSBcIjtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0bGV0IG5ld1F1ZXJpZXMgPSBjb250ZW50RWwucXVlcnlTZWxlY3RvckFsbChcImRpdlwiKTtcclxuXHRcdFx0bmV3UXVlcmllcy5mb3JFYWNoKChkaXYpID0+IHtcclxuXHRcdFx0XHRpZiAoKGRpdi5pZC5jb250YWlucyhcIkFORFwiKSkgfHwgKGRpdi5pZC5jb250YWlucyhcIk9SXCIpKSB8fCAoZGl2LmlkLmNvbnRhaW5zKFwiTk9UXCIpKSkge1xyXG5cdFx0XHRcdFx0bGV0IGNvbnRlbnRRdWVyeSA9IGRpdi5xdWVyeVNlbGVjdG9yQWxsKFwiaW5wdXRcIik7XHJcblx0XHRcdFx0XHRsZXQgc3VicXVlcnkgPSBjb250ZW50UXVlcnkuaXRlbSgwKS52YWx1ZTtcclxuXHRcdFx0XHRcdGxldCBzZWxlY3RCb3hlcyA9IGRpdi5xdWVyeVNlbGVjdG9yQWxsKFwic2VsZWN0XCIpO1xyXG5cdFx0XHRcdFx0c2VsZWN0Qm94ZXMuZm9yRWFjaCgoc2VsZWN0KSA9PiB7XHJcblx0XHRcdFx0XHRcdGlmIChzZWxlY3QuaWQuY29udGFpbnMoXCJTdWJ0eXBlXCIpKSB7XHJcblx0XHRcdFx0XHRcdFx0aWYgKHNlbGVjdC52YWx1ZSA9PSBcIlwiKSB7XHJcblx0XHRcdFx0XHRcdFx0XHQvLyBkbyBub3RoaW5nXHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdGlmIChzZWxlY3QudmFsdWUuY29udGFpbnMoXCJsaW5rXCIpKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRzdWJxdWVyeSA9IFwiXFxcXFtcXFxcWy4qXCIgKyBzdWJxdWVyeSArIFwiLipcXFxcXVxcXFxdXCI7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdGlmIChzZWxlY3QudmFsdWUuY29udGFpbnMoXCJlbWFpbFwiKSkge1xyXG5cdFx0XHRcdFx0XHRcdFx0c3VicXVlcnkgPSBcIihbYS16QS1aMC05X1xcXFwtXFxcXC5dKylAKFthLXpBLVowLTlfXFxcXC1cXFxcLl0rKVxcLihbYS16QS1aXXsyLDV9KVwiO1xyXG5cdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0XHRpZiAoc2VsZWN0LnZhbHVlLmNvbnRhaW5zKFwicGhvbmVcIikpIHtcclxuXHRcdFx0XHRcdFx0XHRcdHN1YnF1ZXJ5ID0gXCJbK10qWyhdezAsMX1bMC05XXsxLDR9WyldezAsMX1bLVxcXFxzXFxcXC4vMC05XSpcIjtcclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0c2VsZWN0Qm94ZXMuZm9yRWFjaCgoc2VsZWN0KSA9PiB7XHJcblx0XHRcdFx0XHRcdGlmIChzZWxlY3QuaWQuY29udGFpbnMoXCJMaXN0XCIpKSB7XHJcblx0XHRcdFx0XHRcdFx0aWYgKHNlbGVjdC52YWx1ZS5jb250YWlucyhcImFueVwiKSkge1xyXG5cdFx0XHRcdFx0XHRcdFx0aWYgKChzdWJxdWVyeS5jb250YWlucyhcIlthLXpBLVowLTlfXCIpKSB8fCBzdWJxdWVyeS5jb250YWlucyhcIn1bMC05XVwiKSkge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRzdWJxdWVyeSA9IFwiKC9cIiArIHN1YnF1ZXJ5ICsgXCIvKVwiO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0XHRpZiAoc2VsZWN0LnZhbHVlLmNvbnRhaW5zKFwibGlzdCBpdGVtXCIpKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRzdWJxdWVyeSA9IFwiKC8tIFteXFxbLlxcXV0uKlwiICsgc3VicXVlcnkgKyBcIi4qLylcIjtcclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0aWYgKHNlbGVjdC52YWx1ZS5jb250YWlucyhcImluY29tcGxldGVcIikpIHtcclxuXHRcdFx0XHRcdFx0XHRcdHN1YnF1ZXJ5ID0gXCIoLy0gXFxcXFsgXFxcXF0uKlwiICsgc3VicXVlcnkgKyBcIi4qLylcIjtcclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0aWYgKHNlbGVjdC52YWx1ZS5jb250YWlucyhcImNvbXBsZXRlZFwiKSkge1xyXG5cdFx0XHRcdFx0XHRcdFx0c3VicXVlcnkgPSBcIigvLSBcXFxcW3hcXFxcXS4qXCIgKyBzdWJxdWVyeSArIFwiLiovKVwiO1xyXG5cdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0XHRpZiAoc2VsZWN0LnZhbHVlLmNvbnRhaW5zKFwiYWxsXCIpKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRzdWJxdWVyeSA9IFwiKC8tIFxcXFxbLlxcXFxdLipcIiArIHN1YnF1ZXJ5ICsgXCIuKi8pXCI7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdHNlbGVjdEJveGVzLmZvckVhY2goKHNlbGVjdCkgPT4ge1xyXG5cdFx0XHRcdFx0XHRpZiAoc2VsZWN0LmlkLmNvbnRhaW5zKFwiVHlwZVwiKSkge1xyXG5cdFx0XHRcdFx0XHRcdGlmIChzZWxlY3QudmFsdWUuY29udGFpbnMoXCJub3RlXCIpKSB7XHJcblx0XHRcdFx0XHRcdFx0XHQvLyBkbyBub3RoaW5nXHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdGlmIChzZWxlY3QudmFsdWUuY29udGFpbnMoXCJzZWN0aW9uXCIpKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRzdWJxdWVyeSA9IFwic2VjdGlvbjpcIiArIHN1YnF1ZXJ5O1xyXG5cdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0XHRpZiAoc2VsZWN0LnZhbHVlLmNvbnRhaW5zKFwiYmxvY2tcIikpIHtcclxuXHRcdFx0XHRcdFx0XHRcdHN1YnF1ZXJ5ID0gXCJibG9jazpcIiArIHN1YnF1ZXJ5O1xyXG5cdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0XHRpZiAoc2VsZWN0LnZhbHVlLmNvbnRhaW5zKFwibGluZVwiKSkge1xyXG5cdFx0XHRcdFx0XHRcdFx0c3VicXVlcnkgPSBcImxpbmU6XCIgKyBzdWJxdWVyeTtcclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdFx0aWYgKGRpdi5pZC5jb250YWlucyhcIkFORFwiKSkge1xyXG5cdFx0XHRcdFx0XHRjb25zb2xlLmxvZyhcIlRoaXMgaXMgYW4gQU5EIHF1ZXJ5XCIpO1xyXG5cdFx0XHRcdFx0XHRzZWFyY2hRdWVyeSA9IHNlYXJjaFF1ZXJ5ICsgXCIgKFwiICsgc3VicXVlcnkgKyBcIilcIjtcclxuXHRcdFx0XHRcdH0gZWxzZSBpZiAoZGl2LmlkLmNvbnRhaW5zKFwiT1JcIikpIHtcclxuXHRcdFx0XHRcdFx0Y29uc29sZS5sb2coXCJUaGlzIGlzIGFuIE9SIHF1ZXJ5XCIpO1xyXG5cdFx0XHRcdFx0XHRzZWFyY2hRdWVyeSA9IHNlYXJjaFF1ZXJ5ICsgXCIgT1IgKFwiICsgc3VicXVlcnkgKyBcIilcIjtcclxuXHRcdFx0XHRcdH0gZWxzZSBpZiAoZGl2LmlkLmNvbnRhaW5zKFwiTk9UXCIpKSB7XHJcblx0XHRcdFx0XHRcdGNvbnNvbGUubG9nKFwiVGhpcyBpcyBhIE5PVCBxdWVyeVwiKTtcclxuXHRcdFx0XHRcdFx0c2VhcmNoUXVlcnkgPSBzZWFyY2hRdWVyeSArIFwiIC0oXCIgKyBzdWJxdWVyeSArIFwiKVwiO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSk7XHJcblx0XHRcdHJldHVybiBzZWFyY2hRdWVyeTtcclxuXHRcdH1cclxuXHJcblx0XHRsZXQgdmFudGFnZUJ1dHRvbnNEaXYgPSBjb250ZW50RWwuY3JlYXRlRWwoXCJkaXZcIik7XHJcblx0XHR2YW50YWdlQnV0dG9uc0Rpdi5hZGRDbGFzcyhcInNldHRpbmctaXRlbVwiKTtcclxuXHRcdGxldCB2YW50YWdlQnV0dG9uc0NvbnRyb2xEaXYgPSBjb250ZW50RWwuY3JlYXRlRWwoXCJkaXZcIilcclxuXHRcdHZhbnRhZ2VCdXR0b25zQ29udHJvbERpdi5hZGRDbGFzcyhcInNldHRpbmctaXRlbS1jb250cm9sXCIpO1xyXG5cdFx0bGV0IHZhbnRhZ2VBZGRlZFF1ZXJpZXNEaXYgPSBjb250ZW50RWwuY3JlYXRlRWwoXCJkaXZcIik7XHJcblx0XHR2YW50YWdlU2V0dGluZ3NEaXYuYXBwZW5kKHZhbnRhZ2VBZGRlZFF1ZXJpZXNEaXYpO1xyXG5cclxuXHRcdHZhciBxdWVyeUNvdW50ID0gMTtcclxuXHJcblx0XHRsZXQgYWRkTmV3QW5kRmllbGRCdXR0b24gPSBuZXcgQnV0dG9uQ29tcG9uZW50KHZhbnRhZ2VTZXR0aW5nc0RpdilcclxuXHRcdFx0LnNldEJ1dHRvblRleHQoXCJBZGQgYW4gQU5EIHNlYXJjaCB0b2tlblwiKVxyXG5cdFx0XHQuc2V0Q2xhc3MoXCJtb2QtY3RhXCIpXHJcblx0XHRcdC5vbkNsaWNrKCgpID0+IHtcclxuXHRcdFx0XHRsZXQgbmV3UXVlcnlEaXYgPSBjb250ZW50RWwuY3JlYXRlRWwoXCJkaXZcIik7XHJcblx0XHRcdFx0bmV3UXVlcnlEaXYuYWRkQ2xhc3MoXCJzZXR0aW5nLWl0ZW1cIik7XHJcblx0XHRcdFx0bmV3UXVlcnlEaXYuc2V0QXR0cihcImlkXCIsIFwiQU5EIHF1ZXJ5XCIgKyBxdWVyeUNvdW50KTtcclxuXHRcdFx0XHRsZXQgbmV3UXVlcnlJbmZvRGl2ID0gY29udGVudEVsLmNyZWF0ZUVsKFwiZGl2XCIpO1xyXG5cdFx0XHRcdG5ld1F1ZXJ5SW5mb0Rpdi5hZGRDbGFzcyhcInNldHRpbmctaXRlbS1pbmZvXCIpO1xyXG5cdFx0XHRcdFxyXG5cdFx0XHRcdGxldCBuZXdRdWVyeUNvbnRyb2xEaXYgPSBjb250ZW50RWwuY3JlYXRlRWwoXCJkaXZcIik7XHJcblx0XHRcdFx0bmV3UXVlcnlDb250cm9sRGl2LmFkZENsYXNzKFwic2V0dGluZy1pdGVtLWNvbnRyb2xcIilcclxuXHRcdFx0XHRsZXQgbmV3UXVlcnlTZW50ZW5jZVN0YXJ0ID0gY29udGVudEVsLmNyZWF0ZUVsKFwiZGl2XCIsIHtcInRleHRcIjogXCJBTkQgc2VhcmNo4qCAXCJ9KVxyXG5cdFx0XHRcdG5ld1F1ZXJ5Q29udHJvbERpdi5hcHBlbmQobmV3UXVlcnlTZW50ZW5jZVN0YXJ0KTtcclxuXHJcblx0XHRcdFx0Ly8gY2hvb3NlIHF1ZXJ5IHR5cGVcclxuXHRcdFx0XHRsZXQgcXVlcnlUeXBlID0gY29udGVudEVsLmNyZWF0ZUVsKFwic2VsZWN0XCIpO1xyXG5cdFx0XHRcdHF1ZXJ5VHlwZS5zZXRBdHRyKFwiY2xhc3NcIiwgXCJkcm9wZG93blwiKTtcclxuXHRcdFx0XHRxdWVyeVR5cGUubXVsdGlwbGU7XHJcblx0XHRcdFx0Ly9xdWVyeVR5cGUuc2V0QXR0cihcInN0eWxlXCIsIFwiZmxvYXQ6IHJpZ2h0O1wiKTtcclxuXHRcdFx0XHRxdWVyeVR5cGUuc2V0QXR0cihcImlkXCIsIFwiQWRkaXRpb25hbCBRdWVyeSBUeXBlIFwiICsgcXVlcnlDb3VudCk7XHJcblx0XHRcdFx0bGV0IGRlZmF1bHRUeXBlT3B0aW9uID0gY29udGVudEVsLmNyZWF0ZUVsKFwib3B0aW9uXCIsIHsgXCJ2YWx1ZVwiOiBcIm5vdGVcIiwgXCJ0ZXh0XCI6IFwibm90ZXNcIn0pO1xyXG5cdFx0XHRcdGRlZmF1bHRUeXBlT3B0aW9uLnNlbGVjdGVkO1xyXG5cdFx0XHRcdHF1ZXJ5VHlwZS5hcHBlbmQoZGVmYXVsdFR5cGVPcHRpb24pO1xyXG5cdFx0XHRcdHF1ZXJ5VHlwZS5hcHBlbmQoY29udGVudEVsLmNyZWF0ZUVsKFwib3B0aW9uXCIsIHsgXCJ2YWx1ZVwiOiBcInNlY3Rpb25cIiwgXCJ0ZXh0XCI6IFwic2VjdGlvbnNcIn0pKTtcclxuXHRcdFx0XHRxdWVyeVR5cGUuYXBwZW5kKGNvbnRlbnRFbC5jcmVhdGVFbChcIm9wdGlvblwiLCB7IFwidmFsdWVcIjogXCJibG9ja1wiLCBcInRleHRcIjogXCJibG9ja3NcIn0pKTtcclxuXHRcdFx0XHRxdWVyeVR5cGUuYXBwZW5kKGNvbnRlbnRFbC5jcmVhdGVFbChcIm9wdGlvblwiLCB7IFwidmFsdWVcIjogXCJsaW5lXCIsIFwidGV4dFwiOiBcImxpbmVzXCJ9KSk7XHJcblx0XHRcdFx0bmV3UXVlcnlDb250cm9sRGl2LmFwcGVuZChxdWVyeVR5cGUpO1xyXG5cclxuXHJcblx0XHRcdFx0bGV0IG5ld1F1ZXJ5Rm9yVGV4dCA9IGNvbnRlbnRFbC5jcmVhdGVFbChcImRpdlwiLCB7XCJ0ZXh0XCI6IFwi4qCAZm9y4qCAXCJ9KTtcclxuXHRcdFx0XHRuZXdRdWVyeUNvbnRyb2xEaXYuYXBwZW5kKG5ld1F1ZXJ5Rm9yVGV4dCk7XHJcblxyXG5cdFx0XHRcdC8vIGNob29zZSBsaXN0IHR5cGVcclxuXHRcdFx0XHRsZXQgbGlzdFR5cGUgPSBjb250ZW50RWwuY3JlYXRlRWwoXCJzZWxlY3RcIik7XHJcblx0XHRcdFx0bGlzdFR5cGUuc2V0QXR0cihcImNsYXNzXCIsIFwiZHJvcGRvd25cIik7XHJcblx0XHRcdFx0bGlzdFR5cGUubXVsdGlwbGU7XHJcblx0XHRcdFx0Ly9saXN0VHlwZS5zZXRBdHRyKFwic3R5bGVcIiwgXCJmbG9hdDogcmlnaHQ7XCIpO1xyXG5cdFx0XHRcdGxpc3RUeXBlLnNldEF0dHIoXCJpZFwiLCBcIkFkZGl0aW9uYWwgUXVlcnkgTGlzdCBUeXBlIFwiICsgcXVlcnlDb3VudCk7XHJcblx0XHRcdFx0bGV0IGRlZmF1bHRMaXN0VHlwZU9wdGlvbiA9IGNvbnRlbnRFbC5jcmVhdGVFbChcIm9wdGlvblwiLCB7IFwidmFsdWVcIjogXCJhbnlcIiwgXCJ0ZXh0XCI6IFwiYW55IGxpbmUgdHlwZVwifSk7XHJcblx0XHRcdFx0ZGVmYXVsdExpc3RUeXBlT3B0aW9uLnNlbGVjdGVkO1xyXG5cdFx0XHRcdGxpc3RUeXBlLmFwcGVuZChkZWZhdWx0TGlzdFR5cGVPcHRpb24pO1xyXG5cdFx0XHRcdGxpc3RUeXBlLmFwcGVuZChjb250ZW50RWwuY3JlYXRlRWwoXCJvcHRpb25cIiwgeyBcInZhbHVlXCI6IFwibGlzdCBpdGVtXCIsIFwidGV4dFwiOiBcImxpc3QgaXRlbXNcIn0pKTtcclxuXHRcdFx0XHRsaXN0VHlwZS5hcHBlbmQoY29udGVudEVsLmNyZWF0ZUVsKFwib3B0aW9uXCIsIHsgXCJ2YWx1ZVwiOiBcImluY29tcGxldGUgdGFza3NcIiwgXCJ0ZXh0XCI6IFwiaW5jb21wbGV0ZSB0YXNrc1wifSkpO1xyXG5cdFx0XHRcdGxpc3RUeXBlLmFwcGVuZChjb250ZW50RWwuY3JlYXRlRWwoXCJvcHRpb25cIiwgeyBcInZhbHVlXCI6IFwiY29tcGxldGVkIHRhc2tzXCIsIFwidGV4dFwiOiBcImNvbXBsZXRlZCB0YXNrc1wifSkpO1xyXG5cdFx0XHRcdGxpc3RUeXBlLmFwcGVuZChjb250ZW50RWwuY3JlYXRlRWwoXCJvcHRpb25cIiwgeyBcInZhbHVlXCI6IFwiYWxsIHRhc2tzXCIsIFwidGV4dFwiOiBcImFsbCB0YXNrc1wifSkpO1xyXG5cdFx0XHRcdG5ld1F1ZXJ5Q29udHJvbERpdi5hcHBlbmQobGlzdFR5cGUpO1xyXG5cclxuXHRcdFx0XHQvLyBjaG9vc2UgcXVlcnkgc3VidHlwZVxyXG5cdFx0XHRcdGxldCBxdWVyeVN1YnR5cGUgPSBjb250ZW50RWwuY3JlYXRlRWwoXCJzZWxlY3RcIik7XHJcblx0XHRcdFx0cXVlcnlTdWJ0eXBlLnNldEF0dHIoXCJjbGFzc1wiLCBcImRyb3Bkb3duXCIpO1xyXG5cdFx0XHRcdHF1ZXJ5U3VidHlwZS5tdWx0aXBsZTtcclxuXHRcdFx0XHRxdWVyeVN1YnR5cGUuc2V0QXR0cihcImlkXCIsIFwiQWRkaXRpb25hbCBRdWVyeSBTdWJ0eXBlIFwiICsgcXVlcnlDb3VudCk7XHJcblx0XHRcdFx0Ly8gcXVlcnlTdWJ0eXBlLnNldEF0dHIoXCJzdHlsZVwiLCBcImZsb2F0OiByaWdodDtcIik7XHJcblx0XHRcdFx0bGV0IGRlZmF1bHRTdWJ0eXBlT3B0aW9uID0gY29udGVudEVsLmNyZWF0ZUVsKFwib3B0aW9uXCIsIHsgXCJ2YWx1ZVwiOiBcIlwiLCBcInRleHRcIjogXCJ3aXRoIHRleHQgY29udGFpbmluZ1wifSk7XHJcblx0XHRcdFx0ZGVmYXVsdFN1YnR5cGVPcHRpb24uc2VsZWN0ZWQ7XHJcblx0XHRcdFx0cXVlcnlTdWJ0eXBlLmFwcGVuZChkZWZhdWx0U3VidHlwZU9wdGlvbik7XHJcblx0XHRcdFx0cXVlcnlTdWJ0eXBlLmFwcGVuZChjb250ZW50RWwuY3JlYXRlRWwoXCJvcHRpb25cIiwgeyBcInZhbHVlXCI6IFwid2l0aCBhIGxpbmsgdG8gbm90ZXMgd2l0aCBuYW1lcyBjb250YWluaW5nXCIsIFwidGV4dFwiOiBcIndpdGggbGlua3MgdG8gbm90ZXMgd2l0aCBuYW1lcyBjb250YWluaW5nXCJ9KSk7XHJcblx0XHRcdFx0cXVlcnlTdWJ0eXBlLmFwcGVuZChjb250ZW50RWwuY3JlYXRlRWwoXCJvcHRpb25cIiwgeyBcInZhbHVlXCI6IFwid2l0aCBhbiBlbWFpbCBhZGRyZXNzXCIsIFwidGV4dFwiOiBcIndpdGggZW1haWwgYWRkcmVzc2VzIChpZ25vcmVzIHRoZSBmb2xsb3dpbmcgc2VhcmNoIGZpZWxkKVwifSkpO1xyXG5cdFx0XHRcdHF1ZXJ5U3VidHlwZS5hcHBlbmQoY29udGVudEVsLmNyZWF0ZUVsKFwib3B0aW9uXCIsIHsgXCJ2YWx1ZVwiOiBcIndpdGggYSBwaG9uZSBudW1iZXJcIiwgXCJ0ZXh0XCI6IFwid2l0aCBwaG9uZSBudW1iZXJzIChpZ25vcmVzIHRoZSBmb2xsb3dpbmcgc2VhcmNoIGZpZWxkKVwifSkpO1xyXG5cdFx0XHRcdG5ld1F1ZXJ5Q29udHJvbERpdi5hcHBlbmQocXVlcnlTdWJ0eXBlKTtcclxuXHJcblx0XHRcdFx0bGV0IG5ld1F1ZXJ5ID0gY29udGVudEVsLmNyZWF0ZUVsKFwiaW5wdXRcIiwge1widHlwZVwiOiBcInRleHRcIn0pO1xyXG5cdFx0XHRcdG5ld1F1ZXJ5LnNldEF0dHIoXCJpZFwiLCBcIkFORCBxdWVyeSBcIiArIHF1ZXJ5Q291bnQpO1xyXG5cdFx0XHRcdHF1ZXJ5Q291bnQgPSBxdWVyeUNvdW50ICsgMTtcclxuXHRcdFx0XHRuZXdRdWVyeUNvbnRyb2xEaXYuYXBwZW5kKG5ld1F1ZXJ5KTtcclxuXHRcdFx0XHRuZXdRdWVyeURpdi5hcHBlbmQobmV3UXVlcnlJbmZvRGl2KTtcclxuXHRcdFx0XHRuZXdRdWVyeURpdi5hcHBlbmQobmV3UXVlcnlDb250cm9sRGl2KTtcclxuXHRcdFx0XHR2YW50YWdlQWRkZWRRdWVyaWVzRGl2LmFwcGVuZChuZXdRdWVyeURpdik7XHJcblxyXG5cdFx0XHRcdGxldCBpbnB1dEJveGVzID0gdmFudGFnZUFkZGVkUXVlcmllc0Rpdi5xdWVyeVNlbGVjdG9yQWxsKFwiaW5wdXRcIik7XHJcblx0XHRcdFx0aW5wdXRCb3hlcy5mb3JFYWNoKChpbnB1dEJveCkgPT4ge1xyXG5cdFx0XHRcdFx0aW5wdXRCb3guYWRkRXZlbnRMaXN0ZW5lcigna2V5cHJlc3MnLCBmdW5jdGlvbiAoa2V5cHJlc3NlZCkge1xyXG5cdFx0XHRcdFx0XHRpZiAoa2V5cHJlc3NlZC5rZXkgPT09ICdFbnRlcicpIHtcclxuXHRcdFx0XHRcdFx0XHRpbml0aWF0ZVNlYXJjaCgpO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHR9KTtcclxuXHJcblx0XHRcdFx0bGV0IG9wdGlvbkJveGVzID0gdmFudGFnZUFkZGVkUXVlcmllc0Rpdi5xdWVyeVNlbGVjdG9yQWxsKFwic2VsZWN0XCIpO1xyXG5cdFx0XHRcdG9wdGlvbkJveGVzLmZvckVhY2goKG9wdGlvbkJveCkgPT4ge1xyXG5cdFx0XHRcdFx0b3B0aW9uQm94LmFkZEV2ZW50TGlzdGVuZXIoJ2tleXByZXNzJywgZnVuY3Rpb24gKGtleXByZXNzZWQpIHtcclxuXHRcdFx0XHRcdFx0aWYgKGtleXByZXNzZWQua2V5ID09PSAnRW50ZXInKSB7XHJcblx0XHRcdFx0XHRcdFx0aW5pdGlhdGVTZWFyY2goKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0fSk7XHJcblx0XHRcdH0pO1xyXG5cclxuXHRcdGxldCBhZGROZXdPckZpZWxkQnV0dG9uID0gbmV3IEJ1dHRvbkNvbXBvbmVudCh2YW50YWdlU2V0dGluZ3NEaXYpXHJcblx0XHRcdC5zZXRCdXR0b25UZXh0KFwiQWRkIGFuIE9SIHNlYXJjaCB0b2tlblwiKVxyXG5cdFx0XHQuc2V0Q2xhc3MoXCJtb2QtY3RhXCIpXHJcblx0XHRcdC5vbkNsaWNrKCgpID0+IHtcclxuXHRcdFx0XHRsZXQgbmV3UXVlcnlEaXYgPSBjb250ZW50RWwuY3JlYXRlRWwoXCJkaXZcIik7XHJcblx0XHRcdFx0bmV3UXVlcnlEaXYuYWRkQ2xhc3MoXCJzZXR0aW5nLWl0ZW1cIik7XHJcblx0XHRcdFx0bmV3UXVlcnlEaXYuc2V0QXR0cihcImlkXCIsIFwiT1IgcXVlcnlcIiArIHF1ZXJ5Q291bnQpO1xyXG5cdFx0XHRcdGxldCBuZXdRdWVyeUluZm9EaXYgPSBjb250ZW50RWwuY3JlYXRlRWwoXCJkaXZcIik7XHJcblx0XHRcdFx0bmV3UXVlcnlJbmZvRGl2LmFkZENsYXNzKFwic2V0dGluZy1pdGVtLWluZm9cIik7XHJcblx0XHRcdFx0Ly8gbGV0IG5ld1F1ZXJ5VGV4dExhYmVsID0gY29udGVudEVsLmNyZWF0ZUVsKFwiZGl2XCIsIHtcInRleHRcIjpcIk9SIHNlYXJjaCAuLi5cIn0pO1xyXG5cdFx0XHRcdC8vIG5ld1F1ZXJ5SW5mb0Rpdi5hcHBlbmQobmV3UXVlcnlUZXh0TGFiZWwpO1xyXG5cdFx0XHRcdGxldCBuZXdRdWVyeUNvbnRyb2xEaXYgPSBjb250ZW50RWwuY3JlYXRlRWwoXCJkaXZcIik7XHJcblx0XHRcdFx0bmV3UXVlcnlDb250cm9sRGl2LmFkZENsYXNzKFwic2V0dGluZy1pdGVtLWNvbnRyb2xcIilcclxuXHRcdFx0XHRsZXQgbmV3UXVlcnlTZW50ZW5jZVN0YXJ0ID0gY29udGVudEVsLmNyZWF0ZUVsKFwiZGl2XCIsIHtcInRleHRcIjogXCJPUiBzZWFyY2jioIBcIn0pXHJcblx0XHRcdFx0bmV3UXVlcnlDb250cm9sRGl2LmFwcGVuZChuZXdRdWVyeVNlbnRlbmNlU3RhcnQpO1xyXG5cclxuXHRcdFx0XHQvLyBjaG9vc2UgcXVlcnkgdHlwZVxyXG5cdFx0XHRcdGxldCBxdWVyeVR5cGUgPSBjb250ZW50RWwuY3JlYXRlRWwoXCJzZWxlY3RcIik7XHJcblx0XHRcdFx0cXVlcnlUeXBlLnNldEF0dHIoXCJjbGFzc1wiLCBcImRyb3Bkb3duXCIpO1xyXG5cdFx0XHRcdHF1ZXJ5VHlwZS5tdWx0aXBsZTtcclxuXHRcdFx0XHQvL3F1ZXJ5VHlwZS5zZXRBdHRyKFwic3R5bGVcIiwgXCJmbG9hdDogcmlnaHQ7XCIpO1xyXG5cdFx0XHRcdHF1ZXJ5VHlwZS5zZXRBdHRyKFwiaWRcIiwgXCJBZGRpdGlvbmFsIFF1ZXJ5IFR5cGUgXCIgKyBxdWVyeUNvdW50KTtcclxuXHRcdFx0XHRsZXQgZGVmYXVsdFR5cGVPcHRpb24gPSBjb250ZW50RWwuY3JlYXRlRWwoXCJvcHRpb25cIiwgeyBcInZhbHVlXCI6IFwibm90ZVwiLCBcInRleHRcIjogXCJub3Rlc1wifSk7XHJcblx0XHRcdFx0ZGVmYXVsdFR5cGVPcHRpb24uc2VsZWN0ZWQ7XHJcblx0XHRcdFx0cXVlcnlUeXBlLmFwcGVuZChkZWZhdWx0VHlwZU9wdGlvbik7XHJcblx0XHRcdFx0cXVlcnlUeXBlLmFwcGVuZChjb250ZW50RWwuY3JlYXRlRWwoXCJvcHRpb25cIiwgeyBcInZhbHVlXCI6IFwic2VjdGlvblwiLCBcInRleHRcIjogXCJzZWN0aW9uc1wifSkpO1xyXG5cdFx0XHRcdHF1ZXJ5VHlwZS5hcHBlbmQoY29udGVudEVsLmNyZWF0ZUVsKFwib3B0aW9uXCIsIHsgXCJ2YWx1ZVwiOiBcImJsb2NrXCIsIFwidGV4dFwiOiBcImJsb2Nrc1wifSkpO1xyXG5cdFx0XHRcdHF1ZXJ5VHlwZS5hcHBlbmQoY29udGVudEVsLmNyZWF0ZUVsKFwib3B0aW9uXCIsIHsgXCJ2YWx1ZVwiOiBcImxpbmVcIiwgXCJ0ZXh0XCI6IFwibGluZXNcIn0pKTtcclxuXHRcdFx0XHRuZXdRdWVyeUNvbnRyb2xEaXYuYXBwZW5kKHF1ZXJ5VHlwZSk7XHJcblxyXG5cclxuXHRcdFx0XHRsZXQgbmV3UXVlcnlGb3JUZXh0ID0gY29udGVudEVsLmNyZWF0ZUVsKFwiZGl2XCIsIHtcInRleHRcIjogXCLioIBmb3LioIBcIn0pO1xyXG5cdFx0XHRcdG5ld1F1ZXJ5Q29udHJvbERpdi5hcHBlbmQobmV3UXVlcnlGb3JUZXh0KTtcclxuXHJcblx0XHRcdFx0Ly8gY2hvb3NlIGxpc3QgdHlwZVxyXG5cdFx0XHRcdGxldCBsaXN0VHlwZSA9IGNvbnRlbnRFbC5jcmVhdGVFbChcInNlbGVjdFwiKTtcclxuXHRcdFx0XHRsaXN0VHlwZS5zZXRBdHRyKFwiY2xhc3NcIiwgXCJkcm9wZG93blwiKTtcclxuXHRcdFx0XHRsaXN0VHlwZS5tdWx0aXBsZTtcclxuXHRcdFx0XHQvL2xpc3RUeXBlLnNldEF0dHIoXCJzdHlsZVwiLCBcImZsb2F0OiByaWdodDtcIik7XHJcblx0XHRcdFx0bGlzdFR5cGUuc2V0QXR0cihcImlkXCIsIFwiQWRkaXRpb25hbCBRdWVyeSBMaXN0IFR5cGUgXCIgKyBxdWVyeUNvdW50KTtcclxuXHRcdFx0XHRsZXQgZGVmYXVsdExpc3RUeXBlT3B0aW9uID0gY29udGVudEVsLmNyZWF0ZUVsKFwib3B0aW9uXCIsIHsgXCJ2YWx1ZVwiOiBcImFueVwiLCBcInRleHRcIjogXCJhbnkgbGluZSB0eXBlXCJ9KTtcclxuXHRcdFx0XHRkZWZhdWx0TGlzdFR5cGVPcHRpb24uc2VsZWN0ZWQ7XHJcblx0XHRcdFx0bGlzdFR5cGUuYXBwZW5kKGRlZmF1bHRMaXN0VHlwZU9wdGlvbik7XHJcblx0XHRcdFx0bGlzdFR5cGUuYXBwZW5kKGNvbnRlbnRFbC5jcmVhdGVFbChcIm9wdGlvblwiLCB7IFwidmFsdWVcIjogXCJsaXN0IGl0ZW1cIiwgXCJ0ZXh0XCI6IFwibGlzdCBpdGVtc1wifSkpO1xyXG5cdFx0XHRcdGxpc3RUeXBlLmFwcGVuZChjb250ZW50RWwuY3JlYXRlRWwoXCJvcHRpb25cIiwgeyBcInZhbHVlXCI6IFwiaW5jb21wbGV0ZSB0YXNrc1wiLCBcInRleHRcIjogXCJpbmNvbXBsZXRlIHRhc2tzXCJ9KSk7XHJcblx0XHRcdFx0bGlzdFR5cGUuYXBwZW5kKGNvbnRlbnRFbC5jcmVhdGVFbChcIm9wdGlvblwiLCB7IFwidmFsdWVcIjogXCJjb21wbGV0ZWQgdGFza3NcIiwgXCJ0ZXh0XCI6IFwiY29tcGxldGVkIHRhc2tzXCJ9KSk7XHJcblx0XHRcdFx0bGlzdFR5cGUuYXBwZW5kKGNvbnRlbnRFbC5jcmVhdGVFbChcIm9wdGlvblwiLCB7IFwidmFsdWVcIjogXCJhbGwgdGFza3NcIiwgXCJ0ZXh0XCI6IFwiYWxsIHRhc2tzXCJ9KSk7XHJcblx0XHRcdFx0bmV3UXVlcnlDb250cm9sRGl2LmFwcGVuZChsaXN0VHlwZSk7XHJcblxyXG5cdFx0XHRcdC8vIGNob29zZSBxdWVyeSBzdWJ0eXBlXHJcblx0XHRcdFx0bGV0IHF1ZXJ5U3VidHlwZSA9IGNvbnRlbnRFbC5jcmVhdGVFbChcInNlbGVjdFwiKTtcclxuXHRcdFx0XHRxdWVyeVN1YnR5cGUuc2V0QXR0cihcImNsYXNzXCIsIFwiZHJvcGRvd25cIik7XHJcblx0XHRcdFx0cXVlcnlTdWJ0eXBlLm11bHRpcGxlO1xyXG5cdFx0XHRcdHF1ZXJ5U3VidHlwZS5zZXRBdHRyKFwiaWRcIiwgXCJBZGRpdGlvbmFsIFF1ZXJ5IFN1YnR5cGUgXCIgKyBxdWVyeUNvdW50KTtcclxuXHRcdFx0XHQvLyBxdWVyeVN1YnR5cGUuc2V0QXR0cihcInN0eWxlXCIsIFwiZmxvYXQ6IHJpZ2h0O1wiKTtcclxuXHRcdFx0XHRsZXQgZGVmYXVsdFN1YnR5cGVPcHRpb24gPSBjb250ZW50RWwuY3JlYXRlRWwoXCJvcHRpb25cIiwgeyBcInZhbHVlXCI6IFwiXCIsIFwidGV4dFwiOiBcIndpdGggdGV4dCBjb250YWluaW5nXCJ9KTtcclxuXHRcdFx0XHRkZWZhdWx0U3VidHlwZU9wdGlvbi5zZWxlY3RlZDtcclxuXHRcdFx0XHRxdWVyeVN1YnR5cGUuYXBwZW5kKGRlZmF1bHRTdWJ0eXBlT3B0aW9uKTtcclxuXHRcdFx0XHRxdWVyeVN1YnR5cGUuYXBwZW5kKGNvbnRlbnRFbC5jcmVhdGVFbChcIm9wdGlvblwiLCB7IFwidmFsdWVcIjogXCJ3aXRoIGEgbGluayB0byBub3RlcyB3aXRoIG5hbWVzIGNvbnRhaW5pbmdcIiwgXCJ0ZXh0XCI6IFwid2l0aCBsaW5rcyB0byBub3RlcyB3aXRoIG5hbWVzIGNvbnRhaW5pbmdcIn0pKTtcclxuXHRcdFx0XHRxdWVyeVN1YnR5cGUuYXBwZW5kKGNvbnRlbnRFbC5jcmVhdGVFbChcIm9wdGlvblwiLCB7IFwidmFsdWVcIjogXCJ3aXRoIGFuIGVtYWlsIGFkZHJlc3NcIiwgXCJ0ZXh0XCI6IFwid2l0aCBlbWFpbCBhZGRyZXNzZXMgKGlnbm9yZXMgdGhlIGZvbGxvd2luZyBzZWFyY2ggZmllbGQpXCJ9KSk7XHJcblx0XHRcdFx0cXVlcnlTdWJ0eXBlLmFwcGVuZChjb250ZW50RWwuY3JlYXRlRWwoXCJvcHRpb25cIiwgeyBcInZhbHVlXCI6IFwid2l0aCBhIHBob25lIG51bWJlclwiLCBcInRleHRcIjogXCJ3aXRoIHBob25lIG51bWJlcnMgKGlnbm9yZXMgdGhlIGZvbGxvd2luZyBzZWFyY2ggZmllbGQpXCJ9KSk7XHJcblx0XHRcdFx0bmV3UXVlcnlDb250cm9sRGl2LmFwcGVuZChxdWVyeVN1YnR5cGUpO1xyXG5cclxuXHRcdFx0XHRsZXQgbmV3UXVlcnkgPSBjb250ZW50RWwuY3JlYXRlRWwoXCJpbnB1dFwiLCB7XCJ0eXBlXCI6IFwidGV4dFwifSk7XHJcblx0XHRcdFx0bmV3UXVlcnkuc2V0QXR0cihcImlkXCIsIFwiT1IgcXVlcnkgXCIgKyBxdWVyeUNvdW50KTtcclxuXHRcdFx0XHRxdWVyeUNvdW50ID0gcXVlcnlDb3VudCArIDE7XHJcblx0XHRcdFx0bmV3UXVlcnlDb250cm9sRGl2LmFwcGVuZChuZXdRdWVyeSk7XHJcblx0XHRcdFx0bmV3UXVlcnlEaXYuYXBwZW5kKG5ld1F1ZXJ5SW5mb0Rpdik7XHJcblx0XHRcdFx0bmV3UXVlcnlEaXYuYXBwZW5kKG5ld1F1ZXJ5Q29udHJvbERpdik7XHJcblx0XHRcdFx0dmFudGFnZUFkZGVkUXVlcmllc0Rpdi5hcHBlbmQobmV3UXVlcnlEaXYpO1xyXG5cclxuXHRcdFx0XHRsZXQgaW5wdXRCb3hlcyA9IHZhbnRhZ2VBZGRlZFF1ZXJpZXNEaXYucXVlcnlTZWxlY3RvckFsbChcImlucHV0XCIpO1xyXG5cdFx0XHRcdGlucHV0Qm94ZXMuZm9yRWFjaCgoaW5wdXRCb3gpID0+IHtcclxuXHRcdFx0XHRcdGlucHV0Qm94LmFkZEV2ZW50TGlzdGVuZXIoJ2tleXByZXNzJywgZnVuY3Rpb24gKGtleXByZXNzZWQpIHtcclxuXHRcdFx0XHRcdFx0aWYgKGtleXByZXNzZWQua2V5ID09PSAnRW50ZXInKSB7XHJcblx0XHRcdFx0XHRcdFx0aW5pdGlhdGVTZWFyY2goKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0fSk7XHJcblxyXG5cdFx0XHRcdGxldCBvcHRpb25Cb3hlcyA9IHZhbnRhZ2VBZGRlZFF1ZXJpZXNEaXYucXVlcnlTZWxlY3RvckFsbChcInNlbGVjdFwiKTtcclxuXHRcdFx0XHRvcHRpb25Cb3hlcy5mb3JFYWNoKChvcHRpb25Cb3gpID0+IHtcclxuXHRcdFx0XHRcdG9wdGlvbkJveC5hZGRFdmVudExpc3RlbmVyKCdrZXlwcmVzcycsIGZ1bmN0aW9uIChrZXlwcmVzc2VkKSB7XHJcblx0XHRcdFx0XHRcdGlmIChrZXlwcmVzc2VkLmtleSA9PT0gJ0VudGVyJykge1xyXG5cdFx0XHRcdFx0XHRcdGluaXRpYXRlU2VhcmNoKCk7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdH0pO1xyXG5cdFx0XHR9KTtcclxuXHJcblx0XHRcdGxldCBhZGROZXdOb3RGaWVsZEJ1dHRvbiA9IG5ldyBCdXR0b25Db21wb25lbnQodmFudGFnZVNldHRpbmdzRGl2KVxyXG5cdFx0XHQuc2V0QnV0dG9uVGV4dChcIkFkZCBhIE5PVCBzZWFyY2ggdG9rZW5cIilcclxuXHRcdFx0LnNldENsYXNzKFwibW9kLWN0YVwiKVxyXG5cdFx0XHQub25DbGljaygoKSA9PiB7XHJcblx0XHRcdFx0bGV0IG5ld1F1ZXJ5RGl2ID0gY29udGVudEVsLmNyZWF0ZUVsKFwiZGl2XCIpO1xyXG5cdFx0XHRcdG5ld1F1ZXJ5RGl2LmFkZENsYXNzKFwic2V0dGluZy1pdGVtXCIpO1xyXG5cdFx0XHRcdG5ld1F1ZXJ5RGl2LnNldEF0dHIoXCJpZFwiLCBcIk5PVCBxdWVyeVwiICsgcXVlcnlDb3VudCk7XHJcblx0XHRcdFx0bGV0IG5ld1F1ZXJ5SW5mb0RpdiA9IGNvbnRlbnRFbC5jcmVhdGVFbChcImRpdlwiKTtcclxuXHRcdFx0XHRuZXdRdWVyeUluZm9EaXYuYWRkQ2xhc3MoXCJzZXR0aW5nLWl0ZW0taW5mb1wiKTtcclxuXHRcdFx0XHRcclxuXHRcdFx0XHRsZXQgbmV3UXVlcnlDb250cm9sRGl2ID0gY29udGVudEVsLmNyZWF0ZUVsKFwiZGl2XCIpO1xyXG5cdFx0XHRcdG5ld1F1ZXJ5Q29udHJvbERpdi5hZGRDbGFzcyhcInNldHRpbmctaXRlbS1jb250cm9sXCIpXHJcblx0XHRcdFx0bGV0IG5ld1F1ZXJ5U2VudGVuY2VTdGFydCA9IGNvbnRlbnRFbC5jcmVhdGVFbChcImRpdlwiLCB7XCJ0ZXh0XCI6IFwiTk9UIHNlYXJjaOKggFwifSlcclxuXHRcdFx0XHRuZXdRdWVyeUNvbnRyb2xEaXYuYXBwZW5kKG5ld1F1ZXJ5U2VudGVuY2VTdGFydCk7XHJcblxyXG5cdFx0XHRcdC8vIGNob29zZSBxdWVyeSB0eXBlXHJcblx0XHRcdFx0bGV0IHF1ZXJ5VHlwZSA9IGNvbnRlbnRFbC5jcmVhdGVFbChcInNlbGVjdFwiKTtcclxuXHRcdFx0XHRxdWVyeVR5cGUuc2V0QXR0cihcImNsYXNzXCIsIFwiZHJvcGRvd25cIik7XHJcblx0XHRcdFx0cXVlcnlUeXBlLm11bHRpcGxlO1xyXG5cdFx0XHRcdC8vcXVlcnlUeXBlLnNldEF0dHIoXCJzdHlsZVwiLCBcImZsb2F0OiByaWdodDtcIik7XHJcblx0XHRcdFx0cXVlcnlUeXBlLnNldEF0dHIoXCJpZFwiLCBcIkFkZGl0aW9uYWwgUXVlcnkgVHlwZSBcIiArIHF1ZXJ5Q291bnQpO1xyXG5cdFx0XHRcdGxldCBkZWZhdWx0VHlwZU9wdGlvbiA9IGNvbnRlbnRFbC5jcmVhdGVFbChcIm9wdGlvblwiLCB7IFwidmFsdWVcIjogXCJub3RlXCIsIFwidGV4dFwiOiBcIm5vdGVzXCJ9KTtcclxuXHRcdFx0XHRkZWZhdWx0VHlwZU9wdGlvbi5zZWxlY3RlZDtcclxuXHRcdFx0XHRxdWVyeVR5cGUuYXBwZW5kKGRlZmF1bHRUeXBlT3B0aW9uKTtcclxuXHRcdFx0XHRxdWVyeVR5cGUuYXBwZW5kKGNvbnRlbnRFbC5jcmVhdGVFbChcIm9wdGlvblwiLCB7IFwidmFsdWVcIjogXCJzZWN0aW9uXCIsIFwidGV4dFwiOiBcInNlY3Rpb25zXCJ9KSk7XHJcblx0XHRcdFx0cXVlcnlUeXBlLmFwcGVuZChjb250ZW50RWwuY3JlYXRlRWwoXCJvcHRpb25cIiwgeyBcInZhbHVlXCI6IFwiYmxvY2tcIiwgXCJ0ZXh0XCI6IFwiYmxvY2tzXCJ9KSk7XHJcblx0XHRcdFx0cXVlcnlUeXBlLmFwcGVuZChjb250ZW50RWwuY3JlYXRlRWwoXCJvcHRpb25cIiwgeyBcInZhbHVlXCI6IFwibGluZVwiLCBcInRleHRcIjogXCJsaW5lc1wifSkpO1xyXG5cdFx0XHRcdG5ld1F1ZXJ5Q29udHJvbERpdi5hcHBlbmQocXVlcnlUeXBlKTtcclxuXHJcblxyXG5cdFx0XHRcdGxldCBuZXdRdWVyeUZvclRleHQgPSBjb250ZW50RWwuY3JlYXRlRWwoXCJkaXZcIiwge1widGV4dFwiOiBcIuKggGZvcuKggFwifSk7XHJcblx0XHRcdFx0bmV3UXVlcnlDb250cm9sRGl2LmFwcGVuZChuZXdRdWVyeUZvclRleHQpO1xyXG5cclxuXHRcdFx0XHQvLyBjaG9vc2UgbGlzdCB0eXBlXHJcblx0XHRcdFx0bGV0IGxpc3RUeXBlID0gY29udGVudEVsLmNyZWF0ZUVsKFwic2VsZWN0XCIpO1xyXG5cdFx0XHRcdGxpc3RUeXBlLnNldEF0dHIoXCJjbGFzc1wiLCBcImRyb3Bkb3duXCIpO1xyXG5cdFx0XHRcdGxpc3RUeXBlLm11bHRpcGxlO1xyXG5cdFx0XHRcdC8vbGlzdFR5cGUuc2V0QXR0cihcInN0eWxlXCIsIFwiZmxvYXQ6IHJpZ2h0O1wiKTtcclxuXHRcdFx0XHRsaXN0VHlwZS5zZXRBdHRyKFwiaWRcIiwgXCJBZGRpdGlvbmFsIFF1ZXJ5IExpc3QgVHlwZSBcIiArIHF1ZXJ5Q291bnQpO1xyXG5cdFx0XHRcdGxldCBkZWZhdWx0TGlzdFR5cGVPcHRpb24gPSBjb250ZW50RWwuY3JlYXRlRWwoXCJvcHRpb25cIiwgeyBcInZhbHVlXCI6IFwiYW55XCIsIFwidGV4dFwiOiBcImFueSBsaW5lIHR5cGVcIn0pO1xyXG5cdFx0XHRcdGRlZmF1bHRMaXN0VHlwZU9wdGlvbi5zZWxlY3RlZDtcclxuXHRcdFx0XHRsaXN0VHlwZS5hcHBlbmQoZGVmYXVsdExpc3RUeXBlT3B0aW9uKTtcclxuXHRcdFx0XHRsaXN0VHlwZS5hcHBlbmQoY29udGVudEVsLmNyZWF0ZUVsKFwib3B0aW9uXCIsIHsgXCJ2YWx1ZVwiOiBcImxpc3QgaXRlbVwiLCBcInRleHRcIjogXCJsaXN0IGl0ZW1zXCJ9KSk7XHJcblx0XHRcdFx0bGlzdFR5cGUuYXBwZW5kKGNvbnRlbnRFbC5jcmVhdGVFbChcIm9wdGlvblwiLCB7IFwidmFsdWVcIjogXCJpbmNvbXBsZXRlIHRhc2tzXCIsIFwidGV4dFwiOiBcImluY29tcGxldGUgdGFza3NcIn0pKTtcclxuXHRcdFx0XHRsaXN0VHlwZS5hcHBlbmQoY29udGVudEVsLmNyZWF0ZUVsKFwib3B0aW9uXCIsIHsgXCJ2YWx1ZVwiOiBcImNvbXBsZXRlZCB0YXNrc1wiLCBcInRleHRcIjogXCJjb21wbGV0ZWQgdGFza3NcIn0pKTtcclxuXHRcdFx0XHRsaXN0VHlwZS5hcHBlbmQoY29udGVudEVsLmNyZWF0ZUVsKFwib3B0aW9uXCIsIHsgXCJ2YWx1ZVwiOiBcImFsbCB0YXNrc1wiLCBcInRleHRcIjogXCJhbGwgdGFza3NcIn0pKTtcclxuXHRcdFx0XHRuZXdRdWVyeUNvbnRyb2xEaXYuYXBwZW5kKGxpc3RUeXBlKTtcclxuXHJcblx0XHRcdFx0Ly8gY2hvb3NlIHF1ZXJ5IHN1YnR5cGVcclxuXHRcdFx0XHRsZXQgcXVlcnlTdWJ0eXBlID0gY29udGVudEVsLmNyZWF0ZUVsKFwic2VsZWN0XCIpO1xyXG5cdFx0XHRcdHF1ZXJ5U3VidHlwZS5zZXRBdHRyKFwiY2xhc3NcIiwgXCJkcm9wZG93blwiKTtcclxuXHRcdFx0XHRxdWVyeVN1YnR5cGUubXVsdGlwbGU7XHJcblx0XHRcdFx0cXVlcnlTdWJ0eXBlLnNldEF0dHIoXCJpZFwiLCBcIkFkZGl0aW9uYWwgUXVlcnkgU3VidHlwZSBcIiArIHF1ZXJ5Q291bnQpO1xyXG5cdFx0XHRcdC8vIHF1ZXJ5U3VidHlwZS5zZXRBdHRyKFwic3R5bGVcIiwgXCJmbG9hdDogcmlnaHQ7XCIpO1xyXG5cdFx0XHRcdGxldCBkZWZhdWx0U3VidHlwZU9wdGlvbiA9IGNvbnRlbnRFbC5jcmVhdGVFbChcIm9wdGlvblwiLCB7IFwidmFsdWVcIjogXCJcIiwgXCJ0ZXh0XCI6IFwid2l0aCB0ZXh0IGNvbnRhaW5pbmdcIn0pO1xyXG5cdFx0XHRcdGRlZmF1bHRTdWJ0eXBlT3B0aW9uLnNlbGVjdGVkO1xyXG5cdFx0XHRcdHF1ZXJ5U3VidHlwZS5hcHBlbmQoZGVmYXVsdFN1YnR5cGVPcHRpb24pO1xyXG5cdFx0XHRcdHF1ZXJ5U3VidHlwZS5hcHBlbmQoY29udGVudEVsLmNyZWF0ZUVsKFwib3B0aW9uXCIsIHsgXCJ2YWx1ZVwiOiBcIndpdGggYSBsaW5rIHRvIG5vdGVzIHdpdGggbmFtZXMgY29udGFpbmluZ1wiLCBcInRleHRcIjogXCJ3aXRoIGxpbmtzIHRvIG5vdGVzIHdpdGggbmFtZXMgY29udGFpbmluZ1wifSkpO1xyXG5cdFx0XHRcdHF1ZXJ5U3VidHlwZS5hcHBlbmQoY29udGVudEVsLmNyZWF0ZUVsKFwib3B0aW9uXCIsIHsgXCJ2YWx1ZVwiOiBcIndpdGggYW4gZW1haWwgYWRkcmVzc1wiLCBcInRleHRcIjogXCJ3aXRoIGVtYWlsIGFkZHJlc3NlcyAoaWdub3JlcyB0aGUgZm9sbG93aW5nIHNlYXJjaCBmaWVsZClcIn0pKTtcclxuXHRcdFx0XHRxdWVyeVN1YnR5cGUuYXBwZW5kKGNvbnRlbnRFbC5jcmVhdGVFbChcIm9wdGlvblwiLCB7IFwidmFsdWVcIjogXCJ3aXRoIGEgcGhvbmUgbnVtYmVyXCIsIFwidGV4dFwiOiBcIndpdGggcGhvbmUgbnVtYmVycyAoaWdub3JlcyB0aGUgZm9sbG93aW5nIHNlYXJjaCBmaWVsZClcIn0pKTtcclxuXHRcdFx0XHRuZXdRdWVyeUNvbnRyb2xEaXYuYXBwZW5kKHF1ZXJ5U3VidHlwZSk7XHJcblxyXG5cdFx0XHRcdGxldCBuZXdRdWVyeSA9IGNvbnRlbnRFbC5jcmVhdGVFbChcImlucHV0XCIsIHtcInR5cGVcIjogXCJ0ZXh0XCJ9KTtcclxuXHRcdFx0XHRuZXdRdWVyeS5zZXRBdHRyKFwiaWRcIiwgXCJOT1QgcXVlcnkgXCIgKyBxdWVyeUNvdW50KTtcclxuXHRcdFx0XHRxdWVyeUNvdW50ID0gcXVlcnlDb3VudCArIDE7XHJcblx0XHRcdFx0bmV3UXVlcnlDb250cm9sRGl2LmFwcGVuZChuZXdRdWVyeSk7XHJcblx0XHRcdFx0bmV3UXVlcnlEaXYuYXBwZW5kKG5ld1F1ZXJ5SW5mb0Rpdik7XHJcblx0XHRcdFx0bmV3UXVlcnlEaXYuYXBwZW5kKG5ld1F1ZXJ5Q29udHJvbERpdik7XHJcblx0XHRcdFx0dmFudGFnZUFkZGVkUXVlcmllc0Rpdi5hcHBlbmQobmV3UXVlcnlEaXYpO1xyXG5cclxuXHRcdFx0XHRsZXQgaW5wdXRCb3hlcyA9IHZhbnRhZ2VBZGRlZFF1ZXJpZXNEaXYucXVlcnlTZWxlY3RvckFsbChcImlucHV0XCIpO1xyXG5cdFx0XHRcdGlucHV0Qm94ZXMuZm9yRWFjaCgoaW5wdXRCb3gpID0+IHtcclxuXHRcdFx0XHRcdGlucHV0Qm94LmFkZEV2ZW50TGlzdGVuZXIoJ2tleXByZXNzJywgZnVuY3Rpb24gKGtleXByZXNzZWQpIHtcclxuXHRcdFx0XHRcdFx0aWYgKGtleXByZXNzZWQua2V5ID09PSAnRW50ZXInKSB7XHJcblx0XHRcdFx0XHRcdFx0aW5pdGlhdGVTZWFyY2goKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0fSk7XHJcblxyXG5cdFx0XHRcdGxldCBvcHRpb25Cb3hlcyA9IHZhbnRhZ2VBZGRlZFF1ZXJpZXNEaXYucXVlcnlTZWxlY3RvckFsbChcInNlbGVjdFwiKTtcclxuXHRcdFx0XHRvcHRpb25Cb3hlcy5mb3JFYWNoKChvcHRpb25Cb3gpID0+IHtcclxuXHRcdFx0XHRcdG9wdGlvbkJveC5hZGRFdmVudExpc3RlbmVyKCdrZXlwcmVzcycsIGZ1bmN0aW9uIChrZXlwcmVzc2VkKSB7XHJcblx0XHRcdFx0XHRcdGlmIChrZXlwcmVzc2VkLmtleSA9PT0gJ0VudGVyJykge1xyXG5cdFx0XHRcdFx0XHRcdGluaXRpYXRlU2VhcmNoKCk7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH0pO1xyXG5cdFx0XHRcdH0pO1xyXG5cdFx0XHR9KTtcclxuXHJcblx0XHRsZXQgZW1iZWRkZWRTZWFyY2hCdXR0b24gPSBuZXcgQnV0dG9uQ29tcG9uZW50KHZhbnRhZ2VCdXR0b25zQ29udHJvbERpdilcclxuXHRcdFx0LnNldEJ1dHRvblRleHQoXCJDcmVhdGUgZW1iZWRkZWQgc2VhcmNoXCIpXHJcblx0XHRcdC5zZXRDbGFzcyhcIm1vZC1jdGFcIilcclxuXHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xyXG5cdFx0XHRcdGxldCBlbWJlZGRlZFNlYXJjaFF1ZXJ5SGVhZGVyID0gXCJgYGBxdWVyeVxcblwiO1xyXG5cdFx0XHRcdGxldCBlbWJlZGRlZFNlYXJjaFF1ZXJ5Rm9vdGVyID0gXCJcXG5gYGBcIjtcclxuXHRcdFx0XHRsZXQgZW1iZWRkZWRTZWFyY2hRdWVyeTogc3RyaW5nO1xyXG5cdFx0XHRcdGZpbGVTdGFydERhdGVJbnB1dC5yZW1vdmVBdHRyaWJ1dGUoXCJzdHlsZVwiKTtcclxuXHRcdFx0XHRmaWxlRW5kRGF0ZUlucHV0LnJlbW92ZUF0dHJpYnV0ZShcInN0eWxlXCIpO1xyXG5cdFx0XHRcdGlmICgoZmlsZVN0YXJ0RGF0ZUlucHV0LnZhbHVlICE9IFwiXCIpICYmIChmaWxlRW5kRGF0ZUlucHV0LnZhbHVlICE9IFwiXCIpKSB7IC8vIElmIGJvdGggZGF0ZSBmaWVsZHMgaGF2ZSB2YWx1ZXMsIHRoZSB1c2VyIGlzIHRyeWluZyB0byBzZWFyY2ggZGFpbHkgbm90ZXNcclxuXHRcdFx0XHRcdGxldCBwYXJzZWRGaWxlU3RhcnREYXRlID0gbmF0dXJhbExhbmd1YWdlRGF0ZXMucGFyc2VEYXRlKGZpbGVTdGFydERhdGVJbnB1dC52YWx1ZSk7XHJcblx0XHRcdFx0XHRsZXQgcGFyc2VkRmlsZUVuZERhdGUgPSBuYXR1cmFsTGFuZ3VhZ2VEYXRlcy5wYXJzZURhdGUoZmlsZUVuZERhdGVJbnB1dC52YWx1ZSk7XHJcblx0XHRcdFx0XHRpZiAobmF0dXJhbExhbmd1YWdlRGF0ZXMuZ2V0Rm9ybWF0dGVkRGF0ZShwYXJzZWRGaWxlU3RhcnREYXRlLm1vbWVudCkuY29udGFpbnMoXCJJbnZhbGlkXCIpKSB7IC8vIGlmIHRoZSBzdGFydCBkYXRlIGNhbm5vdCBiZSBwcm9jZXNzZWQsIGxldCB0aGUgdXNlciBrbm93XHJcblx0XHRcdFx0XHRcdGNvbnNvbGUubG9nKFwiU3RhcnQgZGF0ZSBjb3VsZCBub3QgYmUgcHJvY2Vzc2VkLlwiKTtcclxuXHRcdFx0XHRcdFx0bmV3IE5vdGljZShcIlNvcnJ5LCBzb21ldGhpbmcgc2VlbXMgdG8gYmUgd3Jvbmcgd2l0aCB0aGF0IHN0YXJ0IGRhdGUuXCIpO1xyXG5cdFx0XHRcdFx0XHRmaWxlU3RhcnREYXRlSW5wdXQuc2V0QXR0cihcInN0eWxlXCIsIFwiYm9yZGVyLWNvbG9yOiB2YXIoLS1iYWNrZ3JvdW5kLW1vZGlmaWVyLWVycm9yKTsgYm9yZGVyLXdpZHRoOiAuMWVtO1wiKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdGlmIChuYXR1cmFsTGFuZ3VhZ2VEYXRlcy5nZXRGb3JtYXR0ZWREYXRlKHBhcnNlZEZpbGVFbmREYXRlLm1vbWVudCkuY29udGFpbnMoXCJJbnZhbGlkXCIpKSB7IC8vIGlmIHRoZSBlbmQgZGF0ZSBjYW5ub3QgYmUgcHJvY2Vzc2VkLCBsZXQgdGhlIHVzZXIga25vd1xyXG5cdFx0XHRcdFx0XHRjb25zb2xlLmxvZyhcIkVuZCBkYXRlIGNvdWxkIG5vdCBiZSBwcm9jZXNzZWQuXCIpO1xyXG5cdFx0XHRcdFx0XHRuZXcgTm90aWNlKFwiU29ycnksIHNvbWV0aGluZyBzZWVtcyB0byBiZSB3cm9uZyB3aXRoIHRoYXQgZW5kIGRhdGUuXCIpO1xyXG5cdFx0XHRcdFx0XHRmaWxlRW5kRGF0ZUlucHV0LnNldEF0dHIoXCJzdHlsZVwiLCBcImJvcmRlci1jb2xvcjogdmFyKC0tYmFja2dyb3VuZC1tb2RpZmllci1lcnJvcik7IGJvcmRlci13aWR0aDogLjFlbTtcIik7XHJcblx0XHRcdFx0XHR9IFxyXG5cdFx0XHRcdFx0aWYgKCEobmF0dXJhbExhbmd1YWdlRGF0ZXMuZ2V0Rm9ybWF0dGVkRGF0ZShwYXJzZWRGaWxlU3RhcnREYXRlLm1vbWVudCkuY29udGFpbnMoXCJJbnZhbGlkXCIpKSAmJiAhKG5hdHVyYWxMYW5ndWFnZURhdGVzLmdldEZvcm1hdHRlZERhdGUocGFyc2VkRmlsZUVuZERhdGUubW9tZW50KS5jb250YWlucyhcIkludmFsaWRcIikpKSB7IC8vIG90aGVyd2lzZSBnbyBhaGVhZCB3aXRoIHRoZSBzZWFyY2hcclxuXHRcdFx0XHRcdFx0ZW1iZWRkZWRTZWFyY2hRdWVyeSA9IGVtYmVkZGVkU2VhcmNoUXVlcnlIZWFkZXIgKyBzZXRTZWFyY2hRdWVyeSgpICsgZW1iZWRkZWRTZWFyY2hRdWVyeUZvb3RlcjtcclxuXHRcdFx0XHRcdFx0Ly8gbGV0IGRvYyA9IHRoaXMuYXBwLndvcmtzcGFjZS5hY3RpdmVMZWFmLnZpZXcuc291cmNlTW9kZS5jbUVkaXRvci5nZXREb2MoKTtcclxuXHRcdFx0XHRcdFx0bGV0IHZpZXcgPSB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0QWN0aXZlVmlld09mVHlwZShNYXJrZG93blZpZXcpO1xyXG5cdFx0XHRcdFx0XHRpZiAoIXZpZXcpIHtcclxuXHRcdFx0XHRcdFx0XHRuZXcgTm90aWNlKFwiTm8gZWRpdGFibGUgZG9jdW1lbnQgaXMgb3Blbi4gUGVyaGFwcyB5b3UgbWVhbnQgdG8gY2xpY2sgXFxcIk5ldyBzZWFyY2hcXFwiP1wiKTtcclxuXHRcdFx0XHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0dGhpcy5jbG9zZSgpO1xyXG5cdFx0XHRcdFx0XHRsZXQgZG9jID0gdmlldy5zb3VyY2VNb2RlLmNtRWRpdG9yLmdldERvYygpO1xyXG5cdFx0XHRcdFx0XHRsZXQgY3Vyc29yID0gZG9jLmdldEN1cnNvcigpO1xyXG5cdFx0XHRcdFx0XHRkb2MucmVwbGFjZVJhbmdlKGVtYmVkZGVkU2VhcmNoUXVlcnksIGN1cnNvcik7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fSBlbHNlIHsgLy8gbm8gZGF0ZXMgaGF2ZSBiZWVuIGVudGVyZWQsIHNvIHRoZSBzZWFyY2ggY2FuIGNvbnRpbnVlXHJcblx0XHRcdFx0XHRlbWJlZGRlZFNlYXJjaFF1ZXJ5ID0gZW1iZWRkZWRTZWFyY2hRdWVyeUhlYWRlciArIHNldFNlYXJjaFF1ZXJ5KCkgKyBlbWJlZGRlZFNlYXJjaFF1ZXJ5Rm9vdGVyO1xyXG5cdFx0XHRcdFx0bGV0IHZpZXcgPSB0aGlzLmFwcC53b3Jrc3BhY2UuZ2V0QWN0aXZlVmlld09mVHlwZShNYXJrZG93blZpZXcpO1xyXG5cdFx0XHRcdFx0XHRpZiAoIXZpZXcpIHtcclxuXHRcdFx0XHRcdFx0XHRuZXcgTm90aWNlKFwiTm8gZWRpdGFibGUgZG9jdW1lbnQgaXMgb3Blbi4gUGVyaGFwcyB5b3UgbWVhbnQgdG8gY2xpY2sgXFxcIk5ldyBzZWFyY2hcXFwiP1wiKTtcclxuXHRcdFx0XHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0dGhpcy5jbG9zZSgpO1xyXG5cdFx0XHRcdFx0XHRsZXQgZG9jID0gdmlldy5zb3VyY2VNb2RlLmNtRWRpdG9yLmdldERvYygpO1xyXG5cdFx0XHRcdFx0XHRsZXQgY3Vyc29yID0gZG9jLmdldEN1cnNvcigpO1xyXG5cdFx0XHRcdFx0XHRkb2MucmVwbGFjZVJhbmdlKGVtYmVkZGVkU2VhcmNoUXVlcnksIGN1cnNvcik7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdFxyXG5cdFx0XHR9KTtcclxuXHJcblx0XHRsZXQgaW5pdGlhdGVTZWFyY2hCdXR0b24gPSBuZXcgQnV0dG9uQ29tcG9uZW50KHZhbnRhZ2VCdXR0b25zQ29udHJvbERpdilcclxuXHRcdFx0LnNldEJ1dHRvblRleHQoXCJOZXcgc2VhcmNoXCIpXHJcblx0XHRcdC5zZXRDbGFzcyhcIm1vZC1jdGFcIilcclxuXHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xyXG5cdFx0XHRcdFx0bGV0IHNlYXJjaFF1ZXJ5OiBzdHJpbmc7XHJcblx0XHRcdFx0XHRmaWxlU3RhcnREYXRlSW5wdXQucmVtb3ZlQXR0cmlidXRlKFwic3R5bGVcIik7XHJcblx0XHRcdFx0XHRmaWxlRW5kRGF0ZUlucHV0LnJlbW92ZUF0dHJpYnV0ZShcInN0eWxlXCIpO1xyXG5cdFx0XHRcdFx0aWYgKChmaWxlU3RhcnREYXRlSW5wdXQudmFsdWUgIT0gXCJcIikgJiYgKGZpbGVFbmREYXRlSW5wdXQudmFsdWUgIT0gXCJcIikpIHsgLy8gSWYgYm90aCBkYXRlIGZpZWxkcyBoYXZlIHZhbHVlcywgdGhlIHVzZXIgaXMgdHJ5aW5nIHRvIHNlYXJjaCBkYWlseSBub3Rlc1xyXG5cdFx0XHRcdFx0XHRsZXQgcGFyc2VkRmlsZVN0YXJ0RGF0ZSA9IG5hdHVyYWxMYW5ndWFnZURhdGVzLnBhcnNlRGF0ZShmaWxlU3RhcnREYXRlSW5wdXQudmFsdWUpO1xyXG5cdFx0XHRcdFx0XHRsZXQgcGFyc2VkRmlsZUVuZERhdGUgPSBuYXR1cmFsTGFuZ3VhZ2VEYXRlcy5wYXJzZURhdGUoZmlsZUVuZERhdGVJbnB1dC52YWx1ZSk7XHJcblx0XHRcdFx0XHRcdGlmIChuYXR1cmFsTGFuZ3VhZ2VEYXRlcy5nZXRGb3JtYXR0ZWREYXRlKHBhcnNlZEZpbGVTdGFydERhdGUubW9tZW50KS5jb250YWlucyhcIkludmFsaWRcIikpIHsgLy8gaWYgdGhlIHN0YXJ0IGRhdGUgY2Fubm90IGJlIHByb2Nlc3NlZCwgbGV0IHRoZSB1c2VyIGtub3dcclxuXHRcdFx0XHRcdFx0XHRjb25zb2xlLmxvZyhcIlN0YXJ0IGRhdGUgY291bGQgbm90IGJlIHByb2Nlc3NlZC5cIik7XHJcblx0XHRcdFx0XHRcdFx0bmV3IE5vdGljZShcIlNvcnJ5LCBzb21ldGhpbmcgc2VlbXMgdG8gYmUgd3Jvbmcgd2l0aCB0aGF0IHN0YXJ0IGRhdGUuXCIpO1xyXG5cdFx0XHRcdFx0XHRcdGZpbGVTdGFydERhdGVJbnB1dC5zZXRBdHRyKFwic3R5bGVcIiwgXCJib3JkZXItY29sb3I6IHZhcigtLWJhY2tncm91bmQtbW9kaWZpZXItZXJyb3IpOyBib3JkZXItd2lkdGg6IC4xZW07XCIpO1xyXG5cdFx0XHRcdFx0XHRcdHJldHVybjtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRpZiAobmF0dXJhbExhbmd1YWdlRGF0ZXMuZ2V0Rm9ybWF0dGVkRGF0ZShwYXJzZWRGaWxlRW5kRGF0ZS5tb21lbnQpLmNvbnRhaW5zKFwiSW52YWxpZFwiKSkgeyAvLyBpZiB0aGUgZW5kIGRhdGUgY2Fubm90IGJlIHByb2Nlc3NlZCwgbGV0IHRoZSB1c2VyIGtub3dcclxuXHRcdFx0XHRcdFx0XHRjb25zb2xlLmxvZyhcIkVuZCBkYXRlIGNvdWxkIG5vdCBiZSBwcm9jZXNzZWQuXCIpO1xyXG5cdFx0XHRcdFx0XHRcdG5ldyBOb3RpY2UoXCJTb3JyeSwgc29tZXRoaW5nIHNlZW1zIHRvIGJlIHdyb25nIHdpdGggdGhhdCBlbmQgZGF0ZS5cIik7XHJcblx0XHRcdFx0XHRcdFx0ZmlsZUVuZERhdGVJbnB1dC5zZXRBdHRyKFwic3R5bGVcIiwgXCJib3JkZXItY29sb3I6IHZhcigtLWJhY2tncm91bmQtbW9kaWZpZXItZXJyb3IpOyBib3JkZXItd2lkdGg6IC4xZW07XCIpO1xyXG5cdFx0XHRcdFx0XHRcdHJldHVybjtcclxuXHRcdFx0XHRcdFx0fSBcclxuXHRcdFx0XHRcdFx0aWYgKCEobmF0dXJhbExhbmd1YWdlRGF0ZXMuZ2V0Rm9ybWF0dGVkRGF0ZShwYXJzZWRGaWxlU3RhcnREYXRlLm1vbWVudCkuY29udGFpbnMoXCJJbnZhbGlkXCIpKSAmJiAhKG5hdHVyYWxMYW5ndWFnZURhdGVzLmdldEZvcm1hdHRlZERhdGUocGFyc2VkRmlsZUVuZERhdGUubW9tZW50KS5jb250YWlucyhcIkludmFsaWRcIikpKSB7IC8vIG90aGVyd2lzZSBnbyBhaGVhZCB3aXRoIHRoZSBzZWFyY2hcclxuXHRcdFx0XHRcdFx0XHRpbml0aWF0ZVNlYXJjaCgpO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9IGVsc2UgeyAvLyBubyBkYXRlcyBoYXZlIGJlZW4gZW50ZXJlZCwgc28gdGhlIHNlYXJjaCBjYW4gY29udGludWVcclxuXHRcdFx0XHRcdFx0aW5pdGlhdGVTZWFyY2goKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0fSk7XHJcblxyXG5cdFx0dmFudGFnZUJ1dHRvbnNEaXYuYXBwZW5kKHZhbnRhZ2VCdXR0b25zQ29udHJvbERpdik7XHJcblx0XHR2YW50YWdlU2V0dGluZ3NEaXYuYXBwZW5kKHZhbnRhZ2VCdXR0b25zRGl2KTtcclxuXHR9XHJcblx0XHJcblxyXG5cdG9uQ2xvc2UoKSB7XHJcblx0XHRsZXQge2NvbnRlbnRFbH0gPSB0aGlzO1xyXG5cdFx0Y29udGVudEVsLmVtcHR5KCk7XHJcblx0fVxyXG59XHJcblxyXG4vLyBjbGFzcyBTYW1wbGVTZXR0aW5nVGFiIGV4dGVuZHMgUGx1Z2luU2V0dGluZ1RhYiB7XHJcbi8vIFx0ZGlzcGxheSgpOiB2b2lkIHtcclxuLy8gXHRcdGxldCB7Y29udGFpbmVyRWx9ID0gdGhpcztcclxuXHJcbi8vIFx0XHRjb250YWluZXJFbC5lbXB0eSgpO1xyXG5cclxuLy8gXHRcdGNvbnRhaW5lckVsLmNyZWF0ZUVsKCdoMicsIHt0ZXh0OiAnU2V0dGluZ3MgZm9yIG15IGF3ZXNvbWUgcGx1Z2luLid9KTtcclxuXHJcbi8vIFx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcclxuLy8gXHRcdFx0LnNldE5hbWUoJ1NldHRpbmcgIzEnKVxyXG4vLyBcdFx0XHQuc2V0RGVzYygnSXRcXCdzIGEgc2VjcmV0JylcclxuLy8gXHRcdFx0LmFkZFRleHQodGV4dCA9PiB0ZXh0LnNldFBsYWNlaG9sZGVyKCdFbnRlciB5b3VyIHNlY3JldCcpXHJcbi8vIFx0XHRcdFx0LnNldFZhbHVlKCcnKVxyXG4vLyBcdFx0XHRcdC5vbkNoYW5nZSgodmFsdWUpID0+IHtcclxuLy8gXHRcdFx0XHRcdGNvbnNvbGUubG9nKCdTZWNyZXQ6ICcgKyB2YWx1ZSk7XHJcbi8vIFx0XHRcdFx0fSkpO1xyXG5cclxuLy8gXHR9XHJcbi8vIH1cclxuIl0sIm5hbWVzIjpbIk5vdGljZSIsIlBsdWdpbiIsIkJ1dHRvbkNvbXBvbmVudCIsIk1hcmtkb3duVmlldyIsIk1vZGFsIl0sIm1hcHBpbmdzIjoiOzs7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJLGFBQWEsR0FBRyxTQUFTLENBQUMsRUFBRSxDQUFDLEVBQUU7QUFDbkMsSUFBSSxhQUFhLEdBQUcsTUFBTSxDQUFDLGNBQWM7QUFDekMsU0FBUyxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUUsWUFBWSxLQUFLLElBQUksVUFBVSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO0FBQ3BGLFFBQVEsVUFBVSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsS0FBSyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxNQUFNLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0FBQzFHLElBQUksT0FBTyxhQUFhLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQy9CLENBQUMsQ0FBQztBQUNGO0FBQ08sU0FBUyxTQUFTLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRTtBQUNoQyxJQUFJLElBQUksT0FBTyxDQUFDLEtBQUssVUFBVSxJQUFJLENBQUMsS0FBSyxJQUFJO0FBQzdDLFFBQVEsTUFBTSxJQUFJLFNBQVMsQ0FBQyxzQkFBc0IsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsK0JBQStCLENBQUMsQ0FBQztBQUNsRyxJQUFJLGFBQWEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDeEIsSUFBSSxTQUFTLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDLEVBQUU7QUFDM0MsSUFBSSxDQUFDLENBQUMsU0FBUyxHQUFHLENBQUMsS0FBSyxJQUFJLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQ3pGLENBQUM7QUF1Q0Q7QUFDTyxTQUFTLFNBQVMsQ0FBQyxPQUFPLEVBQUUsVUFBVSxFQUFFLENBQUMsRUFBRSxTQUFTLEVBQUU7QUFDN0QsSUFBSSxTQUFTLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxPQUFPLEtBQUssWUFBWSxDQUFDLEdBQUcsS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLFVBQVUsT0FBTyxFQUFFLEVBQUUsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUU7QUFDaEgsSUFBSSxPQUFPLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxPQUFPLENBQUMsRUFBRSxVQUFVLE9BQU8sRUFBRSxNQUFNLEVBQUU7QUFDL0QsUUFBUSxTQUFTLFNBQVMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO0FBQ25HLFFBQVEsU0FBUyxRQUFRLENBQUMsS0FBSyxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO0FBQ3RHLFFBQVEsU0FBUyxJQUFJLENBQUMsTUFBTSxFQUFFLEVBQUUsTUFBTSxDQUFDLElBQUksR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxRQUFRLENBQUMsQ0FBQyxFQUFFO0FBQ3RILFFBQVEsSUFBSSxDQUFDLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLFVBQVUsSUFBSSxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0FBQzlFLEtBQUssQ0FBQyxDQUFDO0FBQ1AsQ0FBQztBQUNEO0FBQ08sU0FBUyxXQUFXLENBQUMsT0FBTyxFQUFFLElBQUksRUFBRTtBQUMzQyxJQUFJLElBQUksQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDckgsSUFBSSxPQUFPLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsT0FBTyxNQUFNLEtBQUssVUFBVSxLQUFLLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEdBQUcsV0FBVyxFQUFFLE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUM3SixJQUFJLFNBQVMsSUFBSSxDQUFDLENBQUMsRUFBRSxFQUFFLE9BQU8sVUFBVSxDQUFDLEVBQUUsRUFBRSxPQUFPLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ3RFLElBQUksU0FBUyxJQUFJLENBQUMsRUFBRSxFQUFFO0FBQ3RCLFFBQVEsSUFBSSxDQUFDLEVBQUUsTUFBTSxJQUFJLFNBQVMsQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO0FBQ3RFLFFBQVEsT0FBTyxDQUFDLEVBQUUsSUFBSTtBQUN0QixZQUFZLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQ3pLLFlBQVksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUNwRCxZQUFZLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUN6QixnQkFBZ0IsS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEdBQUcs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 diff --git a/.obsidian/plugins/vantage-obsidian/manifest.json b/.obsidian/plugins/vantage-obsidian/manifest.json deleted file mode 100644 index 2e9e89e..0000000 --- a/.obsidian/plugins/vantage-obsidian/manifest.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "id": "vantage-obsidian", - "name": "Vantage - Advanced search builder", - "version": "1.4.0", - "minAppVersion": "0.9.12", - "description": "Build advanced search queries in Obsidian.", - "author": "ryanjamurphy", - "authorUrl": "https://axle.design", - "isDesktopOnly": false -} diff --git a/.obsidian/starred.json b/.obsidian/starred.json index 69a0a79..fd60390 100644 --- a/.obsidian/starred.json +++ b/.obsidian/starred.json @@ -10,6 +10,16 @@ "title": "00 🏠 Main Dashboard", "path": "00 🏠 Main Dashboard.md" }, + { + "type": "file", + "title": "00 🧰 Setup", + "path": "100 Disciplines/110 🎀 Example Discipline/Setup/00 🧰 Setup.md" + }, + { + "type": "file", + "title": "110 🎀 Example Discipline", + "path": "100 Disciplines/110 🎀 Example Discipline/110 🎀 Example Discipline.md" + }, { "type": "file", "title": "00 🔀 Divergence to Disciplines", @@ -25,11 +35,6 @@ "title": "02 🎎 Ikigai Expansion", "path": "999 Setup/02 🎎 Ikigai Expansion.md" }, - { - "type": "file", - "title": "110 🎀 Example Discipline", - "path": "100 Disciplines/110 🎀 Example Discipline/110 🎀 Example Discipline.md" - }, { "type": "file", "title": "00 🎁 Example Project", @@ -43,7 +48,7 @@ { "type": "file", "title": "90 🗃️ Master Backlog", - "path": "90 🗃️ Master Backlog.md" + "path": "01 🗃️ Master Backlog.md" } ] } \ No newline at end of file diff --git a/.obsidian/workspace b/.obsidian/workspace index 3cf8a5b..b5af66c 100644 --- a/.obsidian/workspace +++ b/.obsidian/workspace @@ -4,12 +4,12 @@ "type": "split", "children": [ { - "id": "7a2c304ca628cedc", + "id": "fab993592cdc53bd", "type": "leaf", "state": { "type": "markdown", "state": { - "file": "000 Inbox/00 ❗ Readme.md", + "file": "README.md", "mode": "source" } } @@ -86,52 +86,17 @@ "type": "split", "children": [ { - "id": "5116d57311ec98b6", + "id": "b43dcb35aa923479", "type": "tabs", - "dimension": 38.10861423220974, + "dimension": 33.52059925093633, "children": [ - { - "id": "a853884b70beb523", - "type": "leaf", - "state": { - "type": "outline", - "state": { - "file": "000 Inbox/00 ❗ Readme.md" - } - } - }, - { - "id": "dd85083b98e96ebb", - "type": "leaf", - "state": { - "type": "calendar", - "state": {} - } - }, - { - "id": "16a2297c4248b84a", - "type": "leaf", - "state": { - "type": "backlink", - "state": { - "file": "000 Inbox/00 ❗ Readme.md", - "collapseAll": false, - "extraContext": false, - "sortOrder": "alphabetical", - "showSearch": false, - "searchQuery": "", - "backlinkCollapsed": false, - "unlinkedCollapsed": true - } - } - }, { "id": "3e7ef70c26947fa0", "type": "leaf", "state": { "type": "localgraph", "state": { - "file": "000 Inbox/00 ❗ Readme.md", + "file": "README.md", "options": { "collapse-filter": false, "search": "path:\"000 Inbox\" OR path:\"300 Resources\" OR path:\"100 Disciplines\" -tag:note/dashboard -file:\"🌊\" -file:\"💡\" -file:\"🔨\"", @@ -149,66 +114,56 @@ "textFadeMultiplier": 0, "nodeSizeMultiplier": 1, "lineSizeMultiplier": 1, - "collapse-forces": false, + "collapse-forces": true, "centerStrength": 0.808547008547009, "repelStrength": 4, "linkStrength": 0.370940170940171, "linkDistance": 30, - "scale": 1, + "scale": 0.6554983534946917, "close": true } } } } - ], - "currentTab": 3 + ] }, { - "id": "221c1a9bfdcd9bfe", + "id": "5116d57311ec98b6", "type": "tabs", - "dimension": 61.89138576779026, + "dimension": 66.47940074906367, "children": [ { - "id": "2198e8140483c9c4", - "type": "leaf", - "state": { - "type": "markdown", - "state": { - "file": "700 Views/Tasks Ongoing.md", - "mode": "preview" - } - } - }, - { - "id": "6263f959afaffe0d", + "id": "a853884b70beb523", "type": "leaf", "state": { - "type": "markdown", + "type": "outline", "state": { - "file": "700 Views/Habits (View).md", - "mode": "preview" + "file": "README.md" } } }, { - "id": "b17395fadeb6f461", + "id": "dd85083b98e96ebb", "type": "leaf", "state": { - "type": "markdown", - "state": { - "file": "700 Views/Reminder.md", - "mode": "preview" - } + "type": "calendar", + "state": {} } }, { - "id": "9101501d3e2fc232", + "id": "16a2297c4248b84a", "type": "leaf", "state": { - "type": "markdown", + "type": "backlink", "state": { - "file": "700 Views/Curation.md", - "mode": "preview" + "file": "README.md", + "collapseAll": false, + "extraContext": false, + "sortOrder": "alphabetical", + "showSearch": false, + "searchQuery": "", + "backlinkCollapsed": false, + "unlinkedCollapsed": true } } } @@ -216,19 +171,19 @@ } ], "direction": "horizontal", - "width": 269 + "width": 282 }, - "active": "7a2c304ca628cedc", + "active": "fab993592cdc53bd", "lastOpenFiles": [ + "README.md", "000 Inbox/00 ❗ Readme.md", - "000 Inbox/Other Useful Functionality.md", - "00 🏠 Main Dashboard.md", - "99 💗 Life.md", - "90 🗃️ Master Backlog.md", - "200 Alignment/230 Monthly/2021-10.md", - "80 🌊 Tasks Life.md", - "01 🔁 Habits Dashboard.md", - "100 Disciplines/110 🎀 Example Discipline/110 🎀 Example Discipline.md", - "300 Resources/Tasks.md" + "000 Inbox/Fundamentals of LDP.md", + "100 Disciplines/110 🎀 Example Discipline/Setup/00 🧰 Setup.md", + "100 Disciplines/110 🎀 Example Discipline/Setup/12 🔂 Convergence to Ikigai.md", + "100 Disciplines/110 🎀 Example Discipline/Setup/13 🎎 Ikigai Expansion.md", + "000 Inbox/Suggestions After Learning Initial LDP.md", + "100 Disciplines/110 🎀 Example Discipline/Setup/11 🔀 Divergence to Disciplines.md", + "000 Inbox/Working with LDP.md", + "000 Inbox/Philosophy - How to Approach LDP.md" ] } \ No newline at end of file diff --git "a/00 \360\237\217\240 Main Dashboard.md" "b/00 \360\237\217\240 Main Dashboard.md" index 1205f8b..a2a493f 100644 --- "a/00 \360\237\217\240 Main Dashboard.md" +++ "b/00 \360\237\217\240 Main Dashboard.md" @@ -1,122 +1,22 @@ --- aliases: 🏠 Main Dashboard -tags: [ note/dashboard ] +tags: [ dashboard ] --- # 🏠 Main Dashboard -## Ikigai -```dataview -TABLE WITHOUT ID - link(file.name, default(aliases, file.name)) as "Discipline", - dynamic as "Dynamic" -FROM #note/ikigai -``` - -## Projects -```dataview -TABLE WITHOUT ID - link(file.name, default(link(file.name).aliases, file.name)) as "Project", - status as "Status", - default(due, "Not Set") as "Due", - padleft(string(priority), 2, "0") as "Priority", - date(today) - date(start) as "Duration" -FROM #note/project and !#note/ikigai WHERE status = "00 Ongoing" or status = "01 Blocked" or status = "02 Planned" or status = "03 On-Hold" and file.name != "Dashboard Project" and !contains(tags, "note/habit") -SORT status, "Due" asc, priority desc -``` - -## Resume Work -```query -tag:resume -``` - -## Habits -```tasks -not done -due today -description includes #hb -``` - -## Ongoing Tasks (4) -### Filter Priority +## Ongoing Tasks ```tasks not done description includes #ongoing -description includes #p11 -description does not include #exclude -description does not include #hb -hide task count -``` -```tasks -not done -description includes #ongoing -description includes #p10 -description does not include #exclude -description does not include #hb -hide task count -``` -```tasks -not done -description includes #ongoing -description includes #p01 -description does not include #exclude -description does not include #hb -hide task count -``` -```tasks -not done -description includes #ongoing -description includes #p00 -description does not include #exclude -description does not include #hb -hide task count -``` - -### Filter Due -```tasks -not done -description includes #ongoing -description does not include #exclude -description does not include #hb -hide task count +path does not include 800 Templates ``` -## Reminders +## To do ```tasks not done -description includes #00m -description does not include #ongoing -description does not include #exclude +path does not include 800 Templates ``` -## Blocked -```tasks -not done -description includes #p11 -description includes #block -description does not include #exclude -description does not include #hb -hide task count -``` -```tasks -not done -description includes #p10 -description includes #block -description does not include #exclude -description does not include #hb -hide task count -``` +## Completed ```tasks -not done -description includes #p01 -description includes #block -description does not include #exclude -description does not include #hb -hide task count -``` -```tasks -not done -description includes #p00 -description includes #block -description does not include #exclude -description does not include #hb -hide task count +done ``` \ No newline at end of file diff --git "a/000 Inbox/00 \342\235\227 Readme.md" "b/000 Inbox/00 \342\235\227 Readme.md" index 8a58bfd..3206536 100644 --- "a/000 Inbox/00 \342\235\227 Readme.md" +++ "b/000 Inbox/00 \342\235\227 Readme.md" @@ -1,104 +1,37 @@ --- -aliases: -tags: [ note/info ] -version: 0.1.3 +aliases: ❗ Readme +tags: [ info ] +version: 0.2 --- # Hello! -Welcome to Life-Disciplines-Projects (LDP) is a life-management framework built within [Obsidian](https://obsidian.md/) by [uwi[(https://twitter.com/uwidev). This note serves to explain the theory of LDP and its workflow to my best of his ability. +Welcome to Life-Disciplines-Projects (LDP) is a life-management framework built within [Obsidian](https://obsidian.md/) by [uwi](https://twitter.com/uwidev). It takes inspriation from [[Getting Things Done]], [[Agile Project Management]] and it's derivatives ([[Scrum (Agile)|Scrum]], [[Kanban (Agile)|Kanban]]), [[Ikigai]], [[Pillars, Pipelines, Vaults (PPV)]]. -*Name LDP not final. I'm open to suggestions.* +**I have provided all of this content for free, so please consider donating to me at [ko-fi](https://ko-fi.com/uwidev) when you have the chance.** -## Preface -**This note contains some additional sections relevant to this Vault now that there's more context. You can skip the sections you've already read from [[README]].** - -### Please don't just copy me -**My life is not your life.** I have provided a lot of resources that serve to supplement my model of how to efficiently manage my life. I tried my best to generalize the ideas, but regardless, do not mindlessly follow the motion of the notes I provide. Instead, transform it into something that works with your own views of how life should operate. - -### Why explicitly manage life? -With the sheer amount and rate of information we're constantly bombarded with, most of it absolutely useless, we sometimes lose our sense of self and meaning. Everything around us, especially on the internet, is trying to grab our attention. -- "Hey, look at this! It's a cool product that makes everything harder for no reason!" -- "Look! Your friends online doing absolutely nothing that are interesting to you!" -- "Remember this item still in your cart a month ago? Here's a reminder! Buy it now!" - -Some aren't as irritating the examples I listed above, but the fact that I can make them as examples says a lot. - -We're always distracted to the point where even as adults, we haven't even stopped and thought about what we want to do. This is my experience in my family and what I've observed growing up in the modern States. - -Much of the internet and everyday life are these self-sustaining cycles of complacency. Some of us go to a work we don't particularly enjoy, only to come home to cope with the stress of work, only to repeat the cycle again just because it gets the bills paid. To me, that's my version of hell. I don't want that, and I think most people would agree as well. We need a way to keep us in check and on our path towards what we see as success. - -LDP serves as a way to unstuck oneself and to create velocity and direction towards something you really want. - -### Why Obsidian? -Obsidian is an enhanced, barebones markdown text editor. It isn't really built to ease the complexity of workflows, but with the help of plugin support and the community, its functionality is far beyond what it initially was. - -The catch was that in order to do life management in Obsidian, you had to do thorough research into its plugins, workflow design, etc. There are other applications that streamline the process, allowing you to get started right away. But there's something nice about working within the primitive constraints of Obsidian; it's simple and empowering since everything is personalized. - -But the primary reason why I chose Obsidian was because all documents are locally stored on your computer as plain text. There is no dependence on a cloud or server, the only dependence is your computer. There's also the sense of ownership and historical documentation. Everything is yours; just yours. - -And it just felt right. - -## Organization -The organization of LDP can be summarized as follows. -![[Habits, Life, Disciplines, Projects.drawio.png]] - -[[Projects]] and [[Habits]] are more or less the same thing. They are smaller than and are derived from [[Disciplines]]. Disciplines are smaller than and are derived from [[Ikigai|Life]] and other fundamental [[00 💗 Defining Life|life ideas]]. [[Tasks]] are scattered throughout the entire system as needed. +This note serves to explain the fundamental theory of LDP. -This entire system is modeled through folder hierarchy under the folder `100 Disciplines`, though you can personalize it as you seem fit. What's important is that it models the diagram above. - -## Workflow -Assuming the initial setup of Life and Disciplines are complete, my general workflow is as follows. Note that projects should last anywhere between no longer than 1 month. -1. A new project is created that creates mobility towards or sustains a Discipline's Pillar. -2. The project is loosely defined with an objective and completion criteria—optionally grouped. -3. Tasks are created, given a priority, estimated duration, and tagged with its corresponding completion criteria tag. -4. Tasks are explicitly defined as ongoing and are worked on immediately. -5. Task are marked as complete. -6. Steps 3-5 for tasks continue until the project's completion criteria are met, plus a bit of polish. -7. Project is completed. -8. Refactor useful non-general information into generalized notes. -9. Generalized notes that are non-project specific are sent to `300 Resources`. -10. The project and else are archived to `900 Archive/910 Projects`. - -Fairly straight forward process for Projects and Tasks. - -### Alignment -Alignment is a self-regulating system that supplements and smooths workflow. It refers to the process of ensuring that a lower-ordered item make sense given it's higher-ordered context. Tasks should be aligned with projects, projects should be aligned with disciplines, disciplines should be aligned with life. This is done through routine journaling. - -**Tasks $\rightarrow$ Projects:** Aligned Daily -**Projects $\rightarrow$ Disciplines:** Aligned Weekly -**Disciplines $\rightarrow$ Life:** Aligned Quarterly -**Life $\rightarrow$ Sense of Self:** Aligned Yearly - -How you do alignment is mostly up to you, but the main point is to make sure you're on focused. I have provided some templates in `800 Templates` for you to go off of. Feel free to use them, but again, you should transform them into something that works with you. - -> **Important**: You should be explicitly aligning and doing check-ins. Write why this aligns with that. - -## Resources (Knowledge Base) -Your knowledge-base should be organized however you see fit. If you prefer Zettelkasten, LYT, etc., use that. However, I strongly suggest that your knowledge base be under `300 Resources` so it doesn't interfere with LDP. - -## Views -Views, at `700 Views`, are quick queries that give you useful information. If you hover over them and press control on your keyboard while in editing mode, a small preview pops up. If it doesn't work, you might have to go into your Obsidian settings and enable it. - -This is particularly useful when doing Alignment. When answering the question: "What did you get done yesterday?" You might have forgotten. A view of yesterday's tasks would be sufficient. Just look at the view and answer based on what you remember. - -## Templates -I have provided templates to get LDP up and running. - -Do note that for setting up projects and disciplines, you will need to run the QuickAdd command: `QuickAdd: Create New Habit/Discipline/Project`. See [[01 🔀 Divergence to Disciplines#Next Steps]] on how this macro works. +## Preface +### Who is this for? +LDP is a life-management framework for individuals who would like to create mobiliy towards what they want to acheive in their lifetime. It requires a moderate amount of setup to work properly, but it is possible to forgo this if one has already fleshed out their life values. -## Archive -`999 Archive` is where all irrelevant material, whether due to time or interest, go. I organized it by item type (e.g. Discipline, Project, Template, Habit, etc). The other option was to preserve `100 Disciplines` folder structure, but that had too much overhead and redundancy. +If you're looking for an out-of-the-box complete system right away, this may not be for you. -Having it grouped by item type allows for easier searching in the event I never need to unarchive. Tags will help a lot too, depending on how you have them set up. +This framework can be applied outside of Obsidian if desired. -## Setup -If you like my ideas of this framework, you can start setting up LDP [[00 💗 Defining Life|here]]. +### What can you get from this? +- [[Philosophy - How to Approach LDP|How you should apprach LDP]] +- [[Fundamentals of LDP|The fundamentals of LDP]] +- [[Working with LDP]] +- [[Simple Integration Into Obsidian]] +- [[Suggestions After Learning Initial LDP|Suggestions moving forward]] +- [[00 🧰 Setup|A detailed walkthrough on defining your Life and Disciplines]] -## Suggestions and Concerns -DM me though the [Obsidian Community Discord](https://discord.com/invite/veuWUTm). Join the server and you should be able to mention or DM me. **Please don't add me as a friend.** +## Community Discord +Join the Life-Disciplines-Projects Discord server [here](https://discord.gg/jAYuGaEvJb). Also consider joining the official Obsidian Discord [here](https://discord.com/invite/veuWUTm). ## More about uwi -I am a solo indie game developer with a mission of making people cry not because they're say, but because they've witness the beautiful. As of 2021, October 6, I am planning my workflow for game development, hence LDP. +I am a solo indie game developer with a mission of making people cry, but not through of saddness, but through sheer beauty. As of 2021, October 6, I am planning my workflow for game development, hence LDP. -If you're interested in following me, please consider following me on [twitter](https://twitter.com/uwidev) and donating to me on [ko-fi](https://ko-fi.com/uwidev). I'll need all the support I can get! +If you're interested in following me, please consider following my journey on game development, among other things, follow me on [twitter](https://twitter.com/uwidev). Also please consider donating at [ko-fi](https://ko-fi.com/uwidev) when you have the chance. -If you're also a fan of Cirno from the Touhou Project, you can join my community discord [Club Cirno](https://discord.com/invite/clubcirno). \ No newline at end of file +If you're also a fan of Cirno from the Touhou Project, you can join my community Discord [Club Cirno](https://discord.com/invite/clubcirno). \ No newline at end of file diff --git a/000 Inbox/Other Useful Functionality.md b/000 Inbox/Other Useful Functionality.md deleted file mode 100644 index 7545872..0000000 --- a/000 Inbox/Other Useful Functionality.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -aliases: -tags: [ note/info ] ---- -## Other Useful Functionality -There are a lot of neat little things that can make your workflow easier. Here's a very sparse list of small productivity hacks in this Vault. Some are set to keybinds that work for me, and I highly suggest you set them to something that works for you. -- **Hotkeys for starred files:** press `ALT` + `SHIFT` + `1` to immediately open the first starred note in a new pane. You can exclude shift to open it on this pane. If you don't like the hotkey, feel free to change it. -- **Obsidian Task Archiver:** immediately move all finished `Task` to a header named `Archived` -- **Natural Language Dates:** Need to quickly enter today's date? Type `@today` then type enter. This works for other natural datas, such as `@in 2 days`. Use this everywhere. -- **Templater**: LDP uses templates. One thing that it can do is quickly set up a task with defined values. See [[task]] as a quick example. It assumes you already made the line into a task by pressing `CTRL` + `ENTER`. -- **Note Refactor:** A plugin to quickly refactor notes. I binded it to `CTRL` + `SHIFT` + `M` to refactor and use the first line as the header. -- **Hotkeys++**: Quickly swap a line of text up and down with `ALT` + `W` or `S`. Useful for quickly organizing Tasks. -- **Sort and Permute Lines:** Quickly sort selected lines alphabetically. Applicable for tasks to sort alphabetically to sort by reverse priority, then reverse the sort to sort by priority. Not essential but still useful. -- **Emojis:** There's a plugin for it (not installed). If you're on Windows, pressing `WIN` + `.` will bring up an emoji menu. Type emojis and add that special jazz to your workflow. -- **Open Daily Note $\rightarrow$ Quick Ramblings:** Have something on your mind? `CTRL` + `T` will bring you to your daily journal to ramble on about things. -- **`#resume` Tag:** Use the `#resume` tag to quickly bookmark a location to come back to it later when you have time. On the [[90 🗃️ Master Backlog|🏠 Main Dashboard]] there's an embeded search query for it. If you click on it, it should bring you immediately back to your work (hopefully). You should add context before you call it a day and add this tag. -- **[[Curation]]:** This paired with the local graph (top right panel, right-most tab) can help you find gather related resources for a project. - - Say you have a project to do a presentation on the fundamental components of a plant cell. Assuming you have correct links and tags, you can quickly scour for relevant notes by searching for say `#plant #cell #biology` using **Vantage** or **QuickAdd: Chaotic Note Roller**. The latter is preferred when you're stuck on generating ideas while the former is preferred when you have an idea of what you're looking for. This with the local node graph, golden. \ No newline at end of file diff --git "a/01 \360\237\224\201 Habits Dashboard.md" "b/01 \360\237\224\201 Habits Dashboard.md" deleted file mode 100644 index 514d65e..0000000 --- "a/01 \360\237\224\201 Habits Dashboard.md" +++ /dev/null @@ -1,43 +0,0 @@ ---- -aliases: 🔁 Habits Dashboard -tags: [ note/dashboard, habit ] ---- -# 🔁 Habits Dashboard -```dataview -TABLE WITHOUT ID - link(file.name, default(link(file.name).aliases, file.name)) as "Habit", - status as "Status", - when as "When" -FROM #note/habit -WHERE contains(list("00 Ongoing", "01 Blocked", "02 Planned"), status) -``` - -## Today -```tasks -not done -due today -description includes #hb -``` - -## In the next 3 days -Does not include repeated tasks -```tasks -not done -due after today -due before in 3 days -description includes #hb -``` - -## Overdue -```tasks -not done -due before today -description includes #hb -``` - -## Backlog -```dataview -TASK -FROM #note/habit -WHERE !contains(text, "#hb") and contains(text, "#task") -``` \ No newline at end of file diff --git "a/100 Disciplines/110 \360\237\216\200 Example Discipline/00 Habit - Example Habit/00 \342\234\250 Example Habit.md" "b/100 Disciplines/110 \360\237\216\200 Example Discipline/00 Habit - Example Habit/00 \342\234\250 Example Habit.md" deleted file mode 100644 index 0d8471a..0000000 --- "a/100 Disciplines/110 \360\237\216\200 Example Discipline/00 Habit - Example Habit/00 \342\234\250 Example Habit.md" +++ /dev/null @@ -1,214 +0,0 @@ ---- -aliases: ✨ Example Habit -tags: [ note/dashboard, note/project, note/habit, example_discipline ] -discipline: 110 🎀 Example Discipline -status: 00 Ongoing -start: 2021-10-06 -due: .inf -end: -objective: blah blah blah -when: ---- -[[110 🎀 Example Discipline]] | [[01 🌊 Tasks Example Habit]] | [[02 💡 Ramblings Example Habit]] -# ✨ Example Habit -```dataview -TABLE WITHOUT ID objective as "Objective", default(date(end), date(today)) - date(start) as "Ongoing" -WHERE file.name = this.file.name -``` - -## Abstract -Brief description of what is this habit, why it's important and came to be, and what will happen. - -## Habit -Quick and concrete explanation of what will be done for this Habit. - -## Frequency -How often this Habit is to occur and why. - -## Formation -### Cue -**Where will this Habit take place?** - - -**What time will this Habit be enacted?** - - -**How does this Habit stack with other Habits?** - - -**What will be in place to remind you to do this? Are they passive or active reminders?** - - -### Craving -**How will you increase temptation and reduce friction? Is there a habit you like doing that you can do during or immediately after this?** - - -**What social communities will you join to push further commitment?** - - -### Response -**When the time comes, will there be any additional setup? What will you do to stop lower this friction?** - - -**When you do this habit, how long engage in it? How long now, a week from now, a month, etc.** - - -### Reward -**Will this be tracked some other way besides within Obsidian?** - - -**What are the results of this Habit? How long do you think until these results become rewarding?** - - -## YAML Field -How the data will be tracked within Obsidian. Defined as its own dictionary below, it should be added to [[Journal 00 Daily]]'s YAML. -```YAML -NAME_OF_HABIT: - done: false - stacked: false - bundled: false - duration: -``` - -`done` (bool): Did you do it today? -`stacked` (bool): Did this habit proceed the intended stacking habit? -`bundled` (bool): Did you do a *want* habit after or during this habit? -`duration` (int): How long did you engage in it (in minutes)? - -## [[01 🌊 Tasks Example Habit|Tasks]] -### Ongoing (3) -#### Filter Priority -```tasks -not done -path includes 00 Habit - Example Habit -description includes #ongoing -description includes #p11 -description does not include #exclude -``` -```tasks -not done -path includes 00 Habit - Example Habit -description includes #ongoing -description includes #p10 -description does not include #exclude -``` -```tasks -not done -path includes 00 Habit - Example Habit -description includes #ongoing -description includes #p01 -description does not include #exclude -``` -```tasks -not done -path includes 00 Habit - Example Habit -description includes #ongoing -description includes #p00 -description does not include #exclude -``` - -#### Filter Due -```tasks -not done -path includes 00 Habit - Example Habit -description includes #ongoing -description does not include #exclude -``` - -### Backlog -#### Filter Priority -```tasks -not done -path includes 00 Habit - Example Habit -description includes #p11 -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes 00 Habit - Example Habit -description includes #p10 -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes 00 Habit - Example Habit -description includes #p01 -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes 00 Habit - Example Habit -description includes #p00 -description does not include #ongoing -description does not include #exclude -``` - -#### Filter Duration -```tasks -not done -path includes 00 Habit - Example Habit -description includes #15m -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes 00 Habit - Example Habit -description includes #30m -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes 00 Habit - Example Habit -description includes #01h -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes 00 Habit - Example Habit -description includes #02h -description does not include #ongoing -description does not include #exclude -``` - -### Blocked -```tasks -not done -path includes 00 Habit - Example Habit -description includes #p11 -description includes #block -description does not include #exclude -``` -```tasks -not done -path includes 00 Habit - Example Habit -description includes #p10 -description includes #block -description does not include #exclude -``` -```tasks -not done -path includes 00 Habit - Example Habit -description includes #p01 -description includes #block -description does not include #exclude -``` -```tasks -not done -path includes 00 Habit - Example Habit -description includes #p00 -description includes #block -description does not include #exclude -``` - -### Completed -#### Filter Today -```tasks -done today -path includes 00 Habit - Example Habit -``` \ No newline at end of file diff --git "a/100 Disciplines/110 \360\237\216\200 Example Discipline/00 Habit - Example Habit/01 \360\237\214\212 Tasks Example Habit.md" "b/100 Disciplines/110 \360\237\216\200 Example Discipline/00 Habit - Example Habit/01 \360\237\214\212 Tasks Example Habit.md" deleted file mode 100644 index a94aa54..0000000 --- "a/100 Disciplines/110 \360\237\216\200 Example Discipline/00 Habit - Example Habit/01 \360\237\214\212 Tasks Example Habit.md" +++ /dev/null @@ -1,12 +0,0 @@ ---- -aliases: 🌊 Tasks Example Habit -tags: [ note/data, example_discipline ] ---- -[[00 ✨ Example Habit]] | [[02 💡 Ramblings Example Habit]] -# 🌊 Tasks Example Habit -## Raw -- [ ] #task #p01 #30m #hb Do 20 sit ups 🔁 every day 📅 2021-10-07 -- [x] #task #p01 #30m #hb Do 20 sit ups 🔁 every day 📅 2021-10-06 ✅ 2021-10-06 - -## Archived -- [ ] Archived tasks go here \ No newline at end of file diff --git "a/100 Disciplines/110 \360\237\216\200 Example Discipline/00 Habit - Example Habit/02 \360\237\222\241 Ramblings Example Habit.md" "b/100 Disciplines/110 \360\237\216\200 Example Discipline/00 Habit - Example Habit/02 \360\237\222\241 Ramblings Example Habit.md" deleted file mode 100644 index afee81f..0000000 --- "a/100 Disciplines/110 \360\237\216\200 Example Discipline/00 Habit - Example Habit/02 \360\237\222\241 Ramblings Example Habit.md" +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: 💡 Ramblings Example Habit -tags: [ note/data, example_discipline ] ---- -[[00 ✨ Example Habit]] | [[01 🌊 Tasks Example Habit]] -# 💡 Ramblings Example Habit -## some date -### topic of rambling -ramblings yada yada yada \ No newline at end of file diff --git "a/100 Disciplines/110 \360\237\216\200 Example Discipline/110 \360\237\216\200 Example Discipline.md" "b/100 Disciplines/110 \360\237\216\200 Example Discipline/110 \360\237\216\200 Example Discipline.md" index 6bd5c81..721f6f4 100644 --- "a/100 Disciplines/110 \360\237\216\200 Example Discipline/110 \360\237\216\200 Example Discipline.md" +++ "b/100 Disciplines/110 \360\237\216\200 Example Discipline/110 \360\237\216\200 Example Discipline.md" @@ -1,15 +1,11 @@ --- aliases: 🎀 Example Discipline -tags: [ note/dashboard, note/discipline, note/ikigai, example_discipline ] -ikigai: +tags: [dashboard, discipline, example_discipline] +ikigai: - love - - skill - money - - world -pillars: List 3-8 key values that you want to uphold or eventually uphold to. They should be numbered to indicate priorities. This should also be in the YAML, but in the same order as an unordered list. -dynamic: This is the emerging result of the pillars when viewed together. --- -[[00 🏠 Main Dashboard]] | [[111 🌊 Tasks Example Discipline]] | [[112 💡 Ramblings Example Discipline]] +[[00 🏠 Main Dashboard]] # 🎀 Example Discipline ## Abstract What is the definition of this Discipline? @@ -19,220 +15,9 @@ Continue with a brief description of what this discipline entails. ## Importance and Relevance How is this Discipline important and relevant to you? How and why did you choose the Ikigai characteristics above under the frontmatter YAML? What is your purpose of having this as a Discipline? -#resume (resume example) finish elaboring on what this is +## Tasks +### Raw +- [ ] #task (demo) some random example task to do for this discipline -## Core -```dataview -TABLE WITHOUT ID pillars as "Pillars" -WHERE file.name = this.file.name -``` -```dataview -TABLE WITHOUT ID dynamic as "Dynamic" -WHERE file.name = this.file.name -``` - -## Projects -### Active -```dataview -TABLE WITHOUT ID - link(file.name, default(link(file.name).aliases, file.name)) as "Project", - status as "Status", - due as "Due", - padleft(string(priority), 2, "0") as "Priority", - default(date(end), date(today)) - date(start) as "Duration" -FROM #note/project and #example_discipline -WHERE contains(list("00 Ongoing", "01 Blocked", "02 Planned", "03 Blocked"), status) -SORT status, due asc, priority desc -``` - -### Inactive -```dataview -TABLE WITHOUT ID - link(file.name, default(link(file.name).aliases, file.name)) as "Project", - status as "Status", - end as "End", - padleft(string(priority), 2, "0") as "Priority", - default(date(end), date(today)) - date(start) as "Duration" -FROM #note/project and #example_discipline -WHERE !contains(list("00 Ongoing", "01 Blocked", "02 Planned", "03 Blocked"), status) -SORT status, file.mtime desc -``` - -## [[01 🌊 Tasks Example Discipline|Tasks]] -### Ongoing -#### Filter Priority -```tasks -not done -path includes 110 🎀 Example Discipline -description includes #ongoing -description includes #p11 -description does not include #exclude -``` -```tasks -not done -path includes 110 🎀 Example Discipline -description includes #ongoing -description includes #p10 -description does not include #exclude -``` -```tasks -not done -path includes 110 🎀 Example Discipline -description includes #ongoing -description includes #p01 -description does not include #exclude -``` -```tasks -not done -path includes 110 🎀 Example Discipline -description includes #ongoing -description includes #p00 -description does not include #exclude -``` - -#### Filter Duration -```tasks -not done -path includes 110 🎀 Example Discipline -description includes #ongoing -description includes #15m -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes 110 🎀 Example Discipline -description includes #ongoing -description includes #30m -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes 110 🎀 Example Discipline -description includes #ongoing -description includes #01h -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes 110 🎀 Example Discipline -description includes #ongoing -description includes #02h -description does not include #ongoing -description does not include #exclude -``` - -### Backlog -#### Filter Priority -```tasks -not done -path includes 110 🎀 Example Discipline -description includes #p11 -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes 110 🎀 Example Discipline -description includes #p10 -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes 110 🎀 Example Discipline -description includes #p01 -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes 110 🎀 Example Discipline -description includes #p00 -description does not include #ongoing -description does not include #exclude -``` - -#### Filter Duration -```tasks -not done -path includes 110 🎀 Example Discipline -description includes #15m -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes 110 🎀 Example Discipline -description includes #30m -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes 110 🎀 Example Discipline -description includes #01h -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes 110 🎀 Example Discipline -description includes #02h -description does not include #ongoing -description does not include #exclude -``` - -#### Filter Due -```tasks -not done -path includes 110 🎀 Example Discipline -description does not include #ongoing -description does not include #exclude -``` - -### Blocked -```tasks -not done -path includes 110 🎀 Example Discipline -description includes #p11 -description includes #block -description does not include #exclude -hide task count -``` -```tasks -not done -path includes 110 🎀 Example Discipline -description includes #p10 -description includes #block -description does not include #exclude -hide task count -``` -```tasks -not done -path includes 110 🎀 Example Discipline -description includes #p01 -description includes #block -description does not include #exclude -hide task count -``` -```tasks -not done -path includes 110 🎀 Example Discipline -description includes #p00 -description includes #block -description does not include #exclude -hide task count -``` - -## Resources -```dataview -LIST -FROM #example_discipline - AND -"200 Alignment" - AND -"800 Templates" - AND -"999 Stale" - AND -#note/project -``` \ No newline at end of file +### Archived +- [x] #task (demo) example projects set up #ongoing ✅ 2021-10-07 \ No newline at end of file diff --git "a/100 Disciplines/110 \360\237\216\200 Example Discipline/111 \360\237\214\212 Tasks Example Discipline.md" "b/100 Disciplines/110 \360\237\216\200 Example Discipline/111 \360\237\214\212 Tasks Example Discipline.md" deleted file mode 100644 index 8e286b2..0000000 --- "a/100 Disciplines/110 \360\237\216\200 Example Discipline/111 \360\237\214\212 Tasks Example Discipline.md" +++ /dev/null @@ -1,11 +0,0 @@ ---- -aliases: 🌊 Tasks Example Discipline -tags: [ note/data, example_discipline ] ---- -[[110 🎀 Example Discipline]] | [[112 💡 Ramblings Example Discipline]] -# 🌊 Tasks Example Discipline -## Raw -- [ ] #task #p01 #30m plan a next project for this discipline #ongoing - -## Archived -- [x] #task #p01 #15m example projects set up #ongoing ✅ 2021-10-07 \ No newline at end of file diff --git "a/100 Disciplines/110 \360\237\216\200 Example Discipline/112 \360\237\222\241 Ramblings Example Discipline.md" "b/100 Disciplines/110 \360\237\216\200 Example Discipline/112 \360\237\222\241 Ramblings Example Discipline.md" deleted file mode 100644 index 1df5774..0000000 --- "a/100 Disciplines/110 \360\237\216\200 Example Discipline/112 \360\237\222\241 Ramblings Example Discipline.md" +++ /dev/null @@ -1,9 +0,0 @@ ---- -aliases: 💡 Ramblings Example Discipline -tags: [ note/data, example_discipline ] ---- -[[110 🎀 Example Discipline]] | [[111 🌊 Tasks Example Discipline]] -# 💡 Ramblings Example Discipline -## some date -### topic of rambling -ramblings yada yada yada \ No newline at end of file diff --git "a/100 Disciplines/110 \360\237\216\200 Example Discipline/Example Project/00 \360\237\216\201 Example Project.md" "b/100 Disciplines/110 \360\237\216\200 Example Discipline/Example Project/00 \360\237\216\201 Example Project.md" deleted file mode 100644 index 38ed4fd..0000000 --- "a/100 Disciplines/110 \360\237\216\200 Example Discipline/Example Project/00 \360\237\216\201 Example Project.md" +++ /dev/null @@ -1,192 +0,0 @@ ---- -aliases: 🎁 Example Project -tags: [ note/dashboard, note/project, example_discipline ] -discipline: [[110 🎀 Example Discipline]] -status: 00 Ongoing -start: 2021-10-02 -due: -end: -priority: 00 -objective: one sentence explaining what this project is, why it is needed, and how it's to be done ---- -[[110 🎀 Example Discipline]] | [[01 🌊 Tasks Example Project]] | [[02 💡 Ramblings Example Project]] -# 🎁 Example Project -```dataview -TABLE WITHOUT ID objective as "Objective", default(date(end), date(today)) - date(start) as "Ongoing" -WHERE file.name = this.file.name -``` - -## Abstract -Brief description of what is this project, why it came to be, and how it's going to be conducted. - -## Completion Criteria -**This project is considered complete when the following Requirements are met.** -Create a general Completion Criteria checklist and then start grouping them under `#cc/` tags to later tag related Tasks. - -## [[01 🌊 Tasks Example Project|Tasks]] -### Ongoing (3) -#### Filter Priority -```tasks -not done -path includes Example Project -description includes #ongoing -description includes #p11 -description does not include #exclude -``` -```tasks -not done -path includes Example Project -description includes #ongoing -description includes #p10 -description does not include #exclude -``` -```tasks -not done -path includes Example Project -description includes #ongoing -description includes #p01 -description does not include #exclude -``` -```tasks -not done -path includes Example Project -description includes #ongoing -description includes #p00 -description does not include #exclude -``` - -#### Filter Due -```tasks -not done -path includes Example Project -description includes #ongoing -description does not include #exclude -``` - -### Backlog -#### Filter Priority -```tasks -not done -path includes Example Project -description includes #p11 -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes Example Project -description includes #p10 -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes Example Project -description includes #p01 -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes Example Project -description includes #p00 -description does not include #ongoing -description does not include #exclude -``` - -#### Filter Duration -```tasks -not done -path includes Example Project -description includes #15m -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes Example Project -description includes #30m -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes Example Project -description includes #01h -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes Example Project -description includes #02h -description does not include #ongoing -description does not include #exclude -``` - -#### Filter CC -##### #cc/ -```tasks -not done -path includes Example Project -description includes #cc/ -description does not include #exclude -``` -##### Untagged -```tasks -done -path includes Example Project -description does not include #cc/ -``` - -### Blocked -```tasks -not done -path includes Example Project -description includes #p11 -description includes #block -description does not include #exclude -``` -```tasks -not done -path includes Example Project -description includes #p10 -description includes #block -description does not include #exclude -``` -```tasks -not done -path includes Example Project -description includes #p01 -description includes #block -description does not include #exclude -``` -```tasks -not done -path includes Example Project -description includes #p00 -description includes #block -description does not include #exclude -``` - -### Completed -#### Filter Today -```tasks -done today -path includes Example Project -``` - -## Resources -This is where you can link all the notes and resources you may need to do this project. - -## Retrospection -**What worked well with on this Project?** - - -**What didn't work well on this Project?** - - -**How can the next Project work better?** - - -**In the end, does this Project align well and make progress towards a Discipline?** diff --git "a/100 Disciplines/110 \360\237\216\200 Example Discipline/Example Project/01 \360\237\214\212 Tasks Example Project.md" "b/100 Disciplines/110 \360\237\216\200 Example Discipline/Example Project/01 \360\237\214\212 Tasks Example Project.md" deleted file mode 100644 index 6773362..0000000 --- "a/100 Disciplines/110 \360\237\216\200 Example Discipline/Example Project/01 \360\237\214\212 Tasks Example Project.md" +++ /dev/null @@ -1,15 +0,0 @@ ---- -aliases: 🌊 Tasks Example Project -tags: [ note/data ] ---- -> Make sure you set the YAML `tags` correctly so queries work. Delete this when set. - -[[00 🎁 Example Project]] | [[02 💡 Ramblings Example Project]] -# 🌊 Tasks Example Project -## Raw -- [ ] #task #p01 #30m this is something i plan to do right now #ongoing -- [ ] #task #p01 #30m planned but can't get to it yet -- [ ] #task #p11 #30m something that should be handled immediately - -## Archived -- [ ] Archived tasks go here \ No newline at end of file diff --git "a/100 Disciplines/110 \360\237\216\200 Example Discipline/Example Project/02 \360\237\222\241 Ramblings Example Project.md" "b/100 Disciplines/110 \360\237\216\200 Example Discipline/Example Project/02 \360\237\222\241 Ramblings Example Project.md" deleted file mode 100644 index 98493b5..0000000 --- "a/100 Disciplines/110 \360\237\216\200 Example Discipline/Example Project/02 \360\237\222\241 Ramblings Example Project.md" +++ /dev/null @@ -1,11 +0,0 @@ ---- -aliases: 💡 Ramblings Example Project -tags: [ note/data ] ---- -> Make sure you set the YAML `tags` correctly so queries work. Delete this when set. - -[[00 🎁 Example Project]] | [[01 🌊 Tasks Example Project]] -# 💡 Ramblings Example Project -## some date -### topic of rambling -ramblings yada yada yada \ No newline at end of file diff --git "a/100 Disciplines/110 \360\237\216\200 Example Discipline/Setup/00 \360\237\247\260 Setup.md" "b/100 Disciplines/110 \360\237\216\200 Example Discipline/Setup/00 \360\237\247\260 Setup.md" new file mode 100644 index 0000000..b3f5e93 --- /dev/null +++ "b/100 Disciplines/110 \360\237\216\200 Example Discipline/Setup/00 \360\237\247\260 Setup.md" @@ -0,0 +1,44 @@ +--- +aliases: 🧰 Setup +tags: [dashboard, project] +--- +[[110 🎀 Example Discipline]] +# 🧰 Setup +## Abstract +This is a bottom-up approach for personal exploration to setup LDP. You will be shown several questions. Please answer them the best you can. Fear not, no one will see your answers, they are yours and yours only (unless you share them, of course). + +> **You do not need to follow the tasks to set up LDP. So long as you understand the philosophy and core components (and probably meet the Completion Critera below), you will be fine** + +## Objective +Have a better understanding of your own life. + +## Completion Criteria +**This project is considered complete when the following Requirements are met.** +- [ ] [[99 💗 Life|💗 Life]] has been defined + - [ ] Life have Pillars + - [ ] Life have an emerging Dynamic +- [ ] Disciplines have been thought of + - [ ] Various folders to house work related to Disciplines have been created +- [ ] Dashboard exists for Disciplines + - [ ] Disciplines have Pillars + - [ ] Disciplines have an emerging Dynamic +- [ ] At least 1 Discipline is noted to be your [[Ikigai]] + +## Tasks +- [ ] #task Check out [[00 ❗ Readme|❗ Readme]] #ongoing +- [ ] #task Start and finish [[10 💗 Defining Life]] +- [ ] #task Define your [[10 💗 Defining Life#Life Pillars]] +- [ ] #task Define your [[10 💗 Defining Life#Life Dynamic]] +- [ ] #task Finalize [[10 💗 Defining Life#Life Pillars]] and [[10 💗 Defining Life#Life Dynamic]] +--- +- [ ] #task Start and finish [[11 🔀 Divergence to Disciplines]] +- [ ] #task Created Disciplines and their Dashboard +- [ ] #task Defined Discipline's Abastract +--- +- [ ] #task Start and finish [[12 🔂 Convergence to Ikigai]] +- [ ] #task Setup YAML frontmatter for Disciplines +--- +- [ ] #task Start and finish [[13 🎎 Ikigai Expansion]] +- [ ] #task Completed [[13 🎎 Ikigai Expansion#The Past]] +- [ ] #task Completed [[13 🎎 Ikigai Expansion#The Present]] +- [ ] #task Completed [[13 🎎 Ikigai Expansion#The Future]] \ No newline at end of file diff --git "a/100 Disciplines/110 \360\237\216\200 Example Discipline/Setup/10 \360\237\222\227 Defining Life.md" "b/100 Disciplines/110 \360\237\216\200 Example Discipline/Setup/10 \360\237\222\227 Defining Life.md" new file mode 100644 index 0000000..fafe363 --- /dev/null +++ "b/100 Disciplines/110 \360\237\216\200 Example Discipline/Setup/10 \360\237\222\227 Defining Life.md" @@ -0,0 +1,64 @@ +--- +aliases: 💗 Defining Life +tags: [ data ] +--- +# 💗 Defining Life +## Preface +These notes in this folder is a guided setup on how to define your Life Pillars, Life Dynamic, and relevant Disciplines. These elements are what all action moving forward will work towards. You should set these up first, as Disciplines may be difficult to adjust later, especially if you're unfamiliar with Obsidian and its community plugins. + +You do not have to go through all steps of this document, especially when things seem trivial. The only exception is that you must set up Disciplines. + +If you're just giving this framework a try, feel free to speedily go through the motion. Alternatively, skip to [[11 🔀 Divergence to Disciplines#Next Steps]] to set up Disciplines. + +## Life Pillars +Life Pillars are [[Pillars]] under the context of everyday Life. They are extremely personalized and give Life meaning and direction. They should be defined in the most generalized, fundamental form as possible. + +> In other words, your objective is not that you not need a hammer and nail to hang a picture, it's that you need to make something visible. + +You can have any amount of Life Pillars, but do consider having just a handful so you can always remember them. + +Your Life Pillars also may not reflect you now, and that's fine. As a matter of fact, it's better to define these Life Pillars to be what you want to become. + +### What To Do +Go to [[99 💗 Life#Life Pillars]] and just start defining your Life Pillars. It doesn't matter if you don't have a firm idea. You just have to start externalizing, you will reach it naturally, with time. + +Some example of pillars are as follows. +- Be a good human-being +- Family (or friends) first +- Pay all forms of debt, including social debt + +Be sure to elaborate on what you mean by the pillar, as well as expand on this pillar's relevance and importance to yourself. + +If you're stuck generating your Life Pillars, consider how you personally feel about some of the questions below. If applicable, consider their opposite, and question if it's something that should even matter to begin with. +- How do you love? +- What does the world need? +- What is your version of hell? Of heaven? +- What does it mean to live? +- How do you give back to the world? +- What are your limits? +- What does it mean to be human? +- What deserves respect and appreciation? +- What comes first? +- Do you value the journey or the end? +- What do you want before you die? +- Why are you even doing this right now? + +## Life Dynamic +Life Dynamic is the emerging result of the combined effects of your Life Pillars. Pillars are the founding principles of what make you, you. They all pull you towards some direction, and this direction should agree with what you want. You could consider this your personality. That being said, your Life Dynamic should align with the Life Pillars you defined above. + +Your Life Discipline should be summarized into one sentence, and should thoroughly describe a personality. This is a personality that you currently are or strive to be. + +See [[Dynamics]] for more details on Dynamics. + +### What To Do +Determine the emerging result of your Pillars. Define this under [[99 💗 Life#Life Dynamic]]. + +## Another Iteration +Take a short break. + +- [ ] I took a break to refresh my mind to have a fresh perspective when I come back + +Look over your Life Pillars and Life Dynamic. Really ponder over if you agree with everything. Make revisions as needed. + +## Next Steps +With your fundamental life principles out of the way, you can now define direction towards them. See [[11 🔀 Divergence to Disciplines|🔀 Divergence to Disciplines]]. \ No newline at end of file diff --git "a/100 Disciplines/110 \360\237\216\200 Example Discipline/Setup/11 \360\237\224\200 Divergence to Disciplines.md" "b/100 Disciplines/110 \360\237\216\200 Example Discipline/Setup/11 \360\237\224\200 Divergence to Disciplines.md" new file mode 100644 index 0000000..7c9b9cc --- /dev/null +++ "b/100 Disciplines/110 \360\237\216\200 Example Discipline/Setup/11 \360\237\224\200 Divergence to Disciplines.md" @@ -0,0 +1,93 @@ +--- +aliases: 🔀 Divergence to Disciplines +tags: [ data ] +--- +# 🔀 Divergence to Disciplines +This document serves to explore understand what's important and relevant to your life in the form of Disciplines. This will also help you set up the initial files and folders for this system of Life Discipline Projects. + +## Initial Thinking +[[Disciplines]] are the context in which action will be taken to mobilize yourself and generate velocity towards your Life Dynamic and Life Pillars. These contexts can be as broad as the study and practice of **Health** to the *specifics* of **Ramen Noodles**. It's mainly a matter of depth and perspective. To an extremely nuanced individual, they may see the latter Ramen Noodles as something flawed with infinite room for improvement. + +That being said, how you scope and define your Disciplines is entirely up to its relevance and importance to you. They should at least be scoped wide enough such that, in the end, all Disciplines have no major overlap in context. That is, Mental Health and Physical Health should be merged into Health because both directly affect each other. + +Some examples of Disciplines might be as follows. +- **Well-being**: includes all aspects of health, happiness, longevity, and quality of life +- **Finance**: because money is money +- **Human**: to better understand what it means to be a good human being +- **Art**: catch-all for all your creative outlooks + +The Discipline must be relevant and important to you. + +> Try to keep the number of Disciplines you generate in the single digits. Reaching double digits, or even getting close to it, means that you need to combine the Disciplines more. Imagine having to always maintain your skills for 9 completely different instruments where the skills don't transfer from one instrument to the other, and the note scales differs on each. Just combine them to a generic "Music" to make room for other Disciplines. The only exception is when you are literally the exception. + +## Exploration by Diverging Ideas +Here, we will begin to explore some fundamental driving forces of what usually makes a Discipline fulfilling, by means of [[Ikigai]]. Remember, this is what *you* believe, not what others believe. Take as much or as little time as needed, just know what's important to you. **Always take into account your Life Pillars and Life Disciplines.** + +### Love +#### What does it mean to love an everyday idea and activity? It may help to define the opposite as well. +`Answer` + +#### Using your answer above, what are the everyday ideas or activities you love? What is it that you love about it? Try to make the activities unique from each other. +`Answer` + +### Skill +#### What is your definition of being skilled at something? +`Answer` + +#### Using that definition, what are some skills that you have? How are you skilled? List and scope these skills as general or as specific as you'd like. Try not have skillsets overlap each other. +`Answer` + +### Money +#### What items you can make or services you can provide that you think someone would pay for? Why would someone pay for it +`Answer` + +#### What is your definition of being minimally financially stable? +`Answer` + +#### Using that definition, what activities can you semi-confidently say will make you reach that minimally financially stability? +`Answer` + +#### In the far future, you probably have greater ideas (e.g. Family, Housing, Cars, etc). What activities do you think will actually help you reach them within a reasonable timeframe? +`Answer` + +### World +#### What do you know the world needs? +`Answer` + +#### What do you think is missing, but the world has not yet realized? +`Answer` + +#### Using your answers above, what activities do you believe fulfill the needs of the world? How so? +`Answer` + +## Condensing to Disciplines +**Review all of your answers above. Below, generate a list of activities that you found to be relevant and important. Feel free to delete duplicates and rename activities as needed.** +`Answer` + +**Please review [[Disciplines#Scoping|Discipline]] and [[Ikigai]]. Iterate on your list above and start to group them into generic but dinstinct Disciplines. You may find it useful if you use the some kind of Card Sorting. A Kanban Board may be useful here.** +`Answer` + +**Go take a break, preferably full day and minimally a meal break.** +- [ ] I took a break to refresh my mind to have a fresh perspective when I come back + +**Copy and paste your groupings above, below. Please review and adjust accordingly. Feel free to rename the Disciplines, add new relevant and important activities/ideas, etc. Remember, you want single digit Discilines with distinct skillsets required in each.** +`Answer` + +## Finalizing +**What are your finalized, grouped Disciplines from this exercise? What characteristics of Ikigai do these Disciplines have (love, world, money, skill)?** +`Answer` + +## Initial Creation +When you are done, make folders for Disciplines under `100 Disciplines/`. Consider naming them following [[00 ❗ Readme#Folder Naming]], but just consider it, don't do it quite yet. You may find that you want it ordered differently after finishing setup. + +Once the folder is created, create a Dashboard that will serve as the master note for that Discipline. Name it whatever you want, but I suggest havng it the same as the folder name. + +## Fleshing Disciplines +For each Discipline dashboard, add minimally the following information. +- A short abstract of what this discipline is +- Why and how this discipline is relevant and important + +Feel free to add more. Pillars and Dynamics are not required at the moment. + +## Next Steps +You now have direction for meeting and sustaining your Life Pillars. But your lifetime has limited time and effort. You need to have a focused Discipline; something that gives your live meaning. See [[12 🔂 Convergence to Ikigai|Convergence to Ikigai]] \ No newline at end of file diff --git "a/100 Disciplines/110 \360\237\216\200 Example Discipline/Setup/12 \360\237\224\202 Convergence to Ikigai.md" "b/100 Disciplines/110 \360\237\216\200 Example Discipline/Setup/12 \360\237\224\202 Convergence to Ikigai.md" new file mode 100644 index 0000000..38ff79e --- /dev/null +++ "b/100 Disciplines/110 \360\237\216\200 Example Discipline/Setup/12 \360\237\224\202 Convergence to Ikigai.md" @@ -0,0 +1,154 @@ +--- +aliases: [▶ Convergence to Ikigai,98 ▶ Convergence to Ikigai,Convergence to Ikigai] +tags: [ data ] +--- +# 🔂 Convergence to Ikigai +This document serves to condense your Disciplines and define your single (or very small set) of [[Ikigai]]. + +> Make sure you view this in preview mode so the dataview codeblocks render properly. + +To start with, for each Discipline, please make sure you answer the section **`Importance and Relevance.`** + +## Required Setup +From the previous step [[11 🔀 Divergence to Disciplines#Finalizing]], for each Discipline you should have defined their ikigai characteristics. + +In the top of the Discipline Dashboards, add the following to the YAML frontmatter. +``` +ikigai: + - +``` + +> Note that the indent is two spaces, not tab. + +Now start to list values to mirror what you its ikigai characteristics. For example, if you have a discipline you `love` and can be paid in `money`, it should look like the following on the to top of the note + +```YAML +--- +ikigai: + - love + - money +--- +``` + +Other valid values you can list are `world` and `skill`. + +Once you've done this for all disciplines, you are now ready to gain insight on your Disciplines towards your Ikigai. + +## Your Life Through Disciplines +### Fundamental +This is the basis of what gives meaning to you. Everything else will build off of these fundamentals. + +#### Love +```dataview +TABLE WITHOUT ID link(file.name, file.aliases) as "Discipline" +FROM "100 Disciplines" +WHERE contains(tags, "discipline") and contains(ikigai, "love") +``` +#### World +```dataview +TABLE WITHOUT ID link(file.name, file.aliases) as "Discipline" +FROM "100 Disciplines" +WHERE contains(tags, "discipline") and contains(ikigai, "world") +``` +#### Money +```dataview +TABLE WITHOUT ID link(file.name, file.aliases) as "Discipline" +FROM "100 Disciplines" +WHERE contains(tags, "discipline") and contains(ikigai, "money") +``` +#### Skill +```dataview +TABLE WITHOUT ID link(file.name, file.aliases) as "Discipline" +FROM "100 Disciplines" +WHERE contains(tags, "discipline") and contains(ikigai, "skill") +``` + +### Dynamic 1 +This is the first layer of the emerging effect of 2 fundamental characteristics. + +#### Mission +Defined as what you love and what the world needs. +```dataview +TABLE WITHOUT ID link(file.name, file.aliases) as "Discipline" +FROM "100 Disciplines" +WHERE contains(tags, "discipline") and contains(ikigai, "love") and contains(ikigai, "world") +``` +#### Vocation +Defined as what the world needs and what you can be paid for. +```dataview +TABLE WITHOUT ID link(file.name, file.aliases) as "Discipline" +FROM "100 Disciplines" +WHERE contains(tags, "discipline") and contains(ikigai, "money") and contains(ikigai, "world") +``` +#### Profession +Defined as what you can be paid for and what you are skilled at. +```dataview +TABLE WITHOUT ID link(file.name, file.aliases) as "Discipline" +FROM "100 Disciplines" +WHERE contains(tags, "discipline") and contains(ikigai, "love") and contains(ikigai, "money") +``` +#### Passion +Defined as what you are skilled at and what you love. +```dataview +TABLE WITHOUT ID link(file.name, file.aliases) as "Discipline" +FROM "100 Disciplines" +WHERE contains(tags, "discipline") and contains(ikigai, "love") and contains(ikigai, "skill") +``` + +### Dynamic 2 +These are the second emerging layer of 3 fundamental characteristics. These are Disciplines that are almost there, but are missing something to feel complete. + +#### Useless Satisfaction +These are the cool things in life that don't serve a higher purpose other than being cool. You love these things, they make you money, and you're skilled in it, but that's all to it. +```dataview +TABLE WITHOUT ID link(file.name, file.aliases) as "Discipline" +FROM "100 Disciplines" +WHERE contains(tags, "discipline") and contains(ikigai, "love") and contains(ikigai, "skill") and contains(ikigai, "money") and !contains(ikigai, "world") +``` + +#### Empty Comfort +You can think of these as things you need to do, but aren't particularly fond of. They get the bills paid, you're genuinely being useful to others, and you just happen to be good at it. +```dataview +TABLE WITHOUT ID link(file.name, file.aliases) as "Discipline" +FROM "100 Disciplines" +WHERE contains(tags, "discipline") and contains(ikigai, "world") and contains(ikigai, "skill") and contains(ikigai, "money") and !contains(ikigai, "love") +``` + +#### Uncertain Excitement +These are things that you know are genuinely useful, that you love, and that you know you can be compensated for. However, you have yet to acquire the skills required to do so. **This is something you can aim for with sufficient training.** +```dataview +TABLE WITHOUT ID link(file.name, file.aliases) as "Discipline" +FROM "100 Disciplines" +WHERE contains(tags, "discipline") and contains(ikigai, "world") and contains(ikigai, "love") and contains(ikigai, "money") and !contains(ikigai, "money") +``` + +#### Valueless Delight +You love doing these things. People understand its significance and recognize that you're a pioneer at this. However, they this is something that isn't really sustainable financially. +```dataview +TABLE WITHOUT ID link(file.name, file.aliases) as "Discipline" +FROM "100 Disciplines" +WHERE contains(tags, "discipline") and contains(ikigai, "skill") and contains(ikigai, "love") and contains(ikigai, "money") and contains(ikigai, "money") and !contains(ikigai, "world") +``` + +### Potential Ikigai +Below are your primary driving forces of life, your Ikigai. They are things you love, what the world needs, what you get money for, and what you are skilled at. +```dataview +TABLE WITHOUT ID link(file.name, file.aliases) as "Discipline" +FROM "100 Disciplines" +WHERE contains(tags, "discipline") and length(ikigai) = 4 +``` + +## Selecting your Ikigai(s) +You may find that you have multiple Ikigai. However, it's important to direct your attention to one, if not a very sparse amount, at a time. Truly touching and exercising all fundamental characteristics of a Discipline to sustain Ikigai takes commitment, requiring your limited time and effort. If you find you have multiple, it's best they share at some common ground, whether it be context or skillset. + +> While it's possible to choose Disciplines that are not Potential Ikigais, understand that it will require the initial investment of time and effort to fulfill the missing Ikigai characteristics. + +Now's the time to also reflect on what you wrote down under the Discipline's **`Importance and Relevance`** section. + +**So, what will be your Primary Ikigai(s)?** +`Answer` + +> I suggest you add a note tag: `#ikigai` to that dashboard, or at least note it under [[99 💗 Life|700 Life]] what your Ikigai is. + +## Next Steps +Your Ikigai is now set. This will be your focus moving forwards. Your Ikigai may change in the future, and if so you can always come back here. But we need to take action now. We need to further understand what makes this Ikigai Discipline resonate with us. See [[13 🎎 Ikigai Expansion|🎎 Ikigai Expansion]] \ No newline at end of file diff --git "a/100 Disciplines/110 \360\237\216\200 Example Discipline/Setup/13 \360\237\216\216 Ikigai Expansion.md" "b/100 Disciplines/110 \360\237\216\200 Example Discipline/Setup/13 \360\237\216\216 Ikigai Expansion.md" new file mode 100644 index 0000000..fce298c --- /dev/null +++ "b/100 Disciplines/110 \360\237\216\200 Example Discipline/Setup/13 \360\237\216\216 Ikigai Expansion.md" @@ -0,0 +1,69 @@ +--- +aliases: 🎎 Ikigai Expansion +tags: [ data ] +--- +# 🎎 Ikigai Expansion +Based on your process from on [[12 🔂 Convergence to Ikigai|🔻 Convergence to Ikigai]], this is your chosen Ikigai(s). +```dataview +TABLE WITHOUT ID + link(file.name, default(aliases, name)) as "Chosen Ikigai" +FROM #ikigai +``` + +> This query only works if you tagged that note with `#ikigai` + +We will now begin to expand on them below. Make sure you minimally defined the abstract for your Ikigai. Relevance and Importance is useful but not required, as it will be further expanded here. + +## Your Choice +### Why did you decide to choose this Discipline as your Ikigai? +`Answer` + +## The Past +For this Discipline, do you feel like you or the world meets all the Ikigai characteristics? Be thorough. Ikigai characteristics framed as questions are as follows. +### What brought you to love? +`Answer` + +### What have you gone through to be like this in this field? +`Answer` + +### What has the world gone through to need it? +`Answer` + +### How has it come to the point that people are paying for it? +`Answer` + +### Objectively, from an outsider looking in, would they agree with what you said above? Consider asking another person. +`Answer` + +## The Present +### Start to define your Ikigai's Pillars and Dynamic. Do your current view of your Ikigai Discipline's Pillars align with your Life Pillars? What about their Dynamics? Do you think this is a good thing? Why? +`Answer` + +### Are you partaking in this Discipline yet? What are you doing? +`Answer` + +### If you're not partaking in it, what's blocking you from actively pursuing this Discipline? What can you do right now? +`Answer` + +## The Future +### Long-term goals are a double-edged sword because once they are met, velocity and direction disappear. One solution is to play the infinite game. This is a lesson from Simon Sinek's book, The Infinite Game, which observes that naive business operate towards an end-goal, but the most successful operate as an infinite game. Does your Ikigai Discipline have pillars and a discipline that have considered infinite potential for growth?** +`Answer` + +> If your answer does not allow room for sufficient growth, especially over your lifetime, you should reconsider redefining this Discipline. + +### What will you do right now to make velocity towards your Ikigai Discipline? +`Answer` + +## Epilogue +This is the end of this exploratory life exploration setupf or LDP. You should a diverse set of Disciplines under your belt that you can now create Projects off of. Consider doing another pass on the Disciplines to define all of their Pillars and Dynamics if not already done. + +> You also should have noticed that your Ikigai Discipline should have mostly aligned with your Life Pillars. If they are not, it may cause some conflict in the future. + +You can archive `Setup` into `900 Archive/Projects` for historical data. + +Start making Projects that align with Disciplines to create velocity towards your Life Pillars and Dynamic. They should have a Dashboard as well, which should deine the project's Objective and completion criteria. + +## Support or just to say Thanks +Please consider following me on [twitter](https://twitter.com/uwidev). Also consider donating to me on [ko-fi](https://ko-fi.com/uwidev). + +I hope you at discovered something new about yourself after this setup process. Have a good one and take it easy; you have plenty of time. \ No newline at end of file diff --git a/200 Alignment/210 Daily/2021-10-06 Stand-up.md b/200 Alignment/210 Daily/2021-10-06 Stand-up.md deleted file mode 100644 index 9f2888a..0000000 --- a/200 Alignment/210 Daily/2021-10-06 Stand-up.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -tags: [ note/data ] ---- -[[2021-10-05> Stand-up]] | [[2021-10-06|Ramblings]] | [[2021-10-07 Stand-up]] -# 2021-10-06 Wednesday Stand-up -## Review -### Projects you touched yesterday -```dataview -TABLE status as "Status", - due as "Due", - priority as "Priority" -FROM #note/project -WHERE file.mtime >= date(2021-10-06) - dur(1 days) and file.mtime < date(2021-10-06) and due != null -SORT status, due asc, urgent asc, important asc -``` - -### Tasks you completed yesterday -```tasks -done 2021-10-05 -description includes #p11 -description does not include #exclude -``` -```tasks -done 2021-10-05 -description includes #p10 -description does not include #exclude -``` -```tasks -done 2021-10-05 -description includes #p01 -description does not include #exclude -``` -```tasks -done 2021-10-05 -description includes #p00 -description does not include #exclude -``` -![[2021-10-05 Stand-up#Alignment]] - -### Notes you dealt with yesterday -#### Created -```dataview -LIST -FROM -"Journal" -WHERE file.ctime > date(2021-10-05) and file.ctime < date(2021-10-05) + dur(1 days) -``` - -#### Last Modified -```dataview -LIST -FROM -"Journal" -WHERE file.mtime > date(2021-10-05) and file.mtime < date(2021-10-05) + dur(1 days) -limit 20 -``` - -### Review your blocked items -```tasks -not done -description includes #blocked -``` -```tasks -not done -description includes #blocking -``` -![[2021-10-05 Stand-up#Is anything blocking your work? If so, why?]] - -### Ramblings you did yesterday -![[2021-10-05#2021-10-05 Tuesday Ramblings]] - -## Stand-up -### What did you manage to get done yesterday? -[[Tasks Completed Yesterday]] - -`Explicitly respond here.` - -### What is your focus today? -[[Tasks Ongoing]] [[OLD Backlog]] - -`Answere here. This should be a general focus, not specific tasks.` - -#### Alignment -[[Ongoing Project Reference]] -**Does this focus still Align to its Project's Objective? How and why?** -`Answer here.` - -**Does this Project's Completion Criteria still Align with its Objective?** -`Answer here.` - -### Is anything blocking your work? If so, why? -[[00 🏠 Main Dashboard#Blocked]] - - - -## Next Steps -- [x] #task #p01 #15m Complete [[2021-10-06 Stand-up]] ✅ 2021-10-06 - -Mark as completed and adjust time to reflect how long this took you. Then proceed to [[2021-10-06|Today's Ramblings]]. \ No newline at end of file diff --git a/200 Alignment/210 Daily/2021-10-06.md b/200 Alignment/210 Daily/2021-10-06.md deleted file mode 100644 index 97711aa..0000000 --- a/200 Alignment/210 Daily/2021-10-06.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -tags: [ note/data ] -general: - work_minutes_completed: 120 - focus: 7 ---- -[[2021-10-05]] | [[2021-10-06 Stand-up|Stand-up]] | [[2021-10-07]] -# 2021-10-06 Wednesday Ramblings -> Meaning is something you build into your life. You build it out of your own past, out of your affections and loyalties, out of the experience of humankind as it is passed on to you... You are the only one who can put them together into that unique pattern that will be your life. -> — John Gardner - -`Your opinions on this quote here.` - ---- - -`Other ramblings go here` \ No newline at end of file diff --git a/200 Alignment/220 Weekly/2021-W41.md b/200 Alignment/220 Weekly/2021-W41.md deleted file mode 100644 index 11f08ff..0000000 --- a/200 Alignment/220 Weekly/2021-W41.md +++ /dev/null @@ -1,189 +0,0 @@ ---- -tags: [ note/data ] ---- -[[2021-W40]] | [[2021-W42]] -# 2021-W41 -## Fun -**Copy and paste the first quote within last quarter (<= 3 months ago) from [/r/quotes: For your favorite quotes](https://www.reddit.com/r/quotes/top/?t=year). -** -> Quote goes here -> — Author - -`Your opnions on this quote here. Why do you think became the weekly top?` - -## Review -![[2021-W40#Analysis]] -![[2021-W40#Reflection]] -![[2021-W40#Concerns]] -![[2021-W40#Ramblings]] - -## Performance -### Projects -```dataview -TABLE WITHOUT ID - link(file.name, default(aliases, file.name)) as "Project", - status as "Status", - file.mtime as "Last Modified" -FROM #note/project -WHERE start >= date(2021-10-04) - and start < date(2021-10-11) + dur(1 day) - or end >= date(2021-10-04) - and end < date(2021-10-11) + dur(1 day) - or file.mtime > date(2021-10-04) - and file.mtime < date(2021-10-11) + dur(1 day) -SORT file.mtime desc -``` - -### Tasks -##### Filter None -```tasks -done after 2021-10-03 -done before 2021-10-11 -description does not include #note/project -hide edit button -``` - -##### Filter Priority -###### p11 -```tasks -done after 2021-10-03 -done before 2021-10-11 -description includes #p11 -description does not include #note/project -hide edit button -``` -###### p10 -```tasks -done after 2021-10-03 -done before 2021-10-11 -description includes #p10 -description does not include #note/project -hide edit button -``` -###### p01 -```tasks -done after 2021-10-03 -done before 2021-10-11 -description includes #p01 -description does not include #note/project -hide edit button -``` -###### p00 -```tasks -done after 2021-10-03 -done before 2021-10-11 -description includes #p00 -description does not include #note/project -hide edit button -``` - -##### Filter Duration -###### 02h -```tasks -done after 2021-10-03 -done before 2021-10-11 -description includes #02h -description does not include #note/project -hide edit button -``` -###### 01h -```tasks -done after 2021-10-03 -done before 2021-10-11 -description includes #01h -description does not include #note/project -hide edit button -``` -###### 30m -```tasks -done after 2021-10-03 -done before 2021-10-11 -description includes #30m -description does not include #note/project -hide edit button -``` -###### 15m -```tasks -done after 2021-10-03 -done before 2021-10-11 -description includes #15m -description does not include #note/project -hide edit button -``` - -### Analysis -**How much work in minutes did it did you complete last week? Does this amount seem realistic? If you worked every day for 8 hours for 7 days, you would have worked 56 hours, or 3,360 minutes. If you had part-time for 4 days which cut working hours down to 4 hours, you would have worked 1,920 minute.** -[[Work-Minutes Last 7 Days]] -`Answer here.` - -**How does this work compare to the previous week? Do you think the difference is significant?** -[[Work-Minutes Last 7-14 Days]] -`Answer here.` - -### Reflection -**What do you think worked this week to get that much work done?** -`Answer here.` - -**What do you think didn't work well this week to get that much work done?** -`Answer here.` - -**How can you potentially increase Velocity (get more work done)?** -`Answer here.` - -**What would stunt this increase, or even lower Velocity?** -`Answer here.` - -**What's the likelihood of this concern occurring?** -`Answer here.` - -**How much of an impact would this stunt or lowering Velocity?** -`Answer here.` - -**What will you do to prevent or mitigate the stunting or lowering when it happens?** -`Answer here.` - -## Alignment -```dataview -TABLE WITHOUT ID - link(file.name, default(link(file.name).aliases, file.name)) as "Project", - objective as "Objective", - link(discipline, link(discipline).aliases) as "Discipline" -FROM #note/project and -"Templates" -WHERE file.mtime >= date(2021-10-04) and file.mtime < date(2021-10-11) + dur(1 day) -SORT due asc -``` -```dataview -TABLE WITHOUT ID - link(file.name, default(link(file.name).aliases, link(file.name).name)) as "Discipline", - pillars as "Pillars", - dynamic as "Dynamic" -FROM #note/discipline and -"Templates" -WHERE file.mtime >= date(2021-10-04) and file.mtime < date(2021-10-11) + dur(1 day) -SORT due asc -``` -**For each [[Projects|Project]] that you touched last week, does its Objective still align with most of its [[Disciplines|Discipline]] [[Pillars]]? Does the Objective align with the Discipline Dynamic? How and why?** -[[Projects Touched Last Week]] -[[Project-Disciplines Touched Last Week]] -### `Project 1` -`Answer here.` - -### `Project 2` -`Answer here.` - -## Concerns -**What are at least two things to worry about next week?** -1. What's the likelihood of this concern occurring? -2. How would this impact you? -3. What will you do to prevent this from happening, or at least mitigate the damage when it occurs? - -### Concern 1: `Title of Concern` -`Elaborate concern here` - -### Concern 2: `Title of Concern` -`Elaborate concern here` - -- [x] #task #p01 #30m Complete [[2021-W41]] ✅ 2021-10-06 - -## Ramblings -`Other Ramblings go here.` - diff --git a/200 Alignment/230 Monthly/2021-10.md b/200 Alignment/230 Monthly/2021-10.md deleted file mode 100644 index 090f911..0000000 --- a/200 Alignment/230 Monthly/2021-10.md +++ /dev/null @@ -1,182 +0,0 @@ ---- -tags: [ note/data ] ---- -[[2021-09]] | [[2021-11]] -# 2021-10 Ramblings -## Fun -**Copy and paste the first quote from [/r/quotes: For your favorite quotes](https://www.reddit.com/r/quotes/top/?t=month)** - -> Quote goes here -> — Author - -`Your opnions on this quote here. Why do you think became the monthly top?` - -## Review -![[2021-09#Analysis]] -![[2021-09#Reflection]] -![[2021-09#Concerns]] -![[2021-09#Ramblings]] - -## Performance -### Projects -```dataview -TABLE WITHOUT ID - file.link as "Project", - status as "Status", - objective as "Objective", - start as "Start", - end as "End" -FROM #note/project and -"999 Stale" and -"Templates" -WHERE end >= 2021-09-01 - or start >= 2021-09-01 - or end < 2021-10-01 - or start < 2021-10-01 - or file.mtime >= date(2021-09-01) - or file.mtime < date(2021-10-01) -SORT end desc, start desc, status -``` - -### Tasks -##### Filter None -```tasks -done after 2021-08-31 -done before 2021-10-01 -description does not include #note/project -hide edit button -``` - -##### Filter Priority -###### p11 -```tasks -done after 2021-08-31 -done before 2021-10-01 -description includes #p11 -description does not include #note/project -hide edit button -``` -###### p10 -```tasks -done after 2021-08-31 -done before 2021-10-01 -description includes #p10 -description does not include #note/project -hide edit button -``` -###### p01 -```tasks -done after 2021-08-31 -done before 2021-10-01 -description includes #p01 -description does not include #note/project -hide edit button -``` -###### p00 -```tasks -done after 2021-08-31 -done before 2021-10-01 -description includes #p00 -description does not include #note/project -hide edit button -``` - -##### Filter Duration -###### 02h -```tasks -done after 2021-08-31 -done before 2021-10-01 -description includes #02h -description does not include #note/project -hide edit button -``` -###### 01h -```tasks -done after 2021-08-31 -done before 2021-10-01 -description includes #01h -description does not include #note/project -hide edit button -``` -###### 30m -```tasks -done after 2021-08-31 -done before 2021-10-01 -description includes #30m -description does not include #note/project -hide edit button -``` -###### 15m -```tasks -done after 2021-08-31 -done before 2021-10-01 -description includes #15m -description does not include #note/project -hide edit button -``` - -### Analysis -**How much work in minutes did it did you complete last month? Does this amount seem realistic?** -> If you worked every day for 8 hours in a 28 month-day, you would have worked 13,440 minutes. If you had part-time for 4 out of 7 days of the week in that 28 day month, and those part-time days only allowed for 4 hours of work, you would have worked 10,560 minutes. - -[[Work-Minutes Last 1 Months]] -`Answer here.` - -**How does this work compare to the previous months? Do you think this difference is significant?** -[[Work-Minutes Last 1-2 Months]] -`Answer here.` - -### Reflection -**What do you think worked this month to get that much work done?** -`Answer here.` - -**What do you think didn't work well this month to get that much work done?** -`Answer here.` - -**How can you potentially increase Velocity (get more work done)?** -`Answer here.` - -**What would stunt this increase, or even lower Velocity?** -`Answer here.` - -**What's the likelihood of this concern occurring?** -`Answer here.` - -**How much of an impact would this stunt or lowering Velocity?** -`Answer here.` - -**What will you do to prevent or mitigate the stunting or lowering when it happens?** -`Answer here.` - -## Alignment -```dataview -TABLE WITHOUT ID - link(file.name, default(link(file.name).aliases, link(file.name).name)) as "Discipline", - pillars as "Pillars", - dynamic as "Dynamic" -FROM #note/discipline and -"999 Stale" and -"Templates" -SORT due asc -``` -**For each Discipline, how are you feeling about them at the moment? Do they still feel relevant and important through your Life Pillars?** -### `Discipline 1` -`Answer here.` - -### `Discipline 2` -`Answer here.` - -- [ ] #task #p01 #30m Complete [[2021-10 Retrospection]] - -## Concerns -**What are at least two things to worry about next month?** -1. What's the likelihood of this concern occurring? -2. How would this impact you? -3. What will you do to prevent this from happening, or at least mitigate the damage when it occurs? - -### Concern 1: `Title of Concern` -`Elaborate concern here` - -### Concern 2: `Title of Concern` -`Elaborate concern here` - -## Ramblings -`Other Ramblings go here.` - -- [x] #task #p01 #30m Complete [[2021-10]] ✅ 2021-10-06 \ No newline at end of file diff --git a/200 Alignment/240 Quarterly/2021-Q4.md b/200 Alignment/240 Quarterly/2021-Q4.md deleted file mode 100644 index 38f2087..0000000 --- a/200 Alignment/240 Quarterly/2021-Q4.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -tags: [ note/data ] ---- -[[2021-Q3]] | [[2022-Q1]] -# 2021-Q4 -## Fun -**Copy and paste the first quote within last quarter (<= 3 months ago) from [/r/quotes: For your favorite quotes](https://www.reddit.com/r/quotes/top/?t=year). -** -> Quote goes here -> — Author - -`Your opnions on this quote here. Why do you think became the quarterly top?` - -## Performance -### Projects -```dataview -TABLE WITHOUT ID - link(file.name, default(aliases, file.name)) as "Project", - start as "Start", - end as "End", - status as "Status", - link(discipline, default(link(discipline).aliases, file.name)) as Discipline -FROM #note/project -WHERE start >= date(2021-07-01) - and start < date(2021-10-01) + dur(1 day) - or end >= date(2021-07-01) - and end < date(2021-10-01) + dur(1 day) - or file.mtime > date(2021-07-01) - and file.mtime < date(2021-10-01) + dur(1 day) -sort end, status -``` - -## Alignment -```dataview -TABLE WITHOUT ID - pillars as "Life Pillars" -FROM "/" -WHERE contains(file.aliases, "💗 Life") -``` -```dataview -TABLE WITHOUT ID - dynamic as "Life Dynamic" -FROM "/" -WHERE contains(file.aliases, "💗 Life") -``` -```dataview -TABLE WITHOUT ID - link(file.name, default(link(file.name).aliases, link(file.name).name)) as "Discipline", - dynamic as "Dynamic" -FROM #note/discipline and -"900 Archive" and -"Templates" -``` -**For each Discipline, are they still relevant and important towards at least one Life Pillars? Do they allow mobility towards them? Which Life Pillars? How and Why?** - -### Discipline 1 -`Answer` - -### Discipline 2 -`Answer` - -## Adjustment -**Are there any changes that need to be made to your Disciplines? What will be changed, if anything? How and why? If not needed, why?** -`Answer` - -## Ramblings -`Random quarterly ramblings go here` \ No newline at end of file diff --git a/200 Alignment/250 Yearly/2021.md b/200 Alignment/250 Yearly/2021.md deleted file mode 100644 index 83c5f07..0000000 --- a/200 Alignment/250 Yearly/2021.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -tags: [ note/data ] ---- -[[2020]] | [[2022]] -# 2021 -## Fun -**Copy and paste the first quote from [/r/quotes: For your favorite quotes](https://www.reddit.com/r/quotes/top/?t=year). -** -> Quote goes here -> — Author - -`Your opnions on this quote here.` - -## Performance -### Projects -```dataview -TABLE WITHOUT ID - link(file.name, default(aliases, file.name)) as "Project", - start as "Start", - end as "End", - status as "Status", - link(discipline, default(link(discipline).aliases, file.name)) as Discipline -FROM #note/project -WHERE start >= date(2021-01-01) - and start < date(2022-01-01) + dur(1 day) - or end >= date(2021-01-01) - and end < date(2022-01-01) + dur(1 day) - or file.mtime > date(2021-01-01) - and file.mtime < date(2022-01-01) + dur(1 day) -sort end, status -``` - -## Reflection -Here is a generalized Yearly Reflection. The intent is to be mindful about your personal biases and values, evaluate them, and adjust as needed moving forward. It's suggested to scour the internet for other yearly self-reflection questions for better direction if you are stuck. -### Looking Outwards -**Based on reality, what major events occurred this year? How have they affected your direction and velocity? Consider looking through all your Projects, Disciplines, other Journals, etc.** -`Answer` - -### Looking Within -**How do you feel about those physical events now? Do you think you're in a better spot now than you were last year? Why do you think this is the case?** -`Answer` - -**Look at your [[Life Pillars]]. How do you feel about them now? Do they still feel relevant and important? Have you developed new or dissolved old Life Pillars? Why?** -`Answer` - -**Look at your [[Life Dynamic]]. Does it make sense given your Life Pillars above? Why?** -`Answer` - -**How close are you to embodying your Life Dynamic? How so and why?** -`Answer` - -**Does your [[Ikigai (View)|Ikigai]] still resonate with you? How has it evolved in reference to yourself and the world?** -`Answer` - -**Do you feel like something fundamental needs to change (e.g. you, your circumstances, etc)? Why?** -`Answer` - -### Moving Forward -**If you felt that something needs to change, what can you do to make it happen? If you didn't, how can you keep things the way they are?** -`Answer` - -### Rating -**Through an arbitrary percentage, from within, how positively or negatively do you think you've shifted from last year? +/-100% is when you could not have imagined yourself in that position last year because you have changed so much to get to where you are now.** -`Answer` - -**And how much shifts of your outwards reality?** -`Answer` - -> Please make any adjustments to your Life Pillars, Life Dynamic, Disciplines, Ikigai, etc. now if needed. If anything make a task for it. - -## Ramblings -`Random yearly ramblings go here.` \ No newline at end of file diff --git a/300 Resources/Agile Project Management.md b/300 Resources/Agile Project Management.md index 2e6add1..70303ad 100644 --- a/300 Resources/Agile Project Management.md +++ b/300 Resources/Agile Project Management.md @@ -1,6 +1,6 @@ --- aliases: Agile -tags: [note/info, 'productivity', 'agile', 'gamedev'] +tags: [ info, 'productivity', 'agile', ] --- # Agile Project Management **Agile** is a set of project management principles that focuses on people, products, and tools to by encourage an iterative approach for speedy turnover on product delivery. Unlike other workflows (e.g. Waterfall), allowing, encouraging, and enacting change within a project is welcome. @@ -29,7 +29,7 @@ Customer satisfaction is of top priority, even early during development. This is *Working Software* is the the primary measure of progress; the results are the versions. -Agile emphasizes simplicity for maximizing effective work, with steady, sustainable development for maintaining a constant, indefinite pace to avoid [[Burnout]]. +Agile emphasizes simplicity for maximizing effective work, with steady, sustainable development for maintaining a constant, indefinite pace to avoid fatigue. At regular intervals, teams are to reflect on how to be more effective and adjust behavior accordingly. @@ -40,7 +40,5 @@ There are various methologies that have adapted the principles of Agile. - [[Kanban vs Scrum]] **Sources** -[[🎮 Indie Games - From Dream to Delivery]] -[Indie Games: From Dream to Delivery 1, Daglow, Don L., Ismail, Rami, eBook - Amazon.com](https://www.amazon.com/dp/B079NSDVSF/?coliid=I2DZOZ6WSVO0E0) [What is Agile? | Atlassian](https://www.atlassian.com/agile) [Principles behind the Agile Manifesto](https://agilemanifesto.org/principles.html) \ No newline at end of file diff --git a/300 Resources/Artifacts (Scrum).md b/300 Resources/Artifacts (Scrum).md index 0b8ae62..b739216 100644 --- a/300 Resources/Artifacts (Scrum).md +++ b/300 Resources/Artifacts (Scrum).md @@ -1,16 +1,16 @@ --- aliases: Artifacts -tags: [note/info, 'agile', 'productivity'] +tags: [ info, 'agile', 'productivity' ] --- # Artifacts (Scrum) **Artifacts** are key sources of information required to progress the development of a product under the [[Scrum (Agile)]] methodology. There are three key Artifacts, but there can be many more. ## Key Artifacts -The [[Product Backlog]] lists all new features, enhancements, bug fixes, tasks, etc. that are needed to build the product. Items here are usually low priority compared to the Sprint Backlog. +The **Product Backlog** lists all new features, enhancements, bug fixes, tasks, etc. that are needed to build the product. Items here are usually low priority compared to the Sprint Backlog. -[[Sprint Backlog]] are lower level breakdowns of [[Product Backlog]]. +**Sprint Backlog** are one level higher than Product Backlogs, usually being larger in scope. -[[Product Increment]] are the deliverable. +**Product Increment** are the deliverable. **Sources** [Learn about the main artifacts of agile scrum including prod](https://www.atlassian.com/agile/scrum/artifacts) \ No newline at end of file diff --git a/300 Resources/Atomic Habits.md b/300 Resources/Atomic Habits.md deleted file mode 100644 index 1e43be7..0000000 --- a/300 Resources/Atomic Habits.md +++ /dev/null @@ -1,133 +0,0 @@ ---- -aliases: -tags: [ note/info, productivity, health, habit ] ---- -# Atomic Habits -**Atomic Habits** are regular practices or routines that are small and easy, and are part of a bigger system of personal compound growth. - -## Hopelessness -These small Habits may seem unimportant, but it's note-worthy that they are multiplicative by nature. That is, it will seem worthless at the start, but once you cross the **Plateau of Latent Potential** (below), you will begin to feel rewarded rather than disappointed. -![[Pasted image 20210930105022.png]] - -## Compound Growth -Let's assume that you get better 1% every year. Conversely, let's assume a different scenario where you get worse 1% every year. Let's also assume that the habits you partake in are diverse and multiplicative of each other. With that in mind, we can create the graph below. -![[Pasted image 20210930105507.png]] - -Atomic Habits are that 1%, and you should work to remove the bad Habits and substitute good Habits. - -## Identity and Behavior -Habits are initially viewed as trivial, but they are a difficult beast to tackle because the beast is one's self. As a result, we try to change the wrong thing and in the wrong way. -![[Pasted image 20210930110019.png]] - -Actions start from the center and flow outwards, with Habits ending at the Outcome. That is, based on our Identity, we flow through a Process to reach a desired Outcome. - -In order to have a desired outcome, change must occur at the root of the cascade so it's driven in the right direction. - -**The best way to change your habit is to understand what kind of person you wish to become and embody it.** Everyone else, including yourself, sees you from the outside in. You must reverse this thinking, as only you can see from within outwards. - -> Aside: [[Mechanics-Dynamics-Aesthetics]] is a Game Design Model that describes how Designers view games and how Players view games. Designers are you, Players are everyone else. - -Habits identify you and your beliefs. - -## Sticking Habits -Repetition of an activity causes you to be more efficient and automatic. In the brain, **Long-Term Potentiation** is occurring, strengthening the neural connections correlated to said activity. The brain literally physically changes and can increase gray matter. Each time you repeat a Habit, putting in your reps for a stronger encoding of script. - -![[Pasted image 20211001152331.png]] - -The exact duration of how long you need to deliberately stick to a habit does not matter. What matters is how long the brain well-automates it. - -> Aside: The more rewarding a Habit is, the more likely the brain is to automate it. Additionally, if you can induce [[Flow]] and positive emotions, that may help as well. - -## Reinforcement -**Reinforcement** refers to the added immediate gratification towards an immediately unrewarding Habit. This hacks the brain and discourages it from pushing the immediate Habit away and increases the rate of behavior. This is especially important when it comes to denying Habits. - -Say for example you're on Keto, and you're trying to avoid sugar sweets in the house. Every time you have an urge to eat the sugar sweets and successfully walked away without so, reward yourself a bit. This reward should not satisfy the immediate craving. Rather, it is a reward is for denial. Your brain will recognize that not partaking in something is preferred and more rewarding. - -It's important that these rewards shouldn't conflict with existing Habits. If you exercise, do not reward yourself with food. - -## Formation -Habits have four components. For a habit to be successful, you must support these components. -- Cue -- Craving -- Response (Routine) -- Reward - -### Cue - Make it Obvious -Set your environment to trigger the cue. - -The environment has a large effect on your brain's recognition of a Habit. The environment is usually something you have better control over, compared to willpower and motivation. - -### Craving - Being Irresistible -Habits are based on your brain's response to [[Dopamine]]. A well-established Habit has a Dopamine-driven feedback loop, where Dopamine rises before activity occurs. This is the **Craving** as seen on (B) below. - -![[Pasted image 20211001111734.png]] - -Starting off, your brain has yet to see the new Habit as rewarding; you won't have a craving. You might even have a dip around the Reward. What we want to do is to get into (A). Once the brain recognizes that something is rewarding, you will attain the Craving (B). To get there, the Habit should be irresistible. - -The best way to make a Habit irresistible is to enhance the user experience. A good example is to do something you like passively while going through the motion of the habit. You can exercise while listening to your favorite music or watching a casual episode of Anime. This is called **Temptation Bundling** and can be used in tandem with Habit Stacking. - -Temptation Bundling works as follows. -1. After *this habit*, I will do a *habit I need* -2. After doing a *habit I need*, I will do a *habit I want* - -Going back to the diagram above, Temptation Bundling gets you to (D), which is where the brain begins to recognize the activities before the rewarding *habit I want* as potentially rewarding. - -You can also increase temptation by rewarding the Habit. For exercise, you can look into purchasing an excellent exercise mat. You already sunk some money in, you also sunk it into a quality product. Why would you not exercise? - -Alternatively, you can leverage social networks as a reward. This makes sense since most Habits exist to begin with due to three social pulls. -1. Intimate opinion (family and friends) -2. Popular opinion (majority of society) -3. Powerful opinion (leaders, authority, etc) - -That being said, if you can explicitly leverage the response of Dopamine any of the social pulls, and you become accepted, it can win approval, respect, praise, etc., and we find that rewarding. - -### Response (Routine) - Make it Easy -Minimize [[Friction]] with your Routine. - -The **Law of Least Effort** states that human behavior will naturally gravitate towards the option of the least amount of work. Prime your environment to reduce friction for Habits you want to make. - - Explicitly respond given the Cue and Craving. Do it repeatedly so the eventually Routine sinks to your subconscious. - - If you really have a hard time reducing Friction, try changing the Response itself. Instead of doing 50 push ups, try doing 10 instead. If it's time-based, consider the **Two-Minute Rule**, which states that new Habits should never take longer than two minutes. The more the [[Ceremonies|Ritual]] is in place, the easier it is to expand it. This practices the art of showing up, and since you're already in the circumstance to do it, you will eventually do it. - - > “Standardize before you optimize. You can’t improve a habit that doesn’t exist.” - > — James Clear - -Habits you want to enforce should be inevitable. - -### Reward - Satisfaction -The brain has trouble understanding something is rewarding when it is delayed. It seeks the immediately rewarding and avoids the immediately punishing. For a Habit to stick, it needs to feel immediately rewarding, even if it's incredibly minor. - -If you can make your brain see this Habit as rewarding, it increases the chances that this behavior will be repeated. - -To make a Habit feel rewarding, visually tracking it can give a sense of pride and satisfaction. Be wary of [[Goodhart's Law]], however, which merely states the tunnel vision of focuses solely on simple metrics rather than purpose. - -## Stopping Habits -### Cue - Avoidance -Change your environment to discard the Cue. - -As mentioned under Formation, the environment has the most effect on an existing Habit. Willpower is limited, and it's best to not be in a situation to exert it to begin with. Avoidance is always better than resistance. - -### Craving - The Bright Side -Understand the disgust of this Habit and the benefits of quitting. - -The Cravings you have are temporary and merely a prediction. They may not actually make you better off than you are now. This is something you must remember when these Cravings occur. Remember the benefits of quitting this Habit and it will naturally feel unattractive. - -### Response (Routine) - Make it Difficult -As stated in this section's [[#Response Routine - Make it Easy|inverse]], if you want a Habit to stick you should make it easy. To stop a Habit, make it difficult. - -Do it for long enough and the habit will dissolve. - -Habits you want to deny should be impossible. - -### Reward - Pressure -An easy way to deter a Habit is to put social pressure on yourself. Tell someone that you're going through a phase and to constantly remind you to stop doing what you want to stop doing. This will create shame. Swallow it and use it wisely. - -## What Habits? -Choose habits that work with you. It should make your life easy, not a struggle. Of course, if it's too easy you become bored. You need to strike the middle zone of the **Goldilocks Rule**. -![[Pasted image 20210930152118.png]] - -After successfully sticking a Habit, you must be careful of being complacent. The Goldilocks Rule promotes [[Flow]], and one should be careful not to utilize it too much. See [[Flow#Downsides]] for more details. - -## References -[Book Summary: Atomic Habits by James Clear | Sam Thomas Davies](https://www.samuelthomasdavies.com/book-summaries/self-help/atomic-habits/) \ No newline at end of file diff --git a/300 Resources/Burnout.md b/300 Resources/Burnout.md deleted file mode 100644 index b8a8ddf..0000000 --- a/300 Resources/Burnout.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -tags: [note/info, 'productivity', 'lifestyle', 'introspection', burnout] ---- -# Burnout -**Burnout** is the state of mental and physical exhaustion caused by an intense prolonged mental stress. This intense prolonged stress can be the result of high working hours, prolonged intense focus, prolonged toxic relationships, and more. Many people have difficult sleeping, irritable, close-minded, and less productive. This loosely shares similar symptoms of [[Depression]]. - -It's believed that burnout is the result of a low reward insufficient for the work put in. Biologically, it could mean that the balance of [[Cortisol]] is too high compared when compared to [[Dopamine]]. - -> While this sounds reasonable, I don't really understand it. While (my) the potential explanation on a biological level could make sense, other than that it doesn't. -> -> Let's think of this the other way. Given a high reward and low effort results in elevated levels of Dopamine, leading to excessive activity of the [[Default Mode Network]] (e.g. cravings and "excuses"). The brain and body would have learned how to get the best reward for the least effort, leading to lower concentration of tasks that require more effort. While you don't get burned out, you get "Dopamine Poisoned". -> -> Now the inverse of that, low reward and high effort, would result in a suppression of Dopamine? Since the body/brain has learned that this task isn't rewarding, Dopamine levels drop. When going to other tasks, Dopamine levels come back since it isn't that unrewarding task. Perhaps the reason why we need a break from work is to get the body/brain to unlearn that the unrewarding task is unrewarding and to allow Dopamine to be released when doing that task. Essentially, it's the reverse of tolerance. This explains why burnout is specific to a certain activity. - -Careers that are more likely to cause burnout are the following: Social Workers, Teachers, School Principles, Lawyers, Police Officers, Retail Workers. It's inferred that most of the time these jobs do not provide enough gratification to justify the work put in. - -When we are stressed, we release [[Adrenaline]] to prepare and take action. However, our Adrenal Glands only have so much in reserves. Once empty, Cortisol gets released. Too much of this Cortisol can begin to impact cognition. Doing activities other than the stressful activity, especially lesser stressful activities, lowers Cortisol and helps mitigate burnout. - -**Sources** -[The History of BURNOUT! | Kati Morton - YouTube](https://www.youtube.com/watch?v=usWGg6xKHW0) -[The Science of BURNOUT! | Kati Morton - YouTube](https://www.youtube.com/watch?v=MZGxYBsUXgU) -[The Science Behind BURNOUT - YouTube](https://www.youtube.com/watch?v=8S6-vGY0VeI) - ---- -## Outdated -**Burnout** is the result of chronic exposure to a a single or many related stressors. This is typically related to work because a majority of our awake time is spent working. This means that burnout can also occur when doing leisure, which is thought to negate burnout. In reality, what negated the burnout was having a varied stressors that is unrelated to the previous stressors. - -> Meditating does not appear to mitigate burnout, but it may postpone it. - -According to the limits of [[Absolute Focus]], [[Deep Work]] should be limited to 4 hours, up to 6 if well trained. Going over this daily softcap could potentially lead to burnout. - diff --git a/300 Resources/Ceremonies (Scrum).md b/300 Resources/Ceremonies (Scrum).md index 92f1e36..5843284 100644 --- a/300 Resources/Ceremonies (Scrum).md +++ b/300 Resources/Ceremonies (Scrum).md @@ -1,12 +1,10 @@ --- aliases: Ceremony (Scrum) -tags: [note/info, 'agile', 'productivity'] +tags: [ info, 'agile', 'productivity' ] --- # Ceremonies (Scrum) **Ceremonies** in [[Scrum (Agile)|Scrum]] are a fancy word for the types of goal-oriented meetings to prepare for and reflect on work. -To see a more generalized definition, see [[Ceremonies]]. - There are various types of Ceremonies presented. ### Sprint Planning @@ -24,7 +22,7 @@ Some core ideas that should be discussed are as follows. > Try not to include work that can is blocked by dependencies (e.g. requiring a sign off that you probably won't get before or shortly after the Sprint starts), Also, setting priority on certain kinds of work. -Everything should be placed on the [[Product Backlog]], which each item being clear and measurable. This can take the for of some Acceptance Criteria (a checklist of characteristics and satisfaction) or some Testing Note (guided, potentially automated testing). +Everything should be placed on the Backlog, which each item being clear and measurable. This can take the for of some Acceptance Criteria (a checklist of characteristics and satisfaction) or some Testing Note (guided, potentially automated testing). ### Daily Stand-up (Scrums) A personalized Ceremony done *once per day (morning*), usually lasting <15 minutes to inform everyone the current state of affairs. They should be light, fun, and informative, usually trying to answer the following questions: @@ -36,7 +34,7 @@ To assist the process, one should consider having some kind of view that denotes > It also makes people accountable of themselves and each other. -The [[Product Backlog]] is also adjusted as tasks are labeled as *In-Progress* and *Done*. Also see [[Kanban (Agile)]]. +The Backlog is also adjusted as tasks are labeled as *In-Progress* and *Done*. Also see [[Kanban (Agile)]]. ### Iteration Review (Sprint Review) A Ceremony done at the *end* of a sprint or milestone, usually lasting 60 minutes per sprinted week to showcase and demo work. diff --git a/300 Resources/Ceremonies.md b/300 Resources/Ceremonies.md deleted file mode 100644 index 64ffd99..0000000 --- a/300 Resources/Ceremonies.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -aliases: [ Ceremony, Ritual, Rituals ] -tags: [note/info, productivity, agile, scrum] ---- -# Ceremonies -**Ceremonies** (aka Habit Stacking), are sequential actions to prepare one's self for upcoming adversary. This can be as simple as just preparing for the day or preparing for several hours of deep work. - -For more formal Ceremonies, particularly under the premise of [[Agile Project Management]], see [[Ceremonies (Scrum)]]. - -Your personal ceremonies found [[Personal Ceremonies|here]]. \ No newline at end of file diff --git a/300 Resources/Default Mode Network.md b/300 Resources/Default Mode Network.md deleted file mode 100644 index c7d4437..0000000 --- a/300 Resources/Default Mode Network.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -aliases: DMN -tags: [note/info, 'productivity'] ---- -# Default Mode Network (DMN) -The **Default Mode Network (DMN)**, also known as the **Monkey Mind** refers to the various parts of the brain that are found to be active when you are mentally *at rest*. The DMN is thought to be responsible for your sense of self. It is also thought to be responsible for daydreaming, recalling memories, and general wandering thoughts. - -> Those thoughts telling you that you can't do something, or that you should do something, you can blame the DMN. - -Those having trouble with their sense of self is thought to have a DMN that is too active or unhealthy. It could be linked to anxiety and depression. - -The DMN is found to have lower activity when we are engaged with an activity. [[Mindfulness Meditation]] is an activity which engages the brain to focus on the immediate surroundings, attempting to actively disengage the DMN. - -> It is found that avid meditators have naturally have decreased DMN activity. - -Studies have shown that when people take a story in, whether it be visually through a story, auditorily through its audio, or visually through a book, the Default Mode Network is activated. From this, the Default Mode Network is believed to play a role in comprehension and remembering these stories. - -> If the story is jumbled or told in an unfamiliar language, the Default Mode Network does not activate as readily. The observers tend to actively "think" a lot more to try to comprehend, which *does* appear to impede on overall story recollection. - -If one were to completely turn off the DMN and engaged in an activity, Task-Positive Network, one could be in a state of [[Flow]]. Immediately after one disengages from said activity, DMN activates, and it can take a while to turn it back off as one re-engages. - -Psychedelic drugs appear to deactivate the DMN, which results in transcendence and euphoria. - -**Sources** -[Know Your Brain: Default Mode Network — Neuroscientifically Challenged](https://www.neuroscientificallychallenged.com/blog/know-your-brain-default-mode-network) -[Default mode network - Wikipedia](https://en.wikipedia.org/wiki/Default_mode_network#External_links) -[Why We Ruminate and How to Stop (Default Mode Network) - YouTube](https://www.youtube.com/watch?v=N7AZ-qi_NsE) -[Why Meditate? | Change your Brain's Default Mode - YouTube](https://www.youtube.com/watch?v=aAVPDYhW_nw) \ No newline at end of file diff --git a/300 Resources/Disciplines.md b/300 Resources/Disciplines.md index fe1eee8..37f7502 100644 --- a/300 Resources/Disciplines.md +++ b/300 Resources/Disciplines.md @@ -1,9 +1,9 @@ --- aliases: Discipline -tags: [note/info, original, productivity] +tags: [ info, productivity ] --- # Disciplines -A **Discipline** is a pathway of [[Ikigai]]. Disciplines have a set of values, called [[Pillars]] that when combined forms a Dynamic. A **Dynamic** is a greater goal or meaning that is the resulting effect of Pillars. The Dynamic is what drives future projects and Ikigai. +A **Discipline** is a pathway of [[Ikigai|Life]]. Disciplines have a set of values, called [[Pillars]] that when combined forms a Dynamic. A **Dynamic** is a greater goal or meaning that is the resulting effect of Pillars. The Dynamic is what drives future projects and Ikigai. ## Scoping Disciplines are unique such that there is no majority overlap in skill-set or setting. @@ -12,71 +12,28 @@ For example, Game Development and Programming can be separate Disciplines becaus On the other hand, Physical Health and Mental Health go hand in hand and largely affect each other. In this case, both Disciplines should be grouped as Health. You can also argue that Health is a part of a bigger picture: Well-Being. -## Relations -Disciplines are immediately related to your Life through Ikigai, as Disciplines are the components of one's lifestyle. +## Relations and Placement +Disciplines are immediately related to your [[Ikigai|Life]], as Disciplines are the components of one's lifestyle. [[Projects]] are directly derived from Disciplines. Projects that are multidisciplinary should strongly fit into a single Discipline. If not, it's possible Disciplines are not scoped correctly or that the Project is not well defined. -[[Tasks]] will always be a part of Disciplines. +Disciplines are placed just at the root of the vault. -## Tags -The second index of the `tags` fields inside of the YAML must be the tag designated as the Discipline Tag. +[[Tasks]] will always be a part of Disciplines. ## Pillars A Discipline must have explicitly user-defined Pillars. There should be around 3-8 Pillars in total. These Pillars can be anything so long as they follow the following restrictions. - All Pillars when viewed together should soundly resemble the Discipline - The Discipline should not strongly overlap with another existing Discipline in their repository -### Examples -For the Discipline Work, Pillars might be as follows. -- **Human**: Mental Health, Physical Health, and Family comes first before Work -- **Autonomy**: Work for yourself, not for others -- **Golden Rule**: Everyone is dealing with the same shit you're dealing with, so treat them well as you want them to treat you -- **Marathon**: Stay at a steady pace as to not induce Burnout - -Having Disciplines Social and Work are fine, but having Disciplines Social and Family may run into issues if you internally viewed both as the same. - ## Dynamics -Dynamics are ripped from [[Mechanics-Dynamics-Aesthetics#Dynamics|MDA]]. When applied to the Pillars in Disciplines, the idea is that the whole is greater than the sum of its parts. From [[Systems Thinking]], this is the same idea as Emergence. +When applied to the Pillars in Disciplines, the idea is that the whole is greater than the sum of its parts. From [[Systems Thinking]], this is the same idea as Emergence. + +Pillars when applied in parallel create greater meaning. This greater meaning is the Dynamic. -Pillars when applied in parallel create greater meaning. This greater meaning is the Dynamic. +See [[Dynamics]]. **All Disciplines should have a Dynamic, but the Pillars should come first.** ## Alignment -Disciplines should be routinely reviewed to ensure that the Pillars and Discipline are still relevant to your current life. It's suggested to do this review on a monthly basis. - -## Tags and Sub-Disciplines -All Disciplines will have a tag associated with it. This tag is to be applied to all Projects and Tasks within this Discipline. - -Discipline Tags may have sub-tags as the system grows to differentiate Sub-Disciplines, but care should be taken as to correctly partition the Discipline. - -The Discipline is correctly partitioned into it's Sub-Disciplines when... -- Any Project can only ever strongly fit into one Sub-Disciplines -- There is no *Miscellaneous* or *Other* Sub-Discipline - -## Folders and Organization -Disciplines should have their own dedicated folder. - -It's suggested to NOT have dedicated folders for Sub-Disciplines, as examples such as Physical Health and Mental Health, Sub-Disciplines of Health, at times have overlapping content, which cannot go into both folders. - -## Habits -Some Disciplines (e.g. Physical Health) may require repeated tasks in order to uphold a standard. - -Successful Habits are unconsciously repeated activities. Starting off, however, it will require you to be fully conscious of your time and drive. Because of this, Habits should be explicitly planned, created, tracked, and analyzed. - -Habits are performed to your schedule with the goal to enforce it into your unconscious [[Default Mode Network]]. - -A simple example of a Habit is a quick sketch of any unique household item every day. - -See [[Habits]] for full details on how they operate. - -## Ceremonies -Working on Projects within a Ceremony may *work better* with Ceremonies. - -A simple example of a Ceremony is a set of movements to warm up before Exercise on a Project that follows a new workout schedule. - -See [[Ceremonies]] for full details on how they operate. - -**Source** -[[99 (OLD) Workflow Overhaul]] \ No newline at end of file +Disciplines should be routinely reviewed to ensure that the Pillars and Discipline are still relevant to your current life. It's suggested to do this review on a monthly basis. \ No newline at end of file diff --git a/300 Resources/Dynamics.md b/300 Resources/Dynamics.md new file mode 100644 index 0000000..c65a62e --- /dev/null +++ b/300 Resources/Dynamics.md @@ -0,0 +1,10 @@ +--- +aliases: [ Emergence, Dynamic ] +tags: [ info ] +--- +# Dynamics +**Dynamics** is the multiplicative experience that comes as a result of combining components to make a system. + +An example of this is a living room. At it's core componenets, it's merely a room, a couch, television, lighting, and a coffee table. But when combined together, it becomes a shared space and common ground for the family and guests to safely interact with, along many other emerging Dynamics. + +For the a better understanding of higher-ordered Dynamics, see [[Systems Thinking]]. \ No newline at end of file diff --git a/300 Resources/Eisenhower Matrix.md b/300 Resources/Eisenhower Matrix.md deleted file mode 100644 index a4330b0..0000000 --- a/300 Resources/Eisenhower Matrix.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -aliases: Task Priority -tags: [note/info, 'productivity'] ---- -# Eisenhower Matrix -The **Eisenhower Matrix** is a simple, low-overhead method of prioritizing [[Tasks]]. Tasks are sorted as Important, Urgent, either or or neither. - -| | Urgent | Not Urgent | -| ----------------- |:------------------------ |:------------------ | -| **Important** | Do these now | Schedule for later | -| **Not Important** | Delegate to someone else | Never do | - - -## Variations -### Scope -Usually the Eisenhower Matrix is applied such that its scope includes all minuscule, useless items and all crucial items. The former are considered Not Urgent, the Latter considered Important and situationally Urgent. - -To reduce overhead even further, it's recommend to never note, but still consider, the minuscule, useless items. - -### No Delegation -The Eisenhower Matrix assumes that you can Delegate a task to someone else. However, for certain [[Disciplines|Discipline]] this isn't possible. In this case, Urgent tasks should take priority over Important tasks, especially as the deadline approaches. - -### Individualized -It may be better to follow a matrix more centered around one's self and/or needs-and-wants. This combines a shifted Scope with no Delegation. - -| | Urgent | Not Urgent | -| ----------------- |:------------------------------------ |:------------------------------------------------- | -| **Important** | Critical, do these now | Crucial, do when not pressured and abled exerted | -| **Not Important** | Pressured, do as the date approaches | Relevant, do when there's nothing else to do | - -Note that there is not a place for Tasks that you never do. This reduces overhead as stated under [[Eisenhower Matrix#Scope]], but also allows for *nice to haves* along side the mission critical items. - -It is possible that useless items creep into Not Urgent and Not Important, so it's important to have some kind of realignment system in place to ensure all Tasks remain relevant. - -## Expanded Definitions -### Urgent and Important -A task considered **Urgent** and **Important** are time sensitive and major hallmarks of said [[Projects|Project]]. - -**This takes priority #1.** - -### Urgent -A task is considered **Urgent** if not accomplishing this task would lead to repercussion. This includes blocking other tasks and social, personal, and economical consequences (e.g. logging data now rather than later, how not to lose hair). - -**This takes priority #2.** - -### Important -A task is considered **Important** if completing this task will result in novel knowledge or substantial progress towards a Project or Area of Responsibility (e.g. timed meals under *health*, iteration on a system for *gamedev*). They can also be thought of as the *needs*, *core*, *foundations* of a project rather than the *wants*, *nice-to-haves*. - -**This takes priority #3.** - -### Not Urgent and Important -These are tasks that are still related, but are non-consequential and/or not immediately important to any ongoing Project or Areas of Responsibility (e.g. cooking better food, how to do a backflip, buying trivial things). They can be considered *nice to haves* or *wants* for a project. - -**This takes priority #4.** - -## Referencess -[The Eisenhower Matrix: Introduction & 3-Minute Video Tutorial](https://www.eisenhower.me/eisenhower-matrix/) diff --git a/300 Resources/Flow.md b/300 Resources/Flow.md deleted file mode 100644 index 976715b..0000000 --- a/300 Resources/Flow.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -tags: [note/info, 'productivity'] ---- -# Flow -**Flow** is a mental state characterized by enhanced automatic and unconscious performance during an activity. - -## Developing Flow -Flow is built from mental and physical conditioning; you can jump straight into something new and enter flow. You must be sufficiently skilled at the activity where you can automate. - -## Entering Flow -Once one reaches sufficient skill to attain Flow, they have to enter it. It can be difficult to enter, but easy to get out of. One must stay engaged to an engaging task for up to 15 minutes. Any distraction (e.g. someone calling your name) can ruin Flow. - -It's believed that the following are necessary, if not desired, in order to entering and sustain Flow. -- Clearly defined goals (for motivation) -- A quick way to measure progress -- Near instant feedback based on your actions -- No interruptions -- Challenging enough to not be trivial but easy enough to not create frustration - -## Downsides -As much of Flow is automatic, one needs to be careful of relying too much on flow. As much becomes automated, you can become stuck, only using what you've conditioned yourself to do rather than doing something better. **This is especially troublesome when what's been conditioned is not perfect, and it will never be perfect.** - -To combat this, you may need to alter the activity such that it throws you slightly out of flow. That way you can deliberately think as you do what you need to do. - -You can also just take it slower and be much more deliberate. Do it enough times and you'll recondition yourself. - -## References -[[🎮 Indie Games - From Dream to Delivery]] \ No newline at end of file diff --git a/300 Resources/Friction.md b/300 Resources/Friction.md index c6cec66..48a457a 100644 --- a/300 Resources/Friction.md +++ b/300 Resources/Friction.md @@ -1,40 +1,10 @@ --- -aliases: -tags: [ note/info, original, friction ] +aliases: null +tags: [ info ] --- # Friction **Friction** in Workflow refers to the reluctance or barrier one has towards an activity. Friction can be the result of many things, but the primary cause is based on the Environment and psychology With no Friction, one should be able to immediately sit down and begin their work. -With Friction, and particularly lots of it, one might sit down, look at their work, and immediate look away, think about something else, or even just walk away and not do it. This is Procrastination. - -## Why it Occurs -### Environmental Friction in Habits -[[Habits]] are a great example of how Friction affects work. Let's say you want to start exercising every two days, and let's say there's two scenarios. -1. You don't have a specific spot in your house to exercise so when you do to exercise, you make a clearing. You just start exercising right away, doing what you already know and looking up a few videos and work your way up. You revert the clearing once you're done because it needs to be there. -2. You take a week to prepare, make an exercise habit tracker, research what exercises you will do, clear a specific spot and keep it cleared, then start exercising. - -Out of these two scenarios, the Scenario (2) is much more likely to succeed than Scenario (1). - -This is because for Scenario (1), before you can start exercising, you must clear the space. This already raises a lot of problems, because before you can exercise, you must do something that is not exercise. This is referred to as [[Overhead]]. The more Overhead you have, the much less likely you are to do something. Looking up videos and watching them is additional overhead. - -Scenario (2) attempts to prepare as much as it can before exercise starts. It attempts to reduce overhead as low as possible so that when it's time to exercise, they can exercise and there's not reason to give themselves excuses (e.g. didn't want to make a clearing). - -### Psychological Friction in Rewards -[[Dopamine]] is a particularly key neurotransmitter in the way we think and why we do things. - -If one plays an engaging, potentially rewarding video game all day, the mind gets flooded with Dopamine. Neuronal pathways of said game become enhanced and continuously fire off even when not engaged in the game. This is why you sometimes have dreams of games after playing them long enough. But outside of sleep, when trying to do work, all you can think about is playing that game. - -What's even worse is that your brain has adjusted it's feeling of reward. Feelings are a subjective spectrum, but what's to note here is that the brain builds tolerance of recent rewards. - -If for the past month you have been playing video games non-stop and you want to do work, your brain will ask you why? Why do work, something that's so much less rewarding than video games? You will absolutely feel bored when doing your work. - -Conversely, if you have been doing work for the past month and nothing else that's more *fun*, work to you is fun. That's the only fun you've had and the most fun you've had that past month (assuming work is engaging and *fun*). - -## Reducing Friction -That being said from [[Friction#Why it Occurs - Friction in Habits|above]], Overhead should be reduced as much as possible on the activity that needs to get done. It should be easy to start working and difficult to stop working because you're already working. - -If you find yourself constantly thinking about more rewarding things when you're sitting down to do your work, it's possible you have Dopamine Poisoning (tolerance) and your brain is overly engaged for too long on a particular activity. Consider doing a [[Dopamine Detox]]. - -## References +With Friction, and particularly lots of it, one might sit down, look at their work, and immediate look away, think about something else, or even just walk away and not do it. This is Procrastination. \ No newline at end of file diff --git a/300 Resources/Fundamentals of LDP.md b/300 Resources/Fundamentals of LDP.md new file mode 100644 index 0000000..fc47c04 --- /dev/null +++ b/300 Resources/Fundamentals of LDP.md @@ -0,0 +1,74 @@ +--- +aliases: +tags: [ info ] +--- +[[00 ❗ Readme|❗ Readme]] +## Fundamentals of LDP +### Core Components +#### Tasks +[[Tasks]] are items of action that have an estimated work time less than 2 hours. Anything more can lead to increased friction and reluctance to take on. + +Tasks are everywhere in the system. They can be part of general Life, Disciplines, or Projects. + +Tasks should especially be clear and simple. It should be obvious when it is complete. If not, you need to further clarify the task. + +#### Life +[[Life (LDP)|Life]] is the foundation in which everything you do is based on. LDP is meant to create mobility towards your Life [[Pillars]] and Life [[Dynamics|Dynamic]]. It is who you idealy want to be, not just who you are now. + +[[Ikigai]] is a concept that literally translates into "a reason for being". With this in mind, you want to find this ikigai and define it as a Discipline. + +Life is infinite but ever changing. + +#### Disciplines +[[Disciplines]] are a broad range of skills you find relevant and important. This is what sets the direction for your Life, with a very small few defined as your Ikigai; ikigai(s) should point in the same direction. + +Simialr to Life, Discipines also have Pillars and Dynamics. + +Disciplines are infinite so long as they are relevant and important. + +> I personally think everyone should consider Well-being and Finance part of their disciplines. + +#### Projects +[[Projects]] are derived from Disciplines. If Disciplines defined the direction, Projects actually generate the speed, creating velocity. + +Projects have a single objective, which should uphold or to make progress towards a Discipline's Pillars or Dynamics. Similar to Tasks, they should also have some sort of Completion Criteria to denote when this project is clearly completed. + +Projects should take no longer than an estimated month of work and no shorter than 8 hours to complete. *This is merely a suggestion to reduce friction.* + +#### Alignment +Alignment is a process of check-and-balances that you do to make sure that work is relevant to it's higher-ordered context. In essense, you want to ask yourself the following. + +> "Is this task, project, or discipline relevant in this context?" +> — You, probably + +For Tasks, you would align the work itself to a Project's Objective. For Projects, you with align its Objective with its Discipline's Pillars and Dynamics. Disciplines's Pillars and Dynamics align with that of your Life. Your Life aligns with your ideals. + +> **Tasks $\rightarrow$ Projects:** Daily +> **Projects $\rightarrow$ Disciplines:** Weekly +> **Disciplines $\rightarrow$ Life:** Quarterly +> **Life $\rightarrow$ Sense of Self:** Yearly + +This is something that should be done routinely or as neded to smooth out workflow. + +The exact methods of how you align are up to you, but the main point is to make force an objective perspective to ensure you're on focused. + +### Organization, Simplified +![[Habits, Life, Disciplines, Projects.drawio.png]] + +LDP is organized hierarchicaly as to allow routine alignment of each component to it's higher context. Projects should make sense under Disciplines, and Disciplines should make sense in the context of your Life. And of course, your Life should make sense with your ideals. + +Tasks are scattered throughout the system as needed. + +### Workflow +#### Setup +There's a moderate amount of overhead before this system becomes flows like butter. You first need to understand the [[#Core Components]]. + +Once understood, while taking into account [[#Philosophy - How to Approach LDP|LDP Philosophy]], there are three approaches you can take. +1. Bottom-up + - Start from your current ongoing tasks and projects and derive a discipline that contains those items. Once you cannot make any more disciplines, you can then define what kind of life a person would need to perfect those disciplines. This is useful if you haven't done much personal exploration. +2. Top-down + - Start defining what you find to be valuable when navigating life. From this, what kind of disciplines would a person have to uphold that kind of charcter. Projects and tasks will organically form as needed. Useful if you really hold dear certain values. +3. Wide and Flat **(Recommended)** + - Do top-down and bottom-up at the same time to find a middle ground. It gives insight as to who you are now and who you want to be. You may find a mismatch in who you want to be and who you are now, and that's completely fine. + +[[Working with LDP]] \ No newline at end of file diff --git a/300 Resources/Getting Things Done.md b/300 Resources/Getting Things Done.md index fe39d56..9bc6a21 100644 --- a/300 Resources/Getting Things Done.md +++ b/300 Resources/Getting Things Done.md @@ -1,6 +1,6 @@ --- aliases: GTD -tags: [note/info, productivity] +tags: [ info, productivity ] --- # Getting Things Done **Getting Things Done** is a framework designed to help you keep track of tasks, ideas, and projects around your life and work. diff --git a/300 Resources/Habits.md b/300 Resources/Habits.md deleted file mode 100644 index aa614ab..0000000 --- a/300 Resources/Habits.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -aliases: -tags: [ note/info, habit, productivity, health ] ---- -# Habits -A **Habit** is a routine behavior that tends to occur subconsciously. This behavior is usually initiated by various circumstances, including but not limited to... -- Physical Environment -- Time -- Bodily cycles -- Mental State - -## Why they Occur -The primary factor in why Habits form is due to [[Dopamine]]. Dopamine is responsible for your wants and desires, and once released consistently enough, the brain recognizes that this Habit is desirable and begins to subconsciously crave for it and do the **Routine**. - -The brain recognizes the circumstances that are required to initiate the Routine. This is the **Cue**. - -Sometimes these cravings are strong and Habits become compulsory. This can be especially troublesome for bad Habits (e.g. nail biting, video games, drinking, smoking, etc). - -## Developing Habits -A big factor as to if Habits stick or not are if there is low enough [[Friction]] and if there lies some reward at the end of the Routine. - -One should aim to reduce the amount of Friction required to initiate the Routine. There are various techniques to achieve this. -- **Plan:** plan exactly what will be done and have the routine visually in front of you as you followX as low [[Overhead]] as possible and plan for weeks in advance. -- **Setup**: have your physical environment already and keep it like that. -- **Timeblock**: have an explicit timeframe where this Routine will take place. Even better, you can do Habit Stacking, which is when you add this Routine after or before an existing Habit (e.g. brushing your teeth, waking up, etc.). -- **DND**: have nothing else planned; prevent distractions. -- **Order Matters**: Do not have extremely rewarding activities precede a lesser rewarding Habit. Your brain will question why you're doing something less rewarding. If you must, give some buffer space to become *bored* and reset reward levels. -- **Consistency**: Be consistent with all the above, especially time. - -> It should be noted that **your brain needs to recognize the routine itself as rewarding.** If you give yourself an irrelevant reward, say ice cream, after a routine, your brain might not reward the routine, but reward the ice cream. You will now have cravings for the ice cream and not the routine itself. - -### What to Expect -The first few sessions may feel like a honeymoon. If it's something you're motivated by, that implies that your brain already recognizes it as rewarding. However, that may be just for now. Soon, or even right now, it can feel like an immense amount of work. - -Your brain has yet to recognize that this Habit is rewarding enough to be remembered. Much of the initial Habit formation requires a lot of explicit drive, as it has yet to be driven subconsciously. It will be difficult, and you will want to do other things, but you must be aware that these are merely cravings. - -You are on this Habit Formation because you believe it will benefit you. These cravings to do other Habitual things may not be that good for you. Stick to what you planned to do; take control. - -### Systems, not Goals -Goals are reached and then end. Systems are forever given sufficient input. This isn't to say that Goals are bad, but rather, goals should supplement Systems. As a matter of fact, you could say that a Habit is an emerging result of having a good system set up. See [[Systems Thinking]] for more on this mindset. - -To set up a System for Habit, consider the following elements. -- Accountability: How often did you do the habit? -- Scheduling: When will you do the habit? -- Reminders: Alarms for when you should do the habit. -- Journaling: For reflection, analysis, ramblings, etc - -## How long until it sticks? -For a Habit to truly stick, it may take anywhere between 18 and 254 days. It mainly depends on how rewarding and much [[Flow]] the routine generates. On average, it may take 66 days for the behavior to become subconscious. - -Habits make up you. They make up your lifestyle. Take control of your habits and you take control of your life. - -## References -[Habit - Wikipedia](https://en.wikipedia.org/wiki/Habit) -[[Atomic Habits]] -[Psychology of Habits](https://www.theworldcounts.com/happiness/psychology-of-habits) -[How Long Does It Really Take to Form a Habit? 7 Things to Consider](https://www.healthline.com/health/how-long-does-it-take-to-form-a-habit#base-figure) \ No newline at end of file diff --git a/300 Resources/Ikigai-9.md b/300 Resources/Ikigai-9.md deleted file mode 100644 index af32f9d..0000000 --- a/300 Resources/Ikigai-9.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -aliases: -tags: [ note/info ] ---- -# Ikigai-9 -**Ikigai-9** is a questionnaire and psychometric tool for measuring one's general sense of [[Ikigai]]. Questions are scored on a 5-point scale, 1 being *does not apply to me* and 5 being *applies to me a lot*. - -> The Ikigai-9 was originally asked in Japanese, and being translated over to English, the intent of these questions may have been slightly altered. - -Ikigai-9 asks the following 9 questions. -1. I often feel that I am happy. -2. I would like to learn something new or start something. -3. I feel that I am contributing to someone or the society. -4. I have room in my mind. -5. I am interested in many things. -6. I think that my existence is needed by something or someone. -7. My life is mentally rich and fulfilled. -8. I would like to develop myself. -9. I believe that I have some impact on someone. - -## References -[Finding Your Ikigai: 8 Questionnaires and Tests](https://positivepsychology.com/ikigai-test-questionnaires/) -[(PDF) English Translation and Validation of the Ikigai-9 in a UK Sample](https://www.researchgate.net/publication/336821611_English_Translation_and_Validation_of_the_Ikigai-9_in_a_UK_Sample) \ No newline at end of file diff --git a/300 Resources/Ikigai.md b/300 Resources/Ikigai.md index 6828b59..5e2ac7b 100644 --- a/300 Resources/Ikigai.md +++ b/300 Resources/Ikigai.md @@ -1,9 +1,12 @@ --- -tags: [note/info, productivity, health] +aliases: Life Meaning +tags: [ info, productivity ] --- # Ikigai **Ikigai** is a Japanese concept of a motivating force that gives someone a sense of purpose for loving. Ikigai literally translates into *a reason for being*. +For a general interpretation of Life in the context of Life-Disciplines-Pillars, see [[Life (LDP)]]. + If one can properly define their Ikigai, they should then have a clear direction on what to do to increase well-being and sustain happiness. Ikigai has two important concepts. @@ -26,8 +29,6 @@ There is no way for someone else to define your Ikigai. Everyone is different an A good Ikigai should maintain balance of love, skills, worldly needs, and sustainability. Refer to the diagram below. ![Ikigai Diagram - Kanban](https://kanbanzone.com/wp-content/uploads/2021/04/kanban-zone-ikigai-japanese-concept.png "kanban-zone-ikigai") -I defined my Ikigai [[Defining My Ikigai|here]]. - **Sources** [Ikigai - Wikipedia](https://en.wikipedia.org/wiki/Ikigai) [How To Find Your Ikigai And Transform Your Outlook On Life And Business](https://www.forbes.com/sites/chrismyers/2018/02/23/how-to-find-your-ikigai-and-transform-your-outlook-on-life-and-business/?sh=7d0557c62ed4) diff --git a/300 Resources/Inbox.md b/300 Resources/Inbox.md new file mode 100644 index 0000000..fa40c15 --- /dev/null +++ b/300 Resources/Inbox.md @@ -0,0 +1,6 @@ +--- +aliases: +tags: [info] +--- +# Inbox +Your inbox is where temporay work goes into. It may not fit into any [[Disciplines|Discipline]] or [[Projects|Project]] a this moment, or you may not want to deal with sorting it at the moment. \ No newline at end of file diff --git a/300 Resources/Kanban (Agile).md b/300 Resources/Kanban (Agile).md index 6ffa354..0523b76 100644 --- a/300 Resources/Kanban (Agile).md +++ b/300 Resources/Kanban (Agile).md @@ -1,41 +1,18 @@ --- aliases: Kanban -tags: [note/info, 'agile'] +tags: [ info, 'agile' ] --- # Kanban (Agile) **Kanban** is an adaptation of [[Agile Project Management]] and is a workflow methodology of continuous that uses a visual aid to help organize and limit work that may be invisible to increase work efficiency. It should be applied directly to how you currently work, not the other way around. -At the most fundamental level, a Kanban Board should have the following. -![Elements of a kanban board](https://wac-cdn.atlassian.com/dam/jcr:8d815cd2-6cc0-46a5-976c-5ac6205fbaca/Elements_of_a_kanban_board.png?cdnVersion=1804) -- **Visual Signals**: this includes the cards, any tags they have, and any other visual indicator that shows the type of work that is to be worked on -- **Columns**: as a means to visualize workflow e.g. To Do$\rightarrow$In Progress$\rightarrow$Done -- **Work-in-Progress Limits**: to prevent handling too much work at once and promote efficiency and focus -- **Commitment Point**: a backlog of things that will definitely and eventually be done -- **Delivery Point**: the result of work - An example of a very simple board can be seen below. -![[Pasted image 2021091g4155359.png]] +![[Pasted image 20210914155359.png]] -The very left **Backlog** can be thought of a [[Sprint Backlog]] for [[Scrum (Agile)|Scrum]]. Cards move from left to right as work progresses. These cards should be small enough that one can finish it within a reasonable time-frame. +The very left **Backlog** can be thought of a backlog for [[Scrum (Agile)|Scrum]]. Cards move from left to right as work progresses. These cards should be small enough that one can finish it within a reasonable time-frame. Kanban is a pull system in which that is based on how much free time you have. If you have free hands, you can pull an item over from the Backlog, to Today, to Doing, and eventually, to Done. -The image above is NOT the guideline, but a recommendation. It's recommended to keep it simple. - -## Limiting Work -Typically columns (e.g. Doing) on Kanban have **Card Limits** as a way to direct focus and energy to a limited amount of work. This is an attempt to decrease **Lead Time**, the amount of time a card gets from the Commitment Point to Delivery. With a lower Lead Time, more work can flow. - -> There is no tried and true rule on card limits as it depends on the size of the card. But a general recommendation for teams is to take the amount of people responsible per column and multiply it by 1.5 or 2. - -In order for this limiting of work to work, the Cards added must have a consistent size. General recommendations is that a card should be no more than 16 hours of work but no less than 10 hours. - -## Kanban vs Scrum Boards -[[Scrum (Agile)]] has their own board methodology, but the two are very similar despite their differences. -- Kanban is usually endless commitments while Scrum Boards have a designated start and stop for that particular board - - That is, Kanban boards are used throughout the entire development cycle while Scrum Boards are reset for each [[Sprints (Scrum)|Sprint]] -- Team Roles are explicitly defined in Scrum while Kanban is informal - - Both self-organize -- Kanban is generally more flexible with tasks and timing +The image above is NOT the guideline, but a recommendation. Keep it simple. --- diff --git a/300 Resources/Kanban vs Scrum.md b/300 Resources/Kanban vs Scrum.md index 0aa85e0..47fe71d 100644 --- a/300 Resources/Kanban vs Scrum.md +++ b/300 Resources/Kanban vs Scrum.md @@ -1,36 +1,10 @@ --- -tags: [note/info, 'agile', 'productivity'] +tags: [ info, 'agile', 'productivity' ] --- # Kanban vs Scrum [[Kanban (Agile)|Kanban]] and [[Scrum (Agile)|Scrum]] are different takes on [[Agile Project Management|Agile]]. Both are similar in this aspect, but they have nuanced approaches and workflows that support different environments. ![[Pasted image 20210914171447.png]] -## Understanding Scrum -Scrum are formally structured and presented through it's [[Sprints (Scrum)|Sprints]]. - -Sprints are blocked every 2-5 weeks with clear start and end dates. - -Being more formal, it has clearly defined roles: the Product Owner, Scrum Master, and the Development Team. - -Deliverable are typically released as a batch at the end of Sprints. - -The Key Metric of measurement is Velocity, the number of user stories completed per sprint. See [[Scrum Metrics]]. - -During a Sprint, ongoing planned work is NOT to be changed. Feedback is taken into account and noted for upcoming Sprints. Change occurs between Sprints to reflect customer needs. - -## Understanding Kanban -Kanban is a visualization of workflow to organize and limit work to promote [[Flow]]. In order to allow for this continuous flow, one must be adaptive to be flexible and adaptive. It's less formal than [[Scrum (Agile)|Scrum]] and can be thought as a more casual version of. - -Work is continuously fed and completed at whatever pace is needed according to Lead Time demands. **Work does not typically have a fixed due date.** - -The Kanban Board is managed by everyone, this is no Manager. - -Work is released whenever it's done rather than in formal batches. - -The Key Metric and productivity is measured by Lead Time, the time it takes for an item to get form Planned to Done. - -Kanban usually has a much lower overhead than Scrum, but can be prone to being chaotic due to it's less formal nature. Input that suggests change to ongoing work can and should be applied right away if needed. - **Sources** [Kanban vs Scrum | Atlassian](https://www.atlassian.com/agile/kanban/kanban-vs-scrum) \ No newline at end of file diff --git a/300 Resources/Life (LDP).md b/300 Resources/Life (LDP).md new file mode 100644 index 0000000..920ade6 --- /dev/null +++ b/300 Resources/Life (LDP).md @@ -0,0 +1,12 @@ +--- +aliases: Life +tags: [ info ] +--- +# Life (LDP) +**Life** is has ideals and values, which can the simplied into [[Pillars]]. These Pillars combine to make a [[Dynamics|Dynamic]], which can be thought of the very core of what kind of person this is. + +For example, someone who values the pillars: Family, Sustainability, and Experiences may have a dynamic of "someone who is an outgoing and valuable member to those who they consider family." Likewise, someone who values Inner Peace, Acceptance, and Life's Purpose can be thought of as "someone has become a monk to achieve greatness." + +The Pillars and Dynamic that are defined may not be be true in the present. This is fine and it's actually better to define them in the context of your ideals. Who do you want to be? That way you can start making changes to become who you truly want to be. + +You should also be looking for determining your [[Ikigai]], as this is a valuable idea to supporting those changes. \ No newline at end of file diff --git a/300 Resources/Ongoing Tasks.md b/300 Resources/Ongoing Tasks.md new file mode 100644 index 0000000..74ce937 --- /dev/null +++ b/300 Resources/Ongoing Tasks.md @@ -0,0 +1,8 @@ +--- +tags: [ info, 'productivity' ] +--- +# Ongoing Tasks +**When should I tag a `#task` as `#ongoing`?** +Tasks should be tagged as `#ongoing` when they are planned to be worked on right now (today). There should only be 3 to 5 tasks ongoing at any time. If you finish them early, feel free to add more, but don't overload yourself at the start of your day; your can discourage yourself and begin to procrastinate at your work load. + +Tasks tagged as `#ongoing` should never have their tag taken off except in the event the task is absolutely no longer relevant or something else has taken true priority over this task (e.g. something else is blocking this task). This is to stay determined and prevent switching over to what is immediately curious or satisfying. \ No newline at end of file diff --git a/300 Resources/Philosophy - How to Approach LDP.md b/300 Resources/Philosophy - How to Approach LDP.md new file mode 100644 index 0000000..31c1e89 --- /dev/null +++ b/300 Resources/Philosophy - How to Approach LDP.md @@ -0,0 +1,44 @@ +--- +aliases: +tags: [ info ] +--- +[[00 ❗ Readme|❗ Readme]] +# Philosophy - How to Approach LDP +## Build a System that Works for You +Do not blindly follow me for the easy way out. **My life is not your life.** You are helping no one, especially yourself. + +LDP is a **framework**. It's a foundation that is to be built by whoever utilizes it. You should always be asking the following two questions. +- "Why is something the way it is?" +- "How can I transform so it works even better for my needs?" + +> You should be asking yourself this for everything I say. + +## Keep It Clear, Simple, and Small +You should be able to sit down and immediately do what you want to do. + +LDP relies heavily on the idea of reducing [[Friction]]. This is one of many forces that push back when you try to do what you want to do. What you build from LDP should be clear, simple, and small. + +> No one wants to do work that takes days to complete. On the other hand, work for 30 minutes doesn't sound too bad. + +## Work in Passes +Do something, literally anything, that makes progress. Do the bare minimum now to establish structure and viability. You can always come back later to iterate on the ideas and do polish. + +This idea comes from [[Agile Project Management|Agile]] and it's derivative workflows, [[Scrum (Agile)|Scrum]] and [[Kanban (Agile)|Kanban]]. + +## Work Wide, not Deep + Work on everything at once to understand the bigger picture, then start to polish and tweak. Do not perfect one component and neglact work on the rest. Do not go deep without confirming the truth. Don't put all your eggs in one basket. + +For life-management, you are creating a [[Systems Thinking|System]]. Each component in a system multiplies with each other to create emergence and dynamics. + +> A set of chairs and a table combine to create a space of for common social ground. + +You have limited resources. Your continuous work on one component is additive with diminishing returns; reaching perfection is infinite. + +> A perfect set of chairs does not go well with a sub-par table. + +## Everything should be Relevant and Important +Save time and energy by working on the relevant and important. This is an idea borrowed from [[Minimalism]] to reduce noise and enhance focus. + +You don't need a hammer and nail to put up a picture. What you need is a way to have something you value easily within view. + +You also need to make sure everything makes sense given it's higher context. \ No newline at end of file diff --git a/300 Resources/Pillars, Pipelines, Vaults (PPV).md b/300 Resources/Pillars, Pipelines, Vaults (PPV).md index b0cfac9..c6e4d1c 100644 --- a/300 Resources/Pillars, Pipelines, Vaults (PPV).md +++ b/300 Resources/Pillars, Pipelines, Vaults (PPV).md @@ -1,13 +1,13 @@ --- aliases: PPV -tags: [note/info, productivity] +tags: [ info, productivity ] --- # Pillars, Pipelines, Vaults (PPV) **Pillars, Pipelines, Vaults (PPV)** is an extended and personalized take on [[Getting Things Done]] by [August Bradley](https://www.youtube.com/channel/UCfqj2oq6LVmR3ybC2nfjqKg). He suggests a [[Systems Thinking]] approach to organizing your life, and coins it as a life operating system. By viewing your entire life as a integrated and overlapping systems, new insights can be discovered. ## Objectives PPV has 3 primary objectives. -- **Focus**: to encourage [[Flow]] at times when you need it the most +- **Focus**: to encourage Flow at times when you need it the most - You should be able to sit down, see what you need to do, and immediately start working - **Alignment**: to ensure that work is directed and focused towards the right goals - You should know for sure that what you're doing will make progress towards something your goals @@ -49,7 +49,7 @@ Your personal knowledge database that should be able to be aggregated according - **Notes & Ideas Vault**: your own originals - **Tools & Skills Vault**: notes on software or on individuals -This is your [[Zettelkasten]], [[Link Your Thinking]], etc. +This is your Zettelkasten, Link Your Thinking, etc. ## Cycles Cycles are review sessions that ensure work remains consistent with Pipelines and Pillars. @@ -61,7 +61,7 @@ You should at least have... - one dedicated to taking Action per day, week, month, etc - one dedicated to realignment (Cycles) -These can be thought of as [[Map of Contents]]. +These can be thought of as Map of Contents. **Sources** [Intro & Overview of Pillars, Pipelines & Vaults – Notion Life Operating System - YouTube](https://www.youtube.com/watch?v=d93SGaf82OM) \ No newline at end of file diff --git a/300 Resources/Pillars.md b/300 Resources/Pillars.md index f874d84..87d6acc 100644 --- a/300 Resources/Pillars.md +++ b/300 Resources/Pillars.md @@ -1,11 +1,11 @@ --- aliases: Pillar -tags: [note/info, productivity, alignment, gamedev, original] +tags: [ info, productivity, alignment ] --- # Pillars **Pillars** are Values, Philosophies, Foundations, etc, that give direction and constraints to life or a [[Projects|Project]]. -Having direction opens up the vast future, but since it's near infinite, they also act as constraints to mitigate [[Decision Paralysis]]. +Having direction opens up the vast future, but since it's near infinite, they also act as constraints to mitigate Decision Paralysis. Pillars are prone to change over time, but regardless, careful consideration should be taken when defining the initial set of Pillars. Usually there are 3-8 Pillars for a Video Game, but in other topics it may vary different. These Pillars should lie flat, that is, there should be little to no overlap in what a Pillar encompasses. diff --git a/300 Resources/Product Backlog.md b/300 Resources/Product Backlog.md deleted file mode 100644 index 27c6c1c..0000000 --- a/300 Resources/Product Backlog.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -tags: [note/info, 'productivity', 'agile', 'gamedev'] ---- -# Product Backlog -The Product Backlog is a prioritized list of work based on a project's Roadmap and Requirements. Work presented this way is *pull-based*, as teams only work on what they can handle, not what the product owner pushes on to them. - -Roadmaps and Requirements are based on [[Work Hierarchy (Scrum)]], with Initiatives, Epics, and Stories. The product owner should compile, organize, and present work in a way that denotes highlights relations, blocked items, context, etc. - -Backlogs should be regularly maintained (groomed), reviewed before each [[Ceremonies (Scrum)#Sprint Planning|Sprint Planning]] to update since last [[Sprints (Scrum)]] and incorporate feedback. - -Once large enough, it's generally advised to split work into Near-Term and Long-Term work. Near-Term items are due soon and have been mostly fleshed out with idealized [[Work Hierarchy (Scrum)#Stories|Stories]], vision, and estimations. Long-Term items are the opposite, but should still have some priority towards becoming Short-Term. - -Change on the Backlog is expected, but be careful not to change it when work is in-progress as to retain focus, flow, and morale. - -> **Burndown Charts** are a visual aid that denotes how much work has been done so far. Comparing this to unfinished work, one can determine if the the team is behind to decide what to cut and better prioritize. - -**Source** -[[Agile Project Management]] -[The product backlog: your ultimate to-do list | Atlassian](https://www.atlassian.com/agile/scrum/backlogs) \ No newline at end of file diff --git a/300 Resources/Projects.md b/300 Resources/Projects.md index 4ceb37e..9bff3f1 100644 --- a/300 Resources/Projects.md +++ b/300 Resources/Projects.md @@ -1,43 +1,33 @@ --- aliases: Project -tags: [note/info, original, productivity] +tags: [ info, productivity ] --- # Projects **Projects** are derived from [[Disciplines]] and has some Objective that requires some set of [[Tasks]] complete. These Projects should make progress towards or uphold some [[Pillars|Pillar]] from the parent Discipline. Projects should strongly fit into one Discipline, and if it seems a Project could fit in multiple, the Disciplines need to be reorganized to prevent overlapping dependency, where too many items from one Discipline belong in another Discipline. Just combine the two or figure out some other way to have them clearly different. -Projects may also have [[Ceremonies (Scrum)|Ceremonies]] and a method of tracking [[Habits]]. - ## Scoping Projects will be of varying sizes and should be longer than 2 hours, as this is the arbitrary maximum length of [[Tasks]]. Since Tasks make up a Project, it's a given that Projects should be bigger than a Task. While there isn't a real maximum on how big a Project is, it's suggested to be no longer than a month, averaging several weeks. This duration is based on the general duration of a [[Sprints (Scrum)|Sprint]]. **And this is under the assumption that this Project is the ONLY thing you're working on.** Plan your Projects and focus according to your available TIme. -## Relations -Projects are immediately derived from [[Disciplines]], as a Project's Objective should be related to said Discipline's Pillars and/or Dynamics. +## Relations and Placement +Projects are immediately derived from [[Disciplines]], as a Project's Objective should be related to said Discipline's Pillars and/or Dynamics. That being said, Projects should live within a Discipline's folder. Tasks are largely derived from Projects to make lee-way towards meeting the Objective, which in term, meets the Discipline's Pillars and/or Dynamics. -## Important Setup -Projects must be tagged under YAML with `#note/project` and its corresponding Discipline Tag in order to be properly queried by Dataview. +## Abstract +Explains the context of the project. Generally discusses the following. +- Origins of what prompted this project +- Why this needs to come into fruition, as well as chaining into why what follows is important, and why what follows that is also important... etc +- Other things that can result from this project ## Objective -An Objective comes in two parts: Core and Abstract. All Objectives should answer the following questions. +All Objectives should minimally answer the following questions. - What will come to fruition? -- Why does this need to happen? - - What happens when it comes into fruition? What does it effect or mitigate? - How? What main methods or tools will be used to do this? -### Core -Should be concise enough to Display well on tables or lists during Alignment sessions. Optimally, you want to put it in a single sentence. - -### Abstract -Expands on the Objective, generally discussing the following. -- Origins of what prompted this project -- Repeating why this needs to come into fruition, as well as chaining into why what follows is important, and why what follows that is also important... etc -- Other things that can result from this project - ## Completion Criteria Unlike [[Disciplines]], Projects should eventually come to an end and shouldn't run any longer than 1 month. Since there usually isn't a time-based ending point ([[True Deadlines|True Deadline]]), an end must be defined through some other means. @@ -45,95 +35,9 @@ For Projects, a Completion Criteria is a well-defined checklist that cumulate to Well-Defined as in Requirements can be clearly answered `Yes` or `No` if they have been met. These Requirements should align with the Core. -While there is not hard limit of Completion Criteria count, it should be noted that these are essentially groupings for [[Tasks|Tasks]]. Having too much may hint at a Project that may take longer than 1 month, vice versa. +While there is not hard limit of Completion Criteria count, it should be noted that these are essentially groupings for [[Tasks|Tasks]]. Having too much Completion Critera may hint at a Project that may take longer than 1 month; vice versa. **All Projects should have Completion Criteria, but the Objective should come first.** -### Groups -Completion Criteria should also be categorized, or at least tagged under, some broad tagline under the Tag Group `#cc/`. How you group your Completion Criteria, or not at all, is up to you. - -This CC Tag Group will be used to align Tasks to this group of CC. - -It would seem that grouping by systems works quite will under the context of [[Agile Project Management|Agile]]. This assumes the Project can be decomposed into elements in a [[Systems Thinking|system]]. For example, for [[Life Disciplines Projects]], grouping by various systems allowed for passes on one component until functional, then moved onto the others. There's a final CC Tag Group which is specifically for polish, which consistently and routinely links everything together and makes it presentable. - -But in the event a Project can't be decomposed, or it's blocked solely due to time (e.g. other people, government), then grouping by phases could be the better way to go. - -There are other various ways to group, do what supports the project. - ## Alignment -Projects should be routinely reviewed to ensure that they progress towards some [[Pillars|Pillar]] denoted under its corresponding [[Disciplines|Discipline]]. It's suggested to do this review weekly. - -### Big Projects -There may be rare times in which a Project must take longer than a month. With a similar reasoning as to why Tasks are no longer than 2 hours, the size of these Projects may create friction and reluctance in their undertaking. - -If a Project is believed to be longer than such, deconstruct it into clearly different Projects to make it more approachable. If it's sequential, set the later Projects On-Hold or as a Task under that Discipline. - -If deconstructing it into clearly different Projects is not possible, **your last resort** would be to have a Big Project and Sub-Projects to denote phases and milestones. Project Folders should be nested accordingly. - -## Folders and Organization -Projects should have their own dedicated folder. [[Projects#Big Projects|Big Projects]] also have their own dedicated folder. - -## YAML -Projects will always have YAML on the top of them, denoting which Discipline they belong on, among other things. All of these values you must update manually. - -### discipline -Denotes the Discipline that this Project belongs to. It should also be in its corresponding folder. Do not assign a link as a value. - -### status (YAML) -Denotes the current Status of this Project. See [[Projects#Status]]. - -### start -Denotes when the Project is set to **00 Ongoing**, NOT when the Dashboard was created. - -### due -When the deadline of a project is. - -Similar to [[Tasks#Creation#Due Date]], due dates should only be assigned for [[True Deadlines]]. - -This value should also NOT be infinite. Being infinite indicates that this Project is infinitely large, and should have been a [[Disciplines|Discipline]]. This also lowers drive, as the deadline is infinitely far. - -It should also NOT be -infinite. Being -infinite logically means that this project is way infinitely over its deadline. Whether that brings dead or immense hustle, either is doomed to despair. - -### end -Denotes when the Project is set to **Done** or **Stale**. - -### objective (YAML) -This should be exactly the same as the Project Objective's one sentence summary. - -### priority -This should follows the same methodology as [[Tasks#Priority]]. - -## Status -Projects will have the following Statuses as values in their Status YAML field. Ignore `inline` formatting and only use plain text. - -### Active -#### 00 Ongoing -Defined as a Project that has been setup to do immediate work. If it's still in the setup phase, it should be `02 Planned`. - -#### 01 Blocked -Defined as a Project that was *unwillingly* put stalled. Clearing this blockage takes urgency as resuming the project becomes top priority. - -#### 02 Planned -Defined as a Project that is *Ongoing*, but real work has not started. We are still defining what this Project is, and maybe if we're actually going to execute it to begin with. - -### Inactive -#### 03 On-Hold -Defined a Project that was *willingly* put stalled, which may or may not be resumed. Reviews and Alignments will judge whether the project stays alive. Reasons why vary on a Project may be put on Hold, with some reasons listed below. - - Lost relevancy towards a Discipline - - Lost Velocity or Motivation - -#### 04 Done -Defined as a Project that has all of it's Completion Criteria. With regards to Polish tag `#cc/poi`, this Criteria does not have to be completed, as polishing a Project is subjective and can be infinitely demanding. - -#### 99 Stale -Defined as a project that is no longer relevant. - -## Ceremonies -Ceremonies might be used to prepare one's self for adversity that is this Project's work. - -A simple example of a Ceremony is a set of movements to warm up before a session on a new workout schedule. - -See [[Ceremonies]] for full details on how they operate. - -## References -[[99 (OLD) Workflow Overhaul]] \ No newline at end of file +Projects should be routinely reviewed to ensure that they progress towards some [[Pillars|Pillar]] denoted under its corresponding [[Disciplines|Discipline]]. It's suggested to do this review weekly. \ No newline at end of file diff --git a/300 Resources/Scrum (Agile).md b/300 Resources/Scrum (Agile).md index b686c1d..ea359d2 100644 --- a/300 Resources/Scrum (Agile).md +++ b/300 Resources/Scrum (Agile).md @@ -1,19 +1,11 @@ --- aliases: Scrum -tags: [note/info, 'productivity', 'agile', 'gamedev'] +tags: [ info, 'productivity', 'agile' ] --- # Scrum (Agile) **Scrum** is one of many methodologies build under the principles laid out by [[Agile Project Management|Agile]]. As such, teams are encouraged to self-organize and work in increments, eventually learning through experiences. They will routinely reflect on work and improve workflow. -Scrum limits teams to 7-10 (though 4.6 is perfect according to [Hackerman and Vidmar](https://www.atlassian.com/agile/scrum/scrum-of-scrums)). This to allow team members to create trust, respect, and alignment. Larger teams typically have a harder time doing this and will even naturally segment into smaller social groups. Scaling Scrum then becomes a problem, and is solved via [[Scrum of Scrums]]. Scrum can be done in-person or remotely (see [[Distributed Scrum]]). - -One person is denoted as the [[Scrum Master]] to lead the charge. This person mainly mandates the [[Ceremonies (Scrum)|Ceremonies]] that take place during the sprint (e.g. meetings). - -[[Sprints (Scrum)|Sprints]] and their [[Artifacts (Scrum)|Artifacts]] are a core element of Scrum that actively partition work into manageable, iterative chunks. - -Work generated and organized for Scrum can be described as daily work, the bigger picture, and the vision. See [[Work Hierarchy (Scrum)|Work Hierarchy]] on how work is organized. All if not most of this to-do work is placed on the [[Sprint Backlog]], whose items are derived from the [[Product Backlog]]. - -[[Scrum Metrics]] are a means to measure performance. +Work generated and organized for Scrum can be described as daily work, the bigger picture, and the vision. See [[Work Hierarchy (Scrum)|Work Hierarchy]] on how work is organized. Another popular iteration of Scrum is [[Kanban (Agile)]]. To better understand comparisons between the two, see [[Kanban vs Scrum]]. diff --git a/300 Resources/Scrum Metrics.md b/300 Resources/Scrum Metrics.md deleted file mode 100644 index b4d8f33..0000000 --- a/300 Resources/Scrum Metrics.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -tags: [note/info, ] ---- -# Scrum Metrics -**Scrum Metrics** are points of data that can be collected during [[Scrum (Agile)]] to document and eventually analyze performance for efficiency. There are some things that can only be realized through raw data. - -While you can use [[Key Performance Indicators]] as a metric, you must remember that [[Agile Project Management]] favors individuals over processes and tools, and as such, you should be looking for Customer and Team Satisfaction. Return on Investment is also an important Metric to measure. - -## Metrics on Sprint Planning -Look to measure the following. -- difficulty and amount of sprint goals -- team confidence and **velocity** (productivity) - - the number of stories completed per sprint -- type of work - -## Metrics on Stand-ups (Scrum) -Look to measure the following. -- if actual progress is being made according to sprint goals -- if work is being well distributed - -## Metrics on Retrospectives -Look to measure the following. -- the actual progress made and if goals were checked off - - was everything completed way earlier than expected? -- sprint satisfaction - -**Sources** -[Scrum metrics | Atlassian](https://www.atlassian.com/agile/scrum/scrum-metrics) \ No newline at end of file diff --git a/300 Resources/Simple Integration Into Obsidian.md b/300 Resources/Simple Integration Into Obsidian.md new file mode 100644 index 0000000..616fb4b --- /dev/null +++ b/300 Resources/Simple Integration Into Obsidian.md @@ -0,0 +1,57 @@ +--- +aliases: +tags: [ info ] +--- +## Simple Integration Into Obsidian +### Why Obsidian? +Obsidian is an enhanced, barebones markdown text editor. What makes it optimal is that users can use community plugins to customize and personalize functionality far beyond what it initially intended for. You are building your own system after all. + +There's the added plus that all documents are locally stored on your computer as plain text. There is no dependence on a cloud or server, the only dependence is you (and your compluter). There's also the sense of ownership and historical documentation. Everything is yours; just yours. + +And that just felt right. + +### Some Assumptions +I assume that you are familar with the basics of Obsidian. If not, please press F1 and take a look at the manual. Also consider some Youtube videos. Moving on! + +### Folder Naming +You've probably noticed by now but the folders on the left have a numbered prefix. This is a concept borrowed from the Dewey-Decimal System, where libraries organize their books by numbers. It's modified to do just that, within the digital world, it also organizes the notes. Notice how `Inbox` comes first, not `Archive`. This can also be used to sticky notes to the top of a folder, like `🏠 Main Dashboard`. + +Not everything follows this system; it isn't consistent. I recommend you do this for Disciplines so your most important one, your [[Ikigai]], is the first thing you see. I do not recommend this for projects since order has little to no value. + +> tl;dr - Dewey-Decimal System for when grouping and ordering matters. + +### Folder Hierarchy +Projects are placed within Disciplines, and Disciplines are placed within Life, which is the root of the vault. + +> Life > Disciplines > Projects + +### Dashboards +Dashboards are as the master note for whatever it serves. A dashboard for Life [[99 💗 Life]] is where you would define everything related to your Life under the premise of LDP. + +You want one for Life, all Disciplines, and all Projects. They can also be used in tandem with [[#Obsidian Plugins]]. + +They can also be used as a portal to see what you need to do right now. See [[00 🏠 Main Dashboard|🏠 Main Dashboard]] for an example. + +### Obsidian Plugins +If there's some extra functionality you want that can make your personalized system easier, it probably exists. + +Here are some important plugins I consider core. These plugins have been included for this demo. +- [Obsdian Tasks](https://github.com/schemar/obsidian-tasks) for managing all your tasks +- [obsidian-calendar-plugin](https://github.com/liamcain/obsidian-calendar-plugin) for visual routine alignment +- [Periodic Notes](https://github.com/liamcain/obsidian-periodic-notes) for routine alignment +- [Templater](https://github.com/SilentVoid13/Templater) to reduce friction and quickly set up new disciplines, projects, and tasks (which reduces friction) +- [Natural Language Dates in Obsidian](https://github.com/argenos/nldates-obsidian) for inserting dates in natural english + +There are many, many other plugins that you might find useful. Do your own research. + +> A simple implementation of Obsidian Tasks has already been implemented. Tasks can be tagged with `#ongoing` to mark them as an Ongoing task. + +### Alignment +Routine alignment is done through [obsidian-calendar-plugin](https://github.com/liamcain/obsidian-calendar-plugin) and [Periodic Notes](https://github.com/liamcain/obsidian-periodic-notes). They are placed under `200 Alignment`. + +### Personal Knowledge Base (PKM) +Obsidian is known to be a link-based note taking platform. Most follow some form of Zettelkasten or other graph-based organization of notes. Your PKM should stand next to LDP, but should not be tightly integreted. + +I recommend you create a folder the root of your vault, completely dedicated to your PKM. You can then pull these notes into Projects, create further notes, and then push them back into your PKM. Your PKM will maintain whatever structure it currently is. + +For this demo, they are placed under `300 Resources`. \ No newline at end of file diff --git a/300 Resources/Sprint Backlog.md b/300 Resources/Sprint Backlog.md deleted file mode 100644 index c8048c9..0000000 --- a/300 Resources/Sprint Backlog.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -tags: [note/info, 'agile', 'productivity'] ---- -# Sprint Backlog -The **Sprint Backlog** is an [[Artifacts (Scrum)]] that contains partitioned items from the [[Product Backlog]]. It's designed for the upcoming product increment ([[Sprints (Scrum)|Sprint]]) and is created during the [[Ceremonies (Scrum)#Sprint Planning|Sprint Planning]] phase of Scrum. - -**Source** -[[Artifacts (Scrum)]] \ No newline at end of file diff --git a/300 Resources/Sprints (Scrum).md b/300 Resources/Sprints (Scrum).md index bcc418b..bfe577d 100644 --- a/300 Resources/Sprints (Scrum).md +++ b/300 Resources/Sprints (Scrum).md @@ -1,6 +1,6 @@ --- -aliases: [Sprint, Sprints] -tags: [note/info, 'productivity'] +aliases: [ Sprint, Sprints ] +tags: [ info, 'productivity' ] --- # Sprints (Scrum) **Sprints** are a core concept of [[Scrum (Agile)]]. Sprints themselves are iterative, short time-boxed periods for completing a defined set of of work. Typically they last 2 weeks, but can be longer up to a month. diff --git a/300 Resources/Suggestions After Learning Initial LDP.md b/300 Resources/Suggestions After Learning Initial LDP.md new file mode 100644 index 0000000..5f38d57 --- /dev/null +++ b/300 Resources/Suggestions After Learning Initial LDP.md @@ -0,0 +1,10 @@ +--- +aliases: +tags: [ info ] +--- +## Suggestions After Learning Initial LDP +Remember the first philosophy of LDP: [[#Build a System that Works for You]]. Once you're familiar with the concepts, your next steps moving forward should be to start to deriving your own system. I provided with you the bare minimum to reduce rigidity and allow for organic development. + +Do not worry doing things right. Just start and you'll naturally discover your own derivative from LDP. + +At the very least, you should at least set up your own Discipline and put some though in your [[99 💗 Life|Life Dashboard]]. For a guided, bottom-up approach for personal exploration and setting up the system, see [[00 🧰 Setup|🧰 Setup]]. \ No newline at end of file diff --git a/300 Resources/Systems Thinking.md b/300 Resources/Systems Thinking.md index ba74465..5806582 100644 --- a/300 Resources/Systems Thinking.md +++ b/300 Resources/Systems Thinking.md @@ -1,24 +1,14 @@ --- -tags: [note/info, productivity] +tags: [ info, productivity ] --- # Systems Thinking -Systems Thinking is a methodology of thought such that a singular component, or system, is part of many other systems. It examines and analyses beyond the problem and into how other elements contribute to helping or hindering progress. +**Systems Thinking** is a methodology of thought such that a System is merely a component of many other systems. With this in mind, one can examine and analyses how other those systems contribute or hindering activity. -> Sociology follows a similar thought processing as Systems Thinking. +You can think of this as [[Dynamics]] but the components themselves are Systems. -**Emergence** is defined as the Dynamics and functions that become realized when a system interacts with others. Also see [[Mechanics-Dynamics-Aesthetics#Dynamics|MDA]] +> Sociology follows a similar thought process as Systems Thinking. -To identify Systems and reason with them, consider the following. -1. Define the I/O and the Movements -2. Define if the system is liner or circular - - Is there no modification to the input after it goes in? - - Does additional input affect a processing output? - - Does the output affect the input? -3. Look for patterns -4. Find feedback loops -5. Understand checks and balances - - Considering feedback loops, how does the system stay in control? -6. What larger system is this system part of? +Fundamental knowledge of Systems can be found in [[Systems]]. **Source** [[Pillars, Pipelines, Vaults (PPV)]] diff --git a/300 Resources/Systems.md b/300 Resources/Systems.md new file mode 100644 index 0000000..876a0fa --- /dev/null +++ b/300 Resources/Systems.md @@ -0,0 +1,10 @@ +--- +aliases: null +tags: [ info ] +--- +# Systems +A **System** is a group of components that share and process a common form of input to create a new function, experience, or product. This is thought of as the [[Dynamics|Dynamic]]. + +Input can vary greatly, from human interaction, numbers, water, etc. Input can also come into the system at different steps of processing, not just at the start. Systems can also be self-regulating and provide input to itself, creating a feedback loop. They also usually always have patterns of sorts. + +Systems can also be components of other systems. See [[Systems Thinking]]. \ No newline at end of file diff --git a/300 Resources/Tasks.md b/300 Resources/Tasks.md index b1fc338..3b62285 100644 --- a/300 Resources/Tasks.md +++ b/300 Resources/Tasks.md @@ -1,11 +1,11 @@ --- aliases: [ Task, Task (Concept), Tasks (Concept) ] -tags: [note/info, original, productivity] +tags: [ info, productivity ] --- # Tasks **Tasks** are Actionable items with a clearly defined completion. You should be able to read this Task and trivially answer `Yes` or `No` as to if this Task is complete. -Tasks should work towards some Objective denoted in the corresponding [[Projects|Project]]; or uphold or works towards some [[Disciplines|Discipline]]. Tasks that do not to this are considered [[#Casual Tasks|Casual Tasks]]. +Tasks should work towards some Objective denoted in the corresponding [[Projects|Project]]; or uphold or works towards some [[Disciplines|Discipline]]. Tasks are Pull-based, meaning pull a task into your *Working On* list as you have more free hands, up to the [[#Ongoing]] limit. This concept of Pulling is similar to [[Kanban (Agile)|Kanban]]'s task management. @@ -15,132 +15,29 @@ Tasks are largely related to [[Projects]] as Tasks make lee-way towards its Obje Tasks may also be a part of Disciplines and Life as needed. ## Alignment -It's highly suggested to routinely review all ongoing tasks to make sure they align with the corresponding Project. Do this on a daily basis. Backlogged tasks may not need to be reviewed, but should be groomed to prevent [[Feature Creep]]. - -## Aggregation -Task queries aggregate all tasks within its own folder and sub folders. +It's highly suggested to routinely review all ongoing tasks to make sure they align with the corresponding Project. Do this on a daily basis. Backlogged tasks may not need to be reviewed, but should be groomed to prevent Feature Creep. ## Formatting The format of tasks should follow the following format. -> - [ ] #task `<#priority_tag>` `<#est_duration>` `[#hb]` task description with clear language of doneness `[#cc/group` `[#ongoing]` `[#exclude[/tag][reason]]` `[📅 YYYY-MM-DD]` +> - [ ] #task `` `[📅 YYYY-MM-DD]` `[#ongoing]` `< >` - required `[ ]` - optional -`#task` and the Due Date `[📅 YYYY-MM-DD]` can be automatically handled by the Task Plugin. - -Ongoing and exclude can go in any order. - -`#hb` tags this Task as a Habit. - -## Completion Criteria Tag -All tasks under a Project should be tagged with one or more `#cc/group`, where `group` defines the Completion Criteria Group. - -Tasks tagged with this Completion Criteria Group are related to these groups. See [[Projects#Completion Criteria]] for more details on the Groups. - -## Dealing with Blocked Tasks -Both a [[Tasks#blocking|Blocking]] Task and its corresponding [[Tasks#blocked|Blocked]] should be given a `/key` on it's `#blocking`/`#blocked` to link them together. This is to easily relate the two by query or visual confirmation. - -Ideally Blocked and Blocking Tasks should already be close together, but sometimes that's just not the case. - -> We can't nest Tasks because it breaks workflow support from plugins, so since all Tasks are on the same level it may be difficult to discern related Blocked/Blocking Tasks, hence the Tagging. - -**Once Blocked/Blocking items are complete, you must remove the `/key` (or just remove the entire block tag).** This is to ensure these keys can be reused. +`#task` and the Due Date `[📅 YYYY-MM-DD]` can be automatically handled by the [Obsdian Tasks](https://github.com/schemar/obsidian-tasks) or with the [[Due]] template and [Natural Language Dates in Obsidian](https://github.com/argenos/nldates-obsidian) -## Due Date +### Due Date Similar to [[Projects#YAML#due]], this should only be set for [[True Deadlines]]. -## Location -In order for proper aggregation, Tasks should be created in locations as follows. -- Tasks relating to a Project should be placed somewhere in its Project folder. Preferably it goes into it's `[[Tasks Project#Raw]]` Note. -- Tasks related to a Discipline and not ongoing Project should be placed within the `[[Tasks Discipline#Raw]]` Note. -- Casual Tasks, ones that don't relate to a Discipline or Project, should be placed in the generic Tasks Casual Note on root. - -All tasks, when complete and *need to be out of the way*, should be moved to it's respective `Archived` section, usually located in the `[[Tasks ]]` Note. - -## Priority -Tasks will always have a Priority Tag. Priority follows the [[Eisenhower Matrix]]. - -To reduce overhead, Priority will be represented with bits. - -| Urgent | Important | Result | -| ------:|:--------- | ------ | -| 1 | 1 | 11 | -| 1 | 0 | 10 | -| 0 | 1 | 01 | -| 0 | 0 | 00 | - -This also sorts well descending. -11 > 10 > 01 > 00 - -Since tags cannot only be numbers, a `p` will be prepended to the bits. - -With this, allowed Priority Tags are as follows. -- `#p11` -- `#p10` -- `#p01` -- `#p00` - -## Estimated Duration -Tasks will always have an Estimated Duration tag. This is NOT a due date. Allowed duration tags are as follows. -- `#00m` -- `#15m` -- `#30m` -- `#01h` -- `#02h` - -Estimated should round up. Tasks should never be longer than 2 hours. - -`#00m` is reserved for **Reminders**, which are tasks that you estimate take less than 5 minutes to complete. - -## Ongoing +### Ongoing The Task is currently being worked on should have the `#ongoing` Tag on it. -All `#ongoing` Tasks will be aggregated onto a [[Pillars, Pipelines, Vaults (PPV)#Dashboards|Dashboard]]. +All `#ongoing` Tasks will be aggregated by Tasks query. -There should be no more than 3 `#ongoing` tasks per Project, with a **global limit** of 4. That is, there should never be 4 tasks you queue to wok for at once. +There should be no more than 4 `#ongoing` tasks at any time. This is to reduce friction. See [[Ongoing Tasks]] on what constitutes as an `#ongoing` task. -## Status -Status indicate the current status of a note. - -### (no status) -The task is normal. Handle this task based on its priority and whenever your hands are free. - -### blocked -This Task is unwillingly stalled because of something. It should have nested tasks below it with at least an Urgent priority. This Task Blocked Task should also be tagged with `#blocked`. - -### blocking -This Task is Blocking some Task. It usually should be nested above some other Task, which means it is Blocking that Blocked task, which should have the `#blocked` tag. - -These Blocking tasks should have the `#blocking` task, and their priority should be at least Urgent `#p10`, if not Urgent and Important `#p11`. - -### exclude/on-hold -These Tasks share similarities with the `03 On-Hold` status under [[Projects#status|Projects]]. For Tasks, it means that it was willingly put stalled and may or may not be resumed. If not, it will become Stale. These Tasks should be marked as `#exclude/on-hold`. - -### exclude/stale -Tasks may be come irrelevant due to the passage of time and or a change in interest. A Task that has become irrelevant should be marked as `#exclude/stale` AND checked off as "Done". This will append a Completion Date and will be used for aggregation and analysis. - -There is something wrong if you find that during a Alignment, you find that you have a lot of Stale Tasks. Projects will shift direction from time to time and many Tasks going stale may be expected, but if you find yourself consistently Stale'ing Tasks, it's possible you are not thinking before putting down a Task or you can't stabilize a Project's Objective. - -> Grouped under exclude to reduce overhead queries. - ## Size -Tasks themselves should be broken down such that they take no longer than 2 hours to complete. This 2 hour duration is an arbitrary cutoff, and is based on the idea that if a task is expected to take longer than that, there will be some [[Friction]] and reluctance to its undertaking. - -## Casual Tasks -**Casual Tasks** are *reminders* that let you know there's something you need to take care. They should be dealt with soon (<48h) and should be trivial to complete in effort and time. They should not make leeway towards Project Objectives or Discipline [[Pillars|Pillar]], but may uphold a Pillar. If they make leeway, they might be better represented as a task following a Discipline or existing Project. - -> You might consider these Casual Tasks as automatically urgent. - -Examples include... -- reminder to buy a specific food because you're out -- reminder to restock supplement stacks since you ran out -- reminder to do laundry because you have no clean clothes. - -These Tags should be placed somewhere at the Root folder (e.g. Ramblings). - -**Source** -[[99 (OLD) Workflow Overhaul]] \ No newline at end of file +Tasks themselves should be broken down such that they take no longer than 2 hours to complete. This 2 hour duration is an arbitrary cutoff, and is based on the idea that if a task is expected to take longer than that, there will be some [[Friction]] and reluctance to its undertaking. \ No newline at end of file diff --git a/300 Resources/True Deadlines.md b/300 Resources/True Deadlines.md new file mode 100644 index 0000000..97a74fd --- /dev/null +++ b/300 Resources/True Deadlines.md @@ -0,0 +1,12 @@ +--- +aliases: True Deadline +tags: [ info ] +--- +# True Deadlines +**True Deadlines** are deadlines that must be met or else repercussions are soon to occur. + +This is different from an arbitrary Deadline as casually setting Deadlines usually do not come with any immediate repercussion. Usually one would do this to provoke hustle from an individual, and while it may work, it can cause unnecessary stress and lower quality as one focuses on time rather than quality. + +With time, one might waver when dealing with Casual Deadlines. And if one does, the immediate repercussions are not transparent. The repercussion is a shift in mindset where True Deadlines are now viewed as Casual Deadlines. True Deadlines have become less important. + +**Setting up a deadline solely for hustle is not worth lowering the value of a deadline.** \ No newline at end of file diff --git a/300 Resources/Work Hierarchy (Scrum).md b/300 Resources/Work Hierarchy (Scrum).md index 3266dd6..ffc5d10 100644 --- a/300 Resources/Work Hierarchy (Scrum).md +++ b/300 Resources/Work Hierarchy (Scrum).md @@ -1,6 +1,6 @@ --- aliases: Work Hierarchy -tags: [note/info, productivity, agile, gamedev] +tags: [ info, productivity, agile ] --- # Work Hierarchy (Scrum) Work (tasks) are simplified to three tiers, but can have more. From lowest to highest: **(User) Stories**, **Epics**, **Initiatives**. Stories are based on Epics, and Epics are based on Initiatives. diff --git a/300 Resources/Working with LDP.md b/300 Resources/Working with LDP.md new file mode 100644 index 0000000..89a6850 --- /dev/null +++ b/300 Resources/Working with LDP.md @@ -0,0 +1,36 @@ +--- +aliases: +tags: [ info ] +--- +[[00 ❗ Readme|❗ Readme]] +# Working with LDP +Typical workflows are as follows. There is no particular ordering of the groupings below. + +## I have found an area of skills I'm interested in and would like to invest my resources into it. +Create a new discipline and start fleshing it out. + +## I have to get something done but it's not yet in the system. +Would this take longer than 2 hours? +- If yes, consider the following + - Break it down into elements smaller than 2 hours, then ask the question for each element, or... + - Turn it into a Project +- If no, add it as a Task in the system within the proper context + +## I have some random thoughts or need a workspace to organize ideas. +Create a note in the lowest-ordered context folder (or a global Inbox) and start rambling. + +In other words, if you have thoughts about an ongoing project, put those thoughts in that project. If you have thoughts about a discipline, not relating to any ongoing projects, put it under the discipline. + +## I finished my task and/or have time to do work. +Look at any of your incompleted Tasks in the system and choose a small set (<3) that can fit your time constraint. Set it as **Ongoing** and work on it, or... + +Look for any existing **Ongoing** Task. Work on it. + +## I need to make sure my work is still relevant. +Do [[#Alignment]]. + +##### I have a Task that is no longer relevant. +Delete it if it has absolutely has potential for relevance in the future. And if it has potential, archive it. + +## I just finished a Project. I also have a Project or Discipline that's no longer Relevant. +Move it to an Archive section so it's out of your way when you looking at everything else. \ No newline at end of file diff --git a/300 Resources/scrum_process_atlassian.svg b/300 Resources/scrum_process_atlassian.svg new file mode 100644 index 0000000..ee25f61 --- /dev/null +++ b/300 Resources/scrum_process_atlassian.svg @@ -0,0 +1,540 @@ + + + + +Artboard 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/700 Views/Curation.md b/700 Views/Curation.md deleted file mode 100644 index bd183c5..0000000 --- a/700 Views/Curation.md +++ /dev/null @@ -1,6 +0,0 @@ -#### Curation -```query -(tag:#example_discipline) -``` - -Use the `QuickAdd: Insert Chaotic Note Roller` or Vantage to finely search for notes with specific tags. Chaotic has a lot of visual overhead compared to Vantage, but is good for when stuck. \ No newline at end of file diff --git a/700 Views/Disciplines (View).md b/700 Views/Disciplines (View).md deleted file mode 100644 index 2f6054c..0000000 --- a/700 Views/Disciplines (View).md +++ /dev/null @@ -1,8 +0,0 @@ -```dataview -TABLE WITHOUT ID - link(file.name, default(link(file.name).aliases, link(file.name).name)) as "Discipline", - pillars as "Pillars", - dynamic as "Dynamic" -FROM #note/discipline and -"900 Archive" and -"Templates" -SORT due asc -``` \ No newline at end of file diff --git a/700 Views/Habits (View).md b/700 Views/Habits (View).md deleted file mode 100644 index f22600a..0000000 --- a/700 Views/Habits (View).md +++ /dev/null @@ -1,13 +0,0 @@ -#### Habits Today -```tasks -not done -due today -description includes #hb -``` ---- -#### Habits Overdue -```tasks -not done -due before today -description includes #hb -``` \ No newline at end of file diff --git a/700 Views/Ikigai (View).md b/700 Views/Ikigai (View).md deleted file mode 100644 index 8a5b692..0000000 --- a/700 Views/Ikigai (View).md +++ /dev/null @@ -1,12 +0,0 @@ -```dataview -TABLE WITHOUT ID - link(file.name, default(aliases, name)) as "Ikigai(s)", - dynamic as "Dynamic" -FROM #note/ikigai -``` -```dataview -TABLE WITHOUT ID - link(file.name, default(aliases, name)) as "Ikigai(s)", - pillars as "Pillars" -FROM #note/ikigai -``` \ No newline at end of file diff --git a/700 Views/Life Dynamic.md b/700 Views/Life Dynamic.md deleted file mode 100644 index 0bcf0d7..0000000 --- a/700 Views/Life Dynamic.md +++ /dev/null @@ -1,6 +0,0 @@ -```dataview -TABLE WITHOUT ID - dynamic as "Life Dynamic" -FROM "/" -WHERE contains(file.aliases, "💗 Life") -``` \ No newline at end of file diff --git a/700 Views/Life Pillars.md b/700 Views/Life Pillars.md deleted file mode 100644 index 639bfb2..0000000 --- a/700 Views/Life Pillars.md +++ /dev/null @@ -1,6 +0,0 @@ -```dataview -TABLE WITHOUT ID - pillars as "Life Pillars" -FROM "/" -WHERE contains(file.aliases, "💗 Life") -``` \ No newline at end of file diff --git a/700 Views/Ongoing Project Reference.md b/700 Views/Ongoing Project Reference.md deleted file mode 100644 index bf95532..0000000 --- a/700 Views/Ongoing Project Reference.md +++ /dev/null @@ -1,13 +0,0 @@ -### Ongoing Project Reference -```dataview -TABLE objective as "Objective" -FROM #note/project and -"888 Templates" -WHERE status = "00 Ongoing" or status = "02 Planned" and file.name != "Dashboard Project" -SORT due asc, urgent asc, important asc -``` -### CC -```dataview -TASK -FROM #note/project and !"Templates" -WHERE file.status = "00 Ongoing" or file.status = "01 Blocked" or file.status = "02 Planned" or file.status = "03 On-Hold" and name != "Dashboard Project" -``` \ No newline at end of file diff --git a/700 Views/Project-Disciplines Touched Last Month.md b/700 Views/Project-Disciplines Touched Last Month.md deleted file mode 100644 index 66d0a72..0000000 --- a/700 Views/Project-Disciplines Touched Last Month.md +++ /dev/null @@ -1,9 +0,0 @@ -```dataview -TABLE WITHOUT ID - link(file.name, default(link(file.name).aliases, link(file.name).name)) as "Discipline", - pillars as "Pillars", - dynamic as "Dynamic" -FROM #note/discipline and -"Templates" -WHERE end < date(today) + dur(1 days) or start > date(today) - dur(7 days) or (file.mtime < date(today) + dur(1 days) and file.mtime > date(2021-09-27) - dur(7 days)) -SORT due asc -``` \ No newline at end of file diff --git a/700 Views/Project-Disciplines Touched Last Week.md b/700 Views/Project-Disciplines Touched Last Week.md deleted file mode 100644 index c5cae90..0000000 --- a/700 Views/Project-Disciplines Touched Last Week.md +++ /dev/null @@ -1,9 +0,0 @@ -```dataview -TABLE WITHOUT ID - link(file.name, default(link(file.name).aliases, link(file.name).name)) as "Discipline", - pillars as "Pillars", - dynamic as "Dynamic" -FROM #note/discipline and -"Templates" -WHERE end < date(today) + dur(1 days) or start > date(today) - dur(7 days) or (file.mtime < date(today) + dur(1 days) and file.mtime > date(today) - dur(7 days)) -SORT due asc -``` \ No newline at end of file diff --git a/700 Views/Projects Touched Last Month.md b/700 Views/Projects Touched Last Month.md deleted file mode 100644 index ac9747e..0000000 --- a/700 Views/Projects Touched Last Month.md +++ /dev/null @@ -1,9 +0,0 @@ -```dataview -TABLE WITHOUT ID - link(file.name, default(link(file.name).aliases, file.name)) as "Project", - objective as "Objective", - link(discipline, link(discipline).aliases) as "Discipline" -FROM #note/project -WHERE file.mtime >= date(today) - dur(1 month) and file.mtime < date(today) -SORT due asc -``` \ No newline at end of file diff --git a/700 Views/Projects Touched Last Week.md b/700 Views/Projects Touched Last Week.md deleted file mode 100644 index 0c9bc2e..0000000 --- a/700 Views/Projects Touched Last Week.md +++ /dev/null @@ -1,9 +0,0 @@ -```dataview -TABLE WITHOUT ID - link(file.name, default(link(file.name).aliases, file.name)) as "Project", - objective as "Objective", - link(discipline, link(discipline).aliases) as "Discipline" -FROM #note/project -WHERE file.mtime < date(today) + dur(1 days) and file.mtime > date(today) - dur(7 days) -SORT due asc -``` \ No newline at end of file diff --git a/700 Views/Recently Touched.md b/700 Views/Recently Touched.md deleted file mode 100644 index 948e656..0000000 --- a/700 Views/Recently Touched.md +++ /dev/null @@ -1,7 +0,0 @@ -#### Recently Touched -```dataview -LIST -FROM "/" -SORT file.mtime DESC -LIMIT 20 -``` \ No newline at end of file diff --git a/700 Views/Reminder.md b/700 Views/Reminder.md deleted file mode 100644 index e32d6ce..0000000 --- a/700 Views/Reminder.md +++ /dev/null @@ -1,7 +0,0 @@ -#### Reminder -```tasks -not done -description includes #00m -description does not include #ongoing -description does not include #exclude -``` \ No newline at end of file diff --git a/700 Views/Tasks Completed Last Week.md b/700 Views/Tasks Completed Last Week.md deleted file mode 100644 index 97982a9..0000000 --- a/700 Views/Tasks Completed Last Week.md +++ /dev/null @@ -1,76 +0,0 @@ -### Tasks -##### Filter None -```tasks -done after last week -done before next week -description does not include #note/project -hide edit button -``` - -##### Filter Priority -###### p11 -```tasks -done after last week -done before next week -description includes #p11 -description does not include #note/project -hide edit button -``` -###### p10 -```tasks -done after last week -done before next week -description includes #p10 -description does not include #note/project -hide edit button -``` -###### p01 -```tasks -done after last week -done before next week -description includes #p01 -description does not include #note/project -hide edit button -``` -###### p00 -```tasks -done after last week -done before next week -description includes #p00 -description does not include #note/project -hide edit button -``` - -##### Filter Duration -###### 02h -```tasks -done after last week -done before next week -description includes #02h -description does not include #note/project -hide edit button -``` -###### 01h -```tasks -done after last week -done before next week -description includes #01h -description does not include #note/project -hide edit button -``` -###### 30m -```tasks -done after last week -done before next week -description includes #30m -description does not include #note/project -hide edit button -``` -###### 15m -```tasks -done after last week -done before next week -description includes #15m -description does not include #note/project -hide edit button -``` \ No newline at end of file diff --git a/700 Views/Tasks Completed Today.md b/700 Views/Tasks Completed Today.md deleted file mode 100644 index d5a6e1d..0000000 --- a/700 Views/Tasks Completed Today.md +++ /dev/null @@ -1,43 +0,0 @@ -## Filter Priority -```tasks -done today -description includes #p11 -description does not include #exclude -``` -```tasks -done today -description includes #p10 -description does not include #exclude -``` -```tasks -done today -description includes #p01 -description does not include #exclude -``` -```tasks -done today -description includes #p00 -description does not include #exclude -``` - -## Filter Duration -```tasks -done today -description includes #15m -description does not include #exclude -``` -```tasks -done today -description includes #30m -description does not include #exclude -``` -```tasks -done today -description includes #01h -description does not include #exclude -``` -```tasks -done today -description includes #02h -description does not include #exclude -``` \ No newline at end of file diff --git a/700 Views/Tasks Completed Yesterday.md b/700 Views/Tasks Completed Yesterday.md deleted file mode 100644 index 68825db..0000000 --- a/700 Views/Tasks Completed Yesterday.md +++ /dev/null @@ -1,43 +0,0 @@ -### FIlter Priority -```tasks -done yesterday -description includes #p11 -description does not include #exclude -``` -```tasks -done yesterday -description includes #p10 -description does not include #exclude -``` -```tasks -done yesterday -description includes #p01 -description does not include #exclude -``` -```tasks -done yesterday -description includes #p00 -description does not include #exclude -``` - -### Filter Duration -```tasks -done yesterday -description includes #02h -description does not include #exclude -``` -```tasks -done yesterday -description includes #01h -description does not include #exclude -``` -```tasks -done yesterday -description includes #30m -description does not include #exclude -``` -```tasks -done yesterday -description includes #15m -description does not include #exclude -``` \ No newline at end of file diff --git a/700 Views/Tasks Ongoing.md b/700 Views/Tasks Ongoing.md deleted file mode 100644 index b6fce09..0000000 --- a/700 Views/Tasks Ongoing.md +++ /dev/null @@ -1,29 +0,0 @@ -#### Tasks Ongoing -```tasks -not done -description includes #ongoing -description includes #p11 -description does not include #exclude -hide task count -``` -```tasks -not done -description includes #ongoing -description includes #p10 -description does not include #exclude -hide task count -``` -```tasks -not done -description includes #ongoing -description includes #p01 -description does not include #exclude -hide task count -``` -```tasks -not done -description includes #ongoing -description includes #p00 -description does not include #exclude -hide task count -``` \ No newline at end of file diff --git a/700 Views/Work-Minutes Last 1 Months.md b/700 Views/Work-Minutes Last 1 Months.md deleted file mode 100644 index d5f0a58..0000000 --- a/700 Views/Work-Minutes Last 1 Months.md +++ /dev/null @@ -1,8 +0,0 @@ -```dataview -TABLE WITHOUT ID - "Last 1 Months" as "Timeframe", - sum(default(rows.work_minutes_completed, 0)) as "Work Minutes" -FROM "Journal/00 Daily/Ramblings" -WHERE date(file.name) >= date(today) - dur(1 month) and date(file.name) < date(today) -GROUP BY file.folder as "logs" -``` diff --git a/700 Views/Work-Minutes Last 1-2 Months.md b/700 Views/Work-Minutes Last 1-2 Months.md deleted file mode 100644 index 5061ea1..0000000 --- a/700 Views/Work-Minutes Last 1-2 Months.md +++ /dev/null @@ -1,8 +0,0 @@ -```dataview -TABLE WITHOUT ID - "Previous 1 Months" as "Timeframe", - sum(default(rows.work_minutes_completed, 0)) as "Work Minutes" -FROM "Journal/00 Daily/Ramblings" -WHERE date(file.name) >= date(today) - dur(2 months) and date(file.name) < date(today) - dur(1 months) -GROUP BY file.folder as "logs" -``` \ No newline at end of file diff --git a/700 Views/Work-Minutes Last 7 Days.md b/700 Views/Work-Minutes Last 7 Days.md deleted file mode 100644 index cf39529..0000000 --- a/700 Views/Work-Minutes Last 7 Days.md +++ /dev/null @@ -1,8 +0,0 @@ -```dataview -TABLE WITHOUT ID - "Last 7 days" as "Timeframe", - sum(default(rows.general.work_minutes_completed, 0)) as "Total Work Minutes" -FROM "300 Alignment/301 Daily" -WHERE date(file.name) >= date(today) - dur(7 days) and date(file.name) < date(today) -GROUP BY file.folder as "logs" -``` \ No newline at end of file diff --git a/700 Views/Work-Minutes Last 7-14 Days.md b/700 Views/Work-Minutes Last 7-14 Days.md deleted file mode 100644 index 8ed5ea1..0000000 --- a/700 Views/Work-Minutes Last 7-14 Days.md +++ /dev/null @@ -1,8 +0,0 @@ -```dataview -TABLE WITHOUT ID - "Last 7-14 days" as "Timeframe", - sum(default(rows.general.work_minutes_completed, 0)) as "Total Work Minutes" -FROM "300 Alignment/301 Daily" -WHERE date(file.name) >= date(today) - dur(14 days) and date(file.name) < date(today) - dur(7 days) -GROUP BY file.folder as "logs" -``` \ No newline at end of file diff --git "a/80 \360\237\214\212 Tasks Life.md" "b/80 \360\237\214\212 Tasks Life.md" deleted file mode 100644 index 3dcced7..0000000 --- "a/80 \360\237\214\212 Tasks Life.md" +++ /dev/null @@ -1,11 +0,0 @@ ---- -aliases: -tags: [ note/data ] ---- -[[00 🏠 Main Dashboard]] -# 🌊 Tasks Life -## Raw -- [ ] random tasks go here - -## Archive -- [ ] tasks that are done go here \ No newline at end of file diff --git a/800 Templates/Dashboard Discipline.md b/800 Templates/Dashboard Discipline.md deleted file mode 100644 index 43171f3..0000000 --- a/800 Templates/Dashboard Discipline.md +++ /dev/null @@ -1,215 +0,0 @@ ---- -aliases: {{VALUE:Source Emoji}} {{VALUE:Source Base Name}} -tags: [ note/dashboard, note/discipline, {{VALUE:Source Tag (no hashtag)}} ] -ikigai: - - love - - skill - - money - - world -pillars: List 3-8 key values that you want to uphold or eventually uphold to. They should be numbered to indicate priorities. This should also be in the YAML, but in the same order as an unordered list. -dynamic: This is the emerging result of the pillars when viewed together. ---- -> Make sure you set the YAML pillars and disciplines once realized. Delete this when afterwards. - -[[00 🏠 Main Dashboard]] | [[{{VALUE:Number Prefix}}1 🌊 Tasks {{VALUE:Source Base Name}}]] | [[{{VALUE:Number Prefix}}2 💡 Ramblings {{VALUE:Source Base Name}}]] -# {{VALUE:Source Emoji}} {{VALUE:Source Base Name}} -## Abstract -What is the definition of this Discipline? - -Continue with a brief description of what this discipline entails. - -## Importance and Relevance -How is this Discipline important and relevant to you? How and why did you choose the Ikigai characteristics above under the frontmatter YAML? What is your purpose of having this as a Discipline? - -## Core -```dataview -TABLE WITHOUT ID pillars as "Pillars" -WHERE file.name = this.file.name -``` -```dataview -TABLE WITHOUT ID dynamic as "Dynamic" -WHERE file.name = this.file.name -``` - -## Projects -### Active -```dataview -TABLE WITHOUT ID - link(file.name, default(link(file.name).aliases, file.name)) as "Project", - status as "Status", - due as "Due", - padleft(string(priority), 2, "0") as "Priority", - default(date(end), date(today)) - date(start) as "Duration" -FROM #note/project and #{{VALUE:Source Tag (no hashtag)}} -WHERE contains(list("00 Ongoing", "01 Blocked", "02 Planned", "03 Blocked"), status) -SORT status, due asc, priority desc -``` - -### Inactive -```dataview -TABLE WITHOUT ID - link(file.name, default(link(file.name).aliases, file.name)) as "Project", - status as "Status", - end as "End", - padleft(string(priority), 2, "0") as "Priority", - default(date(end), date(today)) - date(start) as "Duration" -FROM #note/project and #{{VALUE:Source Tag (no hashtag)}} -WHERE !contains(list("00 Ongoing", "01 Blocked", "02 Planned", "03 Blocked"), status) -SORT status, file.mtime desc -``` - -## [[01 🌊 Tasks {{VALUE:Source Base Name}}|Tasks]] -### Ongoing -#### Filter Priority -```tasks -not done -path includes <% tp.file.folder() %> -description includes #ongoing -description includes #p11 -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #ongoing -description includes #p10 -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #ongoing -description includes #p01 -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #ongoing -description includes #p00 -description does not include #exclude -``` - -### Reminder -```tasks -not done -path includes <% tp.file.folder() %> -description includes #00m -description does not include #ongoing -description does not include #exclude -``` - -### Backlog -#### Filter Priority -```tasks -not done -path includes <% tp.file.folder() %> -description includes #p11 -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #p10 -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #p01 -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #p00 -description does not include #ongoing -description does not include #exclude -``` - -#### Filter Duration -```tasks -not done -path includes <% tp.file.folder() %> -description includes #00m -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #15m -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #30m -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #01h -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #02h -description does not include #ongoing -description does not include #exclude -``` - -#### Filter Due -```tasks -not done -path includes <% tp.file.folder() %> -description does not include #ongoing -description does not include #exclude -``` - -### Blocked -```tasks -not done -path includes <% tp.file.folder() %> -description includes #p11 -description includes #block -description does not include #exclude -hide task count -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #p10 -description includes #block -description does not include #exclude -hide task count -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #p01 -description includes #block -description does not include #exclude -hide task count -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #p00 -description includes #block -description does not include #exclude -hide task count -``` - -## Resources -```query -(tag:#{{VALUE:Source Tag (no hashtag)}}) path:(300 Resources) -``` \ No newline at end of file diff --git a/800 Templates/Dashboard Habit.md b/800 Templates/Dashboard Habit.md deleted file mode 100644 index 378ffcf..0000000 --- a/800 Templates/Dashboard Habit.md +++ /dev/null @@ -1,235 +0,0 @@ ---- -aliases: {{VALUE:Source Emoji}} {{VALUE:Source Base Name}} -tags: [ note/dashboard, note/project, note/habit, {{VALUE:Source Discipline's Tag (No hashtag}} ] -discipline: {{VALUE:Link to corresponding Discipline}} -status: [ 02 Planned ] -start: -due: .inf -end: -objective: blah blah blah -when: ---- -> On the frontmatter above, turn the value under Discipline into a regular string. Then delete this. - -{{VALUE:Link to corresponding Discipline}} | [[01 🌊 Tasks {{VALUE:Source Base Name}}]] | [[02 💡 Ramblings {{VALUE:Source Base Name}}]] -# {{VALUE:Source Emoji}} {{VALUE:Source Base Name}} -```dataview -TABLE WITHOUT ID objective as "Objective", default(date(end), date(today)) - date(start) as "Ongoing" -WHERE file.name = this.file.name -``` - -## Abstract -Brief description of what is this habit, why it's important and came to be, and what will happen. - -## Habit -Quick and concrete explanation of what will be done for this Habit. - -## Frequency -How often this Habit is to occur and why. - -## Formation -### Cue -**Where will this Habit take place?** - - -**What time will this Habit be enacted?** - - -**How does this Habit stack with other Habits?** - - -**What will be in place to remind you to do this? Are they passive or active reminders?** - - -### Craving -**How will you increase temptation and reduce friction? Is there a habit you like doing that you can do during or immediately after this?** - - -**What social communities will you join to push further commitment?** - - -### Response -**When the time comes, will there be any additional setup? What will you do to stop lower this friction?** - - -**When you do this habit, how long engage in it? How long now, a week from now, a month, etc.** - - -### Reward -**Will this be tracked some other way besides within Obsidian?** - - -**What are the results of this Habit? How long do you think until these results become rewarding?** - - -## YAML Field -How the data will be tracked within Obsidian. Defined as its own dictionary below, it should be added to [[Journal 00 Daily]]'s YAML. -```YAML -NAME_OF_HABIT: - done: false - stacked: false - bundled: false - duration: -``` - -`done` (bool): Did you do it today? -`stacked` (bool): Did this habit proceed the intended stacking habit? -`bundled` (bool): Did you do a *want* habit after or during this habit? -`duration` (int): How long did you engage in it (in minutes)? - -## [[01 🌊 Tasks {{VALUE:Source Base Name}}|Tasks]] -### Ongoing (3) -#### Filter Priority -```tasks -not done -path includes <% tp.file.folder() %> -description includes #ongoing -description includes #p11 -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #ongoing -description includes #p10 -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #ongoing -description includes #p01 -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #ongoing -description includes #p00 -description does not include #exclude -``` - -### Reminder -```tasks -not done -path includes <% tp.file.folder() %> -description includes #00m -description does not include #ongoing -description does not include #exclude -``` - -### Backlog -#### Filter Priority -```tasks -not done -path includes <% tp.file.folder() %> -description includes #p11 -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #p10 -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #p01 -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #p00 -description does not include #ongoing -description does not include #exclude -``` - -#### Filter Duration -```tasks -not done -path includes <% tp.file.folder() %> -description includes #00m -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #15m -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #30m -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #01h -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #02h -description does not include #ongoing -description does not include #exclude -``` - -#### Filter Due -```tasks -not done -path includes <% tp.file.folder() %> -description does not include #ongoing -description does not include #exclude -``` - -### Blocked -```tasks -not done -path includes <% tp.file.folder() %> -description includes #p11 -description includes #block -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #p10 -description includes #block -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #p01 -description includes #block -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #p00 -description includes #block -description does not include #exclude -``` - -### Completed -#### Filter Today -```tasks -done today -path includes <% tp.file.folder() %> -``` - -## Resources -This is where you can link all the notes and resources relevant to this Habit. \ No newline at end of file diff --git a/800 Templates/Dashboard Project.md b/800 Templates/Dashboard Project.md deleted file mode 100644 index c68f464..0000000 --- a/800 Templates/Dashboard Project.md +++ /dev/null @@ -1,203 +0,0 @@ ---- -aliases: {{VALUE:Source Emoji}} {{VALUE:Source Base Name}} -tags: [ note/dashboard, note/project, {{VALUE:Source Discipline's Tag (No hashtag)}} ] -discipline: {{VALUE:Link to corresponding Discipline}} -status: 02 Planned -start: -due: -end: -priority: 00 -objective: # one sentence explaining what this project is, why it is needed, and how it's to be done ---- -> On the frontmatter above, turn the value under Discipline into a regular string. Then delete this. - -{{VALUE:Link to corresponding Discipline}} | [[01 🌊 Tasks {{VALUE:Source Base Name}}]] | [[02 💡 Ramblings {{VALUE:Source Base Name}}]] -# {{VALUE:Source Emoji}} {{VALUE:Source Base Name}} -```dataview -TABLE WITHOUT ID objective as "Objective", default(date(end), date(today)) - date(start) as "Ongoing" -WHERE file.name = this.file.name -``` - -## Abstract -Brief description of what is this project, why it came to be, and how it's going to be conducted. - -## Completion Criteria -**This project is considered complete when the following Requirements are met.** -Create a general Completion Criteria checklist and then start grouping them under `#cc/` tags to later tag related Tasks. - -## [[01 🌊 Tasks {{VALUE:Source Base Name}}|Tasks]] -### Ongoing (3) -#### Filter Priority -```tasks -not done -path includes <% tp.file.folder() %> -description includes #ongoing -description includes #p11 -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #ongoing -description includes #p10 -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #ongoing -description includes #p01 -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #ongoing -description includes #p00 -description does not include #exclude -``` - -### Reminder -```tasks -not done -path includes <% tp.file.folder() %> -description includes #00m -description does not include #ongoing -description does not include #exclude -``` - -### Backlog -#### Filter Priority -```tasks -not done -path includes <% tp.file.folder() %> -description includes #p11 -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #p10 -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #p01 -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #p00 -description does not include #ongoing -description does not include #exclude -``` - -#### Filter Duration -```tasks -not done -path includes <% tp.file.folder() %> -description includes #15m -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #30m -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #01h -description does not include #ongoing -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #02h -description does not include #ongoing -description does not include #exclude -``` - -#### Filter Due -```tasks -not done -path includes <% tp.file.folder() %> -description does not include #ongoing -description does not include #exclude -``` - -#### Filter CC -##### #cc/ -```tasks -not done -path includes <% tp.file.folder() %> -description includes #cc/ -description does not include #exclude -``` -##### Untagged -```tasks -done -path includes <% tp.file.folder() %> -description does not include #cc/ -``` - -### Blocked -```tasks -not done -path includes <% tp.file.folder() %> -description includes #p11 -description includes #block -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #p10 -description includes #block -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #p01 -description includes #block -description does not include #exclude -``` -```tasks -not done -path includes <% tp.file.folder() %> -description includes #p00 -description includes #block -description does not include #exclude -``` - -### Completed -#### Filter Today -```tasks -done today -path includes <% tp.file.folder() %> -``` - -## Resources -This is where you can link all the notes and resources you may need to do this project. - -## Retrospection -**What worked well with on this Project?** - - -**What didn't work well on this Project?** - - -**How can the next Project work better?** - - -**In the end, does this Project align well and make progress towards a Discipline?** diff --git a/800 Templates/Journal 00 Daily.md b/800 Templates/Journal 00 Daily.md deleted file mode 100644 index beac285..0000000 --- a/800 Templates/Journal 00 Daily.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -tags: [ note/data ] -general: - work_minutes_completed: - focus: -drawing: - done: false - duration: - focus: - stacked: false - bundled: false -exercising: - mobility: - done: false - duration: - performance: - stacked: false - bundled: false - calisthenics: - done: false - duration: - performance: - stacked: false - bundled: false ---- -[[<% tp.date.now("YYYY-MM-DD", -1, tp.file.title, "YYYY-MM-DD") %>]] | [[<% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "YYYY-MM-DD") %> Stand-up|Stand-up]] | [[<% tp.date.now("YYYY-MM-DD", 1, tp.file.title, "YYYY-MM-DD") %>]] -# <% tp.date.now("YYYY-MM-DD dddd", 0, tp.file.title, "YYYY-MM-DD") %> Ramblings -<% tp.web.daily_quote() %> - -`Your opnions on this quote here.` - ---- - diff --git a/800 Templates/Journal 01 Daily Stand-up.md b/800 Templates/Journal 01 Daily Stand-up.md deleted file mode 100644 index 4f1df07..0000000 --- a/800 Templates/Journal 01 Daily Stand-up.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -tags: [ note/data ] ---- -[[<% tp.date.now("YYYY-MM-DD", -1, tp.file.title.split(" ")[0], "YYYY-MM-DD") %> Stand-up]] | [[<% tp.file.title.split(" ")[0] %>|Ramblings]] | [[<% tp.date.now("YYYY-MM-DD", 1, tp.file.title.split(" ")[0], "YYYY-MM-DD") %> Stand-up]] -# <% tp.date.now("YYYY-MM-DD dddd", 0, tp.file.title, "YYYY-MM-DD") %> Stand-up -## Review -### Projects you touched yesterday -```dataview -TABLE WITHOUT ID - link(file.name, default(link(file.name).aliases, file.name)) as "Project", - status as "Status", - due as "Due", - priority as "Priority" -FROM #note/project -WHERE file.mtime >= date(<% tp.file.title.split(" ")[0] %>) - dur(1 days) and file.mtime < date(<% tp.file.title.split(" ")[0] %>) and due != null -SORT status, due asc, urgent asc, important asc -``` - -### Tasks you completed yesterday -```tasks -done <% tp.date.now("YYYY-MM-DD", -1, tp.file.title.split(" ")[0], "YYYY-MM-DD") %> -description includes #p11 -description does not include #exclude -``` -```tasks -done <% tp.date.now("YYYY-MM-DD", -1, tp.file.title.split(" ")[0], "YYYY-MM-DD") %> -description includes #p10 -description does not include #exclude -``` -```tasks -done <% tp.date.now("YYYY-MM-DD", -1, tp.file.title.split(" ")[0], "YYYY-MM-DD") %> -description includes #p01 -description does not include #exclude -``` -```tasks -done <% tp.date.now("YYYY-MM-DD", -1, tp.file.title.split(" ")[0], "YYYY-MM-DD") %> -description includes #p00 -description does not include #exclude -``` -![[<% tp.date.now("YYYY-MM-DD", -1, tp.file.title.split(" ")[0], "YYYY-MM-DD") %> Stand-up#Alignment]] - -### Notes you dealt with yesterday -#### Created -```dataview -LIST -FROM -"Journal" -WHERE file.ctime > date(<% tp.date.now("YYYY-MM-DD", -1, tp.file.title.split(" ")[0], "YYYY-MM-DD") %>) and file.ctime < date(<% tp.date.now("YYYY-MM-DD", -1, tp.file.title.split(" ")[0], "YYYY-MM-DD") %>) + dur(1 days) -``` - -#### Last Modified -```dataview -LIST -FROM -"Journal" -WHERE file.mtime > date(<% tp.date.now("YYYY-MM-DD", -1, tp.file.title.split(" ")[0], "YYYY-MM-DD") %>) and file.mtime < date(<% tp.date.now("YYYY-MM-DD", -1, tp.file.title.split(" ")[0], "YYYY-MM-DD") %>) + dur(1 days) -limit 20 -``` - -### Review your blocked items -```tasks -not done -description includes #blocked -``` -```tasks -not done -description includes #blocking -``` -![[<% tp.date.now("YYYY-MM-DD", -1, tp.file.title.split(" ")[0], "YYYY-MM-DD") %> Stand-up#Is anything blocking your work? If so, why?]] - -### Ramblings you did yesterday -![[<% tp.date.now("YYYY-MM-DD", -1, tp.file.title.split(" ")[0], "YYYY-MM-DD") %>#<% tp.date.now("YYYY-MM-DD dddd", -1, tp.file.title, "YYYY-MM-DD") %> Ramblings]] - -## Stand-up -### What did you manage to get done yesterday? -[[Tasks Completed Yesterday]] - -`Explicitly respond here.` - -### What is your focus today? -[[Tasks Ongoing]] [[90 🗃️ Master Backlog]] - -`Answere here. This should be a general focus, not specific tasks.` - -#### Alignment -[[Ongoing Project Reference]] -**Does this focus still Align to its Project's Objective? How and why?** -`Answer here.` - -**Does this Project's Completion Criteria still Align with its Objective?** -`Answer here.` - -### Is anything blocking your work? If so, why? -[[00 🏠 Main Dashboard#Blocked]] - - - -## Next Steps -- [ ] #task #p01 #15m Complete [[<% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "YYYY-MM-DD") %> Stand-up]] - -Mark as completed and adjust time to reflect how long this took you. Then proceed to [[<% tp.file.title.split(" ")[0] %>|Today's Ramblings]]. \ No newline at end of file diff --git a/800 Templates/Journal 20 Weekly.md b/800 Templates/Journal 20 Weekly.md deleted file mode 100644 index ff8c5f3..0000000 --- a/800 Templates/Journal 20 Weekly.md +++ /dev/null @@ -1,189 +0,0 @@ ---- -tags: [ note/data ] ---- -[[<% tp.date.now("gggg-[W]ww", "P-1W", tp.file.title, "gggg-[W]ww") %>]] | [[<% tp.date.now("gggg-[W]ww", "P1W", tp.file.title, "gggg-[W]ww") %>]] -# <% tp.date.now("gggg-[W]ww", 0, tp.file.title, "gggg-[W]ww") %> -## Fun -**Copy and paste the first quote within last quarter (<= 3 months ago) from [/r/quotes: For your favorite quotes](https://www.reddit.com/r/quotes/top/?t=year). -** -> Quote goes here -> — Author - -`Your opnions on this quote here. Why do you think became the weekly top?` - -## Review -![[<% tp.date.now("gggg-[W]ww", "P-1W", tp.file.title, "gggg-[W]ww") %>#Analysis]] -![[<% tp.date.now("gggg-[W]ww", "P-1W", tp.file.title, "gggg-[W]ww") %>#Reflection]] -![[<% tp.date.now("gggg-[W]ww", "P-1W", tp.file.title, "gggg-[W]ww") %>#Concerns]] -![[<% tp.date.now("gggg-[W]ww", "P-1W", tp.file.title, "gggg-[W]ww") %>#Ramblings]] - -## Performance -### Projects -```dataview -TABLE WITHOUT ID - link(file.name, default(aliases, file.name)) as "Project", - status as "Status", - file.mtime as "Last Modified" -FROM #note/project -WHERE start >= date(<% tp.date.now("YYYY-MM-DD", "P-1W", tp.file.title, "gggg-[W]ww") %>) - and start < date(<% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "gggg-[W]ww") %>) + dur(1 day) - or end >= date(<% tp.date.now("YYYY-MM-DD", "P-1W", tp.file.title, "gggg-[W]ww") %>) - and end < date(<% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "gggg-[W]ww") %>) + dur(1 day) - or file.mtime > date(<% tp.date.now("YYYY-MM-DD", "P-1W", tp.file.title, "gggg-[W]ww") %>) - and file.mtime < date(<% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "gggg-[W]ww") %>) + dur(1 day) -SORT file.mtime desc -``` - -### Tasks -##### Filter None -```tasks -done after <% tp.date.now("YYYY-MM-DD", "P-1W-1D", tp.file.title, "gggg-[W]ww") %> -done before <% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "gggg-[W]ww") %> -description does not include #note/project -hide edit button -``` - -##### Filter Priority -###### p11 -```tasks -done after <% tp.date.now("YYYY-MM-DD", "P-1W-1D", tp.file.title, "gggg-[W]ww") %> -done before <% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "gggg-[W]ww") %> -description includes #p11 -description does not include #note/project -hide edit button -``` -###### p10 -```tasks -done after <% tp.date.now("YYYY-MM-DD", "P-1W-1D", tp.file.title, "gggg-[W]ww") %> -done before <% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "gggg-[W]ww") %> -description includes #p10 -description does not include #note/project -hide edit button -``` -###### p01 -```tasks -done after <% tp.date.now("YYYY-MM-DD", "P-1W-1D", tp.file.title, "gggg-[W]ww") %> -done before <% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "gggg-[W]ww") %> -description includes #p01 -description does not include #note/project -hide edit button -``` -###### p00 -```tasks -done after <% tp.date.now("YYYY-MM-DD", "P-1W-1D", tp.file.title, "gggg-[W]ww") %> -done before <% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "gggg-[W]ww") %> -description includes #p00 -description does not include #note/project -hide edit button -``` - -##### Filter Duration -###### 02h -```tasks -done after <% tp.date.now("YYYY-MM-DD", "P-1W-1D", tp.file.title, "gggg-[W]ww") %> -done before <% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "gggg-[W]ww") %> -description includes #02h -description does not include #note/project -hide edit button -``` -###### 01h -```tasks -done after <% tp.date.now("YYYY-MM-DD", "P-1W-1D", tp.file.title, "gggg-[W]ww") %> -done before <% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "gggg-[W]ww") %> -description includes #01h -description does not include #note/project -hide edit button -``` -###### 30m -```tasks -done after <% tp.date.now("YYYY-MM-DD", "P-1W-1D", tp.file.title, "gggg-[W]ww") %> -done before <% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "gggg-[W]ww") %> -description includes #30m -description does not include #note/project -hide edit button -``` -###### 15m -```tasks -done after <% tp.date.now("YYYY-MM-DD", "P-1W-1D", tp.file.title, "gggg-[W]ww") %> -done before <% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "gggg-[W]ww") %> -description includes #15m -description does not include #note/project -hide edit button -``` - -### Analysis -**How much work in minutes did it did you complete last week? Does this amount seem realistic? If you worked every day for 8 hours for 7 days, you would have worked 56 hours, or 3,360 minutes. If you had part-time for 4 days which cut working hours down to 4 hours, you would have worked 1,920 minute.** -[[Work-Minutes Last 7 Days]] -`Answer here.` - -**How does this work compare to the previous week? Do you think the difference is significant?** -[[Work-Minutes Last 7-14 Days]] -`Answer here.` - -### Reflection -**What do you think worked this week to get that much work done?** -`Answer here.` - -**What do you think didn't work well this week to get that much work done?** -`Answer here.` - -**How can you potentially increase Velocity (get more work done)?** -`Answer here.` - -**What would stunt this increase, or even lower Velocity?** -`Answer here.` - -**What's the likelihood of this concern occurring?** -`Answer here.` - -**How much of an impact would this stunt or lowering Velocity?** -`Answer here.` - -**What will you do to prevent or mitigate the stunting or lowering when it happens?** -`Answer here.` - -## Alignment -```dataview -TABLE WITHOUT ID - link(file.name, default(link(file.name).aliases, file.name)) as "Project", - objective as "Objective", - link(discipline, link(discipline).aliases) as "Discipline" -FROM #note/project and -"Templates" -WHERE file.mtime >= date(<% tp.date.now("YYYY-MM-DD", "P-1W", tp.file.title, "gggg-[W]ww") %>) and file.mtime < date(<% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "gggg-[W]ww") %>) + dur(1 day) -SORT due asc -``` -```dataview -TABLE WITHOUT ID - link(file.name, default(link(file.name).aliases, link(file.name).name)) as "Discipline", - pillars as "Pillars", - dynamic as "Dynamic" -FROM #note/discipline and -"Templates" -WHERE file.mtime >= date(<% tp.date.now("YYYY-MM-DD", "P-1W", tp.file.title, "gggg-[W]ww") %>) and file.mtime < date(<% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "gggg-[W]ww") %>) + dur(1 day) -SORT due asc -``` -**For each [[Projects|Project]] that you touched last week, does its Objective still align with most of its [[Disciplines|Discipline]] [[Pillars]]? Does the Objective align with the Discipline Dynamic? How and why?** -[[Projects Touched Last Week]] -[[Project-Disciplines Touched Last Week]] -### `Project 1` -`Answer here.` - -### `Project 2` -`Answer here.` - -## Concerns -**What are at least two things to worry about next week?** -1. What's the likelihood of this concern occurring? -2. How would this impact you? -3. What will you do to prevent this from happening, or at least mitigate the damage when it occurs? - -### Concern 1: `Title of Concern` -`Elaborate concern here` - -### Concern 2: `Title of Concern` -`Elaborate concern here` - -- [ ] #task #p01 #30m Complete [[<% tp.date.now("gggg-[W]ww", 0, tp.file.title, "gggg-[W]ww") %>]] - -## Ramblings -`Other Ramblings go here.` - diff --git a/800 Templates/Journal 30 Monthly.md b/800 Templates/Journal 30 Monthly.md deleted file mode 100644 index b97e69e..0000000 --- a/800 Templates/Journal 30 Monthly.md +++ /dev/null @@ -1,182 +0,0 @@ ---- -tags: [ note/data ] ---- -[[<% tp.date.now("YYYY-MM", "P-1M", tp.file.title, "YYYY-MM") %>]] | [[<% tp.date.now("YYYY-MM", "P1M", tp.file.title, "YYYY-MM") %>]] -# <% tp.file.title %> Ramblings -## Fun -**Copy and paste the first quote from [/r/quotes: For your favorite quotes](https://www.reddit.com/r/quotes/top/?t=month)** - -> Quote goes here -> — Author - -`Your opnions on this quote here. Why do you think became the monthly top?` - -## Review -![[<% tp.date.now("YYYY-MM", "P-1M", tp.file.title, "YYYY-MM") %>#Analysis]] -![[<% tp.date.now("YYYY-MM", "P-1M", tp.file.title, "YYYY-MM") %>#Reflection]] -![[<% tp.date.now("YYYY-MM", "P-1M", tp.file.title, "YYYY-MM") %>#Concerns]] -![[<% tp.date.now("YYYY-MM", "P-1M", tp.file.title, "YYYY-MM") %>#Ramblings]] - -## Performance -### Projects -```dataview -TABLE WITHOUT ID - file.link as "Project", - status as "Status", - objective as "Objective", - start as "Start", - end as "End" -FROM #note/project and -"999 Stale" and -"Templates" -WHERE end >= <% tp.date.now("YYYY-MM-DD", "P-1M", tp.file.title, "YYYY-MM") %> - or start >= <% tp.date.now("YYYY-MM-DD", "P-1M", tp.file.title, "YYYY-MM") %> - or end < <% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "YYYY-MM") %> - or start < <% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "YYYY-MM") %> - or file.mtime >= date(<% tp.date.now("YYYY-MM-DD", "P-1M", tp.file.title, "YYYY-MM") %>) - or file.mtime < date(<% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "YYYY-MM") %>) -SORT end desc, start desc, status -``` - -### Tasks -##### Filter None -```tasks -done after <% tp.date.now("YYYY-MM-DD", "P-1M-1D", tp.file.title, "YYYY-MM") %> -done before <% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "YYYY-MM") %> -description does not include #note/project -hide edit button -``` - -##### Filter Priority -###### p11 -```tasks -done after <% tp.date.now("YYYY-MM-DD", "P-1M-1D", tp.file.title, "YYYY-MM") %> -done before <% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "YYYY-MM") %> -description includes #p11 -description does not include #note/project -hide edit button -``` -###### p10 -```tasks -done after <% tp.date.now("YYYY-MM-DD", "P-1M-1D", tp.file.title, "YYYY-MM") %> -done before <% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "YYYY-MM") %> -description includes #p10 -description does not include #note/project -hide edit button -``` -###### p01 -```tasks -done after <% tp.date.now("YYYY-MM-DD", "P-1M-1D", tp.file.title, "YYYY-MM") %> -done before <% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "YYYY-MM") %> -description includes #p01 -description does not include #note/project -hide edit button -``` -###### p00 -```tasks -done after <% tp.date.now("YYYY-MM-DD", "P-1M-1D", tp.file.title, "YYYY-MM") %> -done before <% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "YYYY-MM") %> -description includes #p00 -description does not include #note/project -hide edit button -``` - -##### Filter Duration -###### 02h -```tasks -done after <% tp.date.now("YYYY-MM-DD", "P-1M-1D", tp.file.title, "YYYY-MM") %> -done before <% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "YYYY-MM") %> -description includes #02h -description does not include #note/project -hide edit button -``` -###### 01h -```tasks -done after <% tp.date.now("YYYY-MM-DD", "P-1M-1D", tp.file.title, "YYYY-MM") %> -done before <% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "YYYY-MM") %> -description includes #01h -description does not include #note/project -hide edit button -``` -###### 30m -```tasks -done after <% tp.date.now("YYYY-MM-DD", "P-1M-1D", tp.file.title, "YYYY-MM") %> -done before <% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "YYYY-MM") %> -description includes #30m -description does not include #note/project -hide edit button -``` -###### 15m -```tasks -done after <% tp.date.now("YYYY-MM-DD", "P-1M-1D", tp.file.title, "YYYY-MM") %> -done before <% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "YYYY-MM") %> -description includes #15m -description does not include #note/project -hide edit button -``` - -### Analysis -**How much work in minutes did it did you complete last month? Does this amount seem realistic?** -> If you worked every day for 8 hours in a 28 month-day, you would have worked 13,440 minutes. If you had part-time for 4 out of 7 days of the week in that 28 day month, and those part-time days only allowed for 4 hours of work, you would have worked 10,560 minutes. - -[[Work-Minutes Last 1 Months]] -`Answer here.` - -**How does this work compare to the previous months? Do you think this difference is significant?** -[[Work-Minutes Last 1-2 Months]] -`Answer here.` - -### Reflection -**What do you think worked this month to get that much work done?** -`Answer here.` - -**What do you think didn't work well this month to get that much work done?** -`Answer here.` - -**How can you potentially increase Velocity (get more work done)?** -`Answer here.` - -**What would stunt this increase, or even lower Velocity?** -`Answer here.` - -**What's the likelihood of this concern occurring?** -`Answer here.` - -**How much of an impact would this stunt or lowering Velocity?** -`Answer here.` - -**What will you do to prevent or mitigate the stunting or lowering when it happens?** -`Answer here.` - -## Alignment -```dataview -TABLE WITHOUT ID - link(file.name, default(link(file.name).aliases, link(file.name).name)) as "Discipline", - pillars as "Pillars", - dynamic as "Dynamic" -FROM #note/discipline and -"999 Stale" and -"Templates" -SORT due asc -``` -**For each Discipline, how are you feeling about them at the moment? Do they still feel relevant and important through your Life Pillars?** -### `Discipline 1` -`Answer here.` - -### `Discipline 2` -`Answer here.` - -- [ ] #task #p01 #30m Complete [[<% tp.date.now("YYYY-MM", 0, tp.file.title, "YYYY-MM") %> Retrospection]] - -## Concerns -**What are at least two things to worry about next month?** -1. What's the likelihood of this concern occurring? -2. How would this impact you? -3. What will you do to prevent this from happening, or at least mitigate the damage when it occurs? - -### Concern 1: `Title of Concern` -`Elaborate concern here` - -### Concern 2: `Title of Concern` -`Elaborate concern here` - -## Ramblings -`Other Ramblings go here.` - -- [ ] #task #p01 #30m Complete [[<% tp.date.now("YYYY-MM", 0, tp.file.title, "YYYY-MM") %>]] \ No newline at end of file diff --git a/800 Templates/Journal 40 Quarterly.md b/800 Templates/Journal 40 Quarterly.md deleted file mode 100644 index 1bbea2d..0000000 --- a/800 Templates/Journal 40 Quarterly.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -tags: [ note/data ] ---- -[[<% tp.date.now("YYYY-[Q]Q", "P-3M", tp.file.title, "YYYY-[Q]Q") %>]] | [[<% tp.date.now("YYYY-[Q]Q", "P3M", tp.file.title, "YYYY-[Q]Q") %>]] -# <% tp.date.now("YYYY-[Q]Q", 0, tp.file.title, "YYYY-[Q]Q") %> -## Fun -**Copy and paste the first quote within last quarter (<= 3 months ago) from [/r/quotes: For your favorite quotes](https://www.reddit.com/r/quotes/top/?t=year). -** -> Quote goes here -> — Author - -`Your opnions on this quote here. Why do you think became the quarterly top?` - -## Performance -### Projects -```dataview -TABLE WITHOUT ID - link(file.name, default(aliases, file.name)) as "Project", - start as "Start", - end as "End", - status as "Status", - link(discipline, default(link(discipline).aliases, file.name)) as Discipline -FROM #note/project -WHERE start >= date(<% tp.date.now("YYYY-MM-DD", "P-3M", tp.file.title, "YYYY-[Q]Q") %>) - and start < date(<% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "YYYY-[Q]Q") %>) + dur(1 day) - or end >= date(<% tp.date.now("YYYY-MM-DD", "P-3M", tp.file.title, "YYYY-[Q]Q") %>) - and end < date(<% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "YYYY-[Q]Q") %>) + dur(1 day) - or file.mtime > date(<% tp.date.now("YYYY-MM-DD", "P-3M", tp.file.title, "YYYY-[Q]Q") %>) - and file.mtime < date(<% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "YYYY-[Q]Q") %>) + dur(1 day) -sort end, status -``` - -## Alignment -```dataview -TABLE WITHOUT ID - pillars as "Life Pillars" -FROM "/" -WHERE contains(file.aliases, "💗 Life") -``` -```dataview -TABLE WITHOUT ID - dynamic as "Life Dynamic" -FROM "/" -WHERE contains(file.aliases, "💗 Life") -``` -```dataview -TABLE WITHOUT ID - link(file.name, default(link(file.name).aliases, link(file.name).name)) as "Discipline", - dynamic as "Dynamic" -FROM #note/discipline and -"900 Archive" and -"Templates" -``` -**For each Discipline, are they still relevant and important towards at least one Life Pillars? Do they allow mobility towards them? Which Life Pillars? How and Why?** - -### Discipline 1 -`Answer` - -### Discipline 2 -`Answer` - -## Adjustment -**Are there any changes that need to be made to your Disciplines? What will be changed, if anything? How and why? If not needed, why?** -`Answer` - -## Ramblings -`Random quarterly ramblings go here` \ No newline at end of file diff --git a/800 Templates/Journal 50 Yearly.md b/800 Templates/Journal 50 Yearly.md deleted file mode 100644 index 3a30311..0000000 --- a/800 Templates/Journal 50 Yearly.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -tags: [ note/data ] ---- -[[<% tp.date.now("YYYY", "P-1Y", tp.file.title, "YYYY") %>]] | [[<% tp.date.now("YYYY", "P1Y", tp.file.title, "YYYY") %>]] -# <% tp.date.now("YYYY", 0, tp.file.title, "YYYY") %> -## Fun -**Copy and paste the first quote from [/r/quotes: For your favorite quotes](https://www.reddit.com/r/quotes/top/?t=year). -** -> Quote goes here -> — Author - -`Your opnions on this quote here.` - -## Performance -### Projects -```dataview -TABLE WITHOUT ID - link(file.name, default(aliases, file.name)) as "Project", - start as "Start", - end as "End", - status as "Status", - link(discipline, default(link(discipline).aliases, file.name)) as Discipline -FROM #note/project -WHERE start >= date(<% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "YYYY") %>) - and start < date(<% tp.date.now("YYYY-MM-DD", "P1Y", tp.file.title, "YYYY") %>) + dur(1 day) - or end >= date(<% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "YYYY") %>) - and end < date(<% tp.date.now("YYYY-MM-DD", "P1Y", tp.file.title, "YYYY") %>) + dur(1 day) - or file.mtime > date(<% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "YYYY") %>) - and file.mtime < date(<% tp.date.now("YYYY-MM-DD", "P1Y", tp.file.title, "YYYY") %>) + dur(1 day) -sort end, status -``` - -## Reflection -Here is a generalized Yearly Reflection. The intent is to be mindful about your personal biases and values, evaluate them, and adjust as needed moving forward. It's suggested to scour the internet for other yearly self-reflection questions for better direction if you are stuck. -### Looking Outwards -**Based on reality, what major events occurred this year? How have they affected your direction and velocity? Consider looking through all your Projects, Disciplines, other Journals, etc.** -`Answer` - -### Looking Within -**How do you feel about those physical events now? Do you think you're in a better spot now than you were last year? Why do you think this is the case?** -`Answer` - -**Look at your [[Life Pillars]]. How do you feel about them now? Do they still feel relevant and important? Have you developed new or dissolved old Life Pillars? Why?** -`Answer` - -**Look at your [[Life Dynamic]]. Does it make sense given your Life Pillars above? Why?** -`Answer` - -**How close are you to embodying your Life Dynamic? How so and why?** -`Answer` - -**Does your [[Ikigai (View)|Ikigai]] still resonate with you? How has it evolved in reference to yourself and the world?** -`Answer` - -**Do you feel like something fundamental needs to change (e.g. you, your circumstances, etc)? Why?** -`Answer` - -### Moving Forward -**If you felt that something needs to change, what can you do to make it happen? If you didn't, how can you keep things the way they are?** -`Answer` - -### Rating -**Through an arbitrary percentage, from within, how positively or negatively do you think you've shifted from last year? +/-100% is when you could not have imagined yourself in that position last year because you have changed so much to get to where you are now.** -`Answer` - -**And how much shifts of your outwards reality?** -`Answer` - -> Please make any adjustments to your Life Pillars, Life Dynamic, Disciplines, Ikigai, etc. now if needed. If anything make a task for it. - -## Ramblings -`Random yearly ramblings go here.` \ No newline at end of file diff --git a/800 Templates/Note.md b/800 Templates/Note.md index dbe0664..b8b1442 100644 --- a/800 Templates/Note.md +++ b/800 Templates/Note.md @@ -1,6 +1,6 @@ --- aliases: -tags: [ note/ ] +tags: [] --- # <% tp.file.title %> diff --git a/800 Templates/Ramblings.md b/800 Templates/Ramblings.md deleted file mode 100644 index e617198..0000000 --- a/800 Templates/Ramblings.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -aliases: 💡 Ramblings {{VALUE:Source Base Name}} -tags: [ note/data ] ---- -> Make sure you set the YAML `tags` correctly so queries work. Delete this when set. - -[[{{VALUE:Number Prefix}}0 {{VALUE:Source Emoji}} {{VALUE:Source Base Name}}]] | [[{{VALUE:Number Prefix}}1 🌊 Tasks {{VALUE:Source Base Name}}]] -# 💡 Ramblings {{VALUE:Source Base Name}} -## some date -### topic of rambling -ramblings yada yada yada \ No newline at end of file diff --git a/800 Templates/Tasks (Catalog).md b/800 Templates/Tasks (Catalog).md deleted file mode 100644 index b10b9b2..0000000 --- a/800 Templates/Tasks (Catalog).md +++ /dev/null @@ -1,13 +0,0 @@ ---- -aliases: 🌊 Tasks {{VALUE:Source Base Name}} -tags: [ note/data ] ---- -> Make sure you set the YAML `tags` correctly so queries work. Delete this when set. - -[[{{VALUE:Number Prefix}}0 {{VALUE:Source Emoji}} {{VALUE:Source Base Name}}]] | [[{{VALUE:Number Prefix}}2 💡 Ramblings {{VALUE:Source Base Name}}]] -# 🌊 Tasks {{VALUE:Source Base Name}} -## Raw -- [ ] Tasks go here - -## Archived -- [ ] Archived tasks go here \ No newline at end of file diff --git a/800 Templates/leftarrow.md b/800 Templates/arrowleft.md similarity index 100% rename from 800 Templates/leftarrow.md rename to 800 Templates/arrowleft.md diff --git a/800 Templates/rightarrow.md b/800 Templates/arrowright.md similarity index 100% rename from 800 Templates/rightarrow.md rename to 800 Templates/arrowright.md diff --git a/800 Templates/task.md b/800 Templates/task.md deleted file mode 100644 index 8c70ed0..0000000 --- a/800 Templates/task.md +++ /dev/null @@ -1 +0,0 @@ -#task #p01 #30m \ No newline at end of file diff --git a/800 Templates/test.md b/800 Templates/test.md deleted file mode 100644 index 8385e95..0000000 --- a/800 Templates/test.md +++ /dev/null @@ -1 +0,0 @@ -<% tp.date.now("YYYY-[Q]Q", "P-9M") %> \ No newline at end of file diff --git "a/90 \360\237\227\203\357\270\217 Master Backlog.md" "b/90 \360\237\227\203\357\270\217 Master Backlog.md" deleted file mode 100644 index f1ff459..0000000 --- "a/90 \360\237\227\203\357\270\217 Master Backlog.md" +++ /dev/null @@ -1,11 +0,0 @@ ---- -aliases: 🏠 Main Dashboard -tags: [ note/dashboard ] ---- -# 99 🗃️ Master Backlog -```tasks -not done -description does not include #ongoing -description does not include #hb -path does not include 800 Templates -``` \ No newline at end of file diff --git "a/99 \360\237\222\227 Life.md" "b/99 \360\237\222\227 Life.md" index d64ace4..f09aea6 100644 --- "a/99 \360\237\222\227 Life.md" +++ "b/99 \360\237\222\227 Life.md" @@ -1,42 +1,11 @@ --- -aliases: 💗 Life -tags: [ note/data, introspection ] -pillars: - - "Empathy: the ability to project the humanity of another person into yourself" - - "some life pillar 2" -dynamic: the emergence of life pillars +aliases: [ 💗 Life, 700 Life ] +tags: [ data ] --- # 💗 Life -## Core -```dataview -TABLE WITHOUT ID pillars as "Pillars" -WHERE file.name = this.file.name -``` -```dataview -TABLE WITHOUT ID dynamic as "Dynamic" -WHERE file.name = this.file.name -``` - ## Life Pillars -### (Example) Empathy -Specifically, the Golden Rule: treat others the way you want to be treated. Empathy is the capacity to understand and feel what another person is experiencing. In a way, it's the ability to project the humanity of another person into yourself. - -#### (Example) Relevance and Importance -The Golden Rule has been drilled into my head from elementary school. This mindset is something that I continue to do, and it has helped me empathize with many others around me, especially so given my introvert-personality. I feel like it has given me many social insights and perspectives. - -I'd consider this Pillar important because to be socially accepted, you have to be very socially aware of the circumstances leading up to it. It also in a way feels more human since you supposedly put another person's sense of humanity front and center to understand and feel with them, not for them. Doing this just feels right. - -### Pillar -`Abstraction` +**What are your Life Pillars? How and why are they related or important to you?** -#### Relevance and Importance -`Why is it relevant?` - -`Why is it important?` ## Life Dynamic -in one sentence, what kind of person do these pillars combine to make? - -## Action -for each pillar, what discipline(s) will allow mobility towards supporting that pillar? - +**What kind of person embodies all the pillars defined above?** diff --git "a/999 Setup/00 \360\237\222\227 Defining Life.md" "b/999 Setup/00 \360\237\222\227 Defining Life.md" deleted file mode 100644 index 10802ab..0000000 --- "a/999 Setup/00 \360\237\222\227 Defining Life.md" +++ /dev/null @@ -1,44 +0,0 @@ ---- -aliases: 💗 Defining Life -tags: [ note/data, introspection ] ---- -# 💗 Defining Life -## Life Pillars -Life Pillars are [[Pillars]] under the context of everyday Life. They give Life meaning and direction and should be defined in the most generalized, fundamental form as possible. In other words, your objective is not that you not need a hammer and nail to hang a picture, it's that you need to make something visible. - -You can have any amount of Life Pillars, but do consider having just a handful so you can always remember them. - -When you have something in mind, go to [[99 💗 Life#Life Pillars]] and begin to define and thoroughly elaborate on them. - -If you're unsure of your own Life Pillars, consider the following questions under the context of your sense of self. They should get some thoughts flowing. Also, if applicable, consider their opposite and question if it's something that should even matter to begin with. -- What comes first? -- What does it mean to live? -- What do you want before you die? -- What does it mean to be human? -- What deserves respect and appreciation? -- Do you value the journey or the end? -- What are your limits? -- Why are you even doing this right now? -- What is your version of hell? Of heaven? - -## Life Dynamic -Life Dynamic is the emerging result of the combined effects of your Life Pillars. Pillars are the founding principles of what make you, you. They all pull you towards some direction, and this direction should agree with what you want. You could consider this your personality. That being said, your Life Dynamic should align with the Life Pillars you defined above. - -Your Life Discipline should be summarized into one sentence, and should thoroughly describe a personality. This is a personality that you currently are or strive to be. - -## Baking Life -Take a short break. -- [ ] I took a break to refresh my mind to have a fresh perspective when I come back - -Look over your Life Pillars and Life Discipline. Really ponder over if it's something that resonates with you. Make revisions as needed. - -One you feel it's more or less finalized, on the frontmatter of [[99 💗 Life|💗 Life]], under `pillars`, please list your Pillars followed by a one sentence abstraction. Similarly, under `dynamic`, type your Life Dynamic. It should look similar to the following. -```YAML -pillars: - - "Some pillar: yada yada" - - "Sharing Experiences: joy is better experiened with others to spead knowledge" -dynamic: "Pillars combine to create a hard-tempered, refined individual who's passionate about sharing novel experiences to supplement joy in the life the life of others who might not be able to experience joy." -``` - -## Next Steps -With your fundamental life principles out of the way, you can now define action towards them. See [[01 🔀 Divergence to Disciplines|🔀 Divergence to Disciplines]]. \ No newline at end of file diff --git "a/999 Setup/01 \360\237\224\200 Divergence to Disciplines.md" "b/999 Setup/01 \360\237\224\200 Divergence to Disciplines.md" deleted file mode 100644 index 29db624..0000000 --- "a/999 Setup/01 \360\237\224\200 Divergence to Disciplines.md" +++ /dev/null @@ -1,73 +0,0 @@ ---- -aliases: 🔀 Divergence to Disciplines -tags: [ note/data, introspection ] ---- -# 🔀 Divergence to Disciplines -This document serves to explore understand what's important and relevant to your life in the form of [[Disciplines]]. This will also help you set up the initial files and folders for this system of Life Discipline Projects. - -## Exploration by Diverging Ideas -For each section, roughly answer in the context of relevancy and importance to you. *This document is focused on you, not others.* - -### Love -**What is your definition of love for everyday ideas and activities? It may help to define the opposite as well.** -`Answer` - -**Using that definition, what are the everyday ideas or activities you love? Please make a generic list.** -- `Answer` - -### Skill -**What is your definition of being skilled at something?** -`Answer` - -**Using that definition, what are the everyday activities you are skilled at? Please make a generic list.** -- `Answer` - -### Money -**What is your definition of being financially stable?** - - -**Using that definition, what activities can you semi-confidently say will make you reach that financial stability? Please make a generic list.** -- `Answer` - -### World -**What do you know the world needs?** -`Answer` - -**What do you think is missing, but the world has not yet realized?** -`Answer` - -**Using your answers above, what activities do you believe fulfill the needs of the world?** -- `Answer` - -## Condensing to Disciplines -**Using all of your *listed* activities and ideas above, list all of them below.** -- `Answer` - -**Please review [[Disciplines#Scoping|Discipline]] and [[Ikigai]]. Do a first pass of all listed ideas above and start to group them into generic Disciplines.** -Discipline 1 -- Activity 1 - -**Go take a break, preferably full day and minimally a meal break.** -- [ ] I took a break to refresh my mind to have a fresh perspective when I come back - -**Copy and paste your groupings above below. Please review and adjust accordingly. Feel free to rename the Disciplines, add new relevant and important activities/ideas, etc.** -Discipline 1 -- Activity 1 - -## Finalizing -**What are your finalized, grouped Disciplines from this exercise? What characteristics of Ikigai do these Disciplines have (love, world, money, skill)?** -`Answer` - -## Next Steps -When you are done, please make folders for Disciplines under `100 Disciplines/`. Their folder names should be prefixed with a prefix number, where the second digit denotes this discipline's number. **The first digit will always be 1** and the last a 0, inherited from `100 Disciplines`. - -It's set like this to have redundancy when typing references to specific Disciplines. You can either type the Discipline itself or type its Discipline prefix number. Have I found this function useful? Time will tell, but it's set up like this for now. - -Once the folder is created, you need to set up the Discipline files. Run the `QuickAdd: Create Discipline` command. It will ask you for input in the following order. *Source refers to the name of what you're creating.* -1. The path of the folder you made earlier -2. What is the Discipline Prefix Number? (first two digits) -3. The source emoji (e.g. 🎎) -4. The source base name (e.g. Well-Being) -5. The Discipline tag (1 followed by the discipline's number) - -You now have actionable items that make way towards meeting and sustaining your Life Pillars. But with our limited time and efforts, we need to have a focused Discipline, something that gives our lives meaning. See [[02 🔂 Convergence to Ikigai|Convergence to Ikigai]] \ No newline at end of file diff --git "a/999 Setup/02 \360\237\224\202 Convergence to Ikigai.md" "b/999 Setup/02 \360\237\224\202 Convergence to Ikigai.md" deleted file mode 100644 index b81bcb0..0000000 --- "a/999 Setup/02 \360\237\224\202 Convergence to Ikigai.md" +++ /dev/null @@ -1,139 +0,0 @@ ---- -aliases: [ ▶ Convergence to Ikigai, 98 ▶ Convergence to Ikigai, Convergence to Ikigai ] -tags: [ note/data, note/dashboard, introspection ] ---- -# 🔂 Convergence to Ikigai -This document serves to condense your Disciplines and define your single (or very small set) of [[Ikigai]]. - -To start with, for each Discipline, please make sure you answer the section **`Importance and Relevance.`** Also make sure you set proper YAML `ikigai` value(s). These values should reflect what you listed at the bottom of [[01 🔀 Divergence to Disciplines|🔀 Divergence to Disciplines]]. - -They can be any combination or none of the following. -```YAML -ikigai: - - world - - love - - money - - skill -``` - -## Your Life Through Disciplines -### Fundamental -This is the basis of what gives meaning to you. Everything else will build off of these fundamentals. - -#### Love -```dataview -TABLE WITHOUT ID link(file.name, file.aliases) as "Discipline", dynamic as "Dynamic" -FROM "100 Disciplines" -WHERE contains(tags, "note/discipline") and contains(ikigai, "love") -``` -#### World -```dataview -TABLE WITHOUT ID link(file.name, file.aliases) as "Discipline", dynamic as "Dynamic" -FROM "100 Disciplines" -WHERE contains(tags, "note/discipline") and contains(ikigai, "world") -``` -#### Money -```dataview -TABLE WITHOUT ID link(file.name, file.aliases) as "Discipline", dynamic as "Dynamic" -FROM "100 Disciplines" -WHERE contains(tags, "note/discipline") and contains(ikigai, "money") -``` -#### Skill -```dataview -TABLE WITHOUT ID link(file.name, file.aliases) as "Discipline", dynamic as "Dynamic" -FROM "100 Disciplines" -WHERE contains(tags, "note/discipline") and contains(ikigai, "skill") -``` - -### Dynamic 1 -This is the first layer of the emerging effect of 2 fundamental characteristics. - -#### Mission -Defined as what you love and what the world needs. -```dataview -TABLE WITHOUT ID link(file.name, file.aliases) as "Discipline", dynamic as "Dynamic" -FROM "100 Disciplines" -WHERE contains(tags, "note/discipline") and contains(ikigai, "love") and contains(ikigai, "world") -``` -#### Vocation -Defined as what the world needs and what you can be paid for. -```dataview -TABLE WITHOUT ID link(file.name, file.aliases) as "Discipline", dynamic as "Dynamic" -FROM "100 Disciplines" -WHERE contains(tags, "note/discipline") and contains(ikigai, "money") and contains(ikigai, "world") -``` -#### Profession -Defined as what you can be paid for and what you are skilled at. -```dataview -TABLE WITHOUT ID link(file.name, file.aliases) as "Discipline", dynamic as "Dynamic" -FROM "100 Disciplines" -WHERE contains(tags, "note/discipline") and contains(ikigai, "love") and contains(ikigai, "skill") -``` -#### Passion -Defined as what you are skilled at and what you love. -```dataview -TABLE WITHOUT ID link(file.name, file.aliases) as "Discipline", dynamic as "Dynamic" -FROM "100 Disciplines" -WHERE contains(tags, "note/discipline") and contains(ikigai, "love") and contains(ikigai, "skill") -``` - -### Dynamic 2 -These are the second emerging layer of 3 fundamental characteristics. These are Disciplines that are almost there, but are missing something to feel complete. - -#### Useless Satisfaction -These are the cool things in life that don't serve a higher purpose other than being cool. You love these things, they make you money, and you're skilled in it, but that's all to it. -```dataview -TABLE WITHOUT ID link(file.name, file.aliases) as "Discipline", dynamic as "Dynamic" -FROM "100 Disciplines" -WHERE contains(tags, "note/discipline") and contains(ikigai, "love") and contains(ikigai, "skill") and contains(ikigai, "money") -``` - -#### Empty Comfort -You can think of these as things you need to do, but aren't particularly fond of. They get the bills paid, you're genuinely being useful to others, and you just happen to be good at it. -```dataview -TABLE WITHOUT ID link(file.name, file.aliases) as "Discipline", dynamic as "Dynamic" -FROM "100 Disciplines" -WHERE contains(tags, "note/discipline") and contains(ikigai, "world") and contains(ikigai, "skill") and contains(ikigai, "money") -``` - -#### Uncertain Excitement -These are things that you know are genuinely useful, that you love, and that you know you can be compensated for. However, you have yet to acquire the skills required to do so. **This is something you can aim for with sufficient training.** -```dataview -TABLE WITHOUT ID link(file.name, file.aliases) as "Discipline", dynamic as "Dynamic" -FROM "100 Disciplines" -WHERE contains(tags, "note/discipline") and contains(ikigai, "world") and contains(ikigai, "love") and contains(ikigai, "money") -``` - -#### Valueless Delight -You love doing these things. People understand its significance and recognize that you're a pioneer at this. However, they this is something that isn't really sustainable financially. -```dataview -TABLE WITHOUT ID link(file.name, file.aliases) as "Discipline", dynamic as "Dynamic" -FROM "100 Disciplines" -WHERE contains(tags, "note/discipline") and contains(ikigai, "skill") and contains(ikigai, "love") and contains(ikigai, "money") -``` - -### Potential Ikigai -Below are your primary driving forces of life, your Ikigai. They are things you love, what the world needs, what you get money for, and what you are skilled at. -```dataview -TABLE WITHOUT ID link(file.name, file.aliases) as "Discipline", dynamic as "Dynamic" -FROM "100 Disciplines" -WHERE contains(tags, "note/discipline") and length(ikigai) = 4 -``` - -## Selecting your Ikigai(s) -You may find that you have multiple Ikigai. However, it's important to direct your attention to one, if not a very sparse amount, at a time. Truly touching and exercising all fundamental characteristics of a Discipline to sustain Ikigai takes commitment, requiring your limited time and effort. - -> While it's possible to choose Disciplines that are not Potential Ikigais, understand that it will require the initial investment of time and effort to fulfill the missing Ikigai characteristics. - -Now's the time to also reflect on what you wrote down under the Discipline's **`Importance and Relevance`** section. - -So, what will be your Primary Ikigai(s)? -- [[(OLD) 00 🎮 Game Dev|🎮 Game Dev]] - -For your selected Ikigai, please add to its note tags: `#note/ikigai` - -When done, it should appear below in preview mode. -![[Ikigai (View)]] - -## Next Steps -Your Ikigai is now set. This will be your focus moving forwards. Your Ikigai may change in the future, and if so you can always come back here. But we need to take action now. We need to further understand what makes this Ikigai Discipline resonate with us. See [[03 🎎 Ikigai Expansion|🎎 Ikigai Expansion]] \ No newline at end of file diff --git "a/999 Setup/03 \360\237\216\216 Ikigai Expansion.md" "b/999 Setup/03 \360\237\216\216 Ikigai Expansion.md" deleted file mode 100644 index 75e74e1..0000000 --- "a/999 Setup/03 \360\237\216\216 Ikigai Expansion.md" +++ /dev/null @@ -1,74 +0,0 @@ ---- -aliases: 🎎 Ikigai Expansion -tags: [ note/data, introspection ] ---- -# 🎎 Ikigai Expansion -Based on your process from on [[02 🔂 Convergence to Ikigai|🔻 Convergence to Ikigai]], this is your chosen Ikigai(s). -```dataview -TABLE WITHOUT ID - link(file.name, default(aliases, name)) as "Chosen Ikigai" -FROM #note/ikigai -``` - -We will now begin to expand on them below. Make sure for your Ikigai Disciplines that you thoroughly define their Discipline Pillars, and Dynamic on its Dashboard. Relevance and Importance is useful but not required, as it will be further expanded here. - -## Your Choice -**Why did you decide to choose this Discipline as your Ikigai?** -`Answer` - -## The Past -**For this Discipline, do you feel like you or the world meets all the Ikigai characteristics? Be thorough. Ikigai characteristics framed as questions are as follows.** -**What brought you to love?** -`Answer` - -**What have you gone through to be like this in this field?** -`Answer` - -**What has the world gone through to need it?** -`Answer` - -**How has it come to the point that people are paying for it?** -`Answer` - -**Objectively, from an outsider looking in, would they agree with what you said above? Consider asking another person. -** -`Answer` - -## The Present -**How strongly does your current view of your Ikigai Discipline's Pillars align with your Life Pillars? What about their Dynamics? Do you think this is a good thing? Why? -** -`Answer` - -**Are you partaking in this Discipline yet? What are you doing? -** -`Answer` - -**If you're not partaking in it, what's blocking you from actively pursuing this Discipline? What can you do right now? -** -`Answer` - -## The Future -**Long-term goals are a double-edged sword because once they are met, velocity and direction disappear. One solution is to play the infinite game. This is a lesson from Simon Sinek's book, The Infinite Game, which observes that naive business operate towards an end-goal, but the most successful operate as an infinite game. Does your Ikigai Discipline have pillars and a discipline that have considered infinite potential for growth?** -`Answer` - -> If your answer does not allow room for sufficient growth, especially over your lifetime, you should reconsider redefining this Discipline. - -**What will you do right now to make velocity towards your Ikigai Discipline?** -`Answer` - -## Epilogue -This is the end of this life management setup. You should have a better idea of what your Ikigai Discipline means to you. You should consider doing another pass on its **`Relevance and Importance`** section to further flesh it out. - -You also should have noticed that your Ikigai Discipline should have mostly aligned with your Life Pillars. If they are not, it may cause some conflict in the future. - -Everything is now setup. You can archive `999 Setup` into `900 Archive` for historical data. - -Start making Projects that align with Disciplines to create velocity towards your Ikigai. - -To make a project, first create a folder for it under its corresponding Discipline. No need to number it. Then create the initial files by running the command `QuickAdd: Create New Project`. It will ask for the following. -1. Path of project folder -2. Project emoji name -3. Name of project -4. Corresponding discipline tag -5. Link to the discipline note -6. Number prefix (enter 0) \ No newline at end of file diff --git a/Workbench.md b/Workbench.md index 912183c..e69de29 100644 --- a/Workbench.md +++ b/Workbench.md @@ -1,7 +0,0 @@ -```dataview -TABLE WITHOUT ID "," + join(rows.file.name, ",") as "Ongoing Projects QuickAdd String" -FROM #note/project -WHERE contains(list("00 Ongoing", "01 Blocked", "02 Planned"), status) -GROUP BY file.ext -``` -[[112 💡 Ramblings 110 Game Dev]] \ No newline at end of file