/* THIS IS A GENERATED/BUNDLED FILE BY ESBUILD if you want to view the source, please visit the github repository of this plugin */ var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // main.ts var main_exports = {}; __export(main_exports, { QuickChangeTranslationeModal: () => QuickChangeTranslationeModal, default: () => MyBible }); module.exports = __toCommonJS(main_exports); var import_obsidian = require("obsidian"); // node_modules/async-mutex/index.mjs var E_TIMEOUT = new Error("timeout while waiting for mutex to become available"); var E_ALREADY_LOCKED = new Error("mutex already locked"); var E_CANCELED = new Error("request for lock canceled"); var __awaiter$2 = 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()); }); }; var Semaphore = class { constructor(_value, _cancelError = E_CANCELED) { this._value = _value; this._cancelError = _cancelError; this._weightedQueues = []; this._weightedWaiters = []; } acquire(weight = 1) { if (weight <= 0) throw new Error(`invalid weight ${weight}: must be positive`); return new Promise((resolve, reject) => { if (!this._weightedQueues[weight - 1]) this._weightedQueues[weight - 1] = []; this._weightedQueues[weight - 1].push({ resolve, reject }); this._dispatch(); }); } runExclusive(callback, weight = 1) { return __awaiter$2(this, void 0, void 0, function* () { const [value, release] = yield this.acquire(weight); try { return yield callback(value); } finally { release(); } }); } waitForUnlock(weight = 1) { if (weight <= 0) throw new Error(`invalid weight ${weight}: must be positive`); return new Promise((resolve) => { if (!this._weightedWaiters[weight - 1]) this._weightedWaiters[weight - 1] = []; this._weightedWaiters[weight - 1].push(resolve); this._dispatch(); }); } isLocked() { return this._value <= 0; } getValue() { return this._value; } setValue(value) { this._value = value; this._dispatch(); } release(weight = 1) { if (weight <= 0) throw new Error(`invalid weight ${weight}: must be positive`); this._value += weight; this._dispatch(); } cancel() { this._weightedQueues.forEach((queue) => queue.forEach((entry) => entry.reject(this._cancelError))); this._weightedQueues = []; } _dispatch() { var _a; for (let weight = this._value; weight > 0; weight--) { const queueEntry = (_a = this._weightedQueues[weight - 1]) === null || _a === void 0 ? void 0 : _a.shift(); if (!queueEntry) continue; const previousValue = this._value; const previousWeight = weight; this._value -= weight; weight = this._value + 1; queueEntry.resolve([previousValue, this._newReleaser(previousWeight)]); } this._drainUnlockWaiters(); } _newReleaser(weight) { let called = false; return () => { if (called) return; called = true; this.release(weight); }; } _drainUnlockWaiters() { for (let weight = this._value; weight > 0; weight--) { if (!this._weightedWaiters[weight - 1]) continue; this._weightedWaiters[weight - 1].forEach((waiter) => waiter()); this._weightedWaiters[weight - 1] = []; } } }; var __awaiter$1 = 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()); }); }; var Mutex = class { constructor(cancelError) { this._semaphore = new Semaphore(1, cancelError); } acquire() { return __awaiter$1(this, void 0, void 0, function* () { const [, releaser] = yield this._semaphore.acquire(); return releaser; }); } runExclusive(callback) { return this._semaphore.runExclusive(() => callback()); } isLocked() { return this._semaphore.isLocked(); } waitForUnlock() { return this._semaphore.waitForUnlock(); } release() { if (this._semaphore.isLocked()) this._semaphore.release(); } cancel() { return this._semaphore.cancel(); } }; // main.ts var BUILD_END_TOAST = "Bible build finished!"; var SELECTED_TRANSLATION_OPTION = ""; var SELECTED_TRANSLATION_OPTION_KEY = "default"; var DEFAULT_SETTINGS = { translation: SELECTED_TRANSLATION_OPTION_KEY, reading_translation: "WEB", bible_folder: "/My Bible/", book_folders_enabled: true, book_name_format: "{order} {book}", book_name_delimiter: " ", chapter_name_format: "{book} {chapter}", book_name_capitalization: "name_case", book_name_abbreviated: false, padded_order: true, padded_chapter: false, build_with_dynamic_verses: true, verse_body_format: "###### {verse}\n{verse_text}", chapter_body_format: "\n###### Navigation\n**[[{last_chapter_name}|\u23EA {last_chapter_name}]] | [[{chapter_index}|Chapters]] | [[{next_chapter_name}|{next_chapter_name} \u23E9]]**\n**[[{first_chapter_name}|First ({first_chapter})]] | [[{final_chapter_name}|Last ({final_chapter})]]**\n\n{verses}\n\n###### Navigation\n**[[{last_chapter_name}|\u23EA {last_chapter_name}]] | [[{chapter_index}|Chapters]] | [[{next_chapter_name}|{next_chapter_name} \u23E9]]**\n**[[{first_chapter_name}|First ({first_chapter})]] | [[{final_chapter_name}|Last ({final_chapter})]]**\n\n", index_enabled: true, index_name_format: "-- Bible --", index_link_format: "- [[{book_index}|{book}]]", index_format: "### Old testament\n{old_testament}\n### New testament\n{new_testament}\n### Apocrypha\n{apocrypha}", chapter_index_enabled: true, chapter_index_name_format: "-- {book} --", chapter_index_link_format: "- [[{chapter_name}|{chapter}]]", chapter_index_format: "###### Navigation\n*[[{index}|Books]]*\n\n### Chapters\n{chapters}\n", store_locally: false, _built_translation: "", set_translation: async function(val, plugin) { if (val === SELECTED_TRANSLATION_OPTION_KEY) { this.translation = val; return; } let has_translation = false; let translations = await plugin.bible_api.get_translations(); if (!(val in translations)) { this.translation = await plugin.bible_api.get_default_translation(); } else { this.translation = val; } } }; function httpGet(theUrl) { return new Promise(async (ok, err) => { ok(await (0, import_obsidian.requestUrl)(theUrl).text); }); } function is_alpha(string) { for (let char_str of string) { let char = char_str.charCodeAt(0); if (char > 64 && char < 91 || char > 96 && char < 123 || char > 39 && char < 42) { continue; } return false; } return true; } function is_alphanumeric(string) { for (let char_str of string) { let char = char_str.charCodeAt(0); if (char > 64 && char < 91 || char > 96 && char < 123 || char > 47 && char < 58) { continue; } return false; } return true; } function is_numeric(string) { for (let char_str of string) { let char = char_str.charCodeAt(0); if (char > 47 && char < 58) { continue; } return false; } return true; } async function save_file(path, content) { let file_path = (0, import_obsidian.normalizePath)(path); let file = this.app.vault.getAbstractFileByPath(file_path); if (file instanceof import_obsidian.TFile) { await this.app.vault.modify(file, content); } else if (file === null) { await this.app.vault.create( file_path, content ); } } function translation_to_display_name(translation) { return "{0} - {1} - {2}".format(translation.language, translation.abbreviated_name, translation.display_name); } var MyBible = class extends import_obsidian.Plugin { async onload() { await this.loadSettings(); this.bible_api = new BollsLifeBibleAPI(); this.bible_api.plugin = this; await this.settings.set_translation(this.settings.translation, this); this.addCommand({ id: "create_bible_files", name: "Build Bible", callback: async () => { new BuilderModal(this.app, this).open(); } }); this.addCommand({ id: "quick_change_translation", name: "Change translation", callback: async () => { let modal = new QuickChangeTranslationeModal(this); modal.translations = await this.bible_api.get_translations(); modal.onChose = (translation) => { this.settings.reading_translation = translation.abbreviated_name; }; modal.open(); } }); this.addCommand({ id: "clear_cache", name: "Clear local files", callback: async () => { new ClearLocalFilesModal(this.app, this).open(); } }); this.addCommand({ id: "download_bible", name: "Download translation", callback: async () => { let modal = new QuickChangeTranslationeModal(this); modal.translations = await this.bible_api.get_translations(); modal.onChose = async (translation) => { await this.bible_api.user_download_translation( translation.abbreviated_name ); }; modal.open(); } }); this.registerMarkdownCodeBlockProcessor("verse", async (source, element, context) => { const ref = source.trim().replace(/[:-]/g, " ").split(" "); let book = null; let book_id = -1; let chapter = -1; let verse = -1; let verse_end = -1; let maybe_translation = null; let i = 0; while (i != ref.length) { if (i == 0) { book = (book || "") + ref[i]; } else { if (!is_alpha(ref[i])) { break; } book += " " + ref[i]; } i += 1; } if (is_numeric(book || "")) { book_id = Number(book); book = null; } if (i != ref.length && is_numeric(ref[i])) { chapter = Number(ref[i]); i += 1; } if (i != ref.length && is_numeric(ref[i])) { verse = Number(ref[i]); i += 1; } if (i != ref.length && is_numeric(ref[i])) { verse_end = Number(ref[i]); i += 1; } if (i != ref.length && is_alphanumeric(ref[i])) { maybe_translation = ref[i]; i += 1; } let translation = maybe_translation || this.settings.reading_translation; if (book !== null) { book_id = await this.bible_api.book_id(this.settings._built_translation || translation, book); } book = (await this.bible_api.get_book_data(translation, book_id)).name; let text = ""; if (book.length === 0) { text = "[Book and chapter must be provided]"; } else if (chapter === -1) { text = "[Chapter must be provided]"; } else if (verse === -1) { let verses = await this.bible_api.get_chapter( translation, book_id, chapter ); for (const verse_i_ of Object.keys(verses)) { const verse_i = Number(verse_i_); let verse2 = verses[verse_i]; text += "" + (verse_i + 1) + " " + verse2; if (verse_i != Object.keys(verses).length - 1) { text += "
"; } } if (text.length === 0) { text = "".format(String(chapter), book, translation); } } else if (verse_end < verse) { text = await this.bible_api.get_verse( translation, book_id, chapter, verse ); if (text.length === 0) { text = "".format(String(chapter), book, String(verse), translation); } } else { let verses = await this.bible_api.get_chapter( translation, book_id, chapter ); let j = verse; while (j < verse_end + 1 && j < Object.keys(verses).length) { text += "" + j + " " + verses[j - 1]; if (j != verse_end) { text += "
"; } j += 1; } if (text.length === 0) { text = "".format(String(chapter), book, String(verse), String(verse_end), translation); } } let span = element.createSpan({ text: "" }); let tags = text.matchAll( /(?:<\s*([\w]*)\s*>(.*?)<\s*\/\1\s*>)|<\s*(br|\/br|br\/)\s*>|(.+?(?:(?=<\s*[/\\\w]*\s*>)|$))/gs ); for (let match of tags) { let tag_type = match[1]; let tag_text = match[2]; let lone_tag_type = match[3]; let normal_text = match[4]; if (normal_text !== void 0) { span.createSpan({ text: normal_text }); } else if (lone_tag_type === "br") { span.createEl(lone_tag_type); } else if (lone_tag_type === "br/" || lone_tag_type === "/br") { span.createEl("br"); span.createSpan({ text: "\n" }); } else if (lone_tag_type === "/J") { } else if (tag_type === "sup") { span.createEl(tag_type, { text: tag_text }); } else if (tag_type === "sub") { span.createEl(tag_type, { text: tag_text }); } else if (tag_type === "S") { span.createEl( "sub", { text: tag_text, attr: { style: "opacity: 0.5" } } ); } else if (tag_type === "i") { span.createEl(tag_type, { text: tag_text }); } else if (tag_type === "b") { span.createEl(tag_type, { text: tag_text }); } else if (tag_type === "e") { span.createEl("i").createEl("q", { text: tag_text }); } else { span.createSpan( { text: "<{0}>{1}".format(tag_type, tag_text) } ); } } }); this.addSettingTab(new SettingsTab(this.app, this)); } onunload() { } async build_bible() { let bible_path = (0, import_obsidian.normalizePath)(this.settings.bible_folder); let bible_folder = this.app.vault.getAbstractFileByPath(bible_path); if (bible_folder instanceof import_obsidian.TFile) { new ErrorModal( this.app, this, "Failed to build bible", 'The bible folder defined in settings, "{0}", was expected to point to a folder, but it points to a file. Try changing the path to point to a folder, or change the file to a folder.'.format(this.settings.bible_folder) ).open(); return; } else if (bible_folder === null) { this.app.vault.adapter.mkdir(bible_path); } else { } let folders_and_files = await this.app.vault.adapter.list(bible_path); if (folders_and_files.files.length + folders_and_files.folders.length != 0) { new ClearOldBibleFilesModal(this.app, this).open(); } else { await this._build_bible(bible_path); } } async _build_bible(bible_path) { this.show_toast_progress(0, null); try { let translation = ""; if (this.settings.translation == SELECTED_TRANSLATION_OPTION_KEY) { translation = this.settings.reading_translation; } else { translation = this.settings.translation; } this.settings._built_translation = translation; await this.saveSettings(); let ctx = new BuildContext(); ctx.plugin = this; ctx.translation = translation; ctx.books = await this.bible_api.get_books_data(ctx.translation); ctx.verse_counts = await this.bible_api.get_verse_count(ctx.translation); ctx.translation_texts = await this.bible_api.get_translation(ctx.translation); if (ctx.translation_texts !== void 0) { for (let book of ctx.books) { let to_remove = []; for (let i = 1; i != book.chapters.length + 1; i++) { let chapter_texts = ctx.translation_texts.books[book.id]; let verses = chapter_texts[i] || {}; if (Object.keys(verses).length === 0) { to_remove.push(i); } } for (const i of to_remove.reverse()) { book.chapters.remove(i); } } } let built_chapter_count = 0; let total_chapter_count = 0; for (const i in ctx.books) { total_chapter_count += ctx.books[i].chapters.length; } this.show_toast_progress(0, total_chapter_count); if (this.settings.index_enabled) { await save_file( "{0}/{1}.md".format(bible_path, ctx.format_index_name()), ctx.format_index() ); } let file_promises = []; for (let book of ctx.books) { ctx.set_book(book); let texts_of_book = ctx.translation_texts.books[book.id]; let book_path = bible_path; if (this.settings.book_folders_enabled) { book_path += "/" + ctx.format_book_name(this, ctx.book, this.settings.book_name_capitalization); this.app.vault.adapter.mkdir((0, import_obsidian.normalizePath)(book_path)); } if (this.settings.chapter_index_enabled) { file_promises.push(save_file( "{0}/{1}.md".format(book_path, ctx.format_chapter_index_name(ctx.book)), ctx.format_chapter_index(ctx.book) )); } for (const chapter of ctx.book.chapters) { file_promises.push(new Promise(async () => { ctx.set_chapter(chapter); let texts_of_chapter = texts_of_book[chapter]; ctx.verses_text = ""; let added_verse_count = 0; for (const verse_key of Object.keys(texts_of_chapter)) { const verse = Number(verse_key); while (added_verse_count < verse) { ctx.verse = added_verse_count + 1; let text = ctx.format_verse_body( this, this.settings.build_with_dynamic_verses ); ctx.verses_text += text; if (!(text.length === 0 && !this.settings.build_with_dynamic_verses) && verse_key !== Object.keys(texts_of_chapter).last()) { ctx.verses_text += "\n"; } added_verse_count += 1; } } let chapter_note_name = ctx.format_chapter_name(); let note_body = ctx.format_chapter_body(this); let file_path = book_path + "/" + chapter_note_name + ".md"; await save_file(file_path, note_body); built_chapter_count += 1; this.show_toast_progress( built_chapter_count, total_chapter_count ); })); } } await Promise.all(file_promises); } catch (e) { this.show_toast_error(String(e)); throw e; } } show_toast_error(error) { var _a; if (this.progress_notice !== null) { (_a = this.progress_notice) == null ? void 0 : _a.hide(); this.progress_notice = null; } new import_obsidian.Notice("Error building bible: " + error, 0); } show_toast_progress(progress, finish) { var _a; if (progress === finish && finish != null) { (_a = this.progress_notice) == null ? void 0 : _a.hide(); this.progress_notice = null; new import_obsidian.Notice(BUILD_END_TOAST); return; } if (this.progress_notice == null) { this.progress_notice = new import_obsidian.Notice("", 0); } let msg = ""; if (finish == null) { msg = "Building bible..."; } else { msg = "Building bible... ({0}/{1})".format(String(progress), String(finish)); } this.progress_notice.setMessage(msg); } async loadSettings() { this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); } async saveSettings() { let saving = {}; Object.assign(saving, this.settings); for (const key in saving) { let value = DEFAULT_SETTINGS[key]; if (saving[key] === value) { delete saving[key]; } } await this.saveData(saving); } }; var BuildContext = class { constructor() { this.translation = ""; this.books = []; this.chapter = 0; this.prev_chapter = 0; this.next_chapter = 0; this.chapter_verse_count = 0; this.verses_text = ""; this.verse = 0; } /// Find index of book by ID find_book(book_id) { for (let i of this.books.keys()) { if (this.books[i].id === book_id) { return i; } } throw new Error("No book by id ${book_id}"); } abbreviate_book_name(name, delimeter) { return name.replace(delimeter, "").slice(0, 3); } format_book_name(plugin, book, casing) { let delim = plugin.settings.book_name_delimiter; let book_name = this.to_case(book.name, casing, delim); if (plugin.settings.book_name_abbreviated) { book_name = this.abbreviate_book_name(book_name, delim); } return plugin.settings.book_name_format.replace( /{order}/g, String(book.id).padStart(2 * Number(plugin.settings.padded_order), "0") ).replace(/{book}/g, book_name).replace(/{translation}/g, String(this.translation)); } format_book_name_without_order(plugin, book, casing) { let delim = plugin.settings.book_name_delimiter; let book_name = this.to_case(book.name, casing, delim); if (plugin.settings.book_name_abbreviated) { book_name = this.abbreviate_book_name(book_name, delim); } return book_name; } format_chapter_body(plugin) { let casing = plugin.settings.book_name_capitalization; return plugin.settings.chapter_body_format.replace(/{verses}/g, this.verses_text).replace(/{book}/g, this.format_book_name_without_order(plugin, this.book, casing)).replace( /{order}/g, String(this.book.id).padStart(2 * Number(plugin.settings.padded_order), "0") ).replace(/{chapter}/g, String(this.chapter)).replace(/{chapter_name}/g, this.format_chapter_name()).replace(/{chapter_index}/g, this.format_chapter_index_name(this.book)).replace(/{last_chapter}/g, String(this.prev_chapter)).replace(/{last_chapter_name}/g, this.format_chapter_name("last")).replace(/{last_chapter_book}/g, this.format_book_name_without_order(plugin, this.prev_book, casing)).replace(/{next_chapter}/g, String(this.next_chapter)).replace(/{next_chapter_name}/g, this.format_chapter_name("next")).replace(/{next_chapter_book}/g, this.format_book_name_without_order(plugin, this.next_book, casing)).replace(/{first_chapter}/g, String(this.book.chapters.first())).replace(/{first_chapter_name}/g, this.format_chapter_name("first")).replace(/{final_chapter}/g, String(this.book.chapters.last())).replace(/{final_chapter_name}/g, this.format_chapter_name("final")).replace(/{translation}/g, String(this.translation)); } format_chapter_name(tense = "current", custom_chapter = null) { let format = this.plugin.settings.chapter_name_format; if (format.length == 0) { format = DEFAULT_SETTINGS.chapter_name_format; } let chapter_pad_by = 3; if (this.book.chapters.length < 10) { chapter_pad_by = 1; } else if (this.book.chapters.length < 100) { chapter_pad_by = 2; } let casing = this.plugin.settings.book_name_capitalization; let delim = this.plugin.settings.book_name_delimiter; let book_name = ""; let order = -1; let chapter = custom_chapter; switch (tense) { case "current": { book_name = this.format_book_name_without_order(this.plugin, this.book, casing); order = this.book.id; chapter = this.chapter; break; } case "last": { book_name = this.format_book_name_without_order(this.plugin, this.prev_book, casing); order = this.prev_book.id; chapter = this.prev_chapter; break; } case "next": { book_name = this.format_book_name_without_order(this.plugin, this.next_book, casing); order = this.next_book.id; chapter = this.next_chapter; break; } case "first": { book_name = this.format_book_name_without_order(this.plugin, this.book, casing); order = this.book.id; chapter = this.book.chapters.first() || 1; break; } case "final": { book_name = this.format_book_name_without_order(this.plugin, this.book, casing); order = this.book.id; chapter = this.book.chapters.last() || 1; break; } case "custom": { book_name = this.format_book_name_without_order(this.plugin, this.book, casing); order = this.book.id; chapter = custom_chapter; break; } default: throw new Error("Unmatched switch case at tense '{0}'".format(tense)); } if (chapter == null) { throw new Error("Chapter is null"); } return format.replace(/{book}/g, book_name).replace( /{order}/g, String(order).padStart(2 * Number(this.plugin.settings.padded_order), "0") ).replace( /{chapter}/g, String(chapter).padStart(chapter_pad_by * Number(this.plugin.settings.padded_chapter), "0") ).replace(/{translation}/g, String(this.translation)); } format_verse_body(plugin, build_with_dynamic_verses) { let book_name = this.format_book_name_without_order( plugin, this.book, "current" ); let verse_text = ""; if (build_with_dynamic_verses) { verse_text = "``` verse\n{book_id} {chapter} {verse} \n```"; } else { verse_text = this.translation_texts.books[this.book.id][this.chapter][this.verse]; if (verse_text === void 0) { return ""; } if (verse_text.contains("<")) { verse_text = verse_text.replace(/<\s*br\s*\/?>/g, "\n").replace(/<\s*i*\s*>\s*/g, "*").replace(/\s*<\/\s*i*\s*>/g, "*").replace(/<\/?\s*i*\s*\/?>/g, "*").replace(/<\/?\s*b*\s*\/?>/g, "**").replace(/<\s*S*\s*>/g, "*").replace(/<\/\s*S*\s*>/g, "*").replace(/<\/?\s*\w*\s*\/?>/g, ""); } } return plugin.settings.verse_body_format.replace(/{verse_text}/g, verse_text).replace(/{verse}/g, String(this.verse)).replace(/{book}/g, book_name).replace(/{book_id}/g, String(this.book.id)).replace( /{order}/g, String(this.book.id).padStart(2 * Number(plugin.settings.padded_order), "0") ).replace(/{chapter}/g, String(this.chapter)).replace(/{chapter_name}/g, this.format_chapter_name()).replace(/{final_chapter}/g, String(this.book.chapters)).replace(/{translation}/g, String(this.translation)); } format_chapter_index(book) { let book_name = this.format_book_name_without_order( this.plugin, book, this.plugin.settings.book_name_capitalization ); let chapter_links = ""; for (let i = 0; i != book.chapters.length; i++) { let chapter = book.get_chapter_number(i); let link = this.plugin.settings.chapter_index_link_format.replace(/{order}/g, String(book.id).padStart(2 * Number(this.plugin.settings.padded_order), "0")).replace(/{book}/g, book_name).replace(/{book_index}/g, this.format_chapter_index_name(book)).replace(/{translation}/g, String(this.translation)).replace(/{chapter}/g, String(chapter)).replace(/{chapter_name}/g, this.format_chapter_name("custom", chapter)); if (i != book.chapters.length - 1) { link += "\n"; } chapter_links += link; } return this.plugin.settings.chapter_index_format.replace(/{order}/g, String(book.id).padStart(2 * Number(this.plugin.settings.padded_order), "0")).replace(/{book}/g, book_name).replace(/{book_index}/g, this.format_chapter_index_name(book)).replace(/{translation}/g, String(this.translation)).replace(/{index}/g, this.format_index_name()).replace(/{chapters}/g, chapter_links); } format_chapter_index_name(book) { let book_name = this.format_book_name_without_order( this.plugin, book, this.plugin.settings.book_name_capitalization ); return this.plugin.settings.chapter_index_name_format.replace(/{order}/g, String(book.id).padStart(2 * Number(this.plugin.settings.padded_order), "0")).replace(/{book}/g, book_name).replace(/{translation}/g, String(this.translation)); } format_index_name() { return this.plugin.settings.index_name_format.replace(/{translation}/g, this.translation); } format_index() { let old_t_links = ""; let new_t_links = ""; let apocr_links = ""; for (const i in this.books) { let book_name = this.format_book_name_without_order( this.plugin, this.books[i], this.plugin.settings.book_name_capitalization ); let link = this.plugin.settings.index_link_format.replace(/{order}/g, String(this.books[i].id).padStart(2 * Number(this.plugin.settings.padded_order), "0")).replace(/{book}/g, book_name).replace(/{book_index}/g, this.format_chapter_index_name(this.books[i])).replace(/{translation}/g, String(this.translation)) + "\n"; if (this.books[i].id < 40) { old_t_links += link; } else if (this.books[i].id < 67) { new_t_links += link; } else { apocr_links += link; } } old_t_links = old_t_links.slice(0, old_t_links.length - 1); new_t_links = new_t_links.slice(0, new_t_links.length - 1); apocr_links = apocr_links.slice(0, apocr_links.length - 1); return this.plugin.settings.index_format.replace(/{translation}/g, this.translation).replace(/{old_testament}/g, old_t_links).replace(/{new_testament}/g, new_t_links).replace(/{apocrypha}/g, apocr_links); } set_book(book) { this.book = book; let [next_book, next_chapter] = this.next_chapter_of(this.book, this.chapter); let [prev_book, prev_chapter] = this.prev_chapter_of(this.book, this.chapter); this.next_book = next_book; this.next_chapter = next_chapter; this.prev_book = prev_book; this.prev_chapter = prev_chapter; } next_chapter_of(book, chapter) { let next_book = book; if (chapter === book.chapters.last()) { let book_i = this.find_book(book.id); if (book_i == this.books.length - 1) { next_book = this.books[0]; } else { next_book = this.books[book_i + 1]; } } let next_chapter = chapter + 1; if (next_book.id !== book.id) { next_chapter = next_book.chapters[0]; } return [next_book, next_chapter]; } prev_chapter_of(book, chapter) { let prev_book = book; if (chapter === book.chapters.first()) { let book_i = this.find_book(book.id); if (book_i == 0) { prev_book = this.books[this.books.length - 1]; } else { prev_book = this.books[book_i - 1]; } } let prev_chapter = chapter - 1; if (prev_book.id !== book.id) { prev_chapter = prev_book.chapters[prev_book.chapters.length - 1]; } return [prev_book, prev_chapter]; } set_chapter(chapter) { this.chapter = chapter; this.set_book(this.book); } // Sets the capitalization of the given name depending on *name_case*. to_case(name, name_case, delimeter) { name = name.replace(/ /g, delimeter); if (name_case == "lower_case") { name = name.toLowerCase(); } else if (name_case == "upper_case") { name = name.toUpperCase(); } return name; } get_verse_count() { return this.verse_counts.get_count_for(this.book.id, this.chapter); } }; var VerseCounts = class { get_count_for(book, chapter) { return this.books[book][chapter] || 0; } }; var BookData = class { constructor(id, name, chapters) { this.id = id; this.name = name; this.chapters = chapters; } /// Returns the number of the chapter at index get_chapter_number(index) { if (index >= this.chapters.length) { throw new Error(""); } return this.chapters[index]; } has_chapter(chapter) { return this.chapters.find((value, _, __) => value === chapter) !== void 0; } }; var SyncCache = class { constructor() { this.syncs = {}; } async sync(key, body) { if (!(key in this.syncs)) { this.syncs[key] = new SyncCacheItem(); } let sync_item = this.syncs[key]; sync_item.ref_count += 1; try { await sync_item.mutex.acquire().then(async () => { sync_item.data = await body(); sync_item.mutex.cancel(); sync_item.mutex.release(); }).catch((e) => { if (e === E_CANCELED) { } else { throw e; } }); } finally { sync_item.ref_count -= 1; if (sync_item.ref_count === 0) { delete this.syncs[key]; } } return sync_item.data; } }; var SyncCacheItem = class { constructor() { this.mutex = new Mutex(); this.data = null; this.ref_count = 0; } }; var BibleAPI = class { constructor() { this.cache_clear_timer = null; this.sync_cache = new SyncCache(); } async _get_book_data(translation, book_id) { throw new Error("unimplemented"); } async _get_books_data(translation) { throw new Error("unimplemented"); } async _get_chapter(translation, book_id, chapter) { throw new Error("unimplemented"); } async _get_translation(translation) { throw new Error("unimplemented"); } async _get_translations() { throw new Error("unimplemented"); } async get_default_translation() { throw new Error("unimplemented"); } async _get_verse(translation, book_id, chapter, verse) { let chapter_data = await this.get_chapter( translation, book_id, chapter ); return chapter_data[verse] || ""; } async _get_verse_count(translation) { throw new Error("unimplemented"); } /// Downloads a translation and saves it locally. async user_download_translation(translation) { let notify = new import_obsidian.Notice( "Downloading {0} translation".format(translation), 0 ); let promises = []; let translation_data = await this.get_translation(translation); for (const book_id_ in translation_data.books) { const book_id = Number(book_id_); const chapters = translation_data.books[book_id]; for (const chapter_key of Object.keys(chapters)) { const chapter = Number(chapter_key); const chapter_data = chapters[chapter]; promises.push(this.save_chapter_data( chapter_data, translation, book_id, chapter )); } } notify.hide(); notify = new import_obsidian.Notice("Saving {0} translation files".format(translation), 0); await Promise.all(promises); notify.hide(); new import_obsidian.Notice("Download complete"); } // Get book ID from translation and book name async book_id(translation, book_name) { let books = await this.get_books_data(translation); for (let i of books.keys()) { if (books[i].name === book_name) { return books[i].id; } } if (book_name in DEFAULT_NAME_MAP) { return DEFAULT_NAME_MAP[book_name]; } throw new Error( "Translation '{0}' has no book named '{1}'".format(translation, book_name) ); } async get_book_data(translation, book_id) { let book_key = "{0} {1}".format(translation, String(book_id)); let data = await this.sync_cache.sync( "get_book_data_" + book_key, () => this._get_book_data(translation, book_id) ); if (data == null) { throw new Error(); } return data; } async get_books_data(translation) { return await this.sync_cache.sync( "get_books_data_" + translation, () => this._get_books_data(translation) ); } async cache_chapter(translation, book_id, chapter, chapter_data, save_locally) { let key = this.make_chapter_key(translation, book_id, chapter); let cache_path = this.get_cache_path(); this.plugin.app.vault.adapter.mkdir(cache_path); let cached_file_name = "{0} {1} {2}.txt".format(translation, String(book_id), String(chapter)); let cached_file_path = (0, import_obsidian.normalizePath)( cache_path + "/" + cached_file_name ); if (chapter_data != null && !await this.plugin.app.vault.adapter.exists(cached_file_path)) { await this.plugin.app.vault.adapter.write( cached_file_path, this.make_chapter_file(chapter_data) ); } if (this.cache_clear_timer !== null && this.cache_clear_timer_promise_err !== null) { this.cache_clear_timer_promise_err(null); } this.cache_clear_timer = new Promise((ok, err) => { this.cache_clear_timer_promise_err = err; setTimeout(ok, 6e4 * 60); }); this.cache_clear_timer.then(() => this.clear_local_files()).catch((err) => { }); } async get_chapter(translation, book_id, chapter) { let chapter_key = this.make_chapter_key(translation, book_id, chapter); let file_name = this.make_chapter_file_name(translation, book_id, chapter); let download_path = this.get_download_path(); this.plugin.app.vault.adapter.mkdir(download_path); let download_file_path = (0, import_obsidian.normalizePath)( download_path + "/" + file_name ); let cache_path = this.get_cache_path(); this.plugin.app.vault.adapter.mkdir(cache_path); let cached_file_path = (0, import_obsidian.normalizePath)( cache_path + "/" + file_name ); let data = await this.sync_cache.sync( "get_chapter_" + chapter_key, async () => { if (await this.plugin.app.vault.adapter.exists(download_file_path)) { return await this.load_chapter_file(download_path, file_name); } else if (await this.plugin.app.vault.adapter.exists(cached_file_path)) { return await this.load_chapter_file(cache_path, file_name); } return await this._get_chapter( translation, book_id, chapter ); } ); if (data === null || Object.keys(data).length == 0) { return []; } new Promise(async (ok, err) => { try { if (!await this.plugin.app.vault.adapter.exists(download_file_path)) { this.cache_chapter( translation, book_id, chapter, data, this.plugin.settings.store_locally ); } ok(null); } catch (e) { err(e); } }); return data; } get_cache_path() { return (0, import_obsidian.normalizePath)(this.plugin.manifest.dir + "/.mybiblecache"); } get_download_path() { return (0, import_obsidian.normalizePath)(this.plugin.manifest.dir + "/.chapters"); } async get_translation(translation) { return await this.sync_cache.sync( "get_translation_" + translation, () => this._get_translation(translation) ); } async _get_default_translation() { return await this.sync_cache.sync( "get_default_translation", () => this._get_default_translation() ); } async get_translations() { return await this.sync_cache.sync( "get_translations", () => this._get_translations() ); } async get_verse(translation, book_id, chapter, verse) { let key = "get_verse_{0}_{1}_{2}_{3}".format(translation, String(book_id), String(chapter), String(verse)); return await this.sync_cache.sync( key, () => this._get_verse( translation, book_id, chapter, verse ) ); } async get_verse_count(translation) { return await this.sync_cache.sync( "get_verse_count_" + translation, () => this._get_verse_count(translation) ); } async clear_local_files() { this.cache_clear_timer = null; let cache_path = this.get_cache_path(); if (await this.plugin.app.vault.adapter.exists(cache_path)) { if (!await this.plugin.app.vault.adapter.trashSystem(cache_path)) { await this.plugin.app.vault.adapter.trashLocal(cache_path); } } let download_path = this.get_download_path(); if (await this.plugin.app.vault.adapter.exists(download_path)) { if (!await this.plugin.app.vault.adapter.trashSystem(download_path)) { await this.plugin.app.vault.adapter.trashLocal(download_path); } } } async load_chapter_file(folder, path) { this.plugin.app.vault.adapter.mkdir(folder); let raw = await this.plugin.app.vault.adapter.read(folder + "/" + path); let verse_list = []; if (raw.startsWith("[")) { verse_list = JSON.parse(raw); } else { verse_list = raw.split("\n"); } let verses = {}; for (let i = 0; i != verse_list.length; i++) { if (verse_list[i].length == 0) { continue; } verses[i + 1] = verse_list[i]; } return verses; } make_chapter_file(chapter_data) { let added_verse_count = 0; let body = ""; for (let i = 1; added_verse_count !== Object.keys(chapter_data).length; i++) { if (i in chapter_data) { body += chapter_data[i]; added_verse_count += 1; } if (added_verse_count !== Object.keys(chapter_data).length) { body += "\n"; } } return body; } /// Makes the file name for downloaded chapters make_chapter_file_name(translation, book_id, chapter) { return "{0} {1} {2}.txt".format(translation, String(book_id), String(chapter)); } make_chapter_key(translation, book_id, chapter) { return "{0}.{1}.{2}".format(translation, String(book_id), String(chapter)); } /// Saves chapter data to local disk async save_chapter_data(chapter_data, translation, book_id, chapter) { let path = this.get_download_path(); this.plugin.app.vault.adapter.mkdir(path); let file_name = this.make_chapter_file_name(translation, book_id, chapter); let file_path = (0, import_obsidian.normalizePath)( path + "/" + file_name ); if (!await this.plugin.app.vault.adapter.exists(file_path)) { let body = ""; for (const i_ in chapter_data) { const i = Number(i_); body += chapter_data[i]; if (i !== Object.keys(chapter_data).length) { body += "\n"; } } await this.plugin.app.vault.adapter.write( file_path, body ); } } }; var BollsLifeBibleAPI = class extends BibleAPI { constructor() { super(...arguments); this.translations = {}; this.translation_maps = {}; this.cache_clear_timer = null; this.sync_cache = new SyncCache(); } async _get_chapter(translation, book_id, chapter) { try { let verse_data_list = JSON.parse(await httpGet( "https://bolls.life/get-chapter/{0}/{1}/{2}/".format(translation, String(book_id), String(chapter)) )); let texts = {}; for (const data of verse_data_list) { let verse = data["verse"]; texts[verse] = data["text"]; } return texts; } catch (e) { if (e instanceof Error && e.message.startsWith("No book exists by name")) { return []; } throw e; } } async _get_translation(translation) { let verses = JSON.parse( await httpGet( "https://bolls.life/static/translations/{0}.json".format(translation) ) ); let bible = { translation, books: {} }; await new Promise(async (ok, err) => { try { let i = 0; let curr_book_id = -1; let curr_chapter = -1; for (const data of verses) { let verse = data["verse"]; curr_book_id = data["book"]; curr_chapter = data["chapter"]; if (!(curr_book_id in bible.books)) { bible.books[curr_book_id] = []; } if (!(curr_chapter in bible.books[curr_book_id])) { bible.books[curr_book_id][curr_chapter] = {}; } bible.books[curr_book_id][curr_chapter][verse] = data["text"]; i += 1; } ok(null); } catch (e) { err(e); } }).catch((e) => { throw e; }); return bible; } async _get_book_data(translation, book_id) { let books = await this.get_books_data(translation); for (let book of books) { if (book.id == book_id) { return book; } } throw new Error(); } async _get_books_data(translation) { let books = await this.get_translation_map(translation); books.sort(function(x, y) { if (x.id < y.id) { return -1; } if (x.id > y.id) { return 1; } return 0; }); return books; } async _get_default_translation() { return "YLT"; } async _get_translations() { if (Object.keys(this.translations).length === 0) { let list = JSON.parse(await httpGet( "https://bolls.life/static/bolls/app/views/languages.json" )); for (let language of list) { for (let item of language["translations"]) { if (item["short_name"] in this.translations) { throw new Error("Translation already added to map"); } this.translations[item["short_name"]] = { abbreviated_name: item["short_name"], display_name: item["full_name"], language: language["language"] }; } } } return this.translations; } async _get_verse_count(translation) { let json = JSON.parse(await httpGet( "https://bolls.life/get-verse-counts/{0}/".format(translation) )); let counts = new VerseCounts(); counts.books = json; return counts; } async book_to_id(translation, book) { let book_ = book.toLowerCase(); let map = await this.get_translation_map(translation); for (let i in map) { let book_data = map[i]; if (book_ == book_data["name"].toLowerCase()) { return Number(i) + 1; } } throw new Error("No book exists by name {0}.".format(book)); } chapter_key(translation, book_id, chapter) { return "{0}.{1}.{2}".format(translation, String(book_id), String(chapter)); } async generate_translation_map(translation) { let map = await (0, import_obsidian.requestUrl)( "https://bolls.life/get-books/{0}/".format(translation) ).json; let book_data = []; for (let item of map) { let chapter_list = [...Array(item["chapters"]).keys()].map((x) => x + 1); book_data.push(new BookData( item["bookid"], item["name"], chapter_list )); } this.translation_maps[translation] = book_data; } async id_to_book(translation, book_id) { let map = await this.get_translation_map(translation); return map[book_id - 1]["name"]; } async get_translation_map(translation) { if (!(translation in this.translation_maps)) { await this.generate_translation_map(translation); } return this.translation_maps[translation]; } }; var BuilderModal = class extends import_obsidian.Modal { constructor(app, plugin) { super(app); this.plugin = plugin; this.render(); } render() { let containerEl = this.contentEl; new import_obsidian.Setting(containerEl).nameEl.createEl("h1", { text: "Book builder" }); this.renderBibleFolder(new import_obsidian.Setting(containerEl)); new import_obsidian.Setting(containerEl).setName("Translation").setDesc('Builds your Bible according to the layout of this tranlsation. If "Build with dynamic verses" is active, then the text from this version will be built into your Bible.').addDropdown(async (drop) => { drop.addOption(SELECTED_TRANSLATION_OPTION_KEY, SELECTED_TRANSLATION_OPTION.format(this.plugin.settings.reading_translation)); let translations = await this.plugin.bible_api.get_translations(); let translations_list = []; for (const key in translations) { translations_list.push(key); } translations_list = translations_list.sort((a, b) => { if (translations[a].language < translations[b].language) { return -1; } if (translations[a].language > translations[b].language) { return 1; } if (a < b) { return -1; } if (a > b) { return 1; } return 0; }); for (const i in translations_list) { let key = translations_list[i]; drop.addOption( key, translation_to_display_name(translations[key]) ); } drop.onChange(async (value) => { await this.plugin.settings.set_translation(value, this.plugin); await this.plugin.saveSettings(); }); drop.setValue(this.plugin.settings.translation); }); this.renderBuildButton(new import_obsidian.Setting(containerEl)); new import_obsidian.Setting(containerEl).nameEl.createEl("h3", { text: "Chapters" }); this.renderChapterName(new import_obsidian.Setting(containerEl)); this.renderChapterFormat(new import_obsidian.Setting(containerEl)); new import_obsidian.Setting(containerEl).setName("Pad numbers").setDesc('When active, pads chapter numbers with extra zeros. For example, "Psalms 5" becomes "Psalms 005".').addToggle((toggle) => toggle.setTooltip("Toggle alignment padding of chapter numbers").setValue(this.plugin.settings.padded_chapter).onChange(async (value) => { this.plugin.settings.padded_chapter = value; await this.plugin.saveSettings(); })); new import_obsidian.Setting(containerEl).nameEl.createEl("h3", { text: "Verses" }); this.renderVerseFormat(new import_obsidian.Setting(containerEl)); new import_obsidian.Setting(containerEl).setName("Build with dynamic verses").setDesc("When active, your Bible will be built with verse references that can be quickly changed when you switch translations. When inactive, the text of the translation is built directly into your Bible.").addToggle((toggle) => toggle.setTooltip("Toggle generating with dynamic verses").setValue(this.plugin.settings.build_with_dynamic_verses).onChange(async (value) => { this.plugin.settings.build_with_dynamic_verses = value; await this.plugin.saveSettings(); })); let books_header = new import_obsidian.Setting(containerEl); books_header.nameEl.createEl("h3", { text: "Books" }); books_header.addToggle((toggle) => { toggle.setTooltip("Toggle if books should generate folders").setValue(this.plugin.settings.book_folders_enabled).onChange(async (value) => { this.plugin.settings.book_folders_enabled = value; await this.plugin.saveSettings(); }); }); this.renderBookFormat(new import_obsidian.Setting(containerEl)); this.renderNameDelimeter(new import_obsidian.Setting(containerEl)); this.renderBookCapitalization(new import_obsidian.Setting(containerEl)); this.renderBookAbbreviation(new import_obsidian.Setting(containerEl)); this.renderPaddedOrderNums(new import_obsidian.Setting(containerEl)); let index_header = new import_obsidian.Setting(containerEl); let index_name = new import_obsidian.Setting(containerEl); let index_links = new import_obsidian.Setting(containerEl); let index_body = new import_obsidian.Setting(containerEl); index_header.addToggle((toggle) => { toggle.setTooltip("Toggle book index generation").setValue(this.plugin.settings.index_enabled).onChange(async (value) => { this.plugin.settings.index_enabled = value; await this.plugin.saveSettings(); }); }).nameEl.createEl("h3", { text: "Book index" }); this.renderIndexName(index_name); this.renderIndexBookLink(index_links); this.renderIndexBody(index_body); let chapter_index_header = new import_obsidian.Setting(containerEl); let chapter_index_name = new import_obsidian.Setting(containerEl); let chapter_index_links = new import_obsidian.Setting(containerEl); let chapter_index_body = new import_obsidian.Setting(containerEl); chapter_index_header.addToggle((toggle) => { toggle.setTooltip("Toggle chapter index generation").setValue(this.plugin.settings.chapter_index_enabled).onChange(async (value) => { this.plugin.settings.chapter_index_enabled = value; await this.plugin.saveSettings(); }); }).nameEl.createEl("h3", { text: "Chapter indexs" }); this.renderChapterIndexName(chapter_index_name); this.renderChapterIndexLink(chapter_index_links); this.renderChapterIndexBody(chapter_index_body); this.renderBuildButton(new import_obsidian.Setting(containerEl)); } // Top renderers renderBibleFolder(setting) { setting.clear(); setting.setName("Folder").setDesc("The path to the folder where your Bible will be placed. The folder should be empty for your Bible. If the path does not exist it will be created.").addExtraButton( (btn) => btn.setIcon("rotate-ccw").setTooltip("Reset value").onClick(async () => { this.plugin.settings.bible_folder = DEFAULT_SETTINGS.bible_folder; this.renderBibleFolder(setting); await this.plugin.saveSettings(); }) ).addText( (text) => text.setPlaceholder("Example: " + DEFAULT_SETTINGS.bible_folder).setValue(this.plugin.settings.bible_folder).onChange(async (value) => { this.plugin.settings.bible_folder = value; await this.plugin.saveSettings(); }) ); } renderBuildButton(setting) { setting.addButton( (btn) => btn.setButtonText("Build").setTooltip("Build your bible").setCta().onClick(async (_) => { this.close(); await this.plugin.build_bible(); }) ); } // Book renderers renderBookFormat(setting) { setting.clear(); setting.setName("Name format").setDesc('The format for the names of the folders of each book of the bible. For example, "{order} {name}" would become "2 Exodus". Leave blank to not have folders for each book.').addExtraButton( (btn) => btn.setIcon("rotate-ccw").setTooltip("Reset value").onClick(async () => { this.plugin.settings.book_name_format = DEFAULT_SETTINGS.book_name_format; this.renderBookFormat(setting); await this.plugin.saveSettings(); }) ).addText( (text) => text.setPlaceholder("Example: " + DEFAULT_SETTINGS.book_name_format).setValue(this.plugin.settings.book_name_format).onChange(async (value) => { this.plugin.settings.book_name_format = value; await this.plugin.saveSettings(); }) ); } renderBookAbbreviation(setting) { setting.clear(); setting.setName("Abbreviate names").setDesc('When active, The names of books will be abbreviated to three letters. For example, "Genesis" becomes "Gen" and "1 Kings" becomes "1Ki". (May cause issues in some translations.)').addToggle( (toggle) => toggle.setTooltip("Toggle book name abbreviation").setValue(this.plugin.settings.book_name_abbreviated).onChange(async (value) => { this.plugin.settings.book_name_abbreviated = value; await this.plugin.saveSettings(); }) ); } renderBookCapitalization(setting) { setting.clear(); setting.setName("Name capitalization").setDesc("Dictates the capitalization of book names.").addDropdown( (drop) => drop.addOption("lower_case", "Lower case").addOption("name_case", "Name case").addOption("upper_case", "Upper case").setValue(this.plugin.settings.book_name_capitalization).onChange(async (value) => { this.plugin.settings.book_name_capitalization = value; await this.plugin.saveSettings(); }) ); } renderNameDelimeter(setting) { setting.clear(); setting.setName("Name delimiter").setDesc('The characters separating words in book names, such as the spaces in "1 John" or "Song of Solomon".').addExtraButton( (btn) => btn.setIcon("rotate-ccw").setTooltip("Reset value").onClick(async () => { this.plugin.settings.book_name_delimiter = DEFAULT_SETTINGS.book_name_delimiter; this.renderNameDelimeter(setting); await this.plugin.saveSettings(); }) ).addText( (text) => text.setPlaceholder('Example: "' + DEFAULT_SETTINGS.book_name_delimiter + '"').setValue(this.plugin.settings.book_name_delimiter).onChange(async (value) => { this.plugin.settings.book_name_delimiter = value; await this.plugin.saveSettings(); }) ); } renderPaddedOrderNums(setting) { setting.clear(); setting.setName("Pad order numbers").setDesc('When Active, pads order numbers with extra zeros. For example, "1 Genesis" would become "01 Gensis" when active.').addToggle( (toggle) => toggle.setTooltip("Toggle alignment padding of book order numbers").setValue(this.plugin.settings.padded_order).onChange(async (value) => { this.plugin.settings.padded_order = value; await this.plugin.saveSettings(); }) ); } // Chapter renderers renderChapterFormat(setting) { setting.clear(); setting.setName("Body format").setDesc("The format for the contents of chapters.").addExtraButton( (btn) => btn.setIcon("rotate-ccw").setTooltip("Reset value").onClick(async () => { this.plugin.settings.chapter_body_format = DEFAULT_SETTINGS.chapter_body_format; this.renderChapterFormat(setting); await this.plugin.saveSettings(); }) ).addTextArea( (text) => text.setPlaceholder("Example: " + DEFAULT_SETTINGS.chapter_body_format).setValue(this.plugin.settings.chapter_body_format).onChange( async (value) => { this.plugin.settings.chapter_body_format = value; await this.plugin.saveSettings(); } ) ); } renderChapterName(setting) { setting.clear(); setting.setName("Name format").setDesc('The format for the names of chapters. For example, "{book} {chapter}" would become "Psalms 23".').addExtraButton( (btn) => btn.setIcon("rotate-ccw").setTooltip("Reset value").onClick(async () => { this.plugin.settings.chapter_name_format = DEFAULT_SETTINGS.chapter_name_format; this.renderChapterName(setting); await this.plugin.saveSettings(); }) ).addText( (text) => text.setPlaceholder(this.plugin.settings.chapter_name_format).setValue(this.plugin.settings.chapter_name_format).onChange(async (value) => { this.plugin.settings.chapter_name_format = value; await this.plugin.saveSettings(); }) ); } // Verse renders renderVerseFormat(setting) { setting.clear(); setting.setName("Format").setDesc("Formatting for individual verses.").addExtraButton( (btn) => btn.setIcon("rotate-ccw").setTooltip("Reset value").onClick(async () => { this.plugin.settings.verse_body_format = DEFAULT_SETTINGS.verse_body_format; this.renderVerseFormat(setting); await this.plugin.saveSettings(); }) ).addTextArea( (text) => text.setPlaceholder("Example: " + DEFAULT_SETTINGS.verse_body_format).setValue(this.plugin.settings.verse_body_format).onChange(async (value) => { this.plugin.settings.verse_body_format = value; await this.plugin.saveSettings(); }) ); } // Book index renderIndexName(setting) { setting.clear(); setting.setName("Name format").setDesc("The format for the name of the book index.").addExtraButton( (btn) => btn.setIcon("rotate-ccw").setTooltip("Reset value").onClick(async () => { this.plugin.settings.index_name_format = DEFAULT_SETTINGS.index_name_format; this.renderIndexName(setting); await this.plugin.saveSettings(); }) ).addText( (text) => text.setPlaceholder(DEFAULT_SETTINGS.index_name_format).setValue(this.plugin.settings.index_name_format).onChange(async (value) => { this.plugin.settings.index_name_format = value; await this.plugin.saveSettings(); }) ); } renderIndexBookLink(setting) { setting.clear(); setting.setName("Book element format").setDesc("The format for each book element in a list.").addExtraButton( (btn) => btn.setIcon("rotate-ccw").setTooltip("Reset value").onClick(async () => { this.plugin.settings.index_link_format = DEFAULT_SETTINGS.index_link_format; this.renderIndexBookLink(setting); await this.plugin.saveSettings(); }) ).addText( (text) => text.setPlaceholder(DEFAULT_SETTINGS.index_link_format).setValue(this.plugin.settings.index_link_format).onChange(async (value) => { this.plugin.settings.index_link_format = value; await this.plugin.saveSettings(); }) ); setting.setDisabled(!this.plugin.settings.index_enabled); } renderIndexBody(setting) { setting.clear(); setting.setName("Body format").setDesc("The format for the content of the book index.").addExtraButton( (btn) => btn.setIcon("rotate-ccw").setTooltip("Reset value").onClick(async () => { this.plugin.settings.index_format = DEFAULT_SETTINGS.index_format; this.renderIndexBody(setting); await this.plugin.saveSettings(); }) ).addTextArea( (text) => text.setPlaceholder(DEFAULT_SETTINGS.index_format).setValue(this.plugin.settings.index_format).onChange(async (value) => { this.plugin.settings.index_format = value; await this.plugin.saveSettings(); }) ); setting.setDisabled(!this.plugin.settings.index_enabled); } // Chapter index renderChapterIndexName(setting) { setting.clear(); setting.setName("Name format").setDesc("The format for the name of the chapter index.").addExtraButton( (btn) => btn.setIcon("rotate-ccw").setTooltip("Reset value").onClick(async () => { this.plugin.settings.chapter_index_name_format = DEFAULT_SETTINGS.chapter_index_name_format; this.renderChapterIndexName(setting); await this.plugin.saveSettings(); }) ).addText( (text) => text.setPlaceholder(DEFAULT_SETTINGS.chapter_index_name_format).setValue(this.plugin.settings.chapter_index_name_format).onChange(async (value) => { this.plugin.settings.chapter_index_name_format = value; await this.plugin.saveSettings(); }) ); setting.setDisabled(!this.plugin.settings.index_enabled); } renderChapterIndexLink(setting) { setting.clear(); setting.setName("Chapter element format").setDesc("The format for each chapter element in a list.").addExtraButton( (btn) => btn.setIcon("rotate-ccw").setTooltip("Reset value").onClick(async () => { this.plugin.settings.chapter_index_link_format = DEFAULT_SETTINGS.chapter_index_link_format; this.renderChapterIndexLink(setting); await this.plugin.saveSettings(); }) ).addText( (text) => text.setPlaceholder(DEFAULT_SETTINGS.chapter_index_link_format).setValue(this.plugin.settings.chapter_index_link_format).onChange(async (value) => { this.plugin.settings.chapter_index_link_format = value; await this.plugin.saveSettings(); }) ); setting.setDisabled(!this.plugin.settings.index_enabled); } renderChapterIndexBody(setting) { setting.clear(); setting.setName("Chapter format").setDesc("The format for the content of the chapter index.").addExtraButton( (btn) => btn.setIcon("rotate-ccw").setTooltip("Reset value").onClick(async () => { this.plugin.settings.chapter_index_format = DEFAULT_SETTINGS.chapter_index_format; this.renderChapterIndexBody(setting); await this.plugin.saveSettings(); }) ).addTextArea( (text) => text.setPlaceholder(DEFAULT_SETTINGS.chapter_index_format).setValue(this.plugin.settings.chapter_index_format).onChange(async (value) => { this.plugin.settings.chapter_index_format = value; await this.plugin.saveSettings(); }) ); setting.setDisabled(!this.plugin.settings.index_enabled); } refresh() { this.contentEl.empty(); this.render(); } }; var ErrorModal = class extends import_obsidian.Modal { constructor(app, plugin, title, body) { super(app); this.plugin = plugin; this.title = title; this.body = body; } onOpen() { const { contentEl } = this; contentEl.createEl("h1", { text: this.title }); contentEl.createEl("span", { text: this.body }); contentEl.createEl("p", {}); new import_obsidian.Setting(contentEl).addButton( (btn) => btn.setButtonText("Close").onClick(() => { this.close(); }) ); } onClose() { const { contentEl } = this; contentEl.empty(); } }; var ClearLocalFilesModal = class extends import_obsidian.Modal { constructor(app, plugin) { super(app); this.plugin = plugin; } onOpen() { const { contentEl } = this; let bible_path = this.plugin.settings.bible_folder; contentEl.createEl("h1", { text: "Clear local files?" }); contentEl.createEl("span", { text: "You are about to clear out all files added by My Bible from your file system. This includes temporay cached chapters and translations you manually downloaded.".format(bible_path) }); contentEl.createEl("p", { text: "Do you want to clear these files?" }); contentEl.createEl("p", {}); new import_obsidian.Setting(contentEl).addButton( (btn) => btn.setButtonText("Cancel").onClick(() => { this.close(); }) ).addButton( (btn) => btn.setButtonText("Clear files").setCta().onClick(async () => { this.close(); await this.plugin.bible_api.clear_local_files(); new import_obsidian.Notice("Files cleared!"); }) ); } onClose() { const { contentEl } = this; contentEl.empty(); } }; var ClearOldBibleFilesModal = class extends import_obsidian.Modal { constructor(app, plugin) { super(app); this.plugin = plugin; } onOpen() { const { contentEl } = this; let bible_path = this.plugin.settings.bible_folder; contentEl.createEl("h1", { text: "Bible folder is not empty" }); contentEl.createEl("span", { text: "The Bible folder in your settings is not empty. If you built a Bible in this folder before the new bible may be interlaced with the old one.".format(bible_path) }); contentEl.createEl("p", { text: "Do you want to clear the folder before building your Bible?" }); contentEl.createEl("p", {}); new import_obsidian.Setting(contentEl).addButton( (btn) => btn.setButtonText("Cancel").onClick(() => { this.close(); }) ).addButton( (btn) => btn.setButtonText("Build without clearing").setCta().onClick(async () => { this.close(); await this.plugin._build_bible(bible_path); }) ).addButton( (btn) => btn.setButtonText("Clear and build").setCta().onClick(async () => { this.close(); let notice = new import_obsidian.Notice("Clearing bible folder...", 0); let abstract = this.app.vault.getAbstractFileByPath( (0, import_obsidian.normalizePath)(bible_path) ); if (abstract != null) { await this.app.vault.delete(abstract, true); } this.app.vault.adapter.mkdir((0, import_obsidian.normalizePath)(bible_path)); notice.hide(); await this.plugin._build_bible(bible_path); }) ); } onClose() { const { contentEl } = this; contentEl.empty(); } }; var QuickChangeTranslationeModal = class extends import_obsidian.FuzzySuggestModal { constructor(plugin) { super(plugin.app); this.plugin = plugin; } // Returns all available suggestions. getItems() { let translations_list = Object.keys(this.translations).map((k) => this.translations[k]); return translations_list; } getItemText(item) { return translation_to_display_name(item); } // Perform action on the selected suggestion. onChooseItem(item, evt) { if (this.onChose !== null) { this.onChose(item); } } }; var SettingsTab = class extends import_obsidian.PluginSettingTab { constructor(app, plugin) { super(app, plugin); this.plugin = plugin; } display() { const { containerEl } = this; containerEl.empty(); new import_obsidian.Setting(containerEl).setName("Translation").setDesc("The version of the Bible that will be displayed in dynamic verses.").addDropdown(async (drop) => { let translations = await this.plugin.bible_api.get_translations(); let translations_list = []; for (const key in translations) { translations_list.push(key); } translations_list = translations_list.sort((a, b) => { if (translations[a].language < translations[b].language) { return -1; } if (translations[a].language > translations[b].language) { return 1; } if (a < b) { return -1; } if (a > b) { return 1; } return 0; }); for (const i in translations_list) { let key = translations_list[i]; drop.addOption( key, "{0} - {1} - {2}".format( translations[key].language, key, translations[key].display_name ) ); } drop.onChange(async (value) => { this.plugin.settings.reading_translation = value; await this.plugin.saveSettings(); }); drop.setValue(this.plugin.settings.reading_translation); }); } }; var DEFAULT_NAME_MAP = { "Genesis": 1, "Exodus": 2, "Leviticus": 3, "Numbers": 4, "Deuteronomy": 5, "Joshua": 6, "Judges": 7, "Ruth": 8, "1 Samuel": 9, "2 Samuel": 10, "1 Kings": 11, "2 Kings": 12, "1 Chronicles": 13, "2 Chronicles": 14, "Ezra": 15, "Nehemiah": 16, "Esther": 17, "Job": 18, "Psalms": 19, "Psalm": 19, // Alternate spelling "Proverbs": 20, "Ecclesiastes": 21, "Song of Solomon": 22, "Isaiah": 23, "Jeremiah": 24, "Lamentations": 25, "Ezekiel": 26, "Daniel": 27, "Hosea": 28, "Joel": 29, "Amos": 30, "Obadiah": 31, "Jonah": 32, "Micah": 33, "Nahum": 34, "Habakkuk": 35, "Zephaniah": 36, "Haggai": 37, "Zechariah": 38, "Malachi": 39, "Matthew": 40, "Mark": 41, "Luke": 42, "John": 43, "Acts": 44, "Romans": 45, "1 Corinthians": 46, "2 Corinthians": 47, "Galatians": 48, "Ephesians": 49, "Philippians": 50, "Colossians": 51, "1 Thessalonians": 52, "2 Thessalonians": 53, "1 Timothy": 54, "2 Timothy": 55, "Titus": 56, "Philemon": 57, "Hebrews": 58, "James": 59, "1 Peter": 60, "2 Peter": 61, "1 John": 62, "2 John": 63, "3 John": 64, "Jude": 65, "Revelation": 66, "1 Esdras": 67, "Tobit": 68, "Judith": 69, "Wisdom": 70, "Sirach": 71, "Epistle of Jeremiah": 72, "Baruch": 73, "1 Maccabees": 74, "2 Maccabees": 75, "3 Maccabees": 76, "2 Esdras": 77, "Susanna": 78, "Bel and Dragon": 79, "4 Maccabees": 80, "Greek Additions to Esther": 81, "3 Holy Children's Song": 82, "Prayer of Manasseh": 83, "Azariah": 88 // Jump in number }; //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibWFpbi50cyIsICJub2RlX21vZHVsZXMvYXN5bmMtbXV0ZXgvaW5kZXgubWpzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQge1xuXHRBcHAsXG5cdE1vZGFsLFxuXHROb3RpY2UsXG5cdFBsdWdpbixcblx0UGx1Z2luU2V0dGluZ1RhYixcblx0U2V0dGluZyxcblx0RnV6enlTdWdnZXN0TW9kYWwsXG5cdFRGaWxlLFxuXHRURm9sZGVyLFxuXHRub3JtYWxpemVQYXRoLFxuXHRyZXF1ZXN0VXJsLFxufSBmcm9tICdvYnNpZGlhbic7XG5cbmltcG9ydCB7IEVfQ0FOQ0VMRUQsIE11dGV4IH0gZnJvbSAnYXN5bmMtbXV0ZXgnO1xuXG5jb25zdCBCVUlMRF9FTkRfVE9BU1QgPSBcIkJpYmxlIGJ1aWxkIGZpbmlzaGVkIVwiO1xuY29uc3QgU0VMRUNURURfVFJBTlNMQVRJT05fT1BUSU9OID0gXCI8U2VsZWN0ZWQgcmVhZGluZyB0cmFuc2xhdGlvbiwgezB9PlwiXG5jb25zdCBTRUxFQ1RFRF9UUkFOU0xBVElPTl9PUFRJT05fS0VZID0gXCJkZWZhdWx0XCJcblxuLy8gUmVtZW1iZXIgdG8gcmVuYW1lIHRoZXNlIGNsYXNzZXMgYW5kIGludGVyZmFjZXMhXG5cbmNsYXNzIE15QmlibGVTZXR0aW5ncyB7XG5cdHRyYW5zbGF0aW9uOiBzdHJpbmc7XG5cdHJlYWRpbmdfdHJhbnNsYXRpb246IHN0cmluZ1xuXHRiaWJsZV9mb2xkZXI6IHN0cmluZztcblxuXHRzdG9yZV9sb2NhbGx5OiBib29sZWFuO1xuXG5cdHBhZGRlZF9vcmRlcjogYm9vbGVhbjtcblx0Ym9va19mb2xkZXJzX2VuYWJsZWQ6IGJvb2xlYW47XG5cdGJvb2tfbmFtZV9mb3JtYXQ6IHN0cmluZztcblx0Ym9va19uYW1lX2RlbGltaXRlcjogc3RyaW5nO1xuXHRib29rX25hbWVfY2FwaXRhbGl6YXRpb246IHN0cmluZztcblx0Ym9va19uYW1lX2FiYnJldmlhdGVkOiBib29sZWFuO1xuXG5cdHBhZGRlZF9jaGFwdGVyOiBib29sZWFuO1xuXHRjaGFwdGVyX25hbWVfZm9ybWF0OiBzdHJpbmc7XG5cdGNoYXB0ZXJfYm9keV9mb3JtYXQ6IHN0cmluZztcblxuXHRidWlsZF93aXRoX2R5bmFtaWNfdmVyc2VzOiBib29sZWFuO1xuXHR2ZXJzZV9ib2R5X2Zvcm1hdDogc3RyaW5nO1xuXG5cdGluZGV4X2VuYWJsZWQ6IGJvb2xlYW5cblx0aW5kZXhfbmFtZV9mb3JtYXQ6IHN0cmluZ1xuXHRpbmRleF9mb3JtYXQ6IHN0cmluZ1xuXHRpbmRleF9saW5rX2Zvcm1hdDogc3RyaW5nXG5cblx0Y2hhcHRlcl9pbmRleF9lbmFibGVkOiBib29sZWFuXG5cdGNoYXB0ZXJfaW5kZXhfbmFtZV9mb3JtYXQ6IHN0cmluZ1xuXHRjaGFwdGVyX2luZGV4X2Zvcm1hdDogc3RyaW5nXG5cdGNoYXB0ZXJfaW5kZXhfbGlua19mb3JtYXQ6IHN0cmluZ1xuXG5cdF9idWlsdF90cmFuc2xhdGlvbjogc3RyaW5nO1xuXG5cdGFzeW5jIHNldF90cmFuc2xhdGlvbih2YWw6IHN0cmluZywgcGx1Z2luOiBNeUJpYmxlKSB7XG5cdFx0dGhyb3cgXCJVbmltcGxlbWVudGVkXCJcblx0fVxufVxuXG5jb25zdCBERUZBVUxUX1NFVFRJTkdTOiBNeUJpYmxlU2V0dGluZ3MgPSB7XG5cdHRyYW5zbGF0aW9uOiBTRUxFQ1RFRF9UUkFOU0xBVElPTl9PUFRJT05fS0VZLFxuXHRyZWFkaW5nX3RyYW5zbGF0aW9uOiBcIldFQlwiLFxuXHRiaWJsZV9mb2xkZXI6IFwiL015IEJpYmxlL1wiLFxuXHRib29rX2ZvbGRlcnNfZW5hYmxlZDogdHJ1ZSxcblx0Ym9va19uYW1lX2Zvcm1hdDogXCJ7b3JkZXJ9IHtib29rfVwiLFxuXHRib29rX25hbWVfZGVsaW1pdGVyOiBcIiBcIixcblx0Y2hhcHRlcl9uYW1lX2Zvcm1hdDogXCJ7Ym9va30ge2NoYXB0ZXJ9XCIsXG5cdGJvb2tfbmFtZV9jYXBpdGFsaXphdGlvbjogXCJuYW1lX2Nhc2VcIixcblx0Ym9va19uYW1lX2FiYnJldmlhdGVkOiBmYWxzZSxcblx0cGFkZGVkX29yZGVyOiB0cnVlLFxuXHRwYWRkZWRfY2hhcHRlcjogZmFsc2UsXG5cdGJ1aWxkX3dpdGhfZHluYW1pY192ZXJzZXM6IHRydWUsXG5cdHZlcnNlX2JvZHlfZm9ybWF0OiBcIiMjIyMjIyB7dmVyc2V9XFxuXCJcblx0XHQrIFwie3ZlcnNlX3RleHR9XCJcblx0LFxuXHRjaGFwdGVyX2JvZHlfZm9ybWF0OiBcIlxcblwiXG5cdFx0KyBcIiMjIyMjIyBOYXZpZ2F0aW9uXFxuXCJcblx0XHQrIFwiKipbW3tsYXN0X2NoYXB0ZXJfbmFtZX18XHUyM0VBIHtsYXN0X2NoYXB0ZXJfbmFtZX1dXSB8IFtbe2NoYXB0ZXJfaW5kZXh9fENoYXB0ZXJzXV0gfCBbW3tuZXh0X2NoYXB0ZXJfbmFtZX18e25leHRfY2hhcHRlcl9uYW1lfSBcdTIzRTldXSoqXFxuXCJcblx0XHQrIFwiKipbW3tmaXJzdF9jaGFwdGVyX25hbWV9fEZpcnN0ICh7Zmlyc3RfY2hhcHRlcn0pXV0gfCBbW3tmaW5hbF9jaGFwdGVyX25hbWV9fExhc3QgKHtmaW5hbF9jaGFwdGVyfSldXSoqXFxuXCJcblx0XHQrIFwiXFxuXCJcblx0XHQrIFwie3ZlcnNlc31cXG5cIlxuXHRcdCsgXCJcXG5cIlxuXHRcdCsgXCIjIyMjIyMgTmF2aWdhdGlvblxcblwiXG5cdFx0KyBcIioqW1t7bGFzdF9jaGFwdGVyX25hbWV9fFx1MjNFQSB7bGFzdF9jaGFwdGVyX25hbWV9XV0gfCBbW3tjaGFwdGVyX2luZGV4fXxDaGFwdGVyc11dIHwgW1t7bmV4dF9jaGFwdGVyX25hbWV9fHtuZXh0X2NoYXB0ZXJfbmFtZX0gXHUyM0U5XV0qKlxcblwiXG5cdFx0KyBcIioqW1t7Zmlyc3RfY2hhcHRlcl9uYW1lfXxGaXJzdCAoe2ZpcnN0X2NoYXB0ZXJ9KV1dIHwgW1t7ZmluYWxfY2hhcHRlcl9uYW1lfXxMYXN0ICh7ZmluYWxfY2hhcHRlcn0pXV0qKlxcblwiXG5cdFx0KyBcIlxcblwiXG5cdCxcblx0aW5kZXhfZW5hYmxlZDogdHJ1ZSxcblx0aW5kZXhfbmFtZV9mb3JtYXQ6IFwiLS0gQmlibGUgLS1cIixcblx0aW5kZXhfbGlua19mb3JtYXQ6IFwiLSBbW3tib29rX2luZGV4fXx7Ym9va31dXVwiLFxuXHRpbmRleF9mb3JtYXQ6IFwiXCJcblx0XHQrIFwiIyMjIE9sZCB0ZXN0YW1lbnRcXG5cIlxuXHRcdCsgXCJ7b2xkX3Rlc3RhbWVudH1cXG5cIlxuXHRcdCsgXCIjIyMgTmV3IHRlc3RhbWVudFxcblwiXG5cdFx0KyBcIntuZXdfdGVzdGFtZW50fVxcblwiXG5cdFx0KyBcIiMjIyBBcG9jcnlwaGFcXG5cIlxuXHRcdCsgXCJ7YXBvY3J5cGhhfVwiXG5cdCxcblx0Y2hhcHRlcl9pbmRleF9lbmFibGVkOiB0cnVlLFxuXHRjaGFwdGVyX2luZGV4X25hbWVfZm9ybWF0OiBcIi0tIHtib29rfSAtLVwiLFxuXHRjaGFwdGVyX2luZGV4X2xpbmtfZm9ybWF0OiBcIi0gW1t7Y2hhcHRlcl9uYW1lfXx7Y2hhcHRlcn1dXVwiLFxuXHRjaGFwdGVyX2luZGV4X2Zvcm1hdDogXCJcIlxuXHRcdCsgXCIjIyMjIyMgTmF2aWdhdGlvblxcblwiXG5cdFx0KyBcIipbW3tpbmRleH18Qm9va3NdXSpcXG5cIlxuXHRcdCsgXCJcXG5cIlxuXHRcdCsgXCIjIyMgQ2hhcHRlcnNcXG5cIlxuXHRcdCsgXCJ7Y2hhcHRlcnN9XFxuXCJcblx0LFxuXHRzdG9yZV9sb2NhbGx5OiBmYWxzZSxcblxuXHRfYnVpbHRfdHJhbnNsYXRpb246IFwiXCIsXG5cblx0c2V0X3RyYW5zbGF0aW9uOiBhc3luYyBmdW5jdGlvbiAodmFsOiBzdHJpbmcsIHBsdWdpbjogTXlCaWJsZSk6IFByb21pc2U8dm9pZD4ge1xuXHRcdGlmICh2YWwgPT09IFNFTEVDVEVEX1RSQU5TTEFUSU9OX09QVElPTl9LRVkpIHtcblx0XHRcdHRoaXMudHJhbnNsYXRpb24gPSB2YWxcblx0XHRcdHJldHVyblxuXHRcdH1cblxuXHRcdGxldCBoYXNfdHJhbnNsYXRpb24gPSBmYWxzZTtcblx0XHRsZXQgdHJhbnNsYXRpb25zID0gKGF3YWl0IHBsdWdpbi5iaWJsZV9hcGkuZ2V0X3RyYW5zbGF0aW9ucygpKTtcblx0XHRpZiAoISh2YWwgaW4gdHJhbnNsYXRpb25zKSkge1xuXHRcdFx0dGhpcy50cmFuc2xhdGlvbiA9IGF3YWl0IHBsdWdpbi5iaWJsZV9hcGkuZ2V0X2RlZmF1bHRfdHJhbnNsYXRpb24oKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy50cmFuc2xhdGlvbiA9IHZhbDtcblx0XHR9XG5cdH1cbn1cblxuZnVuY3Rpb24gaHR0cEdldCh0aGVVcmw6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG5cdHJldHVybiBuZXcgUHJvbWlzZShhc3luYyAob2ssIGVycikgPT4ge1xuXHRcdG9rKGF3YWl0IHJlcXVlc3RVcmwodGhlVXJsKS50ZXh0KTtcblx0fSk7XG59XG5cbmZ1bmN0aW9uIGlzX2FscGhhKHN0cmluZzogc3RyaW5nKTogYm9vbGVhbiB7XG5cdGZvciAobGV0IGNoYXJfc3RyIG9mIHN0cmluZykge1xuXHRcdGxldCBjaGFyID0gY2hhcl9zdHIuY2hhckNvZGVBdCgwKTtcblx0XHRpZiAoKGNoYXIgPiA2NCAmJiBjaGFyIDwgOTEpIHx8IChjaGFyID4gOTYgJiYgY2hhciA8IDEyMykgfHwgKGNoYXIgPiAzOSAmJiBjaGFyIDwgNDIpKSB7XG5cdFx0XHQvLyBDaGFyYWN0ZXIgaXMgYSBjYXBpdGFsIG9yIGxvd2VyY2FzZSBsZXR0ZXIsIGNvbnRpbnVlXG5cdFx0XHRjb250aW51ZTtcblx0XHR9XG5cdFx0Ly8gQ2hhcmFjdGVyIGlzIG5vdCBhIGNhcGl0YWwgb3IgbG93ZXJjYXNlIGxldHRlciwgcmV0dXJuIGZhbHNlXG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdC8vIEFsbCBjaGFyYWN0ZXJzIHdlcmUgdXBwZXJjYXNlIG9yIGxvd2VyY2FzZSBsZXR0ZXJzLCByZXR1cm4gdHJ1ZVxuXHRyZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gaXNfYWxwaGFudW1lcmljKHN0cmluZzogc3RyaW5nKTogYm9vbGVhbiB7XG5cdGZvciAobGV0IGNoYXJfc3RyIG9mIHN0cmluZykge1xuXHRcdGxldCBjaGFyID0gY2hhcl9zdHIuY2hhckNvZGVBdCgwKTtcblx0XHRpZiAoKGNoYXIgPiA2NCAmJiBjaGFyIDwgOTEpIHx8IChjaGFyID4gOTYgJiYgY2hhciA8IDEyMykgfHwgKGNoYXIgPiA0NyAmJiBjaGFyIDwgNTgpKSB7XG5cdFx0XHQvLyBDaGFyYWN0ZXIgaXMgYSBjYXBpdGFsIG9yIGxvd2VyY2FzZSBsZXR0ZXIsIGNvbnRpbnVlXG5cdFx0XHRjb250aW51ZTtcblx0XHR9XG5cdFx0Ly8gQ2hhcmFjdGVyIGlzIG5vdCBhIGNhcGl0YWwgb3IgbG93ZXJjYXNlIGxldHRlciwgcmV0dXJuIGZhbHNlXG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdC8vIEFsbCBjaGFyYWN0ZXJzIHdlcmUgdXBwZXJjYXNlIG9yIGxvd2VyY2FzZSBsZXR0ZXJzLCByZXR1cm4gdHJ1ZVxuXHRyZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gaXNfbnVtZXJpYyhzdHJpbmc6IHN0cmluZyk6IGJvb2xlYW4ge1xuXHRmb3IgKGxldCBjaGFyX3N0ciBvZiBzdHJpbmcpIHtcblx0XHRsZXQgY2hhciA9IGNoYXJfc3RyLmNoYXJDb2RlQXQoMCk7XG5cdFx0aWYgKGNoYXIgPiA0NyAmJiBjaGFyIDwgNTgpIHtcblx0XHRcdC8vIENoYXJhY3RlciBpcyBhIG51bWJlciwgY29udGludWVcblx0XHRcdGNvbnRpbnVlO1xuXHRcdH1cblx0XHQvLyBDaGFyYWN0ZXIgaXMgbm90IG51bWJlciwgcmV0dXJuIGZhbHNlXG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdC8vIEFsbCBjaGFyYWN0ZXJzIHdlcmUgbnVtYmVycywgcmV0dXJuIHRydWVcblx0cmV0dXJuIHRydWU7XG59XG5cblxuYXN5bmMgZnVuY3Rpb24gc2F2ZV9maWxlKHBhdGg6IHN0cmluZywgY29udGVudDogc3RyaW5nKSB7XG5cdGxldCBmaWxlX3BhdGggPSBub3JtYWxpemVQYXRoKHBhdGgpO1xuXHRsZXQgZmlsZSA9IHRoaXMuYXBwLnZhdWx0LmdldEFic3RyYWN0RmlsZUJ5UGF0aChmaWxlX3BhdGgpXG5cdGlmIChmaWxlIGluc3RhbmNlb2YgVEZpbGUpIHtcblx0XHRhd2FpdCB0aGlzLmFwcC52YXVsdC5tb2RpZnkoZmlsZSwgY29udGVudClcblx0fSBlbHNlIGlmIChmaWxlID09PSBudWxsKSB7XG5cdFx0YXdhaXQgdGhpcy5hcHAudmF1bHQuY3JlYXRlKFxuXHRcdFx0ZmlsZV9wYXRoLFxuXHRcdFx0Y29udGVudCxcblx0XHQpXG5cdH1cbn1cblxuZnVuY3Rpb24gdHJhbnNsYXRpb25fdG9fZGlzcGxheV9uYW1lKHRyYW5zbGF0aW9uOlRyYW5zbGF0aW9uKTpzdHJpbmcge1xuXHRyZXR1cm4gXCJ7MH0gLSB7MX0gLSB7Mn1cIlxuXHRcdC5mb3JtYXQodHJhbnNsYXRpb24ubGFuZ3VhZ2UsIHRyYW5zbGF0aW9uLmFiYnJldmlhdGVkX25hbWUsIHRyYW5zbGF0aW9uLmRpc3BsYXlfbmFtZSlcblx0O1xufVxuXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE15QmlibGUgZXh0ZW5kcyBQbHVnaW4ge1xuXHRiaWJsZV9hcGk6IEJpYmxlQVBJXG5cdHNldHRpbmdzOiBNeUJpYmxlU2V0dGluZ3Ncblx0cHJvZ3Jlc3Nfbm90aWNlOiBOb3RpY2UgfCBudWxsXG5cblx0YXN5bmMgb25sb2FkKCkge1xuXHRcdGF3YWl0IHRoaXMubG9hZFNldHRpbmdzKCk7XG5cblx0XHR0aGlzLmJpYmxlX2FwaSA9IG5ldyBCb2xsc0xpZmVCaWJsZUFQSSgpO1xuXHRcdHRoaXMuYmlibGVfYXBpLnBsdWdpbiA9IHRoaXM7XG5cblx0XHRhd2FpdCB0aGlzLnNldHRpbmdzLnNldF90cmFuc2xhdGlvbih0aGlzLnNldHRpbmdzLnRyYW5zbGF0aW9uLCB0aGlzKTtcblxuXHRcdC8vIFRoaXMgYWRkcyBhIHNpbXBsZSBjb21tYW5kIHRoYXQgY2FuIGJlIHRyaWdnZXJlZCBhbnl3aGVyZVxuXHRcdHRoaXMuYWRkQ29tbWFuZCh7XG5cdFx0XHRpZDogJ2NyZWF0ZV9iaWJsZV9maWxlcycsXG5cdFx0XHRuYW1lOiAnQnVpbGQgQmlibGUnLFxuXHRcdFx0Y2FsbGJhY2s6IGFzeW5jICgpID0+IHtcblx0XHRcdFx0bmV3IEJ1aWxkZXJNb2RhbCh0aGlzLmFwcCwgdGhpcykub3BlbigpXG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHR0aGlzLmFkZENvbW1hbmQoe1xuXHRcdFx0aWQ6ICdxdWlja19jaGFuZ2VfdHJhbnNsYXRpb24nLFxuXHRcdFx0bmFtZTogJ0NoYW5nZSB0cmFuc2xhdGlvbicsXG5cdFx0XHRjYWxsYmFjazogYXN5bmMgKCkgPT4ge1xuXHRcdFx0XHRsZXQgbW9kYWwgPSBuZXcgUXVpY2tDaGFuZ2VUcmFuc2xhdGlvbmVNb2RhbCh0aGlzKVxuXHRcdFx0XHRtb2RhbC50cmFuc2xhdGlvbnMgPSBhd2FpdCB0aGlzLmJpYmxlX2FwaS5nZXRfdHJhbnNsYXRpb25zKClcblx0XHRcdFx0bW9kYWwub25DaG9zZSA9IHRyYW5zbGF0aW9uID0+IHtcblx0XHRcdFx0XHR0aGlzLnNldHRpbmdzLnJlYWRpbmdfdHJhbnNsYXRpb24gPSB0cmFuc2xhdGlvbi5hYmJyZXZpYXRlZF9uYW1lXG5cdFx0XHRcdH1cblx0XHRcdFx0bW9kYWwub3BlbigpXG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHR0aGlzLmFkZENvbW1hbmQoe1xuXHRcdFx0aWQ6ICdjbGVhcl9jYWNoZScsXG5cdFx0XHRuYW1lOiAnQ2xlYXIgbG9jYWwgZmlsZXMnLFxuXHRcdFx0Y2FsbGJhY2s6IGFzeW5jICgpID0+IHtcblx0XHRcdFx0bmV3IENsZWFyTG9jYWxGaWxlc01vZGFsKHRoaXMuYXBwLCB0aGlzKS5vcGVuKCk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHR0aGlzLmFkZENvbW1hbmQoe1xuXHRcdFx0aWQ6ICdkb3dubG9hZF9iaWJsZScsXG5cdFx0XHRuYW1lOiAnRG93bmxvYWQgdHJhbnNsYXRpb24nLFxuXHRcdFx0Y2FsbGJhY2s6IGFzeW5jICgpID0+IHtcblx0XHRcdFx0bGV0IG1vZGFsID0gbmV3IFF1aWNrQ2hhbmdlVHJhbnNsYXRpb25lTW9kYWwodGhpcylcblx0XHRcdFx0bW9kYWwudHJhbnNsYXRpb25zID0gYXdhaXQgdGhpcy5iaWJsZV9hcGkuZ2V0X3RyYW5zbGF0aW9ucygpXG5cdFx0XHRcdG1vZGFsLm9uQ2hvc2UgPSBhc3luYyB0cmFuc2xhdGlvbiA9PiB7XG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5iaWJsZV9hcGkudXNlcl9kb3dubG9hZF90cmFuc2xhdGlvbihcblx0XHRcdFx0XHRcdHRyYW5zbGF0aW9uLmFiYnJldmlhdGVkX25hbWVcblx0XHRcdFx0XHQpXG5cdFx0XHRcdH1cblx0XHRcdFx0bW9kYWwub3BlbigpXG5cdFx0XHRcdFxuXHRcdFx0fVxuXHRcdH0pO1xuXG5cdFx0dGhpcy5yZWdpc3Rlck1hcmtkb3duQ29kZUJsb2NrUHJvY2Vzc29yKFwidmVyc2VcIiwgYXN5bmMgKHNvdXJjZSwgZWxlbWVudCwgY29udGV4dCkgPT4ge1xuXHRcdFx0Y29uc3QgcmVmID0gc291cmNlLnRyaW0oKS5yZXBsYWNlKC9bOi1dL2csIFwiIFwiKS5zcGxpdChcIiBcIik7XG5cblx0XHRcdGxldCBib29rOnN0cmluZ3xudWxsID0gbnVsbDtcblx0XHRcdGxldCBib29rX2lkID0gLTE7XG5cdFx0XHRsZXQgY2hhcHRlciA9IC0xO1xuXHRcdFx0bGV0IHZlcnNlID0gLTE7XG5cdFx0XHRsZXQgdmVyc2VfZW5kID0gLTE7XG5cdFx0XHRsZXQgbWF5YmVfdHJhbnNsYXRpb246IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXHRcdFx0bGV0IGkgPSAwO1xuXG5cdFx0XHR3aGlsZSAoaSAhPSByZWYubGVuZ3RoKSB7XG5cdFx0XHRcdC8vIENvbXBvc2UgYm9vayBuYW1lXG5cdFx0XHRcdGlmIChpID09IDApIHtcblx0XHRcdFx0XHQvLyBBbHdheXMgYWRkIGZpcnN0IGl0ZW0sIG5vIG1hdHRlciB3aGF0IGl0IGlzXG5cdFx0XHRcdFx0Ym9vayA9IChib29rIHx8IFwiXCIpICsgcmVmW2ldO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdC8vIE9ubHkgYWRkIGl0ZW1zIHRoYXQgYXJlIHdvcmRzLCBhbmQgbm90IG51bWJlcnNcblx0XHRcdFx0XHRpZiAoIWlzX2FscGhhKHJlZltpXSkpIHtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRib29rICs9IFwiIFwiICsgcmVmW2ldXG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpICs9IDE7XG5cdFx0XHR9XG5cdFx0XHRpZiAoaXNfbnVtZXJpYyhib29rIHx8IFwiXCIpKSB7XG5cdFx0XHRcdC8vIENvbXBvc2UgYm9va19pZFxuXHRcdFx0XHRib29rX2lkID0gTnVtYmVyKGJvb2spO1xuXHRcdFx0XHRib29rID0gbnVsbDtcblx0XHRcdH1cblxuXHRcdFx0aWYgKGkgIT0gcmVmLmxlbmd0aCAmJiBpc19udW1lcmljKHJlZltpXSkpIHtcblx0XHRcdFx0Ly8gQ29tcG9zZSBjaGFwdGVyXG5cdFx0XHRcdGNoYXB0ZXIgPSBOdW1iZXIocmVmW2ldKTtcblx0XHRcdFx0aSArPSAxO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoaSAhPSByZWYubGVuZ3RoICYmIGlzX251bWVyaWMocmVmW2ldKSkge1xuXHRcdFx0XHQvLyBDb21wb3NlIHZlcnNlXG5cdFx0XHRcdHZlcnNlID0gTnVtYmVyKHJlZltpXSk7XG5cdFx0XHRcdGkgKz0gMTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKGkgIT0gcmVmLmxlbmd0aCAmJiBpc19udW1lcmljKHJlZltpXSkpIHtcblx0XHRcdFx0Ly8gQ29tcG9zZSByYW5nZVxuXHRcdFx0XHR2ZXJzZV9lbmQgPSBOdW1iZXIocmVmW2ldKTtcblx0XHRcdFx0aSArPSAxO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoaSAhPSByZWYubGVuZ3RoICYmIGlzX2FscGhhbnVtZXJpYyhyZWZbaV0pKSB7XG5cdFx0XHRcdC8vIENvbXBvc2UgdHJhbnNsYXRpb25cblx0XHRcdFx0bWF5YmVfdHJhbnNsYXRpb24gPSByZWZbaV07XG5cdFx0XHRcdGkgKz0gMTtcblx0XHRcdH1cblxuXHRcdFx0bGV0IHRyYW5zbGF0aW9uID0gbWF5YmVfdHJhbnNsYXRpb24gfHwgdGhpcy5zZXR0aW5ncy5yZWFkaW5nX3RyYW5zbGF0aW9uO1xuXHRcdFx0aWYgKGJvb2sgIT09IG51bGwpIHtcblx0XHRcdFx0Ym9va19pZCA9IGF3YWl0IHRoaXMuYmlibGVfYXBpXG5cdFx0XHRcdFx0LmJvb2tfaWQodGhpcy5zZXR0aW5ncy5fYnVpbHRfdHJhbnNsYXRpb258fHRyYW5zbGF0aW9uLCBib29rKTtcblx0XHRcdH1cblx0XHRcdGJvb2sgPSAoYXdhaXQgdGhpcy5iaWJsZV9hcGkuZ2V0X2Jvb2tfZGF0YSh0cmFuc2xhdGlvbiwgYm9va19pZCkpLm5hbWU7XG5cdFx0XHRcblx0XHRcdGxldCB0ZXh0ID0gXCJcIjtcblx0XHRcdGlmIChib29rLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0XHR0ZXh0ID0gXCJbQm9vayBhbmQgY2hhcHRlciBtdXN0IGJlIHByb3ZpZGVkXVwiO1xuXHRcdFx0fSBlbHNlIGlmIChjaGFwdGVyID09PSAtMSkge1xuXHRcdFx0XHR0ZXh0ID0gXCJbQ2hhcHRlciBtdXN0IGJlIHByb3ZpZGVkXVwiO1xuXHRcdFx0fSBlbHNlIGlmICh2ZXJzZSA9PT0gLTEpIHtcblx0XHRcdFx0Ly8gV2hvbGUgY2hhcHRlclxuXHRcdFx0XHRsZXQgdmVyc2VzID0gYXdhaXQgdGhpcy5iaWJsZV9hcGkuZ2V0X2NoYXB0ZXIoXG5cdFx0XHRcdFx0dHJhbnNsYXRpb24sXG5cdFx0XHRcdFx0Ym9va19pZCxcblx0XHRcdFx0XHRjaGFwdGVyLFxuXHRcdFx0XHQpO1xuXHRcdFx0XHRmb3IgKGNvbnN0IHZlcnNlX2lfIG9mIE9iamVjdC5rZXlzKHZlcnNlcykpIHtcblx0XHRcdFx0XHRjb25zdCB2ZXJzZV9pID0gTnVtYmVyKHZlcnNlX2lfKVxuXHRcdFx0XHRcdGxldCB2ZXJzZSA9IHZlcnNlc1t2ZXJzZV9pXTtcblx0XHRcdFx0XHR0ZXh0ICs9IFwiPHN1cD5cIiArICh2ZXJzZV9pICsgMSkgKyBcIjwvc3VwPiBcIiArIHZlcnNlO1xuXHRcdFx0XHRcdGlmICh2ZXJzZV9pICE9IE9iamVjdC5rZXlzKHZlcnNlcykubGVuZ3RoIC0gMSkge1xuXHRcdFx0XHRcdFx0dGV4dCArPSBcIjxicj5cIjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKHRleHQubGVuZ3RoID09PSAwKSB7XG5cdFx0XHRcdFx0dGV4dCA9IFwiPE5vIHRleHQgZm91bmQgZm9yIHsxfSB7MH0gaW4gdHJhbnNsYXRpb24gezJ9PlwiXG5cdFx0XHRcdFx0XHQuZm9ybWF0KFN0cmluZyhjaGFwdGVyKSwgYm9vaywgdHJhbnNsYXRpb24pXG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSBpZiAodmVyc2VfZW5kIDwgdmVyc2UpIHtcblx0XHRcdFx0Ly8gU2luZ2xlIHZlcnNlXG5cdFx0XHRcdHRleHQgPSBhd2FpdCB0aGlzLmJpYmxlX2FwaS5nZXRfdmVyc2UoXG5cdFx0XHRcdFx0dHJhbnNsYXRpb24sXG5cdFx0XHRcdFx0Ym9va19pZCxcblx0XHRcdFx0XHRjaGFwdGVyLFxuXHRcdFx0XHRcdHZlcnNlLFxuXHRcdFx0XHQpXG5cdFx0XHRcdGlmICh0ZXh0Lmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0XHRcdHRleHQgPSBcIjxObyB0ZXh0IGZvdW5kIGZvciB7MX0gezB9OnsyfSBpbiB0cmFuc2xhdGlvbiB7M30+XCJcblx0XHRcdFx0XHRcdC5mb3JtYXQoU3RyaW5nKGNoYXB0ZXIpLCBib29rLCBTdHJpbmcodmVyc2UpLCB0cmFuc2xhdGlvbilcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Ly8gVmVyc2UgcmFuZ2Vcblx0XHRcdFx0bGV0IHZlcnNlcyA9IGF3YWl0IHRoaXMuYmlibGVfYXBpLmdldF9jaGFwdGVyKFxuXHRcdFx0XHRcdHRyYW5zbGF0aW9uLFxuXHRcdFx0XHRcdGJvb2tfaWQsXG5cdFx0XHRcdFx0Y2hhcHRlcixcblx0XHRcdFx0KTtcblx0XHRcdFx0bGV0IGogPSB2ZXJzZTtcblx0XHRcdFx0d2hpbGUgKGogPCB2ZXJzZV9lbmQgKyAxICYmIGogPCBPYmplY3Qua2V5cyh2ZXJzZXMpLmxlbmd0aCkge1xuXHRcdFx0XHRcdHRleHQgKz0gXCI8c3VwPlwiICsgaiArIFwiPC9zdXA+IFwiICsgdmVyc2VzW2ogLSAxXTtcblx0XHRcdFx0XHRpZiAoaiAhPSB2ZXJzZV9lbmQpIHtcblx0XHRcdFx0XHRcdHRleHQgKz0gXCI8YnI+XCI7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGogKz0gMTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAodGV4dC5sZW5ndGggPT09IDApIHtcblx0XHRcdFx0XHR0ZXh0ID0gXCI8Tm8gdGV4dCBmb3VuZCBmb3IgezF9IHswfTp7Mn0tezN9IGluIHRyYW5zbGF0aW9uIHs0fT5cIlxuXHRcdFx0XHRcdFx0LmZvcm1hdChTdHJpbmcoY2hhcHRlciksIGJvb2ssIFN0cmluZyh2ZXJzZSksIFN0cmluZyh2ZXJzZV9lbmQpLCB0cmFuc2xhdGlvbilcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRsZXQgc3BhbiA9IGVsZW1lbnQuY3JlYXRlU3Bhbih7XG5cdFx0XHRcdHRleHQ6IFwiXCIsXG5cdFx0XHR9KTtcblxuXHRcdFx0bGV0IHRhZ3MgPSB0ZXh0Lm1hdGNoQWxsKFxuXHRcdFx0XHQvKD86PFxccyooW1xcd10qKVxccyo+KC4qPyk8XFxzKlxcL1xcMVxccyo+KXw8XFxzKihicnxcXC9icnxiclxcLylcXHMqPnwoLis/KD86KD89PFxccypbL1xcXFxcXHddKlxccyo+KXwkKSkvZ3Ncblx0XHRcdCk7XG5cdFx0XHRmb3IgKGxldCBtYXRjaCBvZiB0YWdzKSB7XG5cdFx0XHRcdGxldCB0YWdfdHlwZSA9IG1hdGNoWzFdO1xuXHRcdFx0XHRsZXQgdGFnX3RleHQgPSBtYXRjaFsyXTtcblx0XHRcdFx0bGV0IGxvbmVfdGFnX3R5cGUgPSBtYXRjaFszXTtcblx0XHRcdFx0bGV0IG5vcm1hbF90ZXh0ID0gbWF0Y2hbNF07XG5cblx0XHRcdFx0aWYgKG5vcm1hbF90ZXh0ICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0XHRzcGFuLmNyZWF0ZVNwYW4oe1xuXHRcdFx0XHRcdFx0dGV4dDogbm9ybWFsX3RleHQsXG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH0gZWxzZSBpZiAobG9uZV90YWdfdHlwZSA9PT0gXCJiclwiKSB7XG5cdFx0XHRcdFx0c3Bhbi5jcmVhdGVFbChsb25lX3RhZ190eXBlKTtcblx0XHRcdFx0fSBlbHNlIGlmIChsb25lX3RhZ190eXBlID09PSBcImJyL1wiIHx8IGxvbmVfdGFnX3R5cGUgPT09IFwiL2JyXCIpIHtcblx0XHRcdFx0XHRzcGFuLmNyZWF0ZUVsKFwiYnJcIik7XG5cdFx0XHRcdFx0c3Bhbi5jcmVhdGVTcGFuKHtcblx0XHRcdFx0XHRcdHRleHQ6IFwiXFxuXCIsXG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH0gZWxzZSBpZiAobG9uZV90YWdfdHlwZSA9PT0gXCIvSlwiKSB7XG5cdFx0XHRcdFx0LyogRG8gbm90aGluZyAqL1xuXHRcdFx0XHR9IGVsc2UgaWYgKHRhZ190eXBlID09PSBcInN1cFwiKSB7XG5cdFx0XHRcdFx0c3Bhbi5jcmVhdGVFbCh0YWdfdHlwZSwgeyB0ZXh0OiB0YWdfdGV4dCB9KTtcblx0XHRcdFx0fSBlbHNlIGlmICh0YWdfdHlwZSA9PT0gXCJzdWJcIikge1xuXHRcdFx0XHRcdHNwYW4uY3JlYXRlRWwodGFnX3R5cGUsIHsgdGV4dDogdGFnX3RleHQgfSk7XG5cdFx0XHRcdH0gZWxzZSBpZiAodGFnX3R5cGUgPT09IFwiU1wiKSB7XG5cdFx0XHRcdFx0c3Bhbi5jcmVhdGVFbChcblx0XHRcdFx0XHRcdFwic3ViXCIsXG5cdFx0XHRcdFx0XHR7IHRleHQ6IHRhZ190ZXh0LCBhdHRyOiB7IHN0eWxlOiBcIm9wYWNpdHk6IDAuNVwiIH0gfSxcblx0XHRcdFx0XHQpO1xuXHRcdFx0XHR9IGVsc2UgaWYgKHRhZ190eXBlID09PSBcImlcIikge1xuXHRcdFx0XHRcdHNwYW4uY3JlYXRlRWwodGFnX3R5cGUsIHsgdGV4dDogdGFnX3RleHQgfSk7XG5cdFx0XHRcdH0gZWxzZSBpZiAodGFnX3R5cGUgPT09IFwiYlwiKSB7XG5cdFx0XHRcdFx0c3Bhbi5jcmVhdGVFbCh0YWdfdHlwZSwgeyB0ZXh0OiB0YWdfdGV4dCB9KTtcblx0XHRcdFx0fSBlbHNlIGlmICh0YWdfdHlwZSA9PT0gXCJlXCIpIHtcblx0XHRcdFx0XHQvLy8gQSBxdW90ZSBmcm9tIGZyb20gZWxzZXdoZXJlIGluIHRoZSBiaWJsZS5cblx0XHRcdFx0XHRzcGFuLmNyZWF0ZUVsKFwiaVwiKS5jcmVhdGVFbChcInFcIiwgeyB0ZXh0OiB0YWdfdGV4dCB9KTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRzcGFuLmNyZWF0ZVNwYW4oXG5cdFx0XHRcdFx0XHR7IHRleHQ6IFwiPHswfT57MX08L3swfT5cIi5mb3JtYXQodGFnX3R5cGUsIHRhZ190ZXh0KSB9LFxuXHRcdFx0XHRcdCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdH0pO1xuXG5cblx0XHR0aGlzLmFkZFNldHRpbmdUYWIobmV3IFNldHRpbmdzVGFiKHRoaXMuYXBwLCB0aGlzKSk7XG5cdH1cblxuXHRvbnVubG9hZCgpIHtcblx0fVxuXG5cdGFzeW5jIGJ1aWxkX2JpYmxlKCkge1xuXHRcdGxldCBiaWJsZV9wYXRoID0gbm9ybWFsaXplUGF0aCh0aGlzLnNldHRpbmdzLmJpYmxlX2ZvbGRlcik7XG5cblx0XHRsZXQgYmlibGVfZm9sZGVyID0gdGhpcy5hcHAudmF1bHQuZ2V0QWJzdHJhY3RGaWxlQnlQYXRoKGJpYmxlX3BhdGgpO1xuXHRcdGlmIChiaWJsZV9mb2xkZXIgaW5zdGFuY2VvZiBURmlsZSkge1xuXHRcdFx0Ly8gQ2FuJ3QgaGFuZGxlIGlmIGJpYmxlIHBhdGggaXMgYSBmaWxlLiBBYm9ydFxuXHRcdFx0bmV3IEVycm9yTW9kYWwoXG5cdFx0XHRcdHRoaXMuYXBwLFxuXHRcdFx0XHR0aGlzLFxuXHRcdFx0XHRcIkZhaWxlZCB0byBidWlsZCBiaWJsZVwiLFxuXHRcdFx0XHRcIlRoZSBiaWJsZSBmb2xkZXIgZGVmaW5lZCBpbiBzZXR0aW5ncywgXFxcInswfVxcXCIsIHdhcyBleHBlY3RlZCB0byBwb2ludCB0byBhIGZvbGRlciwgYnV0IGl0IHBvaW50cyB0byBhIGZpbGUuIFRyeSBjaGFuZ2luZyB0aGUgcGF0aCB0byBwb2ludCB0byBhIGZvbGRlciwgb3IgY2hhbmdlIHRoZSBmaWxlIHRvIGEgZm9sZGVyLlwiXG5cdFx0XHRcdFx0LmZvcm1hdCh0aGlzLnNldHRpbmdzLmJpYmxlX2ZvbGRlciksXG5cdFx0XHQpLm9wZW4oKTtcblx0XHRcdHJldHVybjtcblx0XHR9IGVsc2UgaWYgKGJpYmxlX2ZvbGRlciA9PT0gbnVsbCkge1xuXHRcdFx0Ly8gQmlibGUgcGF0aCBkb2Vzbid0IGV4aXN0LiBDcmVhdGUgaXRcblx0XHRcdHRoaXMuYXBwLnZhdWx0LmFkYXB0ZXIubWtkaXIoYmlibGVfcGF0aCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIEJpYmxlIHBhdGggaXMgYWxyZWFkeSBhIHZhbGlkIGZvbGRlci4gTm8gYWN0aW9uIG5lZWRlZFxuXHRcdH1cblxuXHRcdGxldCBmb2xkZXJzX2FuZF9maWxlcyA9IGF3YWl0IHRoaXMuYXBwLnZhdWx0LmFkYXB0ZXIubGlzdChiaWJsZV9wYXRoKTtcblx0XHRpZiAoZm9sZGVyc19hbmRfZmlsZXMuZmlsZXMubGVuZ3RoICsgZm9sZGVyc19hbmRfZmlsZXMuZm9sZGVycy5sZW5ndGggIT0gMCkge1xuXHRcdFx0bmV3IENsZWFyT2xkQmlibGVGaWxlc01vZGFsKHRoaXMuYXBwLCB0aGlzKS5vcGVuKClcblx0XHR9IGVsc2Uge1xuXHRcdFx0YXdhaXQgdGhpcy5fYnVpbGRfYmlibGUoYmlibGVfcGF0aCk7XG5cdFx0fVxuXHR9XG5cblx0YXN5bmMgX2J1aWxkX2JpYmxlKGJpYmxlX3BhdGg6IHN0cmluZykge1xuXHRcdHRoaXMuc2hvd190b2FzdF9wcm9ncmVzcygwLCBudWxsKVxuXHRcdHRyeSB7XG5cdFx0XHRsZXQgdHJhbnNsYXRpb24gPSBcIlwiXG5cdFx0XHRpZiAodGhpcy5zZXR0aW5ncy50cmFuc2xhdGlvbiA9PSBTRUxFQ1RFRF9UUkFOU0xBVElPTl9PUFRJT05fS0VZKSB7XG5cdFx0XHRcdHRyYW5zbGF0aW9uID0gdGhpcy5zZXR0aW5ncy5yZWFkaW5nX3RyYW5zbGF0aW9uXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0cmFuc2xhdGlvbiA9IHRoaXMuc2V0dGluZ3MudHJhbnNsYXRpb25cblx0XHRcdH1cblx0XG5cdFx0XHQvLyBUT0RPOiBCdWlsZCBiaWJsZXMgYWNjb3JkaW5nIHRvIHRyYW5zbGF0aW9uIGluIHNldHRpbmdzXG5cdFx0XHR0aGlzLnNldHRpbmdzLl9idWlsdF90cmFuc2xhdGlvbiA9IHRyYW5zbGF0aW9uO1xuXHRcdFx0YXdhaXQgdGhpcy5zYXZlU2V0dGluZ3MoKTtcblx0XG5cdFx0XHRsZXQgY3R4ID0gbmV3IEJ1aWxkQ29udGV4dDtcblx0XHRcdGN0eC5wbHVnaW4gPSB0aGlzXG5cdFx0XHRjdHgudHJhbnNsYXRpb24gPSB0cmFuc2xhdGlvbjtcblx0XHRcdGN0eC5ib29rcyA9IGF3YWl0IHRoaXMuYmlibGVfYXBpLmdldF9ib29rc19kYXRhKGN0eC50cmFuc2xhdGlvbik7XG5cdFx0XHRjdHgudmVyc2VfY291bnRzID0gYXdhaXQgdGhpcy5iaWJsZV9hcGkuZ2V0X3ZlcnNlX2NvdW50KGN0eC50cmFuc2xhdGlvbik7XG5cdFxuXHRcdFx0Ly8gR2V0IHRyYW5zbGF0aW9uIHRleHRzXG5cdFx0XHRjdHgudHJhbnNsYXRpb25fdGV4dHMgPSBhd2FpdCB0aGlzLmJpYmxlX2FwaVxuXHRcdFx0XHRcdC5nZXRfdHJhbnNsYXRpb24oY3R4LnRyYW5zbGF0aW9uKTtcblxuXHRcdFx0Ly8gUmVtb3ZlIGVtcHR5IGNoYXB0ZXJzIGZyb20gYm9va3MgKEhBQ0s6IFRoaXMgc2hvdWxkIGJlIGRvbmUgaW4gYSBiZXR0ZXIgcGxhY2UsIGJ1dCB0aGlzIGlzIHdoZXJlIGFsbCB0aGUgbmVlZGVkIGluZm9ybWF0aW9uIGlzKVxuXHRcdFx0aWYgKGN0eC50cmFuc2xhdGlvbl90ZXh0cyAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdGZvciAobGV0IGJvb2sgb2YgY3R4LmJvb2tzKSB7XG5cdFx0XHRcdFx0bGV0IHRvX3JlbW92ZSA9IFtdXG5cdFx0XHRcdFx0Zm9yIChsZXQgaSA9IDE7IGkgIT0gYm9vay5jaGFwdGVycy5sZW5ndGgrMTsgaSsrKSB7XG5cdFx0XHRcdFx0XHRsZXQgY2hhcHRlcl90ZXh0cyA9IGN0eC50cmFuc2xhdGlvbl90ZXh0cy5ib29rc1tib29rLmlkXVxuXHRcdFx0XHRcdFx0bGV0IHZlcnNlcyA9IGNoYXB0ZXJfdGV4dHNbaV0gfHwge31cblx0XHRcdFx0XHRcdGlmIChPYmplY3Qua2V5cyh2ZXJzZXMpLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0XHRcdFx0XHR0b19yZW1vdmUucHVzaChpKVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRmb3IgKGNvbnN0IGkgb2YgdG9fcmVtb3ZlLnJldmVyc2UoKSkge1xuXHRcdFx0XHRcdFx0Ym9vay5jaGFwdGVycy5yZW1vdmUoaSlcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gTm90aWZ5IHByb2dyZXNzXG5cdFx0XHRsZXQgYnVpbHRfY2hhcHRlcl9jb3VudCA9IDBcblx0XHRcdGxldCB0b3RhbF9jaGFwdGVyX2NvdW50ID0gMFxuXHRcdFx0Zm9yIChjb25zdCBpIGluIGN0eC5ib29rcykge1xuXHRcdFx0XHR0b3RhbF9jaGFwdGVyX2NvdW50ICs9IGN0eC5ib29rc1tpXS5jaGFwdGVycy5sZW5ndGhcblx0XHRcdH1cblx0XHRcdHRoaXMuc2hvd190b2FzdF9wcm9ncmVzcygwLCB0b3RhbF9jaGFwdGVyX2NvdW50KVxuXHRcblx0XHRcdC8vIEluZGV4XG5cdFx0XHRpZiAodGhpcy5zZXR0aW5ncy5pbmRleF9lbmFibGVkKSB7XG5cdFx0XHRcdGF3YWl0IHNhdmVfZmlsZShcblx0XHRcdFx0XHRcInswfS97MX0ubWRcIi5mb3JtYXQoYmlibGVfcGF0aCwgY3R4LmZvcm1hdF9pbmRleF9uYW1lKCkpLFxuXHRcdFx0XHRcdGN0eC5mb3JtYXRfaW5kZXgoKSxcblx0XHRcdFx0KVxuXHRcdFx0fVxuXHRcblx0XHRcdGxldCBmaWxlX3Byb21pc2VzOiBBcnJheTxQcm9taXNlPGFueT4+ID0gW107XG5cdFxuXHRcdFx0Zm9yIChsZXQgYm9vayBvZiBjdHguYm9va3MpIHtcblx0XHRcdFx0Y3R4LnNldF9ib29rKGJvb2spO1xuXHRcdFx0XHRsZXQgdGV4dHNfb2ZfYm9vayA9IGN0eC50cmFuc2xhdGlvbl90ZXh0cy5ib29rc1tib29rLmlkXVxuXHRcblx0XHRcdFx0Ly8gQm9vayBwYXRoXG5cdFx0XHRcdGxldCBib29rX3BhdGggPSBiaWJsZV9wYXRoO1xuXHRcdFx0XHRpZiAodGhpcy5zZXR0aW5ncy5ib29rX2ZvbGRlcnNfZW5hYmxlZCkge1xuXHRcdFx0XHRcdGJvb2tfcGF0aCArPSBcIi9cIiArIGN0eC5mb3JtYXRfYm9va19uYW1lKHRoaXMsIGN0eC5ib29rLCB0aGlzLnNldHRpbmdzLmJvb2tfbmFtZV9jYXBpdGFsaXphdGlvbik7XG5cdFx0XHRcdFx0dGhpcy5hcHAudmF1bHQuYWRhcHRlci5ta2Rpcihub3JtYWxpemVQYXRoKGJvb2tfcGF0aCkpO1xuXHRcdFx0XHR9XG5cdFxuXHRcdFx0XHQvLyBDaGFwdGVyIGluZGV4XG5cdFx0XHRcdGlmICh0aGlzLnNldHRpbmdzLmNoYXB0ZXJfaW5kZXhfZW5hYmxlZCkge1xuXHRcdFx0XHRcdGZpbGVfcHJvbWlzZXMucHVzaChzYXZlX2ZpbGUoXG5cdFx0XHRcdFx0XHRcInswfS97MX0ubWRcIi5mb3JtYXQoYm9va19wYXRoLCBjdHguZm9ybWF0X2NoYXB0ZXJfaW5kZXhfbmFtZShjdHguYm9vaykpLFxuXHRcdFx0XHRcdFx0Y3R4LmZvcm1hdF9jaGFwdGVyX2luZGV4KGN0eC5ib29rKSxcblx0XHRcdFx0XHQpKVxuXHRcdFx0XHR9XG5cdFx0XHRcdFxuXHRcdFx0XHRmb3IgKGNvbnN0IGNoYXB0ZXIgb2YgY3R4LmJvb2suY2hhcHRlcnMpIHtcblx0XHRcdFx0XHRmaWxlX3Byb21pc2VzLnB1c2gobmV3IFByb21pc2UoYXN5bmMgKCkgPT4ge1xuXHRcdFx0XHRcdFx0Y3R4LnNldF9jaGFwdGVyKGNoYXB0ZXIpO1xuXHRcdFx0XHRcdFx0bGV0IHRleHRzX29mX2NoYXB0ZXIgPSB0ZXh0c19vZl9ib29rW2NoYXB0ZXJdXG5cblx0XHRcdFx0XHRcdC8vIEFzc2VtYmxlIHZlcnNlc1xuXHRcdFx0XHRcdFx0Y3R4LnZlcnNlc190ZXh0ID0gXCJcIlxuXHRcdFx0XHRcdFx0bGV0IGFkZGVkX3ZlcnNlX2NvdW50ID0gMFxuXHRcdFx0XHRcdFx0Zm9yIChjb25zdCB2ZXJzZV9rZXkgb2YgT2JqZWN0LmtleXModGV4dHNfb2ZfY2hhcHRlcikpIHtcblx0XHRcdFx0XHRcdFx0Y29uc3QgdmVyc2UgPSBOdW1iZXIodmVyc2Vfa2V5KVxuXHRcdFx0XHRcdFx0XHR3aGlsZSAoYWRkZWRfdmVyc2VfY291bnQgPCB2ZXJzZSkge1xuXHRcdFx0XHRcdFx0XHRcdGN0eC52ZXJzZSA9IGFkZGVkX3ZlcnNlX2NvdW50ICsgMVxuXHRcdFx0XHRcdFx0XHRcdGxldCB0ZXh0ID0gY3R4LmZvcm1hdF92ZXJzZV9ib2R5KFxuXHRcdFx0XHRcdFx0XHRcdFx0dGhpcyxcblx0XHRcdFx0XHRcdFx0XHRcdHRoaXMuc2V0dGluZ3MuYnVpbGRfd2l0aF9keW5hbWljX3ZlcnNlcyxcblx0XHRcdFx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0XHRcdFx0Y3R4LnZlcnNlc190ZXh0ICs9IHRleHRcblx0XHRcdFx0XHRcdFx0XHRpZiAoXG5cdFx0XHRcdFx0XHRcdFx0XHQhKHRleHQubGVuZ3RoID09PSAwICYmICF0aGlzLnNldHRpbmdzLmJ1aWxkX3dpdGhfZHluYW1pY192ZXJzZXMpXG5cdFx0XHRcdFx0XHRcdFx0XHQmJiB2ZXJzZV9rZXkgIT09IE9iamVjdC5rZXlzKHRleHRzX29mX2NoYXB0ZXIpLmxhc3QoKSlcblx0XHRcdFx0XHRcdFx0XHR7XG5cdFx0XHRcdFx0XHRcdFx0XHRjdHgudmVyc2VzX3RleHQgKz0gXCJcXG5cIjtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0YWRkZWRfdmVyc2VfY291bnQgKz0gMVxuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XG5cdFx0XHRcdFx0XHQvLyBDaGFwdGVyIG5hbWVcblx0XHRcdFx0XHRcdGxldCBjaGFwdGVyX25vdGVfbmFtZSA9IGN0eC5mb3JtYXRfY2hhcHRlcl9uYW1lKCk7XG5cdFx0XG5cdFx0XHRcdFx0XHQvLyBDaGFwdGVyIGJvZHlcblx0XHRcdFx0XHRcdGxldCBub3RlX2JvZHkgPSBjdHguZm9ybWF0X2NoYXB0ZXJfYm9keSh0aGlzKTtcblx0XHRcblx0XHRcdFx0XHRcdC8vIFNhdmUgZmlsZVxuXHRcdFx0XHRcdFx0bGV0IGZpbGVfcGF0aCA9IGJvb2tfcGF0aCArIFwiL1wiICsgY2hhcHRlcl9ub3RlX25hbWUgKyBcIi5tZFwiXG5cdFx0XG5cdFx0XHRcdFx0XHRhd2FpdCBzYXZlX2ZpbGUoZmlsZV9wYXRoLCBub3RlX2JvZHkpXG5cdFx0XHRcdFx0XHRidWlsdF9jaGFwdGVyX2NvdW50ICs9IDFcblx0XHRcdFx0XHRcdHRoaXMuc2hvd190b2FzdF9wcm9ncmVzcyhcblx0XHRcdFx0XHRcdFx0YnVpbHRfY2hhcHRlcl9jb3VudCxcblx0XHRcdFx0XHRcdFx0dG90YWxfY2hhcHRlcl9jb3VudCxcblx0XHRcdFx0XHRcdClcblx0XHRcdFx0XHR9KSlcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcblx0XHRcdGF3YWl0IFByb21pc2UuYWxsKGZpbGVfcHJvbWlzZXMpO1xuXHRcdH0gY2F0Y2ggKGUpICB7XG5cdFx0XHR0aGlzLnNob3dfdG9hc3RfZXJyb3IoU3RyaW5nKGUpKVxuXHRcdFx0dGhyb3cgZVxuXHRcdH1cblx0fVxuXG5cdHNob3dfdG9hc3RfZXJyb3IoZXJyb3I6c3RyaW5nKSB7XG5cdFx0aWYgKHRoaXMucHJvZ3Jlc3Nfbm90aWNlICE9PSBudWxsKSB7XG5cdFx0XHR0aGlzLnByb2dyZXNzX25vdGljZT8uaGlkZSgpXG5cdFx0XHR0aGlzLnByb2dyZXNzX25vdGljZSA9IG51bGxcblx0XHR9XG5cdFx0bmV3IE5vdGljZShcIkVycm9yIGJ1aWxkaW5nIGJpYmxlOiBcIiArIGVycm9yLCAwKVxuXHR9XG5cblx0c2hvd190b2FzdF9wcm9ncmVzcyhwcm9ncmVzczogbnVtYmVyLCBmaW5pc2g6IG51bWJlcnxudWxsKSB7XG5cdFx0aWYgKHByb2dyZXNzID09PSBmaW5pc2ggJiYgZmluaXNoICE9IG51bGwpIHtcblx0XHRcdHRoaXMucHJvZ3Jlc3Nfbm90aWNlPy5oaWRlKClcblx0XHRcdHRoaXMucHJvZ3Jlc3Nfbm90aWNlID0gbnVsbFxuXHRcdFx0bmV3IE5vdGljZShCVUlMRF9FTkRfVE9BU1QpXG5cdFx0XHRyZXR1cm5cblx0XHR9XG5cblx0XHRpZiAodGhpcy5wcm9ncmVzc19ub3RpY2UgPT0gbnVsbCkge1xuXHRcdFx0dGhpcy5wcm9ncmVzc19ub3RpY2UgPSBuZXcgTm90aWNlKFwiXCIsIDApXG5cdFx0fVxuXG5cdFx0bGV0IG1zZyA9IFwiXCJcblx0XHRpZiAoZmluaXNoID09IG51bGwpIHtcblx0XHRcdG1zZyA9IFwiQnVpbGRpbmcgYmlibGUuLi5cIlxuXHRcdH0gZWxzZSB7XG5cdFx0XHRtc2cgPSBcIkJ1aWxkaW5nIGJpYmxlLi4uICh7MH0vezF9KVwiXG5cdFx0XHRcdC5mb3JtYXQoU3RyaW5nKHByb2dyZXNzKSwgU3RyaW5nKGZpbmlzaCkpXG5cdFx0fVxuXHRcdHRoaXMucHJvZ3Jlc3Nfbm90aWNlLnNldE1lc3NhZ2UobXNnKVxuXHR9XG5cblx0YXN5bmMgbG9hZFNldHRpbmdzKCkge1xuXHRcdHRoaXMuc2V0dGluZ3MgPSBPYmplY3QuYXNzaWduKHt9LCBERUZBVUxUX1NFVFRJTkdTLCBhd2FpdCB0aGlzLmxvYWREYXRhKCkpO1xuXHR9XG5cblx0YXN5bmMgc2F2ZVNldHRpbmdzKCkge1xuXHRcdGxldCBzYXZpbmc6UmVjb3JkPHN0cmluZywgYW55PiA9IHt9XG5cdFx0T2JqZWN0LmFzc2lnbihzYXZpbmcsIHRoaXMuc2V0dGluZ3MpXG5cdFx0Zm9yIChjb25zdCBrZXkgaW4gc2F2aW5nKSB7XG5cdFx0XHRsZXQgdmFsdWU6YW55ID0gKERFRkFVTFRfU0VUVElOR1MgYXMgUmVjb3JkPHN0cmluZywgYW55Pilba2V5XVxuXHRcdFx0aWYgKHNhdmluZ1trZXldID09PSB2YWx1ZSkge1xuXHRcdFx0XHRkZWxldGUgc2F2aW5nW2tleV1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRhd2FpdCB0aGlzLnNhdmVEYXRhKHNhdmluZylcblx0fVxufVxuXG5jbGFzcyBCdWlsZENvbnRleHQge1xuXHR0cmFuc2xhdGlvbjogc3RyaW5nID0gXCJcIlxuXHR0cmFuc2xhdGlvbl90ZXh0czogVHJhbnNsYXRpb25EYXRhXG5cdGJvb2tzOiBBcnJheTxCb29rRGF0YT4gPSBbXVxuXHRib29rOiBCb29rRGF0YVxuXHRwcmV2X2Jvb2s6IEJvb2tEYXRhXG5cdG5leHRfYm9vazogQm9va0RhdGFcblx0Y2hhcHRlcjogbnVtYmVyID0gMFxuXHRwcmV2X2NoYXB0ZXI6IG51bWJlciA9IDBcblx0bmV4dF9jaGFwdGVyOiBudW1iZXIgPSAwXG5cdGNoYXB0ZXJzOiBDaGFwdGVyRGF0YVxuXHRsYXN0X2NoYXB0ZXJzOiBDaGFwdGVyRGF0YVxuXHRuZXh0X2NoYXB0ZXJzOiBDaGFwdGVyRGF0YVxuXHRjaGFwdGVyX3ZlcnNlX2NvdW50OiBudW1iZXIgPSAwXG5cdHZlcnNlc190ZXh0OiBzdHJpbmcgPSBcIlwiXG5cdHZlcnNlOiBudW1iZXIgPSAwXG5cdHZlcnNlX2NvdW50czogVmVyc2VDb3VudHNcblx0cGx1Z2luOiBNeUJpYmxlXG5cblx0Ly8vIEZpbmQgaW5kZXggb2YgYm9vayBieSBJRFxuXHRmaW5kX2Jvb2soYm9va19pZDpCb29rSWQpOm51bWJlciB7XG5cdFx0Zm9yIChsZXQgaSBvZiB0aGlzLmJvb2tzLmtleXMoKSkge1xuXHRcdFx0aWYgKHRoaXMuYm9va3NbaV0uaWQgPT09IGJvb2tfaWQpIHtcblx0XHRcdFx0cmV0dXJuIGk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHRocm93IG5ldyBFcnJvcihcIk5vIGJvb2sgYnkgaWQgJHtib29rX2lkfVwiKTtcblx0fVxuXG5cdGFiYnJldmlhdGVfYm9va19uYW1lKG5hbWU6c3RyaW5nLCBkZWxpbWV0ZXI6c3RyaW5nKTogc3RyaW5nIHtcblx0XHRyZXR1cm4gbmFtZS5yZXBsYWNlKGRlbGltZXRlciwgXCJcIikuc2xpY2UoMCwzKTtcblx0fVxuXG5cdGZvcm1hdF9ib29rX25hbWUocGx1Z2luOk15QmlibGUsIGJvb2s6Qm9va0RhdGEsIGNhc2luZzpzdHJpbmcpOiBzdHJpbmcge1xuXHRcdGxldCBkZWxpbSA9IHBsdWdpbi5zZXR0aW5ncy5ib29rX25hbWVfZGVsaW1pdGVyXG5cdFx0bGV0IGJvb2tfbmFtZSA9IHRoaXMudG9fY2FzZShib29rLm5hbWUsIGNhc2luZywgZGVsaW0pXG5cblx0XHRpZiAocGx1Z2luLnNldHRpbmdzLmJvb2tfbmFtZV9hYmJyZXZpYXRlZCkge1xuXHRcdFx0Ym9va19uYW1lID0gdGhpcy5hYmJyZXZpYXRlX2Jvb2tfbmFtZShib29rX25hbWUsIGRlbGltKVxuXHRcdH1cblxuXHRcdHJldHVybiBwbHVnaW4uc2V0dGluZ3MuYm9va19uYW1lX2Zvcm1hdFxuXHRcdFx0LnJlcGxhY2UoXG5cdFx0XHRcdC97b3JkZXJ9L2csXG5cdFx0XHRcdFN0cmluZyhib29rLmlkKVxuXHRcdFx0XHRcdC5wYWRTdGFydCgyICogTnVtYmVyKHBsdWdpbi5zZXR0aW5ncy5wYWRkZWRfb3JkZXIpLCBcIjBcIilcblx0XHRcdClcblx0XHRcdC5yZXBsYWNlKC97Ym9va30vZywgYm9va19uYW1lKVxuXHRcdFx0LnJlcGxhY2UoL3t0cmFuc2xhdGlvbn0vZywgU3RyaW5nKHRoaXMudHJhbnNsYXRpb24pKVxuXHR9XG5cblx0Zm9ybWF0X2Jvb2tfbmFtZV93aXRob3V0X29yZGVyKHBsdWdpbjpNeUJpYmxlLCBib29rOkJvb2tEYXRhLCBjYXNpbmc6c3RyaW5nKTogc3RyaW5nIHtcblx0XHRsZXQgZGVsaW0gPSBwbHVnaW4uc2V0dGluZ3MuYm9va19uYW1lX2RlbGltaXRlclxuXHRcdGxldCBib29rX25hbWUgPSB0aGlzLnRvX2Nhc2UoYm9vay5uYW1lLCBjYXNpbmcsIGRlbGltKVxuXG5cdFx0aWYgKHBsdWdpbi5zZXR0aW5ncy5ib29rX25hbWVfYWJicmV2aWF0ZWQpIHtcblx0XHRcdGJvb2tfbmFtZSA9IHRoaXMuYWJicmV2aWF0ZV9ib29rX25hbWUoYm9va19uYW1lLCBkZWxpbSlcblx0XHR9XG5cblx0XHRyZXR1cm4gYm9va19uYW1lXG5cdH1cblx0XG5cdGZvcm1hdF9jaGFwdGVyX2JvZHkocGx1Z2luOk15QmlibGUpOiBzdHJpbmcge1xuXHRcdGxldCBjYXNpbmcgPSBwbHVnaW4uc2V0dGluZ3MuYm9va19uYW1lX2NhcGl0YWxpemF0aW9uO1xuXHRcdHJldHVybiBwbHVnaW4uc2V0dGluZ3MuY2hhcHRlcl9ib2R5X2Zvcm1hdFxuXHRcdFx0LnJlcGxhY2UoL3t2ZXJzZXN9L2csIHRoaXMudmVyc2VzX3RleHQpXG5cdFx0XHQucmVwbGFjZSgve2Jvb2t9L2csIHRoaXMuZm9ybWF0X2Jvb2tfbmFtZV93aXRob3V0X29yZGVyKHBsdWdpbiwgdGhpcy5ib29rLCBjYXNpbmcpKVxuXHRcdFx0LnJlcGxhY2UoXG5cdFx0XHRcdC97b3JkZXJ9L2csXG5cdFx0XHRcdFN0cmluZyh0aGlzLmJvb2suaWQpXG5cdFx0XHRcdFx0LnBhZFN0YXJ0KDIgKiBOdW1iZXIocGx1Z2luLnNldHRpbmdzLnBhZGRlZF9vcmRlciksIFwiMFwiKVxuXHRcdFx0KVxuXHRcdFx0LnJlcGxhY2UoL3tjaGFwdGVyfS9nLCBTdHJpbmcodGhpcy5jaGFwdGVyKSlcblx0XHRcdC5yZXBsYWNlKC97Y2hhcHRlcl9uYW1lfS9nLCB0aGlzLmZvcm1hdF9jaGFwdGVyX25hbWUoKSlcblx0XHRcdC5yZXBsYWNlKC97Y2hhcHRlcl9pbmRleH0vZywgdGhpcy5mb3JtYXRfY2hhcHRlcl9pbmRleF9uYW1lKHRoaXMuYm9vaykpXG5cdFx0XHQucmVwbGFjZSgve2xhc3RfY2hhcHRlcn0vZywgU3RyaW5nKHRoaXMucHJldl9jaGFwdGVyKSlcblx0XHRcdC5yZXBsYWNlKC97bGFzdF9jaGFwdGVyX25hbWV9L2csIHRoaXMuZm9ybWF0X2NoYXB0ZXJfbmFtZShcImxhc3RcIikpXG5cdFx0XHQucmVwbGFjZSgve2xhc3RfY2hhcHRlcl9ib29rfS9nLCB0aGlzLmZvcm1hdF9ib29rX25hbWVfd2l0aG91dF9vcmRlcihwbHVnaW4sIHRoaXMucHJldl9ib29rLCBjYXNpbmcpKVxuXHRcdFx0LnJlcGxhY2UoL3tuZXh0X2NoYXB0ZXJ9L2csIFN0cmluZyh0aGlzLm5leHRfY2hhcHRlcikpXG5cdFx0XHQucmVwbGFjZSgve25leHRfY2hhcHRlcl9uYW1lfS9nLCB0aGlzLmZvcm1hdF9jaGFwdGVyX25hbWUoXCJuZXh0XCIpKVxuXHRcdFx0LnJlcGxhY2UoL3tuZXh0X2NoYXB0ZXJfYm9va30vZywgdGhpcy5mb3JtYXRfYm9va19uYW1lX3dpdGhvdXRfb3JkZXIocGx1Z2luLCB0aGlzLm5leHRfYm9vaywgY2FzaW5nKSlcblx0XHRcdC5yZXBsYWNlKC97Zmlyc3RfY2hhcHRlcn0vZywgU3RyaW5nKHRoaXMuYm9vay5jaGFwdGVycy5maXJzdCgpKSlcblx0XHRcdC5yZXBsYWNlKC97Zmlyc3RfY2hhcHRlcl9uYW1lfS9nLCB0aGlzLmZvcm1hdF9jaGFwdGVyX25hbWUoXCJmaXJzdFwiKSlcblx0XHRcdC5yZXBsYWNlKC97ZmluYWxfY2hhcHRlcn0vZywgU3RyaW5nKHRoaXMuYm9vay5jaGFwdGVycy5sYXN0KCkpKVxuXHRcdFx0LnJlcGxhY2UoL3tmaW5hbF9jaGFwdGVyX25hbWV9L2csIHRoaXMuZm9ybWF0X2NoYXB0ZXJfbmFtZShcImZpbmFsXCIpKVxuXHRcdFx0LnJlcGxhY2UoL3t0cmFuc2xhdGlvbn0vZywgU3RyaW5nKHRoaXMudHJhbnNsYXRpb24pKVxuXHR9XG5cblx0Zm9ybWF0X2NoYXB0ZXJfbmFtZSh0ZW5zZTpzdHJpbmc9XCJjdXJyZW50XCIsIGN1c3RvbV9jaGFwdGVyOm51bWJlcnxudWxsID0gbnVsbCk6IHN0cmluZyB7XG5cdFx0bGV0IGZvcm1hdCA9IHRoaXMucGx1Z2luLnNldHRpbmdzLmNoYXB0ZXJfbmFtZV9mb3JtYXQ7XG5cdFx0aWYgKGZvcm1hdC5sZW5ndGggPT0gMCkge1xuXHRcdFx0Zm9ybWF0ID0gREVGQVVMVF9TRVRUSU5HUy5jaGFwdGVyX25hbWVfZm9ybWF0O1xuXHRcdH1cblx0XHRsZXQgY2hhcHRlcl9wYWRfYnkgPSAzO1xuXHRcdGlmICh0aGlzLmJvb2suY2hhcHRlcnMubGVuZ3RoIDwgMTApIHtcblx0XHRcdGNoYXB0ZXJfcGFkX2J5ID0gMTtcblx0XHR9IGVsc2UgaWYgKHRoaXMuYm9vay5jaGFwdGVycy5sZW5ndGggPCAxMDApIHtcblx0XHRcdGNoYXB0ZXJfcGFkX2J5ID0gMjtcblx0XHR9XG5cblx0XHRsZXQgY2FzaW5nID0gdGhpcy5wbHVnaW4uc2V0dGluZ3MuYm9va19uYW1lX2NhcGl0YWxpemF0aW9uO1xuXHRcdGxldCBkZWxpbSA9IHRoaXMucGx1Z2luLnNldHRpbmdzLmJvb2tfbmFtZV9kZWxpbWl0ZXI7XG5cdFx0bGV0IGJvb2tfbmFtZSA9IFwiXCI7XG5cdFx0bGV0IG9yZGVyID0gLTE7XG5cdFx0bGV0IGNoYXB0ZXIgPSBjdXN0b21fY2hhcHRlclxuXHRcdHN3aXRjaCAodGVuc2UpIHtcblx0XHRcdGNhc2UgXCJjdXJyZW50XCI6IHtcblx0XHRcdFx0Ym9va19uYW1lID0gdGhpcy5mb3JtYXRfYm9va19uYW1lX3dpdGhvdXRfb3JkZXIodGhpcy5wbHVnaW4sIHRoaXMuYm9vaywgY2FzaW5nKTtcblx0XHRcdFx0b3JkZXIgPSB0aGlzLmJvb2suaWRcblx0XHRcdFx0Y2hhcHRlciA9IHRoaXMuY2hhcHRlclxuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHRcdGNhc2UgXCJsYXN0XCI6IHtcblx0XHRcdFx0Ym9va19uYW1lID0gdGhpcy5mb3JtYXRfYm9va19uYW1lX3dpdGhvdXRfb3JkZXIodGhpcy5wbHVnaW4sIHRoaXMucHJldl9ib29rLCBjYXNpbmcpO1xuXHRcdFx0XHRvcmRlciA9IHRoaXMucHJldl9ib29rLmlkXG5cdFx0XHRcdGNoYXB0ZXIgPSB0aGlzLnByZXZfY2hhcHRlclxuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHRcdGNhc2UgXCJuZXh0XCI6IHtcblx0XHRcdFx0Ym9va19uYW1lID0gdGhpcy5mb3JtYXRfYm9va19uYW1lX3dpdGhvdXRfb3JkZXIodGhpcy5wbHVnaW4sIHRoaXMubmV4dF9ib29rLCBjYXNpbmcpO1xuXHRcdFx0XHRvcmRlciA9IHRoaXMubmV4dF9ib29rLmlkXG5cdFx0XHRcdGNoYXB0ZXIgPSB0aGlzLm5leHRfY2hhcHRlclxuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHRcdGNhc2UgXCJmaXJzdFwiOiB7XG5cdFx0XHRcdGJvb2tfbmFtZSA9IHRoaXMuZm9ybWF0X2Jvb2tfbmFtZV93aXRob3V0X29yZGVyKHRoaXMucGx1Z2luLCB0aGlzLmJvb2ssIGNhc2luZyk7XG5cdFx0XHRcdG9yZGVyID0gdGhpcy5ib29rLmlkXG5cdFx0XHRcdGNoYXB0ZXIgPSB0aGlzLmJvb2suY2hhcHRlcnMuZmlyc3QoKSB8fCAxXG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdFx0Y2FzZSBcImZpbmFsXCI6IHtcblx0XHRcdFx0Ym9va19uYW1lID0gdGhpcy5mb3JtYXRfYm9va19uYW1lX3dpdGhvdXRfb3JkZXIodGhpcy5wbHVnaW4sIHRoaXMuYm9vaywgY2FzaW5nKTtcblx0XHRcdFx0b3JkZXIgPSB0aGlzLmJvb2suaWRcblx0XHRcdFx0Y2hhcHRlciA9IHRoaXMuYm9vay5jaGFwdGVycy5sYXN0KCkgfHwgMVxuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHRcdGNhc2UgXCJjdXN0b21cIjoge1xuXHRcdFx0XHRib29rX25hbWUgPSB0aGlzLmZvcm1hdF9ib29rX25hbWVfd2l0aG91dF9vcmRlcih0aGlzLnBsdWdpbiwgdGhpcy5ib29rLCBjYXNpbmcpO1xuXHRcdFx0XHRvcmRlciA9IHRoaXMuYm9vay5pZFxuXHRcdFx0XHRjaGFwdGVyID0gY3VzdG9tX2NoYXB0ZXI7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdFx0ZGVmYXVsdDogdGhyb3cgbmV3IEVycm9yKFwiVW5tYXRjaGVkIHN3aXRjaCBjYXNlIGF0IHRlbnNlICd7MH0nXCIuZm9ybWF0KHRlbnNlKSk7XG5cdFx0fVxuXG5cdFx0aWYgKGNoYXB0ZXIgPT0gbnVsbCkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFwiQ2hhcHRlciBpcyBudWxsXCIpO1xuXHRcdH1cblxuXHRcdHJldHVybiBmb3JtYXRcblx0XHRcdC5yZXBsYWNlKC97Ym9va30vZywgYm9va19uYW1lKVxuXHRcdFx0LnJlcGxhY2UoXG5cdFx0XHRcdC97b3JkZXJ9L2csXG5cdFx0XHRcdFN0cmluZyhvcmRlcilcblx0XHRcdFx0XHQucGFkU3RhcnQoMiAqIE51bWJlcih0aGlzLnBsdWdpbi5zZXR0aW5ncy5wYWRkZWRfb3JkZXIpLCBcIjBcIilcblx0XHRcdClcblx0XHRcdC5yZXBsYWNlKFxuXHRcdFx0XHQve2NoYXB0ZXJ9L2csXG5cdFx0XHRcdFN0cmluZyhjaGFwdGVyKVxuXHRcdFx0XHRcdC5wYWRTdGFydChjaGFwdGVyX3BhZF9ieSAqIE51bWJlcih0aGlzLnBsdWdpbi5zZXR0aW5ncy5wYWRkZWRfY2hhcHRlciksIFwiMFwiKSxcblx0XHRcdClcblx0XHRcdC5yZXBsYWNlKC97dHJhbnNsYXRpb259L2csIFN0cmluZyh0aGlzLnRyYW5zbGF0aW9uKSlcblx0fVxuXG5cdGZvcm1hdF92ZXJzZV9ib2R5KHBsdWdpbjpNeUJpYmxlLCBidWlsZF93aXRoX2R5bmFtaWNfdmVyc2VzOmJvb2xlYW4pOiBzdHJpbmcge1xuXHRcdGxldCBib29rX25hbWUgPSB0aGlzLmZvcm1hdF9ib29rX25hbWVfd2l0aG91dF9vcmRlcihcblx0XHRcdHBsdWdpbixcblx0XHRcdHRoaXMuYm9vayxcblx0XHRcdFwiY3VycmVudFwiLFxuXHRcdCk7XG5cblx0XHRsZXQgdmVyc2VfdGV4dCA9IFwiXCJcblx0XHRpZiAoYnVpbGRfd2l0aF9keW5hbWljX3ZlcnNlcykge1xuXHRcdFx0dmVyc2VfdGV4dCA9IFwiYGBgIHZlcnNlXFxuXCJcblx0XHRcdFx0KyBcIntib29rX2lkfSB7Y2hhcHRlcn0ge3ZlcnNlfSBcXG5cIlxuXHRcdFx0XHQrIFwiYGBgXCJcblx0XHR9IGVsc2Uge1xuXHRcdFx0dmVyc2VfdGV4dCA9IHRoaXMudHJhbnNsYXRpb25fdGV4dHMuYm9va3NbdGhpcy5ib29rLmlkXVt0aGlzLmNoYXB0ZXJdW3RoaXMudmVyc2VdXG5cdFx0XHRpZiAodmVyc2VfdGV4dCA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdHJldHVybiBcIlwiXG5cdFx0XHR9XG5cdFx0XHRpZiAodmVyc2VfdGV4dC5jb250YWlucyhcIjxcIikpIHtcblx0XHRcdFx0dmVyc2VfdGV4dCA9IHZlcnNlX3RleHRcblx0XHRcdFx0XHQucmVwbGFjZSgvPFxccypiclxccypcXC8/Pi9nLCBcIlxcblwiKSAvLyBCcmVha2xpbmUgdGFnXG5cdFx0XHRcdFx0LnJlcGxhY2UoLzxcXHMqaSpcXHMqPlxccyovZywgXCIqXCIpIC8vIEl0YWxpY3Mgb3BlbiB0YWdcblx0XHRcdFx0XHQucmVwbGFjZSgvXFxzKjxcXC9cXHMqaSpcXHMqPi9nLCBcIipcIikgLy8gSXRhbGljcyBvcGVuIHRhZ1xuXHRcdFx0XHRcdC5yZXBsYWNlKC88XFwvP1xccyppKlxccypcXC8/Pi9nLCBcIipcIikgLy8gSXRhbGljcyBnZW5lcmFsIHRhZ1xuXHRcdFx0XHRcdC5yZXBsYWNlKC88XFwvP1xccypiKlxccypcXC8/Pi9nLCBcIioqXCIpIC8vIEJvbGQgdGFnXG5cdFx0XHRcdFx0LnJlcGxhY2UoLzxcXHMqUypcXHMqPi9nLCBcIjxzdXA+KlwiKSAvLyBTdHJvbmcgb3BlblxuXHRcdFx0XHRcdC5yZXBsYWNlKC88XFwvXFxzKlMqXFxzKj4vZywgXCIqPC9zdXA+XCIpIC8vIFN0cm9uZyBjbG9zZVxuXHRcdFx0XHRcdC5yZXBsYWNlKC88XFwvP1xccypcXHcqXFxzKlxcLz8+L2csIFwiXCIpIC8vIEFueSBvdGhlciB0YWdzXG5cdFx0XHRcdDtcblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdHJldHVybiBwbHVnaW4uc2V0dGluZ3MudmVyc2VfYm9keV9mb3JtYXRcblx0XHRcdC5yZXBsYWNlKC97dmVyc2VfdGV4dH0vZywgdmVyc2VfdGV4dClcblx0XHRcdC5yZXBsYWNlKC97dmVyc2V9L2csIFN0cmluZyh0aGlzLnZlcnNlKSlcblx0XHRcdC5yZXBsYWNlKC97Ym9va30vZywgYm9va19uYW1lKVxuXHRcdFx0LnJlcGxhY2UoL3tib29rX2lkfS9nLCBTdHJpbmcodGhpcy5ib29rLmlkKSlcblx0XHRcdC5yZXBsYWNlKFxuXHRcdFx0XHQve29yZGVyfS9nLFxuXHRcdFx0XHRTdHJpbmcodGhpcy5ib29rLmlkKVxuXHRcdFx0XHRcdC5wYWRTdGFydCgyICogTnVtYmVyKHBsdWdpbi5zZXR0aW5ncy5wYWRkZWRfb3JkZXIpLCBcIjBcIilcblx0XHRcdClcblx0XHRcdC5yZXBsYWNlKC97Y2hhcHRlcn0vZywgU3RyaW5nKHRoaXMuY2hhcHRlcikpXG5cdFx0XHQucmVwbGFjZSgve2NoYXB0ZXJfbmFtZX0vZywgdGhpcy5mb3JtYXRfY2hhcHRlcl9uYW1lKCkpXG5cdFx0XHQucmVwbGFjZSgve2ZpbmFsX2NoYXB0ZXJ9L2csIFN0cmluZyh0aGlzLmJvb2suY2hhcHRlcnMpKVxuXHRcdFx0LnJlcGxhY2UoL3t0cmFuc2xhdGlvbn0vZywgU3RyaW5nKHRoaXMudHJhbnNsYXRpb24pKVxuXHR9XG5cblx0Zm9ybWF0X2NoYXB0ZXJfaW5kZXgoYm9vazogQm9va0RhdGEpOiBzdHJpbmcge1xuXHRcdGxldCBib29rX25hbWUgPSB0aGlzLmZvcm1hdF9ib29rX25hbWVfd2l0aG91dF9vcmRlcihcblx0XHRcdHRoaXMucGx1Z2luLFxuXHRcdFx0Ym9vayxcblx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmJvb2tfbmFtZV9jYXBpdGFsaXphdGlvbixcblx0XHQpO1xuXG5cdFx0bGV0IGNoYXB0ZXJfbGlua3MgPSBcIlwiXG5cblx0XHQvLyBGb3JtYXQgY2hhcHRlciBsaW5rc1xuXHRcdGZvciAobGV0IGkgPSAwOyBpICE9IGJvb2suY2hhcHRlcnMubGVuZ3RoOyBpKyspIHtcblx0XHRcdGxldCBjaGFwdGVyID0gYm9vay5nZXRfY2hhcHRlcl9udW1iZXIoaSk7XG5cdFx0XHRsZXQgbGluayA9IHRoaXMucGx1Z2luLnNldHRpbmdzLmNoYXB0ZXJfaW5kZXhfbGlua19mb3JtYXRcblx0XHRcdFx0LnJlcGxhY2UoL3tvcmRlcn0vZywgU3RyaW5nKGJvb2suaWQpLnBhZFN0YXJ0KDIgKiBOdW1iZXIodGhpcy5wbHVnaW4uc2V0dGluZ3MucGFkZGVkX29yZGVyKSwgXCIwXCIpKVxuXHRcdFx0XHQucmVwbGFjZSgve2Jvb2t9L2csIGJvb2tfbmFtZSlcblx0XHRcdFx0LnJlcGxhY2UoL3tib29rX2luZGV4fS9nLCB0aGlzLmZvcm1hdF9jaGFwdGVyX2luZGV4X25hbWUoYm9vaykpXG5cdFx0XHRcdC5yZXBsYWNlKC97dHJhbnNsYXRpb259L2csIFN0cmluZyh0aGlzLnRyYW5zbGF0aW9uKSlcblx0XHRcdFx0LnJlcGxhY2UoL3tjaGFwdGVyfS9nLCBTdHJpbmcoY2hhcHRlcikpXG5cdFx0XHRcdC5yZXBsYWNlKC97Y2hhcHRlcl9uYW1lfS9nLCB0aGlzLmZvcm1hdF9jaGFwdGVyX25hbWUoXCJjdXN0b21cIiwgY2hhcHRlcikpXG5cdFx0XHQ7XG5cdFx0XHRpZiAoaSAhPSBib29rLmNoYXB0ZXJzLmxlbmd0aC0xKSB7XG5cdFx0XHRcdGxpbmsgKz0gXCJcXG5cIlxuXHRcdFx0fVxuXHRcdFx0Y2hhcHRlcl9saW5rcyArPSBsaW5rXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMucGx1Z2luLnNldHRpbmdzLmNoYXB0ZXJfaW5kZXhfZm9ybWF0XG5cdFx0XHQucmVwbGFjZSgve29yZGVyfS9nLCBTdHJpbmcoYm9vay5pZCkucGFkU3RhcnQoMiAqIE51bWJlcih0aGlzLnBsdWdpbi5zZXR0aW5ncy5wYWRkZWRfb3JkZXIpLCBcIjBcIikpXG5cdFx0XHQucmVwbGFjZSgve2Jvb2t9L2csIGJvb2tfbmFtZSlcblx0XHRcdC5yZXBsYWNlKC97Ym9va19pbmRleH0vZywgdGhpcy5mb3JtYXRfY2hhcHRlcl9pbmRleF9uYW1lKGJvb2spKVxuXHRcdFx0LnJlcGxhY2UoL3t0cmFuc2xhdGlvbn0vZywgU3RyaW5nKHRoaXMudHJhbnNsYXRpb24pKVxuXHRcdFx0LnJlcGxhY2UoL3tpbmRleH0vZywgdGhpcy5mb3JtYXRfaW5kZXhfbmFtZSgpKVxuXHRcdFx0LnJlcGxhY2UoL3tjaGFwdGVyc30vZywgY2hhcHRlcl9saW5rcylcblx0XHQ7XG5cdH1cblxuXHRmb3JtYXRfY2hhcHRlcl9pbmRleF9uYW1lKGJvb2s6IEJvb2tEYXRhKTogc3RyaW5nIHtcblx0XHRsZXQgYm9va19uYW1lID0gdGhpcy5mb3JtYXRfYm9va19uYW1lX3dpdGhvdXRfb3JkZXIoXG5cdFx0XHR0aGlzLnBsdWdpbixcblx0XHRcdGJvb2ssXG5cdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5ib29rX25hbWVfY2FwaXRhbGl6YXRpb24sXG5cdFx0KTtcblx0XHRyZXR1cm4gdGhpcy5wbHVnaW4uc2V0dGluZ3MuY2hhcHRlcl9pbmRleF9uYW1lX2Zvcm1hdFxuXHRcdFx0LnJlcGxhY2UoL3tvcmRlcn0vZywgU3RyaW5nKGJvb2suaWQpLnBhZFN0YXJ0KDIgKiBOdW1iZXIodGhpcy5wbHVnaW4uc2V0dGluZ3MucGFkZGVkX29yZGVyKSwgXCIwXCIpKVxuXHRcdFx0LnJlcGxhY2UoL3tib29rfS9nLCBib29rX25hbWUpXG5cdFx0XHQucmVwbGFjZSgve3RyYW5zbGF0aW9ufS9nLCBTdHJpbmcodGhpcy50cmFuc2xhdGlvbikpXG5cdH1cblx0XG5cdGZvcm1hdF9pbmRleF9uYW1lKCk6IHN0cmluZyB7XG5cdFx0cmV0dXJuIHRoaXMucGx1Z2luLnNldHRpbmdzLmluZGV4X25hbWVfZm9ybWF0XG5cdFx0XHQucmVwbGFjZSgve3RyYW5zbGF0aW9ufS9nLCB0aGlzLnRyYW5zbGF0aW9uKVxuXHR9XG5cblx0Zm9ybWF0X2luZGV4KCk6IHN0cmluZyB7XG5cdFx0bGV0IG9sZF90X2xpbmtzID0gXCJcIlxuXHRcdGxldCBuZXdfdF9saW5rcyA9IFwiXCJcblx0XHRsZXQgYXBvY3JfbGlua3MgPSBcIlwiXG5cblx0XHQvLyBGb3JtYXQgYWxsIGJvb2sgbGlua3Ncblx0XHRmb3IgKGNvbnN0IGkgaW4gdGhpcy5ib29rcykge1xuXHRcdFx0bGV0IGJvb2tfbmFtZSA9IHRoaXMuZm9ybWF0X2Jvb2tfbmFtZV93aXRob3V0X29yZGVyKFxuXHRcdFx0XHR0aGlzLnBsdWdpbixcblx0XHRcdFx0dGhpcy5ib29rc1tpXSxcblx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuYm9va19uYW1lX2NhcGl0YWxpemF0aW9uLFxuXHRcdFx0KTtcblxuXHRcdFx0bGV0IGxpbmsgPSB0aGlzLnBsdWdpbi5zZXR0aW5ncy5pbmRleF9saW5rX2Zvcm1hdFxuXHRcdFx0XHQucmVwbGFjZSgve29yZGVyfS9nLCBTdHJpbmcodGhpcy5ib29rc1tpXS5pZCkucGFkU3RhcnQoMiAqIE51bWJlcih0aGlzLnBsdWdpbi5zZXR0aW5ncy5wYWRkZWRfb3JkZXIpLCBcIjBcIikpXG5cdFx0XHRcdC5yZXBsYWNlKC97Ym9va30vZywgYm9va19uYW1lKVxuXHRcdFx0XHQucmVwbGFjZSgve2Jvb2tfaW5kZXh9L2csIHRoaXMuZm9ybWF0X2NoYXB0ZXJfaW5kZXhfbmFtZSh0aGlzLmJvb2tzW2ldKSlcblx0XHRcdFx0LnJlcGxhY2UoL3t0cmFuc2xhdGlvbn0vZywgU3RyaW5nKHRoaXMudHJhbnNsYXRpb24pKVxuXHRcdFx0XHQrICdcXG4nXG5cblx0XHRcdGlmICh0aGlzLmJvb2tzW2ldLmlkIDwgNDApIHtcblx0XHRcdFx0b2xkX3RfbGlua3MgKz0gbGluayBcblx0XHRcdH0gZWxzZSBpZiAodGhpcy5ib29rc1tpXS5pZCA8IDY3KSB7XG5cdFx0XHRcdG5ld190X2xpbmtzICs9IGxpbmsgXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRhcG9jcl9saW5rcyArPSBsaW5rIFxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdG9sZF90X2xpbmtzID0gb2xkX3RfbGlua3Muc2xpY2UoMCwgb2xkX3RfbGlua3MubGVuZ3RoLTEpXG5cdFx0bmV3X3RfbGlua3MgPSBuZXdfdF9saW5rcy5zbGljZSgwLCBuZXdfdF9saW5rcy5sZW5ndGgtMSlcblx0XHRhcG9jcl9saW5rcyA9IGFwb2NyX2xpbmtzLnNsaWNlKDAsIGFwb2NyX2xpbmtzLmxlbmd0aC0xKVxuXG5cdFx0cmV0dXJuIHRoaXMucGx1Z2luLnNldHRpbmdzLmluZGV4X2Zvcm1hdFxuXHRcdFx0LnJlcGxhY2UoL3t0cmFuc2xhdGlvbn0vZywgdGhpcy50cmFuc2xhdGlvbilcblx0XHRcdC5yZXBsYWNlKC97b2xkX3Rlc3RhbWVudH0vZywgb2xkX3RfbGlua3MpXG5cdFx0XHQucmVwbGFjZSgve25ld190ZXN0YW1lbnR9L2csIG5ld190X2xpbmtzKVxuXHRcdFx0LnJlcGxhY2UoL3thcG9jcnlwaGF9L2csIGFwb2NyX2xpbmtzKVxuXHR9XG5cblx0c2V0X2Jvb2soYm9vazpCb29rRGF0YSkge1xuXHRcdHRoaXMuYm9vayA9IGJvb2s7XG5cblx0XHRsZXQgW25leHRfYm9vaywgbmV4dF9jaGFwdGVyXSA9IHRoaXMubmV4dF9jaGFwdGVyX29mKHRoaXMuYm9vaywgdGhpcy5jaGFwdGVyKVxuXHRcdGxldCBbcHJldl9ib29rLCBwcmV2X2NoYXB0ZXJdID0gdGhpcy5wcmV2X2NoYXB0ZXJfb2YodGhpcy5ib29rLCB0aGlzLmNoYXB0ZXIpXG5cdFx0dGhpcy5uZXh0X2Jvb2sgPSBuZXh0X2Jvb2tcblx0XHR0aGlzLm5leHRfY2hhcHRlciA9IG5leHRfY2hhcHRlclxuXHRcdHRoaXMucHJldl9ib29rID0gcHJldl9ib29rXG5cdFx0dGhpcy5wcmV2X2NoYXB0ZXIgPSBwcmV2X2NoYXB0ZXJcblx0fVxuXG5cdG5leHRfY2hhcHRlcl9vZihcblx0XHRib29rOiBCb29rRGF0YSxcblx0XHRjaGFwdGVyOm51bWJlcixcblx0KTogW25leHRfYm9vazpCb29rRGF0YSwgbmV4dF9jaGFwdGVyOm51bWJlcl0ge1xuXHRcdGxldCBuZXh0X2Jvb2s6Qm9va0RhdGEgPSBib29rXG5cdFx0aWYgKGNoYXB0ZXIgPT09IGJvb2suY2hhcHRlcnMubGFzdCgpKSB7XG5cdFx0XHQvLyBUaGlzIGlzIHRoZSBmaW5hbCBjaGFwdGVyLiBOZXh0IGJvb2sgaXMgbm90IHRoZSBzYW1lXG5cdFx0XHQvLyBhcyB0aGUgY3VycmVudCBib29rXG5cdFx0XHRsZXQgYm9va19pID0gdGhpcy5maW5kX2Jvb2soYm9vay5pZClcblx0XHRcdGlmIChib29rX2kgPT0gdGhpcy5ib29rcy5sZW5ndGgtMSkge1xuXHRcdFx0XHQvLyBgYm9va2AgaXMgbGFzdCBib29rLiBOZXh0IGJvb2sgaXMgZmlyc3QgYm9va1xuXHRcdFx0XHRuZXh0X2Jvb2sgPSB0aGlzLmJvb2tzWzBdXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHQvLyBTZXQgbmV4dF9ib29rIHRvIGJvb2sgYWZ0ZXIgY3VycmVudFxuXHRcdFx0XHRuZXh0X2Jvb2sgPSB0aGlzLmJvb2tzW2Jvb2tfaSsxXVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGxldCBuZXh0X2NoYXB0ZXIgPSBjaGFwdGVyKzFcblx0XHRpZiAobmV4dF9ib29rLmlkICE9PSBib29rLmlkKSB7XG5cdFx0XHQvLyBHZXQgZmlyc3QgY2hhcHRlciBvZiBuZXh0IGJvb2tcblx0XHRcdG5leHRfY2hhcHRlciA9IG5leHRfYm9vay5jaGFwdGVyc1swXVxuXHRcdH1cblxuXHRcdHJldHVybiBbbmV4dF9ib29rLCBuZXh0X2NoYXB0ZXJdXG5cdH1cblxuXHRwcmV2X2NoYXB0ZXJfb2YoXG5cdFx0Ym9vazogQm9va0RhdGEsXG5cdFx0Y2hhcHRlcjpudW1iZXIsXG5cdCk6IFtwcmV2X2Jvb2s6Qm9va0RhdGEsIHByZXZfY2hhcHRlcjpudW1iZXJdIHtcblx0XHRsZXQgcHJldl9ib29rOkJvb2tEYXRhID0gYm9va1xuXHRcdGlmIChjaGFwdGVyID09PSBib29rLmNoYXB0ZXJzLmZpcnN0KCkpIHtcblx0XHRcdC8vIFRoaXMgaXMgdGhlIGZpcnN0IGNoYXB0ZXIuIFByZXZpb3VzIGJvb2sgaXMgbm90IHRoZSBzYW1lXG5cdFx0XHQvLyBhcyB0aGUgY3VycmVudCBib29rXG5cdFx0XHRsZXQgYm9va19pID0gdGhpcy5maW5kX2Jvb2soYm9vay5pZClcblx0XHRcdGlmIChib29rX2kgPT0gMCkge1xuXHRcdFx0XHQvLyBgYm9va2AgaXMgZmlyc3QgYm9vay4gUHJldmlvdXMgYm9vayBpcyBmaW5hbCBib29rXG5cdFx0XHRcdHByZXZfYm9vayA9IHRoaXMuYm9va3NbdGhpcy5ib29rcy5sZW5ndGgtMV1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdC8vIFNldCBwcmV2X2Jvb2sgdG8gYm9vayBiZWZvcmUgY3VycmVudFxuXHRcdFx0XHRwcmV2X2Jvb2sgPSB0aGlzLmJvb2tzW2Jvb2tfaS0xXVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGxldCBwcmV2X2NoYXB0ZXIgPSBjaGFwdGVyLTFcblx0XHRpZiAocHJldl9ib29rLmlkICE9PSBib29rLmlkKSB7XG5cdFx0XHQvLyBHZXQgbGFzdCBjaGFwdGVyIG9mIHByZXZpb3VzIGJvb2tcblx0XHRcdHByZXZfY2hhcHRlciA9IHByZXZfYm9vay5jaGFwdGVyc1twcmV2X2Jvb2suY2hhcHRlcnMubGVuZ3RoLTFdXG5cdFx0fVxuXG5cdFx0cmV0dXJuIFtwcmV2X2Jvb2ssIHByZXZfY2hhcHRlcl1cblx0fVxuXG5cdHNldF9jaGFwdGVyKGNoYXB0ZXI6bnVtYmVyKSB7XG5cdFx0dGhpcy5jaGFwdGVyID0gY2hhcHRlclxuXHRcdHRoaXMuc2V0X2Jvb2sodGhpcy5ib29rKVxuXHR9XG5cblx0Ly8gU2V0cyB0aGUgY2FwaXRhbGl6YXRpb24gb2YgdGhlIGdpdmVuIG5hbWUgZGVwZW5kaW5nIG9uICpuYW1lX2Nhc2UqLlxuXHR0b19jYXNlKG5hbWU6c3RyaW5nLCBuYW1lX2Nhc2U6c3RyaW5nLCBkZWxpbWV0ZXI6c3RyaW5nKTogc3RyaW5nIHtcblx0XHRuYW1lID0gbmFtZS5yZXBsYWNlKC8gL2csIGRlbGltZXRlcilcblx0XHRpZiAobmFtZV9jYXNlID09IFwibG93ZXJfY2FzZVwiKSB7XG5cdFx0XHRuYW1lID0gbmFtZS50b0xvd2VyQ2FzZSgpXG5cdFx0fSBlbHNlIGlmIChuYW1lX2Nhc2UgPT0gXCJ1cHBlcl9jYXNlXCIpIHtcblx0XHRcdG5hbWUgPSBuYW1lLnRvVXBwZXJDYXNlKClcblx0XHR9XG5cdFx0cmV0dXJuIG5hbWU7XG5cdH1cblxuXHRnZXRfdmVyc2VfY291bnQoKTpudW1iZXIge1xuXHRcdHJldHVybiB0aGlzLnZlcnNlX2NvdW50cy5nZXRfY291bnRfZm9yKHRoaXMuYm9vay5pZCwgdGhpcy5jaGFwdGVyKTtcblx0fVxufVxuXG5jbGFzcyBWZXJzZUNvdW50cyB7XG5cdGJvb2tzOiBSZWNvcmQ8Qm9va0lkLCBSZWNvcmQ8bnVtYmVyLCBudW1iZXI+PlxuXG5cdGdldF9jb3VudF9mb3IoYm9vazpCb29rSWQsIGNoYXB0ZXI6bnVtYmVyKTogbnVtYmVyIHtcblx0XHRyZXR1cm4gdGhpcy5ib29rc1tib29rXVtjaGFwdGVyXSB8fCAwXG5cdH1cbn1cblxuaW50ZXJmYWNlIFRyYW5zbGF0aW9uRGF0YSB7XG5cdHRyYW5zbGF0aW9uOiBzdHJpbmc7XG5cdGJvb2tzOiBSZWNvcmQ8Qm9va0lkLCBSZWNvcmQ8bnVtYmVyLCBDaGFwdGVyRGF0YT4+O1xufVxuY2xhc3MgQm9va0RhdGEge1xuXHQvLy8gVGhlIEJvb2sncyBudW1lcmljIElEXG5cdGlkOiBudW1iZXI7XG5cdC8vLyBUaGUgY2hhcHRlcnMgaW5jbHVkZWQgaW4gdGhpcyBib29rIGJ5IHRoZWlyIG51bWVyaWMgb3JkZXJcblx0Y2hhcHRlcnM6IG51bWJlcltdO1xuXHQvLy8gVGhlIGRpc3BsYXkgbmFtZSBmb3IgdGhlIGJvb2tcblx0bmFtZTogc3RyaW5nO1xuXG5cdGNvbnN0cnVjdG9yKGlkOm51bWJlciwgbmFtZTpzdHJpbmcsIGNoYXB0ZXJzOm51bWJlcltdKSB7XG5cdFx0dGhpcy5pZCA9IGlkXG5cdFx0dGhpcy5uYW1lID0gbmFtZVxuXHRcdHRoaXMuY2hhcHRlcnMgPSBjaGFwdGVyc1xuXHR9XG5cblx0Ly8vIFJldHVybnMgdGhlIG51bWJlciBvZiB0aGUgY2hhcHRlciBhdCBpbmRleFxuXHRnZXRfY2hhcHRlcl9udW1iZXIoaW5kZXg6bnVtYmVyKTogbnVtYmVyIHtcblx0XHRpZiAoaW5kZXggPj0gdGhpcy5jaGFwdGVycy5sZW5ndGgpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcihcIlwiKVxuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5jaGFwdGVyc1tpbmRleF1cblx0fVxuXG5cdGhhc19jaGFwdGVyKGNoYXB0ZXI6bnVtYmVyKTogYm9vbGVhbiB7XG5cdFx0cmV0dXJuIHRoaXMuY2hhcHRlcnMuZmluZCgodmFsdWUsIF8sIF9fKSA9PiB2YWx1ZSA9PT0gY2hhcHRlcikgIT09IHVuZGVmaW5lZFxuXHR9XG59XG5cbnR5cGUgQm9va0lkID0gbnVtYmVyO1xuXG4vLy8gQSByZWNvcmQgb2YgdmVyc2VzIHRvIHRleHRzXG50eXBlIENoYXB0ZXJEYXRhID0gUmVjb3JkPG51bWJlciwgc3RyaW5nPjtcblxuLy8vIEVuc3VyZXMgYWxsIGNvcm91dGluZXMgd2FpdCBmb3IgdGhlIHNhbWUgcGllY2Ugb2YgY29kZSB0byBmaW5pc2hcbmNsYXNzIFN5bmNDYWNoZSB7XG5cdHN5bmNzOlJlY29yZDxzdHJpbmcsIFN5bmNDYWNoZUl0ZW0+ID0ge31cblxuXHRhc3luYyBzeW5jKGtleTpzdHJpbmcsIGJvZHk6KCkgPT4gYW55KTogUHJvbWlzZTxhbnk+IHtcblx0XHRpZiAoIShrZXkgaW4gdGhpcy5zeW5jcykpIHtcblx0XHRcdHRoaXMuc3luY3Nba2V5XSA9IG5ldyBTeW5jQ2FjaGVJdGVtKClcblx0XHR9XG5cdFx0bGV0IHN5bmNfaXRlbSA9IHRoaXMuc3luY3Nba2V5XVxuXG5cdFx0c3luY19pdGVtLnJlZl9jb3VudCArPSAxXG5cblxuXHRcdHRyeSB7XG5cdFx0XHRhd2FpdCBzeW5jX2l0ZW0ubXV0ZXhcblx0XHRcdFx0LmFjcXVpcmUoKVxuXHRcdFx0XHQudGhlbihhc3luYyAoKSA9PiB7XG5cdFx0XHRcdFx0c3luY19pdGVtLmRhdGEgPSBhd2FpdCBib2R5KClcblx0XG5cdFx0XHRcdFx0c3luY19pdGVtLm11dGV4LmNhbmNlbCgpXG5cdFx0XHRcdFx0c3luY19pdGVtLm11dGV4LnJlbGVhc2UoKVxuXHRcdFx0XHR9KVxuXHRcdFx0XHQuY2F0Y2goZSA9PiB7XG5cdFx0XHRcdFx0aWYgKGUgPT09IEVfQ0FOQ0VMRUQpIHtcblx0XHRcdFx0XHRcdC8qcGFzcyovXG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHRocm93IGVcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0pXG5cdFx0XHQ7XG5cblx0XHR9IGZpbmFsbHkge1xuXHRcdFx0c3luY19pdGVtLnJlZl9jb3VudCAtPSAxXG5cdFx0XHRpZiAoc3luY19pdGVtLnJlZl9jb3VudCA9PT0gMCkge1xuXHRcdFx0XHRkZWxldGUgdGhpcy5zeW5jc1trZXldXG5cdFx0XHR9XG5cdFx0fVxuXHRcdFxuXHRcdFxuXHRcdHJldHVybiBzeW5jX2l0ZW0uZGF0YVxuXHR9XG59XG5jbGFzcyBTeW5jQ2FjaGVJdGVtIHtcblx0bXV0ZXg6IE11dGV4ID0gbmV3IE11dGV4KClcblx0ZGF0YTogYW55ID0gbnVsbFxuXHRyZWZfY291bnQ6IG51bWJlciA9IDBcbn1cblxuY2xhc3MgQmlibGVBUEkge1xuXHRjYWNoZV9jbGVhcl90aW1lcjogUHJvbWlzZTxudWxsPiB8IG51bGwgPSBudWxsO1xuXHRjYWNoZV9jbGVhcl90aW1lcl9wcm9taXNlX2VycjogKHJlYXNvbj86IGFueSkgPT4gdm9pZDtcblx0c3luY19jYWNoZTogU3luY0NhY2hlID0gbmV3IFN5bmNDYWNoZSgpO1xuXHRwbHVnaW46IE15QmlibGU7XG5cblx0YXN5bmMgX2dldF9ib29rX2RhdGEodHJhbnNsYXRpb246IHN0cmluZywgYm9va19pZDpCb29rSWQpOiBQcm9taXNlPEJvb2tEYXRhPiB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKFwidW5pbXBsZW1lbnRlZFwiKVxuXHR9XG5cblx0YXN5bmMgX2dldF9ib29rc19kYXRhKHRyYW5zbGF0aW9uOiBzdHJpbmcpOiBQcm9taXNlPEFycmF5PEJvb2tEYXRhPj4ge1xuXHRcdHRocm93IG5ldyBFcnJvcihcInVuaW1wbGVtZW50ZWRcIilcblx0fVxuXG5cdGFzeW5jIF9nZXRfY2hhcHRlcihcblx0XHR0cmFuc2xhdGlvbjogc3RyaW5nLFxuXHRcdGJvb2tfaWQ6IG51bWJlcixcblx0XHRjaGFwdGVyOiBudW1iZXIsXG5cdCk6IFByb21pc2U8Q2hhcHRlckRhdGE+IHtcblx0XHR0aHJvdyBuZXcgRXJyb3IoXCJ1bmltcGxlbWVudGVkXCIpXG5cdH1cblxuXHRhc3luYyBfZ2V0X3RyYW5zbGF0aW9uKHRyYW5zbGF0aW9uOiBzdHJpbmcpOiBQcm9taXNlPFRyYW5zbGF0aW9uRGF0YT4ge1xuXHRcdHRocm93IG5ldyBFcnJvcihcInVuaW1wbGVtZW50ZWRcIilcblx0fVxuXG5cdGFzeW5jIF9nZXRfdHJhbnNsYXRpb25zKCk6IFByb21pc2U8VHJhbnNsYXRpb25zPiB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKFwidW5pbXBsZW1lbnRlZFwiKVxuXHR9XG5cblx0YXN5bmMgZ2V0X2RlZmF1bHRfdHJhbnNsYXRpb24oKTogUHJvbWlzZTxzdHJpbmc+IHtcblx0XHR0aHJvdyBuZXcgRXJyb3IoXCJ1bmltcGxlbWVudGVkXCIpXG5cdH1cblxuXHRhc3luYyBfZ2V0X3ZlcnNlKFxuXHRcdHRyYW5zbGF0aW9uOiBzdHJpbmcsXG5cdFx0Ym9va19pZDogbnVtYmVyLFxuXHRcdGNoYXB0ZXI6IG51bWJlcixcblx0XHR2ZXJzZTogbnVtYmVyLFxuXHQpOiBQcm9taXNlPHN0cmluZz4ge1xuXHRcdGxldCBjaGFwdGVyX2RhdGEgPSBhd2FpdCB0aGlzLmdldF9jaGFwdGVyKFxuXHRcdFx0dHJhbnNsYXRpb24sXG5cdFx0XHRib29rX2lkLFxuXHRcdFx0Y2hhcHRlcixcblx0XHQpO1xuXHRcdHJldHVybiBjaGFwdGVyX2RhdGFbdmVyc2VdIHx8IFwiXCI7XG5cdH1cblxuXHRhc3luYyBfZ2V0X3ZlcnNlX2NvdW50KHRyYW5zbGF0aW9uOnN0cmluZyk6IFByb21pc2U8VmVyc2VDb3VudHM+IHtcblx0XHR0aHJvdyBuZXcgRXJyb3IoXCJ1bmltcGxlbWVudGVkXCIpXG5cdH1cblxuXHQvLy8gRG93bmxvYWRzIGEgdHJhbnNsYXRpb24gYW5kIHNhdmVzIGl0IGxvY2FsbHkuXG5cdGFzeW5jIHVzZXJfZG93bmxvYWRfdHJhbnNsYXRpb24odHJhbnNsYXRpb246c3RyaW5nKSB7XG5cdFx0bGV0IG5vdGlmeSA9IG5ldyBOb3RpY2UoXG5cdFx0XHRcIkRvd25sb2FkaW5nIHswfSB0cmFuc2xhdGlvblwiLmZvcm1hdCh0cmFuc2xhdGlvbiksXG5cdFx0XHQwLFxuXHRcdClcblxuXHRcdGxldCBwcm9taXNlcyA9IFtdXG5cdFx0bGV0IHRyYW5zbGF0aW9uX2RhdGEgPSBhd2FpdCB0aGlzLmdldF90cmFuc2xhdGlvbih0cmFuc2xhdGlvbilcblx0XHRmb3IgKGNvbnN0IGJvb2tfaWRfIGluIHRyYW5zbGF0aW9uX2RhdGEuYm9va3MpIHtcblx0XHRcdGNvbnN0IGJvb2tfaWQgPSBOdW1iZXIoYm9va19pZF8pXG5cdFx0XHRjb25zdCBjaGFwdGVycyA9IHRyYW5zbGF0aW9uX2RhdGEuYm9va3NbYm9va19pZF1cblx0XHRcdGZvciAoY29uc3QgY2hhcHRlcl9rZXkgb2YgT2JqZWN0LmtleXMoY2hhcHRlcnMpKSB7XG5cdFx0XHRcdGNvbnN0IGNoYXB0ZXIgPSBOdW1iZXIoY2hhcHRlcl9rZXkpXG5cdFx0XHRcdGNvbnN0IGNoYXB0ZXJfZGF0YSA9IGNoYXB0ZXJzW2NoYXB0ZXJdXG5cdFx0XHRcdHByb21pc2VzLnB1c2godGhpcy5zYXZlX2NoYXB0ZXJfZGF0YShcblx0XHRcdFx0XHRjaGFwdGVyX2RhdGEsXG5cdFx0XHRcdFx0dHJhbnNsYXRpb24sXG5cdFx0XHRcdFx0Ym9va19pZCxcblx0XHRcdFx0XHRjaGFwdGVyLFxuXHRcdFx0XHQpKVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdG5vdGlmeS5oaWRlKClcblx0XHRub3RpZnkgPSBuZXcgTm90aWNlKFwiU2F2aW5nIHswfSB0cmFuc2xhdGlvbiBmaWxlc1wiLmZvcm1hdCh0cmFuc2xhdGlvbiksIDApXG5cdFx0YXdhaXQgUHJvbWlzZS5hbGwocHJvbWlzZXMpXG5cblx0XHRub3RpZnkuaGlkZSgpXG5cdFx0bmV3IE5vdGljZShcIkRvd25sb2FkIGNvbXBsZXRlXCIpXG5cdH1cblxuXHQvLyBHZXQgYm9vayBJRCBmcm9tIHRyYW5zbGF0aW9uIGFuZCBib29rIG5hbWVcblx0YXN5bmMgYm9va19pZCh0cmFuc2xhdGlvbjpzdHJpbmcsIGJvb2tfbmFtZTpzdHJpbmcpOiBQcm9taXNlPG51bWJlcj4ge1xuXHRcdGxldCBib29rcyA9IGF3YWl0IHRoaXMuZ2V0X2Jvb2tzX2RhdGEodHJhbnNsYXRpb24pO1xuXHRcdGZvciAobGV0IGkgb2YgYm9va3Mua2V5cygpKSB7XG5cdFx0XHRpZiAoYm9va3NbaV0ubmFtZSA9PT0gYm9va19uYW1lKSB7XG5cdFx0XHRcdHJldHVybiBib29rc1tpXS5pZDtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoYm9va19uYW1lIGluIERFRkFVTFRfTkFNRV9NQVApIHtcblx0XHRcdHJldHVybiBERUZBVUxUX05BTUVfTUFQW2Jvb2tfbmFtZV07XG5cdFx0fVxuXG5cdFx0dGhyb3cgbmV3IEVycm9yKFxuXHRcdFx0XCJUcmFuc2xhdGlvbiAnezB9JyBoYXMgbm8gYm9vayBuYW1lZCAnezF9J1wiXG5cdFx0XHRcdC5mb3JtYXQodHJhbnNsYXRpb24sIGJvb2tfbmFtZSlcblx0XHQpO1xuXHR9XG5cblx0YXN5bmMgZ2V0X2Jvb2tfZGF0YSh0cmFuc2xhdGlvbjogc3RyaW5nLCBib29rX2lkOkJvb2tJZCk6IFByb21pc2U8Qm9va0RhdGE+IHtcblx0XHRsZXQgYm9va19rZXkgPSBcInswfSB7MX1cIi5mb3JtYXQodHJhbnNsYXRpb24sIFN0cmluZyhib29rX2lkKSk7XG5cblx0XHRsZXQgZGF0YSA9IGF3YWl0IHRoaXMuc3luY19jYWNoZS5zeW5jKFxuXHRcdFx0XCJnZXRfYm9va19kYXRhX1wiICsgYm9va19rZXksXG5cdFx0XHQoKSA9PiB0aGlzLl9nZXRfYm9va19kYXRhKHRyYW5zbGF0aW9uLCBib29rX2lkKSxcblx0XHQpXG5cblx0XHRpZiAoZGF0YSA9PSBudWxsKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gZGF0YTtcblx0fVxuXG5cdGFzeW5jIGdldF9ib29rc19kYXRhKHRyYW5zbGF0aW9uOiBzdHJpbmcpOiBQcm9taXNlPEFycmF5PEJvb2tEYXRhPj4ge1xuXHRcdHJldHVybiBhd2FpdCB0aGlzLnN5bmNfY2FjaGUuc3luYyhcblx0XHRcdFwiZ2V0X2Jvb2tzX2RhdGFfXCIgKyB0cmFuc2xhdGlvbixcblx0XHRcdCgpID0+IHRoaXMuX2dldF9ib29rc19kYXRhKHRyYW5zbGF0aW9uKSxcblx0XHQpXG5cdH1cblxuXHRhc3luYyBjYWNoZV9jaGFwdGVyKFxuXHRcdHRyYW5zbGF0aW9uOiBzdHJpbmcsXG5cdFx0Ym9va19pZDogbnVtYmVyLFxuXHRcdGNoYXB0ZXI6IG51bWJlcixcblx0XHRjaGFwdGVyX2RhdGE6IENoYXB0ZXJEYXRhIHwgbnVsbCxcblx0XHRzYXZlX2xvY2FsbHk6IGJvb2xlYW4sXG5cdCk6IFByb21pc2U8dm9pZD4ge1xuXHRcdGxldCBrZXkgPSB0aGlzLm1ha2VfY2hhcHRlcl9rZXkodHJhbnNsYXRpb24sIGJvb2tfaWQsIGNoYXB0ZXIpO1xuXG5cdFx0Ly8gU2F2ZSBjaGFwdGVyIHRvIGxvY2FsIGZpbGUgc3l0ZW1cblx0XHRsZXQgY2FjaGVfcGF0aCA9IHRoaXMuZ2V0X2NhY2hlX3BhdGgoKTtcblx0XHR0aGlzLnBsdWdpbi5hcHAudmF1bHQuYWRhcHRlci5ta2RpcihjYWNoZV9wYXRoKTtcblx0XHRsZXQgY2FjaGVkX2ZpbGVfbmFtZSA9IFwiezB9IHsxfSB7Mn0udHh0XCJcblx0XHRcdC5mb3JtYXQodHJhbnNsYXRpb24sIFN0cmluZyhib29rX2lkKSwgU3RyaW5nKGNoYXB0ZXIpKTtcblx0XHRsZXQgY2FjaGVkX2ZpbGVfcGF0aCA9IG5vcm1hbGl6ZVBhdGgoXG5cdFx0XHRjYWNoZV9wYXRoICsgXCIvXCIgKyBjYWNoZWRfZmlsZV9uYW1lLFxuXHRcdCk7XG5cdFx0aWYgKFxuXHRcdFx0Y2hhcHRlcl9kYXRhICE9IG51bGxcblx0XHRcdCYmICFhd2FpdCB0aGlzLnBsdWdpbi5hcHAudmF1bHQuYWRhcHRlci5leGlzdHMoY2FjaGVkX2ZpbGVfcGF0aClcblx0XHQpIHtcblx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLmFwcC52YXVsdC5hZGFwdGVyLndyaXRlKFxuXHRcdFx0XHRjYWNoZWRfZmlsZV9wYXRoLFxuXHRcdFx0XHR0aGlzLm1ha2VfY2hhcHRlcl9maWxlKGNoYXB0ZXJfZGF0YSksXG5cdFx0XHQpO1xuXHRcdH1cblxuXHRcdC8vIFN0YXJ0L3JlZnJlc2ggY2FjaGUgY2xlYXIgdGltZXJcblx0XHRpZiAodGhpcy5jYWNoZV9jbGVhcl90aW1lciAhPT0gbnVsbCAmJiB0aGlzLmNhY2hlX2NsZWFyX3RpbWVyX3Byb21pc2VfZXJyICE9PSBudWxsKSB7XG5cdFx0XHQvLyBDbGVhciBvdXQgb2xkIHByb21pc2Vcblx0XHRcdHRoaXMuY2FjaGVfY2xlYXJfdGltZXJfcHJvbWlzZV9lcnIobnVsbCk7XG5cdFx0fVxuXHRcdHRoaXMuY2FjaGVfY2xlYXJfdGltZXIgPSBuZXcgUHJvbWlzZSgob2ssIGVycikgPT4ge1xuXHRcdFx0dGhpcy5jYWNoZV9jbGVhcl90aW1lcl9wcm9taXNlX2VyciA9IGVycjtcblx0XHRcdHNldFRpbWVvdXQob2ssIDYwMDAwICogNjApIC8vIFRpbWVvdXQgYWZ0ZXIgMSBob3VyXG5cdFx0fSk7XG5cdFx0dGhpcy5jYWNoZV9jbGVhcl90aW1lclxuXHRcdFx0LnRoZW4oKCkgPT4gdGhpcy5jbGVhcl9sb2NhbF9maWxlcygpKVxuXHRcdFx0LmNhdGNoKGVyciA9PiB7IH0pO1xuXHR9XG5cblx0YXN5bmMgZ2V0X2NoYXB0ZXIoXG5cdFx0dHJhbnNsYXRpb246IHN0cmluZyxcblx0XHRib29rX2lkOiBudW1iZXIsXG5cdFx0Y2hhcHRlcjogbnVtYmVyLFxuXHQpOiBQcm9taXNlPENoYXB0ZXJEYXRhPiB7XG5cdFx0bGV0IGNoYXB0ZXJfa2V5ID0gdGhpcy5tYWtlX2NoYXB0ZXJfa2V5KHRyYW5zbGF0aW9uLCBib29rX2lkLCBjaGFwdGVyKTtcblxuXHRcdGxldCBmaWxlX25hbWUgPSB0aGlzLm1ha2VfY2hhcHRlcl9maWxlX25hbWUodHJhbnNsYXRpb24sIGJvb2tfaWQsIGNoYXB0ZXIpXG5cblx0XHRsZXQgZG93bmxvYWRfcGF0aCA9IHRoaXMuZ2V0X2Rvd25sb2FkX3BhdGgoKVxuXHRcdHRoaXMucGx1Z2luLmFwcC52YXVsdC5hZGFwdGVyLm1rZGlyKGRvd25sb2FkX3BhdGgpXG5cdFx0bGV0IGRvd25sb2FkX2ZpbGVfcGF0aCA9IG5vcm1hbGl6ZVBhdGgoXG5cdFx0XHRkb3dubG9hZF9wYXRoICsgXCIvXCIgKyBmaWxlX25hbWVcblx0XHQpXG5cblx0XHRsZXQgY2FjaGVfcGF0aCA9IHRoaXMuZ2V0X2NhY2hlX3BhdGgoKVxuXHRcdHRoaXMucGx1Z2luLmFwcC52YXVsdC5hZGFwdGVyLm1rZGlyKGNhY2hlX3BhdGgpXG5cdFx0bGV0IGNhY2hlZF9maWxlX3BhdGggPSBub3JtYWxpemVQYXRoKFxuXHRcdFx0Y2FjaGVfcGF0aCArIFwiL1wiICsgZmlsZV9uYW1lXG5cdFx0KVxuXG5cdFx0bGV0IGRhdGEgPSBhd2FpdCB0aGlzLnN5bmNfY2FjaGUuc3luYyhcblx0XHRcdFwiZ2V0X2NoYXB0ZXJfXCIrY2hhcHRlcl9rZXksXG5cdFx0XHRhc3luYyAoKSA9PiB7XG5cdFx0XHRcdC8vIEF0dGVtcHQgdG8gbG9hZCBjaGFwdGVyIGxvY2FsbHlcblx0XHRcdFx0aWYgKCBhd2FpdCB0aGlzLnBsdWdpbi5hcHAudmF1bHQuYWRhcHRlclxuXHRcdFx0XHRcdC5leGlzdHMoZG93bmxvYWRfZmlsZV9wYXRoKVxuXHRcdFx0XHQpIHtcblx0XHRcdFx0XHQvLyBMb2FkIGZyb20gZG93bmxvYWRcblx0XHRcdFx0XHRyZXR1cm4gYXdhaXQgdGhpcy5sb2FkX2NoYXB0ZXJfZmlsZShkb3dubG9hZF9wYXRoLCBmaWxlX25hbWUpXG5cdFx0XHRcdH0gZWxzZSBpZiAoIGF3YWl0IHRoaXMucGx1Z2luLmFwcC52YXVsdC5hZGFwdGVyXG5cdFx0XHRcdFx0LmV4aXN0cyhjYWNoZWRfZmlsZV9wYXRoKVxuXHRcdFx0XHQpIHtcblx0XHRcdFx0XHQvLyBMb2FkIGZyb20gY2FjaGVcblx0XHRcdFx0XHRyZXR1cm4gYXdhaXQgdGhpcy5sb2FkX2NoYXB0ZXJfZmlsZShjYWNoZV9wYXRoLCBmaWxlX25hbWUpXG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBGZXRjaCBjaGFwdGVyIGZyb20gdGhlIHdlYlxuXHRcdFx0XHRyZXR1cm4gYXdhaXQgdGhpcy5fZ2V0X2NoYXB0ZXIoXG5cdFx0XHRcdFx0dHJhbnNsYXRpb24sXG5cdFx0XHRcdFx0Ym9va19pZCxcblx0XHRcdFx0XHRjaGFwdGVyLFxuXHRcdFx0XHQpO1xuXHRcdFx0fSxcblx0XHQpXG5cblx0XHRpZiAoXG5cdFx0XHRkYXRhID09PSBudWxsXG5cdFx0XHR8fCBPYmplY3Qua2V5cyhkYXRhKS5sZW5ndGggPT0gMFxuXHRcdCkge1xuXHRcdFx0Ly8gRmFpbGVkIHRvIGxvYWQgb3IgZG93bmxvYWQgY2hhcHRlclxuXHRcdFx0cmV0dXJuIFtdO1xuXHRcdH1cblxuXHRcdG5ldyBQcm9taXNlKGFzeW5jIChvaywgZXJyKSA9PiB7XG5cdFx0XHQvLyBDYWNoZSBjaGFwdGVyIGlmIG5vdCBkb3dubG9hZGVkXG5cdFx0XHR0cnkge1xuXHRcdFx0XHRpZiAoXG5cdFx0XHRcdFx0IWF3YWl0IHRoaXMucGx1Z2luLmFwcC52YXVsdC5hZGFwdGVyXG5cdFx0XHRcdFx0XHQuZXhpc3RzKGRvd25sb2FkX2ZpbGVfcGF0aClcblx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0dGhpcy5jYWNoZV9jaGFwdGVyKFxuXHRcdFx0XHRcdFx0dHJhbnNsYXRpb24sXG5cdFx0XHRcdFx0XHRib29rX2lkLFxuXHRcdFx0XHRcdFx0Y2hhcHRlcixcblx0XHRcdFx0XHRcdGRhdGEsXG5cdFx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5zdG9yZV9sb2NhbGx5LFxuXHRcdFx0XHRcdCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0b2sobnVsbClcblx0XHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdFx0ZXJyKGUpXG5cdFx0XHR9XG5cdFx0fSlcblxuXHRcdHJldHVybiBkYXRhO1xuXHR9XG5cblx0Z2V0X2NhY2hlX3BhdGgoKTogc3RyaW5nIHtcblx0XHRyZXR1cm4gbm9ybWFsaXplUGF0aCh0aGlzLnBsdWdpbi5tYW5pZmVzdC5kaXIgKyBcIi8ubXliaWJsZWNhY2hlXCIpO1xuXHR9XG5cblx0Z2V0X2Rvd25sb2FkX3BhdGgoKTogc3RyaW5nIHtcblx0XHRyZXR1cm4gbm9ybWFsaXplUGF0aCh0aGlzLnBsdWdpbi5tYW5pZmVzdC5kaXIgKyBcIi8uY2hhcHRlcnNcIik7XG5cdH1cblxuXHRhc3luYyBnZXRfdHJhbnNsYXRpb24odHJhbnNsYXRpb246IHN0cmluZyk6IFByb21pc2U8VHJhbnNsYXRpb25EYXRhPiB7XG5cdFx0cmV0dXJuIGF3YWl0IHRoaXMuc3luY19jYWNoZS5zeW5jKFxuXHRcdFx0XCJnZXRfdHJhbnNsYXRpb25fXCIgKyB0cmFuc2xhdGlvbixcblx0XHRcdCgpID0+IHRoaXMuX2dldF90cmFuc2xhdGlvbih0cmFuc2xhdGlvbiksXG5cdFx0KVxuXHR9XG5cblx0YXN5bmMgX2dldF9kZWZhdWx0X3RyYW5zbGF0aW9uKCk6IFByb21pc2U8c3RyaW5nPiB7XG5cdFx0cmV0dXJuIGF3YWl0IHRoaXMuc3luY19jYWNoZS5zeW5jKFxuXHRcdFx0XCJnZXRfZGVmYXVsdF90cmFuc2xhdGlvblwiLFxuXHRcdFx0KCkgPT4gdGhpcy5fZ2V0X2RlZmF1bHRfdHJhbnNsYXRpb24oKSxcblx0XHQpXG5cdH1cblxuXHRhc3luYyBnZXRfdHJhbnNsYXRpb25zKCk6IFByb21pc2U8VHJhbnNsYXRpb25zPiB7XG5cdFx0cmV0dXJuIGF3YWl0IHRoaXMuc3luY19jYWNoZS5zeW5jKFxuXHRcdFx0XCJnZXRfdHJhbnNsYXRpb25zXCIsXG5cdFx0XHQoKSA9PiB0aGlzLl9nZXRfdHJhbnNsYXRpb25zKCksXG5cdFx0KVxuXHR9XG5cblx0YXN5bmMgZ2V0X3ZlcnNlKFxuXHRcdHRyYW5zbGF0aW9uOiBzdHJpbmcsXG5cdFx0Ym9va19pZDogbnVtYmVyLFxuXHRcdGNoYXB0ZXI6IG51bWJlcixcblx0XHR2ZXJzZTogbnVtYmVyLFxuXHQpOiBQcm9taXNlPHN0cmluZz4ge1xuXHRcdGxldCBrZXkgPSBcImdldF92ZXJzZV97MH1fezF9X3syfV97M31cIi5mb3JtYXQodHJhbnNsYXRpb24sIFN0cmluZyhib29rX2lkKSwgU3RyaW5nKGNoYXB0ZXIpLCBTdHJpbmcodmVyc2UpKVxuXHRcdHJldHVybiBhd2FpdCB0aGlzLnN5bmNfY2FjaGUuc3luYyhcblx0XHRcdGtleSxcblx0XHRcdCgpID0+IHRoaXMuX2dldF92ZXJzZShcblx0XHRcdFx0dHJhbnNsYXRpb24sXG5cdFx0XHRcdGJvb2tfaWQsXG5cdFx0XHRcdGNoYXB0ZXIsXG5cdFx0XHRcdHZlcnNlLFxuXHRcdFx0KSxcblx0XHQpXG5cdH1cblxuXHRhc3luYyBnZXRfdmVyc2VfY291bnQodHJhbnNsYXRpb246c3RyaW5nKTogUHJvbWlzZTxWZXJzZUNvdW50cz4ge1xuXHRcdHJldHVybiBhd2FpdCB0aGlzLnN5bmNfY2FjaGUuc3luYyhcblx0XHRcdFwiZ2V0X3ZlcnNlX2NvdW50X1wiK3RyYW5zbGF0aW9uLFxuXHRcdFx0KCkgPT4gdGhpcy5fZ2V0X3ZlcnNlX2NvdW50KHRyYW5zbGF0aW9uKSxcblx0XHQpXG5cdH1cblxuXHRhc3luYyBjbGVhcl9sb2NhbF9maWxlcygpIHtcblx0XHR0aGlzLmNhY2hlX2NsZWFyX3RpbWVyID0gbnVsbDtcblxuXHRcdGxldCBjYWNoZV9wYXRoID0gdGhpcy5nZXRfY2FjaGVfcGF0aCgpO1xuXHRcdGlmIChhd2FpdCB0aGlzLnBsdWdpbi5hcHAudmF1bHQuYWRhcHRlci5leGlzdHMoY2FjaGVfcGF0aCkpIHtcblx0XHRcdGlmICghYXdhaXQgdGhpcy5wbHVnaW4uYXBwLnZhdWx0LmFkYXB0ZXIudHJhc2hTeXN0ZW0oY2FjaGVfcGF0aCkpIHtcblx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uYXBwLnZhdWx0LmFkYXB0ZXIudHJhc2hMb2NhbChjYWNoZV9wYXRoKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRsZXQgZG93bmxvYWRfcGF0aCA9IHRoaXMuZ2V0X2Rvd25sb2FkX3BhdGgoKTtcblx0XHRpZiAoYXdhaXQgdGhpcy5wbHVnaW4uYXBwLnZhdWx0LmFkYXB0ZXIuZXhpc3RzKGRvd25sb2FkX3BhdGgpKSB7XG5cdFx0XHRpZiAoIWF3YWl0IHRoaXMucGx1Z2luLmFwcC52YXVsdC5hZGFwdGVyLnRyYXNoU3lzdGVtKGRvd25sb2FkX3BhdGgpKSB7XG5cdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLmFwcC52YXVsdC5hZGFwdGVyLnRyYXNoTG9jYWwoZG93bmxvYWRfcGF0aCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0YXN5bmMgbG9hZF9jaGFwdGVyX2ZpbGUoZm9sZGVyOnN0cmluZywgcGF0aDogc3RyaW5nKTogUHJvbWlzZTxDaGFwdGVyRGF0YT4ge1xuXHRcdHRoaXMucGx1Z2luLmFwcC52YXVsdC5hZGFwdGVyLm1rZGlyKGZvbGRlcilcblx0XHRsZXQgcmF3ID0gYXdhaXQgdGhpcy5wbHVnaW4uYXBwLnZhdWx0LmFkYXB0ZXJcblx0XHRcdC5yZWFkKGZvbGRlciArIFwiL1wiICsgcGF0aClcblx0XHQ7XG5cdFx0XG5cdFx0bGV0IHZlcnNlX2xpc3QgPSBbXVxuXHRcdGlmIChyYXcuc3RhcnRzV2l0aChcIltcIikpIHtcblx0XHRcdHZlcnNlX2xpc3QgPSBKU09OLnBhcnNlKHJhdylcblx0XHR9IGVsc2Uge1xuXHRcdFx0dmVyc2VfbGlzdCA9IHJhdy5zcGxpdChcIlxcblwiKVxuXHRcdH1cblx0XHRcblx0XHRsZXQgdmVyc2VzOkNoYXB0ZXJEYXRhID0ge31cblx0XHRmb3IgKGxldCBpID0gMDsgaSAhPSB2ZXJzZV9saXN0Lmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRpZiAodmVyc2VfbGlzdFtpXS5sZW5ndGggPT0gMCkge1xuXHRcdFx0XHRjb250aW51ZVxuXHRcdFx0fVxuXHRcdFx0dmVyc2VzW2krMV0gPSB2ZXJzZV9saXN0W2ldXG5cdFx0fVxuXHRcdHJldHVybiB2ZXJzZXNcblx0fVxuXG5cdG1ha2VfY2hhcHRlcl9maWxlKGNoYXB0ZXJfZGF0YTpDaGFwdGVyRGF0YSk6IHN0cmluZyB7XG5cdFx0bGV0IGFkZGVkX3ZlcnNlX2NvdW50ID0gMFxuXHRcdGxldCBib2R5ID0gXCJcIjtcblx0XHRmb3IgKGxldCBpID0gMTsgYWRkZWRfdmVyc2VfY291bnQgIT09IE9iamVjdC5rZXlzKGNoYXB0ZXJfZGF0YSkubGVuZ3RoOyBpKyspIHtcblx0XHRcdGlmIChpIGluIGNoYXB0ZXJfZGF0YSkge1xuXHRcdFx0XHRib2R5ICs9IGNoYXB0ZXJfZGF0YVtpXVxuXHRcdFx0XHRhZGRlZF92ZXJzZV9jb3VudCArPSAxXG5cdFx0XHR9XG5cdFx0XHRpZiAoYWRkZWRfdmVyc2VfY291bnQgIT09IE9iamVjdC5rZXlzKGNoYXB0ZXJfZGF0YSkubGVuZ3RoKSB7XG5cdFx0XHRcdGJvZHkgKz0gXCJcXG5cIlxuXHRcdFx0fVxuXHRcdH1cblx0XHRcblx0XHRyZXR1cm4gYm9keVxuXHR9XG5cblx0Ly8vIE1ha2VzIHRoZSBmaWxlIG5hbWUgZm9yIGRvd25sb2FkZWQgY2hhcHRlcnNcblx0bWFrZV9jaGFwdGVyX2ZpbGVfbmFtZSh0cmFuc2xhdGlvbjogc3RyaW5nLCBib29rX2lkOiBudW1iZXIsIGNoYXB0ZXI6IE51bWJlcik6IHN0cmluZyB7XG5cdFx0cmV0dXJuIFwiezB9IHsxfSB7Mn0udHh0XCIuZm9ybWF0KHRyYW5zbGF0aW9uLCBTdHJpbmcoYm9va19pZCksIFN0cmluZyhjaGFwdGVyKSk7XG5cdFx0XG5cdH1cblxuXHRtYWtlX2NoYXB0ZXJfa2V5KHRyYW5zbGF0aW9uOiBzdHJpbmcsIGJvb2tfaWQ6IG51bWJlciwgY2hhcHRlcjogTnVtYmVyKSB7XG5cdFx0cmV0dXJuIFwiezB9LnsxfS57Mn1cIi5mb3JtYXQodHJhbnNsYXRpb24sIFN0cmluZyhib29rX2lkKSwgU3RyaW5nKGNoYXB0ZXIpKTtcblx0fVxuXG5cdC8vLyBTYXZlcyBjaGFwdGVyIGRhdGEgdG8gbG9jYWwgZGlza1xuXHRhc3luYyBzYXZlX2NoYXB0ZXJfZGF0YShcblx0XHRjaGFwdGVyX2RhdGE6Q2hhcHRlckRhdGEsXG5cdFx0dHJhbnNsYXRpb246c3RyaW5nLFxuXHRcdGJvb2tfaWQ6bnVtYmVyLFxuXHRcdGNoYXB0ZXI6bnVtYmVyLFxuXHQpIHtcblx0XHQvLyBTYXZlIGNoYXB0ZXIgdG8gbG9jYWwgZmlsZSBzeXRlbVxuXHRcdGxldCBwYXRoID0gdGhpcy5nZXRfZG93bmxvYWRfcGF0aCgpO1xuXHRcdHRoaXMucGx1Z2luLmFwcC52YXVsdC5hZGFwdGVyLm1rZGlyKHBhdGgpO1xuXHRcdGxldCBmaWxlX25hbWUgPSB0aGlzXG5cdFx0XHQubWFrZV9jaGFwdGVyX2ZpbGVfbmFtZSh0cmFuc2xhdGlvbiwgYm9va19pZCwgY2hhcHRlcik7XG5cdFx0bGV0IGZpbGVfcGF0aCA9IG5vcm1hbGl6ZVBhdGgoXG5cdFx0XHRwYXRoICsgXCIvXCIgKyBmaWxlX25hbWUsXG5cdFx0KTtcblx0XHRpZiAoXG5cdFx0XHQhYXdhaXQgdGhpcy5wbHVnaW4uYXBwLnZhdWx0LmFkYXB0ZXIuZXhpc3RzKGZpbGVfcGF0aClcblx0XHQpIHtcblx0XHRcdGxldCBib2R5ID0gXCJcIjtcblx0XHRcdGZvciAoY29uc3QgaV8gaW4gY2hhcHRlcl9kYXRhKSB7XG5cdFx0XHRcdGNvbnN0IGkgPSBOdW1iZXIoaV8pXG5cdFx0XHRcdGJvZHkgKz0gY2hhcHRlcl9kYXRhW2ldO1xuXHRcdFx0XHRpZiAoaSAhPT0gT2JqZWN0LmtleXMoY2hhcHRlcl9kYXRhKS5sZW5ndGgpIHtcblx0XHRcdFx0XHRib2R5ICs9IFwiXFxuXCJcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uYXBwLnZhdWx0LmFkYXB0ZXIud3JpdGUoXG5cdFx0XHRcdGZpbGVfcGF0aCxcblx0XHRcdFx0Ym9keSxcblx0XHRcdCk7XG5cdFx0fVxuXHR9XG59XG5cbnR5cGUgQm9va0tleSA9IHN0cmluZztcbnR5cGUgQ2hhcHRlcktleSA9IHN0cmluZztcblxudHlwZSBUcmFuc2xhdGlvbnMgPSBSZWNvcmQ8c3RyaW5nLCBUcmFuc2xhdGlvbj47XG5pbnRlcmZhY2UgVHJhbnNsYXRpb24ge1xuXHRkaXNwbGF5X25hbWU6IHN0cmluZyxcblx0YWJicmV2aWF0ZWRfbmFtZTogc3RyaW5nLFxuXHRsYW5ndWFnZTogc3RyaW5nLFxufVxuXG5jbGFzcyBCb2xsc0xpZmVCaWJsZUFQSSBleHRlbmRzIEJpYmxlQVBJIHtcblx0cGx1Z2luOiBNeUJpYmxlXG5cdHRyYW5zbGF0aW9uczogVHJhbnNsYXRpb25zID0ge31cblx0dHJhbnNsYXRpb25fbWFwczogUmVjb3JkPHN0cmluZywgQXJyYXk8Qm9va0RhdGE+PiA9IHt9XG5cdGNhY2hlX2NsZWFyX3RpbWVyOiBQcm9taXNlPG51bGw+IHwgbnVsbCA9IG51bGxcblx0c3luY19jYWNoZTogU3luY0NhY2hlID0gbmV3IFN5bmNDYWNoZSgpXG5cblx0YXN5bmMgX2dldF9jaGFwdGVyKFxuXHRcdHRyYW5zbGF0aW9uOiBzdHJpbmcsXG5cdFx0Ym9va19pZDogbnVtYmVyLFxuXHRcdGNoYXB0ZXI6IG51bWJlcixcblx0KTogUHJvbWlzZTxDaGFwdGVyRGF0YT4ge1xuXHRcdC8vIEZldGNoIGNoYXB0ZXIgZnJvbSB0aGUgd2ViXG5cdFx0dHJ5IHtcblx0XHRcdGxldCB2ZXJzZV9kYXRhX2xpc3QgPSBKU09OLnBhcnNlKGF3YWl0IGh0dHBHZXQoXG5cdFx0XHRcdFwiaHR0cHM6Ly9ib2xscy5saWZlL2dldC1jaGFwdGVyL3swfS97MX0vezJ9L1wiXG5cdFx0XHRcdFx0LmZvcm1hdCh0cmFuc2xhdGlvbiwgU3RyaW5nKGJvb2tfaWQpLCBTdHJpbmcoY2hhcHRlcikpXG5cdFx0XHQpKTtcblxuXHRcdFx0bGV0IHRleHRzOkNoYXB0ZXJEYXRhID0ge31cblx0XHRcdGZvciAoY29uc3QgZGF0YSBvZiB2ZXJzZV9kYXRhX2xpc3QpIHtcblx0XHRcdFx0bGV0IHZlcnNlID0gZGF0YVtcInZlcnNlXCJdXG5cdFx0XHRcdHRleHRzW3ZlcnNlXSA9IGRhdGFbXCJ0ZXh0XCJdXG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiB0ZXh0c1xuXHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdGlmIChlIGluc3RhbmNlb2YgRXJyb3IgJiYgZS5tZXNzYWdlLnN0YXJ0c1dpdGgoXCJObyBib29rIGV4aXN0cyBieSBuYW1lXCIpKSB7XG5cdFx0XHRcdHJldHVybiBbXTtcblx0XHRcdH1cblx0XHRcdHRocm93IGU7XG5cdFx0fVxuXHR9XG5cblx0YXN5bmMgX2dldF90cmFuc2xhdGlvbih0cmFuc2xhdGlvbjogc3RyaW5nKTogUHJvbWlzZTxUcmFuc2xhdGlvbkRhdGE+IHtcblx0XHRsZXQgdmVyc2VzID0gSlNPTi5wYXJzZShcblx0XHRcdGF3YWl0IGh0dHBHZXQoXG5cdFx0XHRcdFwiaHR0cHM6Ly9ib2xscy5saWZlL3N0YXRpYy90cmFuc2xhdGlvbnMvezB9Lmpzb25cIi5mb3JtYXQodHJhbnNsYXRpb24pXG5cdFx0XHQpXG5cdFx0KTtcblxuXHRcdGxldCBiaWJsZTogVHJhbnNsYXRpb25EYXRhID0ge1xuXHRcdFx0dHJhbnNsYXRpb246IHRyYW5zbGF0aW9uLFxuXHRcdFx0Ym9va3M6IHt9LFxuXHRcdH07XG5cblx0XHRhd2FpdCBuZXcgUHJvbWlzZShhc3luYyAob2ssIGVycikgPT4ge1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0bGV0IGkgPSAwO1xuXHRcdFx0XHRsZXQgY3Vycl9ib29rX2lkID0gLTE7XG5cdFx0XHRcdGxldCBjdXJyX2NoYXB0ZXIgPSAtMTtcblx0XHRcdFx0Zm9yIChjb25zdCBkYXRhIG9mIHZlcnNlcykge1xuXHRcdFx0XHRcdGxldCB2ZXJzZSA9IGRhdGFbXCJ2ZXJzZVwiXVxuXHRcblx0XHRcdFx0XHRjdXJyX2Jvb2tfaWQgPSBkYXRhW1wiYm9va1wiXVxuXHRcdFx0XHRcdGN1cnJfY2hhcHRlciA9IGRhdGFbXCJjaGFwdGVyXCJdXG5cdFxuXHRcdFx0XHRcdGlmICghKGN1cnJfYm9va19pZCBpbiBiaWJsZS5ib29rcykpIHtcblx0XHRcdFx0XHRcdGJpYmxlLmJvb2tzW2N1cnJfYm9va19pZF0gPSBbXVx0XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmICghKGN1cnJfY2hhcHRlciBpbiBiaWJsZS5ib29rc1tjdXJyX2Jvb2tfaWRdKSkge1xuXHRcdFx0XHRcdFx0YmlibGUuYm9va3NbY3Vycl9ib29rX2lkXVtjdXJyX2NoYXB0ZXJdID0ge31cblx0XHRcdFx0XHR9XG5cdFxuXHRcdFx0XHRcdGJpYmxlLmJvb2tzW2N1cnJfYm9va19pZF1bY3Vycl9jaGFwdGVyXVt2ZXJzZV0gPSBkYXRhW1widGV4dFwiXVxuXHRcdFx0XHRcdGkgKz0gMTtcblx0XHRcdFx0fVxuXHRcdFx0XHRvayhudWxsKTtcblx0XHRcdH0gY2F0Y2ggKGUpIHtcblx0XHRcdFx0ZXJyKGUpXG5cdFx0XHR9XG5cdFx0fSkuY2F0Y2goZSA9PiB7XG5cdFx0XHR0aHJvdyBlXG5cdFx0fSlcblxuXHRcdHJldHVybiBiaWJsZTtcblx0fVxuXG5cdGFzeW5jIF9nZXRfYm9va19kYXRhKHRyYW5zbGF0aW9uOiBzdHJpbmcsIGJvb2tfaWQ6Qm9va0lkKTogUHJvbWlzZTxCb29rRGF0YT4ge1xuXHRcdGxldCBib29rcyA9IGF3YWl0IHRoaXMuZ2V0X2Jvb2tzX2RhdGEodHJhbnNsYXRpb24pO1xuXHRcdGZvciAobGV0IGJvb2sgb2YgYm9va3MpIHtcblx0XHRcdGlmIChib29rLmlkID09IGJvb2tfaWQpIHtcblx0XHRcdFx0cmV0dXJuIGJvb2s7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHRocm93IG5ldyBFcnJvcigpO1xuXHR9XG5cblx0YXN5bmMgX2dldF9ib29rc19kYXRhKHRyYW5zbGF0aW9uOiBzdHJpbmcpOiBQcm9taXNlPEJvb2tEYXRhW10+IHtcblx0XHRsZXQgYm9va3MgPSBhd2FpdCB0aGlzLmdldF90cmFuc2xhdGlvbl9tYXAodHJhbnNsYXRpb24pO1xuXHRcdGJvb2tzLnNvcnQoZnVuY3Rpb24oeCwgeSkge1xuXHRcdFx0aWYgKHguaWQgPCB5LmlkKSB7XG5cdFx0XHRcdHJldHVybiAtMTtcblx0XHRcdH1cblx0XHRcdGlmICh4LmlkID4geS5pZCkge1xuXHRcdFx0XHRyZXR1cm4gMTtcblx0XHRcdH1cblx0XHRcdHJldHVybiAwO1xuXHRcdH0pO1xuXHRcdHJldHVybiBib29rcztcblx0fVxuXG5cdGFzeW5jIF9nZXRfZGVmYXVsdF90cmFuc2xhdGlvbigpOiBQcm9taXNlPHN0cmluZz4ge1xuXHRcdHJldHVybiBcIllMVFwiO1xuXHR9XG5cblx0YXN5bmMgX2dldF90cmFuc2xhdGlvbnMoKTogUHJvbWlzZTxUcmFuc2xhdGlvbnM+IHtcblx0XHRpZiAoT2JqZWN0LmtleXModGhpcy50cmFuc2xhdGlvbnMpLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0bGV0IGxpc3QgPSBKU09OLnBhcnNlKGF3YWl0IGh0dHBHZXQoXG5cdFx0XHRcdFwiaHR0cHM6Ly9ib2xscy5saWZlL3N0YXRpYy9ib2xscy9hcHAvdmlld3MvbGFuZ3VhZ2VzLmpzb25cIlxuXHRcdFx0KSk7XG5cdFx0XHRmb3IgKGxldCBsYW5ndWFnZSBvZiBsaXN0KSB7XG5cdFx0XHRcdGZvciAobGV0IGl0ZW0gb2YgbGFuZ3VhZ2VbXCJ0cmFuc2xhdGlvbnNcIl0pIHtcblx0XHRcdFx0XHRpZiAoaXRlbVtcInNob3J0X25hbWVcIl0gaW4gdGhpcy50cmFuc2xhdGlvbnMpIHtcblx0XHRcdFx0XHRcdHRocm93IG5ldyBFcnJvcihcIlRyYW5zbGF0aW9uIGFscmVhZHkgYWRkZWQgdG8gbWFwXCIpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHR0aGlzLnRyYW5zbGF0aW9uc1tpdGVtW1wic2hvcnRfbmFtZVwiXV0gPSB7XG5cdFx0XHRcdFx0XHRhYmJyZXZpYXRlZF9uYW1lOiBpdGVtW1wic2hvcnRfbmFtZVwiXSxcblx0XHRcdFx0XHRcdGRpc3BsYXlfbmFtZTogaXRlbVtcImZ1bGxfbmFtZVwiXSxcblx0XHRcdFx0XHRcdGxhbmd1YWdlOiBsYW5ndWFnZVtcImxhbmd1YWdlXCJdLFxuXHRcdFx0XHRcdH07XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMudHJhbnNsYXRpb25zO1xuXHR9XG5cblx0YXN5bmMgX2dldF92ZXJzZV9jb3VudCh0cmFuc2xhdGlvbjpzdHJpbmcpOiBQcm9taXNlPFZlcnNlQ291bnRzPiB7XG5cdFx0bGV0IGpzb24gPSBKU09OLnBhcnNlKGF3YWl0IGh0dHBHZXQoXG5cdFx0XHRcImh0dHBzOi8vYm9sbHMubGlmZS9nZXQtdmVyc2UtY291bnRzL3swfS9cIi5mb3JtYXQodHJhbnNsYXRpb24pXG5cdFx0KSk7XG5cdFx0bGV0IGNvdW50cyA9IG5ldyBWZXJzZUNvdW50cygpO1xuXHRcdGNvdW50cy5ib29rcyA9IGpzb247XG5cdFx0cmV0dXJuIGNvdW50c1xuXHR9XG5cblx0YXN5bmMgYm9va190b19pZCh0cmFuc2xhdGlvbjogc3RyaW5nLCBib29rOiBzdHJpbmcpOiBQcm9taXNlPG51bWJlcj4ge1xuXHRcdGxldCBib29rXyA9IGJvb2sudG9Mb3dlckNhc2UoKTtcblx0XHRsZXQgbWFwID0gYXdhaXQgdGhpcy5nZXRfdHJhbnNsYXRpb25fbWFwKHRyYW5zbGF0aW9uKTtcblx0XHRmb3IgKGxldCBpIGluIG1hcCkge1xuXHRcdFx0bGV0IGJvb2tfZGF0YSA9IG1hcFtpXTtcblx0XHRcdGlmIChib29rXyA9PSBib29rX2RhdGFbXCJuYW1lXCJdLnRvTG93ZXJDYXNlKCkpIHtcblx0XHRcdFx0cmV0dXJuIE51bWJlcihpKSArIDE7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHRocm93IG5ldyBFcnJvcignTm8gYm9vayBleGlzdHMgYnkgbmFtZSB7MH0uJy5mb3JtYXQoYm9vaykpO1xuXHR9XG5cblx0Y2hhcHRlcl9rZXkodHJhbnNsYXRpb246IHN0cmluZywgYm9va19pZDogbnVtYmVyLCBjaGFwdGVyOiBOdW1iZXIpIHtcblx0XHRyZXR1cm4gXCJ7MH0uezF9LnsyfVwiLmZvcm1hdCh0cmFuc2xhdGlvbiwgU3RyaW5nKGJvb2tfaWQpLCBTdHJpbmcoY2hhcHRlcikpO1xuXHR9XG5cblx0YXN5bmMgZ2VuZXJhdGVfdHJhbnNsYXRpb25fbWFwKHRyYW5zbGF0aW9uOiBzdHJpbmcpIHtcblx0XHRsZXQgbWFwOiBBcnJheTxSZWNvcmQ8c3RyaW5nLCBhbnk+PiA9IGF3YWl0IHJlcXVlc3RVcmwoXG5cdFx0XHRcImh0dHBzOi8vYm9sbHMubGlmZS9nZXQtYm9va3MvezB9L1wiLmZvcm1hdCh0cmFuc2xhdGlvbilcblx0XHQpLmpzb247XG5cdFx0bGV0IGJvb2tfZGF0YTogQXJyYXk8Qm9va0RhdGE+ID0gW107XG5cdFx0Zm9yIChsZXQgaXRlbSBvZiBtYXApIHtcblx0XHRcdGxldCBjaGFwdGVyX2xpc3QgPSBbLi4uQXJyYXkoaXRlbVtcImNoYXB0ZXJzXCJdKS5rZXlzKCldLm1hcCh4ID0+IHgrMSlcblx0XHRcdGJvb2tfZGF0YS5wdXNoKG5ldyBCb29rRGF0YShcblx0XHRcdFx0aXRlbVtcImJvb2tpZFwiXSxcblx0XHRcdFx0aXRlbVtcIm5hbWVcIl0sXG5cdFx0XHRcdGNoYXB0ZXJfbGlzdCxcblx0XHRcdCkpO1xuXHRcdH1cblx0XHR0aGlzLnRyYW5zbGF0aW9uX21hcHNbdHJhbnNsYXRpb25dID0gYm9va19kYXRhO1xuXHR9XG5cblx0YXN5bmMgaWRfdG9fYm9vayh0cmFuc2xhdGlvbjogc3RyaW5nLCBib29rX2lkOiBudW1iZXIpOiBQcm9taXNlPHN0cmluZz4ge1xuXHRcdGxldCBtYXAgPSBhd2FpdCB0aGlzLmdldF90cmFuc2xhdGlvbl9tYXAodHJhbnNsYXRpb24pO1xuXHRcdHJldHVybiBtYXBbYm9va19pZCAtIDFdW1wibmFtZVwiXTtcblx0fVxuXG5cdGFzeW5jIGdldF90cmFuc2xhdGlvbl9tYXAodHJhbnNsYXRpb246IHN0cmluZyk6IFByb21pc2U8QXJyYXk8Qm9va0RhdGE+PiB7XG5cdFx0aWYgKCEodHJhbnNsYXRpb24gaW4gdGhpcy50cmFuc2xhdGlvbl9tYXBzKSkge1xuXHRcdFx0YXdhaXQgdGhpcy5nZW5lcmF0ZV90cmFuc2xhdGlvbl9tYXAodHJhbnNsYXRpb24pO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy50cmFuc2xhdGlvbl9tYXBzW3RyYW5zbGF0aW9uXTtcblx0fVxufVxuXG5jbGFzcyBCdWlsZGVyTW9kYWwgZXh0ZW5kcyBNb2RhbCB7XG5cdHBsdWdpbjogTXlCaWJsZVxuXG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwLCBwbHVnaW46IE15QmlibGUpIHtcblx0XHRzdXBlcihhcHApO1xuXHRcdHRoaXMucGx1Z2luID0gcGx1Z2luO1xuXHRcdHRoaXMucmVuZGVyKCk7XG5cdH1cblxuXHRyZW5kZXIoKSB7XG5cdFx0bGV0IGNvbnRhaW5lckVsID0gdGhpcy5jb250ZW50RWw7XG5cblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbCkubmFtZUVsLmNyZWF0ZUVsKFwiaDFcIiwgeyB0ZXh0OiBcIkJvb2sgYnVpbGRlclwiIH0pXG5cblx0XHQvLyBUb3Agc2V0dGluZ3NcblxuXHRcdHRoaXMucmVuZGVyQmlibGVGb2xkZXIobmV3IFNldHRpbmcoY29udGFpbmVyRWwpKTtcblxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdFx0LnNldE5hbWUoJ1RyYW5zbGF0aW9uJylcblx0XHRcdC5zZXREZXNjKCdCdWlsZHMgeW91ciBCaWJsZSBhY2NvcmRpbmcgdG8gdGhlIGxheW91dCBvZiB0aGlzIHRyYW5sc2F0aW9uLiBJZiBcIkJ1aWxkIHdpdGggZHluYW1pYyB2ZXJzZXNcIiBpcyBhY3RpdmUsIHRoZW4gdGhlIHRleHQgZnJvbSB0aGlzIHZlcnNpb24gd2lsbCBiZSBidWlsdCBpbnRvIHlvdXIgQmlibGUuJylcblx0XHRcdC5hZGREcm9wZG93bihhc3luYyBkcm9wID0+IHtcblx0XHRcdFx0ZHJvcC5hZGRPcHRpb24oU0VMRUNURURfVFJBTlNMQVRJT05fT1BUSU9OX0tFWSwgU0VMRUNURURfVFJBTlNMQVRJT05fT1BUSU9OLmZvcm1hdCh0aGlzLnBsdWdpbi5zZXR0aW5ncy5yZWFkaW5nX3RyYW5zbGF0aW9uKSlcblxuXHRcdFx0XHRsZXQgdHJhbnNsYXRpb25zID0gYXdhaXQgdGhpcy5wbHVnaW4uYmlibGVfYXBpLmdldF90cmFuc2xhdGlvbnMoKTtcblx0XHRcdFx0XG5cdFx0XHRcdGxldCB0cmFuc2xhdGlvbnNfbGlzdCA9IFtdO1xuXHRcdFx0XHRmb3IgKGNvbnN0IGtleSBpbiB0cmFuc2xhdGlvbnMpIHtcblx0XHRcdFx0XHR0cmFuc2xhdGlvbnNfbGlzdC5wdXNoKGtleSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0dHJhbnNsYXRpb25zX2xpc3QgPSB0cmFuc2xhdGlvbnNfbGlzdC5zb3J0KChhLCBiKSA9PiB7XG5cdFx0XHRcdFx0aWYgKHRyYW5zbGF0aW9uc1thXS5sYW5ndWFnZSA8IHRyYW5zbGF0aW9uc1tiXS5sYW5ndWFnZSkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIC0xO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZiAodHJhbnNsYXRpb25zW2FdLmxhbmd1YWdlID4gdHJhbnNsYXRpb25zW2JdLmxhbmd1YWdlKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gMTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRpZiAoYSA8IGIpIHtcblx0XHRcdFx0XHRcdHJldHVybiAtMTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKGEgPiBiKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gMTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRyZXR1cm4gMDtcblx0XHRcdFx0fSlcblxuXHRcdFx0XHRmb3IgKGNvbnN0IGkgaW4gdHJhbnNsYXRpb25zX2xpc3QpIHtcblx0XHRcdFx0XHRsZXQga2V5ID0gdHJhbnNsYXRpb25zX2xpc3RbaV07XG5cdFx0XHRcdFx0ZHJvcC5hZGRPcHRpb24oXG5cdFx0XHRcdFx0XHRrZXksXG5cdFx0XHRcdFx0XHR0cmFuc2xhdGlvbl90b19kaXNwbGF5X25hbWUodHJhbnNsYXRpb25zW2tleV0pLFxuXHRcdFx0XHRcdCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZHJvcC5vbkNoYW5nZShhc3luYyB2YWx1ZSA9PiB7XG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2V0dGluZ3Muc2V0X3RyYW5zbGF0aW9uKHZhbHVlLCB0aGlzLnBsdWdpbik7XG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdH0pXG5cdFx0XHRcdGRyb3Auc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MudHJhbnNsYXRpb24pO1xuXHRcdFx0fSlcblx0XHQ7XG5cblx0XHR0aGlzLnJlbmRlckJ1aWxkQnV0dG9uKG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKSk7XG5cblx0XHQvLyBDaGFwdGVyc1xuXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpLm5hbWVFbC5jcmVhdGVFbChcImgzXCIsIHsgdGV4dDogXCJDaGFwdGVyc1wiIH0pXG5cdFx0XG5cdFx0dGhpcy5yZW5kZXJDaGFwdGVyTmFtZShuZXcgU2V0dGluZyhjb250YWluZXJFbCkpO1xuXG5cdFx0dGhpcy5yZW5kZXJDaGFwdGVyRm9ybWF0KG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKSk7XG5cdFx0XHRcdFx0XG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0XHQuc2V0TmFtZSgnUGFkIG51bWJlcnMnKVxuXHRcdFx0LnNldERlc2MoJ1doZW4gYWN0aXZlLCBwYWRzIGNoYXB0ZXIgbnVtYmVycyB3aXRoIGV4dHJhIHplcm9zLiBGb3IgZXhhbXBsZSwgXCJQc2FsbXMgNVwiIGJlY29tZXMgXCJQc2FsbXMgMDA1XCIuJylcblx0XHRcdC5hZGRUb2dnbGUodG9nZ2xlID0+IHRvZ2dsZVxuXHRcdFx0XHQuc2V0VG9vbHRpcChcIlRvZ2dsZSBhbGlnbm1lbnQgcGFkZGluZyBvZiBjaGFwdGVyIG51bWJlcnNcIilcblx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLnBhZGRlZF9jaGFwdGVyKVxuXHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MucGFkZGVkX2NoYXB0ZXIgPSB2YWx1ZTtcblx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0fSkpXG5cblx0XHQvLyBWZXJzZXNcblxuXHRcdG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKS5uYW1lRWwuY3JlYXRlRWwoXCJoM1wiLCB7IHRleHQ6IFwiVmVyc2VzXCIgfSlcblxuXHRcdHRoaXMucmVuZGVyVmVyc2VGb3JtYXQobmV3IFNldHRpbmcoY29udGFpbmVyRWwpKVxuXG5cdFx0bmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0XHQuc2V0TmFtZSgnQnVpbGQgd2l0aCBkeW5hbWljIHZlcnNlcycpXG5cdFx0XHQuc2V0RGVzYygnV2hlbiBhY3RpdmUsIHlvdXIgQmlibGUgd2lsbCBiZSBidWlsdCB3aXRoIHZlcnNlIHJlZmVyZW5jZXMgdGhhdCBjYW4gYmUgcXVpY2tseSBjaGFuZ2VkIHdoZW4geW91IHN3aXRjaCB0cmFuc2xhdGlvbnMuIFdoZW4gaW5hY3RpdmUsIHRoZSB0ZXh0IG9mIHRoZSB0cmFuc2xhdGlvbiBpcyBidWlsdCBkaXJlY3RseSBpbnRvIHlvdXIgQmlibGUuJylcblx0XHRcdC5hZGRUb2dnbGUodG9nZ2xlID0+IHRvZ2dsZVxuXHRcdFx0XHQuc2V0VG9vbHRpcChcIlRvZ2dsZSBnZW5lcmF0aW5nIHdpdGggZHluYW1pYyB2ZXJzZXNcIilcblx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmJ1aWxkX3dpdGhfZHluYW1pY192ZXJzZXMpXG5cdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5idWlsZF93aXRoX2R5bmFtaWNfdmVyc2VzID0gdmFsdWU7XG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdH0pKVxuXG5cdFx0Ly8gQm9va3Ncblx0XHRsZXQgYm9va3NfaGVhZGVyID0gbmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0Ym9va3NfaGVhZGVyLm5hbWVFbC5jcmVhdGVFbChcImgzXCIsIHsgdGV4dDogXCJCb29rc1wiIH0pXG5cdFx0Ym9va3NfaGVhZGVyLmFkZFRvZ2dsZSh0b2dnbGUgPT4ge3RvZ2dsZVxuXHRcdFx0LnNldFRvb2x0aXAoXCJUb2dnbGUgaWYgYm9va3Mgc2hvdWxkIGdlbmVyYXRlIGZvbGRlcnNcIilcblx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmJvb2tfZm9sZGVyc19lbmFibGVkKVxuXHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgdmFsdWUgPT4ge1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmJvb2tfZm9sZGVyc19lbmFibGVkID0gdmFsdWU7XG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdH0pXG5cdFx0fSlcblx0XHR0aGlzLnJlbmRlckJvb2tGb3JtYXQobmV3IFNldHRpbmcoY29udGFpbmVyRWwpKTtcblx0XHR0aGlzLnJlbmRlck5hbWVEZWxpbWV0ZXIobmV3IFNldHRpbmcoY29udGFpbmVyRWwpKTtcblx0XHR0aGlzLnJlbmRlckJvb2tDYXBpdGFsaXphdGlvbihuZXcgU2V0dGluZyhjb250YWluZXJFbCkpO1xuXHRcdHRoaXMucmVuZGVyQm9va0FiYnJldmlhdGlvbihuZXcgU2V0dGluZyhjb250YWluZXJFbCkpO1xuXHRcdHRoaXMucmVuZGVyUGFkZGVkT3JkZXJOdW1zKG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKSk7XG5cblx0XHQvLyBCb29rIGluZGV4XG5cdFx0bGV0IGluZGV4X2hlYWRlciAgPSBuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHRsZXQgaW5kZXhfbmFtZSAgPSBuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHRsZXQgaW5kZXhfbGlua3MgID0gbmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0bGV0IGluZGV4X2JvZHkgID0gbmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0aW5kZXhfaGVhZGVyXG5cdFx0XHQuYWRkVG9nZ2xlKHRvZ2dsZSA9PiB7dG9nZ2xlXG5cdFx0XHRcdC5zZXRUb29sdGlwKFwiVG9nZ2xlIGJvb2sgaW5kZXggZ2VuZXJhdGlvblwiKVxuXHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuaW5kZXhfZW5hYmxlZClcblx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jIHZhbHVlID0+IHtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5pbmRleF9lbmFibGVkID0gdmFsdWU7XG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdH0pXG5cdFx0XHR9KVxuXHRcdFx0Lm5hbWVFbC5jcmVhdGVFbChcImgzXCIsIHsgdGV4dDogXCJCb29rIGluZGV4XCIgfSlcblx0XHQ7XG5cblx0XHR0aGlzLnJlbmRlckluZGV4TmFtZShpbmRleF9uYW1lKVxuXHRcdHRoaXMucmVuZGVySW5kZXhCb29rTGluayhpbmRleF9saW5rcylcblx0XHR0aGlzLnJlbmRlckluZGV4Qm9keShpbmRleF9ib2R5KVxuXG5cdFx0Ly8gQ2hhcHRlciBpbmRleFxuXHRcdGxldCBjaGFwdGVyX2luZGV4X2hlYWRlciAgPSBuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHRsZXQgY2hhcHRlcl9pbmRleF9uYW1lICA9IG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdGxldCBjaGFwdGVyX2luZGV4X2xpbmtzICA9IG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKVxuXHRcdGxldCBjaGFwdGVyX2luZGV4X2JvZHkgID0gbmV3IFNldHRpbmcoY29udGFpbmVyRWwpXG5cdFx0Y2hhcHRlcl9pbmRleF9oZWFkZXJcblx0XHRcdC5hZGRUb2dnbGUodG9nZ2xlID0+IHt0b2dnbGVcblx0XHRcdFx0LnNldFRvb2x0aXAoXCJUb2dnbGUgY2hhcHRlciBpbmRleCBnZW5lcmF0aW9uXCIpXG5cdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5jaGFwdGVyX2luZGV4X2VuYWJsZWQpXG5cdFx0XHRcdC5vbkNoYW5nZShhc3luYyB2YWx1ZSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuY2hhcHRlcl9pbmRleF9lbmFibGVkID0gdmFsdWU7XG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdH0pXG5cdFx0XHR9KVxuXHRcdFx0Lm5hbWVFbC5jcmVhdGVFbChcImgzXCIsIHsgdGV4dDogXCJDaGFwdGVyIGluZGV4c1wiIH0pXG5cdFx0O1xuXHRcdHRoaXMucmVuZGVyQ2hhcHRlckluZGV4TmFtZShjaGFwdGVyX2luZGV4X25hbWUpXG5cdFx0dGhpcy5yZW5kZXJDaGFwdGVySW5kZXhMaW5rKGNoYXB0ZXJfaW5kZXhfbGlua3MpXG5cdFx0dGhpcy5yZW5kZXJDaGFwdGVySW5kZXhCb2R5KGNoYXB0ZXJfaW5kZXhfYm9keSlcblxuXHRcdC8vIEFmdGVyXG5cblx0XHR0aGlzLnJlbmRlckJ1aWxkQnV0dG9uKG5ldyBTZXR0aW5nKGNvbnRhaW5lckVsKSk7XG5cdH1cblxuXHQvLyBUb3AgcmVuZGVyZXJzXG5cblx0cmVuZGVyQmlibGVGb2xkZXIoc2V0dGluZzogU2V0dGluZykge1xuXHRcdHNldHRpbmcuY2xlYXIoKVxuXHRcdHNldHRpbmdcblx0XHRcdC5zZXROYW1lKCdGb2xkZXInKVxuXHRcdFx0LnNldERlc2MoJ1RoZSBwYXRoIHRvIHRoZSBmb2xkZXIgd2hlcmUgeW91ciBCaWJsZSB3aWxsIGJlIHBsYWNlZC4gVGhlIGZvbGRlciBzaG91bGQgYmUgZW1wdHkgZm9yIHlvdXIgQmlibGUuIElmIHRoZSBwYXRoIGRvZXMgbm90IGV4aXN0IGl0IHdpbGwgYmUgY3JlYXRlZC4nKVxuXHRcdFx0LmFkZEV4dHJhQnV0dG9uKGJ0biA9PiBidG5cblx0XHRcdFx0LnNldEljb24oXCJyb3RhdGUtY2N3XCIpXG5cdFx0XHRcdC5zZXRUb29sdGlwKFwiUmVzZXQgdmFsdWVcIilcblx0XHRcdFx0Lm9uQ2xpY2soYXN5bmMgKCkgPT4ge1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmJpYmxlX2ZvbGRlclxuXHRcdFx0XHRcdFx0PSBERUZBVUxUX1NFVFRJTkdTLmJpYmxlX2ZvbGRlcjtcblx0XHRcdFx0XHR0aGlzLnJlbmRlckJpYmxlRm9sZGVyKHNldHRpbmcpO1xuXHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHR9KVxuXHRcdFx0KVxuXHRcdFx0LmFkZFRleHQodGV4dCA9PiB0ZXh0XG5cdFx0XHRcdC5zZXRQbGFjZWhvbGRlcihcIkV4YW1wbGU6IFwiICsgREVGQVVMVF9TRVRUSU5HUy5iaWJsZV9mb2xkZXIpXG5cdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5iaWJsZV9mb2xkZXIpXG5cdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5iaWJsZV9mb2xkZXIgPSB2YWx1ZTtcblx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0fSlcblx0XHRcdClcblx0XHQ7XG5cdH1cblxuXHRyZW5kZXJCdWlsZEJ1dHRvbihzZXR0aW5nOiBTZXR0aW5nKSB7XG5cdFx0c2V0dGluZ1xuXHRcdFx0LmFkZEJ1dHRvbihidG4gPT4gYnRuXG5cdFx0XHRcdC5zZXRCdXR0b25UZXh0KFwiQnVpbGRcIilcblx0XHRcdFx0LnNldFRvb2x0aXAoXCJCdWlsZCB5b3VyIGJpYmxlXCIpXG5cdFx0XHRcdC5zZXRDdGEoKVxuXHRcdFx0XHQub25DbGljayhhc3luYyBfID0+IHtcblx0XHRcdFx0XHR0aGlzLmNsb3NlKClcblx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5idWlsZF9iaWJsZSgpXG5cdFx0XHRcdH0pXG5cdFx0XHQpXG5cdFx0O1xuXHR9XG5cblx0Ly8gQm9vayByZW5kZXJlcnNcblxuXHRyZW5kZXJCb29rRm9ybWF0KHNldHRpbmc6IFNldHRpbmcpIHtcblx0XHRzZXR0aW5nLmNsZWFyKClcblx0XHRzZXR0aW5nXG5cdFx0XHQuc2V0TmFtZSgnTmFtZSBmb3JtYXQnKVxuXHRcdFx0LnNldERlc2MoJ1RoZSBmb3JtYXQgZm9yIHRoZSBuYW1lcyBvZiB0aGUgZm9sZGVycyBvZiBlYWNoIGJvb2sgb2YgdGhlIGJpYmxlLiBGb3IgZXhhbXBsZSwgXCJ7b3JkZXJ9IHtuYW1lfVwiIHdvdWxkIGJlY29tZSBcIjIgRXhvZHVzXCIuIExlYXZlIGJsYW5rIHRvIG5vdCBoYXZlIGZvbGRlcnMgZm9yIGVhY2ggYm9vay4nKVxuXHRcdFx0LmFkZEV4dHJhQnV0dG9uKGJ0biA9PiBidG5cblx0XHRcdFx0LnNldEljb24oXCJyb3RhdGUtY2N3XCIpXG5cdFx0XHRcdC5zZXRUb29sdGlwKFwiUmVzZXQgdmFsdWVcIilcblx0XHRcdFx0Lm9uQ2xpY2soYXN5bmMgKCkgPT4ge1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmJvb2tfbmFtZV9mb3JtYXRcblx0XHRcdFx0XHRcdD0gREVGQVVMVF9TRVRUSU5HUy5ib29rX25hbWVfZm9ybWF0O1xuXHRcdFx0XHRcdHRoaXMucmVuZGVyQm9va0Zvcm1hdChzZXR0aW5nKTtcblx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0fSlcblx0XHRcdClcblx0XHRcdC5hZGRUZXh0KHRleHQgPT4gdGV4dFxuXHRcdFx0XHQuc2V0UGxhY2Vob2xkZXIoXCJFeGFtcGxlOiBcIiArIERFRkFVTFRfU0VUVElOR1MuYm9va19uYW1lX2Zvcm1hdClcblx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmJvb2tfbmFtZV9mb3JtYXQpXG5cdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5ib29rX25hbWVfZm9ybWF0ID0gdmFsdWU7XG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdH0pXG5cdFx0XHQpXG5cdFx0O1xuXHR9XG5cblx0cmVuZGVyQm9va0FiYnJldmlhdGlvbihzZXR0aW5nOiBTZXR0aW5nKSB7XG5cdFx0c2V0dGluZy5jbGVhcigpXG5cdFx0c2V0dGluZ1xuXHRcdFx0LnNldE5hbWUoJ0FiYnJldmlhdGUgbmFtZXMnKVxuXHRcdFx0LnNldERlc2MoJ1doZW4gYWN0aXZlLCBUaGUgbmFtZXMgb2YgYm9va3Mgd2lsbCBiZSBhYmJyZXZpYXRlZCB0byB0aHJlZSBsZXR0ZXJzLiBGb3IgZXhhbXBsZSwgXCJHZW5lc2lzXCIgYmVjb21lcyBcIkdlblwiIGFuZCBcIjEgS2luZ3NcIiBiZWNvbWVzIFwiMUtpXCIuIChNYXkgY2F1c2UgaXNzdWVzIGluIHNvbWUgdHJhbnNsYXRpb25zLiknKVxuXHRcdFx0LmFkZFRvZ2dsZSh0b2dnbGUgPT4gdG9nZ2xlXG5cdFx0XHRcdC5zZXRUb29sdGlwKFwiVG9nZ2xlIGJvb2sgbmFtZSBhYmJyZXZpYXRpb25cIilcblx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmJvb2tfbmFtZV9hYmJyZXZpYXRlZClcblx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmJvb2tfbmFtZV9hYmJyZXZpYXRlZCA9IHZhbHVlO1xuXHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHR9KVxuXHRcdFx0KVxuXHRcdDtcblx0fVxuXG5cdHJlbmRlckJvb2tDYXBpdGFsaXphdGlvbihzZXR0aW5nOiBTZXR0aW5nKSB7XG5cdFx0c2V0dGluZy5jbGVhcigpXG5cdFx0c2V0dGluZ1xuXHRcdFx0LnNldE5hbWUoJ05hbWUgY2FwaXRhbGl6YXRpb24nKVxuXHRcdFx0LnNldERlc2MoJ0RpY3RhdGVzIHRoZSBjYXBpdGFsaXphdGlvbiBvZiBib29rIG5hbWVzLicpXG5cdFx0XHQuYWRkRHJvcGRvd24oZHJvcCA9PiBkcm9wXG5cdFx0XHRcdC5hZGRPcHRpb24oXCJsb3dlcl9jYXNlXCIsIFwiTG93ZXIgY2FzZVwiKVxuXHRcdFx0XHQuYWRkT3B0aW9uKFwibmFtZV9jYXNlXCIsIFwiTmFtZSBjYXNlXCIpXG5cdFx0XHRcdC5hZGRPcHRpb24oXCJ1cHBlcl9jYXNlXCIsIFwiVXBwZXIgY2FzZVwiKVxuXHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuYm9va19uYW1lX2NhcGl0YWxpemF0aW9uKVxuXHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuYm9va19uYW1lX2NhcGl0YWxpemF0aW9uID0gdmFsdWU7XG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdH0pXG5cdFx0XHQpXG5cdFx0O1xuXHR9XG5cblx0cmVuZGVyTmFtZURlbGltZXRlcihzZXR0aW5nOiBTZXR0aW5nKSB7XG5cdFx0c2V0dGluZy5jbGVhcigpXG5cdFx0c2V0dGluZ1xuXHRcdFx0LnNldE5hbWUoJ05hbWUgZGVsaW1pdGVyJylcblx0XHRcdC5zZXREZXNjKCdUaGUgY2hhcmFjdGVycyBzZXBhcmF0aW5nIHdvcmRzIGluIGJvb2sgbmFtZXMsIHN1Y2ggYXMgdGhlIHNwYWNlcyBpbiBcIjEgSm9oblwiIG9yIFwiU29uZyBvZiBTb2xvbW9uXCIuJylcblx0XHRcdC5hZGRFeHRyYUJ1dHRvbihidG4gPT4gYnRuXG5cdFx0XHRcdC5zZXRJY29uKFwicm90YXRlLWNjd1wiKVxuXHRcdFx0XHQuc2V0VG9vbHRpcChcIlJlc2V0IHZhbHVlXCIpXG5cdFx0XHRcdC5vbkNsaWNrKGFzeW5jICgpID0+IHtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5ib29rX25hbWVfZGVsaW1pdGVyXG5cdFx0XHRcdFx0XHQ9IERFRkFVTFRfU0VUVElOR1MuYm9va19uYW1lX2RlbGltaXRlcjtcblx0XHRcdFx0XHR0aGlzLnJlbmRlck5hbWVEZWxpbWV0ZXIoc2V0dGluZyk7XG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdH0pXG5cdFx0XHQpXG5cdFx0XHQuYWRkVGV4dCh0ZXh0ID0+IHRleHRcblx0XHRcdFx0LnNldFBsYWNlaG9sZGVyKCdFeGFtcGxlOiBcIicgKyBERUZBVUxUX1NFVFRJTkdTLmJvb2tfbmFtZV9kZWxpbWl0ZXIgKyAnXCInKVxuXHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuYm9va19uYW1lX2RlbGltaXRlcilcblx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmJvb2tfbmFtZV9kZWxpbWl0ZXIgPSB2YWx1ZTtcblx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0fSlcblx0XHRcdClcblx0XHQ7XG5cdH1cblxuXHRyZW5kZXJQYWRkZWRPcmRlck51bXMoc2V0dGluZzogU2V0dGluZykge1xuXHRcdHNldHRpbmcuY2xlYXIoKVxuXHRcdHNldHRpbmdcblx0XHRcdC5zZXROYW1lKCdQYWQgb3JkZXIgbnVtYmVycycpXG5cdFx0XHQuc2V0RGVzYygnV2hlbiBBY3RpdmUsIHBhZHMgb3JkZXIgbnVtYmVycyB3aXRoIGV4dHJhIHplcm9zLiBGb3IgZXhhbXBsZSwgXCIxIEdlbmVzaXNcIiB3b3VsZCBiZWNvbWUgXCIwMSBHZW5zaXNcIiB3aGVuIGFjdGl2ZS4nKVxuXHRcdFx0LmFkZFRvZ2dsZSh0b2dnbGUgPT4gdG9nZ2xlXG5cdFx0XHRcdC5zZXRUb29sdGlwKFwiVG9nZ2xlIGFsaWdubWVudCBwYWRkaW5nIG9mIGJvb2sgb3JkZXIgbnVtYmVyc1wiKVxuXHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MucGFkZGVkX29yZGVyKVxuXHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MucGFkZGVkX29yZGVyID0gdmFsdWU7XG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdH0pXG5cdFx0XHQpXG5cdFx0O1xuXHR9XG5cblx0Ly8gQ2hhcHRlciByZW5kZXJlcnNcblxuXHRyZW5kZXJDaGFwdGVyRm9ybWF0KHNldHRpbmc6IFNldHRpbmcpIHtcblx0XHRzZXR0aW5nLmNsZWFyKClcblx0XHRzZXR0aW5nXG5cdFx0XHQuc2V0TmFtZSgnQm9keSBmb3JtYXQnKVxuXHRcdFx0LnNldERlc2MoJ1RoZSBmb3JtYXQgZm9yIHRoZSBjb250ZW50cyBvZiBjaGFwdGVycy4nKVxuXHRcdFx0LmFkZEV4dHJhQnV0dG9uKGJ0biA9PiBidG5cblx0XHRcdFx0LnNldEljb24oXCJyb3RhdGUtY2N3XCIpXG5cdFx0XHRcdC5zZXRUb29sdGlwKFwiUmVzZXQgdmFsdWVcIilcblx0XHRcdFx0Lm9uQ2xpY2soYXN5bmMgKCkgPT4ge1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmNoYXB0ZXJfYm9keV9mb3JtYXRcblx0XHRcdFx0XHRcdD0gREVGQVVMVF9TRVRUSU5HUy5jaGFwdGVyX2JvZHlfZm9ybWF0O1xuXHRcdFx0XHRcdHRoaXMucmVuZGVyQ2hhcHRlckZvcm1hdChzZXR0aW5nKTtcblx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0fSlcblx0XHRcdClcblx0XHRcdC5hZGRUZXh0QXJlYSh0ZXh0ID0+IHRleHRcblx0XHRcdFx0LnNldFBsYWNlaG9sZGVyKFwiRXhhbXBsZTogXCIgKyBERUZBVUxUX1NFVFRJTkdTLmNoYXB0ZXJfYm9keV9mb3JtYXQpXG5cdFx0XHRcdC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5jaGFwdGVyX2JvZHlfZm9ybWF0KVxuXHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuY2hhcHRlcl9ib2R5X2Zvcm1hdCA9IHZhbHVlO1xuXHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0KVxuXHRcdFx0KVxuXHRcdDtcblx0fVxuXG5cdHJlbmRlckNoYXB0ZXJOYW1lKHNldHRpbmc6IFNldHRpbmcpIHtcblx0XHRzZXR0aW5nLmNsZWFyKClcblx0XHRzZXR0aW5nXG5cdFx0XHQuc2V0TmFtZSgnTmFtZSBmb3JtYXQnKVxuXHRcdFx0LnNldERlc2MoJ1RoZSBmb3JtYXQgZm9yIHRoZSBuYW1lcyBvZiBjaGFwdGVycy4gRm9yIGV4YW1wbGUsIFwie2Jvb2t9IHtjaGFwdGVyfVwiIHdvdWxkIGJlY29tZSBcIlBzYWxtcyAyM1wiLicpXG5cdFx0XHQuYWRkRXh0cmFCdXR0b24oYnRuID0+IGJ0blxuXHRcdFx0XHQuc2V0SWNvbihcInJvdGF0ZS1jY3dcIilcblx0XHRcdFx0LnNldFRvb2x0aXAoXCJSZXNldCB2YWx1ZVwiKVxuXHRcdFx0XHQub25DbGljayhhc3luYyAoKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuY2hhcHRlcl9uYW1lX2Zvcm1hdFxuXHRcdFx0XHRcdFx0PSBERUZBVUxUX1NFVFRJTkdTLmNoYXB0ZXJfbmFtZV9mb3JtYXQ7XG5cdFx0XHRcdFx0dGhpcy5yZW5kZXJDaGFwdGVyTmFtZShzZXR0aW5nKTtcblx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0fSlcblx0XHRcdClcblx0XHRcdC5hZGRUZXh0KHRleHQgPT4gdGV4dFxuXHRcdFx0XHQuc2V0UGxhY2Vob2xkZXIodGhpcy5wbHVnaW4uc2V0dGluZ3MuY2hhcHRlcl9uYW1lX2Zvcm1hdClcblx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmNoYXB0ZXJfbmFtZV9mb3JtYXQpXG5cdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5jaGFwdGVyX25hbWVfZm9ybWF0ID0gdmFsdWU7XG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdH0pXG5cdFx0XHQpXG5cdFx0O1xuXHR9XG5cblx0Ly8gVmVyc2UgcmVuZGVyc1xuXG5cdHJlbmRlclZlcnNlRm9ybWF0KHNldHRpbmc6IFNldHRpbmcpIHtcblx0XHRzZXR0aW5nLmNsZWFyKClcblx0XHRzZXR0aW5nXG5cdFx0XHQuc2V0TmFtZSgnRm9ybWF0Jylcblx0XHRcdC5zZXREZXNjKCdGb3JtYXR0aW5nIGZvciBpbmRpdmlkdWFsIHZlcnNlcy4nKVxuXHRcdFx0LmFkZEV4dHJhQnV0dG9uKGJ0biA9PiBidG5cblx0XHRcdFx0LnNldEljb24oXCJyb3RhdGUtY2N3XCIpXG5cdFx0XHRcdC5zZXRUb29sdGlwKFwiUmVzZXQgdmFsdWVcIilcblx0XHRcdFx0Lm9uQ2xpY2soYXN5bmMgKCkgPT4ge1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnZlcnNlX2JvZHlfZm9ybWF0XG5cdFx0XHRcdFx0XHQ9IERFRkFVTFRfU0VUVElOR1MudmVyc2VfYm9keV9mb3JtYXQ7XG5cdFx0XHRcdFx0dGhpcy5yZW5kZXJWZXJzZUZvcm1hdChzZXR0aW5nKTtcblx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0fSlcblx0XHRcdClcblx0XHRcdC5hZGRUZXh0QXJlYSh0ZXh0ID0+IHRleHRcblx0XHRcdFx0LnNldFBsYWNlaG9sZGVyKFwiRXhhbXBsZTogXCIgKyBERUZBVUxUX1NFVFRJTkdTLnZlcnNlX2JvZHlfZm9ybWF0KVxuXHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MudmVyc2VfYm9keV9mb3JtYXQpXG5cdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy52ZXJzZV9ib2R5X2Zvcm1hdCA9IHZhbHVlO1xuXHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHR9KVxuXHRcdFx0KVxuXHRcdDtcblx0fVxuXG5cdC8vIEJvb2sgaW5kZXhcblxuXHRyZW5kZXJJbmRleE5hbWUoc2V0dGluZzogU2V0dGluZykge1xuXHRcdHNldHRpbmcuY2xlYXIoKVxuXHRcdHNldHRpbmdcblx0XHRcdC5zZXROYW1lKCdOYW1lIGZvcm1hdCcpXG5cdFx0XHQuc2V0RGVzYygnVGhlIGZvcm1hdCBmb3IgdGhlIG5hbWUgb2YgdGhlIGJvb2sgaW5kZXguJylcblx0XHRcdC5hZGRFeHRyYUJ1dHRvbihidG4gPT4gYnRuXG5cdFx0XHRcdC5zZXRJY29uKFwicm90YXRlLWNjd1wiKVxuXHRcdFx0XHQuc2V0VG9vbHRpcChcIlJlc2V0IHZhbHVlXCIpXG5cdFx0XHRcdC5vbkNsaWNrKGFzeW5jICgpID0+IHtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5pbmRleF9uYW1lX2Zvcm1hdFxuXHRcdFx0XHRcdFx0PSBERUZBVUxUX1NFVFRJTkdTLmluZGV4X25hbWVfZm9ybWF0O1xuXHRcdFx0XHRcdHRoaXMucmVuZGVySW5kZXhOYW1lKHNldHRpbmcpO1xuXHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHR9KVxuXHRcdFx0KVxuXHRcdFx0LmFkZFRleHQodGV4dCA9PiB0ZXh0XG5cdFx0XHRcdC5zZXRQbGFjZWhvbGRlcihERUZBVUxUX1NFVFRJTkdTLmluZGV4X25hbWVfZm9ybWF0KVxuXHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuaW5kZXhfbmFtZV9mb3JtYXQpXG5cdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5pbmRleF9uYW1lX2Zvcm1hdCA9IHZhbHVlO1xuXHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHR9KVxuXHRcdFx0KVxuXHRcdDtcblx0fVxuXG5cdHJlbmRlckluZGV4Qm9va0xpbmsoc2V0dGluZzogU2V0dGluZykge1xuXHRcdHNldHRpbmcuY2xlYXIoKVxuXHRcdHNldHRpbmdcblx0XHRcdC5zZXROYW1lKCdCb29rIGVsZW1lbnQgZm9ybWF0Jylcblx0XHRcdC5zZXREZXNjKCdUaGUgZm9ybWF0IGZvciBlYWNoIGJvb2sgZWxlbWVudCBpbiBhIGxpc3QuJylcblx0XHRcdC5hZGRFeHRyYUJ1dHRvbihidG4gPT4gYnRuXG5cdFx0XHRcdC5zZXRJY29uKFwicm90YXRlLWNjd1wiKVxuXHRcdFx0XHQuc2V0VG9vbHRpcChcIlJlc2V0IHZhbHVlXCIpXG5cdFx0XHRcdC5vbkNsaWNrKGFzeW5jICgpID0+IHtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5pbmRleF9saW5rX2Zvcm1hdFxuXHRcdFx0XHRcdFx0PSBERUZBVUxUX1NFVFRJTkdTLmluZGV4X2xpbmtfZm9ybWF0O1xuXHRcdFx0XHRcdHRoaXMucmVuZGVySW5kZXhCb29rTGluayhzZXR0aW5nKTtcblx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0fSlcblx0XHRcdClcblx0XHRcdC5hZGRUZXh0KHRleHQgPT4gdGV4dFxuXHRcdFx0XHQuc2V0UGxhY2Vob2xkZXIoREVGQVVMVF9TRVRUSU5HUy5pbmRleF9saW5rX2Zvcm1hdClcblx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmluZGV4X2xpbmtfZm9ybWF0KVxuXHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuaW5kZXhfbGlua19mb3JtYXQgPSB2YWx1ZTtcblx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0fSlcblx0XHRcdClcblx0XHQ7XG5cdFx0c2V0dGluZy5zZXREaXNhYmxlZCghdGhpcy5wbHVnaW4uc2V0dGluZ3MuaW5kZXhfZW5hYmxlZClcblx0fVxuXG5cdHJlbmRlckluZGV4Qm9keShzZXR0aW5nOiBTZXR0aW5nKSB7XG5cdFx0c2V0dGluZy5jbGVhcigpXG5cdFx0c2V0dGluZ1xuXHRcdFx0LnNldE5hbWUoJ0JvZHkgZm9ybWF0Jylcblx0XHRcdC5zZXREZXNjKCdUaGUgZm9ybWF0IGZvciB0aGUgY29udGVudCBvZiB0aGUgYm9vayBpbmRleC4nKVxuXHRcdFx0LmFkZEV4dHJhQnV0dG9uKGJ0biA9PiBidG5cblx0XHRcdFx0LnNldEljb24oXCJyb3RhdGUtY2N3XCIpXG5cdFx0XHRcdC5zZXRUb29sdGlwKFwiUmVzZXQgdmFsdWVcIilcblx0XHRcdFx0Lm9uQ2xpY2soYXN5bmMgKCkgPT4ge1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmluZGV4X2Zvcm1hdFxuXHRcdFx0XHRcdFx0PSBERUZBVUxUX1NFVFRJTkdTLmluZGV4X2Zvcm1hdDtcblx0XHRcdFx0XHR0aGlzLnJlbmRlckluZGV4Qm9keShzZXR0aW5nKTtcblx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0fSlcblx0XHRcdClcblx0XHRcdC5hZGRUZXh0QXJlYSh0ZXh0ID0+IHRleHRcblx0XHRcdFx0LnNldFBsYWNlaG9sZGVyKERFRkFVTFRfU0VUVElOR1MuaW5kZXhfZm9ybWF0KVxuXHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuaW5kZXhfZm9ybWF0KVxuXHRcdFx0XHQub25DaGFuZ2UoYXN5bmMgKHZhbHVlKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuaW5kZXhfZm9ybWF0ID0gdmFsdWU7XG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdH0pXG5cdFx0XHQpXG5cdFx0O1xuXHRcdHNldHRpbmcuc2V0RGlzYWJsZWQoIXRoaXMucGx1Z2luLnNldHRpbmdzLmluZGV4X2VuYWJsZWQpXG5cdH1cblxuXHQvLyBDaGFwdGVyIGluZGV4XG5cblx0cmVuZGVyQ2hhcHRlckluZGV4TmFtZShzZXR0aW5nOiBTZXR0aW5nKSB7XG5cdFx0c2V0dGluZy5jbGVhcigpXG5cdFx0c2V0dGluZ1xuXHRcdFx0LnNldE5hbWUoJ05hbWUgZm9ybWF0Jylcblx0XHRcdC5zZXREZXNjKCdUaGUgZm9ybWF0IGZvciB0aGUgbmFtZSBvZiB0aGUgY2hhcHRlciBpbmRleC4nKVxuXHRcdFx0LmFkZEV4dHJhQnV0dG9uKGJ0biA9PiBidG5cblx0XHRcdFx0LnNldEljb24oXCJyb3RhdGUtY2N3XCIpXG5cdFx0XHRcdC5zZXRUb29sdGlwKFwiUmVzZXQgdmFsdWVcIilcblx0XHRcdFx0Lm9uQ2xpY2soYXN5bmMgKCkgPT4ge1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmNoYXB0ZXJfaW5kZXhfbmFtZV9mb3JtYXRcblx0XHRcdFx0XHRcdD0gREVGQVVMVF9TRVRUSU5HUy5jaGFwdGVyX2luZGV4X25hbWVfZm9ybWF0O1xuXHRcdFx0XHRcdHRoaXMucmVuZGVyQ2hhcHRlckluZGV4TmFtZShzZXR0aW5nKTtcblx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0fSlcblx0XHRcdClcblx0XHRcdC5hZGRUZXh0KHRleHQgPT4gdGV4dFxuXHRcdFx0XHQuc2V0UGxhY2Vob2xkZXIoREVGQVVMVF9TRVRUSU5HUy5jaGFwdGVyX2luZGV4X25hbWVfZm9ybWF0KVxuXHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuY2hhcHRlcl9pbmRleF9uYW1lX2Zvcm1hdClcblx0XHRcdFx0Lm9uQ2hhbmdlKGFzeW5jICh2YWx1ZSkgPT4ge1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLmNoYXB0ZXJfaW5kZXhfbmFtZV9mb3JtYXQgPSB2YWx1ZTtcblx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0fSlcblx0XHRcdClcblx0XHQ7XG5cdFx0c2V0dGluZy5zZXREaXNhYmxlZCghdGhpcy5wbHVnaW4uc2V0dGluZ3MuaW5kZXhfZW5hYmxlZClcblx0fVxuXG5cdHJlbmRlckNoYXB0ZXJJbmRleExpbmsoc2V0dGluZzogU2V0dGluZykge1xuXHRcdHNldHRpbmcuY2xlYXIoKVxuXHRcdHNldHRpbmdcblx0XHRcdC5zZXROYW1lKCdDaGFwdGVyIGVsZW1lbnQgZm9ybWF0Jylcblx0XHRcdC5zZXREZXNjKCdUaGUgZm9ybWF0IGZvciBlYWNoIGNoYXB0ZXIgZWxlbWVudCBpbiBhIGxpc3QuJylcblx0XHRcdC5hZGRFeHRyYUJ1dHRvbihidG4gPT4gYnRuXG5cdFx0XHRcdC5zZXRJY29uKFwicm90YXRlLWNjd1wiKVxuXHRcdFx0XHQuc2V0VG9vbHRpcChcIlJlc2V0IHZhbHVlXCIpXG5cdFx0XHRcdC5vbkNsaWNrKGFzeW5jICgpID0+IHtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5jaGFwdGVyX2luZGV4X2xpbmtfZm9ybWF0XG5cdFx0XHRcdFx0XHQ9IERFRkFVTFRfU0VUVElOR1MuY2hhcHRlcl9pbmRleF9saW5rX2Zvcm1hdDtcblx0XHRcdFx0XHR0aGlzLnJlbmRlckNoYXB0ZXJJbmRleExpbmsoc2V0dGluZyk7XG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdH0pXG5cdFx0XHQpXG5cdFx0XHQuYWRkVGV4dCh0ZXh0ID0+IHRleHRcblx0XHRcdFx0LnNldFBsYWNlaG9sZGVyKERFRkFVTFRfU0VUVElOR1MuY2hhcHRlcl9pbmRleF9saW5rX2Zvcm1hdClcblx0XHRcdFx0LnNldFZhbHVlKHRoaXMucGx1Z2luLnNldHRpbmdzLmNoYXB0ZXJfaW5kZXhfbGlua19mb3JtYXQpXG5cdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5jaGFwdGVyX2luZGV4X2xpbmtfZm9ybWF0ID0gdmFsdWU7XG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdH0pXG5cdFx0XHQpXG5cdFx0O1xuXHRcdHNldHRpbmcuc2V0RGlzYWJsZWQoIXRoaXMucGx1Z2luLnNldHRpbmdzLmluZGV4X2VuYWJsZWQpXG5cdH1cblxuXHRyZW5kZXJDaGFwdGVySW5kZXhCb2R5KHNldHRpbmc6IFNldHRpbmcpIHtcblx0XHRzZXR0aW5nLmNsZWFyKClcblx0XHRzZXR0aW5nXG5cdFx0XHQuc2V0TmFtZSgnQ2hhcHRlciBmb3JtYXQnKVxuXHRcdFx0LnNldERlc2MoJ1RoZSBmb3JtYXQgZm9yIHRoZSBjb250ZW50IG9mIHRoZSBjaGFwdGVyIGluZGV4LicpXG5cdFx0XHQuYWRkRXh0cmFCdXR0b24oYnRuID0+IGJ0blxuXHRcdFx0XHQuc2V0SWNvbihcInJvdGF0ZS1jY3dcIilcblx0XHRcdFx0LnNldFRvb2x0aXAoXCJSZXNldCB2YWx1ZVwiKVxuXHRcdFx0XHQub25DbGljayhhc3luYyAoKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5wbHVnaW4uc2V0dGluZ3MuY2hhcHRlcl9pbmRleF9mb3JtYXRcblx0XHRcdFx0XHRcdD0gREVGQVVMVF9TRVRUSU5HUy5jaGFwdGVyX2luZGV4X2Zvcm1hdDtcblx0XHRcdFx0XHR0aGlzLnJlbmRlckNoYXB0ZXJJbmRleEJvZHkoc2V0dGluZyk7XG5cdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uc2F2ZVNldHRpbmdzKCk7XG5cdFx0XHRcdH0pXG5cdFx0XHQpXG5cdFx0XHQuYWRkVGV4dEFyZWEodGV4dCA9PiB0ZXh0XG5cdFx0XHRcdC5zZXRQbGFjZWhvbGRlcihERUZBVUxUX1NFVFRJTkdTLmNoYXB0ZXJfaW5kZXhfZm9ybWF0KVxuXHRcdFx0XHQuc2V0VmFsdWUodGhpcy5wbHVnaW4uc2V0dGluZ3MuY2hhcHRlcl9pbmRleF9mb3JtYXQpXG5cdFx0XHRcdC5vbkNoYW5nZShhc3luYyAodmFsdWUpID0+IHtcblx0XHRcdFx0XHR0aGlzLnBsdWdpbi5zZXR0aW5ncy5jaGFwdGVyX2luZGV4X2Zvcm1hdCA9IHZhbHVlO1xuXHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLnNhdmVTZXR0aW5ncygpO1xuXHRcdFx0XHR9KVxuXHRcdFx0KVxuXHRcdDtcblx0XHRzZXR0aW5nLnNldERpc2FibGVkKCF0aGlzLnBsdWdpbi5zZXR0aW5ncy5pbmRleF9lbmFibGVkKVxuXHR9XG5cblx0cmVmcmVzaCgpIHtcblx0XHR0aGlzLmNvbnRlbnRFbC5lbXB0eSgpXG5cdFx0dGhpcy5yZW5kZXIoKVxuXHR9XG59XG5cbmNsYXNzIEVycm9yTW9kYWwgZXh0ZW5kcyBNb2RhbCB7XG5cdHBsdWdpbjogTXlCaWJsZVxuXHR0aXRsZTogc3RyaW5nXG5cdGJvZHk6IHN0cmluZ1xuXG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwLCBwbHVnaW46IE15QmlibGUsIHRpdGxlOnN0cmluZywgYm9keTpzdHJpbmcpIHtcblx0XHRzdXBlcihhcHApO1xuXHRcdHRoaXMucGx1Z2luID0gcGx1Z2luO1xuXHRcdHRoaXMudGl0bGUgPSB0aXRsZTtcblx0XHR0aGlzLmJvZHkgPSBib2R5O1xuXHR9XG5cblx0b25PcGVuKCkge1xuXHRcdGNvbnN0IHsgY29udGVudEVsIH0gPSB0aGlzO1xuXG5cdFx0Y29udGVudEVsLmNyZWF0ZUVsKFwiaDFcIiwgeyB0ZXh0OiB0aGlzLnRpdGxlIH0pO1xuXHRcdGNvbnRlbnRFbC5jcmVhdGVFbChcInNwYW5cIiwgeyB0ZXh0OiB0aGlzLmJvZHkgfSk7XG5cblx0XHRjb250ZW50RWwuY3JlYXRlRWwoXCJwXCIsIHt9KTtcblxuXHRcdG5ldyBTZXR0aW5nKGNvbnRlbnRFbClcblx0XHRcdC5hZGRCdXR0b24oKGJ0bikgPT5cblx0XHRcdFx0YnRuXG5cdFx0XHRcdFx0LnNldEJ1dHRvblRleHQoXCJDbG9zZVwiKVxuXHRcdFx0XHRcdC5vbkNsaWNrKCgpID0+IHtcblx0XHRcdFx0XHRcdHRoaXMuY2xvc2UoKTtcblx0XHRcdFx0XHR9KVxuXHRcdFx0KVxuXHR9XG5cblx0b25DbG9zZSgpIHtcblx0XHRjb25zdCB7IGNvbnRlbnRFbCB9ID0gdGhpcztcblx0XHRjb250ZW50RWwuZW1wdHkoKTtcblx0fVxufVxuXG5jbGFzcyBDbGVhckxvY2FsRmlsZXNNb2RhbCBleHRlbmRzIE1vZGFsIHtcblx0cGx1Z2luOiBNeUJpYmxlO1xuXG5cdGNvbnN0cnVjdG9yKGFwcDogQXBwLCBwbHVnaW46IE15QmlibGUpIHtcblx0XHRzdXBlcihhcHApO1xuXHRcdHRoaXMucGx1Z2luID0gcGx1Z2luO1xuXHR9XG5cblx0b25PcGVuKCkge1xuXHRcdGNvbnN0IHsgY29udGVudEVsIH0gPSB0aGlzO1xuXG5cdFx0bGV0IGJpYmxlX3BhdGggPSB0aGlzLnBsdWdpbi5zZXR0aW5ncy5iaWJsZV9mb2xkZXI7XG5cblx0XHRjb250ZW50RWwuY3JlYXRlRWwoXCJoMVwiLCB7IHRleHQ6IFwiQ2xlYXIgbG9jYWwgZmlsZXM/XCIgfSk7XG5cdFx0Y29udGVudEVsLmNyZWF0ZUVsKFwic3BhblwiLCB7XG5cdFx0XHR0ZXh0OiBcIllvdSBhcmUgYWJvdXQgdG8gY2xlYXIgb3V0IGFsbCBmaWxlcyBhZGRlZCBieSBNeSBCaWJsZSBmcm9tIHlvdXIgZmlsZSBzeXN0ZW0uIFRoaXMgaW5jbHVkZXMgdGVtcG9yYXkgY2FjaGVkIGNoYXB0ZXJzIGFuZCB0cmFuc2xhdGlvbnMgeW91IG1hbnVhbGx5IGRvd25sb2FkZWQuXCJcblx0XHRcdFx0LmZvcm1hdChiaWJsZV9wYXRoKVxuXHRcdH0pO1xuXHRcdGNvbnRlbnRFbC5jcmVhdGVFbChcInBcIiwge1xuXHRcdFx0dGV4dDogXCJEbyB5b3Ugd2FudCB0byBjbGVhciB0aGVzZSBmaWxlcz9cIlxuXHRcdH0pO1xuXHRcdGNvbnRlbnRFbC5jcmVhdGVFbChcInBcIiwge30pO1xuXG5cdFx0bmV3IFNldHRpbmcoY29udGVudEVsKVxuXHRcdFx0LmFkZEJ1dHRvbigoYnRuKSA9PlxuXHRcdFx0XHRidG5cblx0XHRcdFx0XHQuc2V0QnV0dG9uVGV4dChcIkNhbmNlbFwiKVxuXHRcdFx0XHRcdC5vbkNsaWNrKCgpID0+IHtcblx0XHRcdFx0XHRcdHRoaXMuY2xvc2UoKTtcblx0XHRcdFx0XHR9KVxuXHRcdFx0KVxuXHRcdFx0LmFkZEJ1dHRvbigoYnRuKSA9PlxuXHRcdFx0XHRidG5cblx0XHRcdFx0XHQuc2V0QnV0dG9uVGV4dChcIkNsZWFyIGZpbGVzXCIpXG5cdFx0XHRcdFx0LnNldEN0YSgpXG5cdFx0XHRcdFx0Lm9uQ2xpY2soYXN5bmMgKCkgPT4ge1xuXHRcdFx0XHRcdFx0dGhpcy5jbG9zZSgpO1xuXHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5wbHVnaW4uYmlibGVfYXBpLmNsZWFyX2xvY2FsX2ZpbGVzKCk7XG5cdFx0XHRcdFx0XHRuZXcgTm90aWNlKFwiRmlsZXMgY2xlYXJlZCFcIik7XG5cdFx0XHRcdFx0fSlcblx0XHRcdCk7XG5cdH1cblxuXHRvbkNsb3NlKCkge1xuXHRcdGNvbnN0IHsgY29udGVudEVsIH0gPSB0aGlzO1xuXHRcdGNvbnRlbnRFbC5lbXB0eSgpO1xuXHR9XG59XG5cbmNsYXNzIENsZWFyT2xkQmlibGVGaWxlc01vZGFsIGV4dGVuZHMgTW9kYWwge1xuXHRwbHVnaW46IE15QmlibGVcblxuXHRjb25zdHJ1Y3RvcihhcHA6IEFwcCwgcGx1Z2luOiBNeUJpYmxlKSB7XG5cdFx0c3VwZXIoYXBwKTtcblx0XHR0aGlzLnBsdWdpbiA9IHBsdWdpbjtcblx0fVxuXG5cdG9uT3BlbigpIHtcblx0XHRjb25zdCB7IGNvbnRlbnRFbCB9ID0gdGhpcztcblxuXHRcdGxldCBiaWJsZV9wYXRoID0gdGhpcy5wbHVnaW4uc2V0dGluZ3MuYmlibGVfZm9sZGVyO1xuXG5cdFx0Y29udGVudEVsLmNyZWF0ZUVsKFwiaDFcIiwgeyB0ZXh0OiBcIkJpYmxlIGZvbGRlciBpcyBub3QgZW1wdHlcIiB9KTtcblx0XHRjb250ZW50RWwuY3JlYXRlRWwoXCJzcGFuXCIsIHtcblx0XHRcdHRleHQ6IFwiVGhlIEJpYmxlIGZvbGRlciBpbiB5b3VyIHNldHRpbmdzIGlzIG5vdCBlbXB0eS4gSWYgeW91IGJ1aWx0IGEgQmlibGUgaW4gdGhpcyBmb2xkZXIgYmVmb3JlIHRoZSBuZXcgYmlibGUgbWF5IGJlIGludGVybGFjZWQgd2l0aCB0aGUgb2xkIG9uZS5cIlxuXHRcdFx0XHQuZm9ybWF0KGJpYmxlX3BhdGgpXG5cdFx0fSk7XG5cdFx0Y29udGVudEVsLmNyZWF0ZUVsKFwicFwiLCB7XG5cdFx0XHR0ZXh0OiBcIkRvIHlvdSB3YW50IHRvIGNsZWFyIHRoZSBmb2xkZXIgYmVmb3JlIGJ1aWxkaW5nIHlvdXIgQmlibGU/XCJcblx0XHR9KTtcblx0XHRjb250ZW50RWwuY3JlYXRlRWwoXCJwXCIsIHt9KTtcblxuXHRcdG5ldyBTZXR0aW5nKGNvbnRlbnRFbClcblx0XHRcdC5hZGRCdXR0b24oKGJ0bikgPT5cblx0XHRcdFx0YnRuXG5cdFx0XHRcdFx0LnNldEJ1dHRvblRleHQoXCJDYW5jZWxcIilcblx0XHRcdFx0XHQub25DbGljaygoKSA9PiB7XG5cdFx0XHRcdFx0XHR0aGlzLmNsb3NlKCk7XG5cdFx0XHRcdFx0XHRcblx0XHRcdFx0XHR9KVxuXHRcdFx0KVxuXHRcdFx0LmFkZEJ1dHRvbigoYnRuKSA9PlxuXHRcdFx0XHRidG5cblx0XHRcdFx0XHQuc2V0QnV0dG9uVGV4dChcIkJ1aWxkIHdpdGhvdXQgY2xlYXJpbmdcIilcblx0XHRcdFx0XHQuc2V0Q3RhKClcblx0XHRcdFx0XHQub25DbGljayhhc3luYyAoKSA9PiB7XG5cdFx0XHRcdFx0XHR0aGlzLmNsb3NlKCk7XG5cdFx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5fYnVpbGRfYmlibGUoYmlibGVfcGF0aCk7XG5cdFx0XHRcdFx0fSlcblx0XHRcdClcblx0XHRcdC5hZGRCdXR0b24oKGJ0bikgPT5cblx0XHRcdFx0YnRuXG5cdFx0XHRcdFx0LnNldEJ1dHRvblRleHQoXCJDbGVhciBhbmQgYnVpbGRcIilcblx0XHRcdFx0XHQuc2V0Q3RhKClcblx0XHRcdFx0XHQub25DbGljayhhc3luYyAoKSA9PiB7XG5cdFx0XHRcdFx0XHR0aGlzLmNsb3NlKCk7XG5cdFx0XHRcdFx0XHRsZXQgbm90aWNlID0gbmV3IE5vdGljZShcIkNsZWFyaW5nIGJpYmxlIGZvbGRlci4uLlwiLCAwKVxuXG5cdFx0XHRcdFx0XHRsZXQgYWJzdHJhY3QgPSB0aGlzLmFwcC52YXVsdC5nZXRBYnN0cmFjdEZpbGVCeVBhdGgoXG5cdFx0XHRcdFx0XHRcdG5vcm1hbGl6ZVBhdGgoYmlibGVfcGF0aCwpXG5cdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0aWYgKGFic3RyYWN0ICE9IG51bGwpIHtcblx0XHRcdFx0XHRcdFx0YXdhaXQgdGhpcy5hcHAudmF1bHQuZGVsZXRlKGFic3RyYWN0LCB0cnVlKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdHRoaXMuYXBwLnZhdWx0LmFkYXB0ZXIubWtkaXIobm9ybWFsaXplUGF0aChiaWJsZV9wYXRoKSk7XG5cblx0XHRcdFx0XHRcdG5vdGljZS5oaWRlKClcblx0XHRcdFx0XHRcdGF3YWl0IHRoaXMucGx1Z2luLl9idWlsZF9iaWJsZShiaWJsZV9wYXRoKTtcblx0XHRcdFx0XHR9KVxuXHRcdFx0KTtcblx0fVxuXG5cdG9uQ2xvc2UoKSB7XG5cdFx0Y29uc3QgeyBjb250ZW50RWwgfSA9IHRoaXM7XG5cdFx0Y29udGVudEVsLmVtcHR5KCk7XG5cdH1cbn1cblxuY2xhc3MgRG93bmxvYWRCaWJsZU1vZGFsIGV4dGVuZHMgTW9kYWwge1xuXHRwbHVnaW46IE15QmlibGU7XG5cblx0Y29uc3RydWN0b3IoYXBwOiBBcHAsIHBsdWdpbjogTXlCaWJsZSkge1xuXHRcdHN1cGVyKGFwcCk7XG5cdFx0dGhpcy5wbHVnaW4gPSBwbHVnaW47XG5cdH1cblxuXHRvbk9wZW4oKSB7XG5cdFx0Y29uc3QgeyBjb250ZW50RWwgfSA9IHRoaXM7XG5cblx0XHRsZXQgdHJhbnNsYXRpb24gPSB0aGlzLnBsdWdpbi5zZXR0aW5ncy50cmFuc2xhdGlvbjtcblxuXHRcdGNvbnRlbnRFbC5jcmVhdGVFbChcImgxXCIsIHsgdGV4dDogXCJEb3dubG9hZCBiaWJsZT9cIiB9KTtcblx0XHRjb250ZW50RWwuY3JlYXRlRWwoXCJzcGFuXCIsIHtcblx0XHRcdHRleHQ6IFwiWW91IGFyZSBhYm91dCB0byBkb3dubG9hZCB0aGUgZW50aXJlIHswfSB0cmFuc2xhdGlvbiBvZiB0aGUgQmlibGUsIGFjY29yZGluZyB0byB5b3VyIHNldHRpbmdzLlwiXG5cdFx0XHRcdC5mb3JtYXQodHJhbnNsYXRpb24pXG5cdFx0fSk7XG5cdFx0Y29udGVudEVsLmNyZWF0ZUVsKFwicFwiLCB7XG5cdFx0XHR0ZXh0OiBcIkRvIHlvdSB3YW50IHRvIGNvbnRpbnVlP1wiXG5cdFx0fSk7XG5cdFx0Y29udGVudEVsLmNyZWF0ZUVsKFwicFwiLCB7fSk7XG5cblx0XHRuZXcgU2V0dGluZyhjb250ZW50RWwpXG5cdFx0XHQuYWRkQnV0dG9uKChidG4pID0+XG5cdFx0XHRcdGJ0blxuXHRcdFx0XHRcdC5zZXRCdXR0b25UZXh0KFwiQ2FuY2VsXCIpXG5cdFx0XHRcdFx0Lm9uQ2xpY2soKCkgPT4ge1xuXHRcdFx0XHRcdFx0dGhpcy5jbG9zZSgpO1xuXHRcdFx0XHRcdH0pXG5cdFx0XHQpXG5cdFx0XHQuYWRkQnV0dG9uKChidG4pID0+XG5cdFx0XHRcdGJ0blxuXHRcdFx0XHRcdC5zZXRCdXR0b25UZXh0KFwiRG93bmxvYWRcIilcblx0XHRcdFx0XHQuc2V0Q3RhKClcblx0XHRcdFx0XHQub25DbGljaygoKSA9PiB7XG5cdFx0XHRcdFx0XHR0aGlzLmNsb3NlKCk7XG5cdFx0XHRcdFx0XHR0aGlzLmRvd25sb2FkQmlibGUodHJhbnNsYXRpb24pO1xuXHRcdFx0XHRcdH0pXG5cdFx0XHQpO1xuXHR9XG5cblx0b25DbG9zZSgpIHtcblx0XHRjb25zdCB7IGNvbnRlbnRFbCB9ID0gdGhpcztcblx0XHRjb250ZW50RWwuZW1wdHkoKTtcblx0fVxuXG5cdGFzeW5jIGRvd25sb2FkQmlibGUodHJhbnNsYXRpb246IHN0cmluZykge1xuXHRcdG5ldyBOb3RpY2UoXG5cdFx0XHQnU3RhcnRlZCBkb3dubG9hZCBvZiB0aGUgezB9IHRyYW5zbGF0aW9uISdcblx0XHRcdFx0LmZvcm1hdCh0cmFuc2xhdGlvbilcblx0XHQpO1xuXG5cdFx0bGV0IGJpYmxlID0gYXdhaXQgdGhpcy5wbHVnaW4uYmlibGVfYXBpLmdldF90cmFuc2xhdGlvbih0cmFuc2xhdGlvbik7XG5cdFx0Zm9yIChjb25zdCBib29rX2lkIGluIGJpYmxlLmJvb2tzKSB7XG5cdFx0XHRmb3IgKGNvbnN0IGNoYXB0ZXJfa2V5IG9mIE9iamVjdC5rZXlzKGJpYmxlLmJvb2tzW2Jvb2tfaWRdKSkge1xuXHRcdFx0XHRjb25zdCBjaGFwdGVyID0gTnVtYmVyKGNoYXB0ZXJfa2V5KVxuXHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5iaWJsZV9hcGkuY2FjaGVfY2hhcHRlcihcblx0XHRcdFx0XHR0cmFuc2xhdGlvbixcblx0XHRcdFx0XHROdW1iZXIoYm9va19pZCksXG5cdFx0XHRcdFx0Y2hhcHRlciArIDEsXG5cdFx0XHRcdFx0YmlibGUuYm9va3NbYm9va19pZF1bY2hhcHRlcl0sXG5cdFx0XHRcdFx0dHJ1ZSxcblx0XHRcdFx0KTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRuZXcgTm90aWNlKFxuXHRcdFx0J0NvbXBsZXRlZCBkb3dubG9hZCBvZiB0aGUgezB9IHRyYW5zbGF0aW9uISdcblx0XHRcdFx0LmZvcm1hdCh0cmFuc2xhdGlvbilcblx0XHQpO1xuXHR9XG59XG4gIFxuZXhwb3J0IGNsYXNzIFF1aWNrQ2hhbmdlVHJhbnNsYXRpb25lTW9kYWwgZXh0ZW5kcyBGdXp6eVN1Z2dlc3RNb2RhbDxUcmFuc2xhdGlvbj4ge1xuXHRwbHVnaW46IE15QmlibGVcblx0dHJhbnNsYXRpb25zOiBUcmFuc2xhdGlvbnNcblx0b25DaG9zZTogKGNob3NlbjpUcmFuc2xhdGlvbikgPT4gKHZvaWR8UHJvbWlzZTx2b2lkPikgfCBudWxsXG5cblx0Y29uc3RydWN0b3IocGx1Z2luOiBNeUJpYmxlKSB7XG5cdFx0c3VwZXIocGx1Z2luLmFwcCk7XG5cdFx0dGhpcy5wbHVnaW4gPSBwbHVnaW47XG5cdH1cblxuXHQvLyBSZXR1cm5zIGFsbCBhdmFpbGFibGUgc3VnZ2VzdGlvbnMuXG5cdGdldEl0ZW1zKCk6IFRyYW5zbGF0aW9uW10ge1xuXHRcdGxldCB0cmFuc2xhdGlvbnNfbGlzdCA9IE9iamVjdC5rZXlzKHRoaXMudHJhbnNsYXRpb25zKS5tYXAoayA9PiB0aGlzLnRyYW5zbGF0aW9uc1trXSlcblx0XHRyZXR1cm4gdHJhbnNsYXRpb25zX2xpc3Rcblx0fVxuXG5cdGdldEl0ZW1UZXh0KGl0ZW06VHJhbnNsYXRpb24pOnN0cmluZyB7XG5cdFx0cmV0dXJuIHRyYW5zbGF0aW9uX3RvX2Rpc3BsYXlfbmFtZShpdGVtKVxuXHR9XG5cblx0Ly8gUGVyZm9ybSBhY3Rpb24gb24gdGhlIHNlbGVjdGVkIHN1Z2dlc3Rpb24uXG5cdG9uQ2hvb3NlSXRlbShpdGVtOiBUcmFuc2xhdGlvbiwgZXZ0OiBNb3VzZUV2ZW50IHwgS2V5Ym9hcmRFdmVudCkge1xuXHRcdGlmICh0aGlzLm9uQ2hvc2UgIT09IG51bGwpIHtcblx0XHRcdHRoaXMub25DaG9zZShpdGVtKVxuXHRcdH1cblx0fVxufVxuXG5jbGFzcyBTZXR0aW5nc1RhYiBleHRlbmRzIFBsdWdpblNldHRpbmdUYWIge1xuXHRwbHVnaW46IE15QmlibGU7XG5cblx0Y29uc3RydWN0b3IoYXBwOiBBcHAsIHBsdWdpbjogTXlCaWJsZSkge1xuXHRcdHN1cGVyKGFwcCwgcGx1Z2luKTtcblx0XHR0aGlzLnBsdWdpbiA9IHBsdWdpbjtcblx0fVxuXG5cdGRpc3BsYXkoKTogdm9pZCB7XG5cdFx0Y29uc3QgeyBjb250YWluZXJFbCB9ID0gdGhpcztcblxuXHRcdGNvbnRhaW5lckVsLmVtcHR5KCk7XG5cblx0XHRuZXcgU2V0dGluZyhjb250YWluZXJFbClcblx0XHRcdC5zZXROYW1lKCdUcmFuc2xhdGlvbicpXG5cdFx0XHQuc2V0RGVzYygnVGhlIHZlcnNpb24gb2YgdGhlIEJpYmxlIHRoYXQgd2lsbCBiZSBkaXNwbGF5ZWQgaW4gZHluYW1pYyB2ZXJzZXMuJylcblx0XHRcdC5hZGREcm9wZG93bihhc3luYyBkcm9wID0+IHtcblx0XHRcdFx0bGV0IHRyYW5zbGF0aW9ucyA9IGF3YWl0IHRoaXMucGx1Z2luLmJpYmxlX2FwaS5nZXRfdHJhbnNsYXRpb25zKCk7XG5cdFx0XHRcdFxuXHRcdFx0XHRsZXQgdHJhbnNsYXRpb25zX2xpc3QgPSBbXTtcblx0XHRcdFx0Zm9yIChjb25zdCBrZXkgaW4gdHJhbnNsYXRpb25zKSB7XG5cdFx0XHRcdFx0dHJhbnNsYXRpb25zX2xpc3QucHVzaChrZXkpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHRyYW5zbGF0aW9uc19saXN0ID0gdHJhbnNsYXRpb25zX2xpc3Quc29ydCgoYSwgYikgPT4ge1xuXHRcdFx0XHRcdGlmICh0cmFuc2xhdGlvbnNbYV0ubGFuZ3VhZ2UgPCB0cmFuc2xhdGlvbnNbYl0ubGFuZ3VhZ2UpIHtcblx0XHRcdFx0XHRcdHJldHVybiAtMTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKHRyYW5zbGF0aW9uc1thXS5sYW5ndWFnZSA+IHRyYW5zbGF0aW9uc1tiXS5sYW5ndWFnZSkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIDE7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0aWYgKGEgPCBiKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gLTE7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmIChhID4gYikge1xuXHRcdFx0XHRcdFx0cmV0dXJuIDE7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0cmV0dXJuIDA7XG5cdFx0XHRcdH0pXG5cblx0XHRcdFx0Zm9yIChjb25zdCBpIGluIHRyYW5zbGF0aW9uc19saXN0KSB7XG5cdFx0XHRcdFx0bGV0IGtleSA9IHRyYW5zbGF0aW9uc19saXN0W2ldO1xuXHRcdFx0XHRcdGRyb3AuYWRkT3B0aW9uKFxuXHRcdFx0XHRcdFx0a2V5LFxuXHRcdFx0XHRcdFx0XCJ7MH0gLSB7MX0gLSB7Mn1cIi5mb3JtYXQoXG5cdFx0XHRcdFx0XHRcdHRyYW5zbGF0aW9uc1trZXldLmxhbmd1YWdlLFxuXHRcdFx0XHRcdFx0XHRrZXksXG5cdFx0XHRcdFx0XHRcdHRyYW5zbGF0aW9uc1trZXldLmRpc3BsYXlfbmFtZSxcblx0XHRcdFx0XHRcdClcblx0XHRcdFx0XHQpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGRyb3Aub25DaGFuZ2UoYXN5bmMgdmFsdWUgPT4ge1xuXHRcdFx0XHRcdHRoaXMucGx1Z2luLnNldHRpbmdzLnJlYWRpbmdfdHJhbnNsYXRpb24gPSB2YWx1ZTtcblx0XHRcdFx0XHRhd2FpdCB0aGlzLnBsdWdpbi5zYXZlU2V0dGluZ3MoKTtcblx0XHRcdFx0fSlcblx0XHRcdFx0ZHJvcC5zZXRWYWx1ZSh0aGlzLnBsdWdpbi5zZXR0aW5ncy5yZWFkaW5nX3RyYW5zbGF0aW9uKTtcblx0XHRcdH0pXG5cdFx0O1xuXHR9XG59XG5cbmNvbnN0IERFRkFVTFRfTkFNRV9NQVA6IFJlY29yZDxzdHJpbmcsIEJvb2tJZD4gPSB7XG5cdFwiR2VuZXNpc1wiOiAxLFxuXHRcIkV4b2R1c1wiOiAyLFxuXHRcIkxldml0aWN1c1wiOiAzLFxuXHRcIk51bWJlcnNcIjogNCxcblx0XCJEZXV0ZXJvbm9teVwiOiA1LFxuXHRcIkpvc2h1YVwiOiA2LFxuXHRcIkp1ZGdlc1wiOiA3LFxuXHRcIlJ1dGhcIjogOCxcblx0XCIxIFNhbXVlbFwiOiA5LFxuXHRcIjIgU2FtdWVsXCI6IDEwLFxuXHRcIjEgS2luZ3NcIjogMTEsXG5cdFwiMiBLaW5nc1wiOiAxMixcblx0XCIxIENocm9uaWNsZXNcIjogMTMsXG5cdFwiMiBDaHJvbmljbGVzXCI6IDE0LFxuXHRcIkV6cmFcIjogMTUsXG5cdFwiTmVoZW1pYWhcIjogMTYsXG5cdFwiRXN0aGVyXCI6IDE3LFxuXHRcIkpvYlwiOiAxOCxcblx0XCJQc2FsbXNcIjogMTksXG5cdFwiUHNhbG1cIjogMTksIC8vIEFsdGVybmF0ZSBzcGVsbGluZ1xuXHRcIlByb3ZlcmJzXCI6IDIwLFxuXHRcIkVjY2xlc2lhc3Rlc1wiOiAyMSxcblx0XCJTb25nIG9mIFNvbG9tb25cIjogMjIsXG5cdFwiSXNhaWFoXCI6IDIzLFxuXHRcIkplcmVtaWFoXCI6IDI0LFxuXHRcIkxhbWVudGF0aW9uc1wiOiAyNSxcblx0XCJFemVraWVsXCI6IDI2LFxuXHRcIkRhbmllbFwiOiAyNyxcblx0XCJIb3NlYVwiOiAyOCxcblx0XCJKb2VsXCI6IDI5LFxuXHRcIkFtb3NcIjogMzAsXG5cdFwiT2JhZGlhaFwiOiAzMSxcblx0XCJKb25haFwiOiAzMixcblx0XCJNaWNhaFwiOiAzMyxcblx0XCJOYWh1bVwiOiAzNCxcblx0XCJIYWJha2t1a1wiOiAzNSxcblx0XCJaZXBoYW5pYWhcIjogMzYsXG5cdFwiSGFnZ2FpXCI6IDM3LFxuXHRcIlplY2hhcmlhaFwiOiAzOCxcblx0XCJNYWxhY2hpXCI6IDM5LFxuXHRcIk1hdHRoZXdcIjogNDAsXG5cdFwiTWFya1wiOiA0MSxcblx0XCJMdWtlXCI6IDQyLFxuXHRcIkpvaG5cIjogNDMsXG5cdFwiQWN0c1wiOiA0NCxcblx0XCJSb21hbnNcIjogNDUsXG5cdFwiMSBDb3JpbnRoaWFuc1wiOiA0Nixcblx0XCIyIENvcmludGhpYW5zXCI6IDQ3LFxuXHRcIkdhbGF0aWFuc1wiOiA0OCxcblx0XCJFcGhlc2lhbnNcIjogNDksXG5cdFwiUGhpbGlwcGlhbnNcIjogNTAsXG5cdFwiQ29sb3NzaWFuc1wiOiA1MSxcblx0XCIxIFRoZXNzYWxvbmlhbnNcIjogNTIsXG5cdFwiMiBUaGVzc2Fsb25pYW5zXCI6IDUzLFxuXHRcIjEgVGltb3RoeVwiOiA1NCxcblx0XCIyIFRpbW90aHlcIjogNTUsXG5cdFwiVGl0dXNcIjogNTYsXG5cdFwiUGhpbGVtb25cIjogNTcsXG5cdFwiSGVicmV3c1wiOiA1OCxcblx0XCJKYW1lc1wiOiA1OSxcblx0XCIxIFBldGVyXCI6IDYwLFxuXHRcIjIgUGV0ZXJcIjogNjEsXG5cdFwiMSBKb2huXCI6IDYyLFxuXHRcIjIgSm9oblwiOiA2Myxcblx0XCIzIEpvaG5cIjogNjQsXG5cdFwiSnVkZVwiOiA2NSxcblx0XCJSZXZlbGF0aW9uXCI6IDY2LFxuXHRcIjEgRXNkcmFzXCI6IDY3LFxuXHRcIlRvYml0XCI6IDY4LFxuXHRcIkp1ZGl0aFwiOiA2OSxcblx0XCJXaXNkb21cIjogNzAsXG5cdFwiU2lyYWNoXCI6IDcxLFxuXHRcIkVwaXN0bGUgb2YgSmVyZW1pYWhcIjogNzIsXG5cdFwiQmFydWNoXCI6IDczLFxuXHRcIjEgTWFjY2FiZWVzXCI6IDc0LFxuXHRcIjIgTWFjY2FiZWVzXCI6IDc1LFxuXHRcIjMgTWFjY2FiZWVzXCI6IDc2LFxuXHRcIjIgRXNkcmFzXCI6IDc3LFxuXHRcIlN1c2FubmFcIjogNzgsXG5cdFwiQmVsIGFuZCBEcmFnb25cIjogNzksXG5cdFwiNCBNYWNjYWJlZXNcIjogODAsXG5cdFwiR3JlZWsgQWRkaXRpb25zIHRvIEVzdGhlclwiOiA4MSxcblx0XCIzIEhvbHkgQ2hpbGRyZW4ncyBTb25nXCI6IDgyLFxuXHRcIlByYXllciBvZiBNYW5hc3NlaFwiOiA4Myxcblx0XCJBemFyaWFoXCI6IDg4LCAvLyBKdW1wIGluIG51bWJlclxufSIsICJjb25zdCBFX1RJTUVPVVQgPSBuZXcgRXJyb3IoJ3RpbWVvdXQgd2hpbGUgd2FpdGluZyBmb3IgbXV0ZXggdG8gYmVjb21lIGF2YWlsYWJsZScpO1xuY29uc3QgRV9BTFJFQURZX0xPQ0tFRCA9IG5ldyBFcnJvcignbXV0ZXggYWxyZWFkeSBsb2NrZWQnKTtcbmNvbnN0IEVfQ0FOQ0VMRUQgPSBuZXcgRXJyb3IoJ3JlcXVlc3QgZm9yIGxvY2sgY2FuY2VsZWQnKTtcblxudmFyIF9fYXdhaXRlciQyID0gKHVuZGVmaW5lZCAmJiB1bmRlZmluZWQuX19hd2FpdGVyKSB8fCBmdW5jdGlvbiAodGhpc0FyZywgX2FyZ3VtZW50cywgUCwgZ2VuZXJhdG9yKSB7XG4gICAgZnVuY3Rpb24gYWRvcHQodmFsdWUpIHsgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgUCA/IHZhbHVlIDogbmV3IFAoZnVuY3Rpb24gKHJlc29sdmUpIHsgcmVzb2x2ZSh2YWx1ZSk7IH0pOyB9XG4gICAgcmV0dXJuIG5ldyAoUCB8fCAoUCA9IFByb21pc2UpKShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICAgIGZ1bmN0aW9uIGZ1bGZpbGxlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvci5uZXh0KHZhbHVlKSk7IH0gY2F0Y2ggKGUpIHsgcmVqZWN0KGUpOyB9IH1cbiAgICAgICAgZnVuY3Rpb24gcmVqZWN0ZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3JbXCJ0aHJvd1wiXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XG4gICAgICAgIGZ1bmN0aW9uIHN0ZXAocmVzdWx0KSB7IHJlc3VsdC5kb25lID8gcmVzb2x2ZShyZXN1bHQudmFsdWUpIDogYWRvcHQocmVzdWx0LnZhbHVlKS50aGVuKGZ1bGZpbGxlZCwgcmVqZWN0ZWQpOyB9XG4gICAgICAgIHN0ZXAoKGdlbmVyYXRvciA9IGdlbmVyYXRvci5hcHBseSh0aGlzQXJnLCBfYXJndW1lbnRzIHx8IFtdKSkubmV4dCgpKTtcbiAgICB9KTtcbn07XG5jbGFzcyBTZW1hcGhvcmUge1xuICAgIGNvbnN0cnVjdG9yKF92YWx1ZSwgX2NhbmNlbEVycm9yID0gRV9DQU5DRUxFRCkge1xuICAgICAgICB0aGlzLl92YWx1ZSA9IF92YWx1ZTtcbiAgICAgICAgdGhpcy5fY2FuY2VsRXJyb3IgPSBfY2FuY2VsRXJyb3I7XG4gICAgICAgIHRoaXMuX3dlaWdodGVkUXVldWVzID0gW107XG4gICAgICAgIHRoaXMuX3dlaWdodGVkV2FpdGVycyA9IFtdO1xuICAgIH1cbiAgICBhY3F1aXJlKHdlaWdodCA9IDEpIHtcbiAgICAgICAgaWYgKHdlaWdodCA8PSAwKVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIHdlaWdodCAke3dlaWdodH06IG11c3QgYmUgcG9zaXRpdmVgKTtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGlmICghdGhpcy5fd2VpZ2h0ZWRRdWV1ZXNbd2VpZ2h0IC0gMV0pXG4gICAgICAgICAgICAgICAgdGhpcy5fd2VpZ2h0ZWRRdWV1ZXNbd2VpZ2h0IC0gMV0gPSBbXTtcbiAgICAgICAgICAgIHRoaXMuX3dlaWdodGVkUXVldWVzW3dlaWdodCAtIDFdLnB1c2goeyByZXNvbHZlLCByZWplY3QgfSk7XG4gICAgICAgICAgICB0aGlzLl9kaXNwYXRjaCgpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgcnVuRXhjbHVzaXZlKGNhbGxiYWNrLCB3ZWlnaHQgPSAxKSB7XG4gICAgICAgIHJldHVybiBfX2F3YWl0ZXIkMih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAgIGNvbnN0IFt2YWx1ZSwgcmVsZWFzZV0gPSB5aWVsZCB0aGlzLmFjcXVpcmUod2VpZ2h0KTtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHlpZWxkIGNhbGxiYWNrKHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgICAgIHJlbGVhc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHdhaXRGb3JVbmxvY2sod2VpZ2h0ID0gMSkge1xuICAgICAgICBpZiAod2VpZ2h0IDw9IDApXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgd2VpZ2h0ICR7d2VpZ2h0fTogbXVzdCBiZSBwb3NpdGl2ZWApO1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgIGlmICghdGhpcy5fd2VpZ2h0ZWRXYWl0ZXJzW3dlaWdodCAtIDFdKVxuICAgICAgICAgICAgICAgIHRoaXMuX3dlaWdodGVkV2FpdGVyc1t3ZWlnaHQgLSAxXSA9IFtdO1xuICAgICAgICAgICAgdGhpcy5fd2VpZ2h0ZWRXYWl0ZXJzW3dlaWdodCAtIDFdLnB1c2gocmVzb2x2ZSk7XG4gICAgICAgICAgICB0aGlzLl9kaXNwYXRjaCgpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgaXNMb2NrZWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl92YWx1ZSA8PSAwO1xuICAgIH1cbiAgICBnZXRWYWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlO1xuICAgIH1cbiAgICBzZXRWYWx1ZSh2YWx1ZSkge1xuICAgICAgICB0aGlzLl92YWx1ZSA9IHZhbHVlO1xuICAgICAgICB0aGlzLl9kaXNwYXRjaCgpO1xuICAgIH1cbiAgICByZWxlYXNlKHdlaWdodCA9IDEpIHtcbiAgICAgICAgaWYgKHdlaWdodCA8PSAwKVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIHdlaWdodCAke3dlaWdodH06IG11c3QgYmUgcG9zaXRpdmVgKTtcbiAgICAgICAgdGhpcy5fdmFsdWUgKz0gd2VpZ2h0O1xuICAgICAgICB0aGlzLl9kaXNwYXRjaCgpO1xuICAgIH1cbiAgICBjYW5jZWwoKSB7XG4gICAgICAgIHRoaXMuX3dlaWdodGVkUXVldWVzLmZvckVhY2goKHF1ZXVlKSA9PiBxdWV1ZS5mb3JFYWNoKChlbnRyeSkgPT4gZW50cnkucmVqZWN0KHRoaXMuX2NhbmNlbEVycm9yKSkpO1xuICAgICAgICB0aGlzLl93ZWlnaHRlZFF1ZXVlcyA9IFtdO1xuICAgIH1cbiAgICBfZGlzcGF0Y2goKSB7XG4gICAgICAgIHZhciBfYTtcbiAgICAgICAgZm9yIChsZXQgd2VpZ2h0ID0gdGhpcy5fdmFsdWU7IHdlaWdodCA+IDA7IHdlaWdodC0tKSB7XG4gICAgICAgICAgICBjb25zdCBxdWV1ZUVudHJ5ID0gKF9hID0gdGhpcy5fd2VpZ2h0ZWRRdWV1ZXNbd2VpZ2h0IC0gMV0pID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5zaGlmdCgpO1xuICAgICAgICAgICAgaWYgKCFxdWV1ZUVudHJ5KVxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgY29uc3QgcHJldmlvdXNWYWx1ZSA9IHRoaXMuX3ZhbHVlO1xuICAgICAgICAgICAgY29uc3QgcHJldmlvdXNXZWlnaHQgPSB3ZWlnaHQ7XG4gICAgICAgICAgICB0aGlzLl92YWx1ZSAtPSB3ZWlnaHQ7XG4gICAgICAgICAgICB3ZWlnaHQgPSB0aGlzLl92YWx1ZSArIDE7XG4gICAgICAgICAgICBxdWV1ZUVudHJ5LnJlc29sdmUoW3ByZXZpb3VzVmFsdWUsIHRoaXMuX25ld1JlbGVhc2VyKHByZXZpb3VzV2VpZ2h0KV0pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2RyYWluVW5sb2NrV2FpdGVycygpO1xuICAgIH1cbiAgICBfbmV3UmVsZWFzZXIod2VpZ2h0KSB7XG4gICAgICAgIGxldCBjYWxsZWQgPSBmYWxzZTtcbiAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgIGlmIChjYWxsZWQpXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgY2FsbGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMucmVsZWFzZSh3ZWlnaHQpO1xuICAgICAgICB9O1xuICAgIH1cbiAgICBfZHJhaW5VbmxvY2tXYWl0ZXJzKCkge1xuICAgICAgICBmb3IgKGxldCB3ZWlnaHQgPSB0aGlzLl92YWx1ZTsgd2VpZ2h0ID4gMDsgd2VpZ2h0LS0pIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5fd2VpZ2h0ZWRXYWl0ZXJzW3dlaWdodCAtIDFdKVxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgdGhpcy5fd2VpZ2h0ZWRXYWl0ZXJzW3dlaWdodCAtIDFdLmZvckVhY2goKHdhaXRlcikgPT4gd2FpdGVyKCkpO1xuICAgICAgICAgICAgdGhpcy5fd2VpZ2h0ZWRXYWl0ZXJzW3dlaWdodCAtIDFdID0gW107XG4gICAgICAgIH1cbiAgICB9XG59XG5cbnZhciBfX2F3YWl0ZXIkMSA9ICh1bmRlZmluZWQgJiYgdW5kZWZpbmVkLl9fYXdhaXRlcikgfHwgZnVuY3Rpb24gKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xuICAgIGZ1bmN0aW9uIGFkb3B0KHZhbHVlKSB7IHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIFAgPyB2YWx1ZSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUodmFsdWUpOyB9KTsgfVxuICAgIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XG4gICAgICAgIGZ1bmN0aW9uIHJlamVjdGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yW1widGhyb3dcIl0odmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxuICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IGFkb3B0KHJlc3VsdC52YWx1ZSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XG4gICAgfSk7XG59O1xuY2xhc3MgTXV0ZXgge1xuICAgIGNvbnN0cnVjdG9yKGNhbmNlbEVycm9yKSB7XG4gICAgICAgIHRoaXMuX3NlbWFwaG9yZSA9IG5ldyBTZW1hcGhvcmUoMSwgY2FuY2VsRXJyb3IpO1xuICAgIH1cbiAgICBhY3F1aXJlKCkge1xuICAgICAgICByZXR1cm4gX19hd2FpdGVyJDEodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICBjb25zdCBbLCByZWxlYXNlcl0gPSB5aWVsZCB0aGlzLl9zZW1hcGhvcmUuYWNxdWlyZSgpO1xuICAgICAgICAgICAgcmV0dXJuIHJlbGVhc2VyO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgcnVuRXhjbHVzaXZlKGNhbGxiYWNrKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zZW1hcGhvcmUucnVuRXhjbHVzaXZlKCgpID0+IGNhbGxiYWNrKCkpO1xuICAgIH1cbiAgICBpc0xvY2tlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NlbWFwaG9yZS5pc0xvY2tlZCgpO1xuICAgIH1cbiAgICB3YWl0Rm9yVW5sb2NrKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2VtYXBob3JlLndhaXRGb3JVbmxvY2soKTtcbiAgICB9XG4gICAgcmVsZWFzZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuX3NlbWFwaG9yZS5pc0xvY2tlZCgpKVxuICAgICAgICAgICAgdGhpcy5fc2VtYXBob3JlLnJlbGVhc2UoKTtcbiAgICB9XG4gICAgY2FuY2VsKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc2VtYXBob3JlLmNhbmNlbCgpO1xuICAgIH1cbn1cblxudmFyIF9fYXdhaXRlciA9ICh1bmRlZmluZWQgJiYgdW5kZWZpbmVkLl9fYXdhaXRlcikgfHwgZnVuY3Rpb24gKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikge1xuICAgIGZ1bmN0aW9uIGFkb3B0KHZhbHVlKSB7IHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIFAgPyB2YWx1ZSA6IG5ldyBQKGZ1bmN0aW9uIChyZXNvbHZlKSB7IHJlc29sdmUodmFsdWUpOyB9KTsgfVxuICAgIHJldHVybiBuZXcgKFAgfHwgKFAgPSBQcm9taXNlKSkoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9XG4gICAgICAgIGZ1bmN0aW9uIHJlamVjdGVkKHZhbHVlKSB7IHRyeSB7IHN0ZXAoZ2VuZXJhdG9yW1widGhyb3dcIl0odmFsdWUpKTsgfSBjYXRjaCAoZSkgeyByZWplY3QoZSk7IH0gfVxuICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IGFkb3B0KHJlc3VsdC52YWx1ZSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfVxuICAgICAgICBzdGVwKChnZW5lcmF0b3IgPSBnZW5lcmF0b3IuYXBwbHkodGhpc0FyZywgX2FyZ3VtZW50cyB8fCBbXSkpLm5leHQoKSk7XG4gICAgfSk7XG59O1xuZnVuY3Rpb24gd2l0aFRpbWVvdXQoc3luYywgdGltZW91dCwgdGltZW91dEVycm9yID0gRV9USU1FT1VUKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgYWNxdWlyZTogKHdlaWdodCkgPT4ge1xuICAgICAgICAgICAgaWYgKHdlaWdodCAhPT0gdW5kZWZpbmVkICYmIHdlaWdodCA8PSAwKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBpbnZhbGlkIHdlaWdodCAke3dlaWdodH06IG11c3QgYmUgcG9zaXRpdmVgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0IGlzVGltZW91dCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGNvbnN0IGhhbmRsZSA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpc1RpbWVvdXQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICByZWplY3QodGltZW91dEVycm9yKTtcbiAgICAgICAgICAgICAgICB9LCB0aW1lb3V0KTtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB0aWNrZXQgPSB5aWVsZCBzeW5jLmFjcXVpcmUod2VpZ2h0KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGlzVGltZW91dCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVsZWFzZSA9IEFycmF5LmlzQXJyYXkodGlja2V0KSA/IHRpY2tldFsxXSA6IHRpY2tldDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbGVhc2UoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChoYW5kbGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh0aWNrZXQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghaXNUaW1lb3V0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQoaGFuZGxlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgfSxcbiAgICAgICAgcnVuRXhjbHVzaXZlKGNhbGxiYWNrLCB3ZWlnaHQpIHtcbiAgICAgICAgICAgIHJldHVybiBfX2F3YWl0ZXIodGhpcywgdm9pZCAwLCB2b2lkIDAsIGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0IHJlbGVhc2UgPSAoKSA9PiB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdGlja2V0ID0geWllbGQgdGhpcy5hY3F1aXJlKHdlaWdodCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHRpY2tldCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbGVhc2UgPSB0aWNrZXRbMV07XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4geWllbGQgY2FsbGJhY2sodGlja2V0WzBdKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbGVhc2UgPSB0aWNrZXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4geWllbGQgY2FsbGJhY2soKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBmaW5hbGx5IHtcbiAgICAgICAgICAgICAgICAgICAgcmVsZWFzZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9LFxuICAgICAgICByZWxlYXNlKHdlaWdodCkge1xuICAgICAgICAgICAgc3luYy5yZWxlYXNlKHdlaWdodCk7XG4gICAgICAgIH0sXG4gICAgICAgIGNhbmNlbCgpIHtcbiAgICAgICAgICAgIHJldHVybiBzeW5jLmNhbmNlbCgpO1xuICAgICAgICB9LFxuICAgICAgICB3YWl0Rm9yVW5sb2NrOiAod2VpZ2h0KSA9PiB7XG4gICAgICAgICAgICBpZiAod2VpZ2h0ICE9PSB1bmRlZmluZWQgJiYgd2VpZ2h0IDw9IDApIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgd2VpZ2h0ICR7d2VpZ2h0fTogbXVzdCBiZSBwb3NpdGl2ZWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgICAgICBzeW5jLndhaXRGb3JVbmxvY2sod2VpZ2h0KS50aGVuKHJlc29sdmUpO1xuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gcmVqZWN0KHRpbWVvdXRFcnJvciksIHRpbWVvdXQpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sXG4gICAgICAgIGlzTG9ja2VkOiAoKSA9PiBzeW5jLmlzTG9ja2VkKCksXG4gICAgICAgIGdldFZhbHVlOiAoKSA9PiBzeW5jLmdldFZhbHVlKCksXG4gICAgICAgIHNldFZhbHVlOiAodmFsdWUpID0+IHN5bmMuc2V0VmFsdWUodmFsdWUpLFxuICAgIH07XG59XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGlzbmUgQHR5cGVzY3JpcHQtZXNsaW50L2V4cGxpY2l0LW1vZHVsZS1ib3VuZGFyeS10eXBlc1xuZnVuY3Rpb24gdHJ5QWNxdWlyZShzeW5jLCBhbHJlYWR5QWNxdWlyZWRFcnJvciA9IEVfQUxSRUFEWV9MT0NLRUQpIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgIHJldHVybiB3aXRoVGltZW91dChzeW5jLCAwLCBhbHJlYWR5QWNxdWlyZWRFcnJvcik7XG59XG5cbmV4cG9ydCB7IEVfQUxSRUFEWV9MT0NLRUQsIEVfQ0FOQ0VMRUQsIEVfVElNRU9VVCwgTXV0ZXgsIFNlbWFwaG9yZSwgdHJ5QWNxdWlyZSwgd2l0aFRpbWVvdXQgfTtcbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLHNCQVlPOzs7QUNaUCxJQUFNLFlBQVksSUFBSSxNQUFNLHFEQUFxRDtBQUNqRixJQUFNLG1CQUFtQixJQUFJLE1BQU0sc0JBQXNCO0FBQ3pELElBQU0sYUFBYSxJQUFJLE1BQU0sMkJBQTJCO0FBRXhELElBQUksY0FBb0QsU0FBVSxTQUFTLFlBQVksR0FBRyxXQUFXO0FBQ2pHLFdBQVMsTUFBTSxPQUFPO0FBQUUsV0FBTyxpQkFBaUIsSUFBSSxRQUFRLElBQUksRUFBRSxTQUFVLFNBQVM7QUFBRSxjQUFRLEtBQUs7QUFBQSxJQUFHLENBQUM7QUFBQSxFQUFHO0FBQzNHLFNBQU8sS0FBSyxNQUFNLElBQUksVUFBVSxTQUFVLFNBQVMsUUFBUTtBQUN2RCxhQUFTLFVBQVUs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