From fb5acef605f86de6e27b61346ae7ef620cf8f5ee Mon Sep 17 00:00:00 2001 From: Ankit Kapur Date: Sun, 16 Mar 2025 01:11:02 -0700 Subject: [PATCH] Fixed pull release issues from github actions bot --- .gitignore | 2 + main.js | 551 ----------------------------------------------------- main.ts | 26 ++- 3 files changed, 20 insertions(+), 559 deletions(-) delete mode 100644 main.js diff --git a/.gitignore b/.gitignore index 57c60d1..d4aa826 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +main.js + # Dependency directories node_modules/ diff --git a/main.js b/main.js deleted file mode 100644 index 75d9b9e..0000000 --- a/main.js +++ /dev/null @@ -1,551 +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. -***************************************************************************** */ - -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()); - }); -} - -typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { - var e = new Error(message); - return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; -}; - -const DEFAULT_SETTINGS = { - statusPropertyName: 'status', - showNotifications: false, - debugMode: false // Default to false for better performance -}; -class KanbanStatusUpdaterPlugin extends obsidian.Plugin { - constructor() { - super(...arguments); - // Track active observers to disconnect them when not needed - this.currentObserver = null; - this.isProcessing = false; - this.activeKanbanBoard = null; - } - onload() { - return __awaiter(this, void 0, void 0, function* () { - console.log('Loading Kanban Status Updater plugin'); - // Load settings - yield this.loadSettings(); - // Add status bar item - this.statusBarItem = this.addStatusBarItem(); - this.statusBarItem.setText('KSU: Idle'); - this.statusBarItem.addClass('kanban-status-updater-statusbar'); - // Display startup notification - if (this.settings.showNotifications) { - new obsidian.Notice('Kanban Status Updater activated'); - } - this.log('Plugin loaded'); - // Register DOM event listener for drag events - but only process if active leaf is Kanban - this.registerDomEvent(document, 'dragend', this.onDragEnd.bind(this)); - this.log('Registered drag event listener'); - // Watch for active leaf changes to only observe the current Kanban board - this.registerEvent(this.app.workspace.on('active-leaf-change', this.onActiveLeafChange.bind(this))); - // Initial check for active Kanban board - this.app.workspace.onLayoutReady(() => { - this.checkForActiveKanbanBoard(); - }); - // Add settings tab - this.addSettingTab(new KanbanStatusUpdaterSettingTab(this.app, this)); - }); - } - onunload() { - // Disconnect any active observers to prevent memory leaks - this.disconnectObservers(); - this.log('Plugin unloaded'); - } - loadSettings() { - return __awaiter(this, void 0, void 0, function* () { - this.settings = Object.assign({}, DEFAULT_SETTINGS, yield this.loadData()); - }); - } - saveSettings() { - return __awaiter(this, void 0, void 0, function* () { - yield this.saveData(this.settings); - }); - } - // Log helper with debug mode check - log(message) { - if (this.settings.debugMode) { - console.log(`[KSU] ${message}`); - // Update status bar - this.statusBarItem.setText(`KSU: ${message.substring(0, 25)}${message.length > 25 ? '...' : ''}`); - // Reset status bar after 3 seconds if no other logs happen - setTimeout(() => { - if (this.activeKanbanBoard) { - this.statusBarItem.setText('KSU: Active'); - } - else { - this.statusBarItem.setText('KSU: Idle'); - } - }, 3000); - } - } - // Clean up observers when switching away from a Kanban board - disconnectObservers() { - if (this.currentObserver) { - this.log('Disconnecting observer for performance'); - this.currentObserver.disconnect(); - this.currentObserver = null; - } - this.activeKanbanBoard = null; - } - // Check if the active leaf is a Kanban board - onActiveLeafChange(leaf) { - this.checkForActiveKanbanBoard(); - } - checkForActiveKanbanBoard() { - var _a; - // First disconnect any existing observers - this.disconnectObservers(); - // Get the active leaf - const activeLeaf = this.app.workspace.activeLeaf; - if (!activeLeaf) - return; - try { - // Find the content element safely - let contentEl = null; - // Use type assertions to avoid TypeScript errors - if (activeLeaf.view) { - // Try to access the contentEl property using type assertion - // @ts-ignore - contentEl exists but might not be in type definitions - contentEl = activeLeaf.view.contentEl; - } - // If that didn't work, try another approach - if (!contentEl) { - // Try to get the Kanban board directly from the DOM - // Leaf containers have 'view-content' elements that contain the actual view - const viewContent = (_a = activeLeaf.containerEl) === null || _a === void 0 ? void 0 : _a.querySelector('.view-content'); - if (viewContent) { - contentEl = viewContent; - } - else { - // Last resort - look for Kanban boards anywhere in the workspace - contentEl = document.querySelector('.workspace-leaf.mod-active .view-content'); - } - } - if (!contentEl) { - this.log('Could not access content element for active leaf'); - return; - } - // Check if this is a Kanban board - const kanbanBoard = contentEl.querySelector('.kanban-plugin__board'); - if (kanbanBoard) { - this.log('Found active Kanban board, setting up observer'); - this.statusBarItem.setText('KSU: Active'); - // Store reference to active board - this.activeKanbanBoard = kanbanBoard; - // Set up observer only for this board - this.setupObserverForBoard(kanbanBoard); - } - else { - this.log('Active leaf is not a Kanban board'); - this.statusBarItem.setText('KSU: Idle'); - } - } - catch (error) { - this.log(`Error detecting Kanban board: ${error.message}`); - this.statusBarItem.setText('KSU: Error'); - } - } - setupObserverForBoard(boardElement) { - // Create a new observer for this specific board - this.currentObserver = new MutationObserver((mutations) => { - if (this.isProcessing) - return; - // Simple debounce to prevent rapid-fire processing - this.isProcessing = true; - setTimeout(() => { - this.handleMutations(mutations); - this.isProcessing = false; - }, 300); - }); - // Observe only this board with minimal options needed - this.currentObserver.observe(boardElement, { - childList: true, - subtree: true, - attributes: false // Don't need attribute changes for performance - }); - this.log('Observer set up for active Kanban board'); - } - handleMutations(mutations) { - if (!this.activeKanbanBoard) - return; - try { - const max_mutations = 10; - // Only process a sample of mutations for performance - const mutationsToProcess = mutations.length > max_mutations ? - mutations.slice(0, max_mutations) : mutations; - this.log(`Got ${mutationsToProcess.length} mutations of ${mutations.length}`); - // Look for Kanban items in mutation - let i = 0; - for (const mutation of mutationsToProcess) { - this.log(`Mutation #${++i} - Type: ${mutation.type}`); - if (mutation.type === 'childList') { - // Check added nodes for Kanban items - for (const node of Array.from(mutation.addedNodes)) { - try { - // Check if node is any kind of Element (HTML or SVG) - if (node instanceof Element) { - this.log(`Processing Element of type: ${node.tagName}`); - // Handle the node according to its type - if (node instanceof HTMLElement || node instanceof HTMLDivElement) { - // Direct processing for HTML elements - this.log(`Found HTML element of type ${node.className}`); - this.processElement(node); - } - else if (node instanceof SVGElement) { - // For SVG elements, look for parent HTML element - const parentElement = node.closest('.kanban-plugin__item'); - if (parentElement) { - this.log('Found Kanban item parent of SVG element'); - this.processElement(parentElement); - } - else { - // Look for any kanban items in the document that might have changed - // This is for cases where the SVG update is related to a card movement - const items = this.activeKanbanBoard.querySelectorAll('.kanban-plugin__item'); - if (items.length > 0) { - // Process only the most recently modified item - const recentItems = Array.from(items).slice(-1); - for (const item of recentItems) { - this.log('Processing recent item after SVG change'); - this.processElement(item); - } - } - } - } - } - else if (node.nodeType === Node.TEXT_NODE) { - // For text nodes, check the parent element - const parentElement = node.parentElement; - if (parentElement && (parentElement.classList.contains('kanban-plugin__item-title') || - parentElement.closest('.kanban-plugin__item'))) { - this.log('Found text change in Kanban item'); - const itemElement = parentElement.closest('.kanban-plugin__item'); - if (itemElement) { - this.processElement(itemElement); - } - } - } - else { - this.log(`Skipping node type: ${node.nodeType}`); - } - } - catch (nodeError) { - this.log(`Error processing node: ${nodeError.message}`); - // Continue with next node even if this one fails - } - } - } - else { - this.log('Ignoring mutation type: ' + mutation.type); - } - } - } - catch (error) { - this.log(`Error in handleMutations: ${error.message}`); - } - } - onDragEnd(event) { - // Only process if we have an active Kanban board - if (!this.activeKanbanBoard || this.isProcessing) { - this.log('Drag end detected but no active Kanban board or already processing'); - this.log('activeKanbanBoard: ' + (this.activeKanbanBoard ? 'Yes' : 'No')); - this.log('isProcessing: ' + (this.isProcessing ? 'Yes' : 'No')); - return; - } - try { - this.log('Drag end detected'); - // Set processing flag to prevent multiple processing - this.isProcessing = true; - const target = event.target; - if (!target) - return; - this.processElement(target); - } - catch (error) { - this.log(`Error in onDragEnd: ${error.message}`); - } - finally { - // Reset processing flag after a delay to debounce - setTimeout(() => { - this.isProcessing = false; - }, 300); - } - } - processElement(element) { - try { - // Only process if inside our active Kanban board - if (!this.activeKanbanBoard || !element.closest('.kanban-plugin__board')) { - this.log('Element NOT in active Kanban board. Skipping.'); - return; - } - // Use different strategies to find the Kanban item - this.log("👀 Looking for Kanban item element"); - // Check if element is a Kanban item or contains one - const kanbanItem = element.classList.contains('kanban-plugin__item') - ? element - : element.querySelector('.kanban-plugin__item'); - if (kanbanItem) { - this.log(`✅ Found Kanban item: ${kanbanItem}`); - this.log('classList of kanbanItem: ' + kanbanItem.classList); - this.processKanbanItem(kanbanItem); - return; - } - this.log('Not a Kanban item, checking for parent'); - // If element is inside a Kanban item, find the parent - const parentItem = element.closest('.kanban-plugin__item'); - this.log(`Parent item: ${parentItem ? parentItem : 'Not found'}`); - if (parentItem) { - this.processKanbanItem(parentItem); - return; - } - } - catch (error) { - this.log(`Error in processElement: ${error.message}`); - } - } - processKanbanItem(itemElement) { - try { - // TODO: Select the title - const internalLink = itemElement.querySelector('.kanban-plugin__item-title .kanban-plugin__item-markdown a.internal-link'); - if (!internalLink) { - this.log('🚫 No internal link found in item'); - return; - } - this.log(`Found internal link: ${internalLink.textContent}`); - // Get the link path from data-href or href attribute - const linkPath = internalLink.getAttribute('data-href') || - internalLink.getAttribute('href'); - if (!linkPath) - return; - this.log(`🔗 Link path: ${linkPath}`); - // Find the lane (column) this item is in - const lane = itemElement.closest('.kanban-plugin__lane'); - if (!lane) { - this.log('🚫 No lane found for item'); - return; - } - // Get column name from the lane header - const laneHeader = lane.querySelector('.kanban-plugin__lane-header-wrapper .kanban-plugin__lane-title'); - if (!laneHeader) { - this.log('🚫 No laneHeader found for item'); - return; - } - const columnName = laneHeader.textContent.trim(); - this.log(`✅ Got lane name: ${columnName}`); - this.log(`Processing card with link to "${linkPath}" in column "${columnName}"`); - // Update the linked note's status - this.updateNoteStatus(linkPath, columnName); - } - catch (error) { - this.log(`Error in processKanbanItem: ${error.message}`); - } - } - updateNoteStatus(notePath, status) { - return __awaiter(this, void 0, void 0, function* () { - try { - // Find the linked file - const file = this.app.metadataCache.getFirstLinkpathDest(notePath, ''); - if (!file) { - if (this.settings.showNotifications) { - new obsidian.Notice(`⚠️ Note "${notePath}" not found`, 3000); - } - return; - } - // Read the file content - const content = yield this.app.vault.read(file); - // Check for existing frontmatter - const frontmatterRegex = /^---\n([\s\S]*?)\n---/; - const frontmatterMatch = content.match(frontmatterRegex); - let newContent; - let oldStatus = null; - if (frontmatterMatch) { - // File has frontmatter - const frontmatterText = frontmatterMatch[1]; - let frontmatterObj; - try { - // Try to parse the frontmatter - frontmatterObj = obsidian.parseYaml(frontmatterText); - // Check if status property already exists - if (frontmatterObj[this.settings.statusPropertyName]) { - oldStatus = frontmatterObj[this.settings.statusPropertyName]; - } - } - catch (e) { - this.log(`Error parsing frontmatter: ${e.message}`); - frontmatterObj = {}; - } - // Only update if status has changed - if (frontmatterObj[this.settings.statusPropertyName] !== status) { - // Update the status property - frontmatterObj[this.settings.statusPropertyName] = status; - // Generate new frontmatter text - const newFrontmatterText = obsidian.stringifyYaml(frontmatterObj); - // Replace the frontmatter in the content - newContent = content.replace(frontmatterRegex, `---\n${newFrontmatterText}---`); - // Save the modified content - yield this.app.vault.modify(file, newContent); - // Show notification if enabled - if (this.settings.showNotifications) { - if (oldStatus) { - new obsidian.Notice(`Updated ${this.settings.statusPropertyName}: "${oldStatus}" → "${status}" for ${file.basename}`, 3000); - } - else { - new obsidian.Notice(`Set ${this.settings.statusPropertyName}: "${status}" for ${file.basename}`, 3000); - } - } - this.log(`Updated status for ${file.basename} to "${status}"`); - } - else { - this.log(`Status already set to "${status}" for ${file.basename}, skipping update`); - } - } - else { - // File has no frontmatter, create it - const frontmatterObj = { - [this.settings.statusPropertyName]: status - }; - const frontmatterText = obsidian.stringifyYaml(frontmatterObj); - newContent = `---\n${frontmatterText}---\n\n${content}`; - // Save the modified content - yield this.app.vault.modify(file, newContent); - // Show notification if enabled - if (this.settings.showNotifications) { - new obsidian.Notice(`Added ${this.settings.statusPropertyName}: "${status}" to ${file.basename}`, 3000); - } - this.log(`Added frontmatter with status to ${file.basename}`); - } - } - catch (error) { - this.log(`Error updating note status: ${error.message}`); - if (this.settings.showNotifications) { - new obsidian.Notice(`⚠️ Error updating status: ${error.message}`, 3000); - } - } - }); - } - // Method for the test button to use - runTest() { - this.log('Running test...'); - // Make sure we're using the current active board - this.checkForActiveKanbanBoard(); - if (!this.activeKanbanBoard) { - new obsidian.Notice('⚠️ No active Kanban board found - open a Kanban board first', 5000); - return; - } - // Find items in the active board - const items = this.activeKanbanBoard.querySelectorAll('.kanban-plugin__item'); - const count = items.length; - new obsidian.Notice(`Found ${count} cards in active Kanban board`, 3000); - if (count > 0) { - // Process the first item with a link - for (let i = 0; i < count; i++) { - const item = items[i]; - if (item.querySelector('a.internal-link')) { - new obsidian.Notice(`Testing with card: "${item.textContent.substring(0, 20)}..."`, 3000); - this.processKanbanItem(item); - break; - } - } - } - } -} -class KanbanStatusUpdaterSettingTab extends obsidian.PluginSettingTab { - constructor(app, plugin) { - super(app, plugin); - this.plugin = plugin; - } - display() { - const { containerEl } = this; - containerEl.empty(); - containerEl.createEl('h2', { text: 'Kanban Status Updater Settings' }); - new obsidian.Setting(containerEl) - .setName('Status Property Name') - .setDesc('The name of the property to update when a card is moved') - .addText(text => text - .setPlaceholder('status') - .setValue(this.plugin.settings.statusPropertyName) - .onChange((value) => __awaiter(this, void 0, void 0, function* () { - this.plugin.settings.statusPropertyName = value; - yield this.plugin.saveSettings(); - }))); - new obsidian.Setting(containerEl) - .setName('Show Notifications') - .setDesc('Show a notification when a status is updated') - .addToggle(toggle => toggle - .setValue(this.plugin.settings.showNotifications) - .onChange((value) => __awaiter(this, void 0, void 0, function* () { - this.plugin.settings.showNotifications = value; - yield this.plugin.saveSettings(); - }))); - new obsidian.Setting(containerEl) - .setName('Debug Mode') - .setDesc('Enable detailed logging (reduces performance)') - .addToggle(toggle => toggle - .setValue(this.plugin.settings.debugMode) - .onChange((value) => __awaiter(this, void 0, void 0, function* () { - this.plugin.settings.debugMode = value; - yield this.plugin.saveSettings(); - if (value) { - new obsidian.Notice('Debug mode enabled - check console for logs', 3000); - } - else { - new obsidian.Notice('Debug mode disabled', 3000); - } - }))); - // Add a test button - new obsidian.Setting(containerEl) - .setName('Test Plugin') - .setDesc('Test with current Kanban board') - .addButton(button => button - .setButtonText('Run Test') - .onClick(() => { - this.plugin.runTest(); - })); - // Performance info - containerEl.createEl('h3', { text: 'Performance Optimization' }); - containerEl.createEl('p', { - text: 'This plugin only monitors the currently active Kanban board to minimize performance impact.' - }); - // Troubleshooting section - containerEl.createEl('h3', { text: 'Troubleshooting' }); - const list = containerEl.createEl('ul'); - list.createEl('li', { - text: 'The plugin only works with the currently open Kanban board' - }); - list.createEl('li', { - text: 'Cards must contain internal links to notes' - }); - list.createEl('li', { - text: 'Keep Debug Mode disabled for best performance' - }); - } -} - -module.exports = KanbanStatusUpdaterPlugin; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZXMiOlsibm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsIm1haW4udHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG5Db3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi5cclxuXHJcblBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZC9vciBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yIGFueVxyXG5wdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQuXHJcblxyXG5USEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIXHJcblJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWVxyXG5BTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsXHJcbklORElSRUNULCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTVxyXG5MT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUlxyXG5PVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SXHJcblBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuXHJcbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovXHJcbi8qIGdsb2JhbCBSZWZsZWN0LCBQcm9taXNlLCBTdXBwcmVzc2VkRXJyb3IsIFN5bWJvbCwgSXRlcmF0b3IgKi9cclxuXHJcbnZhciBleHRlbmRTdGF0aWNzID0gZnVuY3Rpb24oZCwgYikge1xyXG4gICAgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHRlbmRzKGQsIGIpIHtcclxuICAgIGlmICh0eXBlb2YgYiAhPT0gXCJmdW5jdGlvblwiICYmIGIgIT09IG51bGwpXHJcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNsYXNzIGV4dGVuZHMgdmFsdWUgXCIgKyBTdHJpbmcoYikgKyBcIiBpcyBub3QgYSBjb25zdHJ1Y3RvciBvciBudWxsXCIpO1xyXG4gICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fYXNzaWduID0gZnVuY3Rpb24oKSB7XHJcbiAgICBfX2Fzc2lnbiA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gX19hc3NpZ24odCkge1xyXG4gICAgICAgIGZvciAodmFyIHMsIGkgPSAxLCBuID0gYXJndW1lbnRzLmxlbmd0aDsgaSA8IG47IGkrKykge1xyXG4gICAgICAgICAgICBzID0gYXJndW1lbnRzW2ldO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkpIHRbcF0gPSBzW3BdO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdDtcclxuICAgIH1cclxuICAgIHJldHVybiBfX2Fzc2lnbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZXN0KHMsIGUpIHtcclxuICAgIHZhciB0ID0ge307XHJcbiAgICBmb3IgKHZhciBwIGluIHMpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocywgcCkgJiYgZS5pbmRleE9mKHApIDwgMClcclxuICAgICAgICB0W3BdID0gc1twXTtcclxuICAgIGlmIChzICE9IG51bGwgJiYgdHlwZW9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMgPT09IFwiZnVuY3Rpb25cIilcclxuICAgICAgICBmb3IgKHZhciBpID0gMCwgcCA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMocyk7IGkgPCBwLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmIChlLmluZGV4T2YocFtpXSkgPCAwICYmIE9iamVjdC5wcm90b3R5cGUucHJvcGVydHlJc0VudW1lcmFibGUuY2FsbChzLCBwW2ldKSlcclxuICAgICAgICAgICAgICAgIHRbcFtpXV0gPSBzW3BbaV1dO1xyXG4gICAgICAgIH1cclxuICAgIHJldHVybiB0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYykge1xyXG4gICAgdmFyIGMgPSBhcmd1bWVudHMubGVuZ3RoLCByID0gYyA8IDMgPyB0YXJnZXQgOiBkZXNjID09PSBudWxsID8gZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBrZXkpIDogZGVzYywgZDtcclxuICAgIGlmICh0eXBlb2YgUmVmbGVjdCA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgUmVmbGVjdC5kZWNvcmF0ZSA9PT0gXCJmdW5jdGlvblwiKSByID0gUmVmbGVjdC5kZWNvcmF0ZShkZWNvcmF0b3JzLCB0YXJnZXQsIGtleSwgZGVzYyk7XHJcbiAgICBlbHNlIGZvciAodmFyIGkgPSBkZWNvcmF0b3JzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSBpZiAoZCA9IGRlY29yYXRvcnNbaV0pIHIgPSAoYyA8IDMgPyBkKHIpIDogYyA+IDMgPyBkKHRhcmdldCwga2V5LCByKSA6IGQodGFyZ2V0LCBrZXkpKSB8fCByO1xyXG4gICAgcmV0dXJuIGMgPiAzICYmIHIgJiYgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwga2V5LCByKSwgcjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcGFyYW0ocGFyYW1JbmRleCwgZGVjb3JhdG9yKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKHRhcmdldCwga2V5KSB7IGRlY29yYXRvcih0YXJnZXQsIGtleSwgcGFyYW1JbmRleCk7IH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXNEZWNvcmF0ZShjdG9yLCBkZXNjcmlwdG9ySW4sIGRlY29yYXRvcnMsIGNvbnRleHRJbiwgaW5pdGlhbGl6ZXJzLCBleHRyYUluaXRpYWxpemVycykge1xyXG4gICAgZnVuY3Rpb24gYWNjZXB0KGYpIHsgaWYgKGYgIT09IHZvaWQgMCAmJiB0eXBlb2YgZiAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRnVuY3Rpb24gZXhwZWN0ZWRcIik7IHJldHVybiBmOyB9XHJcbiAgICB2YXIga2luZCA9IGNvbnRleHRJbi5raW5kLCBrZXkgPSBraW5kID09PSBcImdldHRlclwiID8gXCJnZXRcIiA6IGtpbmQgPT09IFwic2V0dGVyXCIgPyBcInNldFwiIDogXCJ2YWx1ZVwiO1xyXG4gICAgdmFyIHRhcmdldCA9ICFkZXNjcmlwdG9ySW4gJiYgY3RvciA/IGNvbnRleHRJbltcInN0YXRpY1wiXSA/IGN0b3IgOiBjdG9yLnByb3RvdHlwZSA6IG51bGw7XHJcbiAgICB2YXIgZGVzY3JpcHRvciA9IGRlc2NyaXB0b3JJbiB8fCAodGFyZ2V0ID8gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIGNvbnRleHRJbi5uYW1lKSA6IHt9KTtcclxuICAgIHZhciBfLCBkb25lID0gZmFsc2U7XHJcbiAgICBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xyXG4gICAgICAgIHZhciBjb250ZXh0ID0ge307XHJcbiAgICAgICAgZm9yICh2YXIgcCBpbiBjb250ZXh0SW4pIGNvbnRleHRbcF0gPSBwID09PSBcImFjY2Vzc1wiID8ge30gOiBjb250ZXh0SW5bcF07XHJcbiAgICAgICAgZm9yICh2YXIgcCBpbiBjb250ZXh0SW4uYWNjZXNzKSBjb250ZXh0LmFjY2Vzc1twXSA9IGNvbnRleHRJbi5hY2Nlc3NbcF07XHJcbiAgICAgICAgY29udGV4dC5hZGRJbml0aWFsaXplciA9IGZ1bmN0aW9uIChmKSB7IGlmIChkb25lKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGFkZCBpbml0aWFsaXplcnMgYWZ0ZXIgZGVjb3JhdGlvbiBoYXMgY29tcGxldGVkXCIpOyBleHRyYUluaXRpYWxpemVycy5wdXNoKGFjY2VwdChmIHx8IG51bGwpKTsgfTtcclxuICAgICAgICB2YXIgcmVzdWx0ID0gKDAsIGRlY29yYXRvcnNbaV0pKGtpbmQgPT09IFwiYWNjZXNzb3JcIiA/IHsgZ2V0OiBkZXNjcmlwdG9yLmdldCwgc2V0OiBkZXNjcmlwdG9yLnNldCB9IDogZGVzY3JpcHRvcltrZXldLCBjb250ZXh0KTtcclxuICAgICAgICBpZiAoa2luZCA9PT0gXCJhY2Nlc3NvclwiKSB7XHJcbiAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IHZvaWQgMCkgY29udGludWU7XHJcbiAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IG51bGwgfHwgdHlwZW9mIHJlc3VsdCAhPT0gXCJvYmplY3RcIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdCBleHBlY3RlZFwiKTtcclxuICAgICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LmdldCkpIGRlc2NyaXB0b3IuZ2V0ID0gXztcclxuICAgICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LnNldCkpIGRlc2NyaXB0b3Iuc2V0ID0gXztcclxuICAgICAgICAgICAgaWYgKF8gPSBhY2NlcHQocmVzdWx0LmluaXQpKSBpbml0aWFsaXplcnMudW5zaGlmdChfKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoXyA9IGFjY2VwdChyZXN1bHQpKSB7XHJcbiAgICAgICAgICAgIGlmIChraW5kID09PSBcImZpZWxkXCIpIGluaXRpYWxpemVycy51bnNoaWZ0KF8pO1xyXG4gICAgICAgICAgICBlbHNlIGRlc2NyaXB0b3Jba2V5XSA9IF87XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKHRhcmdldCkgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgY29udGV4dEluLm5hbWUsIGRlc2NyaXB0b3IpO1xyXG4gICAgZG9uZSA9IHRydWU7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19ydW5Jbml0aWFsaXplcnModGhpc0FyZywgaW5pdGlhbGl6ZXJzLCB2YWx1ZSkge1xyXG4gICAgdmFyIHVzZVZhbHVlID0gYXJndW1lbnRzLmxlbmd0aCA+IDI7XHJcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGluaXRpYWxpemVycy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIHZhbHVlID0gdXNlVmFsdWUgPyBpbml0aWFsaXplcnNbaV0uY2FsbCh0aGlzQXJnLCB2YWx1ZSkgOiBpbml0aWFsaXplcnNbaV0uY2FsbCh0aGlzQXJnKTtcclxuICAgIH1cclxuICAgIHJldHVybiB1c2VWYWx1ZSA/IHZhbHVlIDogdm9pZCAwO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcHJvcEtleSh4KSB7XHJcbiAgICByZXR1cm4gdHlwZW9mIHggPT09IFwic3ltYm9sXCIgPyB4IDogXCJcIi5jb25jYXQoeCk7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19zZXRGdW5jdGlvbk5hbWUoZiwgbmFtZSwgcHJlZml4KSB7XHJcbiAgICBpZiAodHlwZW9mIG5hbWUgPT09IFwic3ltYm9sXCIpIG5hbWUgPSBuYW1lLmRlc2NyaXB0aW9uID8gXCJbXCIuY29uY2F0KG5hbWUuZGVzY3JpcHRpb24sIFwiXVwiKSA6IFwiXCI7XHJcbiAgICByZXR1cm4gT2JqZWN0LmRlZmluZVByb3BlcnR5KGYsIFwibmFtZVwiLCB7IGNvbmZpZ3VyYWJsZTogdHJ1ZSwgdmFsdWU6IHByZWZpeCA/IFwiXCIuY29uY2F0KHByZWZpeCwgXCIgXCIsIG5hbWUpIDogbmFtZSB9KTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX21ldGFkYXRhKG1ldGFkYXRhS2V5LCBtZXRhZGF0YVZhbHVlKSB7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QubWV0YWRhdGEgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIFJlZmxlY3QubWV0YWRhdGEobWV0YWRhdGFLZXksIG1ldGFkYXRhVmFsdWUpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19hd2FpdGVyKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xyXG4gICAgZnVuY3Rpb24gYWRvcHQodmFsdWUpIHsgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgUCA/IHZhbHVlIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZSh2YWx1ZSk7IH0pOyB9XHJcbiAgICByZXR1cm4gbmV3IChQIHx8IChQID0gUHJvbWlzZSkpKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XHJcbiAgICAgICAgZnVuY3Rpb24gc3RlcChyZXN1bHQpIHsgcmVzdWx0LmRvbmUgPyByZXNvbHZlKHJlc3VsdC52YWx1ZSkgOiBhZG9wdChyZXN1bHQudmFsdWUpLnRoZW4oZnVsZmlsbGVkLCByZWplY3RlZCk7IH1cclxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZ2VuZXJhdG9yKHRoaXNBcmcsIGJvZHkpIHtcclxuICAgIHZhciBfID0geyBsYWJlbDogMCwgc2VudDogZnVuY3Rpb24oKSB7IGlmICh0WzBdICYgMSkgdGhyb3cgdFsxXTsgcmV0dXJuIHRbMV07IH0sIHRyeXM6IFtdLCBvcHM6IFtdIH0sIGYsIHksIHQsIGcgPSBPYmplY3QuY3JlYXRlKCh0eXBlb2YgSXRlcmF0b3IgPT09IFwiZnVuY3Rpb25cIiA/IEl0ZXJhdG9yIDogT2JqZWN0KS5wcm90b3R5cGUpO1xyXG4gICAgcmV0dXJuIGcubmV4dCA9IHZlcmIoMCksIGdbXCJ0aHJvd1wiXSA9IHZlcmIoMSksIGdbXCJyZXR1cm5cIl0gPSB2ZXJiKDIpLCB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgKGdbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpczsgfSksIGc7XHJcbiAgICBmdW5jdGlvbiB2ZXJiKG4pIHsgcmV0dXJuIGZ1bmN0aW9uICh2KSB7IHJldHVybiBzdGVwKFtuLCB2XSk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHN0ZXAob3ApIHtcclxuICAgICAgICBpZiAoZikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkdlbmVyYXRvciBpcyBhbHJlYWR5IGV4ZWN1dGluZy5cIik7XHJcbiAgICAgICAgd2hpbGUgKGcgJiYgKGcgPSAwLCBvcFswXSAmJiAoXyA9IDApKSwgXykgdHJ5IHtcclxuICAgICAgICAgICAgaWYgKGYgPSAxLCB5ICYmICh0ID0gb3BbMF0gJiAyID8geVtcInJldHVyblwiXSA6IG9wWzBdID8geVtcInRocm93XCJdIHx8ICgodCA9IHlbXCJyZXR1cm5cIl0pICYmIHQuY2FsbCh5KSwgMCkgOiB5Lm5leHQpICYmICEodCA9IHQuY2FsbCh5LCBvcFsxXSkpLmRvbmUpIHJldHVybiB0O1xyXG4gICAgICAgICAgICBpZiAoeSA9IDAsIHQpIG9wID0gW29wWzBdICYgMiwgdC52YWx1ZV07XHJcbiAgICAgICAgICAgIHN3aXRjaCAob3BbMF0pIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgMDogY2FzZSAxOiB0ID0gb3A7IGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSA0OiBfLmxhYmVsKys7IHJldHVybiB7IHZhbHVlOiBvcFsxXSwgZG9uZTogZmFsc2UgfTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNTogXy5sYWJlbCsrOyB5ID0gb3BbMV07IG9wID0gWzBdOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGNhc2UgNzogb3AgPSBfLm9wcy5wb3AoKTsgXy50cnlzLnBvcCgpOyBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEodCA9IF8udHJ5cywgdCA9IHQubGVuZ3RoID4gMCAmJiB0W3QubGVuZ3RoIC0gMV0pICYmIChvcFswXSA9PT0gNiB8fCBvcFswXSA9PT0gMikpIHsgXyA9IDA7IGNvbnRpbnVlOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wWzBdID09PSAzICYmICghdCB8fCAob3BbMV0gPiB0WzBdICYmIG9wWzFdIDwgdFszXSkpKSB7IF8ubGFiZWwgPSBvcFsxXTsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3BbMF0gPT09IDYgJiYgXy5sYWJlbCA8IHRbMV0pIHsgXy5sYWJlbCA9IHRbMV07IHQgPSBvcDsgYnJlYWs7IH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAodCAmJiBfLmxhYmVsIDwgdFsyXSkgeyBfLmxhYmVsID0gdFsyXTsgXy5vcHMucHVzaChvcCk7IGJyZWFrOyB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRbMl0pIF8ub3BzLnBvcCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIF8udHJ5cy5wb3AoKTsgY29udGludWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgb3AgPSBib2R5LmNhbGwodGhpc0FyZywgXyk7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkgeyBvcCA9IFs2LCBlXTsgeSA9IDA7IH0gZmluYWxseSB7IGYgPSB0ID0gMDsgfVxyXG4gICAgICAgIGlmIChvcFswXSAmIDUpIHRocm93IG9wWzFdOyByZXR1cm4geyB2YWx1ZTogb3BbMF0gPyBvcFsxXSA6IHZvaWQgMCwgZG9uZTogdHJ1ZSB9O1xyXG4gICAgfVxyXG59XHJcblxyXG5leHBvcnQgdmFyIF9fY3JlYXRlQmluZGluZyA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgbSwgaywgazIpIHtcclxuICAgIGlmIChrMiA9PT0gdW5kZWZpbmVkKSBrMiA9IGs7XHJcbiAgICB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IobSwgayk7XHJcbiAgICBpZiAoIWRlc2MgfHwgKFwiZ2V0XCIgaW4gZGVzYyA/ICFtLl9fZXNNb2R1bGUgOiBkZXNjLndyaXRhYmxlIHx8IGRlc2MuY29uZmlndXJhYmxlKSkge1xyXG4gICAgICAgIGRlc2MgPSB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZnVuY3Rpb24oKSB7IHJldHVybiBtW2tdOyB9IH07XHJcbiAgICB9XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobywgazIsIGRlc2MpO1xyXG59KSA6IChmdW5jdGlvbihvLCBtLCBrLCBrMikge1xyXG4gICAgaWYgKGsyID09PSB1bmRlZmluZWQpIGsyID0gaztcclxuICAgIG9bazJdID0gbVtrXTtcclxufSk7XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHBvcnRTdGFyKG0sIG8pIHtcclxuICAgIGZvciAodmFyIHAgaW4gbSkgaWYgKHAgIT09IFwiZGVmYXVsdFwiICYmICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobywgcCkpIF9fY3JlYXRlQmluZGluZyhvLCBtLCBwKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fdmFsdWVzKG8pIHtcclxuICAgIHZhciBzID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIFN5bWJvbC5pdGVyYXRvciwgbSA9IHMgJiYgb1tzXSwgaSA9IDA7XHJcbiAgICBpZiAobSkgcmV0dXJuIG0uY2FsbChvKTtcclxuICAgIGlmIChvICYmIHR5cGVvZiBvLmxlbmd0aCA9PT0gXCJudW1iZXJcIikgcmV0dXJuIHtcclxuICAgICAgICBuZXh0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChvICYmIGkgPj0gby5sZW5ndGgpIG8gPSB2b2lkIDA7XHJcbiAgICAgICAgICAgIHJldHVybiB7IHZhbHVlOiBvICYmIG9baSsrXSwgZG9uZTogIW8gfTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihzID8gXCJPYmplY3QgaXMgbm90IGl0ZXJhYmxlLlwiIDogXCJTeW1ib2wuaXRlcmF0b3IgaXMgbm90IGRlZmluZWQuXCIpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19yZWFkKG8sIG4pIHtcclxuICAgIHZhciBtID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9bU3ltYm9sLml0ZXJhdG9yXTtcclxuICAgIGlmICghbSkgcmV0dXJuIG87XHJcbiAgICB2YXIgaSA9IG0uY2FsbChvKSwgciwgYXIgPSBbXSwgZTtcclxuICAgIHRyeSB7XHJcbiAgICAgICAgd2hpbGUgKChuID09PSB2b2lkIDAgfHwgbi0tID4gMCkgJiYgIShyID0gaS5uZXh0KCkpLmRvbmUpIGFyLnB1c2goci52YWx1ZSk7XHJcbiAgICB9XHJcbiAgICBjYXRjaCAoZXJyb3IpIHsgZSA9IHsgZXJyb3I6IGVycm9yIH07IH1cclxuICAgIGZpbmFsbHkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGlmIChyICYmICFyLmRvbmUgJiYgKG0gPSBpW1wicmV0dXJuXCJdKSkgbS5jYWxsKGkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmaW5hbGx5IHsgaWYgKGUpIHRocm93IGUuZXJyb3I7IH1cclxuICAgIH1cclxuICAgIHJldHVybiBhcjtcclxufVxyXG5cclxuLyoqIEBkZXByZWNhdGVkICovXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZCgpIHtcclxuICAgIGZvciAodmFyIGFyID0gW10sIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKVxyXG4gICAgICAgIGFyID0gYXIuY29uY2F0KF9fcmVhZChhcmd1bWVudHNbaV0pKTtcclxuICAgIHJldHVybiBhcjtcclxufVxyXG5cclxuLyoqIEBkZXByZWNhdGVkICovXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3NwcmVhZEFycmF5cygpIHtcclxuICAgIGZvciAodmFyIHMgPSAwLCBpID0gMCwgaWwgPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgaWw7IGkrKykgcyArPSBhcmd1bWVudHNbaV0ubGVuZ3RoO1xyXG4gICAgZm9yICh2YXIgciA9IEFycmF5KHMpLCBrID0gMCwgaSA9IDA7IGkgPCBpbDsgaSsrKVxyXG4gICAgICAgIGZvciAodmFyIGEgPSBhcmd1bWVudHNbaV0sIGogPSAwLCBqbCA9IGEubGVuZ3RoOyBqIDwgamw7IGorKywgaysrKVxyXG4gICAgICAgICAgICByW2tdID0gYVtqXTtcclxuICAgIHJldHVybiByO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19zcHJlYWRBcnJheSh0bywgZnJvbSwgcGFjaykge1xyXG4gICAgaWYgKHBhY2sgfHwgYXJndW1lbnRzLmxlbmd0aCA9PT0gMikgZm9yICh2YXIgaSA9IDAsIGwgPSBmcm9tLmxlbmd0aCwgYXI7IGkgPCBsOyBpKyspIHtcclxuICAgICAgICBpZiAoYXIgfHwgIShpIGluIGZyb20pKSB7XHJcbiAgICAgICAgICAgIGlmICghYXIpIGFyID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoZnJvbSwgMCwgaSk7XHJcbiAgICAgICAgICAgIGFyW2ldID0gZnJvbVtpXTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdG8uY29uY2F0KGFyIHx8IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGZyb20pKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fYXdhaXQodikge1xyXG4gICAgcmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBfX2F3YWl0ID8gKHRoaXMudiA9IHYsIHRoaXMpIDogbmV3IF9fYXdhaXQodik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jR2VuZXJhdG9yKHRoaXNBcmcsIF9hcmd1bWVudHMsIGdlbmVyYXRvcikge1xyXG4gICAgaWYgKCFTeW1ib2wuYXN5bmNJdGVyYXRvcikgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0l0ZXJhdG9yIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgIHZhciBnID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pLCBpLCBxID0gW107XHJcbiAgICByZXR1cm4gaSA9IE9iamVjdC5jcmVhdGUoKHR5cGVvZiBBc3luY0l0ZXJhdG9yID09PSBcImZ1bmN0aW9uXCIgPyBBc3luY0l0ZXJhdG9yIDogT2JqZWN0KS5wcm90b3R5cGUpLCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIsIGF3YWl0UmV0dXJuKSwgaVtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9LCBpO1xyXG4gICAgZnVuY3Rpb24gYXdhaXRSZXR1cm4oZikgeyByZXR1cm4gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh2KS50aGVuKGYsIHJlamVjdCk7IH07IH1cclxuICAgIGZ1bmN0aW9uIHZlcmIobiwgZikgeyBpZiAoZ1tuXSkgeyBpW25dID0gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChhLCBiKSB7IHEucHVzaChbbiwgdiwgYSwgYl0pID4gMSB8fCByZXN1bWUobiwgdik7IH0pOyB9OyBpZiAoZikgaVtuXSA9IGYoaVtuXSk7IH0gfVxyXG4gICAgZnVuY3Rpb24gcmVzdW1lKG4sIHYpIHsgdHJ5IHsgc3RlcChnW25dKHYpKTsgfSBjYXRjaCAoZSkgeyBzZXR0bGUocVswXVszXSwgZSk7IH0gfVxyXG4gICAgZnVuY3Rpb24gc3RlcChyKSB7IHIudmFsdWUgaW5zdGFuY2VvZiBfX2F3YWl0ID8gUHJvbWlzZS5yZXNvbHZlKHIudmFsdWUudikudGhlbihmdWxmaWxsLCByZWplY3QpIDogc2V0dGxlKHFbMF1bMl0sIHIpOyB9XHJcbiAgICBmdW5jdGlvbiBmdWxmaWxsKHZhbHVlKSB7IHJlc3VtZShcIm5leHRcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiByZWplY3QodmFsdWUpIHsgcmVzdW1lKFwidGhyb3dcIiwgdmFsdWUpOyB9XHJcbiAgICBmdW5jdGlvbiBzZXR0bGUoZiwgdikgeyBpZiAoZih2KSwgcS5zaGlmdCgpLCBxLmxlbmd0aCkgcmVzdW1lKHFbMF1bMF0sIHFbMF1bMV0pOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jRGVsZWdhdG9yKG8pIHtcclxuICAgIHZhciBpLCBwO1xyXG4gICAgcmV0dXJuIGkgPSB7fSwgdmVyYihcIm5leHRcIiksIHZlcmIoXCJ0aHJvd1wiLCBmdW5jdGlvbiAoZSkgeyB0aHJvdyBlOyB9KSwgdmVyYihcInJldHVyblwiKSwgaVtTeW1ib2wuaXRlcmF0b3JdID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpczsgfSwgaTtcclxuICAgIGZ1bmN0aW9uIHZlcmIobiwgZikgeyBpW25dID0gb1tuXSA/IGZ1bmN0aW9uICh2KSB7IHJldHVybiAocCA9ICFwKSA/IHsgdmFsdWU6IF9fYXdhaXQob1tuXSh2KSksIGRvbmU6IGZhbHNlIH0gOiBmID8gZih2KSA6IHY7IH0gOiBmOyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FzeW5jVmFsdWVzKG8pIHtcclxuICAgIGlmICghU3ltYm9sLmFzeW5jSXRlcmF0b3IpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJTeW1ib2wuYXN5bmNJdGVyYXRvciBpcyBub3QgZGVmaW5lZC5cIik7XHJcbiAgICB2YXIgbSA9IG9bU3ltYm9sLmFzeW5jSXRlcmF0b3JdLCBpO1xyXG4gICAgcmV0dXJuIG0gPyBtLmNhbGwobykgOiAobyA9IHR5cGVvZiBfX3ZhbHVlcyA9PT0gXCJmdW5jdGlvblwiID8gX192YWx1ZXMobykgOiBvW1N5bWJvbC5pdGVyYXRvcl0oKSwgaSA9IHt9LCB2ZXJiKFwibmV4dFwiKSwgdmVyYihcInRocm93XCIpLCB2ZXJiKFwicmV0dXJuXCIpLCBpW1N5bWJvbC5hc3luY0l0ZXJhdG9yXSA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXM7IH0sIGkpO1xyXG4gICAgZnVuY3Rpb24gdmVyYihuKSB7IGlbbl0gPSBvW25dICYmIGZ1bmN0aW9uICh2KSB7IHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7IHYgPSBvW25dKHYpLCBzZXR0bGUocmVzb2x2ZSwgcmVqZWN0LCB2LmRvbmUsIHYudmFsdWUpOyB9KTsgfTsgfVxyXG4gICAgZnVuY3Rpb24gc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgZCwgdikgeyBQcm9taXNlLnJlc29sdmUodikudGhlbihmdW5jdGlvbih2KSB7IHJlc29sdmUoeyB2YWx1ZTogdiwgZG9uZTogZCB9KTsgfSwgcmVqZWN0KTsgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19tYWtlVGVtcGxhdGVPYmplY3QoY29va2VkLCByYXcpIHtcclxuICAgIGlmIChPYmplY3QuZGVmaW5lUHJvcGVydHkpIHsgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvb2tlZCwgXCJyYXdcIiwgeyB2YWx1ZTogcmF3IH0pOyB9IGVsc2UgeyBjb29rZWQucmF3ID0gcmF3OyB9XHJcbiAgICByZXR1cm4gY29va2VkO1xyXG59O1xyXG5cclxudmFyIF9fc2V0TW9kdWxlRGVmYXVsdCA9IE9iamVjdC5jcmVhdGUgPyAoZnVuY3Rpb24obywgdikge1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG8sIFwiZGVmYXVsdFwiLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2IH0pO1xyXG59KSA6IGZ1bmN0aW9uKG8sIHYpIHtcclxuICAgIG9bXCJkZWZhdWx0XCJdID0gdjtcclxufTtcclxuXHJcbnZhciBvd25LZXlzID0gZnVuY3Rpb24obykge1xyXG4gICAgb3duS2V5cyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzIHx8IGZ1bmN0aW9uIChvKSB7XHJcbiAgICAgICAgdmFyIGFyID0gW107XHJcbiAgICAgICAgZm9yICh2YXIgayBpbiBvKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG8sIGspKSBhclthci5sZW5ndGhdID0gaztcclxuICAgICAgICByZXR1cm4gYXI7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIG93bktleXMobyk7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19pbXBvcnRTdGFyKG1vZCkge1xyXG4gICAgaWYgKG1vZCAmJiBtb2QuX19lc01vZHVsZSkgcmV0dXJuIG1vZDtcclxuICAgIHZhciByZXN1bHQgPSB7fTtcclxuICAgIGlmIChtb2QgIT0gbnVsbCkgZm9yICh2YXIgayA9IG93bktleXMobW9kKSwgaSA9IDA7IGkgPCBrLmxlbmd0aDsgaSsrKSBpZiAoa1tpXSAhPT0gXCJkZWZhdWx0XCIpIF9fY3JlYXRlQmluZGluZyhyZXN1bHQsIG1vZCwga1tpXSk7XHJcbiAgICBfX3NldE1vZHVsZURlZmF1bHQocmVzdWx0LCBtb2QpO1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9faW1wb3J0RGVmYXVsdChtb2QpIHtcclxuICAgIHJldHVybiAobW9kICYmIG1vZC5fX2VzTW9kdWxlKSA/IG1vZCA6IHsgZGVmYXVsdDogbW9kIH07XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHJlY2VpdmVyLCBzdGF0ZSwga2luZCwgZikge1xyXG4gICAgaWYgKGtpbmQgPT09IFwiYVwiICYmICFmKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiUHJpdmF0ZSBhY2Nlc3NvciB3YXMgZGVmaW5lZCB3aXRob3V0IGEgZ2V0dGVyXCIpO1xyXG4gICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gXCJmdW5jdGlvblwiID8gcmVjZWl2ZXIgIT09IHN0YXRlIHx8ICFmIDogIXN0YXRlLmhhcyhyZWNlaXZlcikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgcmVhZCBwcml2YXRlIG1lbWJlciBmcm9tIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXRcIik7XHJcbiAgICByZXR1cm4ga2luZCA9PT0gXCJtXCIgPyBmIDoga2luZCA9PT0gXCJhXCIgPyBmLmNhbGwocmVjZWl2ZXIpIDogZiA/IGYudmFsdWUgOiBzdGF0ZS5nZXQocmVjZWl2ZXIpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZFNldChyZWNlaXZlciwgc3RhdGUsIHZhbHVlLCBraW5kLCBmKSB7XHJcbiAgICBpZiAoa2luZCA9PT0gXCJtXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIG1ldGhvZCBpcyBub3Qgd3JpdGFibGVcIik7XHJcbiAgICBpZiAoa2luZCA9PT0gXCJhXCIgJiYgIWYpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJQcml2YXRlIGFjY2Vzc29yIHdhcyBkZWZpbmVkIHdpdGhvdXQgYSBzZXR0ZXJcIik7XHJcbiAgICBpZiAodHlwZW9mIHN0YXRlID09PSBcImZ1bmN0aW9uXCIgPyByZWNlaXZlciAhPT0gc3RhdGUgfHwgIWYgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCB3cml0ZSBwcml2YXRlIG1lbWJlciB0byBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0XCIpO1xyXG4gICAgcmV0dXJuIChraW5kID09PSBcImFcIiA/IGYuY2FsbChyZWNlaXZlciwgdmFsdWUpIDogZiA/IGYudmFsdWUgPSB2YWx1ZSA6IHN0YXRlLnNldChyZWNlaXZlciwgdmFsdWUpKSwgdmFsdWU7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2NsYXNzUHJpdmF0ZUZpZWxkSW4oc3RhdGUsIHJlY2VpdmVyKSB7XHJcbiAgICBpZiAocmVjZWl2ZXIgPT09IG51bGwgfHwgKHR5cGVvZiByZWNlaXZlciAhPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgcmVjZWl2ZXIgIT09IFwiZnVuY3Rpb25cIikpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgdXNlICdpbicgb3BlcmF0b3Igb24gbm9uLW9iamVjdFwiKTtcclxuICAgIHJldHVybiB0eXBlb2Ygc3RhdGUgPT09IFwiZnVuY3Rpb25cIiA/IHJlY2VpdmVyID09PSBzdGF0ZSA6IHN0YXRlLmhhcyhyZWNlaXZlcik7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2FkZERpc3Bvc2FibGVSZXNvdXJjZShlbnYsIHZhbHVlLCBhc3luYykge1xyXG4gICAgaWYgKHZhbHVlICE9PSBudWxsICYmIHZhbHVlICE9PSB2b2lkIDApIHtcclxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSBcIm9iamVjdFwiICYmIHR5cGVvZiB2YWx1ZSAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiT2JqZWN0IGV4cGVjdGVkLlwiKTtcclxuICAgICAgICB2YXIgZGlzcG9zZSwgaW5uZXI7XHJcbiAgICAgICAgaWYgKGFzeW5jKSB7XHJcbiAgICAgICAgICAgIGlmICghU3ltYm9sLmFzeW5jRGlzcG9zZSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5hc3luY0Rpc3Bvc2UgaXMgbm90IGRlZmluZWQuXCIpO1xyXG4gICAgICAgICAgICBkaXNwb3NlID0gdmFsdWVbU3ltYm9sLmFzeW5jRGlzcG9zZV07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChkaXNwb3NlID09PSB2b2lkIDApIHtcclxuICAgICAgICAgICAgaWYgKCFTeW1ib2wuZGlzcG9zZSkgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN5bWJvbC5kaXNwb3NlIGlzIG5vdCBkZWZpbmVkLlwiKTtcclxuICAgICAgICAgICAgZGlzcG9zZSA9IHZhbHVlW1N5bWJvbC5kaXNwb3NlXTtcclxuICAgICAgICAgICAgaWYgKGFzeW5jKSBpbm5lciA9IGRpc3Bvc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0eXBlb2YgZGlzcG9zZSAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiT2JqZWN0IG5vdCBkaXNwb3NhYmxlLlwiKTtcclxuICAgICAgICBpZiAoaW5uZXIpIGRpc3Bvc2UgPSBmdW5jdGlvbigpIHsgdHJ5IHsgaW5uZXIuY2FsbCh0aGlzKTsgfSBjYXRjaCAoZSkgeyByZXR1cm4gUHJvbWlzZS5yZWplY3QoZSk7IH0gfTtcclxuICAgICAgICBlbnYuc3RhY2sucHVzaCh7IHZhbHVlOiB2YWx1ZSwgZGlzcG9zZTogZGlzcG9zZSwgYXN5bmM6IGFzeW5jIH0pO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAoYXN5bmMpIHtcclxuICAgICAgICBlbnYuc3RhY2sucHVzaCh7IGFzeW5jOiB0cnVlIH0pO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHZhbHVlO1xyXG5cclxufVxyXG5cclxudmFyIF9TdXBwcmVzc2VkRXJyb3IgPSB0eXBlb2YgU3VwcHJlc3NlZEVycm9yID09PSBcImZ1bmN0aW9uXCIgPyBTdXBwcmVzc2VkRXJyb3IgOiBmdW5jdGlvbiAoZXJyb3IsIHN1cHByZXNzZWQsIG1lc3NhZ2UpIHtcclxuICAgIHZhciBlID0gbmV3IEVycm9yKG1lc3NhZ2UpO1xyXG4gICAgcmV0dXJuIGUubmFtZSA9IFwiU3VwcHJlc3NlZEVycm9yXCIsIGUuZXJyb3IgPSBlcnJvciwgZS5zdXBwcmVzc2VkID0gc3VwcHJlc3NlZCwgZTtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX2Rpc3Bvc2VSZXNvdXJjZXMoZW52KSB7XHJcbiAgICBmdW5jdGlvbiBmYWlsKGUpIHtcclxuICAgICAgICBlbnYuZXJyb3IgPSBlbnYuaGFzRXJyb3IgPyBuZXcgX1N1cHByZXNzZWRFcnJvcihlLCBlbnYuZXJyb3IsIFwiQW4gZXJyb3Igd2FzIHN1cHByZXNzZWQgZHVyaW5nIGRpc3Bvc2FsLlwiKSA6IGU7XHJcbiAgICAgICAgZW52Lmhhc0Vycm9yID0gdHJ1ZTtcclxuICAgIH1cclxuICAgIHZhciByLCBzID0gMDtcclxuICAgIGZ1bmN0aW9uIG5leHQoKSB7XHJcbiAgICAgICAgd2hpbGUgKHIgPSBlbnYuc3RhY2sucG9wKCkpIHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIGlmICghci5hc3luYyAmJiBzID09PSAxKSByZXR1cm4gcyA9IDAsIGVudi5zdGFjay5wdXNoKHIpLCBQcm9taXNlLnJlc29sdmUoKS50aGVuKG5leHQpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHIuZGlzcG9zZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSByLmRpc3Bvc2UuY2FsbChyLnZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoci5hc3luYykgcmV0dXJuIHMgfD0gMiwgUHJvbWlzZS5yZXNvbHZlKHJlc3VsdCkudGhlbihuZXh0LCBmdW5jdGlvbihlKSB7IGZhaWwoZSk7IHJldHVybiBuZXh0KCk7IH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSBzIHw9IDE7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgIGZhaWwoZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHMgPT09IDEpIHJldHVybiBlbnYuaGFzRXJyb3IgPyBQcm9taXNlLnJlamVjdChlbnYuZXJyb3IpIDogUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgICAgICAgaWYgKGVudi5oYXNFcnJvcikgdGhyb3cgZW52LmVycm9yO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIG5leHQoKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmV3cml0ZVJlbGF0aXZlSW1wb3J0RXh0ZW5zaW9uKHBhdGgsIHByZXNlcnZlSnN4KSB7XHJcbiAgICBpZiAodHlwZW9mIHBhdGggPT09IFwic3RyaW5nXCIgJiYgL15cXC5cXC4/XFwvLy50ZXN0KHBhdGgpKSB7XHJcbiAgICAgICAgcmV0dXJuIHBhdGgucmVwbGFjZSgvXFwuKHRzeCkkfCgoPzpcXC5kKT8pKCg/OlxcLlteLi9dKz8pPylcXC4oW2NtXT8pdHMkL2ksIGZ1bmN0aW9uIChtLCB0c3gsIGQsIGV4dCwgY20pIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRzeCA/IHByZXNlcnZlSnN4ID8gXCIuanN4XCIgOiBcIi5qc1wiIDogZCAmJiAoIWV4dCB8fCAhY20pID8gbSA6IChkICsgZXh0ICsgXCIuXCIgKyBjbS50b0xvd2VyQ2FzZSgpICsgXCJqc1wiKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIHJldHVybiBwYXRoO1xyXG59XHJcblxyXG5leHBvcnQgZGVmYXVsdCB7XHJcbiAgICBfX2V4dGVuZHM6IF9fZXh0ZW5kcyxcclxuICAgIF9fYXNzaWduOiBfX2Fzc2lnbixcclxuICAgIF9fcmVzdDogX19yZXN0LFxyXG4gICAgX19kZWNvcmF0ZTogX19kZWNvcmF0ZSxcclxuICAgIF9fcGFyYW06IF9fcGFyYW0sXHJcbiAgICBfX2VzRGVjb3JhdGU6IF9fZXNEZWNvcmF0ZSxcclxuICAgIF9fcnVuSW5pdGlhbGl6ZXJzOiBfX3J1bkluaXRpYWxpemVycyxcclxuICAgIF9fcHJvcEtleTogX19wcm9wS2V5LFxyXG4gICAgX19zZXRGdW5jdGlvbk5hbWU6IF9fc2V0RnVuY3Rpb25OYW1lLFxyXG4gICAgX19tZXRhZGF0YTogX19tZXRhZGF0YSxcclxuICAgIF9fYXdhaXRlcjogX19hd2FpdGVyLFxyXG4gICAgX19nZW5lcmF0b3I6IF9fZ2VuZXJhdG9yLFxyXG4gICAgX19jcmVhdGVCaW5kaW5nOiBfX2NyZWF0ZUJpbmRpbmcsXHJcbiAgICBfX2V4cG9ydFN0YXI6IF9fZXhwb3J0U3RhcixcclxuICAgIF9fdmFsdWVzOiBfX3ZhbHVlcyxcclxuICAgIF9fcmVhZDogX19yZWFkLFxyXG4gICAgX19zcHJlYWQ6IF9fc3ByZWFkLFxyXG4gICAgX19zcHJlYWRBcnJheXM6IF9fc3ByZWFkQXJyYXlzLFxyXG4gICAgX19zcHJlYWRBcnJheTogX19zcHJlYWRBcnJheSxcclxuICAgIF9fYXdhaXQ6IF9fYXdhaXQsXHJcbiAgICBfX2FzeW5jR2VuZXJhdG9yOiBfX2FzeW5jR2VuZXJhdG9yLFxyXG4gICAgX19hc3luY0RlbGVnYXRvcjogX19hc3luY0RlbGVnYXRvcixcclxuICAgIF9fYXN5bmNWYWx1ZXM6IF9fYXN5bmNWYWx1ZXMsXHJcbiAgICBfX21ha2VUZW1wbGF0ZU9iamVjdDogX19tYWtlVGVtcGxhdGVPYmplY3QsXHJcbiAgICBfX2ltcG9ydFN0YXI6IF9faW1wb3J0U3RhcixcclxuICAgIF9faW1wb3J0RGVmYXVsdDogX19pbXBvcnREZWZhdWx0LFxyXG4gICAgX19jbGFzc1ByaXZhdGVGaWVsZEdldDogX19jbGFzc1ByaXZhdGVGaWVsZEdldCxcclxuICAgIF9fY2xhc3NQcml2YXRlRmllbGRTZXQ6IF9fY2xhc3NQcml2YXRlRmllbGRTZXQsXHJcbiAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkSW46IF9fY2xhc3NQcml2YXRlRmllbGRJbixcclxuICAgIF9fYWRkRGlzcG9zYWJsZVJlc291cmNlOiBfX2FkZERpc3Bvc2FibGVSZXNvdXJjZSxcclxuICAgIF9fZGlzcG9zZVJlc291cmNlczogX19kaXNwb3NlUmVzb3VyY2VzLFxyXG4gICAgX19yZXdyaXRlUmVsYXRpdmVJbXBvcnRFeHRlbnNpb246IF9fcmV3cml0ZVJlbGF0aXZlSW1wb3J0RXh0ZW5zaW9uLFxyXG59O1xyXG4iLCJpbXBvcnQge1xuICBBcHAsXG4gIE5vdGljZSxcbiAgcGFyc2VZYW1sLFxuICBQbHVnaW4sXG4gIFBsdWdpblNldHRpbmdUYWIsXG4gIFNldHRpbmcsXG4gIHN0cmluZ2lmeVlhbWwsXG4gIFdvcmtzcGFjZUxlYWZcbn0gZnJvbSAnb2JzaWRpYW4nO1xuXG5pbnRlcmZhY2UgS2FuYmFuU3RhdHVzVXBkYXRlclNldHRpbmdzIHtcbiAgc3RhdHVzUHJvcGVydHlOYW1lOiBzdHJpbmc7XG4gIHNob3dOb3RpZmljYXRpb25zOiBib29sZWFuO1xuICBkZWJ1Z01vZGU6IGJvb2xlYW47XG59XG5cbmNvbnN0IERFRkFVTFRfU0VUVElOR1M6IEthbmJhblN0YXR1c1VwZGF0ZXJTZXR0aW5ncyA9IHtcbiAgc3RhdHVzUHJvcGVydHlOYW1lOiAnc3RhdHVzJyxcbiAgc2hvd05vdGlmaWNhdGlvbnM6IGZhbHNlLFxuICBkZWJ1Z01vZGU6IGZhbHNlICAvLyBEZWZhdWx0IHRvIGZhbHNlIGZvciBiZXR0ZXIgcGVyZm9ybWFuY2Vcbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgS2FuYmFuU3RhdHVzVXBkYXRlclBsdWdpbiBleHRlbmRzIFBsdWdpbiB7XG4gIHNldHRpbmdzOiBLYW5iYW5TdGF0dXNVcGRhdGVyU2V0dGluZ3M7XG4gIHN0YXR1c0Jhckl0ZW06IEhUTUxFbGVtZW50O1xuICBcbiAgLy8gVHJhY2sgYWN0aXZlIG9ic2VydmVycyB0byBkaXNjb25uZWN0IHRoZW0gd2hlbiBub3QgbmVlZGVkXG4gIHByaXZhdGUgY3VycmVudE9ic2VydmVyOiBNdXRhdGlvbk9ic2VydmVyIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgaXNQcm9jZXNzaW5nID0gZmFsc2U7XG4gIHByaXZhdGUgYWN0aXZlS2FuYmFuQm9hcmQ6IEhUTUxFbGVtZW50IHwgbnVsbCA9IG51bGw7XG4gIFxuICBhc3luYyBvbmxvYWQoKSB7XG4gICAgICBjb25zb2xlLmxvZygnTG9hZGluZyBLYW5iYW4gU3RhdHVzIFVwZGF0ZXIgcGx1Z2luJyk7XG4gICAgICBcbiAgICAgIC8vIExvYWQgc2V0dGluZ3NcbiAgICAgIGF3YWl0IHRoaXMubG9hZFNldHRpbmdzKCk7XG4gICAgICBcbiAgICAgIC8vIEFkZCBzdGF0dXMgYmFyIGl0ZW1cbiAgICAgIHRoaXMuc3RhdHVzQmFySXRlbSA9IHRoaXMuYWRkU3RhdHVzQmFySXRlbSgpO1xuICAgICAgdGhpcy5zdGF0dXNCYXJJdGVtLnNldFRleHQoJ0tTVTogSWRsZScpO1xuICAgICAgdGhpcy5zdGF0dXNCYXJJdGVtLmFkZENsYXNzKCdrYW5iYW4tc3RhdHVzLXVwZGF0ZXItc3RhdHVzYmFyJyk7XG4gICAgICBcbiAgICAgIC8vIERpc3BsYXkgc3RhcnR1cCBub3RpZmljYXRpb25cbiAgICAgIGlmICh0aGlzLnNldHRpbmdzLnNob3dOb3RpZmljYXRpb25zKSB7XG4gICAgICAgICAgbmV3IE5vdGljZSgnS2FuYmFuIFN0YXR1cyBVcGRhdGVyIGFjdGl2YXRlZCcpO1xuICAgICAgfVxuICAgICAgdGhpcy5sb2coJ1BsdWdpbiBsb2FkZWQnKTtcbiAgICAgIFxuICAgICAgLy8gUmVnaXN0ZXIgRE9NIGV2ZW50IGxpc3RlbmVyIGZvciBkcmFnIGV2ZW50cyAtIGJ1dCBvbmx5IHByb2Nlc3MgaWYgYWN0aXZlIGxlYWYgaXMgS2FuYmFuXG4gICAgICB0aGlzLnJlZ2lzdGVyRG9tRXZlbnQoZG9jdW1lbnQsICdkcmFnZW5kJywgdGhpcy5vbkRyYWdFbmQuYmluZCh0aGlzKSk7XG4gICAgICB0aGlzLmxvZygnUmVnaXN0ZXJlZCBkcmFnIGV2ZW50IGxpc3RlbmVyJyk7XG4gICAgICBcbiAgICAgIC8vIFdhdGNoIGZvciBhY3RpdmUgbGVhZiBjaGFuZ2VzIHRvIG9ubHkgb2JzZXJ2ZSB0aGUgY3VycmVudCBLYW5iYW4gYm9hcmRcbiAgICAgIHRoaXMucmVnaXN0ZXJFdmVudChcbiAgICAgICAgICB0aGlzLmFwcC53b3Jrc3BhY2Uub24oJ2FjdGl2ZS1sZWFmLWNoYW5nZScsIHRoaXMub25BY3RpdmVMZWFmQ2hhbmdlLmJpbmQodGhpcykpXG4gICAgICApO1xuICAgICAgXG4gICAgICAvLyBJbml0aWFsIGNoZWNrIGZvciBhY3RpdmUgS2FuYmFuIGJvYXJkXG4gICAgICB0aGlzLmFwcC53b3Jrc3BhY2Uub25MYXlvdXRSZWFkeSgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5jaGVja0ZvckFjdGl2ZUthbmJhbkJvYXJkKCk7XG4gICAgICB9KTtcbiAgICAgIFxuICAgICAgLy8gQWRkIHNldHRpbmdzIHRhYlxuICAgICAgdGhpcy5hZGRTZXR0aW5nVGFiKG5ldyBLYW5iYW5TdGF0dXNVcGRhdGVyU2V0dGluZ1RhYih0aGlzLmFwcCwgdGhpcykpO1xuICB9XG4gIFxuICBvbnVubG9hZCgpIHtcbiAgICAgIC8vIERpc2Nvbm5lY3QgYW55IGFjdGl2ZSBvYnNlcnZlcnMgdG8gcHJldmVudCBtZW1vcnkgbGVha3NcbiAgICAgIHRoaXMuZGlzY29ubmVjdE9ic2VydmVycygpO1xuICAgICAgdGhpcy5sb2coJ1BsdWdpbiB1bmxvYWRlZCcpO1xuICB9XG4gIFxuICBhc3luYyBsb2FkU2V0dGluZ3MoKSB7XG4gICAgICB0aGlzLnNldHRpbmdzID0gT2JqZWN0LmFzc2lnbih7fSwgREVGQVVMVF9TRVRUSU5HUywgYXdhaXQgdGhpcy5sb2FkRGF0YSgpKTtcbiAgfVxuICBcbiAgYXN5bmMgc2F2ZVNldHRpbmdzKCkge1xuICAgICAgYXdhaXQgdGhpcy5zYXZlRGF0YSh0aGlzLnNldHRpbmdzKTtcbiAgfVxuICBcbiAgLy8gTG9nIGhlbHBlciB3aXRoIGRlYnVnIG1vZGUgY2hlY2tcbiAgbG9nKG1lc3NhZ2U6IHN0cmluZykge1xuICAgICAgaWYgKHRoaXMuc2V0dGluZ3MuZGVidWdNb2RlKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coYFtLU1VdICR7bWVzc2FnZX1gKTtcbiAgICAgICAgICBcbiAgICAgICAgICAvLyBVcGRhdGUgc3RhdHVzIGJhclxuICAgICAgICAgIHRoaXMuc3RhdHVzQmFySXRlbS5zZXRUZXh0KGBLU1U6ICR7bWVzc2FnZS5zdWJzdHJpbmcoMCwgMjUpfSR7bWVzc2FnZS5sZW5ndGggPiAyNSA/ICcuLi4nIDogJyd9YCk7XG4gICAgICAgICAgXG4gICAgICAgICAgLy8gUmVzZXQgc3RhdHVzIGJhciBhZnRlciAzIHNlY29uZHMgaWYgbm8gb3RoZXIgbG9ncyBoYXBwZW5cbiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKHRoaXMuYWN0aXZlS2FuYmFuQm9hcmQpIHtcbiAgICAgICAgICAgICAgICAgIHRoaXMuc3RhdHVzQmFySXRlbS5zZXRUZXh0KCdLU1U6IEFjdGl2ZScpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0dXNCYXJJdGVtLnNldFRleHQoJ0tTVTogSWRsZScpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgfSwgMzAwMCk7XG4gICAgICB9XG4gIH1cbiAgXG4gIC8vIENsZWFuIHVwIG9ic2VydmVycyB3aGVuIHN3aXRjaGluZyBhd2F5IGZyb20gYSBLYW5iYW4gYm9hcmRcbiAgZGlzY29ubmVjdE9ic2VydmVycygpIHtcbiAgICAgIGlmICh0aGlzLmN1cnJlbnRPYnNlcnZlcikge1xuICAgICAgICAgIHRoaXMubG9nKCdEaXNjb25uZWN0aW5nIG9ic2VydmVyIGZvciBwZXJmb3JtYW5jZScpO1xuICAgICAgICAgIHRoaXMuY3VycmVudE9ic2VydmVyLmRpc2Nvbm5lY3QoKTtcbiAgICAgICAgICB0aGlzLmN1cnJlbnRPYnNlcnZlciA9IG51bGw7XG4gICAgICB9XG4gICAgICB0aGlzLmFjdGl2ZUthbmJhbkJvYXJkID0gbnVsbDtcbiAgfVxuICBcbiAgLy8gQ2hlY2sgaWYgdGhlIGFjdGl2ZSBsZWFmIGlzIGEgS2FuYmFuIGJvYXJkXG4gIG9uQWN0aXZlTGVhZkNoYW5nZShsZWFmOiBXb3Jrc3BhY2VMZWFmKSB7XG4gICAgICB0aGlzLmNoZWNrRm9yQWN0aXZlS2FuYmFuQm9hcmQoKTtcbiAgfVxuICBcbiAgY2hlY2tGb3JBY3RpdmVLYW5iYW5Cb2FyZCgpIHtcbiAgICAvLyBGaXJzdCBkaXNjb25uZWN0IGFueSBleGlzdGluZyBvYnNlcnZlcnNcbiAgICB0aGlzLmRpc2Nvbm5lY3RPYnNlcnZlcnMoKTtcbiAgICBcbiAgICAvLyBHZXQgdGhlIGFjdGl2ZSBsZWFmXG4gICAgY29uc3QgYWN0aXZlTGVhZiA9IHRoaXMuYXBwLndvcmtzcGFjZS5hY3RpdmVMZWFmO1xuICAgIGlmICghYWN0aXZlTGVhZikgcmV0dXJuO1xuICAgIFxuICAgIHRyeSB7XG4gICAgICAgIC8vIEZpbmQgdGhlIGNvbnRlbnQgZWxlbWVudCBzYWZlbHlcbiAgICAgICAgbGV0IGNvbnRlbnRFbDogSFRNTEVsZW1lbnQgfCBudWxsID0gbnVsbDtcbiAgICAgICAgXG4gICAgICAgIC8vIFVzZSB0eXBlIGFzc2VydGlvbnMgdG8gYXZvaWQgVHlwZVNjcmlwdCBlcnJvcnNcbiAgICAgICAgaWYgKGFjdGl2ZUxlYWYudmlldykge1xuICAgICAgICAgICAgLy8gVHJ5IHRvIGFjY2VzcyB0aGUgY29udGVudEVsIHByb3BlcnR5IHVzaW5nIHR5cGUgYXNzZXJ0aW9uXG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlIC0gY29udGVudEVsIGV4aXN0cyBidXQgbWlnaHQgbm90IGJlIGluIHR5cGUgZGVmaW5pdGlvbnNcbiAgICAgICAgICAgIGNvbnRlbnRFbCA9IGFjdGl2ZUxlYWYudmlldy5jb250ZW50RWw7XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIC8vIElmIHRoYXQgZGlkbid0IHdvcmssIHRyeSBhbm90aGVyIGFwcHJvYWNoXG4gICAgICAgIGlmICghY29udGVudEVsKSB7XG4gICAgICAgICAgICAvLyBUcnkgdG8gZ2V0IHRoZSBLYW5iYW4gYm9hcmQgZGlyZWN0bHkgZnJvbSB0aGUgRE9NXG4gICAgICAgICAgICAvLyBMZWFmIGNvbnRhaW5lcnMgaGF2ZSAndmlldy1jb250ZW50JyBlbGVtZW50cyB0aGF0IGNvbnRhaW4gdGhlIGFjdHVhbCB2aWV3XG4gICAgICAgICAgICBjb25zdCB2aWV3Q29udGVudCA9IChhY3RpdmVMZWFmIGFzIGFueSkuY29udGFpbmVyRWw/LnF1ZXJ5U2VsZWN0b3IoJy52aWV3LWNvbnRlbnQnKTtcbiAgICAgICAgICAgIGlmICh2aWV3Q29udGVudCkge1xuICAgICAgICAgICAgICAgIGNvbnRlbnRFbCA9IHZpZXdDb250ZW50O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBMYXN0IHJlc29ydCAtIGxvb2sgZm9yIEthbmJhbiBib2FyZHMgYW55d2hlcmUgaW4gdGhlIHdvcmtzcGFjZVxuICAgICAgICAgICAgICAgIGNvbnRlbnRFbCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy53b3Jrc3BhY2UtbGVhZi5tb2QtYWN0aXZlIC52aWV3LWNvbnRlbnQnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgaWYgKCFjb250ZW50RWwpIHtcbiAgICAgICAgICAgIHRoaXMubG9nKCdDb3VsZCBub3QgYWNjZXNzIGNvbnRlbnQgZWxlbWVudCBmb3IgYWN0aXZlIGxlYWYnKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBhIEthbmJhbiBib2FyZFxuICAgICAgICBjb25zdCBrYW5iYW5Cb2FyZCA9IGNvbnRlbnRFbC5xdWVyeVNlbGVjdG9yKCcua2FuYmFuLXBsdWdpbl9fYm9hcmQnKTtcbiAgICAgICAgaWYgKGthbmJhbkJvYXJkKSB7XG4gICAgICAgICAgICB0aGlzLmxvZygnRm91bmQgYWN0aXZlIEthbmJhbiBib2FyZCwgc2V0dGluZyB1cCBvYnNlcnZlcicpO1xuICAgICAgICAgICAgdGhpcy5zdGF0dXNCYXJJdGVtLnNldFRleHQoJ0tTVTogQWN0aXZlJyk7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIC8vIFN0b3JlIHJlZmVyZW5jZSB0byBhY3RpdmUgYm9hcmRcbiAgICAgICAgICAgIHRoaXMuYWN0aXZlS2FuYmFuQm9hcmQgPSBrYW5iYW5Cb2FyZCBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgLy8gU2V0IHVwIG9ic2VydmVyIG9ubHkgZm9yIHRoaXMgYm9hcmRcbiAgICAgICAgICAgIHRoaXMuc2V0dXBPYnNlcnZlckZvckJvYXJkKGthbmJhbkJvYXJkIGFzIEhUTUxFbGVtZW50KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMubG9nKCdBY3RpdmUgbGVhZiBpcyBub3QgYSBLYW5iYW4gYm9hcmQnKTtcbiAgICAgICAgICAgIHRoaXMuc3RhdHVzQmFySXRlbS5zZXRUZXh0KCdLU1U6IElkbGUnKTtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHRoaXMubG9nKGBFcnJvciBkZXRlY3RpbmcgS2FuYmFuIGJvYXJkOiAke2Vycm9yLm1lc3NhZ2V9YCk7XG4gICAgICAgIHRoaXMuc3RhdHVzQmFySXRlbS5zZXRUZXh0KCdLU1U6IEVycm9yJyk7XG4gICAgfVxuICB9XG4gIFxuICBzZXR1cE9ic2VydmVyRm9yQm9hcmQoYm9hcmRFbGVtZW50OiBIVE1MRWxlbWVudCkge1xuICAgICAgLy8gQ3JlYXRlIGEgbmV3IG9ic2VydmVyIGZvciB0aGlzIHNwZWNpZmljIGJvYXJkXG4gICAgICB0aGlzLmN1cnJlbnRPYnNlcnZlciA9IG5ldyBNdXRhdGlvbk9ic2VydmVyKChtdXRhdGlvbnMpID0+IHtcbiAgICAgICAgICBpZiAodGhpcy5pc1Byb2Nlc3NpbmcpIHJldHVybjtcbiAgICAgICAgICBcbiAgICAgICAgICAvLyBTaW1wbGUgZGVib3VuY2UgdG8gcHJldmVudCByYXBpZC1maXJlIHByb2Nlc3NpbmdcbiAgICAgICAgICB0aGlzLmlzUHJvY2Vzc2luZyA9IHRydWU7XG4gICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMuaGFuZGxlTXV0YXRpb25zKG11dGF0aW9ucyk7XG4gICAgICAgICAgICAgIHRoaXMuaXNQcm9jZXNzaW5nID0gZmFsc2U7XG4gICAgICAgICAgfSwgMzAwKTtcbiAgICAgIH0pO1xuICAgICAgXG4gICAgICAvLyBPYnNlcnZlIG9ubHkgdGhpcyBib2FyZCB3aXRoIG1pbmltYWwgb3B0aW9ucyBuZWVkZWRcbiAgICAgIHRoaXMuY3VycmVudE9ic2VydmVyLm9ic2VydmUoYm9hcmRFbGVtZW50LCB7XG4gICAgICAgICAgY2hpbGRMaXN0OiB0cnVlLFxuICAgICAgICAgIHN1YnRyZWU6IHRydWUsXG4gICAgICAgICAgYXR0cmlidXRlczogZmFsc2UgLy8gRG9uJ3QgbmVlZCBhdHRyaWJ1dGUgY2hhbmdlcyBmb3IgcGVyZm9ybWFuY2VcbiAgICAgIH0pO1xuICAgICAgXG4gICAgICB0aGlzLmxvZygnT2JzZXJ2ZXIgc2V0IHVwIGZvciBhY3RpdmUgS2FuYmFuIGJvYXJkJyk7XG4gIH1cbiAgXG4gIGhhbmRsZU11dGF0aW9ucyhtdXRhdGlvbnM6IE11dGF0aW9uUmVjb3JkW10pIHtcbiAgICBpZiAoIXRoaXMuYWN0aXZlS2FuYmFuQm9hcmQpIHJldHVybjtcbiAgICBcbiAgICB0cnkge1xuICAgICAgICBjb25zdCBtYXhfbXV0YXRpb25zID0gMTA7XG4gICAgICAgIC8vIE9ubHkgcHJvY2VzcyBhIHNhbXBsZSBvZiBtdXRhdGlvbnMgZm9yIHBlcmZvcm1hbmNlXG4gICAgICAgIGNvbnN0IG11dGF0aW9uc1RvUHJvY2VzcyA9IG11dGF0aW9ucy5sZW5ndGggPiBtYXhfbXV0YXRpb25zID8gXG4gICAgICAgICAgICBtdXRhdGlvbnMuc2xpY2UoMCwgbWF4X211dGF0aW9ucykgOiBtdXRhdGlvbnM7XG4gICAgICAgICAgICBcbiAgICAgICAgdGhpcy5sb2coYEdvdCAke211dGF0aW9uc1RvUHJvY2Vzcy5sZW5ndGh9IG11dGF0aW9ucyBvZiAke211dGF0aW9ucy5sZW5ndGh9YCk7XG4gICAgICAgIFxuICAgICAgICAvLyBMb29rIGZvciBLYW5iYW4gaXRlbXMgaW4gbXV0YXRpb25cbiAgICAgICAgbGV0IGkgPSAwO1xuICAgICAgICBmb3IgKGNvbnN0IG11dGF0aW9uIG9mIG11dGF0aW9uc1RvUHJvY2Vzcykge1xuICAgICAgICAgICAgdGhpcy5sb2coYE11dGF0aW9uICMkeysraX0gLSBUeXBlOiAke211dGF0aW9uLnR5cGV9YCk7XG4gICAgICAgICAgICBpZiAobXV0YXRpb24udHlwZSA9PT0gJ2NoaWxkTGlzdCcpIHtcbiAgICAgICAgICAgICAgICAvLyBDaGVjayBhZGRlZCBub2RlcyBmb3IgS2FuYmFuIGl0ZW1zXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBub2RlIG9mIEFycmF5LmZyb20obXV0YXRpb24uYWRkZWROb2RlcykpIHtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIG5vZGUgaXMgYW55IGtpbmQgb2YgRWxlbWVudCAoSFRNTCBvciBTVkcpXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobm9kZSBpbnN0YW5jZW9mIEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZyhgUHJvY2Vzc2luZyBFbGVtZW50IG9mIHR5cGU6ICR7bm9kZS50YWdOYW1lfWApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEhhbmRsZSB0aGUgbm9kZSBhY2NvcmRpbmcgdG8gaXRzIHR5cGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobm9kZSBpbnN0YW5jZW9mIEhUTUxFbGVtZW50IHx8IG5vZGUgaW5zdGFuY2VvZiBIVE1MRGl2RWxlbWVudCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBEaXJlY3QgcHJvY2Vzc2luZyBmb3IgSFRNTCBlbGVtZW50c1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZyhgRm91bmQgSFRNTCBlbGVtZW50IG9mIHR5cGUgJHtub2RlLmNsYXNzTmFtZX1gKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzRWxlbWVudChub2RlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5vZGUgaW5zdGFuY2VvZiBTVkdFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZvciBTVkcgZWxlbWVudHMsIGxvb2sgZm9yIHBhcmVudCBIVE1MIGVsZW1lbnRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcGFyZW50RWxlbWVudCA9IG5vZGUuY2xvc2VzdCgnLmthbmJhbi1wbHVnaW5fX2l0ZW0nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmVudEVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nKCdGb3VuZCBLYW5iYW4gaXRlbSBwYXJlbnQgb2YgU1ZHIGVsZW1lbnQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJvY2Vzc0VsZW1lbnQocGFyZW50RWxlbWVudCBhcyBIVE1MRWxlbWVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBMb29rIGZvciBhbnkga2FuYmFuIGl0ZW1zIGluIHRoZSBkb2N1bWVudCB0aGF0IG1pZ2h0IGhhdmUgY2hhbmdlZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyBpcyBmb3IgY2FzZXMgd2hlcmUgdGhlIFNWRyB1cGRhdGUgaXMgcmVsYXRlZCB0byBhIGNhcmQgbW92ZW1lbnRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGl0ZW1zID0gdGhpcy5hY3RpdmVLYW5iYW5Cb2FyZC5xdWVyeVNlbGVjdG9yQWxsKCcua2FuYmFuLXBsdWdpbl9faXRlbScpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZW1zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQcm9jZXNzIG9ubHkgdGhlIG1vc3QgcmVjZW50bHkgbW9kaWZpZWQgaXRlbVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlY2VudEl0ZW1zID0gQXJyYXkuZnJvbShpdGVtcykuc2xpY2UoLTEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiByZWNlbnRJdGVtcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZygnUHJvY2Vzc2luZyByZWNlbnQgaXRlbSBhZnRlciBTVkcgY2hhbmdlJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJvY2Vzc0VsZW1lbnQoaXRlbSBhcyBIVE1MRWxlbWVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChub2RlLm5vZGVUeXBlID09PSBOb2RlLlRFWFRfTk9ERSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZvciB0ZXh0IG5vZGVzLCBjaGVjayB0aGUgcGFyZW50IGVsZW1lbnRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXJlbnRFbGVtZW50ID0gbm9kZS5wYXJlbnRFbGVtZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJlbnRFbGVtZW50ICYmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50RWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoJ2thbmJhbi1wbHVnaW5fX2l0ZW0tdGl0bGUnKSB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnRFbGVtZW50LmNsb3Nlc3QoJy5rYW5iYW4tcGx1Z2luX19pdGVtJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nKCdGb3VuZCB0ZXh0IGNoYW5nZSBpbiBLYW5iYW4gaXRlbScpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpdGVtRWxlbWVudCA9IHBhcmVudEVsZW1lbnQuY2xvc2VzdCgnLmthbmJhbi1wbHVnaW5fX2l0ZW0nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGl0ZW1FbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnByb2Nlc3NFbGVtZW50KGl0ZW1FbGVtZW50IGFzIEhUTUxFbGVtZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2coYFNraXBwaW5nIG5vZGUgdHlwZTogJHtub2RlLm5vZGVUeXBlfWApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChub2RlRXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nKGBFcnJvciBwcm9jZXNzaW5nIG5vZGU6ICR7bm9kZUVycm9yLm1lc3NhZ2V9YCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBDb250aW51ZSB3aXRoIG5leHQgbm9kZSBldmVuIGlmIHRoaXMgb25lIGZhaWxzXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMubG9nKCdJZ25vcmluZyBtdXRhdGlvbiB0eXBlOiAnICsgbXV0YXRpb24udHlwZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICB0aGlzLmxvZyhgRXJyb3IgaW4gaGFuZGxlTXV0YXRpb25zOiAke2Vycm9yLm1lc3NhZ2V9YCk7XG4gICAgfVxuICB9XG4gIFxuICBvbkRyYWdFbmQoZXZlbnQ6IERyYWdFdmVudCkge1xuICAgICAgLy8gT25seSBwcm9jZXNzIGlmIHdlIGhhdmUgYW4gYWN0aXZlIEthbmJhbiBib2FyZFxuICAgICAgaWYgKCF0aGlzLmFjdGl2ZUthbmJhbkJvYXJkIHx8IHRoaXMuaXNQcm9jZXNzaW5nKSB7XG4gICAgICAgIHRoaXMubG9nKCdEcmFnIGVuZCBkZXRlY3RlZCBidXQgbm8gYWN0aXZlIEthbmJhbiBib2FyZCBvciBhbHJlYWR5IHByb2Nlc3NpbmcnKTtcbiAgICAgICAgdGhpcy5sb2coJ2FjdGl2ZUthbmJhbkJvYXJkOiAnICsgKHRoaXMuYWN0aXZlS2FuYmFuQm9hcmQgPyAnWWVzJyA6ICdObycpKTtcbiAgICAgICAgdGhpcy5sb2coJ2lzUHJvY2Vzc2luZzogJyArICh0aGlzLmlzUHJvY2Vzc2luZyA/ICdZZXMnIDogJ05vJykpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBcbiAgICAgIHRyeSB7XG4gICAgICAgICAgdGhpcy5sb2coJ0RyYWcgZW5kIGRldGVjdGVkJyk7XG4gICAgICAgICAgXG4gICAgICAgICAgLy8gU2V0IHByb2Nlc3NpbmcgZmxhZyB0byBwcmV2ZW50IG11bHRpcGxlIHByb2Nlc3NpbmdcbiAgICAgICAgICB0aGlzLmlzUHJvY2Vzc2luZyA9IHRydWU7XG4gICAgICAgICAgXG4gICAgICAgICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50O1xuICAgICAgICAgIGlmICghdGFyZ2V0KSByZXR1cm47XG4gICAgICAgICAgXG4gICAgICAgICAgdGhpcy5wcm9jZXNzRWxlbWVudCh0YXJnZXQpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICB0aGlzLmxvZyhgRXJyb3IgaW4gb25EcmFnRW5kOiAke2Vycm9yLm1lc3NhZ2V9YCk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIC8vIFJlc2V0IHByb2Nlc3NpbmcgZmxhZyBhZnRlciBhIGRlbGF5IHRvIGRlYm91bmNlXG4gICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMuaXNQcm9jZXNzaW5nID0gZmFsc2U7XG4gICAgICAgICAgfSwgMzAwKTtcbiAgICAgIH1cbiAgfVxuICBcbiAgcHJvY2Vzc0VsZW1lbnQoZWxlbWVudDogSFRNTEVsZW1lbnQpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgICAgLy8gT25seSBwcm9jZXNzIGlmIGluc2lkZSBvdXIgYWN0aXZlIEthbmJhbiBib2FyZFxuICAgICAgICAgIGlmICghdGhpcy5hY3RpdmVLYW5iYW5Cb2FyZCB8fCAhZWxlbWVudC5jbG9zZXN0KCcua2FuYmFuLXBsdWdpbl9fYm9hcmQnKSkge1xuICAgICAgICAgICAgICB0aGlzLmxvZygnRWxlbWVudCBOT1QgaW4gYWN0aXZlIEthbmJhbiBib2FyZC4gU2tpcHBpbmcuJyk7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgXG4gICAgICAgICAgLy8gVXNlIGRpZmZlcmVudCBzdHJhdGVnaWVzIHRvIGZpbmQgdGhlIEthbmJhbiBpdGVtXG4gICAgICAgICAgdGhpcy5sb2coXCLwn5GAIExvb2tpbmcgZm9yIEthbmJhbiBpdGVtIGVsZW1lbnRcIik7XG4gICAgICAgICAgXG4gICAgICAgICAgLy8gQ2hlY2sgaWYgZWxlbWVudCBpcyBhIEthbmJhbiBpdGVtIG9yIGNvbnRhaW5zIG9uZVxuICAgICAgICAgIGNvbnN0IGthbmJhbkl0ZW0gPSBlbGVtZW50LmNsYXNzTGlzdC5jb250YWlucygna2FuYmFuLXBsdWdpbl9faXRlbScpIFxuICAgICAgICAgICAgICA/IGVsZW1lbnRcbiAgICAgICAgICAgICAgOiBlbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy5rYW5iYW4tcGx1Z2luX19pdGVtJyk7XG4gICAgICAgICAgICAgIFxuICAgICAgICAgIGlmIChrYW5iYW5JdGVtKSB7XG4gICAgICAgICAgICAgIHRoaXMubG9nKGDinIUgRm91bmQgS2FuYmFuIGl0ZW06ICR7a2FuYmFuSXRlbX1gKTtcbiAgICAgICAgICAgICAgdGhpcy5sb2coJ2NsYXNzTGlzdCBvZiBrYW5iYW5JdGVtOiAnICsga2FuYmFuSXRlbS5jbGFzc0xpc3QpO1xuICAgICAgICAgICAgICB0aGlzLnByb2Nlc3NLYW5iYW5JdGVtKGthbmJhbkl0ZW0gYXMgSFRNTEVsZW1lbnQpO1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMubG9nKCdOb3QgYSBLYW5iYW4gaXRlbSwgY2hlY2tpbmcgZm9yIHBhcmVudCcpO1xuICAgICAgICAgIFxuICAgICAgICAgIC8vIElmIGVsZW1lbnQgaXMgaW5zaWRlIGEgS2FuYmFuIGl0ZW0sIGZpbmQgdGhlIHBhcmVudFxuICAgICAgICAgIGNvbnN0IHBhcmVudEl0ZW0gPSBlbGVtZW50LmNsb3Nlc3QoJy5rYW5iYW4tcGx1Z2luX19pdGVtJykgYXMgSFRNTEVsZW1lbnQ7XG4gICAgICAgICAgdGhpcy5sb2coYFBhcmVudCBpdGVtOiAke3BhcmVudEl0ZW0gPyBwYXJlbnRJdGVtIDogJ05vdCBmb3VuZCd9YCk7XG4gICAgICAgICAgaWYgKHBhcmVudEl0ZW0pIHtcbiAgICAgICAgICAgICAgdGhpcy5wcm9jZXNzS2FuYmFuSXRlbShwYXJlbnRJdGVtKTtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgdGhpcy5sb2coYEVycm9yIGluIHByb2Nlc3NFbGVtZW50OiAke2Vycm9yLm1lc3NhZ2V9YCk7XG4gICAgICB9XG4gIH1cbiAgXG4gIHByb2Nlc3NLYW5iYW5JdGVtKGl0ZW1FbGVtZW50OiBIVE1MRWxlbWVudCkgeyAvLyBpdGVtRWxlbWVudCB3aWxsIGJlIG9mIGNsYXNzIGBrYW5iYW4tcGx1Z2luX19pdGVtYFxuICAgICAgdHJ5IHtcblxuICAgICAgICAgIC8vIFRPRE86IFNlbGVjdCB0aGUgdGl0bGVcbiAgICAgICAgICBjb25zdCBpbnRlcm5hbExpbmsgPSBpdGVtRWxlbWVudC5xdWVyeVNlbGVjdG9yKCcua2FuYmFuLXBsdWdpbl9faXRlbS10aXRsZSAua2FuYmFuLXBsdWdpbl9faXRlbS1tYXJrZG93biBhLmludGVybmFsLWxpbmsnKTtcbiAgICAgICAgICBcbiAgICAgICAgICBpZiAoIWludGVybmFsTGluaykge1xuICAgICAgICAgICAgdGhpcy5sb2coJ/CfmqsgTm8gaW50ZXJuYWwgbGluayBmb3VuZCBpbiBpdGVtJyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMubG9nKGBGb3VuZCBpbnRlcm5hbCBsaW5rOiAke2ludGVybmFsTGluay50ZXh0Q29udGVudH1gKTtcbiAgICAgICAgICBcbiAgICAgICAgICAvLyBHZXQgdGhlIGxpbmsgcGF0aCBmcm9tIGRhdGEtaHJlZiBvciBocmVmIGF0dHJpYnV0ZVxuICAgICAgICAgIGNvbnN0IGxpbmtQYXRoID0gaW50ZXJuYWxMaW5rLmdldEF0dHJpYnV0ZSgnZGF0YS1ocmVmJykgfHwgXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGludGVybmFsTGluay5nZXRBdHRyaWJ1dGUoJ2hyZWYnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgaWYgKCFsaW5rUGF0aCkgcmV0dXJuO1xuICAgICAgICAgIHRoaXMubG9nKGDwn5SXIExpbmsgcGF0aDogJHtsaW5rUGF0aH1gKTtcblxuICAgICAgICAgIC8vIEZpbmQgdGhlIGxhbmUgKGNvbHVtbikgdGhpcyBpdGVtIGlzIGluXG4gICAgICAgICAgY29uc3QgbGFuZSA9IGl0ZW1FbGVtZW50LmNsb3Nlc3QoJy5rYW5iYW4tcGx1Z2luX19sYW5lJyk7XG4gICAgICAgICAgaWYgKCFsYW5lKSB7IFxuICAgICAgICAgICAgdGhpcy5sb2coJ/CfmqsgTm8gbGFuZSBmb3VuZCBmb3IgaXRlbScpO1xuICAgICAgICAgICAgcmV0dXJuOyBcbiAgICAgICAgICB9XG4gICAgICAgICAgXG4gICAgICAgICAgLy8gR2V0IGNvbHVtbiBuYW1lIGZyb20gdGhlIGxhbmUgaGVhZGVyXG4gICAgICAgICAgY29uc3QgbGFuZUhlYWRlciA9IGxhbmUucXVlcnlTZWxlY3RvcignLmthbmJhbi1wbHVnaW5fX2xhbmUtaGVhZGVyLXdyYXBwZXIgLmthbmJhbi1wbHVnaW5fX2xhbmUtdGl0bGUnKTtcbiAgICAgICAgICBpZiAoIWxhbmVIZWFkZXIpIHsgXG4gICAgICAgICAgICB0aGlzLmxvZygn8J+aqyBObyBsYW5lSGVhZGVyIGZvdW5kIGZvciBpdGVtJyk7XG4gICAgICAgICAgICByZXR1cm47IFxuICAgICAgICAgIH1cbiAgICAgICAgICBcbiAgICAgICAgICBjb25zdCBjb2x1bW5OYW1lID0gbGFuZUhlYWRlci50ZXh0Q29udGVudC50cmltKCk7XG4gICAgICAgICAgdGhpcy5sb2coYOKchSBHb3QgbGFuZSBuYW1lOiAke2NvbHVtbk5hbWV9YCk7XG4gICAgICAgICAgXG4gICAgICAgICAgdGhpcy5sb2coYFByb2Nlc3NpbmcgY2FyZCB3aXRoIGxpbmsgdG8gXCIke2xpbmtQYXRofVwiIGluIGNvbHVtbiBcIiR7Y29sdW1uTmFtZX1cImApO1xuICAgICAgICAgIFxuICAgICAgICAgIC8vIFVwZGF0ZSB0aGUgbGlua2VkIG5vdGUncyBzdGF0dXNcbiAgICAgICAgICB0aGlzLnVwZGF0ZU5vdGVTdGF0dXMobGlua1BhdGgsIGNvbHVtbk5hbWUpO1xuICAgICAgICAgIFxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICB0aGlzLmxvZyhgRXJyb3IgaW4gcHJvY2Vzc0thbmJhbkl0ZW06ICR7ZXJyb3IubWVzc2FnZX1gKTtcbiAgICAgIH1cbiAgfVxuICBcbiAgYXN5bmMgdXBkYXRlTm90ZVN0YXR1cyhub3RlUGF0aDogc3RyaW5nLCBzdGF0dXM6IHN0cmluZykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyBGaW5kIHRoZSBsaW5rZWQgZmlsZVxuICAgICAgICAgIGNvbnN0IGZpbGUgPSB0aGlzLmFwcC5tZXRhZGF0YUNhY2hlLmdldEZpcnN0TGlua3BhdGhEZXN0KG5vdGVQYXRoLCAnJyk7XG4gICAgICAgICAgXG4gICAgICAgICAgaWYgKCFmaWxlKSB7XG4gICAgICAgICAgICAgIGlmICh0aGlzLnNldHRpbmdzLnNob3dOb3RpZmljYXRpb25zKSB7XG4gICAgICAgICAgICAgICAgICBuZXcgTm90aWNlKGDimqDvuI8gTm90ZSBcIiR7bm90ZVBhdGh9XCIgbm90IGZvdW5kYCwgMzAwMCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICBcbiAgICAgICAgICAvLyBSZWFkIHRoZSBmaWxlIGNvbnRlbnRcbiAgICAgICAgICBjb25zdCBjb250ZW50ID0gYXdhaXQgdGhpcy5hcHAudmF1bHQucmVhZChmaWxlKTtcbiAgICAgICAgICBcbiAgICAgICAgICAvLyBDaGVjayBmb3IgZXhpc3RpbmcgZnJvbnRtYXR0ZXJcbiAgICAgICAgICBjb25zdCBmcm9udG1hdHRlclJlZ2V4ID0gL14tLS1cXG4oW1xcc1xcU10qPylcXG4tLS0vO1xuICAgICAgICAgIGNvbnN0IGZyb250bWF0dGVyTWF0Y2ggPSBjb250ZW50Lm1hdGNoKGZyb250bWF0dGVyUmVnZXgpO1xuICAgICAgICAgIFxuICAgICAgICAgIGxldCBuZXdDb250ZW50O1xuICAgICAgICAgIGxldCBvbGRTdGF0dXMgPSBudWxsO1xuICAgICAgICAgIFxuICAgICAgICAgIGlmIChmcm9udG1hdHRlck1hdGNoKSB7XG4gICAgICAgICAgICAgIC8vIEZpbGUgaGFzIGZyb250bWF0dGVyXG4gICAgICAgICAgICAgIGNvbnN0IGZyb250bWF0dGVyVGV4dCA9IGZyb250bWF0dGVyTWF0Y2hbMV07XG4gICAgICAgICAgICAgIGxldCBmcm9udG1hdHRlck9iajtcbiAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAvLyBUcnkgdG8gcGFyc2UgdGhlIGZyb250bWF0dGVyXG4gICAgICAgICAgICAgICAgICBmcm9udG1hdHRlck9iaiA9IHBhcnNlWWFtbChmcm9udG1hdHRlclRleHQpO1xuICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiBzdGF0dXMgcHJvcGVydHkgYWxyZWFkeSBleGlzdHNcbiAgICAgICAgICAgICAgICAgIGlmIChmcm9udG1hdHRlck9ialt0aGlzLnNldHRpbmdzLnN0YXR1c1Byb3BlcnR5TmFtZV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICBvbGRTdGF0dXMgPSBmcm9udG1hdHRlck9ialt0aGlzLnNldHRpbmdzLnN0YXR1c1Byb3BlcnR5TmFtZV07XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgdGhpcy5sb2coYEVycm9yIHBhcnNpbmcgZnJvbnRtYXR0ZXI6ICR7ZS5tZXNzYWdlfWApO1xuICAgICAgICAgICAgICAgICAgZnJvbnRtYXR0ZXJPYmogPSB7fTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgLy8gT25seSB1cGRhdGUgaWYgc3RhdHVzIGhhcyBjaGFuZ2VkXG4gICAgICAgICAgICAgIGlmIChmcm9udG1hdHRlck9ialt0aGlzLnNldHRpbmdzLnN0YXR1c1Byb3BlcnR5TmFtZV0gIT09IHN0YXR1cykge1xuICAgICAgICAgICAgICAgICAgLy8gVXBkYXRlIHRoZSBzdGF0dXMgcHJvcGVydHlcbiAgICAgICAgICAgICAgICAgIGZyb250bWF0dGVyT2JqW3RoaXMuc2V0dGluZ3Muc3RhdHVzUHJvcGVydHlOYW1lXSA9IHN0YXR1cztcbiAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgLy8gR2VuZXJhdGUgbmV3IGZyb250bWF0dGVyIHRleHRcbiAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld0Zyb250bWF0dGVyVGV4dCA9IHN0cmluZ2lmeVlhbWwoZnJvbnRtYXR0ZXJPYmopO1xuICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAvLyBSZXBsYWNlIHRoZSBmcm9udG1hdHRlciBpbiB0aGUgY29udGVudFxuICAgICAgICAgICAgICAgICAgbmV3Q29udGVudCA9IGNvbnRlbnQucmVwbGFjZShmcm9udG1hdHRlclJlZ2V4LCBgLS0tXFxuJHtuZXdGcm9udG1hdHRlclRleHR9LS0tYCk7XG4gICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgIC8vIFNhdmUgdGhlIG1vZGlmaWVkIGNvbnRlbnRcbiAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuYXBwLnZhdWx0Lm1vZGlmeShmaWxlLCBuZXdDb250ZW50KTtcbiAgICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgLy8gU2hvdyBub3RpZmljYXRpb24gaWYgZW5hYmxlZFxuICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuc2V0dGluZ3Muc2hvd05vdGlmaWNhdGlvbnMpIHtcbiAgICAgICAgICAgICAgICAgICAgICBpZiAob2xkU3RhdHVzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBOb3RpY2UoYFVwZGF0ZWQgJHt0aGlzLnNldHRpbmdzLnN0YXR1c1Byb3BlcnR5TmFtZX06IFwiJHtvbGRTdGF0dXN9XCIg4oaSIFwiJHtzdGF0dXN9XCIgZm9yICR7ZmlsZS5iYXNlbmFtZX1gLCAzMDAwKTtcbiAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgTm90aWNlKGBTZXQgJHt0aGlzLnNldHRpbmdzLnN0YXR1c1Byb3BlcnR5TmFtZX06IFwiJHtzdGF0dXN9XCIgZm9yICR7ZmlsZS5iYXNlbmFtZX1gLCAzMDAwKTtcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgIHRoaXMubG9nKGBVcGRhdGVkIHN0YXR1cyBmb3IgJHtmaWxlLmJhc2VuYW1lfSB0byBcIiR7c3RhdHVzfVwiYCk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICB0aGlzLmxvZyhgU3RhdHVzIGFscmVhZHkgc2V0IHRvIFwiJHtzdGF0dXN9XCIgZm9yICR7ZmlsZS5iYXNlbmFtZX0sIHNraXBwaW5nIHVwZGF0ZWApO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgLy8gRmlsZSBoYXMgbm8gZnJvbnRtYXR0ZXIsIGNyZWF0ZSBpdFxuICAgICAgICAgICAgICBjb25zdCBmcm9udG1hdHRlck9iaiA9IHtcbiAgICAgICAgICAgICAgICAgIFt0aGlzLnNldHRpbmdzLnN0YXR1c1Byb3BlcnR5TmFtZV06IHN0YXR1c1xuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgY29uc3QgZnJvbnRtYXR0ZXJUZXh0ID0gc3RyaW5naWZ5WWFtbChmcm9udG1hdHRlck9iaik7XG4gICAgICAgICAgICAgIG5ld0NvbnRlbnQgPSBgLS0tXFxuJHtmcm9udG1hdHRlclRleHR9LS0tXFxuXFxuJHtjb250ZW50fWA7XG4gICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAvLyBTYXZlIHRoZSBtb2RpZmllZCBjb250ZW50XG4gICAgICAgICAgICAgIGF3YWl0IHRoaXMuYXBwLnZhdWx0Lm1vZGlmeShmaWxlLCBuZXdDb250ZW50KTtcbiAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgIC8vIFNob3cgbm90aWZpY2F0aW9uIGlmIGVuYWJsZWRcbiAgICAgICAgICAgICAgaWYgKHRoaXMuc2V0dGluZ3Muc2hvd05vdGlmaWNhdGlvbnMpIHtcbiAgICAgICAgICAgICAgICAgIG5ldyBOb3RpY2UoYEFkZGVkICR7dGhpcy5zZXR0aW5ncy5zdGF0dXNQcm9wZXJ0eU5hbWV9OiBcIiR7c3RhdHVzfVwiIHRvICR7ZmlsZS5iYXNlbmFtZX1gLCAzMDAwKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBcbiAgICAgICAgICAgICAgdGhpcy5sb2coYEFkZGVkIGZyb250bWF0dGVyIHdpdGggc3RhdHVzIHRvICR7ZmlsZS5iYXNlbmFtZX1gKTtcbiAgICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIHRoaXMubG9nKGBFcnJvciB1cGRhdGluZyBub3RlIHN0YXR1czogJHtlcnJvci5tZXNzYWdlfWApO1xuICAgICAgICAgIGlmICh0aGlzLnNldHRpbmdzLnNob3dOb3RpZmljYXRpb25zKSB7XG4gICAgICAgICAgICAgIG5ldyBOb3RpY2UoYOKaoO+4jyBFcnJvciB1cGRhdGluZyBzdGF0dXM6ICR7ZXJyb3IubWVzc2FnZX1gLCAzMDAwKTtcbiAgICAgICAgICB9XG4gICAgICB9XG4gIH1cbiAgXG4gIC8vIE1ldGhvZCBmb3IgdGhlIHRlc3QgYnV0dG9uIHRvIHVzZVxuICBydW5UZXN0KCkge1xuICAgICAgdGhpcy5sb2coJ1J1bm5pbmcgdGVzdC4uLicpO1xuICAgICAgXG4gICAgICAvLyBNYWtlIHN1cmUgd2UncmUgdXNpbmcgdGhlIGN1cnJlbnQgYWN0aXZlIGJvYXJkXG4gICAgICB0aGlzLmNoZWNrRm9yQWN0aXZlS2FuYmFuQm9hcmQoKTtcbiAgICAgIFxuICAgICAgaWYgKCF0aGlzLmFjdGl2ZUthbmJhbkJvYXJkKSB7XG4gICAgICAgICAgbmV3IE5vdGljZSgn4pqg77iPIE5vIGFjdGl2ZSBLYW5iYW4gYm9hcmQgZm91bmQgLSBvcGVuIGEgS2FuYmFuIGJvYXJkIGZpcnN0JywgNTAwMCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBGaW5kIGl0ZW1zIGluIHRoZSBhY3RpdmUgYm9hcmRcbiAgICAgIGNvbnN0IGl0ZW1zID0gdGhpcy5hY3RpdmVLYW5iYW5Cb2FyZC5xdWVyeVNlbGVjdG9yQWxsKCcua2FuYmFuLXBsdWdpbl9faXRlbScpO1xuICAgICAgY29uc3QgY291bnQgPSBpdGVtcy5sZW5ndGg7XG4gICAgICBcbiAgICAgIG5ldyBOb3RpY2UoYEZvdW5kICR7Y291bnR9IGNhcmRzIGluIGFjdGl2ZSBLYW5iYW4gYm9hcmRgLCAzMDAwKTtcbiAgICAgIFxuICAgICAgaWYgKGNvdW50ID4gMCkge1xuICAgICAgICAgIC8vIFByb2Nlc3MgdGhlIGZpcnN0IGl0ZW0gd2l0aCBhIGxpbmtcbiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHtcbiAgICAgICAgICAgICAgY29uc3QgaXRlbSA9IGl0ZW1zW2ldIGFzIEhUTUxFbGVtZW50O1xuICAgICAgICAgICAgICBpZiAoaXRlbS5xdWVyeVNlbGVjdG9yKCdhLmludGVybmFsLWxpbmsnKSkge1xuICAgICAgICAgICAgICAgICAgbmV3IE5vdGljZShgVGVzdGluZyB3aXRoIGNhcmQ6IFwiJHtpdGVtLnRleHRDb250ZW50LnN1YnN0cmluZygwLCAyMCl9Li4uXCJgLCAzMDAwKTtcbiAgICAgICAgICAgICAgICAgIHRoaXMucHJvY2Vzc0thbmJhbkl0ZW0oaXRlbSk7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgIH1cbiAgfVxufVxuXG5jbGFzcyBLYW5iYW5TdGF0dXNVcGRhdGVyU2V0dGluZ1RhYiBleHRlbmRzIFBsdWdpblNldHRpbmdUYWIge1xuICBwbHVnaW46IEthbmJhblN0YXR1c1VwZGF0ZXJQbHVnaW47XG4gIFxuICBjb25zdHJ1Y3RvcihhcHA6IEFwcCwgcGx1Z2luOiBLYW5iYW5TdGF0dXNVcGRhdGVyUGx1Z2luKSB7XG4gICAgICBzdXBlcihhcHAsIHBsdWdpbik7XG4gICAgICB0aGlzLnBsdWdpbiA9IHBsdWdpbjtcbiAgfVxuICBcbiAgZGlzcGxheSgpOiB2b2lkIHtcbiAgICAgIGNvbnN0IHtjb250YWluZXJFbH0gPSB0aGlzO1xuICAgICAgXG4gICAgICBjb250YWluZXJFbC5lbXB0eSgpO1xuICAgICAgY29udGFpbmVyRWwuY3JlYXRlRWwoJ2gyJywge3RleHQ6ICdLYW5iYW4gU3RhdHVzIFVwZGF0ZXIgU2V0dGluZ3MnfSk7XG4gICAgICBcbiAgICAgIG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuICAgICAgICAgIC5zZXROYW1lKCdTdGF0dXMgUHJvcGVydHkgTmFtZScpXG4gICAgICAgICAgLnNldERlc2MoJ1RoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSB0byB1cGRhdGUgd2hlbiBhIGNhcmQgaXMgbW92ZWQnKVxuICAgICAgICAgIC5hZGRUZXh0KHRleHQgPT4gdGV4dFxuICAgICAgICAgICAgICAuc2V0UGxhY2Vob2xkZXIoJ3N0YXR1cycpXG4gICAgICAgICAgICAgIC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdGF0dXNQcm9wZXJ0eU5hbWUpXG4gICAgICAgICAgICAgIC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcbiAgICAgICAgICAgICAgICAgIHRoaXMucGx1Z2luLnNldHRpbmdzLnN0YXR1c1Byb3BlcnR5TmFtZSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG4gICAgICAgICAgICAgIH0pKTtcbiAgICAgIFxuICAgICAgbmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG4gICAgICAgICAgLnNldE5hbWUoJ1Nob3cgTm90aWZpY2F0aW9ucycpXG4gICAgICAgICAgLnNldERlc2MoJ1Nob3cgYSBub3RpZmljYXRpb24gd2hlbiBhIHN0YXR1cyBpcyB1cGRhdGVkJylcbiAgICAgICAgICAuYWRkVG9nZ2xlKHRvZ2dsZSA9PiB0b2dnbGVcbiAgICAgICAgICAgICAgLnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLnNob3dOb3RpZmljYXRpb25zKVxuICAgICAgICAgICAgICAub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5zaG93Tm90aWZpY2F0aW9ucyA9IHZhbHVlO1xuICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG4gICAgICAgICAgICAgIH0pKTtcbiAgICAgIFxuICAgICAgbmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG4gICAgICAgICAgLnNldE5hbWUoJ0RlYnVnIE1vZGUnKVxuICAgICAgICAgIC5zZXREZXNjKCdFbmFibGUgZGV0YWlsZWQgbG9nZ2luZyAocmVkdWNlcyBwZXJmb3JtYW5jZSknKVxuICAgICAgICAgIC5hZGRUb2dnbGUodG9nZ2xlID0+IHRvZ2dsZVxuICAgICAgICAgICAgICAuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuZGVidWdNb2RlKVxuICAgICAgICAgICAgICAub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgICB0aGlzLnBsdWdpbi5zZXR0aW5ncy5kZWJ1Z01vZGUgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuICAgICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICBuZXcgTm90aWNlKCdEZWJ1ZyBtb2RlIGVuYWJsZWQgLSBjaGVjayBjb25zb2xlIGZvciBsb2dzJywgMzAwMCk7XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgIG5ldyBOb3RpY2UoJ0RlYnVnIG1vZGUgZGlzYWJsZWQnLCAzMDAwKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSkpO1xuICAgICAgXG4gICAgICAvLyBBZGQgYSB0ZXN0IGJ1dHRvblxuICAgICAgbmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG4gICAgICAgICAgLnNldE5hbWUoJ1Rlc3QgUGx1Z2luJylcbiAgICAgICAgICAuc2V0RGVzYygnVGVzdCB3aXRoIGN1cnJlbnQgS2FuYmFuIGJvYXJkJylcbiAgICAgICAgICAuYWRkQnV0dG9uKGJ1dHRvbiA9PiBidXR0b25cbiAgICAgICAgICAgICAgLnNldEJ1dHRvblRleHQoJ1J1biBUZXN0JylcbiAgICAgICAgICAgICAgLm9uQ2xpY2soKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgdGhpcy5wbHVnaW4ucnVuVGVzdCgpO1xuICAgICAgICAgICAgICB9KSk7XG4gICAgICBcbiAgICAgIC8vIFBlcmZvcm1hbmNlIGluZm9cbiAgICAgIGNvbnRhaW5lckVsLmNyZWF0ZUVsKCdoMycsIHt0ZXh0OiAnUGVyZm9ybWFuY2UgT3B0aW1pemF0aW9uJ30pO1xuICAgICAgXG4gICAgICBjb250YWluZXJFbC5jcmVhdGVFbCgncCcsIHtcbiAgICAgICAgICB0ZXh0OiAnVGhpcyBwbHVnaW4gb25seSBtb25pdG9ycyB0aGUgY3VycmVudGx5IGFjdGl2ZSBLYW5iYW4gYm9hcmQgdG8gbWluaW1pemUgcGVyZm9ybWFuY2UgaW1wYWN0LidcbiAgICAgIH0pO1xuICAgICAgXG4gICAgICAvLyBUcm91Ymxlc2hvb3Rpbmcgc2VjdGlvblxuICAgICAgY29udGFpbmVyRWwuY3JlYXRlRWwoJ2gzJywge3RleHQ6ICdUcm91Ymxlc2hvb3RpbmcnfSk7XG4gICAgICBcbiAgICAgIGNvbnN0IGxpc3QgPSBjb250YWluZXJFbC5jcmVhdGVFbCgndWwnKTtcbiAgICAgIFxuICAgICAgbGlzdC5jcmVhdGVFbCgnbGknLCB7XG4gICAgICAgICAgdGV4dDogJ1RoZSBwbHVnaW4gb25seSB3b3JrcyB3aXRoIHRoZSBjdXJyZW50bHkgb3BlbiBLYW5iYW4gYm9hcmQnXG4gICAgICB9KTtcbiAgICAgIFxuICAgICAgbGlzdC5jcmVhdGVFbCgnbGknLCB7XG4gICAgICAgICAgdGV4dDogJ0NhcmRzIG11c3QgY29udGFpbiBpbnRlcm5hbCBsaW5rcyB0byBub3RlcydcbiAgICAgIH0pO1xuICAgICAgXG4gICAgICBsaXN0LmNyZWF0ZUVsKCdsaScsIHtcbiAgICAgICAgICB0ZXh0OiAnS2VlcCBEZWJ1ZyBNb2RlIGRpc2FibGVkIGZvciBiZXN0IHBlcmZvcm1hbmNlJ1xuICAgICAgfSk7XG4gIH1cbn0iXSwibmFtZXMiOlsiUGx1Z2luIiwiTm90aWNlIiwicGFyc2VZYW1sIiwic3RyaW5naWZ5WWFtbCIsIlBsdWdpblNldHRpbmdUYWIiLCJTZXR0aW5nIl0sIm1hcHBpbmdzIjoiOzs7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQW9HQTtBQUNPLFNBQVMsU0FBUyxDQUFDLE9BQU8sRUFBRSxVQUFVLEVBQUUsQ0FBQyxFQUFFLFNBQVMsRUFBRTtBQUM3RCxJQUFJLFNBQVMsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLE9BQU8sS0FBSyxZQUFZLENBQUMsR0FBRyxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsVUFBVSxPQUFPLEVBQUUsRUFBRSxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRTtBQUNoSCxJQUFJLE9BQU8sS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLE9BQU8sQ0FBQyxFQUFFLFVBQVUsT0FBTyxFQUFFLE1BQU0sRUFBRTtBQUMvRCxRQUFRLFNBQVMsU0FBUyxDQUFDLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7QUFDbkcsUUFBUSxTQUFTLFFBQVEsQ0FBQyxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMs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 diff --git a/main.ts b/main.ts index 8db668b..cb118fa 100644 --- a/main.ts +++ b/main.ts @@ -6,9 +6,20 @@ import { PluginSettingTab, Setting, stringifyYaml, - WorkspaceLeaf + WorkspaceLeaf, + View } from 'obsidian'; +// Extended interfaces for Obsidian internal properties +interface ExtendedWorkspaceLeaf extends WorkspaceLeaf { + containerEl?: HTMLElement; + view: ExtendedView; +} + +interface ExtendedView extends View { + contentEl?: HTMLElement; +} + interface KanbanStatusUpdaterSettings { statusPropertyName: string; showNotifications: boolean; @@ -117,8 +128,8 @@ export default class KanbanStatusUpdaterPlugin extends Plugin { // First disconnect any existing observers this.disconnectObservers(); - // Get the active leaf - const activeLeaf = this.app.workspace.activeLeaf; + // Get the active leaf using the non-deprecated API + const activeLeaf = this.app.workspace.getLeaf(false); if (!activeLeaf) return; try { @@ -128,17 +139,16 @@ export default class KanbanStatusUpdaterPlugin extends Plugin { // Use type assertions to avoid TypeScript errors if (activeLeaf.view) { // Try to access the contentEl property using type assertion - // @ts-ignore - contentEl exists but might not be in type definitions - contentEl = activeLeaf.view.contentEl; + contentEl = (activeLeaf as ExtendedWorkspaceLeaf).view.contentEl || null; } // If that didn't work, try another approach if (!contentEl) { // Try to get the Kanban board directly from the DOM // Leaf containers have 'view-content' elements that contain the actual view - const viewContent = (activeLeaf as any).containerEl?.querySelector('.view-content'); + const viewContent = (activeLeaf as ExtendedWorkspaceLeaf).containerEl?.querySelector('.view-content'); if (viewContent) { - contentEl = viewContent; + contentEl = viewContent as HTMLElement; } else { // Last resort - look for Kanban boards anywhere in the workspace contentEl = document.querySelector('.workspace-leaf.mod-active .view-content'); @@ -595,4 +605,4 @@ class KanbanStatusUpdaterSettingTab extends PluginSettingTab { text: 'Keep Debug Mode disabled for best performance' }); } -} \ No newline at end of file +}